diff --git a/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs b/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs index ce96bb755b..b52a85ca08 100644 --- a/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs @@ -33,40 +33,19 @@ namespace Content.Server.Atmos.Monitor.Systems { [Dependency] private readonly DeviceNetworkSystem _deviceNet = default!; [Dependency] private readonly AtmosDeviceNetworkSystem _atmosDevNetSystem = default!; + [Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly AccessReaderSystem _accessSystem = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; #region Device Network API - /// - /// Command to set device data within the air alarm's network. - /// - public const string AirAlarmSetData = "air_alarm_set_device_data"; - - /// - /// Command to request a sync from devices in an air alarm's network. - /// - public const string AirAlarmSyncCmd = "air_alarm_sync_devices"; /// /// Command to set an air alarm's mode. /// public const string AirAlarmSetMode = "air_alarm_set_mode"; - // -- Packet Data -- - - /// - /// Data response to an AirAlarmSetData command. - /// - public const string AirAlarmSetDataStatus = "air_alarm_set_device_data_status"; - - /// - /// Data response to an AirAlarmSync command. Contains - /// IAtmosDeviceData in this system's implementation. - /// - public const string AirAlarmSyncData = "air_alarm_device_sync_data"; - // -- API -- /// @@ -408,7 +387,7 @@ namespace Content.Server.Atmos.Monitor.Systems switch (cmd) { case AtmosDeviceNetworkSystem.SyncData: - if (!args.Data.TryGetValue(AirAlarmSyncData, out IAtmosDeviceData? data) + if (!args.Data.TryGetValue(AtmosDeviceNetworkSystem.SyncData, out IAtmosDeviceData? data) || !controller.CanSync) break; @@ -532,10 +511,15 @@ namespace Content.Server.Atmos.Monitor.Systems var deviceCount = alarm.VentData.Count + alarm.ScrubberData.Count + alarm.SensorData.Count; + if (!_atmosAlarmable.TryGetHighestAlert(uid, out var highestAlarm)) + { + highestAlarm = AtmosMonitorAlarmType.Normal; + } + _uiSystem.TrySetUiState( uid, SharedAirAlarmInterfaceKey.Key, - new AirAlarmUIState(devNet.Address, deviceCount, pressure, temperature, dataToSend, alarm.CurrentMode, alarm.CurrentTab, alarmable.HighestNetworkState)); + new AirAlarmUIState(devNet.Address, deviceCount, pressure, temperature, dataToSend, alarm.CurrentMode, alarm.CurrentTab, highestAlarm.Value)); } private const float _delay = 8f; diff --git a/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs b/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs index db8db150a8..4a2dd208c6 100644 --- a/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs @@ -5,6 +5,7 @@ using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; using Content.Server.Power.Components; using Content.Shared.Atmos.Monitor; +using Content.Shared.Tag; using Robust.Server.GameObjects; using Robust.Shared.Audio; using Robust.Shared.Utility; @@ -57,7 +58,7 @@ namespace Content.Server.Atmos.Monitor.Systems return; if (!args.Data.TryGetValue(DeviceNetworkConstants.Command, out string? cmd) - || !args.Data.TryGetValue(AlertSource, out List? sourceTags)) + || !args.Data.TryGetValue(AlertSource, out HashSet? sourceTags)) { return; } @@ -101,11 +102,7 @@ namespace Content.Server.Atmos.Monitor.Systems netMax = AtmosMonitorAlarmType.Normal; } - component.LastAlarmState = netMax.Value; - - UpdateAppearance(uid, netMax.Value); - PlayAlertSound(uid, netMax.Value, component); - RaiseLocalEvent(component.Owner, new AtmosMonitorAlarmEvent(state, netMax.Value), true); + TryUpdateAlert(uid, netMax.Value, component); break; case ResetAll: @@ -128,20 +125,32 @@ namespace Content.Server.Atmos.Monitor.Systems } } - if (TryGetHighestAlert(uid, out var maxAlert, component) - && component.LastAlarmState < maxAlert) + if (TryGetHighestAlert(uid, out var maxAlert, component)) { - component.LastAlarmState = maxAlert.Value; - RaiseLocalEvent(uid, new AtmosMonitorAlarmEvent(maxAlert.Value, maxAlert.Value)); + TryUpdateAlert(uid, maxAlert.Value, component); } break; } } - public void SyncAlertsToNetwork(EntityUid uid, string? address = null, AtmosAlarmableComponent? alarmable = null) + private void TryUpdateAlert(EntityUid uid, AtmosMonitorAlarmType type, AtmosAlarmableComponent alarmable) { - if (!Resolve(uid, ref alarmable) || alarmable.ReceiveOnly) + if (alarmable.LastAlarmState == type) + { + return; + } + + alarmable.LastAlarmState = type; + UpdateAppearance(uid, type); + PlayAlertSound(uid, type, alarmable); + SyncAlertsToNetwork(uid, null, alarmable); + RaiseLocalEvent(uid, new AtmosMonitorAlarmEvent(type, type), true); + } + + public void SyncAlertsToNetwork(EntityUid uid, string? address = null, AtmosAlarmableComponent? alarmable = null, TagComponent? tags = null) + { + if (!Resolve(uid, ref alarmable, ref tags) || alarmable.ReceiveOnly) { return; } @@ -150,7 +159,7 @@ namespace Content.Server.Atmos.Monitor.Systems { [DeviceNetworkConstants.Command] = SyncAlerts, [SyncAlerts] = alarmable.NetworkAlarmStates, - [AlertSource] = alarmable.SyncWithTags + [AlertSource] = tags.Tags }; _deviceNet.QueuePacket(uid, address, payload); @@ -158,22 +167,28 @@ namespace Content.Server.Atmos.Monitor.Systems /// /// Forces this alarmable to have a specific alert. This will not be reset until the alarmable - /// is manually reset. This will store the alarmable as a device in its network states, and sync - /// it to the rest of the network. + /// is manually reset. This will store the alarmable as a device in its network states. /// /// /// /// public void ForceAlert(EntityUid uid, AtmosMonitorAlarmType alarmType, - AtmosAlarmableComponent? alarmable = null, DeviceNetworkComponent? devNet = null) + AtmosAlarmableComponent? alarmable = null, DeviceNetworkComponent? devNet = null, TagComponent? tags = null) { - if (!Resolve(uid, ref alarmable, ref devNet)) + if (!Resolve(uid, ref alarmable, ref devNet, ref tags)) { return; } alarmable.LastAlarmState = alarmType; + RaiseLocalEvent(uid, new AtmosMonitorAlarmEvent(alarmType, alarmType)); + + if (alarmable.ReceiveOnly) + { + return; + } + if (!alarmable.NetworkAlarmStates.TryAdd(devNet.Address, alarmType)) { alarmable.NetworkAlarmStates[devNet.Address] = alarmType; @@ -183,12 +198,10 @@ namespace Content.Server.Atmos.Monitor.Systems { [DeviceNetworkConstants.Command] = AlertCmd, [DeviceNetworkConstants.CmdSetState] = alarmType, - [AlertSource] = alarmable.SyncWithTags + [AlertSource] = tags.Tags }; _deviceNet.QueuePacket(uid, null, payload); - - RaiseLocalEvent(uid, new AtmosMonitorAlarmEvent(alarmType, alarmType)); } /// @@ -206,24 +219,22 @@ namespace Content.Server.Atmos.Monitor.Systems alarmable.LastAlarmState = AtmosMonitorAlarmType.Normal; alarmable.NetworkAlarmStates.Clear(); - SyncAlertsToNetwork(uid); RaiseLocalEvent(uid, new AtmosMonitorAlarmEvent(AtmosMonitorAlarmType.Normal, AtmosMonitorAlarmType.Normal)); } - public void ResetAllOnNetwork(EntityUid uid, AtmosAlarmableComponent? alarmable = null) + public void ResetAllOnNetwork(EntityUid uid, AtmosAlarmableComponent? alarmable = null, TagComponent? tags = null) { - if (!Resolve(uid, ref alarmable)) + if (!Resolve(uid, ref alarmable, ref tags) || alarmable.ReceiveOnly) { return; } - alarmable.LastAlarmState = AtmosMonitorAlarmType.Normal; - alarmable.NetworkAlarmStates.Clear(); + Reset(uid, alarmable); var payload = new NetworkPayload { [DeviceNetworkConstants.Command] = ResetAll, - [AlertSource] = alarmable.SyncWithTags + [AlertSource] = tags.Tags }; _deviceNet.QueuePacket(uid, null, payload); diff --git a/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs b/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs index 4e7f94de59..f0113e6039 100644 --- a/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs @@ -343,10 +343,12 @@ namespace Content.Server.Atmos.Monitor.Systems } + /* string source = string.Empty; if (alarms == null) alarms = new List(); var prototype = Prototype(monitor.Owner); if (prototype != null) source = prototype.ID; + */ var payload = new NetworkPayload { diff --git a/Content.Server/Atmos/Monitor/Systems/FireAlarmSystem.cs b/Content.Server/Atmos/Monitor/Systems/FireAlarmSystem.cs index 829728c504..981bbe012f 100644 --- a/Content.Server/Atmos/Monitor/Systems/FireAlarmSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/FireAlarmSystem.cs @@ -12,7 +12,7 @@ namespace Content.Server.Atmos.Monitor.Systems { public sealed class FireAlarmSystem : EntitySystem { - [Dependency] private readonly AtmosMonitorSystem _monitorSystem = default!; + [Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; public override void Initialize() @@ -26,17 +26,20 @@ namespace Content.Server.Atmos.Monitor.Systems if (!_interactionSystem.InRangeUnobstructed(args.User, args.Target)) return; - if (EntityManager.TryGetComponent(args.User, out ActorComponent? actor) - && EntityManager.TryGetComponent(uid, out AtmosMonitorComponent? monitor) - && this.IsPowered(uid, EntityManager)) + if (this.IsPowered(uid, EntityManager)) { - if (monitor.HighestAlarmInNetwork == AtmosMonitorAlarmType.Normal) + if (!_atmosAlarmable.TryGetHighestAlert(uid, out var alarm)) { - _monitorSystem.Alert(uid, AtmosMonitorAlarmType.Danger); + alarm = AtmosMonitorAlarmType.Normal; + } + + if (alarm == AtmosMonitorAlarmType.Normal) + { + _atmosAlarmable.ForceAlert(uid, AtmosMonitorAlarmType.Danger); } else { - _monitorSystem.ResetAll(uid); + _atmosAlarmable.ResetAllOnNetwork(uid); } } } @@ -48,7 +51,7 @@ namespace Content.Server.Atmos.Monitor.Systems if (atmosMonitor?.MonitorFire == true) { atmosMonitor.MonitorFire = false; - _monitorSystem.Alert(uid, AtmosMonitorAlarmType.Emagged); + _atmosAlarmable.ForceAlert(uid, AtmosMonitorAlarmType.Emagged); args.Handled = true; } } diff --git a/Content.Server/Atmos/Monitor/WireActions/AtmosMonitorAlarmWire.cs b/Content.Server/Atmos/Monitor/WireActions/AtmosMonitorAlarmWire.cs index 7fde988084..b3c3247749 100644 --- a/Content.Server/Atmos/Monitor/WireActions/AtmosMonitorAlarmWire.cs +++ b/Content.Server/Atmos/Monitor/WireActions/AtmosMonitorAlarmWire.cs @@ -17,7 +17,7 @@ public sealed class AtmosMonitorDeviceNetWire : BaseWireAction private string _text = "NETW"; private Color _color = Color.Orange; - private AtmosMonitorSystem _atmosMonitorSystem = default!; + private AtmosAlarmableSystem _atmosAlarmableSystem = default!; public override object StatusKey { get; } = AtmosMonitorAlarmWireActionKeys.Network; @@ -27,7 +27,12 @@ public sealed class AtmosMonitorDeviceNetWire : BaseWireAction if (IsPowered(wire.Owner) && EntityManager.TryGetComponent(wire.Owner, out var monitor)) { - lightState = monitor.HighestAlarmInNetwork == AtmosMonitorAlarmType.Danger + if (!_atmosAlarmableSystem.TryGetHighestAlert(wire.Owner, out var alarm)) + { + alarm = AtmosMonitorAlarmType.Normal; + } + + lightState = alarm == AtmosMonitorAlarmType.Danger ? StatusLightState.BlinkingFast : StatusLightState.On; } @@ -42,7 +47,7 @@ public sealed class AtmosMonitorDeviceNetWire : BaseWireAction { base.Initialize(); - _atmosMonitorSystem = EntitySystem.Get(); + _atmosAlarmableSystem = EntitySystem.Get(); } public override bool Cut(EntityUid user, Wire wire) @@ -69,7 +74,7 @@ public sealed class AtmosMonitorDeviceNetWire : BaseWireAction { if (_alarmOnPulse) { - _atmosMonitorSystem.Alert(wire.Owner, AtmosMonitorAlarmType.Danger); + _atmosAlarmableSystem.ForceAlert(wire.Owner, AtmosMonitorAlarmType.Danger); } return true; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs index 4507f56dfe..1437c50f7a 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs @@ -195,8 +195,8 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems _deviceNetSystem.QueuePacket(uid, args.SenderAddress, payload, device: netConn); return; - case AtmosDeviceNetworkSystem.SetState: - if (!args.Data.TryGetValue(AtmosDeviceNetworkSystem.SetState, out GasVentPumpData? setData)) + case DeviceNetworkConstants.CmdSetState: + if (!args.Data.TryGetValue(DeviceNetworkConstants.CmdSetState, out GasVentPumpData? setData)) break; component.FromAirAlarmData(setData); diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs index de3b9b6c4a..3a9c70205a 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs @@ -161,8 +161,8 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems _deviceNetSystem.QueuePacket(uid, args.SenderAddress, payload, device: netConn); return; - case AtmosDeviceNetworkSystem.SetState: - if (!args.Data.TryGetValue(AtmosDeviceNetworkSystem.SetState, out GasVentScrubberData? setData)) + case DeviceNetworkConstants.CmdSetState: + if (!args.Data.TryGetValue(DeviceNetworkConstants.CmdSetState, out GasVentScrubberData? setData)) break; component.FromAirAlarmData(setData); diff --git a/Content.Server/Doors/Systems/FirelockSystem.cs b/Content.Server/Doors/Systems/FirelockSystem.cs index 42bdba35ba..b959405dd1 100644 --- a/Content.Server/Doors/Systems/FirelockSystem.cs +++ b/Content.Server/Doors/Systems/FirelockSystem.cs @@ -12,6 +12,7 @@ namespace Content.Server.Doors.Systems public sealed class FirelockSystem : EntitySystem { [Dependency] private readonly SharedDoorSystem _doorSystem = default!; + [Dependency] private readonly AtmosAlarmableSystem _atmosAlarmable = default!; public override void Initialize() { @@ -65,12 +66,7 @@ namespace Content.Server.Doors.Systems // Make firelocks autoclose, but only if the last alarm type it // remembers was a danger. This is to prevent people from // flooding hallways with endless bad air/fire. - if (!EntityManager.TryGetComponent(uid, out AtmosAlarmableComponent? alarmable)) - { - args.Cancel(); - return; - } - if (alarmable.HighestNetworkState != AtmosMonitorAlarmType.Danger) + if (_atmosAlarmable.TryGetHighestAlert(uid, out var alarm) && alarm == AtmosMonitorAlarmType.Danger) args.Cancel(); }