some backend stuff for air alarms
finally, some UI states!!!
This commit is contained in:
@@ -40,9 +40,10 @@
|
||||
<ScrollContainer VerticalExpand="True">
|
||||
<BoxContainer Name="CScrubberContainer" Orientation="Vertical"/>
|
||||
</ScrollContainer>
|
||||
<!-- Alarm thresholds -->
|
||||
<!-- Sensors -->
|
||||
<ScrollContainer VerticalExpand="True">
|
||||
<BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||
<BoxContainer Name="CSensorContainer" Orientation="Vertical"/>
|
||||
<!-- <BoxContainer Orientation="Vertical" VerticalExpand="True">
|
||||
<BoxContainer Name="CPressureThreshold" Orientation="Vertical" Margin="2 0 2 0" />
|
||||
<BoxContainer Name="CTemperatureThreshold" Orientation="Vertical" Margin="2 0 2 0" />
|
||||
<Collapsible Orientation="Vertical">
|
||||
@@ -51,7 +52,7 @@
|
||||
<BoxContainer Name="CGasThresholdContainer" Orientation="Vertical" Margin="2 0 2 0" />
|
||||
</CollapsibleBody>
|
||||
</Collapsible>
|
||||
</BoxContainer>
|
||||
</BoxContainer> -->
|
||||
</ScrollContainer>
|
||||
</TabContainer>
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.Atmos.Monitor.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Robust.Shared.Network;
|
||||
|
||||
namespace Content.Server.Atmos.Monitor.Components
|
||||
@@ -11,7 +13,12 @@ namespace Content.Server.Atmos.Monitor.Components
|
||||
// Remember to null this afterwards.
|
||||
[ViewVariables] public IAirAlarmModeUpdate? CurrentModeUpdater { get; set; }
|
||||
|
||||
[ViewVariables] public AirAlarmTab CurrentTab { get; set; }
|
||||
|
||||
public Dictionary<string, IAtmosDeviceData> DeviceData = new();
|
||||
public Dictionary<string, GasVentPumpData> VentData = new();
|
||||
public Dictionary<string, GasVentScrubberData> ScrubberData = new();
|
||||
public Dictionary<string, AtmosSensorData> SensorData = new();
|
||||
|
||||
public HashSet<NetUserId> ActivePlayers = new();
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Content.Shared.Atmos.Monitor.Components;
|
||||
using Content.Shared.Atmos.Piping.Unary.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Player;
|
||||
@@ -124,6 +125,24 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
_deviceNet.QueuePacket(uid, address, payload);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Synchronize all sensors on an air alarm, but only if its current tab is set to Sensors.
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="monitor"></param>
|
||||
private void SyncAllSensors(EntityUid uid, AirAlarmComponent? monitor = null)
|
||||
{
|
||||
if (!Resolve(uid, ref monitor) || monitor.CurrentTab != AirAlarmTab.Sensors)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var addr in monitor.SensorData.Keys)
|
||||
{
|
||||
SyncDevice(uid, addr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sync this air alarm's mode with the rest of the network.
|
||||
/// </summary>
|
||||
@@ -168,7 +187,9 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
{
|
||||
ForceCloseAllInterfaces(uid);
|
||||
component.CurrentModeUpdater = null;
|
||||
component.DeviceData.Clear();
|
||||
component.ScrubberData.Clear();
|
||||
component.SensorData.Clear();
|
||||
component.VentData.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -208,18 +229,18 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
_uiSystem.GetUiOrNull(component.Owner, SharedAirAlarmInterfaceKey.Key)?.Open(actor.PlayerSession);
|
||||
component.ActivePlayers.Add(actor.PlayerSession.UserId);
|
||||
AddActiveInterface(uid);
|
||||
SendAddress(uid);
|
||||
SendAlarmMode(uid);
|
||||
SendThresholds(uid);
|
||||
SyncAllDevices(uid);
|
||||
SendAirData(uid);
|
||||
UpdateUI(uid, component);
|
||||
}
|
||||
|
||||
private void OnResyncAll(EntityUid uid, AirAlarmComponent component, AirAlarmResyncAllDevicesMessage args)
|
||||
{
|
||||
if (AccessCheck(uid, args.Session.AttachedEntity, component))
|
||||
{
|
||||
component.DeviceData.Clear();
|
||||
component.VentData.Clear();
|
||||
component.ScrubberData.Clear();
|
||||
component.SensorData.Clear();
|
||||
|
||||
SyncAllDevices(uid);
|
||||
}
|
||||
}
|
||||
@@ -231,7 +252,7 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
if (AccessCheck(uid, args.Session.AttachedEntity, component))
|
||||
SetMode(uid, addr, args.Mode, true, false);
|
||||
else
|
||||
SendAlarmMode(uid);
|
||||
UpdateUI(uid, component);
|
||||
}
|
||||
|
||||
private void OnUpdateThreshold(EntityUid uid, AirAlarmComponent component, AirAlarmUpdateAlarmThresholdMessage args)
|
||||
@@ -239,7 +260,7 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
if (AccessCheck(uid, args.Session.AttachedEntity, component))
|
||||
SetThreshold(uid, args.Threshold, args.Type, args.Gas);
|
||||
else
|
||||
SendThresholds(uid);
|
||||
UpdateUI(uid, component);
|
||||
}
|
||||
|
||||
private void OnUpdateDeviceData(EntityUid uid, AirAlarmComponent component, AirAlarmUpdateDeviceDataMessage args)
|
||||
@@ -247,7 +268,7 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
if (AccessCheck(uid, args.Session.AttachedEntity, component))
|
||||
SetDeviceData(uid, args.Address, args.Data);
|
||||
else
|
||||
SyncDevice(uid, args.Address);
|
||||
UpdateUI(uid, component);
|
||||
}
|
||||
|
||||
private bool AccessCheck(EntityUid uid, EntityUid? user, AirAlarmComponent? component = null)
|
||||
@@ -272,7 +293,6 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
if (component.ActivePlayers.Count != 0)
|
||||
{
|
||||
SyncAllDevices(uid);
|
||||
SendAirData(uid);
|
||||
}
|
||||
|
||||
string addr = string.Empty;
|
||||
@@ -296,6 +316,8 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
// no, this still doesn't execute the mode
|
||||
SetMode(uid, addr, AirAlarmMode.Filtering, true);
|
||||
}
|
||||
|
||||
UpdateUI(uid, component);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -355,10 +377,7 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
&& controller.CurrentModeUpdater.NetOwner != origin)
|
||||
controller.CurrentModeUpdater = null;
|
||||
|
||||
// controller.SendMessage(new AirAlarmUpdateAlarmModeMessage(mode));
|
||||
// TODO: Use BUI states instead...
|
||||
_uiSystem.TrySendUiMessage(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmUpdateAlarmModeMessage(mode));
|
||||
|
||||
UpdateUI(uid, controller);
|
||||
|
||||
// setting sync deals with the issue of air alarms
|
||||
// in the same network needing to have the same mode
|
||||
@@ -384,7 +403,6 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
if (component.ActivePlayers.Count != 0)
|
||||
{
|
||||
SyncAllDevices(uid);
|
||||
SendAirData(uid);
|
||||
}
|
||||
|
||||
string addr = string.Empty;
|
||||
@@ -398,12 +416,6 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
return;
|
||||
}
|
||||
|
||||
// set this air alarm's visuals to match the highest network alarm
|
||||
if (TryComp(uid, out AppearanceComponent? appearanceComponent))
|
||||
{
|
||||
appearanceComponent.SetData(AtmosMonitorVisuals.AlarmType, highestNetworkType);
|
||||
}
|
||||
|
||||
if (highestNetworkType == AtmosMonitorAlarmType.Danger)
|
||||
{
|
||||
SetMode(uid, addr, AirAlarmMode.None, true);
|
||||
@@ -421,6 +433,8 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
// no, this still doesn't execute the mode
|
||||
SetMode(uid, addr, AirAlarmMode.Filtering, true);
|
||||
}
|
||||
|
||||
UpdateUI(uid, component);
|
||||
}
|
||||
|
||||
private void OnPacketRecv(EntityUid uid, AirAlarmComponent controller, DeviceNetworkPacketEvent args)
|
||||
@@ -439,10 +453,23 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
// Sync data to interface.
|
||||
// _airAlarmDataSystem.UpdateDeviceData(uid, args.SenderAddress, data);
|
||||
//
|
||||
_uiSystem.TrySendUiMessage(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmUpdateDeviceDataMessage(args.SenderAddress, data));
|
||||
// if (HasComp<WiresComponent>(uid)) controller.UpdateWires();
|
||||
if (!controller.DeviceData.TryAdd(args.SenderAddress, data))
|
||||
controller.DeviceData[args.SenderAddress] = data;
|
||||
switch (data)
|
||||
{
|
||||
case GasVentPumpData ventData:
|
||||
if (!controller.VentData.TryAdd(args.SenderAddress, ventData))
|
||||
controller.VentData[args.SenderAddress] = ventData;
|
||||
break;
|
||||
case GasVentScrubberData scrubberData:
|
||||
if (!controller.ScrubberData.TryAdd(args.SenderAddress, scrubberData))
|
||||
controller.ScrubberData[args.SenderAddress] = scrubberData;
|
||||
break;
|
||||
case AtmosSensorData sensorData:
|
||||
if (!controller.SensorData.TryAdd(args.SenderAddress, sensorData))
|
||||
controller.SensorData[args.SenderAddress] = sensorData;
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateUI(uid, controller);
|
||||
|
||||
return;
|
||||
case AirAlarmSetDataStatus:
|
||||
@@ -486,84 +513,10 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
/// <summary>
|
||||
/// Force closes all interfaces currently open related to this air alarm.
|
||||
/// </summary>
|
||||
public void ForceCloseAllInterfaces(EntityUid uid) =>
|
||||
public void ForceCloseAllInterfaces(EntityUid uid)
|
||||
{
|
||||
_uiSystem.TryCloseAll(uid, SharedAirAlarmInterfaceKey.Key);
|
||||
|
||||
private void SendAddress(EntityUid uid, DeviceNetworkComponent? netConn = null)
|
||||
{
|
||||
if (!Resolve(uid, ref netConn)) return;
|
||||
|
||||
// TODO: Use BUI states instead...
|
||||
_uiSystem.TrySendUiMessage(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmSetAddressMessage(netConn.Address));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update an interface's air data. This is all the 'hot' data
|
||||
/// that an air alarm contains server-side. Updated with a whopping 8
|
||||
/// delay automatically once a UI is in the loop.
|
||||
/// </summary>
|
||||
public void SendAirData(EntityUid uid, AirAlarmComponent? alarm = null, AtmosMonitorComponent? monitor = null, ApcPowerReceiverComponent? power = null)
|
||||
{
|
||||
if (!Resolve(uid, ref alarm, ref monitor, ref power)) return;
|
||||
|
||||
if (!power.Powered) return;
|
||||
|
||||
|
||||
if (monitor.TileGas != null)
|
||||
{
|
||||
var gases = new Dictionary<Gas, float>();
|
||||
|
||||
foreach (var gas in Enum.GetValues<Gas>())
|
||||
gases.Add(gas, monitor.TileGas.GetMoles(gas));
|
||||
|
||||
var airData = new AirAlarmAirData(monitor.TileGas.Pressure, monitor.TileGas.Temperature, monitor.TileGas.TotalMoles, monitor.LastAlarmState, gases);
|
||||
|
||||
// TODO: Use BUI states instead...
|
||||
_uiSystem.TrySendUiMessage(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmUpdateAirDataMessage(airData));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send an air alarm mode to any open interface related to an air alarm.
|
||||
/// </summary>
|
||||
public void SendAlarmMode(EntityUid uid, AtmosMonitorComponent? monitor = null, ApcPowerReceiverComponent? power = null, AirAlarmComponent? controller = null)
|
||||
{
|
||||
if (!Resolve(uid, ref monitor, ref power, ref controller)
|
||||
|| !power.Powered) return;
|
||||
|
||||
// TODO: Use BUI states instead...
|
||||
_uiSystem.TrySendUiMessage(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmUpdateAlarmModeMessage(controller.CurrentMode));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send all thresholds to any open interface related to a given air alarm.
|
||||
/// </summary>
|
||||
public void SendThresholds(EntityUid uid, AtmosMonitorComponent? monitor = null, ApcPowerReceiverComponent? power = null, AirAlarmComponent? controller = null)
|
||||
{
|
||||
if (!Resolve(uid, ref monitor, ref power, ref controller)
|
||||
|| !power.Powered) return;
|
||||
|
||||
if (monitor.PressureThreshold == null
|
||||
&& monitor.TemperatureThreshold == null
|
||||
&& monitor.GasThresholds == null)
|
||||
return;
|
||||
|
||||
// TODO: Use BUI states instead...
|
||||
if (monitor.PressureThreshold != null)
|
||||
{
|
||||
_uiSystem.TrySendUiMessage(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmUpdateAlarmThresholdMessage(AtmosMonitorThresholdType.Pressure, monitor.PressureThreshold));
|
||||
}
|
||||
|
||||
if (monitor.TemperatureThreshold != null)
|
||||
{
|
||||
_uiSystem.TrySendUiMessage(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmUpdateAlarmThresholdMessage(AtmosMonitorThresholdType.Temperature, monitor.TemperatureThreshold));
|
||||
}
|
||||
|
||||
if (monitor.GasThresholds != null)
|
||||
{
|
||||
foreach (var (gas, threshold) in monitor.GasThresholds)
|
||||
_uiSystem.TrySendUiMessage(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmUpdateAlarmThresholdMessage(AtmosMonitorThresholdType.Gas, threshold, gas));
|
||||
}
|
||||
RemoveActiveInterface(uid);
|
||||
}
|
||||
|
||||
public void OnAtmosUpdate(EntityUid uid, AirAlarmComponent alarm, AtmosDeviceUpdateEvent args)
|
||||
@@ -572,6 +525,49 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
alarm.CurrentModeUpdater.Update(uid);
|
||||
}
|
||||
|
||||
public void UpdateUI(EntityUid uid, AirAlarmComponent? alarm = null, AtmosAlarmableComponent? alarmable = null)
|
||||
{
|
||||
if (!Resolve(uid, ref alarm, ref alarmable))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dataToSend = new Dictionary<string, IAtmosDeviceData>();
|
||||
|
||||
if (alarm.CurrentTab != AirAlarmTab.Settings)
|
||||
{
|
||||
switch (alarm.CurrentTab)
|
||||
{
|
||||
case AirAlarmTab.Vent:
|
||||
foreach (var (addr, data) in alarm.VentData)
|
||||
{
|
||||
dataToSend.Add(addr, data);
|
||||
}
|
||||
|
||||
break;
|
||||
case AirAlarmTab.Scrubber:
|
||||
foreach (var (addr, data) in alarm.ScrubberData)
|
||||
{
|
||||
dataToSend.Add(addr, data);
|
||||
}
|
||||
|
||||
break;
|
||||
case AirAlarmTab.Sensors:
|
||||
foreach (var (addr, data) in alarm.SensorData)
|
||||
{
|
||||
dataToSend.Add(addr, data);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_uiSystem.TrySetUiState(
|
||||
uid,
|
||||
SharedAirAlarmInterfaceKey.Key,
|
||||
new AirAlarmUIState(dataToSend, alarm.CurrentMode, alarm.CurrentTab, alarmable.HighestNetworkState));
|
||||
}
|
||||
|
||||
private const float _delay = 8f;
|
||||
private float _timer = 0f;
|
||||
|
||||
@@ -583,9 +579,7 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
_timer = 0f;
|
||||
foreach (var uid in _activeUserInterfaces)
|
||||
{
|
||||
// TODO: Awful idea, use BUI states instead...
|
||||
SendAirData(uid);
|
||||
_uiSystem.TrySetUiState(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmUIState());
|
||||
SyncAllSensors(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@ using Content.Server.DeviceNetwork;
|
||||
using Content.Server.DeviceNetwork.Components;
|
||||
using Content.Server.DeviceNetwork.Systems;
|
||||
using Content.Shared.Atmos.Monitor;
|
||||
using Robust.Server.GameObjects;
|
||||
|
||||
namespace Content.Server.Atmos.Monitor.Systems
|
||||
{
|
||||
public sealed class AtmosAlarmableSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AppearanceSystem _appearance = default!;
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<AtmosAlarmableComponent, DeviceNetworkPacketEvent>(OnPacketRecv);
|
||||
@@ -34,9 +36,15 @@ namespace Content.Server.Atmos.Monitor.Systems
|
||||
{
|
||||
component.LastAlarmState = state;
|
||||
component.HighestNetworkState = netMax;
|
||||
UpdateAppearance(uid, netMax);
|
||||
RaiseLocalEvent(component.Owner, new AtmosMonitorAlarmEvent(state, netMax), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAppearance(EntityUid uid, AtmosMonitorAlarmType alarm)
|
||||
{
|
||||
_appearance.SetData(uid, AtmosMonitorVisuals.AlarmType, alarm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
37
Content.Shared/Atmos/Monitor/AtmosSensorData.cs
Normal file
37
Content.Shared/Atmos/Monitor/AtmosSensorData.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Content.Shared.Atmos.Monitor.Components;
|
||||
|
||||
namespace Content.Shared.Atmos.Monitor;
|
||||
|
||||
public sealed class AtmosSensorData : IAtmosDeviceData
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public bool Dirty { get; set; }
|
||||
public bool IgnoreAlarms { get; set; }
|
||||
|
||||
/// Most fields are readonly, because it's data that's meant to be transmitted.
|
||||
|
||||
/// <summary>
|
||||
/// Current pressure detected by this sensor.
|
||||
/// </summary>
|
||||
public float? Pressure { get; }
|
||||
/// <summary>
|
||||
/// Current temperature detected by this sensor.
|
||||
/// </summary>
|
||||
public float? Temperature { get; }
|
||||
/// <summary>
|
||||
/// Current amount of moles detected by this sensor.
|
||||
/// </summary>
|
||||
public float? TotalMoles { get; }
|
||||
/// <summary>
|
||||
/// Current alarm state of this sensor. Does not reflect the highest alarm state on the network.
|
||||
/// </summary>
|
||||
public AtmosMonitorAlarmType AlarmState { get; }
|
||||
/// <summary>
|
||||
/// Current number of gases on this sensor.
|
||||
/// </summary>
|
||||
public Dictionary<Gas, float> Gases { get; }
|
||||
/// <summary>
|
||||
/// If this sensor is currently detecting a fire.
|
||||
/// </summary>
|
||||
public bool OnFire { get; }
|
||||
}
|
||||
@@ -55,11 +55,34 @@ namespace Content.Shared.Atmos.Monitor.Components
|
||||
public bool IgnoreAlarms { get; set; }
|
||||
}
|
||||
|
||||
// would be nice to include the entire state here
|
||||
// but it's already handled by messages
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class AirAlarmUIState : BoundUserInterfaceState
|
||||
{}
|
||||
{
|
||||
public AirAlarmUIState(Dictionary<string, IAtmosDeviceData> deviceData, AirAlarmMode mode, AirAlarmTab tab, AtmosMonitorAlarmType alarmType)
|
||||
{
|
||||
DeviceData = deviceData;
|
||||
Mode = mode;
|
||||
Tab = tab;
|
||||
AlarmType = alarmType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Every single device data that can be seen from this
|
||||
/// air alarm. This includes vents, scrubbers, and sensors.
|
||||
/// The device data you get, however, depends on the current
|
||||
/// selected tab.
|
||||
/// </summary>
|
||||
public Dictionary<string, IAtmosDeviceData> DeviceData { get; }
|
||||
public AirAlarmMode Mode { get; }
|
||||
public AirAlarmTab Tab { get; }
|
||||
public AtmosMonitorAlarmType AlarmType { get; }
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class AirAlarmTabSetMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public AirAlarmTab Tab { get; }
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class AirAlarmResyncAllDevicesMessage : BoundUserInterfaceMessage
|
||||
@@ -126,5 +149,11 @@ namespace Content.Shared.Atmos.Monitor.Components
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum AirAlarmTab
|
||||
{
|
||||
Vent,
|
||||
Scrubber,
|
||||
Sensors,
|
||||
Settings
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user