Advertisement
NickNDS

Rotating Piston Drill Controller

Nov 26th, 2019
689
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 16.26 KB | None | 0 0
  1. public float rotationVelocity = 0.5f,
  2. angleVariance = 0.25f,
  3. pistonExtensionSpeed = 0.5f, rotorAngleStepDistance = 0.5f,
  4. nextRotorAngle = 0f, nextPistonDistance = 0f, pistonExtensionDistance = 0.5f,
  5. cargoCapacityLimit = 0.9f, autoRange = 0f,
  6. maxPistonDistance = 0f;
  7.  
  8. public string
  9. rotorKeyword = "drill", pistonKeyword = "drill",
  10. drillKeyword = "drill", cameraKeyword = "drill",
  11. connectorKeyword = "drill";
  12.  
  13. public List<IMyTerminalBlock>
  14. downPistons = new List<IMyTerminalBlock>(),
  15. drills = new List<IMyTerminalBlock>(),
  16. containers = new List<IMyTerminalBlock>();
  17.  
  18. public bool drilling = false, retracting = true, stepping = false,
  19. centeredRotor = true, drillingRotor = false, auto = false,
  20. scanningRange = false, outCapacity = false;
  21.  
  22. public SavedRotor savedRotor;
  23.  
  24. public IMyCameraBlock cameraBlock;
  25.  
  26. public IMyShipConnector connector;
  27.  
  28. public string settingBackup = "";
  29.  
  30. public TimeSpan lockableSpan = new TimeSpan(0, 0, 0);
  31.  
  32. public Program()
  33. {
  34.     Runtime.UpdateFrequency = UpdateFrequency.Update1;
  35.     if (Me.CustomData == "") SaveData();
  36.     else LoadData();
  37.     Scan();
  38.     SetPistonVelocity(downPistons, -0.5f);
  39.     SetPistonDistance(downPistons, 0f);
  40.     Save();
  41. }
  42.  
  43. public void Scan()
  44. {
  45.     //Get down pistons
  46.     GridTerminalSystem.GetBlocksOfType<IMyPistonBase>(downPistons, b => b.CustomName.ToLower().Contains(pistonKeyword.ToLower()));
  47.     for (int i = 0; i < downPistons.Count; i++)
  48.         maxPistonDistance += ((IMyPistonBase)downPistons[i]).HighestPosition;
  49.     Echo("'" + pistonKeyword + "' Pistons: " + downPistons.Count);
  50.     //Get rotor
  51.     List<IMyTerminalBlock> rotors = new List<IMyTerminalBlock>();
  52.     GridTerminalSystem.GetBlocksOfType<IMyMotorAdvancedStator>(rotors, b => rotorKeyword == "" || b.CustomName.ToLower().Contains(rotorKeyword.ToLower()));
  53.     Echo("'" + rotorKeyword + "' Rotors Found: " + rotors.Count);
  54.     if (rotors.Count > 0) {
  55.         SavedRotor rotor = new SavedRotor();
  56.         rotor.rotor = rotors[0];
  57.         rotor.angleVariance = angleVariance;
  58.         rotor.desiredAngle = ((IMyMotorAdvancedStator)rotors[0]).Angle * 180f / (float)Math.PI;
  59.         nextRotorAngle = rotor.desiredAngle;
  60.         rotor.rotationVelocity = rotationVelocity;
  61.         ((IMyMotorAdvancedStator)rotors[0]).TargetVelocityRPM = 0f;
  62.         savedRotor = rotor;
  63.         Echo("Added Rotor: " + rotors[0].CustomName);
  64.     } else throw new Exception("\nNo Rotor Found With Keyword '" + rotorKeyword + "'");
  65.     //Get drills
  66.     GridTerminalSystem.GetBlocksOfType<IMyShipDrill>(drills, d => d.CustomName.ToLower().Contains(drillKeyword.ToLower()));
  67.     Echo("'" + drillKeyword + "' Drills: " + drills.Count);
  68.     GridTerminalSystem.GetBlocksOfType<IMyCargoContainer>(containers, c => c.CubeGrid == Me.CubeGrid || c.CustomData.ToLower().Contains("drill"));
  69.     Echo("Containers: " + containers.Count);
  70.     //Get camera
  71.     List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
  72.     GridTerminalSystem.GetBlocksOfType<IMyCameraBlock>(blocks, b => b.CustomName.ToLower().Contains(cameraKeyword.ToLower()));
  73.     if (blocks.Count > 0) {
  74.         cameraBlock = (IMyCameraBlock)blocks[0];
  75.         Echo("Camera Found");
  76.     }
  77.     //Get connector
  78.     GridTerminalSystem.GetBlocksOfType<IMyShipConnector>(blocks, b => b.CustomName.ToLower().Contains(connectorKeyword.ToLower()));
  79.     if (blocks.Count > 0) {
  80.         connector = (IMyShipConnector)blocks[0];
  81.         Echo("Connector Found");
  82.     }
  83. }
  84.  
  85. public void Save()
  86. {
  87.  
  88. }
  89.  
  90. public void Main(string argument, UpdateType updateSource)
  91. {
  92.     outCapacity = false;
  93.     if (Me.CustomData != settingBackup) LoadData();
  94.     if (argument != "") try { Commands(argument.ToLower()); } catch { }
  95.     Purge();
  96.     if (scanningRange) AutoRange();
  97.     if (drilling) {
  98.         Echo("Drilling");
  99.         if (autoRange != 0f) Echo("Auto Range: " + autoRange.ToString("N1"));
  100.         DrillScript();
  101.     }
  102.     else if (retracting) {
  103.         Echo("Inactive");
  104.         Echo("Drills: " + drills.Count);
  105.         Echo("Pistons: " + downPistons.Count);
  106.         Echo("Camera: " + (cameraBlock != null).ToString());
  107.         Echo("Connector: " + (connector != null).ToString());
  108.         SetDrills(false);
  109.         SetRotor(0f);
  110.         SetPistonVelocity(downPistons, -0.5f);
  111.         SetPistonDistance(downPistons, 0f);
  112.         nextPistonDistance = 0f;
  113.         if (auto && FillLevel() < cargoCapacityLimit) {
  114.             retracting = false;
  115.             drilling = true;
  116.             AutoRange();
  117.         }
  118.         if (!drilling && connector != null)
  119.         {
  120.             connector.Enabled = true;
  121.             if (connector.Status == MyShipConnectorStatus.Connectable)
  122.             {
  123.                 if (lockableSpan.TotalSeconds >= 5.0) connector.Connect();
  124.                 else lockableSpan += Runtime.TimeSinceLastRun;
  125.             } else lockableSpan = new TimeSpan(0, 0, 0);
  126.         }
  127.     }
  128.     CheckRotors();
  129. }
  130.  
  131. public void Commands(string arg)
  132. {
  133.     if (arg.StartsWith("set ")) {
  134.         float distance = float.Parse(arg.Substring(4));
  135.         nextPistonDistance = distance / (float)downPistons.Count;
  136.         SetPistonDistance(downPistons, nextPistonDistance);
  137.     }
  138.     else switch (arg)
  139.     {
  140.         case "drill":
  141.             drilling = !drilling;
  142.             retracting = !drilling;
  143.             if (drilling) {
  144.                 SetPistonVelocity(downPistons, pistonExtensionSpeed);
  145.                 if (connector != null) connector.Enabled = false;
  146.             } else if (connector != null) connector.Enabled = true;
  147.         break;
  148.         case "scan":
  149.             Scan();
  150.         break;
  151.         case "auto":
  152.             auto = !auto;
  153.             SaveData();
  154.             if (auto && cameraBlock != null) AutoRange();
  155.             else
  156.             {
  157.                 drilling = false;
  158.                 retracting = true;
  159.                 if (connector != null) connector.Enabled = true;
  160.             }
  161.         break;
  162.     }
  163. }
  164.  
  165. public void SaveData()
  166. {
  167.     StringBuilder builder = new StringBuilder();
  168.     builder.AppendLine("pistonExtensionSpeed=" + pistonExtensionSpeed + ";");
  169.     builder.AppendLine("pistonExtensionDistance=" + pistonExtensionDistance + ";");
  170.     builder.AppendLine("pistonKeyword=" + pistonKeyword + ";");
  171.     builder.AppendLine("connectorKeyword=" + connectorKeyword + ";");
  172.     builder.AppendLine("rotorAngleStepDistance=" + rotorAngleStepDistance + ";");
  173.     builder.AppendLine("rotationVelocity=" + rotationVelocity + ";");
  174.     builder.AppendLine("angleVariance=" + angleVariance + ";");
  175.     builder.AppendLine("rotorKeyword=" + rotorKeyword + ";");
  176.     builder.AppendLine("drillKeyword=" + drillKeyword + ";");
  177.     builder.AppendLine("cameraKeyword=" + cameraKeyword + ";");
  178.     builder.Append("auto=" + auto + ";");
  179.     Me.CustomData = builder.ToString();
  180.     settingBackup = Me.CustomData;
  181. }
  182.  
  183. public void LoadData()
  184. {
  185.     string settingString = Me.CustomData;
  186.     settingString = settingString.Replace("\r\n", String.Empty);
  187.     settingString = settingString.Replace("\n", String.Empty);
  188.     settingString = settingString.Replace("\r", String.Empty);
  189.     settingString = settingString.Replace("\t", String.Empty);
  190.     string[] settingArray = settingString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
  191.     for (int i = 0; i < settingArray.Length; i++)
  192.         if (settingArray[i].Contains("=")) ProcessSetting(settingArray[i]);
  193.     settingBackup = Me.CustomData;
  194. }
  195.  
  196. public void ProcessSetting(string setting)
  197. {
  198.     bool boolSetting = false;
  199.     float floatSetting = 0f;
  200.     int settingIndex = setting.IndexOf("=");
  201.     string stringSetting = setting.Substring(settingIndex + 1), settingKey = setting.Substring(0, settingIndex);
  202.     boolSetting = stringSetting.ToLower().Contains("true");
  203.     try { floatSetting = float.Parse(stringSetting); } catch { }
  204.     switch (settingKey)
  205.     {
  206.         case "pistonExtensionSpeed":
  207.             pistonExtensionSpeed = floatSetting;
  208.         break;
  209.         case "pistonExtensionDistance":
  210.             pistonExtensionDistance = floatSetting;
  211.         break;
  212.         case "pistonKeyword":
  213.             pistonKeyword = stringSetting;
  214.         break;
  215.         case "rotorAngleStepDistance":
  216.             rotorAngleStepDistance = floatSetting;
  217.         break;
  218.         case "rotationVelocity":
  219.             rotationVelocity = floatSetting;
  220.         break;
  221.         case "angleVariance":
  222.             angleVariance = floatSetting;
  223.         break;
  224.         case "rotorKeyword":
  225.             rotorKeyword = stringSetting;
  226.         break;
  227.         case "drillKeyword":
  228.             drillKeyword = stringSetting;
  229.         break;
  230.         case "connectorKeyword":
  231.             connectorKeyword = stringSetting;
  232.         break;
  233.         case "cameraKeyword":
  234.             cameraKeyword = stringSetting;
  235.         break;
  236.         case "auto":
  237.             auto = boolSetting;
  238.         break;
  239.     }
  240. }
  241.  
  242. public void AutoRange()
  243. {
  244.     if (connector != null) connector.Enabled = false;
  245.     double scanDistance = 0, currentDistance = (double)PistonDistance(downPistons);
  246.     for (int i = 0; i < downPistons.Count; i++)
  247.     {
  248.         scanDistance += (double)((IMyPistonBase)downPistons[i]).HighestPosition - (double)((IMyPistonBase)downPistons[i]).CurrentPosition;
  249.     }
  250.     if (!scanningRange) {
  251.         cameraBlock.EnableRaycast = true;
  252.         scanningRange = true;
  253.     }
  254.     if (cameraBlock.CanScan(scanDistance))
  255.     {
  256.         MyDetectedEntityInfo info = cameraBlock.Raycast(scanDistance, 0f, 0f);
  257.         if (info.HitPosition.HasValue)
  258.         {
  259.             float hitDistance = (float)currentDistance + (float)Vector3D.Distance(cameraBlock.GetPosition(), info.HitPosition.Value) - 7f;
  260.             if (info.Type == MyDetectedEntityType.Planet || info.Type == MyDetectedEntityType.Asteroid)
  261.             {
  262.                 scanningRange = false;
  263.                 nextPistonDistance = hitDistance / (float)downPistons.Count;
  264.                 SetPistonVelocity(downPistons, pistonExtensionSpeed);
  265.                 SetPistonDistance(downPistons, nextPistonDistance);
  266.                 drilling = true;
  267.                 retracting = false;
  268.             }
  269.         }
  270.     }
  271. }
  272.  
  273. public void Purge()
  274. {
  275.     PurgeList(downPistons);
  276.     PurgeList(containers);
  277.     PurgeList(drills);
  278.     if (cameraBlock != null && !Verify((IMyTerminalBlock)cameraBlock)) cameraBlock = null;
  279. }
  280.  
  281. public void PurgeList(List<IMyTerminalBlock> blocks)
  282. {
  283.     for (int i = 0; i < blocks.Count; i += 0)
  284.     {
  285.         if (!Verify(blocks[i])) blocks.RemoveAt(i);
  286.         else i++;
  287.     }
  288. }
  289.  
  290. public bool Verify(IMyTerminalBlock block)
  291. {
  292.     return block.CubeGrid.CubeExists(block.Position);
  293. }
  294.  
  295. public void DrillScript()
  296. {
  297.     if (FillLevel() < cargoCapacityLimit) {
  298.         SetDrills(true);
  299.         if (RotorPlaced()) StepRotor();
  300.         SetRotor(nextRotorAngle);
  301.         bool isCentered = IsCentered();
  302.         if (centeredRotor && !isCentered) {
  303.             centeredRotor = false;
  304.             drillingRotor = true;
  305.         }
  306.         else if (!centeredRotor && isCentered) centeredRotor = true;
  307.         if (drillingRotor && centeredRotor)
  308.         {
  309.             drillingRotor = false;
  310.             if (!FullyExtended())
  311.                 StepPiston();
  312.             else
  313.             {
  314.                 drilling = false;
  315.                 retracting = true;
  316.             }
  317.         }
  318.         Echo((((nextPistonDistance * (float)downPistons.Count) / maxPistonDistance) * 100f).ToString("N2") + "% Done");
  319.     } else SetDrills(false);
  320. }
  321.  
  322. public float FillLevel()
  323. {
  324.     float currLevel = 0f, maxLevel = 0f;
  325.     for (int i = 0; i < containers.Count; i++)
  326.     {
  327.         IMyInventory inv = containers[i].GetInventory(0);
  328.         currLevel += (float)inv.CurrentVolume;
  329.         maxLevel += (float)inv.MaxVolume;
  330.     }
  331.     if (!outCapacity && maxLevel != 0f)
  332.     {
  333.         outCapacity = true;
  334.         string capacityString = "";
  335.         if (currLevel == 0f) capacityString = "0 / ";
  336.         else capacityString = ((currLevel / maxLevel) * 100f).ToString("N2") + " / ";
  337.         capacityString += (cargoCapacityLimit * 100f).ToString("N2") + "% Filled";
  338.         Echo(capacityString);
  339.     }
  340.     return currLevel / maxLevel;
  341. }
  342.  
  343. public bool IsCentered()
  344. {
  345.     float angle = savedRotor.CurrentAngle();
  346.     return 360f - angle <= angleVariance || angle <= angleVariance;
  347. }
  348.  
  349. public void SetDrills(bool enabled)
  350. {
  351.     for (int i = 0; i < drills.Count; i++)
  352.         ((IMyFunctionalBlock)drills[i]).Enabled = enabled;
  353. }
  354.  
  355. public bool RotorPlaced()
  356. {
  357.     float angle = savedRotor.CurrentAngle();
  358.     Echo("Current Angle: " + angle);
  359.     Echo("Next Angle: " + nextRotorAngle);
  360.     Echo("Current Depth: " + (nextPistonDistance * (float)downPistons.Count));
  361.     return Math.Abs(savedRotor.desiredAngle - angle) <= angleVariance;
  362. }
  363.  
  364. public void StepPiston()
  365. {
  366.     nextPistonDistance += pistonExtensionDistance / (float)downPistons.Count;
  367.     SetPistonDistance(downPistons, nextPistonDistance);
  368. }
  369.  
  370. public void StepRotor()
  371. {
  372.     nextRotorAngle += rotorAngleStepDistance;
  373.     if (nextRotorAngle >= 360f) nextRotorAngle -= 360f;
  374. }
  375.  
  376. public float PistonDistance(List<IMyTerminalBlock> pistons)
  377. {
  378.     float dist = 0f;
  379.     for (int i = 0; i < pistons.Count; i++)
  380.         dist += ((IMyPistonBase)pistons[i]).CurrentPosition;
  381.     return dist;
  382. }
  383.  
  384. public void SetPistonDistance(List<IMyTerminalBlock> pistons, float distance)
  385. {
  386.     for (int i = 0; i < pistons.Count; i++)
  387.     {
  388.         if (distance < ((IMyPistonBase)pistons[i]).HighestPosition)
  389.             ((IMyPistonBase)pistons[i]).MaxLimit = distance;
  390.     }
  391. }
  392.  
  393. public void SetPistonVelocity(List<IMyTerminalBlock> pistons, float velocity)
  394. {
  395.     for (int i = 0; i < pistons.Count; i++)
  396.         ((IMyPistonBase)pistons[i]).Velocity = velocity;
  397. }
  398.  
  399. public bool FullyRetracted(List<IMyTerminalBlock> pistons)
  400. {
  401.     for (int i = 0; i < pistons.Count; i++) {
  402.         IMyPistonBase pistonBase = (IMyPistonBase)pistons[i];
  403.         if (pistonBase.CurrentPosition > pistonBase.MinLimit)
  404.             return false;
  405.     }
  406.     return true;
  407. }
  408.  
  409. public bool FullyExtended(List<IMyTerminalBlock> pistons)
  410. {
  411.     for (int i = 0; i < pistons.Count; i++) {
  412.         IMyPistonBase pistonBase = (IMyPistonBase)pistons[i];
  413.         if (pistonBase.CurrentPosition < pistonBase.MaxLimit)
  414.             return false;
  415.     }
  416.     return true;
  417. }
  418.  
  419. public bool Positive(float angleA, float angleB)
  420. {
  421.     if (angleA < angleB) {
  422.         if (Math.Abs(angleA - angleB) < 180f)
  423.             return true;
  424.         else return false;
  425.     } else {
  426.         if (Math.Abs(angleA - angleB) < 180f)
  427.             return false;
  428.         else return true;
  429.     }
  430. }
  431.  
  432. public void CheckRotors()
  433. {
  434.     savedRotor.CheckRotor();
  435. }
  436.  
  437. public void SetRotor(float angle)
  438. {
  439.     savedRotor.desiredAngle = angle;
  440.     savedRotor.rotationVelocity = rotationVelocity;
  441.     savedRotor.angleVariance = angleVariance;
  442. }
  443.  
  444. public class SavedRotor
  445. {
  446.     public IMyTerminalBlock rotor;
  447.     public float desiredAngle = 0f, angleVariance = 1f, rotationVelocity = 0f;
  448.  
  449.     public void IncrementRotor(float increment)
  450.     {
  451.         if (desiredAngle + increment > 360) desiredAngle = desiredAngle + increment - 360f;
  452.         else if (desiredAngle + increment < 0) desiredAngle = 360 + desiredAngle + increment;
  453.         else desiredAngle += increment;
  454.     }
  455.    
  456.     public float CurrentAngle()
  457.     {
  458.         return ((IMyMotorAdvancedStator)rotor).Angle * 180f / (float)Math.PI;
  459.     }
  460.  
  461.     public void CheckRotor()
  462.     {
  463.         float currentAngle = ((IMyMotorAdvancedStator)rotor).Angle * 180f / (float)Math.PI;
  464.         if (Math.Abs(currentAngle - desiredAngle) > angleVariance)
  465.         {
  466.             float positiveDistance = 0f, negativeDistace = 0f;
  467.             if (desiredAngle > currentAngle) {
  468.                 positiveDistance = desiredAngle - currentAngle;
  469.                 negativeDistace = currentAngle + 360f - desiredAngle;
  470.             } else {
  471.                 negativeDistace = currentAngle - desiredAngle;
  472.                 positiveDistance = desiredAngle + 360f - currentAngle;
  473.             }
  474.             if (positiveDistance < negativeDistace || positiveDistance == negativeDistace) ((IMyMotorAdvancedStator)rotor).TargetVelocityRPM = rotationVelocity;
  475.             else ((IMyMotorAdvancedStator)rotor).TargetVelocityRPM = -rotationVelocity;
  476.         } else ((IMyMotorAdvancedStator)rotor).TargetVelocityRPM = 0f;
  477.     }
  478. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement