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();
}
}
}
}
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();
}
}
}
}