diff --git a/Content.Client/Atmos/Monitor/AtmosMonitorVisualizer.cs b/Content.Client/Atmos/Monitor/AtmosMonitorVisualizer.cs new file mode 100644 index 0000000000..dc86118e1e --- /dev/null +++ b/Content.Client/Atmos/Monitor/AtmosMonitorVisualizer.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using Content.Shared.Atmos.Monitor; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Maths; +using Robust.Shared.Serialization.Manager.Attributes; + +namespace Content.Client.Atmos.Monitor +{ + public class AtmosMonitorVisualizer : AppearanceVisualizer + { + [Dependency] IEntityManager _entityManager = default!; + [DataField("layerMap")] + private string _layerMap { get; } = string.Empty; + + [DataField("alarmStates")] + private readonly Dictionary _alarmStates = new(); + + [DataField("hideOnDepowered")] + private readonly List? _hideOnDepowered; + + // eh... + [DataField("setOnDepowered")] + private readonly Dictionary? _setOnDepowered; + + public override void InitializeEntity(EntityUid entity) + { + base.InitializeEntity(entity); + + IoCManager.InjectDependencies(this); + } + + public override void OnChangeData(AppearanceComponent component) + { + if (!_entityManager.TryGetComponent(component.Owner, out var sprite)) + return; + + if (!sprite.LayerMapTryGet(_layerMap, out int layer)) + return; + + if (component.TryGetData("powered", out var powered)) + { + if (_hideOnDepowered != null) + foreach (var visLayer in _hideOnDepowered) + if (sprite.LayerMapTryGet(visLayer, out int powerVisibilityLayer)) + sprite.LayerSetVisible(powerVisibilityLayer, powered); + + if (_setOnDepowered != null && !powered) + foreach (var (setLayer, state) in _setOnDepowered) + if (sprite.LayerMapTryGet(setLayer, out int setStateLayer)) + sprite.LayerSetState(setStateLayer, new RSI.StateId(state)); + } + + if (component.TryGetData("offset", out Vector2 offset)) + { + sprite.Offset = offset; + } + + if (component.TryGetData("alarmType", out var alarmType) + && powered) + if (_alarmStates.TryGetValue(alarmType, out var state)) + sprite.LayerSetState(layer, new RSI.StateId(state)); + } + } +} diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs new file mode 100644 index 0000000000..0c28dd3b0e --- /dev/null +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmBoundUserInterface.cs @@ -0,0 +1,87 @@ +using Content.Shared.Atmos; +using Content.Shared.Atmos.Monitor; +using Content.Shared.Atmos.Monitor.Components; +using Robust.Client.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Log; + +namespace Content.Client.Atmos.Monitor.UI +{ + public class AirAlarmBoundUserInterface : BoundUserInterface + { + private AirAlarmWindow? _window; + + public AirAlarmBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) + {} + + protected override void Open() + { + base.Open(); + + _window = new AirAlarmWindow(); + + if (State != null) UpdateState(State); + + _window.OpenCentered(); + + _window.OnClose += Close; + _window.AtmosDeviceDataChanged += OnDeviceDataChanged; + _window.AtmosAlarmThresholdChanged += OnThresholdChanged; + _window.AirAlarmModeChanged += OnAirAlarmModeChanged; + _window.ResyncAllRequested += ResyncAllDevices; + } + + private void ResyncAllDevices() + { + SendMessage(new AirAlarmResyncAllDevicesMessage()); + } + + private void OnDeviceDataChanged(string address, IAtmosDeviceData data) + { + SendMessage(new AirAlarmUpdateDeviceDataMessage(address, data)); + } + + private void OnAirAlarmModeChanged(AirAlarmMode mode) + { + SendMessage(new AirAlarmUpdateAlarmModeMessage(mode)); + } + + private void OnThresholdChanged(AtmosMonitorThresholdType type, AtmosAlarmThreshold threshold, Gas? gas = null) + { + SendMessage(new AirAlarmUpdateAlarmThresholdMessage(type, threshold, gas)); + } + + protected override void ReceiveMessage(BoundUserInterfaceMessage message) + { + if (_window == null) + return; + + switch (message) + { + case AirAlarmSetAddressMessage addrMsg: + _window.SetAddress(addrMsg.Address); + break; + case AirAlarmUpdateDeviceDataMessage deviceMsg: + _window.UpdateDeviceData(deviceMsg.Address, deviceMsg.Data); + break; + case AirAlarmUpdateAlarmModeMessage alarmMsg: + _window.UpdateModeSelector(alarmMsg.Mode); + break; + case AirAlarmUpdateAlarmThresholdMessage thresholdMsg: + _window.UpdateThreshold(ref thresholdMsg); + break; + case AirAlarmUpdateAirDataMessage airDataMsg: + _window.UpdateGasData(ref airDataMsg.AirData); + break; + } + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (disposing) _window?.Dispose(); + } + } +} diff --git a/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml new file mode 100644 index 0000000000..a75894647a --- /dev/null +++ b/Content.Client/Atmos/Monitor/UI/AirAlarmWindow.xaml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +