diff --git a/Content.Server/Atmos/Monitor/Components/AtmosAlarmableComponent.cs b/Content.Server/Atmos/Monitor/Components/AtmosAlarmableComponent.cs index b762df7b02..c9435bdef6 100644 --- a/Content.Server/Atmos/Monitor/Components/AtmosAlarmableComponent.cs +++ b/Content.Server/Atmos/Monitor/Components/AtmosAlarmableComponent.cs @@ -1,4 +1,5 @@ using Content.Shared.Atmos.Monitor; +using Robust.Shared.Audio; namespace Content.Server.Atmos.Monitor.Components { @@ -30,6 +31,12 @@ namespace Content.Server.Atmos.Monitor.Components [ViewVariables] public AtmosMonitorAlarmType HighestNetworkState = AtmosMonitorAlarmType.Normal; [ViewVariables] public bool IgnoreAlarms { get; set; } = false; + [DataField("alarmSound")] + public SoundSpecifier AlarmSound { get; set; } = new SoundPathSpecifier("/Audio/Machines/alarm.ogg"); + + [DataField("alarmVolume")] + public float AlarmVolume { get; set; } = -10; + /// /// List of prototypes that this alarmable can be /// alarmed by - must be a prototype with AtmosMonitor diff --git a/Content.Server/Atmos/Monitor/Components/AtmosMonitorComponent.cs b/Content.Server/Atmos/Monitor/Components/AtmosMonitorComponent.cs index a8c56439e6..d741be8ad1 100644 --- a/Content.Server/Atmos/Monitor/Components/AtmosMonitorComponent.cs +++ b/Content.Server/Atmos/Monitor/Components/AtmosMonitorComponent.cs @@ -46,15 +46,6 @@ namespace Content.Server.Atmos.Monitor.Components [DataField("monitorFire")] public bool MonitorFire = false; - [DataField("displayMaxAlarmInNet")] - public bool DisplayMaxAlarmInNet = false; - - [DataField("alarmSound")] - public SoundSpecifier AlarmSound { get; set; } = new SoundPathSpecifier("/Audio/Machines/alarm.ogg"); - - [DataField("alarmVolume")] - public float AlarmVolume { get; set; } = -10; - // really messy but this is parsed at runtime after // prototypes are initialized, there's no // way without implementing a new diff --git a/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs b/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs index d70268d513..d0d0246989 100644 --- a/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs @@ -516,7 +516,6 @@ namespace Content.Server.Atmos.Monitor.Systems public void ForceCloseAllInterfaces(EntityUid uid) { _uiSystem.TryCloseAll(uid, SharedAirAlarmInterfaceKey.Key); - RemoveActiveInterface(uid); } public void OnAtmosUpdate(EntityUid uid, AirAlarmComponent alarm, AtmosDeviceUpdateEvent args) diff --git a/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs b/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs index ae8664ac54..b38916567e 100644 --- a/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs @@ -4,12 +4,14 @@ using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; using Content.Shared.Atmos.Monitor; using Robust.Server.GameObjects; +using Robust.Shared.Audio; namespace Content.Server.Atmos.Monitor.Systems { public sealed class AtmosAlarmableSystem : EntitySystem { [Dependency] private readonly AppearanceSystem _appearance = default!; + [Dependency] private readonly AudioSystem _audioSystem = default!; public override void Initialize() { SubscribeLocalEvent(OnPacketRecv); @@ -37,11 +39,20 @@ namespace Content.Server.Atmos.Monitor.Systems component.LastAlarmState = state; component.HighestNetworkState = netMax; UpdateAppearance(uid, netMax); + PlayAlertSound(uid, netMax, component); RaiseLocalEvent(component.Owner, new AtmosMonitorAlarmEvent(state, netMax), true); } } } + private void PlayAlertSound(EntityUid uid, AtmosMonitorAlarmType alarm, AtmosAlarmableComponent alarmable) + { + if (alarm == AtmosMonitorAlarmType.Danger) + { + _audioSystem.PlayPvs(alarmable.AlarmSound, uid, AudioParams.Default.WithVolume(alarmable.AlarmVolume)); + } + } + private void UpdateAppearance(EntityUid uid, AtmosMonitorAlarmType alarm) { _appearance.SetData(uid, AtmosMonitorVisuals.AlarmType, alarm); diff --git a/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs b/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs index d94f97d801..1b192c4ca8 100644 --- a/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs @@ -44,6 +44,8 @@ namespace Content.Server.Atmos.Monitor.Systems /// public const string AtmosMonitorAlarmResetAllCmd = "atmos_monitor_alarm_reset_all"; + public const string AtmosMonitorSetThresholdData = "atmos_monitor_set_threshold"; + // Packet data /// /// Data response that contains the threshold types in an atmos monitor alarm. @@ -60,6 +62,13 @@ namespace Content.Server.Atmos.Monitor.Systems /// public const string AtmosMonitorAlarmNetMax = "atmos_monitor_alarm_net_max"; + /// + /// Data response that contains the last state recorded by this air monitor. + /// + public const string AtmosMonitorAtmosData = "atmos_monitor_atmos_data"; + + public const string AtmosMonitorThresholdData = "atmos_monitor_threshold_data"; + public override void Initialize() { SubscribeLocalEvent(OnAtmosMonitorInit); @@ -189,16 +198,42 @@ namespace Content.Server.Atmos.Monitor.Systems component.NetworkAlarmStates.Clear(); } break; + case AirAlarmSystem.AirAlarmSyncCmd: + var payload = new NetworkPayload(); + payload.Add(DeviceNetworkConstants.Command, AirAlarmSystem.AirAlarmSyncData); + if (component.TileGas != null) + { + var gases = new Dictionary(); + foreach (var gas in Enum.GetValues()) + { + gases.Add(gas, component.TileGas.GetMoles(gas)); + } + + payload.Add(AtmosMonitorAtmosData, new AtmosSensorData( + component.TileGas.Pressure, + component.TileGas.Temperature, + component.TileGas.TotalMoles, + component.HighestAlarmInNetwork, + gases, + false, + component.PressureThreshold ?? new(), + component.TemperatureThreshold ?? new(), + component.GasThresholds ?? new() + )); + } + + _deviceNetSystem.QueuePacket(uid, args.SenderAddress, payload); + break; } + /* if (component.DisplayMaxAlarmInNet) { if (EntityManager.TryGetComponent(component.Owner, out AppearanceComponent? appearanceComponent)) appearanceComponent.SetData(AtmosMonitorVisuals.AlarmType, component.HighestAlarmInNetwork); - if (component.HighestAlarmInNetwork == AtmosMonitorAlarmType.Danger) PlayAlertSound(uid, component); } - + */ } private void OnPowerChangedEvent(EntityUid uid, AtmosMonitorComponent component, PowerChangedEvent args) @@ -344,21 +379,12 @@ namespace Content.Server.Atmos.Monitor.Systems BroadcastAlertPacket(monitor, alarms); - if (state == AtmosMonitorAlarmType.Danger) PlayAlertSound(uid, monitor); - if (EntityManager.TryGetComponent(monitor.Owner, out AtmosAlarmableComponent? alarmable) && !alarmable.IgnoreAlarms) RaiseLocalEvent(monitor.Owner, new AtmosMonitorAlarmEvent(monitor.LastAlarmState, monitor.HighestAlarmInNetwork), true); // TODO: Central system that grabs *all* alarms from wired network } - private void PlayAlertSound(EntityUid uid, AtmosMonitorComponent? monitor = null) - { - if (!Resolve(uid, ref monitor)) return; - - SoundSystem.Play(monitor.AlarmSound.GetSound(), Filter.Pvs(uid), uid, AudioParams.Default.WithVolume(monitor.AlarmVolume)); - } - /// /// Resets a single monitor's alarm. /// diff --git a/Content.Shared/Atmos/Monitor/AtmosAlarmThresholdPrototype.cs b/Content.Shared/Atmos/Monitor/AtmosAlarmThresholdPrototype.cs index 68ac59b86d..31f077206e 100644 --- a/Content.Shared/Atmos/Monitor/AtmosAlarmThresholdPrototype.cs +++ b/Content.Shared/Atmos/Monitor/AtmosAlarmThresholdPrototype.cs @@ -52,6 +52,9 @@ namespace Content.Shared.Atmos.Monitor get => CalculateWarningBound(AtmosMonitorThresholdBound.Lower); } + public AtmosAlarmThreshold() + {} + public AtmosAlarmThreshold(AtmosAlarmThreshold other) { Ignore = other.Ignore; diff --git a/Content.Shared/Atmos/Monitor/AtmosSensorData.cs b/Content.Shared/Atmos/Monitor/AtmosSensorData.cs index 81adf5d91c..3cb2f09be5 100644 --- a/Content.Shared/Atmos/Monitor/AtmosSensorData.cs +++ b/Content.Shared/Atmos/Monitor/AtmosSensorData.cs @@ -4,6 +4,19 @@ namespace Content.Shared.Atmos.Monitor; public sealed class AtmosSensorData : IAtmosDeviceData { + public AtmosSensorData(float pressure, float temperature, float totalMoles, AtmosMonitorAlarmType alarmState, Dictionary gases, bool onFire, AtmosAlarmThreshold pressureThreshold, AtmosAlarmThreshold temperatureThreshold, Dictionary gasThresholds) + { + Pressure = pressure; + Temperature = temperature; + TotalMoles = totalMoles; + AlarmState = alarmState; + Gases = gases; + OnFire = onFire; + PressureThreshold = pressureThreshold; + TemperatureThreshold = temperatureThreshold; + GasThresholds = gasThresholds; + } + public bool Enabled { get; set; } public bool Dirty { get; set; } public bool IgnoreAlarms { get; set; } @@ -13,15 +26,15 @@ public sealed class AtmosSensorData : IAtmosDeviceData /// /// Current pressure detected by this sensor. /// - public float? Pressure { get; } + public float Pressure { get; } /// /// Current temperature detected by this sensor. /// - public float? Temperature { get; } + public float Temperature { get; } /// /// Current amount of moles detected by this sensor. /// - public float? TotalMoles { get; } + public float TotalMoles { get; } /// /// Current alarm state of this sensor. Does not reflect the highest alarm state on the network. /// @@ -34,4 +47,8 @@ public sealed class AtmosSensorData : IAtmosDeviceData /// If this sensor is currently detecting a fire. /// public bool OnFire { get; } + + public AtmosAlarmThreshold PressureThreshold { get; } + public AtmosAlarmThreshold TemperatureThreshold { get; } + public Dictionary GasThresholds { get; } }