XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

AutoMiningScript

【SpaceEngineer】全自动挖矿脚本

公开
关注 0 Fork 0 Star 0
UTF-8
using System;
using System.Collections.Generic;
using Sandbox.ModAPI.Ingame;
using VRage.Game.ModAPI.Ingame;
using VRage.Game.ModAPI.Ingame.Utilities;
using VRageMath;

namespace AutoMiningScript
{
    public partial class Program
    {
        public static class Marking
        {
            public static double Number(string text)
            {
                double n;if(!double.TryParse(text,System.Globalization.NumberStyles.Float,Data.Culture,out n)||!Data.Finite(n)) throw new ArgumentException(L.F(L.FleetNumericArgumentInvalid,text));return n;
            }
            public static MyIni Parse(Program p,string command)
            {
                int gps=command.IndexOf("GPS:",StringComparison.Ordinal);
                string prefix=gps<0?command:command.Substring(0,gps);
                string[] parts=prefix.Trim().Split(new[]{' '},StringSplitOptions.RemoveEmptyEntries);
                if(parts.Length!=4) throw new ArgumentException(L.FleetMarkUsage);
                double width=Number(parts[1]),height=Number(parts[2]),depth=Number(parts[3]);
                if(width<=0||height<=0||depth<=0||width>1000||height>1000||depth>1000) throw new ArgumentException(L.FleetMarkDimensions);
                Vector3D entry,direction,up=p.Me.WorldMatrix.Up;
                if(gps>=0)
                {
                    int second=command.IndexOf("GPS:",gps+4,StringComparison.Ordinal);Vector3D inside;
                    if(second<0||!Data.TryGps(command.Substring(gps,second-gps),out entry)||!Data.TryGps(command.Substring(second),out inside)) throw new ArgumentException(L.FleetTwoGpsRequired);
                    direction=inside-entry;if(direction.LengthSquared()<0.01) throw new ArgumentException(L.FleetGpsPointsDiffer);
                }
                else
                {
                    string name=p.Config.Text("Marker","Camera","");var cameras=new List<IMyCameraBlock>();
                    p.GridTerminalSystem.GetBlocksOfType(cameras,c=>c.CubeGrid==p.Me.CubeGrid&&c.IsFunctional&&(name.Length==0||c.CustomName==name));
                    if(cameras.Count==0) throw new ArgumentException(L.FleetMarkerCameraMissing);
                    IMyCameraBlock camera=cameras[0];camera.EnableRaycast=true;
                    double distance=p.Config.Number("Marker","ScanDistance",1000,10,10000);
                    if(!camera.CanScan(distance)) throw new ArgumentException(L.F(L.FleetMarkerCameraCharging,camera.AvailableScanRange));
                    MyDetectedEntityInfo hit=camera.Raycast(distance);
                    if(hit.IsEmpty()||!hit.HitPosition.HasValue||(hit.Type!=MyDetectedEntityType.Asteroid&&hit.Type!=MyDetectedEntityType.Planet)) throw new ArgumentException(L.FleetMarkerSurfaceRequired);
                    entry=hit.HitPosition.Value;direction=entry-camera.GetPosition();up=camera.WorldMatrix.Up;
                }
                var i=new MyIni();i.Set("mark","Entry",Data.Vector(entry));i.Set("mark","Direction",Data.Vector(Data.Unit(direction,Vector3D.Forward)));i.Set("mark","Up",Data.Vector(Data.Perpendicular(direction,up)));
                i.Set("mark","Width",width);i.Set("mark","Height",height);i.Set("mark","Depth",depth);return i;
            }
        }

        public class MarkerController : RoleLogic
        {
            string last=L.FleetMarkerGuidance;
            string lastStatus="Guidance",lastWidth="",lastHeight="",lastDepth="",lastEntry="";
            public MarkerController(Program p):base(p) {EnableCameras();}
            void EnableCameras()
            {
                var cameras=new List<IMyCameraBlock>();P.GridTerminalSystem.GetBlocksOfType(cameras,c=>c.CubeGrid==P.Me.CubeGrid);
                foreach(var camera in cameras) camera.EnableRaycast=true;
            }
            public override string Diagnostics {get{return L.F(L.FleetMarkerDiagnostics,P.Config.BaseId,last);}}
            public override void Command(string command)
            {
                string[] parts=command.Trim().Split(new[]{' '},StringSplitOptions.RemoveEmptyEntries);if(parts.Length==0) return;
                string verb=parts[0].ToLowerInvariant();
                if(verb=="init"||verb=="rescan"||verb=="diagnose") {EnableCameras();P.Log(Diagnostics);return;}
                if(verb=="mark")
                {
                    MyIni body=Marking.Parse(P,command);P.Bus.Send("MARK",P.Config.BaseId,body,true);
                    lastStatus="Manual";lastWidth=body.Get("mark","Width").ToString();lastHeight=body.Get("mark","Height").ToString();lastDepth=body.Get("mark","Depth").ToString();lastEntry=body.Get("mark","Entry").ToString();UpdateLast();P.Log(last);return;
                }
                if(verb=="survey")
                {
                    double radius=parts.Length>1?Marking.Number(parts[1]):0;if(radius!=0&&(radius<20||radius>20000)) throw new ArgumentException(L.FleetSurveyRadius);
                    var body=new MyIni();body.Set("survey","Radius",radius);P.Bus.Send("SURVEY_REQUEST",P.Config.BaseId,body,true);lastStatus="Survey";UpdateLast();P.Log(last);return;
                }
                P.Log(L.FleetMarkerCommands);
            }
            void UpdateLast()
            {
                last=lastStatus=="Manual"?L.F(L.FleetMarkerSubmitted,lastWidth,lastHeight,lastDepth,lastEntry):lastStatus=="Survey"?L.FleetMarkerSurveySubmitted:L.FleetMarkerGuidance;
            }
            public override void Save(MyIni ini)
            {
                ini.Set("marker","Last",last);ini.Set("marker","Status",lastStatus);ini.Set("marker","Width",lastWidth);ini.Set("marker","Height",lastHeight);ini.Set("marker","Depth",lastDepth);ini.Set("marker","Entry",lastEntry);
            }
            public override void Load(MyIni ini)
            {
                // Persist stable status tokens so replacing the script's language changes the UI immediately.
                lastStatus=ini.Get("marker","Status").ToString("Guidance");lastWidth=ini.Get("marker","Width").ToString();lastHeight=ini.Get("marker","Height").ToString();lastDepth=ini.Get("marker","Depth").ToString();lastEntry=ini.Get("marker","Entry").ToString();UpdateLast();
            }
        }
    }
}