space_engineers/Mixins/Sequencer/SequenceableBlock.cs

132 lines
4.6 KiB
C#

// 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<bool> Run();
}
public class SequenceableBlock
{
private IConsole _console;
private IMyTerminalBlock _block;
private Dictionary<string, ISequenceableAction> _actions = new Dictionary<string, ISequenceableAction>();
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<MyIniKey> keys = new List<MyIniKey>();
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<MyIniKey> 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<MyIniKey> 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<MyIniKey> keys)
{
foreach (MyIniKey key in keys)
{
string[] values = ini.Get(key).ToString().Split(',');
SequenceableActionRotor action = new SequenceableActionRotor();
_actions.Add(key.Name, action);
}
}
}
}
}