114 lines
4.2 KiB
C#
114 lines
4.2 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, IConsoleProgram
|
|
{
|
|
public MyIni Ini { get; } = new MyIni();
|
|
public IConsole Console { get; private set; }
|
|
|
|
private MyCommandLine _cli = new MyCommandLine();
|
|
private List<IEnumerator<bool>> _jobs = new List<IEnumerator<bool>>();
|
|
private Dictionary<string, Sequencer> _doors = new Dictionary<string, Sequencer>();
|
|
|
|
public Program()
|
|
{
|
|
Console = new MainConsole(this, "Door Controller");
|
|
|
|
List<IMyTerminalBlock> doorBlocks = new List<IMyTerminalBlock>();
|
|
GridTerminalSystem.GetBlocksOfType(doorBlocks, block => MyIni.HasSection(block.CustomData, "mechDoor"));
|
|
foreach (IMyTerminalBlock block in doorBlocks)
|
|
{
|
|
Ini.TryParse(block.CustomData);
|
|
string doorName = Ini.Get("mechDoor", "id").ToString();
|
|
// Create the door if this is a new id
|
|
if (!_doors.ContainsKey(doorName))
|
|
{
|
|
_doors[doorName] = new Sequencer(this, doorName);
|
|
}
|
|
|
|
// Add the part; the Door object handles typing and sequencing.
|
|
ISequenceable wrapped = SequenceableFactory.MakeSequenceable(block, Ini, "mechDoor");
|
|
if (!(block is IMyShipMergeBlock)) wrapped.Step = 1; // TODO: actually support merge blocks here
|
|
if (wrapped == null) { Console.Print($"Tried to add incompatible block '{block.CustomName}'"); continue; }
|
|
_doors[doorName].AddBlock(wrapped);
|
|
}
|
|
|
|
Console.Print($"Found {_doors.Keys.Count} doors.");
|
|
Console.UpdateTickCount();
|
|
}
|
|
|
|
public void Main(string argument, UpdateType updateSource)
|
|
{
|
|
Console.UpdateTickCount();
|
|
|
|
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 = _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 deploy = _cli.Switch("deploy") || _cli.Switch("open");
|
|
foreach (Sequencer door in doorsToControl)
|
|
{
|
|
_jobs.Add(door.RunSequence(deploy));
|
|
}
|
|
Runtime.UpdateFrequency |= UpdateFrequency.Update10;
|
|
}
|
|
}
|
|
|
|
// Process running jobs
|
|
for (int i = 0; i < _jobs.Count; i++)
|
|
{
|
|
if (_jobs[i].MoveNext()) continue;
|
|
|
|
_jobs[i].Dispose();
|
|
_jobs.Remove(_jobs[i]);
|
|
i--;
|
|
Console.Print("Operation Complete.");
|
|
}
|
|
|
|
if (_jobs.Count == 0)
|
|
{
|
|
Runtime.UpdateFrequency = UpdateFrequency.None;
|
|
}
|
|
}
|
|
}
|
|
}
|