117 lines
4.3 KiB
C#
117 lines
4.3 KiB
C#
using Sandbox.ModAPI.Ingame;
|
|
using SpaceEngineers.Game.ModAPI.Ingame;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using VRageMath;
|
|
|
|
namespace IngameScript
|
|
{
|
|
partial class Program
|
|
{
|
|
public class AirZone
|
|
{
|
|
public string Name { get; private set; }
|
|
public bool Triggered { get; private set; } = false;
|
|
public List<IMyAirVent> Vents { get; } = new List<IMyAirVent>();
|
|
|
|
private IConsoleProgram _program;
|
|
private List<IMyDoor> _doors = new List<IMyDoor>();
|
|
private List<IMyTextSurface> _displays = new List<IMyTextSurface>();
|
|
private List<IMyLightingBlock> _lights = new List<IMyLightingBlock>();
|
|
private PrefixedConsole _console;
|
|
private Sequencer _sequencer;
|
|
|
|
private const float TriggerLevel = 0.75F;
|
|
|
|
public AirZone(string zoneName, IConsoleProgram program)
|
|
{
|
|
Name = zoneName;
|
|
_program = program;
|
|
_console = new PrefixedConsole(program.Console, zoneName);
|
|
_sequencer = new Sequencer(zoneName, _console);
|
|
}
|
|
|
|
public void AddBlock(IMyTerminalBlock block)
|
|
{
|
|
if (block is IMyAirVent)
|
|
{
|
|
Vents.Add(block as IMyAirVent);
|
|
}
|
|
else if (block is IMyDoor)
|
|
{
|
|
_doors.Add(block as IMyDoor);
|
|
SequenceableDoor wrapped = SequenceableFactory.MakeSequenceable(
|
|
block as IMyDoor,
|
|
_program.Ini,
|
|
"airMonitor") as SequenceableDoor;
|
|
wrapped.Step = 0;
|
|
wrapped.DeployOpen = false;
|
|
wrapped.LockOpen = false;
|
|
wrapped.LockClosed = true;
|
|
_sequencer.AddBlock(wrapped);
|
|
}
|
|
else if (block is IMyLightingBlock)
|
|
{
|
|
_lights.Add(block as IMyLightingBlock);
|
|
}
|
|
else
|
|
{
|
|
_console.Print("Tried to add incompatible block '{block.CustomName}'");
|
|
}
|
|
// TODO: support for arbitrary (sub-)sequences here could be powerful
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
_console.Print("Resetting sensor.");
|
|
Triggered = false;
|
|
}
|
|
|
|
// This enumerator should run forever.
|
|
public IEnumerator<bool> Monitor()
|
|
{
|
|
while (true)
|
|
{
|
|
foreach (IMyAirVent vent in Vents)
|
|
{
|
|
if (vent.GetOxygenLevel() < TriggerLevel) Triggered = true;
|
|
}
|
|
|
|
// TODO: add informational lights per-zone
|
|
if (Triggered == true)
|
|
{
|
|
_console.Print($"Low pressure alarm triggered.");
|
|
foreach (IMyLightingBlock light in _lights)
|
|
{
|
|
light.Enabled = true;
|
|
light.Color = Color.Red;
|
|
}
|
|
|
|
// close the doors
|
|
IEnumerator<bool> job = _sequencer.RunSequence(true);
|
|
while (job.MoveNext())
|
|
{
|
|
// It would be nice if the API had UpdateFrequency.Once10, e.g. "re-run in 10 ticks and then clear the flag"
|
|
// We'll just monitor every tick instead.
|
|
_program.Runtime.UpdateFrequency |= UpdateFrequency.Once;
|
|
yield return true;
|
|
}
|
|
|
|
while (Triggered) yield return true;
|
|
|
|
// unlock the doors, but we'll leave them closed.
|
|
foreach (IMyDoor door in _doors) { door.Enabled = true; }
|
|
|
|
foreach (IMyLightingBlock light in _lights)
|
|
{
|
|
light.Enabled = true;
|
|
light.Color = Color.White;
|
|
}
|
|
}
|
|
|
|
yield return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |