space_engineers/MechanicalDoor/Program.cs

120 lines
4.3 KiB
C#

using Sandbox.ModAPI.Ingame;
using SpaceEngineers.Game.ModAPI.Ingame;
using System.Collections.Generic;
using VRage.Game.ModAPI.Ingame.Utilities;
namespace IngameScript
{
public partial class Program : MyGridProgram
{
private MyCommandLine _cli;
private MyIni _ini;
private Console _console;
private List<IEnumerator<bool>> _jobs;
private Dictionary<string, Sequencer> _doors;
private int _tickCount;
public Program()
{
_tickCount = 0;
_cli = new MyCommandLine();
_ini = new MyIni();
_console = new Console(this, _ini);
_jobs = new List<IEnumerator<bool>>();
_doors = new Dictionary<string, Sequencer>();
List<IMyTerminalBlock> doorBlocks = new List<IMyTerminalBlock>();
GridTerminalSystem.GetBlocksOfType<IMyTerminalBlock>(doorBlocks, block => block.CustomName.Contains("!Door"));
foreach (IMyTerminalBlock block in doorBlocks)
{
string doorName = Utils.ExtractTag(block, "!Door");
// Create the door if this is a new tag
if (!_doors.ContainsKey(doorName))
{
_doors[doorName] = new Sequencer(doorName, new PrefixedConsole(_console, doorName));
}
// Add the part; the Door object handles typing and sequencing.
int defaultStep = 1;
if (block is IMyShipMergeBlock) defaultStep = 0;
ISequenceable wrapped = SequenceableFactory.MakeSequenceable(block, _ini, defaultStep);
if (wrapped == null) { _console.Print($"Tried to add incompatible block '{block.CustomName}'"); continue; }
_doors[doorName].AddBlock(wrapped);
}
_console.Print($"Found {_doors.Keys.Count} doors.");
}
public void Main(string argument, UpdateType updateSource)
{
_console.PrintLower($"Total Ticks: {_tickCount++}");
if (updateSource == UpdateType.Trigger || updateSource == UpdateType.Terminal)
{
// Create a new job
_cli.TryParse(argument);
List<Sequencer> doorsToControl = new List<Sequencer>();
if (_cli.ArgumentCount == 0)
{
_console.Print("No arguments passed. Controlling all doors.");
foreach (Sequencer door in _doors.Values)
{
if (door.Running) continue;
doorsToControl.Add(door);
}
}
for (int i = 0; i < _cli.ArgumentCount; i++)
{
string key = "Door" + _cli.Argument(i);
if (!_doors.ContainsKey(key))
{
_console.Print($"Door '{key}' not found. Skipping.");
continue;
}
if (_doors[key].Running)
{
_console.Print($"Door '{key}' already moving. Skipping.");
continue;
}
doorsToControl.Add(_doors[key]);
}
if (doorsToControl.Count == 0)
{
_console.Print("No doors found. Not creating new job.");
}
else
{
_console.Print("Creating new job(s).");
bool close = _cli.Switch("close");
foreach (Sequencer door in doorsToControl)
{
_jobs.Add(door.RunSequence(close));
}
Runtime.UpdateFrequency |= UpdateFrequency.Update1;
}
}
// Process running jobs
for (int i = 0; i < _jobs.Count; i++)
{
if (!_jobs[i].MoveNext())
{
_jobs[i].Dispose();
_jobs.Remove(_jobs[i]);
i--;
_console.Print("Operation Complete.");
}
}
if (_jobs.Count == 0)
{
Runtime.UpdateFrequency = UpdateFrequency.None;
}
}
}
}