Advertisement
idiotonastic

Untitled

May 7th, 2019
388
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 52.03 KB | None | 0 0
  1. /*
  2.  *   R e a d m e
  3.  *   -----------
  4.  *      Version 1.1
  5.  *      Based on Rdav's AI Autominer Script (https://steamcommunity.com/sharedfiles/filedetails/?id=1356607768) by Rdav full credit goes to him for the majority of this script.
  6.  *      
  7.  */
  8.  
  9.  
  10. //changing things below this comment may cause the script to break.
  11.  
  12. //Code Constructor For Initialisation
  13. public Program()
  14. { FirstTimeSetup(); }
  15.  
  16. //Code Saves For Further Functions
  17. public void Save()
  18. { SaveCode(); }
  19.  
  20. //Primary Code Runtime
  21. //========================
  22.  
  23. //Setup Of Code Constants
  24.  
  25. //STORED VARIABLES
  26. //----------------------------------------------------------------------------------------------------------------------
  27.  
  28. //SUBCATEGORY PERMANENT ASSIGNMENTS:
  29. string VERSION = "1.1"; //Script Version
  30. double PrecisionMaxAngularVel = 0.6; //Maximum Precision Ship Angular Velocity
  31. double RotationalSensitvity = 1; //Gain Applied To Gyros
  32. bool ThrustCountOverride = false; //Togglable Override On Thrust Count
  33. double MinCharge = 0.9; //minimum charge for batteries to re deploy
  34.  
  35. //Main Method Runtime
  36. void Main(string argument)
  37. {
  38.  
  39.     try
  40.     {
  41.  
  42.         //Sets Up Code Runtime Indicators & Docking Route Checks
  43.         //---------------------------------------------------------
  44.         OP_BAR();
  45.         Echo("General Information:\n----------------------------");
  46.  
  47.         //System Error Readouts And Diag
  48.         //---------------------------------
  49.  
  50.         if (RC == null || RC.CubeGrid.GetCubeBlock(RC.Position) == null)
  51.         { Echo("No Remote Control Found,\nInstall Forward Facing Remote Control Block And Press Recompile"); RC = null; return; }
  52.         if (CONNECTOR == null || CONNECTOR.CubeGrid.GetCubeBlock(CONNECTOR.Position) == null)
  53.         { Echo("No Connector Found,\nInstall Connector And Press Recompile "); CONNECTOR = null; return; }
  54.         /*
  55.                 if (TIMER == null || TIMER.CubeGrid.GetCubeBlock(TIMER.Position) == null)
  56.                 { Echo("No Timer Found,\nInstall Timer And Press Recompile."); SENSOR = null; return; }
  57.                 */
  58.         if (SENSOR == null || SENSOR.CubeGrid.GetCubeBlock(SENSOR.Position) == null)
  59.         { Echo("No Sensor Found,\nInstall Sensor For Asteroid Detection And Press Recompile,\n(all sensor settings will automatically be set)"); SENSOR = null; return; }
  60.         if (GYRO == null || GYRO.CubeGrid.GetCubeBlock(GYRO.Position) == null)
  61.         { Echo("No Gyro Found,\nInstall Gyro And Press Recompile"); GYRO = null; return; }
  62.  
  63.         if (CAF2_THRUST.Count > 15 && ThrustCountOverride)
  64.         {
  65.             Echo("Large Amount Of Thrusters Detected\nProgram Terminated To Prevent Performance Issues\n" +
  66.               "Remove Unecessary Thrusters And Press Recompile (15 max)\n" +
  67.               "This safety measure can be disabled on line 56"); return;
  68.         }
  69.  
  70.         //Dockpoint Handler
  71.         //-----------------------
  72.         Auto_DockpointDetect(); //Automatically Detects Docking Route
  73.         var DOCKLIST = new List<Vector3D>();
  74.         DOCKLIST.Add(DockPos3.Val);
  75.         DOCKLIST.Add(DockPos2.Val);
  76.         DOCKLIST.Add(DockPos1.Val);
  77.  
  78.         if (DOCKLIST[0] == new Vector3D()) //Returns Error If No Docking Route
  79.         { Echo("Cannot Find Docking Route\nPlease Dock To (Static) Connector\nTo Use As A Drop-Off Point"); return; }
  80.  
  81.         //Manual Resetter Returns To Base
  82.         //--------------------------------
  83.         if (argument == "FIN")
  84.         { MININGSTATUS.Val = "FIN"; HASFINISHED.Val = true; }
  85.         if (argument == "RETURN")
  86.         { MININGSTATUS.Val = "FULL"; HASFINISHED.Val = true; }
  87.         if (argument == "CHARGE")
  88.         { BatteryCharger(); }
  89.         //Manual Override Enabler
  90.         //-----------------------------
  91.         bool ALL_RUN = true;
  92.         foreach (var item in CONTROLLERS)
  93.         { if ((item as IMyShipController).IsUnderControl) { ALL_RUN = false; } }
  94.         if (ALL_RUN == false)
  95.         {
  96.             //Sets Standard Delogging Procedures
  97.             RC.SetAutoPilotEnabled(false);
  98.             for (int j = 0; j < CAF2_THRUST.Count; j++)
  99.             { (CAF2_THRUST[j] as IMyThrust).ThrustOverride = 0; (CAF2_THRUST[j] as IMyThrust).Enabled = true; }
  100.             GYRO.GyroOverride = false;
  101.             CONNECTOR.Enabled = true;
  102.             Echo("Manual Override Engaged\nStop controlling ship to continue program");
  103.  
  104.             //Sets Docked Status If Docked
  105.             if (CONNECTOR.Status == MyShipConnectorStatus.Connected)
  106.             { COORD_ID.Val = 2; }
  107.             return;
  108.         }
  109.  
  110.         //Updates Coordinates (not size) in a new Locator Scenario
  111.         //-------------------------------------------------------------
  112.         try
  113.         {
  114.             if (ISNOTBURIED.Val)
  115.             {
  116.                 //Splits The Code Into Chunks
  117.                 string[] InputData = Me.CustomData.Split('@');
  118.                 string[] InputGpsList = InputData[1].Split(':');
  119.                 Vector3D TryVector = new Vector3D(double.Parse(InputGpsList[2]), double.Parse(InputGpsList[3]), double.Parse(InputGpsList[4]));
  120.  
  121.                 //Updates If Both Not Buried And Different
  122.                 if (TryVector != StoredAsteroidLoc.Val && ISNOTBURIED.Val)
  123.                 {
  124.                     StoredAsteroidLoc.Val = TryVector;
  125.                     MiningLogic(RC, DOCKLIST, GYRO, CONNECTOR, true);
  126.                     Echo("Updated Input Correctly");
  127.                     return;
  128.                 }
  129.             }
  130.         }
  131.         catch { Echo("Incorrect Input Format,\n Refer Instructions, or Press 'Recompile' to reset."); }
  132.  
  133.         if (StoredAsteroidLoc.Val == new Vector3D()) //Returns Error If No Docking Route
  134.         { Echo("No Asteroid Input,\n Please Paste Valid GPS in Custom Data"); return; }
  135.  
  136.         //Updates A Sensor If Ship Has One
  137.         //---------------------------------------------
  138.         if (SENSOR != null && SENSOR.DetectAsteroids == false)
  139.         {
  140.             SENSOR.DetectAsteroids = true;
  141.             SENSOR.DetectPlayers = false;
  142.             SENSOR.DetectOwner = false;
  143.             SENSOR.DetectLargeShips = false;
  144.             SENSOR.DetectSmallShips = false;
  145.             SENSOR.LeftExtend = 50;
  146.             SENSOR.RightExtend = 50;
  147.             SENSOR.TopExtend = 50;
  148.             SENSOR.FrontExtend = 50;
  149.             SENSOR.BottomExtend = 50;
  150.             SENSOR.BackExtend = 50;
  151.         }
  152.  
  153.         //Desets Thrust & Gyro
  154.         //----------------------
  155.         for (int j = 0; j < CAF2_THRUST.Count; j++)
  156.         { (CAF2_THRUST[j] as IMyThrust).ThrustOverride = 0; } //(CAF2_THRUST[j] as IMyThrust).Enabled = true;
  157.  
  158.         //Runs Primary Mnining Logic (only if not 0,0,0)
  159.         //-------------------------------------------------
  160.         Echo("Status: " + MININGSTATUS.Val.ToString());
  161.         Echo("CurrentRoid: " + Vector3D.Round(StoredAsteroidLoc.Val));
  162.         Echo("CurrentCentre: " + Vector3D.Round(StoredAsteroidCentre.Val));
  163.         Echo("CurrentRoidSize: " + Math.Round(StoredAsteroidDiameter.Val) + " Metres");
  164.        // Echo("Is Vanilla RC A: " + Math.Round(StoredAsteroidDiameter.Val) + " Metres");
  165.         Echo("Outside Asteroid? " + ISNOTBURIED.Val);
  166.         Echo("Runtime: " + Math.Round(Runtime.LastRunTimeMs, 3) + " Ms");
  167.         Echo("Version: " + VERSION + "\n");
  168.  
  169.         MiningLogic(RC, DOCKLIST, GYRO, CONNECTOR, false);
  170.     }
  171.     catch (Exception e)
  172.     { Echo(e + ""); }
  173. }
  174.  
  175. //Function Specific Functions
  176. //============================
  177.  
  178. //Used For Mining Management
  179. /*=======================================================================================
  180.           Function: Mining Logic
  181.           ---------------------------------------
  182.           function will: The next generation of Rc manager, will automatically compensate for
  183.                          drifting to ensure the ship arrives on target quickly.
  184.         //----------==--------=------------=-----------=---------------=------------=-----=-----*/
  185. Savable_Vector StoredAsteroidLoc = new Savable_Vector();
  186. Savable_Vector StoredAsteroidCentre = new Savable_Vector();
  187. Savable_Double StoredAsteroidDiameter = new Savable_Double();
  188. Savable_Bool AbleToMine = new Savable_Bool();
  189. void MiningLogic(IMyRemoteControl RC, List<Vector3D> DOCK_ROUTE, IMyGyro GYRO, IMyShipConnector CONNECTOR, bool RESET)
  190. {
  191.     //Resets Function If A New Roid Is Detected
  192.     if (RESET)
  193.     {
  194.         StoredAsteroidDiameter.Val = 0;
  195.         StoredAsteroidCentre.Val = StoredAsteroidLoc.Val;
  196.         ROW.Val = 1;
  197.         COLUMN.Val = 1;
  198.         MININGSTATUS.Val = "MINE";
  199.         HASFINISHED.Val = false;
  200.         return;
  201.     }
  202.     Echo("Mining Logic:\n--------------");
  203.  
  204.     //Sets If Full Or Not
  205.     bool IsEmpty = (SHIP_DRILLS[0].GetInventory().CurrentMass < 100); //sets primary is empty
  206.     foreach (var CargoContainer in Cargo)
  207.     {
  208.         IMyInventory CurrentCargo = CargoContainer.GetInventory(0);
  209.         IsEmpty = CurrentCargo.CurrentMass > 900 ? false : IsEmpty;
  210.     }
  211.  
  212.     bool IsMassAboveThreshold = (double)SHIP_DRILLS[0].GetInventory().CurrentVolume > (double)SHIP_DRILLS[0].GetInventory().MaxVolume * 0.80;
  213.  
  214.     if (IsMassAboveThreshold) { Echo("Drill Inventory Is Currently Full"); }
  215.     if (IsEmpty) { Echo("Drill Inventory Is Currently Empty"); }
  216.  
  217.     //bool IsEmpty = (CONNECTOR.GetInventory().CurrentMass < 100); //SHIP_DRILLS[0].GetInventory().MaxVolume - SHIP_DRILLS[0].GetInventory().CurrentVolume > 10 ||
  218.     //bool IsMassAboveThreshold = CONNECTOR.GetInventory().CurrentMass > 200000; //use connector for time being
  219.     if (IsEmpty && MININGSTATUS.Val != "FIN")
  220.     { MININGSTATUS.Val = "MINE"; }
  221.     if (IsMassAboveThreshold && MININGSTATUS.Val != "FIN")
  222.     { MININGSTATUS.Val = "FULL"; HASFINISHED.Val = true; }
  223.     if(IsEmpty && CONNECTOR.Status == MyShipConnectorStatus.Connected)
  224.     { MININGSTATUS.Val = "DOCKED"; }
  225.     //Sets Drills:
  226.     if (SHIP_DRILLS[0].IsWorking == false && MININGSTATUS.Val == "MINE")
  227.     {
  228.         for (int j = 0; j < SHIP_DRILLS.Count; j++)
  229.         { (SHIP_DRILLS[j] as IMyShipDrill).Enabled = true; }
  230.     }
  231.     else if (SHIP_DRILLS[0].IsWorking == true && MININGSTATUS.Val != "MINE")
  232.     {
  233.         for (int j = 0; j < SHIP_DRILLS.Count; j++)
  234.         { (SHIP_DRILLS[j] as IMyShipDrill).Enabled = false; }
  235.     }
  236.  
  237.  
  238.     //If Full Go And Free Dock (stage 1)
  239.     if (MININGSTATUS.Val == "FULL" && ISNOTBURIED.Val)
  240.     {
  241.         RADIO.CustomName = "FULL";
  242.         DockingIterator(true, DOCK_ROUTE, GYRO, CONNECTOR, RC);
  243.         Echo("Status: Docking To Offload");
  244.         for (int j = 0; j < SHIP_DRILLS.Count; j++)
  245.         { (SHIP_DRILLS[j] as IMyShipDrill).Enabled = false; }
  246.         return;
  247.     }
  248.     //If Empty And Docked And Want To Go Mine, Undock (stage 2)
  249.     if (COORD_ID.Val != 0 && MININGSTATUS.Val == "DOCKED")
  250.     {
  251.         RADIO.CustomName = "Docked";
  252.         BatteryCharger(); // check battery and return status mining
  253.         if (!(MININGSTATUS.Val == "MINE"))
  254.         {
  255.             RADIO.CustomName = "Charging";
  256.             return;
  257.         }
  258.  
  259.     }
  260.     //If Empty And Docked And Want To Go Mine, Undock (stage 3)
  261.     if (COORD_ID.Val != 0 && MININGSTATUS.Val == "MINE")
  262.     {
  263.         DockingIterator(false, DOCK_ROUTE, GYRO, CONNECTOR, RC);
  264.         Echo("Status: Undocking");
  265.         RADIO.CustomName = "Undocking";
  266.         return;
  267.     }
  268.  
  269.     //If Fin, then Stop operations (stage 4)
  270.     if (MININGSTATUS.Val == "FIN" && ISNOTBURIED.Val)
  271.     {
  272.         RADIO.CustomName = "FIN";
  273.         DockingIterator(true, DOCK_ROUTE, GYRO, CONNECTOR, RC);
  274.         Echo("Status: Finished Task, Returning To Drop Off");
  275.         return;
  276.     }
  277.  
  278.     //Always Calls Mine Function If Undocked And Not Full
  279.     if (COORD_ID.Val == 0) //If Undocked
  280.     {
  281.  
  282.         //Uses Sensor To Update Information On Asteroid Within 250m of Selected Asteroid (prevents Close Proximity Asteroid Failure)
  283.         if (SENSOR.IsActive && (StoredAsteroidLoc.Val - RC.GetPosition()).Length() < 50 && StoredAsteroidCentre.Val == StoredAsteroidLoc.Val)
  284.         {
  285.             StoredAsteroidDiameter.Val = SENSOR.LastDetectedEntity.BoundingBox.Size.Length();
  286.             StoredAsteroidCentre.Val = SENSOR.LastDetectedEntity.BoundingBox.Center;
  287.         }
  288.  
  289.         //If No Asteroid Detected Goes To Location To Detect Asteroid
  290.         if (StoredAsteroidDiameter.Val == 0)
  291.         {
  292.             RADIO.CustomName = "Locating Asteroid";
  293.             RC_Manager(StoredAsteroidLoc.Val, RC, false);
  294.             return; //No Need For Remainder Of Logic
  295.         }
  296.  
  297.         //Toggles Should-be-Mining Based On Proximity
  298.         double Dist_To_Mine_Start = (StoredAsteroidLoc.Val - RC.GetPosition()).Length();
  299.         double Dist_To_Mine_Centre = (StoredAsteroidCentre.Val - RC.GetPosition()).Length();
  300.         if (Dist_To_Mine_Start < 4) //Toggles Mining Mode On
  301.         { AbleToMine.Val = true; }
  302.         if (Dist_To_Mine_Centre > StoredAsteroidDiameter.Val + 40) //Toggles Mining Mode Off
  303.         { AbleToMine.Val = false; }
  304.  
  305.         //Goes To Location And Mines
  306.         if (AbleToMine.Val == false)
  307.         {
  308.             RC_Manager(StoredAsteroidLoc.Val, RC, false);
  309.             ISNOTBURIED.Val = true;
  310.         }
  311.         else if (AbleToMine.Val == true)
  312.         {
  313.             double DistToDrill = Math.Sqrt(SHIP_DRILLS.Count) * 0.9; //Size of Ship
  314.             if (Me.CubeGrid.ToString().Contains("Large")) //if large grid
  315.             { DistToDrill = DistToDrill * 1.5; }
  316.             if (StoredAsteroidDiameter.Val > DistToDrill) //Only if drill size is bigger than ship 9prevents array handlign issues
  317.             { BoreMine(RC, StoredAsteroidLoc.Val, StoredAsteroidCentre.Val, StoredAsteroidDiameter.Val, DistToDrill, false); }
  318.             else { Echo("No Asteroid Detected, Drill array too large"); }
  319.         }
  320.  
  321.         Echo("Status: Mining");
  322.         RADIO.CustomName = "Mining";
  323.         //Echo(SHIP_DRILLS[0].GetInventory().MaxVolume + " Inventory Count"); // - SHIP_DRILLS[0].GetInventory().CurrentVolume +
  324.     }
  325.  
  326. }
  327.  
  328. //Used For Generic BoreMining
  329. /*=======================================================================================
  330.           Function: RC_MANAGER
  331.           ---------------------------------------
  332.           function will: The next generation of Rc manager, will automatically compensate for
  333.                          drifting to ensure the ship arrives on target quickly.
  334.         //----------==--------=------------=-----------=---------------=------------=-----=-----*/
  335. Savable_Int ROW = new Savable_Int();
  336. Savable_Int COLUMN = new Savable_Int();
  337. Savable_String MININGSTATUS = new Savable_String();
  338. Savable_Bool ISNOTBURIED = new Savable_Bool();
  339. Savable_Bool HASFINISHED = new Savable_Bool();
  340. List<IMyTerminalBlock> SHIP_DRILLS = new List<IMyTerminalBlock>();     //List Of all the ships drills
  341. List<IMyBatteryBlock> SHIP_BATT = new List<IMyBatteryBlock>();     //List Of all the ships drills
  342. void BoreMine(IMyRemoteControl RC, Vector3D ROID_START, Vector3D ROID_CENTRE, double ROID_DIAMETER, double SHIPSIZE, bool Reset)
  343. {
  344.  
  345.     //Setup Of Common Variables
  346.     Vector3D DronePosition = RC.GetPosition();
  347.     Vector3D Drone_To_Target = Vector3D.Normalize(ROID_CENTRE - DronePosition);
  348.  
  349.     //Generates XYZ Vectors
  350.     Vector3D X_ADD = Vector3D.Normalize(ROID_CENTRE - ROID_START);//Characteristic 'Forward' vector
  351.     Vector3D Y_ADD = Vector3D.CalculatePerpendicularVector(X_ADD); //Characteristic 'Left' vector
  352.     Vector3D Z_ADD = Vector3D.Cross(X_ADD, Y_ADD); //Characteristic 'Up' vector
  353.  
  354.     //Generates Array Of Starting Vectors
  355.     int Steps = MathHelper.Clamp((int)((ROID_DIAMETER * 0.3) / SHIPSIZE), 1, 16); //How many horizontal passes of the ship are required to eat the roid
  356.     double StepSize = SHIPSIZE;  //How big are those passes
  357.     Vector3D[,] GridCoords = new Vector3D[Steps + 1, Steps + 1]; //i as ROW.Val, j as COLUMN.Val
  358.     for (int i = 0; i < (Steps + 1); i++)
  359.     {
  360.         for (int j = 0; j < (Steps + 1); j++)
  361.         {
  362.             Vector3D Ipos = (Math.Pow(-1, i) == -1) ? ROID_START + StepSize * (i - 1) * -1 * Z_ADD : ROID_START + StepSize * i * Z_ADD;
  363.             Vector3D Jpos = (Math.Pow(-1, j) == -1) ? Ipos + StepSize * (j - 1) * -1 * Y_ADD : Ipos + StepSize * j * Y_ADD;
  364.             GridCoords[i, j] = Jpos;
  365.         }
  366.     }
  367.  
  368.     //Readouts
  369.     Echo("Has Finished Tunnel: " + HASFINISHED.Val); Echo(StepSize + " 'Step' Size");
  370.     Echo(ROW.Val + " /" + Steps + " Rows"); Echo(COLUMN.Val + " /" + Steps + " Columns"); //Echo((CurrentVectorEnd - DronePosition).Length() + " dist to iter++");
  371.  
  372.     //Generates Currently Targeted Vector As A Function Of 2 integers, ROW.Val and Depth
  373.     Vector3D CurrentVectorStart = GridCoords[ROW.Val, COLUMN.Val]; //Start Vector
  374.     Vector3D CurrentVectorEnd = CurrentVectorStart + X_ADD * (((ROID_CENTRE - ROID_START).Length() - ROID_DIAMETER / 2) + ROID_DIAMETER * 0.8); //Accounts for small input
  375.  
  376.     //Sets IsBuried And Has Finished
  377.     ISNOTBURIED.Val = (CurrentVectorStart - RC.GetPosition()).Length() < 4; //If Retracted Allows Switching Of Case
  378.     if ((CurrentVectorEnd - DronePosition).Length() < 1) { HASFINISHED.Val = true; } //If Reached End Toggle Finished
  379.  
  380.     //Inputs To Autopilot Function
  381.     double RollReqt = (float)(0.6 * (Vector3D.Dot(Z_ADD, RC.WorldMatrix.Down)));
  382.     GyroTurn6(X_ADD * 999999999999999999, RotationalSensitvity, GYRO, RC, RollReqt, PrecisionMaxAngularVel);
  383.  
  384.     if (HASFINISHED.Val) //Reverses Once Finished
  385.     { Vector_Thrust_Manager(CurrentVectorEnd, CurrentVectorStart, RC.GetPosition(), 2, 0.5, RC); }
  386.     else //else standard forward
  387.     { Vector_Thrust_Manager(CurrentVectorStart, CurrentVectorEnd, RC.GetPosition(), 1, 0.5, RC); }
  388.  
  389.     //Iterates Based On Proximity
  390.     if ((CurrentVectorStart - DronePosition).Length() < 1 && ROW.Val == Steps && COLUMN.Val == Steps && HASFINISHED.Val)
  391.     {
  392.         MININGSTATUS.Val = "FIN";
  393.         return;
  394.     }
  395.     if ((CurrentVectorStart - DronePosition).Length() < 1 && ROW.Val == Steps && HASFINISHED.Val)
  396.     { COLUMN.Val++; ROW.Val = 1; HASFINISHED.Val = false; }
  397.     if ((CurrentVectorStart - DronePosition).Length() < 1 && HASFINISHED.Val)
  398.     { ROW.Val++; HASFINISHED.Val = false; }
  399.  
  400. }
  401.  
  402. //Used For Docking And Undocking Of Ships
  403. /*====================================================================================================================================
  404.         Secondary Function: Dock Iterator
  405.         -----------------------------------------------------
  406.         Function will: Operate docking & undocking sequences for ships based on a Direct string Input
  407.         //-=--------------=-----------=-----------=-------------------=-------------------=----------------------=----------------------------*/
  408. Savable_Int COORD_ID = new Savable_Int(); //Current Docking ID
  409. void DockingIterator(bool Docking, List<Vector3D> COORDINATES, IMyGyro GYRO, IMyShipConnector CONNECTOR, IMyRemoteControl RC)
  410. {
  411.  
  412.     //Logic Check To Check Coords Are Within Limits
  413.     if (COORDINATES.Count < 3) { return; }
  414.  
  415.     //Changes Increment Based on Dock/Undock Requirement
  416.     int TargetID = 0;
  417.     int CurrentID = 0;
  418.     int iter_er = 0;
  419.     if (Docking == true)
  420.     { TargetID = 1; CurrentID = 0; iter_er = +1; RADIO.CustomName = "Docking"; }
  421.     if (Docking == false)
  422.     { TargetID = 0; CurrentID = 1; iter_er = -1; }
  423.  
  424.  
  425.     //Toggles State Of Thrusters Connectors And Gyros On The Ship
  426.     if (Docking == true) { CONNECTOR.Connect(); }
  427.     if (Docking == true && CONNECTOR.IsWorking == false) { CONNECTOR.Enabled = true; }
  428.     if (Docking == false && CONNECTOR.IsWorking == true) { CONNECTOR.Disconnect(); CONNECTOR.Enabled = true; }
  429.     if (CONNECTOR.Status == MyShipConnectorStatus.Connected && Docking == true)
  430.     {
  431.         //for (int j = 0; j < CAF2_THRUST.Count; j++)
  432.         //{(CAF2_THRUST[j] as IMyThrust).Enabled = false; }
  433.         GYRO.GyroOverride = false;
  434.         return;
  435.     }
  436.  
  437.     //Setting Up a Few Constants
  438.     Vector3D RollOrienter = Vector3D.Normalize(COORDINATES[COORDINATES.Count - 1] - COORDINATES[COORDINATES.Count - 2]);
  439.     Vector3D Connector_Direction = -1 * ReturnConnectorDirection(CONNECTOR, RC);
  440.     double RollReqt = (float)(0.6 * (Vector3D.Dot(RollOrienter, Connector_Direction)));
  441.  
  442.     //Vertical Motion During Dock
  443.     if (COORD_ID.Val == COORDINATES.Count - 1)
  444.     {
  445.         Vector3D DockingHeading = Vector3D.Normalize(COORDINATES[COORDINATES.Count - 3] - COORDINATES[COORDINATES.Count - 2]) * 9000000; //Heading
  446.         GyroTurn6(DockingHeading, RotationalSensitvity, GYRO, RC, RollReqt, PrecisionMaxAngularVel); //Turn to heading
  447.         if (Vector3D.Dot(RC.WorldMatrix.Forward, Vector3D.Normalize(DockingHeading)) > 0.98) //Error check for small rotational velocity
  448.         { Vector_Thrust_Manager(COORDINATES[COORD_ID.Val - TargetID], COORDINATES[COORD_ID.Val - CurrentID], CONNECTOR.GetPosition(), 5, 0.7, RC); }  //Thrusts to point
  449.     }
  450.  
  451.     //Last/First External Coord During Dock
  452.     else if (COORD_ID.Val == 0)
  453.     { RC_Manager(COORDINATES[0], RC, false); }  //Standard Auto for first location
  454.  
  455.     //Horizontal And Iterative Statement
  456.     else
  457.     {
  458.         var HEADING = Vector3D.Normalize(COORDINATES[COORD_ID.Val - CurrentID] - COORDINATES[COORD_ID.Val - TargetID]) * 9000000;
  459.         Vector_Thrust_Manager(COORDINATES[COORD_ID.Val - TargetID], COORDINATES[COORD_ID.Val - CurrentID], CONNECTOR.GetPosition(), 8, 1, RC); //Runs docking sequence
  460.         GyroTurn6(HEADING, RotationalSensitvity, GYRO, RC, RollReqt, PrecisionMaxAngularVel);
  461.     }
  462.  
  463.     //Logic checks and iterates
  464.     if (Docking == false && COORD_ID.Val == 0) { }
  465.     else if ((CONNECTOR.GetPosition() - COORDINATES[COORD_ID.Val - CurrentID]).Length() < 1 || ((RC.GetPosition() - COORDINATES[COORD_ID.Val - CurrentID]).Length() < 10 && COORD_ID.Val == 0))
  466.     {
  467.         COORD_ID.Val = COORD_ID.Val + iter_er;
  468.         if (COORD_ID.Val == COORDINATES.Count)
  469.         { COORD_ID.Val = COORDINATES.Count - 1; }
  470.         if (COORD_ID.Val < 0)
  471.         { COORD_ID.Val = 0; }
  472.     }
  473. }
  474. //----------==--------=------------=-----------=---------------=------------=-------==--------=------------=-----------=----------
  475.  
  476.  
  477. //Standardised First Time Setup
  478. /*====================================================================================================================
  479.         Function: FIRST_TIME_SETUP
  480.         ---------------------------------------
  481.         function will: Initiates Systems and initiasing Readouts to LCD
  482.         Performance Cost:
  483.        //======================================================================================================================*/
  484. //SUBCATEGORY STORED BLOCKS
  485. IMyRemoteControl RC;
  486. IMyShipConnector CONNECTOR;
  487. //IMyTimerBlock TIMER;
  488. IMySensorBlock SENSOR;
  489. List<IMyLargeTurretBase> DIRECTORS = new List<IMyLargeTurretBase>();
  490. IMyRadioAntenna RADIO;
  491. IMyGyro GYRO;
  492. List<IMyTerminalBlock> CONTROLLERS = new List<IMyTerminalBlock>();
  493. List<IMyTerminalBlock> Cargo = new List<IMyTerminalBlock>();
  494. List<IMyTerminalBlock> DIRECTIONAL_FIRE = new List<IMyTerminalBlock>();  //Directional ship weaponry
  495. string Prefix = "ADM";
  496.  
  497. void FirstTimeSetup()
  498. {
  499.     //Gathers Key Components
  500.     //-----------------------------------
  501.     //Sets Update Frequency
  502.     Runtime.UpdateFrequency = UpdateFrequency.Update10;
  503.     Me.CustomName = Prefix + " PB";
  504.     //Gathers Remote Control
  505.     try
  506.     {
  507.         List<IMyTerminalBlock> TEMP_RC = new List<IMyTerminalBlock>();
  508.         GridTerminalSystem.GetBlocksOfType<IMyRemoteControl>(TEMP_RC, b => b.CubeGrid == Me.CubeGrid);
  509.         RC = TEMP_RC[0] as IMyRemoteControl;
  510.     }
  511.     catch { }
  512.     RC.CustomName = Prefix + " RC";
  513.     //GathersConnector
  514.     try
  515.     {
  516.         List<IMyTerminalBlock> TEMP_CON = new List<IMyTerminalBlock>();
  517.         GridTerminalSystem.GetBlocksOfType<IMyShipConnector>(TEMP_CON, b => b.CubeGrid == Me.CubeGrid && b.CustomName.Contains("Ejector") == false);
  518.         CONNECTOR = TEMP_CON[0] as IMyShipConnector;
  519.     }
  520.     catch { }
  521.     CONNECTOR.CustomName = Prefix + " Connector";
  522.     try
  523.     {
  524.         GridTerminalSystem.GetBlocksOfType<IMyBatteryBlock>(SHIP_BATT, b => b.CubeGrid == Me.CubeGrid);
  525.     }
  526.     catch { }
  527.     for (int j = 0; j < SHIP_BATT.Count; j++)
  528.     { (SHIP_BATT[j] as IMyBatteryBlock).CustomName = Prefix + " Battery " + j.ToString(); }
  529.     /*
  530.             //Sets Timer
  531.             try
  532.             {
  533.                 List<IMyTerminalBlock> TEMP_TIMER = new List<IMyTerminalBlock>();
  534.                 GridTerminalSystem.GetBlocksOfType<IMyTimerBlock>(TEMP_TIMER, b => b.CubeGrid == Me.CubeGrid);
  535.                 TIMER = TEMP_TIMER[0] as IMyTimerBlock;
  536.             }
  537.             catch { }
  538.             TIMER.CustomName = Prefix + " Timer";
  539.             */
  540.     //Sets Gyro
  541.     try
  542.     {
  543.         List<IMyTerminalBlock> TEMP_GYRO = new List<IMyTerminalBlock>();
  544.         GridTerminalSystem.GetBlocksOfType<IMyGyro>(TEMP_GYRO, b => b.CubeGrid == Me.CubeGrid);
  545.         GYRO = TEMP_GYRO[0] as IMyGyro;
  546.     }
  547.     catch { }
  548.     GYRO.CustomName = Prefix + " Gyro";
  549.     //Sets Sensor
  550.     try
  551.     {
  552.         List<IMyTerminalBlock> TEMP_SENSOR = new List<IMyTerminalBlock>();
  553.         GridTerminalSystem.GetBlocksOfType<IMySensorBlock>(TEMP_SENSOR, b => b.CubeGrid == Me.CubeGrid);
  554.         SENSOR = TEMP_SENSOR[0] as IMySensorBlock;
  555.     }
  556.     catch { }
  557.     SENSOR.CustomName = Prefix + " Sensor";
  558.     //Initialising Dedicated Cargo
  559.     try
  560.     {
  561.         GridTerminalSystem.GetBlocksOfType<IMyCargoContainer>(Cargo, b => b.CubeGrid == Me.CubeGrid);
  562.     }
  563.     catch
  564.     { }
  565.  
  566.     //Gathers Antennae
  567.     try
  568.     {
  569.         List<IMyTerminalBlock> TEMP = new List<IMyTerminalBlock>();
  570.         GridTerminalSystem.GetBlocksOfType<IMyRadioAntenna>(TEMP, b => b.CubeGrid == Me.CubeGrid);
  571.         RADIO = TEMP[0] as IMyRadioAntenna;
  572.         RADIO.SetValue<long>("PBList", Me.EntityId);
  573.         RADIO.EnableBroadcasting = true;
  574.         RADIO.Enabled = true;
  575.     }
  576.     catch { }
  577.  
  578.     //GathersControllers
  579.     try
  580.     {
  581.         GridTerminalSystem.GetBlocksOfType<IMyShipController>(CONTROLLERS, b => b.CubeGrid == Me.CubeGrid);
  582.     }
  583.     catch { }
  584.  
  585.     //Gathers Director Turret
  586.     try
  587.     {
  588.         GridTerminalSystem.GetBlocksOfType<IMyLargeTurretBase>(DIRECTORS, b => b.CubeGrid == Me.CubeGrid);
  589.     }
  590.     catch { }
  591.  
  592.     //Gathers Drills
  593.     try
  594.     {
  595.         GridTerminalSystem.GetBlocksOfType<IMyShipDrill>(SHIP_DRILLS, b => b.CubeGrid == Me.CubeGrid);
  596.     }
  597.     catch { }
  598.  
  599.     //Gathers Directional Weaponry
  600.     try
  601.     {
  602.         GridTerminalSystem.GetBlocksOfType<IMyUserControllableGun>(DIRECTIONAL_FIRE,
  603.             (block => block.GetType().Name == "MySmallMissileLauncher" || block.GetType().Name == "MySmallGatlingGun"
  604.                 || block.GetType().Name == "MySmallMissileLauncherReload")); //Collects the directional weaponry (in a group)
  605.     }
  606.     catch { }
  607.  
  608.     //Runs Thruster Setup
  609.     try
  610.     {
  611.         CollectAndFire2(new Vector3D(), 0, 0, RC.GetPosition(), RC);
  612.         for (int j = 0; j < CAF2_THRUST.Count; j++)
  613.         { CAF2_THRUST[j].SetValue<float>("Override", 0.0f); CAF2_THRUST[j].ApplyAction("OnOff_On"); }
  614.     }
  615.     catch { }
  616.  
  617.     //Loads Saved Data
  618.     try
  619.     {
  620.         //Retrieves And Deserializes Saved Data
  621.         //string DataInput = Me.CustomData;
  622.         DeSerializer(Storage);
  623.     }
  624.     catch
  625.     { }
  626.  
  627.     //Creates User Interface
  628.     try
  629.     {
  630.         Me.CustomData = "Paste Asteroid GPS Here: \n===========================\n@" + "GPS:Mine:" + StoredAsteroidLoc.Val.X + ":" + StoredAsteroidLoc.Val.Y + ":" + StoredAsteroidLoc.Val.Z +
  631.             "@\n\nInstructions:\n===========================\nPaste GPS coords of point no closer than 30m to asteroid\nbetween the symbols." +
  632.             "\nDo NOT include the 'at' symbol in the GPS name\nErrors Will be displayed in the terminal\n\n" +
  633.             "Hints/Tips:\n===========================\n" +
  634.             "-Look at the antena for live mining progress\n" +
  635.             "-Paste GPS near the ore you want collected for faster mining\n" +
  636.             "-NEVER paste a GPS from inside an asteroid \n" +
  637.             "-Rename any connectors you don't want the code\n to use as docking points as 'Ejector' \n" +
  638.             "-The code uses the GPS as a starting point so for\n larger ships keep this GPS further away from the asteroid\n" +
  639.             "-The miner will remember the orientation you dock with \n so remember to dock in the direction you want to launch\n" +
  640.             "-You can reassign docking coordinates at any point\n by manually overriding and docking somewhere else \n" +
  641.             "-To return miner to base \n run the PB with the argument 'RETURN'";
  642.     }
  643.     catch
  644.     { }
  645.  
  646. }
  647.  
  648. void SaveCode()
  649. {
  650.     //Serializes Savable Data
  651.     //Me.CustomData = Serializer();
  652.     Storage = Serializer();
  653. }
  654.  
  655. //Used For Automatic Dockpoint Recognition
  656. /*=======================================================================================
  657.           Function: Auto-DockpointDetect
  658.           ---------------------------------------
  659.           function will: Automatically detect dockpoints for usage
  660.         //----------==--------=------------=-----------=---------------=------------=-----=-----*/
  661. Savable_Vector DockPos1 = new Savable_Vector(); //Conncetor Location
  662. Savable_Vector DockPos2 = new Savable_Vector(); //Straight Up Location
  663. Savable_Vector DockPos3 = new Savable_Vector(); //Straight Up And Forward Location
  664. IMyShipConnector OtherTempConnector;
  665.  
  666. void Auto_DockpointDetect()
  667. {
  668.     //if Docked Only And A new Dockpoint Assign New Dockpoint
  669.     if (CONNECTOR.Status == MyShipConnectorStatus.Connected)
  670.     {
  671.         OtherTempConnector = CONNECTOR.OtherConnector;
  672.         DockPos1.Val = OtherTempConnector.GetPosition() + OtherTempConnector.WorldMatrix.Forward * (0.75);
  673.         DockPos2.Val = OtherTempConnector.GetPosition() + OtherTempConnector.WorldMatrix.Forward * (6);
  674.         DockPos3.Val = DockPos2.Val + RC.WorldMatrix.Forward * 40;
  675.         COORD_ID.Val = 2;
  676.     }
  677.  
  678.     //If Other Connector Is not Null Reassign Docking Coordinates
  679.     if (OtherTempConnector != null)
  680.     {
  681.  
  682.     }
  683.  
  684. }
  685.  
  686. //Primary Generic Functions
  687. //==========================
  688.  
  689. //Use For General Drone Flying:
  690. /*=======================================================================================
  691.           Function: RC_MANAGER
  692.           ---------------------------------------
  693.           function will: The next generation of Rc manager, will automatically compensate for
  694.                          drifting to ensure the ship arrives on target quickly.
  695.         //----------==--------=------------=-----------=---------------=------------=-----=-----*/
  696. void RC_Manager(Vector3D TARGET, IMyRemoteControl RC, bool TURN_ONLY)
  697. {
  698.     //Uses Rotation Control To Handle Max Rotational Velocity
  699.     //---------------------------------------------------------
  700.     if (RC.GetShipVelocities().AngularVelocity.AbsMax() > PrecisionMaxAngularVel)
  701.     { Echo("Slowing Rotational Velocity"); RC.SetAutoPilotEnabled(false); return; }
  702.  
  703.     //Setup Of Common Variables
  704.     //--------------------------------------------
  705.     Vector3D DronePosition = RC.GetPosition();
  706.     Vector3D Drone_To_Target = Vector3D.Normalize(TARGET - DronePosition);
  707.  
  708.     //Override Direction Detection
  709.     //-------------------------------
  710.     double To_Target_Angle = Vector3D.Dot(Vector3D.Normalize(RC.GetShipVelocities().LinearVelocity), Drone_To_Target);
  711.     double Ship_Velocity = RC.GetShipVelocities().LinearVelocity.Length();
  712.  
  713.     //int i = 0; //counting
  714.  
  715.     //Turn Only: (Will drift ship automatically)
  716.     //--------------------------------------------
  717.     if (TURN_ONLY)
  718.     {
  719.         RC.ClearWaypoints();
  720.         RC.AddWaypoint(TARGET, "1");
  721.         RC.AddWaypoint(TARGET, "cc1");
  722.         RC.ApplyAction("AutoPilot_On");
  723.         RC.ApplyAction("CollisionAvoidance_Off");
  724.         RC.ControlThrusters = false;
  725.         /*
  726.                 while (i < 10)
  727.                 {
  728.                  i++;
  729.                 }
  730.                 i = 0;
  731.                 */
  732.         return;
  733.     }
  734.  
  735.     //Drift Cancellation Enabled:
  736.     //-----------------------------
  737.     if (To_Target_Angle < 0.4 && Ship_Velocity > 3)
  738.     {
  739.         Echo("Drift Cancellation Enabled");
  740.  
  741.         //Aim Gyro To Reflected Vector
  742.         Vector3D DRIFT_VECTOR = Vector3D.Normalize(RC.GetShipVelocities().LinearVelocity);
  743.         Vector3D REFLECTED_DRIFT_VECTOR = -1 * (Vector3D.Normalize(Vector3D.Reflect(DRIFT_VECTOR, Drone_To_Target)));
  744.         Vector3D AIMPINGPOS = (-1 * DRIFT_VECTOR * 500) + DronePosition;
  745.  
  746.         //Sets Autopilot To Turn
  747.         RC.ClearWaypoints();
  748.         RC.AddWaypoint(AIMPINGPOS, "1");
  749.         RC.AddWaypoint(AIMPINGPOS, "cc1");
  750.         RC.ApplyAction("AutoPilot_On");
  751.         RC.ApplyAction("CollisionAvoidance_Off");
  752.  
  753.         /*
  754.                 while (i < 10)
  755.                 {
  756.                  i++;
  757.                 }
  758.                 i = 0;
  759.                 */
  760.     }
  761.  
  762.     //System Standard Operation:
  763.     //---------------------------
  764.     else
  765.     {
  766.         Echo("Drift Cancellation Disabled");
  767.  
  768.         //Assign To RC, Clear And Refresh Command
  769.         RC.ClearWaypoints();
  770.         RC.ControlThrusters = true;
  771.         RC.AddWaypoint(TARGET, "1");
  772.         RC.AddWaypoint(TARGET, "cc1");
  773.         RC.ApplyAction("AutoPilot_On");                   //RC toggle
  774.         RC.ApplyAction("DockingMode_Off");                //Precision Mode
  775.         RC.ApplyAction("CollisionAvoidance_On");          //Col avoidance
  776.  
  777.     }
  778.  
  779. }
  780.  
  781. //Use For Precise Turning (docking, mining, attacking)
  782. /*=======================================================================================
  783.           Function: GyroTurn6
  784.           ---------------------------------------
  785.           function will: The next generation of Gyroturn, designed to be performance optimised
  786.                          over actuating performance, it detects orientation and directly applies overrides
  787.         //----------==--------=------------=-----------=---------------=------------=-----=-----*/
  788. void GyroTurn6(Vector3D TARGET, double GAIN, IMyGyro GYRO, IMyRemoteControl REF_RC, double ROLLANGLE, double MAXANGULARVELOCITY)
  789. {
  790.     //Ensures Autopilot Not Functional
  791.     REF_RC.SetAutoPilotEnabled(false);
  792.     Echo("Running Gyro Control Program");
  793.  
  794.     //Detect Forward, Up & Pos
  795.     Vector3D ShipForward = REF_RC.WorldMatrix.Forward;
  796.     Vector3D ShipUp = REF_RC.WorldMatrix.Up;
  797.     Vector3D ShipPos = REF_RC.GetPosition();
  798.  
  799.     //Create And Use Inverse Quatinion
  800.     Quaternion Quat_Two = Quaternion.CreateFromForwardUp(ShipForward, ShipUp);
  801.     var InvQuat = Quaternion.Inverse(Quat_Two);
  802.     Vector3D DirectionVector = Vector3D.Normalize(TARGET - ShipPos); //RealWorld Target Vector
  803.     Vector3D RCReferenceFrameVector = Vector3D.Transform(DirectionVector, InvQuat); //Target Vector In Terms Of RC Block
  804.  
  805.     //Convert To Local Azimuth And Elevation
  806.     double ShipForwardAzimuth = 0; double ShipForwardElevation = 0;
  807.     Vector3D.GetAzimuthAndElevation(RCReferenceFrameVector, out ShipForwardAzimuth, out ShipForwardElevation);
  808.  
  809.     //Does Some Rotations To Provide For any Gyro-Orientation
  810.     var RC_Matrix = REF_RC.WorldMatrix.GetOrientation();
  811.     var Vector = Vector3.Transform((new Vector3D(ShipForwardElevation, ShipForwardAzimuth, ROLLANGLE)), RC_Matrix); //Converts To World
  812.     var TRANS_VECT = Vector3.Transform(Vector, Matrix.Transpose(GYRO.WorldMatrix.GetOrientation()));  //Converts To Gyro Local
  813.  
  814.     //Applies To Scenario
  815.     GYRO.Pitch = (float)MathHelper.Clamp((-TRANS_VECT.X * GAIN), -MAXANGULARVELOCITY, MAXANGULARVELOCITY);
  816.     GYRO.Yaw = (float)MathHelper.Clamp(((-TRANS_VECT.Y) * GAIN), -MAXANGULARVELOCITY, MAXANGULARVELOCITY);
  817.     GYRO.Roll = (float)MathHelper.Clamp(((-TRANS_VECT.Z) * GAIN), -MAXANGULARVELOCITY, MAXANGULARVELOCITY);
  818.     GYRO.GyroOverride = true;
  819.  
  820.     //GYRO.SetValueFloat("Pitch", (float)((TRANS_VECT.X) * GAIN));
  821.     //GYRO.SetValueFloat("Yaw", (float)((-TRANS_VECT.Y) * GAIN));
  822.     //GYRO.SetValueFloat("Roll", (float)((-TRANS_VECT.Z) * GAIN));
  823. }
  824.  
  825. //Use For Precise Thrusting (docking, mining, attacking)
  826. /*=======================================================================================
  827.           Function: COLLECT_AND_FIRE
  828.           ---------------------------------------
  829.           function will: Collect thrust pointing in a input direction and fire said thrust
  830.                          towards that point, remember to deset
  831.         //----------==--------=------------=-----------=---------------=------------=-----=-----*/
  832. class Thrust_info                   //Basic Information For Axial Thrust
  833. {
  834.     public double PositiveMaxForce;
  835.     public double NegativeMaxForce;
  836.     public List<IMyThrust> PositiveThrusters;
  837.     public List<IMyThrust> NegativeThrusters;
  838.     public double VCF;
  839.     public Thrust_info(Vector3D DIRECT, IMyGridTerminalSystem GTS, IMyCubeGrid MEGRID)
  840.     {
  841.         PositiveThrusters = new List<IMyThrust>(); NegativeThrusters = new List<IMyThrust>();
  842.         List<IMyTerminalBlock> TEMP_RC = new List<IMyTerminalBlock>();
  843.         GTS.GetBlocksOfType<IMyThrust>(PositiveThrusters, block => Vector3D.Dot(-1 * block.WorldMatrix.Forward, DIRECT) > 0.7 && block.CubeGrid == MEGRID);
  844.         GTS.GetBlocksOfType<IMyThrust>(NegativeThrusters, block => Vector3D.Dot(block.WorldMatrix.Forward, DIRECT) > 0.7 && block.CubeGrid == MEGRID);
  845.         double POWER_COUNT = 0;
  846.         foreach (var item in PositiveThrusters)
  847.         { POWER_COUNT = POWER_COUNT + item.MaxEffectiveThrust; }
  848.         PositiveMaxForce = POWER_COUNT;
  849.         POWER_COUNT = 0;
  850.         foreach (var item in NegativeThrusters)
  851.         { POWER_COUNT = POWER_COUNT + item.MaxEffectiveThrust; }
  852.         NegativeMaxForce = POWER_COUNT;
  853.     }
  854. }
  855. Thrust_info CAF2_FORWARD;
  856. Thrust_info CAF2_UP;
  857. Thrust_info CAF2_RIGHT;
  858. List<Thrust_info> CAFTHI = new List<Thrust_info>();
  859.  
  860. List<IMyTerminalBlock> CAF2_THRUST = new List<IMyTerminalBlock>();
  861. bool C_A_F_HASRUN = false;
  862. double CAF2_BRAKING_COUNT = 99999999;
  863.  
  864. double CAF_SHIP_DECELLERATION;                        //Outputs current decelleration
  865. double CAF_STOPPING_DIST;                             //Outputs current stopping distance
  866. double CAF_DIST_TO_TARGET;                            //Outputs distance to target
  867.  
  868. void CollectAndFire2(Vector3D INPUT_POINT, double INPUT_VELOCITY, double INPUT_MAX_VELOCITY, Vector3D REFPOS, IMyRemoteControl RC)
  869. {
  870.     //Function Initialisation
  871.     //--------------------------------------------------------------------
  872.     if (C_A_F_HASRUN == false)
  873.     {
  874.         //Initialise Classes And Basic System
  875.         CAF2_FORWARD = new Thrust_info(RC.WorldMatrix.Forward, GridTerminalSystem, Me.CubeGrid);
  876.         CAF2_UP = new Thrust_info(RC.WorldMatrix.Up, GridTerminalSystem, Me.CubeGrid);
  877.         CAF2_RIGHT = new Thrust_info(RC.WorldMatrix.Right, GridTerminalSystem, Me.CubeGrid);
  878.         CAFTHI = new List<Thrust_info>() { CAF2_FORWARD, CAF2_UP, CAF2_RIGHT };
  879.         GridTerminalSystem.GetBlocksOfType<IMyThrust>(CAF2_THRUST, block => block.CubeGrid == Me.CubeGrid);
  880.         C_A_F_HASRUN = true;
  881.  
  882.         //Initialises Braking Component
  883.         foreach (var item in CAFTHI)
  884.         {
  885.             CAF2_BRAKING_COUNT = (item.PositiveMaxForce < CAF2_BRAKING_COUNT) ? item.PositiveMaxForce : CAF2_BRAKING_COUNT;
  886.             CAF2_BRAKING_COUNT = (item.NegativeMaxForce < CAF2_BRAKING_COUNT) ? item.PositiveMaxForce : CAF2_BRAKING_COUNT;
  887.         }
  888.     }
  889.     Echo("Running Thruster Control Program");
  890.  
  891.     //Generating Maths To Point and decelleration information etc.
  892.     //--------------------------------------------------------------------
  893.     double SHIPMASS = Convert.ToDouble(RC.CalculateShipMass().PhysicalMass);
  894.     Vector3D INPUT_VECTOR = Vector3D.Normalize(INPUT_POINT - REFPOS);
  895.     double VELOCITY = RC.GetShipSpeed();
  896.     CAF_DIST_TO_TARGET = (REFPOS - INPUT_POINT).Length();
  897.     CAF_SHIP_DECELLERATION = 0.75 * (CAF2_BRAKING_COUNT / SHIPMASS);
  898.     CAF_STOPPING_DIST = (((VELOCITY * VELOCITY) - (INPUT_VELOCITY * INPUT_VELOCITY))) / (2 * CAF_SHIP_DECELLERATION);
  899.  
  900.     //If Within Stopping Distance Halts Programme
  901.     //--------------------------------------------
  902.     if (!(CAF_DIST_TO_TARGET > (CAF_STOPPING_DIST + 0.25)) || CAF_DIST_TO_TARGET < 0.25 || VELOCITY > INPUT_MAX_VELOCITY)
  903.     { foreach (var thruster in CAF2_THRUST) { (thruster as IMyThrust).ThrustOverride = 0; } return; }
  904.     //dev notes, this is the most major source of discontinuity between theorised system response
  905.  
  906.     //Reflects Vector To Cancel Orbiting
  907.     //------------------------------------
  908.     Vector3D DRIFT_VECTOR = Vector3D.Normalize(RC.GetShipVelocities().LinearVelocity + RC.WorldMatrix.Forward * 0.00001);
  909.     Vector3D R_DRIFT_VECTOR = -1 * Vector3D.Normalize(Vector3D.Reflect(DRIFT_VECTOR, INPUT_VECTOR));
  910.     R_DRIFT_VECTOR = ((Vector3D.Dot(R_DRIFT_VECTOR, INPUT_VECTOR) < -0.3)) ? 0 * R_DRIFT_VECTOR : R_DRIFT_VECTOR;
  911.     INPUT_VECTOR = Vector3D.Normalize((4 * R_DRIFT_VECTOR) + INPUT_VECTOR);
  912.  
  913.     //Components Of Input Vector In FUR Axis
  914.     //----------------------------------------
  915.     double F_COMP_IN = Vector_Projection(INPUT_VECTOR, RC.WorldMatrix.Forward);
  916.     double U_COMP_IN = Vector_Projection(INPUT_VECTOR, RC.WorldMatrix.Up);
  917.     double R_COMP_IN = Vector_Projection(INPUT_VECTOR, RC.WorldMatrix.Right);
  918.  
  919.     //Calculate MAX Allowable in Each Axis & Length
  920.     //-----------------------------------------------
  921.     double F_COMP_MAX = (F_COMP_IN > 0) ? CAF2_FORWARD.PositiveMaxForce : -1 * CAF2_FORWARD.NegativeMaxForce;
  922.     double U_COMP_MAX = (U_COMP_IN > 0) ? CAF2_UP.PositiveMaxForce : -1 * CAF2_UP.NegativeMaxForce;
  923.     double R_COMP_MAX = (R_COMP_IN > 0) ? CAF2_RIGHT.PositiveMaxForce : -1 * CAF2_RIGHT.NegativeMaxForce;
  924.     double MAX_FORCE = Math.Sqrt(F_COMP_MAX * F_COMP_MAX + U_COMP_MAX * U_COMP_MAX + R_COMP_MAX * R_COMP_MAX);
  925.  
  926.     //Apply Length to Input Components and Calculates Smallest Multiplier
  927.     //--------------------------------------------------------------------
  928.     double F_COMP_PROJ = F_COMP_IN * MAX_FORCE;
  929.     double U_COMP_PROJ = U_COMP_IN * MAX_FORCE;
  930.     double R_COMP_PROJ = R_COMP_IN * MAX_FORCE;
  931.     double MULTIPLIER = 1;
  932.     MULTIPLIER = (F_COMP_MAX / F_COMP_PROJ < MULTIPLIER) ? F_COMP_MAX / F_COMP_PROJ : MULTIPLIER;
  933.     MULTIPLIER = (U_COMP_MAX / U_COMP_PROJ < MULTIPLIER) ? U_COMP_MAX / U_COMP_PROJ : MULTIPLIER;
  934.     MULTIPLIER = (R_COMP_MAX / R_COMP_PROJ < MULTIPLIER) ? R_COMP_MAX / R_COMP_PROJ : MULTIPLIER;
  935.  
  936.     //Calculate Multiplied Components
  937.     //---------------------------------
  938.     CAF2_FORWARD.VCF = ((F_COMP_PROJ * MULTIPLIER) / F_COMP_MAX) * Math.Sign(F_COMP_MAX);
  939.     CAF2_UP.VCF = ((U_COMP_PROJ * MULTIPLIER) / U_COMP_MAX) * Math.Sign(U_COMP_MAX);
  940.     CAF2_RIGHT.VCF = ((R_COMP_PROJ * MULTIPLIER) / R_COMP_MAX) * Math.Sign(R_COMP_MAX);
  941.  
  942.     //Runs System Thrust Application
  943.     //----------------------------------
  944.     Dictionary<IMyThrust, float> THRUSTVALUES = new Dictionary<IMyThrust, float>();
  945.     foreach (var thruster in CAF2_THRUST) { THRUSTVALUES.Add((thruster as IMyThrust), 0f); }
  946.  
  947.     foreach (var THRUSTSYSTM in CAFTHI)
  948.     {
  949.         List<IMyThrust> POSTHRUST = THRUSTSYSTM.PositiveThrusters;
  950.         List<IMyThrust> NEGTHRUST = THRUSTSYSTM.NegativeThrusters;
  951.         if (THRUSTSYSTM.VCF < 0) { POSTHRUST = THRUSTSYSTM.NegativeThrusters; NEGTHRUST = THRUSTSYSTM.PositiveThrusters; }
  952.         foreach (var thruster in POSTHRUST) { THRUSTVALUES[thruster as IMyThrust] = (float)(Math.Abs(THRUSTSYSTM.VCF)) * (thruster as IMyThrust).MaxThrust; }
  953.         foreach (var thruster in NEGTHRUST) { THRUSTVALUES[thruster as IMyThrust] = 1; }//(float)0.01001;}
  954.         foreach (var thruster in THRUSTVALUES) { thruster.Key.ThrustOverride = thruster.Value; } //thruster.Key.ThrustOverride = thruster.Value;
  955.     }
  956. }
  957. //----------==--------=------------=-----------=---------------=------------=-------==--------=-----
  958.  
  959. //Used For Precise Thrusting Along A Vector (docking, mining, attacking)
  960. /*====================================================================================================================================
  961.         Secondary Function: PRECISION MANAGER
  962.         -----------------------------------------------------
  963.         Function will: Given two inputs manage vector-based thrusting
  964.         Inputs: DIRECTION, BLOCK
  965.         //-=--------------=-----------=-----------=-------------------=-------------------=----------------------=----------------------------*/
  966. void Vector_Thrust_Manager(Vector3D PM_START, Vector3D PM_TARGET, Vector3D PM_REF, double PR_MAX_VELOCITY, double PREC, IMyRemoteControl RC)
  967. {
  968.     Vector3D VECTOR = Vector3D.Normalize(PM_START - PM_TARGET);
  969.     Vector3D GOTOPOINT = PM_TARGET + VECTOR * MathHelper.Clamp((((PM_REF - PM_TARGET).Length() - 0.2)), 0, (PM_START - PM_TARGET).Length());
  970.     double DIST_TO_POINT = MathHelper.Clamp((GOTOPOINT - PM_REF).Length(), 0, (PM_START - PM_TARGET).Length());
  971.  
  972.     if (DIST_TO_POINT > PREC)
  973.     { CollectAndFire2(GOTOPOINT, 0, PR_MAX_VELOCITY * 2, PM_REF, RC); }
  974.     else
  975.     { CollectAndFire2(PM_TARGET, 0, PR_MAX_VELOCITY, PM_REF, RC); }
  976. }
  977. //----------==--------=------------=-----------=---------------=------------=-------==--------=------------=-----------=----------
  978.  
  979. //Use For Magnitudes Of Vectors In Directions
  980. /*=================================================
  981.           Function: Vector Projection Useful For Generic
  982.                     quantity in direction algorithms
  983.           ---------------------------------------     */
  984. double Vector_Projection(Vector3D IN, Vector3D Axis)
  985. {
  986.     double OUT = 0;
  987.     OUT = Vector3D.Dot(IN, Axis) / IN.Length();
  988.     if (OUT + "" == "NaN")
  989.     { OUT = 0; }
  990.     return OUT;
  991. }
  992.  
  993. //Use For General Display
  994. /*=================================================
  995.           Function: RFC Function bar #RFC#
  996.           ---------------------------------------     */
  997. string[] FUNCTION_BAR = new string[] { "", " ===||===", " ==|==|==", " =|====|=", " |======|", "  ======" };
  998. int FUNCTION_TIMER = 0;                                     //For Runtime Indicator
  999. void OP_BAR()
  1000. {
  1001.     FUNCTION_TIMER++;
  1002.     Echo("     ~ V" + VERSION.ToString() +" ADM AI Running~  \n               " + FUNCTION_BAR[FUNCTION_TIMER] + "");
  1003.     if (FUNCTION_TIMER == 5) { FUNCTION_TIMER = 0; }
  1004. }
  1005.  
  1006. //Returns Connector Orientation As A String
  1007. /*=======================================================================================
  1008.           Function: Connector Direction
  1009.           ---------------------------------------
  1010.           function will: return a string for the RC to use for docking procedures
  1011.         //=======================================================================================*/
  1012. Vector3D ReturnConnectorDirection(IMyShipConnector CONNECTOR, IMyRemoteControl RC)
  1013. {
  1014.     if (CONNECTOR.Orientation.Forward == RC.Orientation.TransformDirection(Base6Directions.Direction.Down))
  1015.     { return RC.WorldMatrix.Left; }  //Connector is the bottom of ship
  1016.     if (CONNECTOR.Orientation.Forward == RC.Orientation.TransformDirection(Base6Directions.Direction.Up))
  1017.     { return RC.WorldMatrix.Right; }  //Connector is on the top of the ship
  1018.     if (CONNECTOR.Orientation.Forward == RC.Orientation.TransformDirection(Base6Directions.Direction.Right))
  1019.     { return RC.WorldMatrix.Up; }  //Connector is on the left of the ship
  1020.     if (CONNECTOR.Orientation.Forward == RC.Orientation.TransformDirection(Base6Directions.Direction.Left))
  1021.     { return RC.WorldMatrix.Down; }  //Connector is on the right of the ship
  1022.     return RC.WorldMatrix.Down;
  1023. }
  1024.  
  1025. //Generic Constructors Used For Serialization & Saving/Loading
  1026. /*=======================================================================================
  1027.           Function: Serializer
  1028.           ---------------------------------------
  1029.           function will: Serialize & Deserialize any variable using the Savable_ tag
  1030.         //----------==--------=------------=-----------=---------------=------------=-----=-----*/
  1031.  
  1032. //Serialization Lists (All static, bahhh)
  1033. static List<Savable_String> SavableStrings = new List<Savable_String>();
  1034. static List<Savable_Int> SavableInts = new List<Savable_Int>();
  1035. static List<Savable_Vector> SavableVectors = new List<Savable_Vector>();
  1036. static List<Savable_Double> SavableDoubles = new List<Savable_Double>();
  1037. static List<Savable_Bool> SavableBools = new List<Savable_Bool>();
  1038.  
  1039. //Serializable Variable Types
  1040. class Savable_String //Savable String Interface
  1041. { public string Val = ""; public Savable_String() { SavableStrings.Add(this); } }
  1042. class Savable_Int //Savable Int Interface
  1043. { public int Val = 0; public Savable_Int() { SavableInts.Add(this); } }
  1044. class Savable_Vector //Savable Vector3D Interface
  1045. { public Vector3D Val = new Vector3D(0, 0, 0); public Savable_Vector() { SavableVectors.Add(this); } }
  1046. class Savable_Double //Savable Double Interface
  1047. { public double Val = 0; public Savable_Double() { SavableDoubles.Add(this); } }
  1048. class Savable_Bool//Savable Boolean Interface
  1049. { public bool Val = true; public Savable_Bool() { SavableBools.Add(this); } }
  1050.  
  1051. //Methods For Serialization/Deserialization
  1052. string Serializer()
  1053. {
  1054.  
  1055.     //Saves GridId First (Prevents Reoccuring ID feature)
  1056.     string SaveString = Me.CubeGrid.EntityId + "";
  1057.  
  1058.     //Iterates Through Strings
  1059.     SaveString = SaveString + "/";
  1060.     foreach (var item in SavableStrings)
  1061.     {
  1062.         SaveString = SaveString + item.Val + "^";
  1063.     }
  1064.  
  1065.     //Iterates Through Ints
  1066.     SaveString = SaveString + "/";
  1067.     foreach (var item in SavableInts)
  1068.     {
  1069.         SaveString = SaveString + item.Val + "^";
  1070.     }
  1071.  
  1072.     //Iterates Through 3DVectors
  1073.     SaveString = SaveString + "/";
  1074.     foreach (var item in SavableVectors)
  1075.     {
  1076.         SaveString = SaveString + Vector3D.Round(item.Val, 2) + "^";
  1077.     }
  1078.  
  1079.     //Iterates Through Doubles
  1080.     SaveString = SaveString + "/";
  1081.     foreach (var item in SavableDoubles)
  1082.     {
  1083.         SaveString = SaveString + Math.Round(item.Val, 2) + "^";
  1084.     }
  1085.  
  1086.     //Iterates Through Bools
  1087.     SaveString = SaveString + "/";
  1088.     foreach (var item in SavableBools)
  1089.     {
  1090.         SaveString = SaveString + item.Val + "^";
  1091.     }
  1092.  
  1093.     //Clears Lists To Free Up Memory Allocation
  1094.     //(Cannot properly finalise)
  1095.     //SavableStrings.Clear();
  1096.     //SavableInts.Clear();
  1097.     //SavableVectors.Clear();
  1098.     //SavableDoubles.Clear();
  1099.     //SavableBools.Clear();
  1100.     return SaveString;
  1101. }
  1102. void DeSerializer(string Input)
  1103. {
  1104.     //Splits Input Into Sections
  1105.     String[] SplitInput = Input.Split('/');
  1106.     Echo(Input);
  1107.  
  1108.     //Throw.Vals Error If Cannot Split
  1109.     if (SplitInput.Length < 5)
  1110.     { Echo("Error During DeSerialization"); return; }
  1111.  
  1112.     //Exits If Grid ID is not equal to current
  1113.     if (SplitInput[0] != Me.CubeGrid.EntityId + "")
  1114.     { Echo("New Grid, Serialization Cancelled"); return; }
  1115.  
  1116.     //Splits Strings And Assigns
  1117.     string[] SplitStrings = SplitInput[1].Split('^');
  1118.     for (int i = 0; i < SavableStrings.Count; i++)
  1119.     {
  1120.         SavableStrings[i].Val = SplitStrings[i];
  1121.     }
  1122.  
  1123.     //Splits Ints And Assigns
  1124.     string[] SplitInts = SplitInput[2].Split('^');
  1125.     for (int i = 0; i < SavableInts.Count; i++)
  1126.     {
  1127.         SavableInts[i].Val = int.Parse(SplitInts[i]);
  1128.     }
  1129.  
  1130.     //Splits 3DVectors And Assigns
  1131.     string[] SplitVectors = SplitInput[3].Split('^');
  1132.     for (int i = 0; i < SavableVectors.Count; i++)
  1133.     {
  1134.         Vector3D.TryParse(SplitVectors[i], out SavableVectors[i].Val);
  1135.     }
  1136.  
  1137.     //Splits Doubles And Assigns
  1138.     string[] SplitDoubles = SplitInput[4].Split('^');
  1139.     for (int i = 0; i < SavableDoubles.Count; i++)
  1140.     {
  1141.         SavableDoubles[i].Val = double.Parse(SplitDoubles[i]);
  1142.     }
  1143.  
  1144.     //Splits Bools And Assigns
  1145.     string[] SplitBools = SplitInput[5].Split('^');
  1146.     for (int i = 0; i < SavableBools.Count; i++)
  1147.     {
  1148.         SavableBools[i].Val = bool.Parse(SplitBools[i]);
  1149.     }
  1150.  
  1151. }
  1152.  
  1153.  
  1154. void BatteryCharger()
  1155. {
  1156.  
  1157.  
  1158.     if (!BatCharged(MinCharge))
  1159.  
  1160.     {
  1161.  
  1162.         //set all ship batteries to charge
  1163.         for (int j = 0; j < SHIP_BATT.Count; j++)
  1164.         { (SHIP_BATT[j] as IMyBatteryBlock).ChargeMode = ChargeMode.Recharge; }
  1165.  
  1166.     }
  1167.     else
  1168.     {
  1169.  
  1170.         MININGSTATUS.Val = "MINE";
  1171.         //set all ship batteries to auto
  1172.         for (int j = 0; j < SHIP_BATT.Count; j++)
  1173.         { (SHIP_BATT[j] as IMyBatteryBlock).ChargeMode = ChargeMode.Auto; }
  1174.  
  1175.     }
  1176.  
  1177. }
  1178.  
  1179. bool BatCharged(double amount)
  1180. {
  1181.  
  1182.     double MaxPower = 0;
  1183.     double CurrentPower = 0;
  1184.  
  1185.     for (int i = 0; i < SHIP_BATT.Count; i++)
  1186.     {
  1187.         CurrentPower += SHIP_BATT[i].CurrentStoredPower;
  1188.         MaxPower += SHIP_BATT[i].MaxStoredPower;
  1189.     }
  1190.     return (CurrentPower >= (MaxPower * amount));
  1191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement