// A SequenceableBlock holds a reference to a compatible block type, // and a list of available actions sorted by name. // It provides a RunAction() method that allows the caller to // run the configured actions. using System; using System.Collections.Generic; using Sandbox.ModAPI.Ingame; using VRage.Game.ModAPI.Ingame.Utilities; namespace IngameScript { partial class Program { public interface ISequenceableAction { string Name { get; } IEnumerator Run(); } public class SequenceableBlock { private IConsole _console; private IMyTerminalBlock _block; private Dictionary _actions = new Dictionary(); public SequenceableBlock(IConsole console, IMyTerminalBlock block) { _console = console; if (!(_block is IMyDoor || _block is IMyPistonBase || _block is IMyMotorRotor)) { _console.Print("ERROR: Incompatible block '{_block.CustomName}' being sequenced."); } _block = block; } // We employ a pseudo-factory pattern to parse the settings // into ISequenceableAction objects. public void Parse(MyIni ini, string sectionName = "sequencer") { ini.TryParse(_block.CustomData, sectionName); List keys = new List(); ini.GetKeys(sectionName, keys); if (_block is IMyDoor) { parseDoor(ini, keys); } else if (_block is IMyPistonBase) { parsePiston(ini, keys); } else if (_block is IMyMotorRotor) { parseRotor(ini, keys); } } // Alternatively, the user can parse manually and override anything they // need to. public void AddAction(ISequenceableAction action, string name) { _actions.Add(action.Name, action); } private void parseDoor(MyIni ini, List keys) { foreach (MyIniKey key in keys) { string[] values = ini.Get(key).ToString().Split(','); string actionType = values[1]; bool lockDoor = true; if (values.Length >= 3) lockDoor = values[2] == "true" ? true : false; SequenceableActionDoor action = new SequenceableActionDoor( _console, key.Name, _block as IMyDoor, actionType, lockDoor ); _actions.Add(key.Name, action); } } private void parsePiston(MyIni ini, List keys) { foreach (MyIniKey key in keys) { string[] values = ini.Get(key).ToString().Split(','); float angle = Single.Parse(values[1]); float velocity = 5f; if (values.Length >= 3) velocity = Single.Parse(values[2]); MyRotationDirection dir = MyRotationDirection.AUTO; if (values.Length >= 4) { switch (values[3]) { case "cw": dir = MyRotationDirection.CW; break; case "ccw": dir = MyRotationDirection.CCW; break; } } SequenceableActionPiston action = new SequenceableActionPiston( _console, key.Name, _block as IMyPistonBase, ); _actions.Add(key.Name, action); } } private void parseRotor(MyIni ini, List keys) { foreach (MyIniKey key in keys) { string[] values = ini.Get(key).ToString().Split(','); SequenceableActionRotor action = new SequenceableActionRotor(); _actions.Add(key.Name, action); } } } } }