126 lines
4.3 KiB
C#
126 lines
4.3 KiB
C#
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 || vent.Status == VentStatus.Depressurized) return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public float OxygenLevel
|
|
{
|
|
get
|
|
{
|
|
float ret = 100F;
|
|
foreach (IMyAirVent vent in Vents)
|
|
{
|
|
if (vent.GetOxygenLevel() < ret) ret = vent.GetOxygenLevel();
|
|
}
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
public List<IMyAirVent> Vents { get; } = new List<IMyAirVent>();
|
|
|
|
private Program _program;
|
|
|
|
// private List<IMyTextSurface> _displays = new List<IMyTextSurface>(); // TODO: add single-zone displays
|
|
private List<IMyLightingBlock> _lights = new List<IMyLightingBlock>();
|
|
private List<AirDoor> _doors = new List<AirDoor>();
|
|
private PrefixedConsole _console;
|
|
private ActionSequence _sealBulkheads; // actions to perform when the pressure alarm is triggered
|
|
|
|
private const float TriggerLevel = 0.75F;
|
|
|
|
public AirZone(Program program, string zoneName)
|
|
{
|
|
Name = zoneName;
|
|
_program = program;
|
|
_console = new PrefixedConsole(_program.Console, Name);
|
|
_sealBulkheads = new ActionSequence(Name);
|
|
}
|
|
|
|
public void AddDoor(AirDoor door)
|
|
{
|
|
_doors.Add(door);
|
|
IMyDoor doorBlock = door.Door;
|
|
_sealBulkheads.Add(0, new BlockActionDoor(
|
|
doorBlock,
|
|
DoorAction.Close,
|
|
true
|
|
));
|
|
}
|
|
|
|
public void AddBlock(IMyTerminalBlock block)
|
|
{
|
|
if (block is IMyAirVent)
|
|
{
|
|
Vents.Add(block as IMyAirVent);
|
|
}
|
|
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<bool> Monitor()
|
|
{
|
|
while (true)
|
|
{
|
|
if (Triggered == true)
|
|
{
|
|
_console.Print($"Low pressure alarm triggered.");
|
|
// close the doors
|
|
IEnumerator<bool> job = _sealBulkheads.Run();
|
|
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.
|
|
setTriggeredStates();
|
|
_program.Runtime.UpdateFrequency |= UpdateFrequency.Once;
|
|
yield return true;
|
|
}
|
|
job.Dispose();
|
|
|
|
while (Triggered)
|
|
{
|
|
setTriggeredStates();
|
|
yield return true;
|
|
}
|
|
_console.Print("Air pressure returned to safe levels.");
|
|
}
|
|
|
|
yield return true;
|
|
}
|
|
}
|
|
|
|
private void setTriggeredStates()
|
|
{
|
|
foreach (IMyLightingBlock light in _lights) light.Color = Color.Red;
|
|
foreach (AirDoor door in _doors) door.Triggered = true;
|
|
}
|
|
}
|
|
}
|
|
} |