alert sounds from alarmables, sensor data ctor
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using Content.Shared.Atmos.Monitor;
|
using Content.Shared.Atmos.Monitor;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
|
||||||
namespace Content.Server.Atmos.Monitor.Components
|
namespace Content.Server.Atmos.Monitor.Components
|
||||||
{
|
{
|
||||||
@@ -30,6 +31,12 @@ namespace Content.Server.Atmos.Monitor.Components
|
|||||||
[ViewVariables] public AtmosMonitorAlarmType HighestNetworkState = AtmosMonitorAlarmType.Normal;
|
[ViewVariables] public AtmosMonitorAlarmType HighestNetworkState = AtmosMonitorAlarmType.Normal;
|
||||||
[ViewVariables] public bool IgnoreAlarms { get; set; } = false;
|
[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;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of prototypes that this alarmable can be
|
/// List of prototypes that this alarmable can be
|
||||||
/// alarmed by - must be a prototype with AtmosMonitor
|
/// alarmed by - must be a prototype with AtmosMonitor
|
||||||
|
|||||||
@@ -46,15 +46,6 @@ namespace Content.Server.Atmos.Monitor.Components
|
|||||||
[DataField("monitorFire")]
|
[DataField("monitorFire")]
|
||||||
public bool MonitorFire = false;
|
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
|
// really messy but this is parsed at runtime after
|
||||||
// prototypes are initialized, there's no
|
// prototypes are initialized, there's no
|
||||||
// way without implementing a new
|
// way without implementing a new
|
||||||
|
|||||||
@@ -516,7 +516,6 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
public void ForceCloseAllInterfaces(EntityUid uid)
|
public void ForceCloseAllInterfaces(EntityUid uid)
|
||||||
{
|
{
|
||||||
_uiSystem.TryCloseAll(uid, SharedAirAlarmInterfaceKey.Key);
|
_uiSystem.TryCloseAll(uid, SharedAirAlarmInterfaceKey.Key);
|
||||||
RemoveActiveInterface(uid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnAtmosUpdate(EntityUid uid, AirAlarmComponent alarm, AtmosDeviceUpdateEvent args)
|
public void OnAtmosUpdate(EntityUid uid, AirAlarmComponent alarm, AtmosDeviceUpdateEvent args)
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ using Content.Server.DeviceNetwork.Components;
|
|||||||
using Content.Server.DeviceNetwork.Systems;
|
using Content.Server.DeviceNetwork.Systems;
|
||||||
using Content.Shared.Atmos.Monitor;
|
using Content.Shared.Atmos.Monitor;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
|
||||||
namespace Content.Server.Atmos.Monitor.Systems
|
namespace Content.Server.Atmos.Monitor.Systems
|
||||||
{
|
{
|
||||||
public sealed class AtmosAlarmableSystem : EntitySystem
|
public sealed class AtmosAlarmableSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||||
|
[Dependency] private readonly AudioSystem _audioSystem = default!;
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<AtmosAlarmableComponent, DeviceNetworkPacketEvent>(OnPacketRecv);
|
SubscribeLocalEvent<AtmosAlarmableComponent, DeviceNetworkPacketEvent>(OnPacketRecv);
|
||||||
@@ -37,11 +39,20 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
component.LastAlarmState = state;
|
component.LastAlarmState = state;
|
||||||
component.HighestNetworkState = netMax;
|
component.HighestNetworkState = netMax;
|
||||||
UpdateAppearance(uid, netMax);
|
UpdateAppearance(uid, netMax);
|
||||||
|
PlayAlertSound(uid, netMax, component);
|
||||||
RaiseLocalEvent(component.Owner, new AtmosMonitorAlarmEvent(state, netMax), true);
|
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)
|
private void UpdateAppearance(EntityUid uid, AtmosMonitorAlarmType alarm)
|
||||||
{
|
{
|
||||||
_appearance.SetData(uid, AtmosMonitorVisuals.AlarmType, alarm);
|
_appearance.SetData(uid, AtmosMonitorVisuals.AlarmType, alarm);
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const string AtmosMonitorAlarmResetAllCmd = "atmos_monitor_alarm_reset_all";
|
public const string AtmosMonitorAlarmResetAllCmd = "atmos_monitor_alarm_reset_all";
|
||||||
|
|
||||||
|
public const string AtmosMonitorSetThresholdData = "atmos_monitor_set_threshold";
|
||||||
|
|
||||||
// Packet data
|
// Packet data
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Data response that contains the threshold types in an atmos monitor alarm.
|
/// Data response that contains the threshold types in an atmos monitor alarm.
|
||||||
@@ -60,6 +62,13 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const string AtmosMonitorAlarmNetMax = "atmos_monitor_alarm_net_max";
|
public const string AtmosMonitorAlarmNetMax = "atmos_monitor_alarm_net_max";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Data response that contains the last state recorded by this air monitor.
|
||||||
|
/// </summary>
|
||||||
|
public const string AtmosMonitorAtmosData = "atmos_monitor_atmos_data";
|
||||||
|
|
||||||
|
public const string AtmosMonitorThresholdData = "atmos_monitor_threshold_data";
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<AtmosMonitorComponent, ComponentInit>(OnAtmosMonitorInit);
|
SubscribeLocalEvent<AtmosMonitorComponent, ComponentInit>(OnAtmosMonitorInit);
|
||||||
@@ -189,16 +198,42 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
component.NetworkAlarmStates.Clear();
|
component.NetworkAlarmStates.Clear();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case AirAlarmSystem.AirAlarmSyncCmd:
|
||||||
|
var payload = new NetworkPayload();
|
||||||
|
payload.Add(DeviceNetworkConstants.Command, AirAlarmSystem.AirAlarmSyncData);
|
||||||
|
if (component.TileGas != null)
|
||||||
|
{
|
||||||
|
var gases = new Dictionary<Gas, float>();
|
||||||
|
foreach (var gas in Enum.GetValues<Gas>())
|
||||||
|
{
|
||||||
|
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 (component.DisplayMaxAlarmInNet)
|
||||||
{
|
{
|
||||||
if (EntityManager.TryGetComponent(component.Owner, out AppearanceComponent? appearanceComponent))
|
if (EntityManager.TryGetComponent(component.Owner, out AppearanceComponent? appearanceComponent))
|
||||||
appearanceComponent.SetData(AtmosMonitorVisuals.AlarmType, component.HighestAlarmInNetwork);
|
appearanceComponent.SetData(AtmosMonitorVisuals.AlarmType, component.HighestAlarmInNetwork);
|
||||||
|
|
||||||
if (component.HighestAlarmInNetwork == AtmosMonitorAlarmType.Danger) PlayAlertSound(uid, component);
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPowerChangedEvent(EntityUid uid, AtmosMonitorComponent component, PowerChangedEvent args)
|
private void OnPowerChangedEvent(EntityUid uid, AtmosMonitorComponent component, PowerChangedEvent args)
|
||||||
@@ -344,21 +379,12 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
|
|
||||||
BroadcastAlertPacket(monitor, alarms);
|
BroadcastAlertPacket(monitor, alarms);
|
||||||
|
|
||||||
if (state == AtmosMonitorAlarmType.Danger) PlayAlertSound(uid, monitor);
|
|
||||||
|
|
||||||
if (EntityManager.TryGetComponent(monitor.Owner, out AtmosAlarmableComponent? alarmable)
|
if (EntityManager.TryGetComponent(monitor.Owner, out AtmosAlarmableComponent? alarmable)
|
||||||
&& !alarmable.IgnoreAlarms)
|
&& !alarmable.IgnoreAlarms)
|
||||||
RaiseLocalEvent(monitor.Owner, new AtmosMonitorAlarmEvent(monitor.LastAlarmState, monitor.HighestAlarmInNetwork), true);
|
RaiseLocalEvent(monitor.Owner, new AtmosMonitorAlarmEvent(monitor.LastAlarmState, monitor.HighestAlarmInNetwork), true);
|
||||||
// TODO: Central system that grabs *all* alarms from wired network
|
// 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resets a single monitor's alarm.
|
/// Resets a single monitor's alarm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ namespace Content.Shared.Atmos.Monitor
|
|||||||
get => CalculateWarningBound(AtmosMonitorThresholdBound.Lower);
|
get => CalculateWarningBound(AtmosMonitorThresholdBound.Lower);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AtmosAlarmThreshold()
|
||||||
|
{}
|
||||||
|
|
||||||
public AtmosAlarmThreshold(AtmosAlarmThreshold other)
|
public AtmosAlarmThreshold(AtmosAlarmThreshold other)
|
||||||
{
|
{
|
||||||
Ignore = other.Ignore;
|
Ignore = other.Ignore;
|
||||||
|
|||||||
@@ -4,6 +4,19 @@ namespace Content.Shared.Atmos.Monitor;
|
|||||||
|
|
||||||
public sealed class AtmosSensorData : IAtmosDeviceData
|
public sealed class AtmosSensorData : IAtmosDeviceData
|
||||||
{
|
{
|
||||||
|
public AtmosSensorData(float pressure, float temperature, float totalMoles, AtmosMonitorAlarmType alarmState, Dictionary<Gas, float> gases, bool onFire, AtmosAlarmThreshold pressureThreshold, AtmosAlarmThreshold temperatureThreshold, Dictionary<Gas, AtmosAlarmThreshold> 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 Enabled { get; set; }
|
||||||
public bool Dirty { get; set; }
|
public bool Dirty { get; set; }
|
||||||
public bool IgnoreAlarms { get; set; }
|
public bool IgnoreAlarms { get; set; }
|
||||||
@@ -13,15 +26,15 @@ public sealed class AtmosSensorData : IAtmosDeviceData
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current pressure detected by this sensor.
|
/// Current pressure detected by this sensor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float? Pressure { get; }
|
public float Pressure { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current temperature detected by this sensor.
|
/// Current temperature detected by this sensor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float? Temperature { get; }
|
public float Temperature { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current amount of moles detected by this sensor.
|
/// Current amount of moles detected by this sensor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float? TotalMoles { get; }
|
public float TotalMoles { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current alarm state of this sensor. Does not reflect the highest alarm state on the network.
|
/// Current alarm state of this sensor. Does not reflect the highest alarm state on the network.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -34,4 +47,8 @@ public sealed class AtmosSensorData : IAtmosDeviceData
|
|||||||
/// If this sensor is currently detecting a fire.
|
/// If this sensor is currently detecting a fire.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool OnFire { get; }
|
public bool OnFire { get; }
|
||||||
|
|
||||||
|
public AtmosAlarmThreshold PressureThreshold { get; }
|
||||||
|
public AtmosAlarmThreshold TemperatureThreshold { get; }
|
||||||
|
public Dictionary<Gas, AtmosAlarmThreshold> GasThresholds { get; }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user