using Sandbox.ModAPI.Ingame; using SpaceEngineers.Game.ModAPI.Ingame; using System.Collections.Generic; using VRageMath; namespace IngameScript { partial class Program { public class AirZone { public string Name { get; private set; } public bool Triggered { get { foreach (IMyAirVent vent in Vents) { if (vent.GetOxygenLevel() < TriggerLevel) return true; } return false; } } public List Vents { get; } = new List(); private Program _program; private List _doors = new List(); private List _displays = new List(); private List _lights = new List(); private PrefixedConsole _console; private Sequencer _sequencer; private const float TriggerLevel = 0.75F; public AirZone(Program program, string zoneName) { Name = zoneName; _program = program; _console = new PrefixedConsole(_program.Console, Name); _sequencer = new Sequencer(_program, Name); } 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( _program, block as IMyDoor, "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 } // This enumerator should run forever. public IEnumerator Monitor() { while (true) { if (Triggered == true) { _console.Print($"Low pressure alarm triggered."); // close the doors IEnumerator 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; } job.Dispose(); 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; } } public void SetLights() { bool warning = false; foreach (IMyAirVent vent in Vents) { if (vent.GetOxygenLevel() < TriggerLevel) { warning = true; break; } } foreach (IMyLightingBlock light in _lights) { if (warning) { light.Enabled = true; light.Color = Color.Red; } else light.Color = Color.White; } } } } }