monitors will now always alarm if threshold types have been tripped/reset to normal on update

This commit is contained in:
vulppine
2022-08-22 17:42:47 -07:00
parent 901670c2ea
commit 8de6193ff2
2 changed files with 51 additions and 24 deletions

View File

@@ -59,6 +59,8 @@ namespace Content.Server.Atmos.Monitor.Components
[ViewVariables] [ViewVariables]
public AtmosMonitorAlarmType LastAlarmState = AtmosMonitorAlarmType.Normal; public AtmosMonitorAlarmType LastAlarmState = AtmosMonitorAlarmType.Normal;
public HashSet<AtmosMonitorThresholdType> TrippedThresholds = new();
/// <summary> /// <summary>
/// Registered devices in this atmos monitor. Alerts will be sent directly /// Registered devices in this atmos monitor. Alerts will be sent directly
/// to these devices. /// to these devices.

View File

@@ -177,7 +177,10 @@ namespace Content.Server.Atmos.Monitor.Systems
// somebody else can reset it :sunglasses: // somebody else can reset it :sunglasses:
if (component.MonitorFire if (component.MonitorFire
&& component.LastAlarmState != AtmosMonitorAlarmType.Danger) && component.LastAlarmState != AtmosMonitorAlarmType.Danger)
Alert(uid, AtmosMonitorAlarmType.Danger, new []{ AtmosMonitorThresholdType.Temperature }, component); // technically??? {
component.TrippedThresholds.Add(AtmosMonitorThresholdType.Temperature);
Alert(uid, AtmosMonitorAlarmType.Danger, null, component); // technically???
}
// only monitor state elevation so that stuff gets alarmed quicker during a fire, // only monitor state elevation so that stuff gets alarmed quicker during a fire,
// let the atmos update loop handle when temperature starts to reach different // let the atmos update loop handle when temperature starts to reach different
@@ -185,7 +188,10 @@ namespace Content.Server.Atmos.Monitor.Systems
if (component.TemperatureThreshold != null if (component.TemperatureThreshold != null
&& component.TemperatureThreshold.CheckThreshold(args.Temperature, out var temperatureState) && component.TemperatureThreshold.CheckThreshold(args.Temperature, out var temperatureState)
&& temperatureState > component.LastAlarmState) && temperatureState > component.LastAlarmState)
Alert(uid, AtmosMonitorAlarmType.Danger, new []{ AtmosMonitorThresholdType.Temperature }, component); {
component.TrippedThresholds.Add(AtmosMonitorThresholdType.Temperature);
Alert(uid, AtmosMonitorAlarmType.Danger, null, component);
}
} }
private void OnAtmosUpdate(EntityUid uid, AtmosMonitorComponent component, AtmosDeviceUpdateEvent args) private void OnAtmosUpdate(EntityUid uid, AtmosMonitorComponent component, AtmosDeviceUpdateEvent args)
@@ -224,26 +230,40 @@ namespace Content.Server.Atmos.Monitor.Systems
if (!Resolve(uid, ref monitor)) return; if (!Resolve(uid, ref monitor)) return;
AtmosMonitorAlarmType state = AtmosMonitorAlarmType.Normal; AtmosMonitorAlarmType state = AtmosMonitorAlarmType.Normal;
List<AtmosMonitorThresholdType> alarmTypes = new(); HashSet<AtmosMonitorThresholdType> alarmTypes = new(monitor.TrippedThresholds);
if (monitor.TemperatureThreshold != null if (monitor.TemperatureThreshold != null
&& monitor.TemperatureThreshold.CheckThreshold(air.Temperature, out var temperatureState) && monitor.TemperatureThreshold.CheckThreshold(air.Temperature, out var temperatureState))
&& temperatureState > state) {
if (temperatureState > state)
{ {
state = temperatureState; state = temperatureState;
alarmTypes.Add(AtmosMonitorThresholdType.Temperature); alarmTypes.Add(AtmosMonitorThresholdType.Temperature);
} }
else if (temperatureState == AtmosMonitorAlarmType.Normal)
{
alarmTypes.Remove(AtmosMonitorThresholdType.Temperature);
}
}
if (monitor.PressureThreshold != null if (monitor.PressureThreshold != null
&& monitor.PressureThreshold.CheckThreshold(air.Pressure, out var pressureState) && monitor.PressureThreshold.CheckThreshold(air.Pressure, out var pressureState)
&& pressureState > state) )
{
if (pressureState > state)
{ {
state = pressureState; state = pressureState;
alarmTypes.Add(AtmosMonitorThresholdType.Pressure); alarmTypes.Add(AtmosMonitorThresholdType.Pressure);
} }
else if (pressureState == AtmosMonitorAlarmType.Normal)
{
alarmTypes.Remove(AtmosMonitorThresholdType.Pressure);
}
}
if (monitor.GasThresholds != null) if (monitor.GasThresholds != null)
{ {
var tripped = false;
foreach (var (gas, threshold) in monitor.GasThresholds) foreach (var (gas, threshold) in monitor.GasThresholds)
{ {
var gasRatio = air.GetMoles(gas) / air.TotalMoles; var gasRatio = air.GetMoles(gas) / air.TotalMoles;
@@ -251,14 +271,23 @@ namespace Content.Server.Atmos.Monitor.Systems
&& gasState > state) && gasState > state)
{ {
state = gasState; state = gasState;
tripped = true;
}
}
if (tripped)
{
alarmTypes.Add(AtmosMonitorThresholdType.Gas); alarmTypes.Add(AtmosMonitorThresholdType.Gas);
} }
else
{
alarmTypes.Remove(AtmosMonitorThresholdType.Gas);
} }
} }
// if the state of the current air doesn't match the last alarm state, // if the state of the current air doesn't match the last alarm state,
// we update the state // we update the state
if (state != monitor.LastAlarmState) if (state != monitor.LastAlarmState && !alarmTypes.SetEquals(monitor.TrippedThresholds))
{ {
Alert(uid, state, alarmTypes, monitor); Alert(uid, state, alarmTypes, monitor);
} }
@@ -269,14 +298,14 @@ namespace Content.Server.Atmos.Monitor.Systems
/// </summary> /// </summary>
/// <param name="state">The alarm state to set this monitor to.</param> /// <param name="state">The alarm state to set this monitor to.</param>
/// <param name="alarms">The alarms that caused this alarm state.</param> /// <param name="alarms">The alarms that caused this alarm state.</param>
public void Alert(EntityUid uid, AtmosMonitorAlarmType state, IEnumerable<AtmosMonitorThresholdType>? alarms = null, AtmosMonitorComponent? monitor = null) public void Alert(EntityUid uid, AtmosMonitorAlarmType state, HashSet<AtmosMonitorThresholdType>? alarms = null, AtmosMonitorComponent? monitor = null)
{ {
if (!Resolve(uid, ref monitor)) return; if (!Resolve(uid, ref monitor)) return;
monitor.LastAlarmState = state;
if (EntityManager.TryGetComponent(monitor.Owner, out AppearanceComponent? appearanceComponent))
appearanceComponent.SetData(AtmosMonitorVisuals.AlarmType, monitor.LastAlarmState);
BroadcastAlertPacket(monitor, alarms); monitor.LastAlarmState = state;
monitor.TrippedThresholds = alarms ?? monitor.TrippedThresholds;
BroadcastAlertPacket(monitor);
// TODO: Central system that grabs *all* alarms from wired network // TODO: Central system that grabs *all* alarms from wired network
} }
@@ -302,7 +331,7 @@ namespace Content.Server.Atmos.Monitor.Systems
/// is synced between monitors the moment a monitor sends out an alarm, /// is synced between monitors the moment a monitor sends out an alarm,
/// or if it is explicitly synced (see ResetAll/Sync). /// or if it is explicitly synced (see ResetAll/Sync).
/// </remarks> /// </remarks>
private void BroadcastAlertPacket(AtmosMonitorComponent monitor, IEnumerable<AtmosMonitorThresholdType>? alarms = null, TagComponent? tags = null) private void BroadcastAlertPacket(AtmosMonitorComponent monitor, TagComponent? tags = null)
{ {
if (!monitor.NetEnabled) return; if (!monitor.NetEnabled) return;
@@ -315,14 +344,10 @@ namespace Content.Server.Atmos.Monitor.Systems
{ {
[DeviceNetworkConstants.Command] = AtmosAlarmableSystem.AlertCmd, [DeviceNetworkConstants.Command] = AtmosAlarmableSystem.AlertCmd,
[DeviceNetworkConstants.CmdSetState] = monitor.LastAlarmState, [DeviceNetworkConstants.CmdSetState] = monitor.LastAlarmState,
[AtmosAlarmableSystem.AlertSource] = tags.Tags [AtmosAlarmableSystem.AlertSource] = tags.Tags,
[AtmosAlarmableSystem.AlertTypes] = monitor.TrippedThresholds
}; };
if (alarms != null)
{
payload.Add(AtmosAlarmableSystem.AlertTypes, alarms.ToHashSet());
}
foreach (var addr in monitor.RegisteredDevices) foreach (var addr in monitor.RegisteredDevices)
{ {
_deviceNetSystem.QueuePacket(monitor.Owner, addr, payload); _deviceNetSystem.QueuePacket(monitor.Owner, addr, payload);