using Sandbox.ModAPI.Ingame; using System.Collections.Generic; using VRage.Game.ModAPI.Ingame.Utilities; namespace IngameScript { public partial class Program : MyGridProgram, IConsoleProgram { public IConsole Console { get; private set; } public MyIni Ini { get; } = new MyIni(); private IEnumerator _job = null; private MyCommandLine _cli = new MyCommandLine(); private List _dockingPorts = new List(); private ActionGroup _actionGroup; public Program() { Console = new MainConsole(this, "Docking Controller"); _actionGroup = new ActionGroup(Console, "docking"); // We store a list of the dockingPorts because we will only dock if one is ready to lock. GridTerminalSystem.GetBlocksOfType(_dockingPorts, blockFilter); foreach (IMyShipConnector dockingPort in _dockingPorts) { _actionGroup.AddActionBlock("dock", 0, new BlockActionConnector(dockingPort, ConnectorAction.Connect)); _actionGroup.AddActionBlock("undock", 1, new BlockActionConnector(dockingPort, ConnectorAction.Disconnect)); } List thrusters = new List(); GridTerminalSystem.GetBlocksOfType(thrusters, blockFilter); foreach (IMyThrust thruster in thrusters) { _actionGroup.AddActionBlock("dock", 1, new BlockActionThruster(thruster, ThrusterAction.Disable)); _actionGroup.AddActionBlock("undock", 0, new BlockActionThruster(thruster, ThrusterAction.Enable)); } List gasTanks = new List(); GridTerminalSystem.GetBlocksOfType(gasTanks, blockFilter); foreach (IMyGasTank gasTank in gasTanks) { _actionGroup.AddActionBlock("dock", 1, new BlockActionGasTank(gasTank, GasTankAction.Stockpile)); _actionGroup.AddActionBlock("undock", 0, new BlockActionGasTank(gasTank, GasTankAction.Dispense)); } Console.Print($"Found {_dockingPorts.Count} docking ports."); Console.Print($"Found {thrusters.Count} thrusters."); Console.Print($"Found {gasTanks.Count} gas tanks."); Console.UpdateTickCount(); } public void Main(string argument, UpdateType updateSource) { Console.UpdateTickCount(); if (argument != "") { if (_job != null) { Console.Print("Already performing a docking action."); } else { _cli.TryParse(argument); if (_cli.ArgumentCount == 0) { Console.Print("Error: Must pass an argument, 'dock' or 'undock'."); return; } string action = _cli.Argument(0).ToLower(); if (action == "dock" && !readyToDock()) { Console.Print("No docking port in a dockable state."); return; } _job = _actionGroup.RunAction(_cli.Argument(0).ToLower()); Runtime.UpdateFrequency = UpdateFrequency.Update10; } } if (_job != null && !_job.MoveNext()) { _job.Dispose(); _job = null; Console.Print("Docking action complete."); Runtime.UpdateFrequency = UpdateFrequency.None; } } private bool blockFilter(IMyTerminalBlock block) { if (!block.IsSameConstructAs(this.Me)) return false; if (MyIni.HasSection(block.CustomData, "docking")) { Ini.TryParse(block.CustomData); return !Ini.Get("docking", "ignore").ToBoolean(false); } return true; } private bool readyToDock() { foreach (IMyShipConnector dockingPort in _dockingPorts) { if (dockingPort.Status == MyShipConnectorStatus.Connectable) return true; } return false; } } }