sync alarms, reset all, etc
This commit is contained in:
@@ -28,13 +28,10 @@ namespace Content.Server.Atmos.Monitor.Components
|
|||||||
public sealed class AtmosAlarmableComponent : Component
|
public sealed class AtmosAlarmableComponent : Component
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public List<EntityUid> LinkedMonitors { get; set; } = new();
|
public readonly Dictionary<string, AtmosMonitorAlarmType> NetworkAlarmStates = new();
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public Dictionary<string, AtmosMonitorAlarmType> NetworkAlarmStates = new();
|
|
||||||
|
|
||||||
[ViewVariables] public AtmosMonitorAlarmType LastAlarmState = AtmosMonitorAlarmType.Normal;
|
[ViewVariables] public AtmosMonitorAlarmType LastAlarmState = AtmosMonitorAlarmType.Normal;
|
||||||
[ViewVariables] public AtmosMonitorAlarmType HighestNetworkState = AtmosMonitorAlarmType.Normal;
|
|
||||||
[ViewVariables] public bool IgnoreAlarms { get; set; } = false;
|
[ViewVariables] public bool IgnoreAlarms { get; set; } = false;
|
||||||
|
|
||||||
[DataField("alarmSound")]
|
[DataField("alarmSound")]
|
||||||
@@ -44,11 +41,19 @@ namespace Content.Server.Atmos.Monitor.Components
|
|||||||
public float AlarmVolume { get; set; } = -10;
|
public float AlarmVolume { get; set; } = -10;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of prototypes that this alarmable can be
|
/// List of prototypes that this alarmable can
|
||||||
/// alarmed by - must be a prototype with AtmosMonitor
|
/// sync with - this is so that you can sync without
|
||||||
/// attached to it
|
/// having to worry about cross-contamination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("alarmedBy")]
|
[DataField("syncWith")]
|
||||||
public List<string> AlarmedByPrototypes { get; } = new();
|
public List<string> SyncWithPrototypes { get; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If this device should receive only. If it can only
|
||||||
|
/// receive, that means that attempting to sync outwards
|
||||||
|
/// will result in nothing happening.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("receiveOnly")]
|
||||||
|
public bool ReceiveOnly { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,6 @@ namespace Content.Server.Atmos.Monitor.Components
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public bool NetEnabled = true;
|
public bool NetEnabled = true;
|
||||||
|
|
||||||
// Entities that the monitor will alarm. Stores only EntityUids, is populated
|
|
||||||
// when this component starts up.
|
|
||||||
[ViewVariables]
|
|
||||||
public List<EntityUid> LinkedEntities = new();
|
|
||||||
|
|
||||||
[DataField("temperatureThreshold", customTypeSerializer: (typeof(PrototypeIdSerializer<AtmosAlarmThreshold>)))]
|
[DataField("temperatureThreshold", customTypeSerializer: (typeof(PrototypeIdSerializer<AtmosAlarmThreshold>)))]
|
||||||
public readonly string? TemperatureThresholdId;
|
public readonly string? TemperatureThresholdId;
|
||||||
|
|
||||||
@@ -64,34 +59,10 @@ namespace Content.Server.Atmos.Monitor.Components
|
|||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public AtmosMonitorAlarmType LastAlarmState = AtmosMonitorAlarmType.Normal;
|
public AtmosMonitorAlarmType LastAlarmState = AtmosMonitorAlarmType.Normal;
|
||||||
|
|
||||||
// feeling real dirty about this one
|
|
||||||
// Caches the alarm states it recieves from the rest of the network.
|
|
||||||
// This is so that the highest alarm in the network can be calculated
|
|
||||||
// from any monitor without having to reping every alarm.
|
|
||||||
[ViewVariables]
|
|
||||||
public Dictionary<string, AtmosMonitorAlarmType> NetworkAlarmStates = 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.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables] public HashSet<string> RegisteredDevices = new();
|
[ViewVariables] public HashSet<string> RegisteredDevices = new();
|
||||||
|
|
||||||
// Calculates the highest alarm in the network, including itself.
|
|
||||||
[ViewVariables]
|
|
||||||
public AtmosMonitorAlarmType HighestAlarmInNetwork
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var state = AtmosMonitorAlarmType.Normal;
|
|
||||||
foreach (var (_, netState) in NetworkAlarmStates)
|
|
||||||
if (state < netState)
|
|
||||||
state = netState;
|
|
||||||
|
|
||||||
if (LastAlarmState > state) state = LastAlarmState;
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||||
[Dependency] private readonly AudioSystem _audioSystem = default!;
|
[Dependency] private readonly AudioSystem _audioSystem = default!;
|
||||||
|
[Dependency] private readonly DeviceNetworkSystem _deviceNet = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Syncs alerts from this alarm receiver to other alarm receivers.
|
/// Syncs alerts from this alarm receiver to other alarm receivers.
|
||||||
@@ -23,6 +24,8 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const string SyncAlerts = "atmos_alarmable_sync_alerts";
|
public const string SyncAlerts = "atmos_alarmable_sync_alerts";
|
||||||
|
|
||||||
|
public const string ResetAll = "atmos_alarmable_reset_all";
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<AtmosAlarmableComponent, DeviceNetworkPacketEvent>(OnPacketRecv);
|
SubscribeLocalEvent<AtmosAlarmableComponent, DeviceNetworkPacketEvent>(OnPacketRecv);
|
||||||
@@ -77,6 +80,9 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
RaiseLocalEvent(component.Owner, new AtmosMonitorAlarmEvent(state, netMax.Value), true);
|
RaiseLocalEvent(component.Owner, new AtmosMonitorAlarmEvent(state, netMax.Value), true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ResetAll:
|
||||||
|
Reset(uid, component);
|
||||||
|
break;
|
||||||
case SyncAlerts:
|
case SyncAlerts:
|
||||||
// Synchronize alerts, but only if they're already known by this monitor.
|
// Synchronize alerts, but only if they're already known by this monitor.
|
||||||
// This should help eliminate the chain effect, especially with
|
// This should help eliminate the chain effect, especially with
|
||||||
@@ -105,6 +111,22 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SyncAlertsToNetwork(EntityUid uid, string? address = null, AtmosAlarmableComponent? alarmable = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref alarmable) || alarmable.ReceiveOnly)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var payload = new NetworkPayload
|
||||||
|
{
|
||||||
|
[DeviceNetworkConstants.Command] = SyncAlerts,
|
||||||
|
[SyncAlerts] = alarmable.NetworkAlarmStates
|
||||||
|
};
|
||||||
|
|
||||||
|
_deviceNet.QueuePacket(uid, address, payload);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resets the state of this alarmable to normal.
|
/// Resets the state of this alarmable to normal.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -120,9 +142,28 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
alarmable.LastAlarmState = AtmosMonitorAlarmType.Normal;
|
alarmable.LastAlarmState = AtmosMonitorAlarmType.Normal;
|
||||||
alarmable.NetworkAlarmStates.Clear();
|
alarmable.NetworkAlarmStates.Clear();
|
||||||
|
|
||||||
|
SyncAlertsToNetwork(uid);
|
||||||
RaiseLocalEvent(uid, new AtmosMonitorAlarmEvent(AtmosMonitorAlarmType.Normal, AtmosMonitorAlarmType.Normal));
|
RaiseLocalEvent(uid, new AtmosMonitorAlarmEvent(AtmosMonitorAlarmType.Normal, AtmosMonitorAlarmType.Normal));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ResetAllOnNetwork(EntityUid uid, AtmosAlarmableComponent? alarmable = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref alarmable))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
alarmable.LastAlarmState = AtmosMonitorAlarmType.Normal;
|
||||||
|
alarmable.NetworkAlarmStates.Clear();
|
||||||
|
|
||||||
|
var payload = new NetworkPayload
|
||||||
|
{
|
||||||
|
[DeviceNetworkConstants.Command] = ResetAll
|
||||||
|
};
|
||||||
|
|
||||||
|
_deviceNet.QueuePacket(uid, null, payload);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to get the highest possible alert stored in this alarm.
|
/// Tries to get the highest possible alert stored in this alarm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -300,9 +300,6 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
|
|
||||||
BroadcastAlertPacket(monitor, alarms);
|
BroadcastAlertPacket(monitor, alarms);
|
||||||
|
|
||||||
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
|
// TODO: Central system that grabs *all* alarms from wired network
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,38 +317,6 @@ namespace Content.Server.Atmos.Monitor.Systems
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public void ResetAll(EntityUid uid, AtmosMonitorComponent? monitor = null)
|
public void ResetAll(EntityUid uid, AtmosMonitorComponent? monitor = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref monitor)) return;
|
|
||||||
|
|
||||||
var prototype = Prototype(monitor.Owner);
|
|
||||||
var payload = new NetworkPayload
|
|
||||||
{
|
|
||||||
[DeviceNetworkConstants.Command] = AtmosMonitorAlarmResetAllCmd,
|
|
||||||
[AtmosMonitorAlarmSrc] = prototype != null ? prototype.ID : string.Empty
|
|
||||||
};
|
|
||||||
|
|
||||||
_deviceNetSystem.QueuePacket(monitor.Owner, null, payload);
|
|
||||||
monitor.NetworkAlarmStates.Clear();
|
|
||||||
|
|
||||||
Alert(uid, AtmosMonitorAlarmType.Normal, null, monitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// (TODO: maybe just cache monitors in other monitors?)
|
|
||||||
/// <summary>
|
|
||||||
/// Syncs the current state of this monitor to the network (to avoid alerting other monitors).
|
|
||||||
/// </summary>
|
|
||||||
private void Sync(AtmosMonitorComponent monitor)
|
|
||||||
{
|
|
||||||
if (!monitor.NetEnabled) return;
|
|
||||||
|
|
||||||
var prototype = Prototype(monitor.Owner);
|
|
||||||
var payload = new NetworkPayload
|
|
||||||
{
|
|
||||||
[DeviceNetworkConstants.Command] = AtmosMonitorAlarmSyncCmd,
|
|
||||||
[DeviceNetworkConstants.CmdSetState] = monitor.LastAlarmState,
|
|
||||||
[AtmosMonitorAlarmSrc] = prototype != null ? prototype.ID : string.Empty
|
|
||||||
};
|
|
||||||
|
|
||||||
_deviceNetSystem.QueuePacket(monitor.Owner, null, payload);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user