--- /dev/null
+using Content.Client.Atmos.UI;
+using Content.Shared.Atmos.Components;
+using Content.Shared.Atmos.EntitySystems;
+using Content.Shared.Atmos.Piping.Binary.Components;
+
+namespace Content.Client.Atmos.EntitySystems;
+
+public sealed class GasPressurePumpSystem : SharedGasPressurePumpSystem
+{
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent<GasPressurePumpComponent, AfterAutoHandleStateEvent>(OnPumpUpdate);
+ }
+
+ private void OnPumpUpdate(Entity<GasPressurePumpComponent> ent, ref AfterAutoHandleStateEvent args)
+ {
+ if (UserInterfaceSystem.TryGetOpenUi<GasPressurePumpBoundUserInterface>(ent.Owner, GasPressurePumpUiKey.Key, out var bui))
+ {
+ bui.Update();
+ }
+ }
+}
using Content.Shared.Atmos;
+using Content.Shared.Atmos.Components;
using Content.Shared.Atmos.Piping.Binary.Components;
+using Content.Shared.IdentityManagement;
using Content.Shared.Localizations;
using JetBrains.Annotations;
-using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
-namespace Content.Client.Atmos.UI
+namespace Content.Client.Atmos.UI;
+
+/// <summary>
+/// Initializes a <see cref="GasPressurePumpWindow"/> and updates it when new server messages are received.
+/// </summary>
+[UsedImplicitly]
+public sealed class GasPressurePumpBoundUserInterface : BoundUserInterface
{
- /// <summary>
- /// Initializes a <see cref="GasPressurePumpWindow"/> and updates it when new server messages are received.
- /// </summary>
- [UsedImplicitly]
- public sealed class GasPressurePumpBoundUserInterface : BoundUserInterface
- {
- [ViewVariables]
- private const float MaxPressure = Atmospherics.MaxOutputPressure;
+ [ViewVariables]
+ private const float MaxPressure = Atmospherics.MaxOutputPressure;
+
+ [ViewVariables]
+ private GasPressurePumpWindow? _window;
- [ViewVariables]
- private GasPressurePumpWindow? _window;
+ public GasPressurePumpBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
+ {
+ }
- public GasPressurePumpBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
- {
- }
+ protected override void Open()
+ {
+ base.Open();
- protected override void Open()
- {
- base.Open();
+ _window = this.CreateWindow<GasPressurePumpWindow>();
- _window = this.CreateWindow<GasPressurePumpWindow>();
+ _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed;
+ _window.PumpOutputPressureChanged += OnPumpOutputPressurePressed;
+ Update();
+ }
- _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed;
- _window.PumpOutputPressureChanged += OnPumpOutputPressurePressed;
- }
+ public void Update()
+ {
+ if (_window == null)
+ return;
- private void OnToggleStatusButtonPressed()
- {
- if (_window is null) return;
- SendMessage(new GasPressurePumpToggleStatusMessage(_window.PumpStatus));
- }
+ _window.Title = Identity.Name(Owner, EntMan);
- private void OnPumpOutputPressurePressed(string value)
- {
- var pressure = UserInputParser.TryFloat(value, out var parsed) ? parsed : 0f;
- if (pressure > MaxPressure) pressure = MaxPressure;
+ if (!EntMan.TryGetComponent(Owner, out GasPressurePumpComponent? pump))
+ return;
- SendMessage(new GasPressurePumpChangeOutputPressureMessage(pressure));
- }
+ _window.SetPumpStatus(pump.Enabled);
+ _window.MaxPressure = pump.MaxTargetPressure;
+ _window.SetOutputPressure(pump.TargetPressure);
+ }
- /// <summary>
- /// Update the UI state based on server-sent info
- /// </summary>
- /// <param name="state"></param>
- protected override void UpdateState(BoundUserInterfaceState state)
- {
- base.UpdateState(state);
- if (_window == null || state is not GasPressurePumpBoundUserInterfaceState cast)
- return;
+ private void OnToggleStatusButtonPressed()
+ {
+ if (_window is null) return;
+ SendPredictedMessage(new GasPressurePumpToggleStatusMessage(_window.PumpStatus));
+ }
- _window.Title = (cast.PumpLabel);
- _window.SetPumpStatus(cast.Enabled);
- _window.SetOutputPressure(cast.OutputPressure);
- }
+ private void OnPumpOutputPressurePressed(float value)
+ {
+ SendPredictedMessage(new GasPressurePumpChangeOutputPressureMessage(value));
}
}
-<DefaultWindow xmlns="https://spacestation14.io"
+<controls:FancyWindow xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- MinSize="200 120" Title="Pressure Pump">
+ xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
+ SetSize="340 110" MinSize="340 110" Title="Pressure Pump">
<BoxContainer Orientation="Vertical" Margin="5 5 5 5" SeparationOverride="10">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
- <Label Text="{Loc comp-gas-pump-ui-pump-status}"/>
- <Control MinSize="5 0" />
+ <Label Text="{Loc comp-gas-pump-ui-pump-status}" Margin="0 0 5 0"/>
<Button Name="ToggleStatusButton"/>
+ <Control HorizontalExpand="True"/>
+ <Button HorizontalAlignment="Right" Name="SetOutputPressureButton" Text="{Loc comp-gas-pump-ui-pump-set-rate}" Disabled="True" Margin="0 0 5 0"/>
+ <Button Name="SetMaxPressureButton" Text="{Loc comp-gas-pump-ui-pump-set-max}" />
</BoxContainer>
-
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Label Text="{Loc comp-gas-pump-ui-pump-output-pressure}"/>
- <Control MinSize="5 0" />
- <LineEdit Name="PumpPressureOutputInput" MinSize="70 0" />
- <Control MinSize="5 0" />
- <Button Name="SetMaxPressureButton" Text="{Loc comp-gas-pump-ui-pump-set-max}" />
- <Control MinSize="5 0" />
- <Control HorizontalExpand="True" />
- <Button Name="SetOutputPressureButton" Text="{Loc comp-gas-pump-ui-pump-set-rate}" HorizontalAlignment="Right" Disabled="True"/>
+ <FloatSpinBox HorizontalExpand="True" Name="PumpPressureOutputInput" MinSize="70 0" />
</BoxContainer>
</BoxContainer>
-</DefaultWindow>
+</controls:FancyWindow>
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using Content.Client.Atmos.EntitySystems;
+using Content.Client.UserInterface.Controls;
using Content.Shared.Atmos;
-using Content.Shared.Atmos.Prototypes;
using Robust.Client.AutoGenerated;
-using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
-using Robust.Shared.Localization;
namespace Content.Client.Atmos.UI
{
/// Client-side UI used to control a gas pressure pump.
/// </summary>
[GenerateTypedNameReferences]
- public sealed partial class GasPressurePumpWindow : DefaultWindow
+ public sealed partial class GasPressurePumpWindow : FancyWindow
{
public bool PumpStatus = true;
public event Action? ToggleStatusButtonPressed;
- public event Action<string>? PumpOutputPressureChanged;
+ public event Action<float>? PumpOutputPressureChanged;
+
+ public float MaxPressure
+ {
+ get => _maxPressure;
+ set
+ {
+ _maxPressure = value;
+
+ PumpPressureOutputInput.Value = MathF.Min(value, PumpPressureOutputInput.Value);
+ }
+ }
+
+ private float _maxPressure = Atmospherics.MaxOutputPressure;
public GasPressurePumpWindow()
{
ToggleStatusButton.OnPressed += _ => SetPumpStatus(!PumpStatus);
ToggleStatusButton.OnPressed += _ => ToggleStatusButtonPressed?.Invoke();
- PumpPressureOutputInput.OnTextChanged += _ => SetOutputPressureButton.Disabled = false;
+ PumpPressureOutputInput.OnValueChanged += _ => SetOutputPressureButton.Disabled = false;
+
SetOutputPressureButton.OnPressed += _ =>
{
- PumpOutputPressureChanged?.Invoke(PumpPressureOutputInput.Text ??= "");
+ PumpPressureOutputInput.Value = Math.Clamp(PumpPressureOutputInput.Value, 0f, _maxPressure);
+ PumpOutputPressureChanged?.Invoke(PumpPressureOutputInput.Value);
SetOutputPressureButton.Disabled = true;
};
SetMaxPressureButton.OnPressed += _ =>
{
- PumpPressureOutputInput.Text = Atmospherics.MaxOutputPressure.ToString(CultureInfo.CurrentCulture);
+ PumpPressureOutputInput.Value = _maxPressure;
SetOutputPressureButton.Disabled = false;
};
}
public void SetOutputPressure(float pressure)
{
- PumpPressureOutputInput.Text = pressure.ToString(CultureInfo.CurrentCulture);
+ PumpPressureOutputInput.Value = pressure;
}
public void SetPumpStatus(bool enabled)
using Content.Server.Power.EntitySystems;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
+using Content.Shared.Atmos.Piping.Components;
using Content.Shared.DeviceNetwork;
using Content.Shared.Power;
using Content.Shared.Tag;
+++ /dev/null
-using Content.Shared.Atmos;
-
-namespace Content.Server.Atmos.Piping.Binary.Components
-{
- [RegisterComponent]
- public sealed partial class GasPressurePumpComponent : Component
- {
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("enabled")]
- public bool Enabled { get; set; } = true;
-
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("inlet")]
- public string InletName { get; set; } = "inlet";
-
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("outlet")]
- public string OutletName { get; set; } = "outlet";
-
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("targetPressure")]
- public float TargetPressure { get; set; } = Atmospherics.OneAtmosphere;
-
- /// <summary>
- /// Max pressure of the target gas (NOT relative to source).
- /// </summary>
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("maxTargetPressure")]
- public float MaxTargetPressure = Atmospherics.MaxOutputPressure;
- }
-}
-using Content.Server.Administration.Logs;
using Content.Server.Atmos.EntitySystems;
-using Content.Server.Atmos.Piping.Binary.Components;
using Content.Server.Atmos.Piping.Components;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Server.Power.Components;
using Content.Shared.Atmos;
-using Content.Shared.Atmos.Piping;
-using Content.Shared.Atmos.Piping.Binary.Components;
+using Content.Shared.Atmos.Components;
+using Content.Shared.Atmos.EntitySystems;
using Content.Shared.Audio;
-using Content.Shared.Database;
-using Content.Shared.Examine;
-using Content.Shared.Interaction;
-using Content.Shared.Popups;
-using Content.Shared.Power;
using JetBrains.Annotations;
-using Robust.Server.GameObjects;
-using Robust.Shared.Player;
-namespace Content.Server.Atmos.Piping.Binary.EntitySystems
-{
- [UsedImplicitly]
- public sealed class GasPressurePumpSystem : EntitySystem
- {
- [Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
- [Dependency] private readonly IAdminLogManager _adminLogger = default!;
- [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
- [Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
- [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
- [Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
- [Dependency] private readonly SharedPopupSystem _popup = default!;
-
- public override void Initialize()
- {
- base.Initialize();
-
- SubscribeLocalEvent<GasPressurePumpComponent, ComponentInit>(OnInit);
- SubscribeLocalEvent<GasPressurePumpComponent, AtmosDeviceUpdateEvent>(OnPumpUpdated);
- SubscribeLocalEvent<GasPressurePumpComponent, AtmosDeviceDisabledEvent>(OnPumpLeaveAtmosphere);
- SubscribeLocalEvent<GasPressurePumpComponent, ExaminedEvent>(OnExamined);
- SubscribeLocalEvent<GasPressurePumpComponent, ActivateInWorldEvent>(OnPumpActivate);
- SubscribeLocalEvent<GasPressurePumpComponent, PowerChangedEvent>(OnPowerChanged);
- // Bound UI subscriptions
- SubscribeLocalEvent<GasPressurePumpComponent, GasPressurePumpChangeOutputPressureMessage>(OnOutputPressureChangeMessage);
- SubscribeLocalEvent<GasPressurePumpComponent, GasPressurePumpToggleStatusMessage>(OnToggleStatusMessage);
- }
-
- private void OnInit(EntityUid uid, GasPressurePumpComponent pump, ComponentInit args)
- {
- UpdateAppearance(uid, pump);
- }
-
- private void OnExamined(EntityUid uid, GasPressurePumpComponent pump, ExaminedEvent args)
- {
- if (!EntityManager.GetComponent<TransformComponent>(uid).Anchored || !args.IsInDetailsRange) // Not anchored? Out of range? No status.
- return;
-
- if (Loc.TryGetString("gas-pressure-pump-system-examined", out var str,
- ("statusColor", "lightblue"), // TODO: change with pressure?
- ("pressure", pump.TargetPressure)
- ))
- {
- args.PushMarkup(str);
- }
- }
-
- private void OnPowerChanged(EntityUid uid, GasPressurePumpComponent component, ref PowerChangedEvent args)
- {
- UpdateAppearance(uid, component);
- }
-
- private void OnPumpUpdated(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceUpdateEvent args)
- {
- if (!pump.Enabled
- || (TryComp<ApcPowerReceiverComponent>(uid, out var power) && !power.Powered)
- || !_nodeContainer.TryGetNodes(uid, pump.InletName, pump.OutletName, out PipeNode? inlet, out PipeNode? outlet))
- {
- _ambientSoundSystem.SetAmbience(uid, false);
- return;
- }
-
- var outputStartingPressure = outlet.Air.Pressure;
+namespace Content.Server.Atmos.Piping.Binary.EntitySystems;
- if (outputStartingPressure >= pump.TargetPressure)
- {
- _ambientSoundSystem.SetAmbience(uid, false);
- return; // No need to pump gas if target has been reached.
- }
-
- if (inlet.Air.TotalMoles > 0 && inlet.Air.Temperature > 0)
- {
- // We calculate the necessary moles to transfer using our good ol' friend PV=nRT.
- var pressureDelta = pump.TargetPressure - outputStartingPressure;
- var transferMoles = (pressureDelta * outlet.Air.Volume) / (inlet.Air.Temperature * Atmospherics.R);
-
- var removed = inlet.Air.Remove(transferMoles);
- _atmosphereSystem.Merge(outlet.Air, removed);
- _ambientSoundSystem.SetAmbience(uid, removed.TotalMoles > 0f);
- }
- }
-
- private void OnPumpLeaveAtmosphere(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceDisabledEvent args)
- {
- pump.Enabled = false;
- UpdateAppearance(uid, pump);
-
- DirtyUI(uid, pump);
- _userInterfaceSystem.CloseUi(uid, GasPressurePumpUiKey.Key);
- }
-
- private void OnPumpActivate(EntityUid uid, GasPressurePumpComponent pump, ActivateInWorldEvent args)
- {
- if (args.Handled || !args.Complex)
- return;
-
- if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
- return;
+[UsedImplicitly]
+public sealed class GasPressurePumpSystem : SharedGasPressurePumpSystem
+{
+ [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
+ [Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
+ [Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
- if (Transform(uid).Anchored)
- {
- _userInterfaceSystem.OpenUi(uid, GasPressurePumpUiKey.Key, actor.PlayerSession);
- DirtyUI(uid, pump);
- }
- else
- {
- _popup.PopupCursor(Loc.GetString("comp-gas-pump-ui-needs-anchor"), args.User);
- }
+ public override void Initialize()
+ {
+ base.Initialize();
- args.Handled = true;
- }
+ SubscribeLocalEvent<GasPressurePumpComponent, AtmosDeviceUpdateEvent>(OnPumpUpdated);
+ }
- private void OnToggleStatusMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpToggleStatusMessage args)
+ private void OnPumpUpdated(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceUpdateEvent args)
+ {
+ if (!pump.Enabled
+ || (TryComp<ApcPowerReceiverComponent>(uid, out var power) && !power.Powered)
+ || !_nodeContainer.TryGetNodes(uid, pump.InletName, pump.OutletName, out PipeNode? inlet, out PipeNode? outlet))
{
- pump.Enabled = args.Enabled;
- _adminLogger.Add(LogType.AtmosPowerChanged, LogImpact.Medium,
- $"{ToPrettyString(args.Actor):player} set the power on {ToPrettyString(uid):device} to {args.Enabled}");
- DirtyUI(uid, pump);
- UpdateAppearance(uid, pump);
+ _ambientSoundSystem.SetAmbience(uid, false);
+ return;
}
- private void OnOutputPressureChangeMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpChangeOutputPressureMessage args)
- {
- pump.TargetPressure = Math.Clamp(args.Pressure, 0f, Atmospherics.MaxOutputPressure);
- _adminLogger.Add(LogType.AtmosPressureChanged, LogImpact.Medium,
- $"{ToPrettyString(args.Actor):player} set the pressure on {ToPrettyString(uid):device} to {args.Pressure}kPa");
- DirtyUI(uid, pump);
-
- }
+ var outputStartingPressure = outlet.Air.Pressure;
- private void DirtyUI(EntityUid uid, GasPressurePumpComponent? pump)
+ if (outputStartingPressure >= pump.TargetPressure)
{
- if (!Resolve(uid, ref pump))
- return;
-
- _userInterfaceSystem.SetUiState(uid, GasPressurePumpUiKey.Key,
- new GasPressurePumpBoundUserInterfaceState(EntityManager.GetComponent<MetaDataComponent>(uid).EntityName, pump.TargetPressure, pump.Enabled));
+ _ambientSoundSystem.SetAmbience(uid, false);
+ return; // No need to pump gas if target has been reached.
}
- private void UpdateAppearance(EntityUid uid, GasPressurePumpComponent? pump = null, AppearanceComponent? appearance = null)
+ if (inlet.Air.TotalMoles > 0 && inlet.Air.Temperature > 0)
{
- if (!Resolve(uid, ref pump, ref appearance, false))
- return;
+ // We calculate the necessary moles to transfer using our good ol' friend PV=nRT.
+ var pressureDelta = pump.TargetPressure - outputStartingPressure;
+ var transferMoles = (pressureDelta * outlet.Air.Volume) / (inlet.Air.Temperature * Atmospherics.R);
- bool pumpOn = pump.Enabled && (TryComp<ApcPowerReceiverComponent>(uid, out var power) && power.Powered);
- _appearance.SetData(uid, PumpVisuals.Enabled, pumpOn, appearance);
+ var removed = inlet.Air.Remove(transferMoles);
+ _atmosphereSystem.Merge(outlet.Air, removed);
+ _ambientSoundSystem.SetAmbience(uid, removed.TotalMoles > 0f);
}
}
}
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping;
+using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Audio;
using Content.Shared.Examine;
using JetBrains.Annotations;
using Content.Server.NodeContainer.Nodes;
using Content.Server.Power.Components;
using Content.Shared.Atmos.Piping.Binary.Components;
+using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Visuals;
using Content.Shared.Audio;
using Content.Shared.Database;
/// </summary>
public readonly Entity<MapAtmosphereComponent?>? Map = map;
}
-
-/// <summary>
-/// Raised directed on an atmos device when it is enabled.
-/// </summary>
-[ByRefEvent]
-public record struct AtmosDeviceEnabledEvent;
-
-/// <summary>
-/// Raised directed on an atmos device when it is enabled.
-/// </summary>
-[ByRefEvent]
-public record struct AtmosDeviceDisabledEvent;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Atmos.Piping.Components;
+using Content.Shared.Atmos.Piping.Components;
using JetBrains.Annotations;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping;
+using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Piping.Trinary.Components;
using Content.Shared.Audio;
using Content.Shared.Database;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping;
+using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Piping.Trinary.Components;
using Content.Shared.Audio;
using Content.Shared.Database;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos.Piping;
+using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Audio;
using JetBrains.Annotations;
using Content.Server.NodeContainer.Nodes;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
+using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Piping.Unary;
using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.Atmos.Visuals;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping.Unary.Visuals;
using Content.Shared.Atmos.Monitor;
+using Content.Shared.Atmos.Piping.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.Audio;
using Content.Shared.DeviceNetwork;
--- /dev/null
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Atmos.Components;
+
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class GasPressurePumpComponent : Component
+{
+ [DataField, AutoNetworkedField]
+ public bool Enabled = true;
+
+ [DataField("inlet")]
+ public string InletName = "inlet";
+
+ [DataField("outlet")]
+ public string OutletName = "outlet";
+
+ [DataField, AutoNetworkedField]
+ public float TargetPressure = Atmospherics.OneAtmosphere;
+
+ /// <summary>
+ /// Max pressure of the target gas (NOT relative to source).
+ /// </summary>
+ [DataField]
+ public float MaxTargetPressure = Atmospherics.MaxOutputPressure;
+}
--- /dev/null
+using Content.Shared.Administration.Logs;
+using Content.Shared.Atmos.Components;
+using Content.Shared.Atmos.Piping;
+using Content.Shared.Atmos.Piping.Binary.Components;
+using Content.Shared.Atmos.Piping.Components;
+using Content.Shared.Database;
+using Content.Shared.Examine;
+using Content.Shared.Popups;
+using Content.Shared.Power;
+using Content.Shared.Power.Components;
+using Content.Shared.Power.EntitySystems;
+using Content.Shared.UserInterface;
+
+namespace Content.Shared.Atmos.EntitySystems;
+
+public abstract class SharedGasPressurePumpSystem : EntitySystem
+{
+ [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
+ [Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
+ [Dependency] private readonly SharedPowerReceiverSystem _receiver = default!;
+ [Dependency] protected readonly SharedUserInterfaceSystem UserInterfaceSystem = default!;
+
+ // TODO: Check enabled for activatableUI
+ // TODO: Add activatableUI to it.
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent<GasPressurePumpComponent, ComponentInit>(OnInit);
+ SubscribeLocalEvent<GasPressurePumpComponent, PowerChangedEvent>(OnPowerChanged);
+
+ SubscribeLocalEvent<GasPressurePumpComponent, GasPressurePumpChangeOutputPressureMessage>(OnOutputPressureChangeMessage);
+ SubscribeLocalEvent<GasPressurePumpComponent, GasPressurePumpToggleStatusMessage>(OnToggleStatusMessage);
+
+ SubscribeLocalEvent<GasPressurePumpComponent, AtmosDeviceDisabledEvent>(OnPumpLeaveAtmosphere);
+ SubscribeLocalEvent<GasPressurePumpComponent, ExaminedEvent>(OnExamined);
+ }
+
+ private void OnExamined(EntityUid uid, GasPressurePumpComponent pump, ExaminedEvent args)
+ {
+ if (!Transform(uid).Anchored)
+ return;
+
+ if (Loc.TryGetString("gas-pressure-pump-system-examined", out var str,
+ ("statusColor", "lightblue"), // TODO: change with pressure?
+ ("pressure", pump.TargetPressure)
+ ))
+ {
+ args.PushMarkup(str);
+ }
+ }
+
+ private void OnInit(EntityUid uid, GasPressurePumpComponent pump, ComponentInit args)
+ {
+ UpdateAppearance(uid, pump);
+ }
+
+ private void OnPowerChanged(EntityUid uid, GasPressurePumpComponent component, ref PowerChangedEvent args)
+ {
+ UpdateAppearance(uid, component);
+ }
+
+ private void UpdateAppearance(EntityUid uid, GasPressurePumpComponent? pump = null, AppearanceComponent? appearance = null)
+ {
+ if (!Resolve(uid, ref pump, ref appearance, false))
+ return;
+
+ var pumpOn = pump.Enabled && _receiver.IsPowered(uid);
+ Appearance.SetData(uid, PumpVisuals.Enabled, pumpOn, appearance);
+ }
+
+ private void OnToggleStatusMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpToggleStatusMessage args)
+ {
+ pump.Enabled = args.Enabled;
+ _adminLogger.Add(LogType.AtmosPowerChanged, LogImpact.Medium,
+ $"{ToPrettyString(args.Actor):player} set the power on {ToPrettyString(uid):device} to {args.Enabled}");
+ Dirty(uid, pump);
+ UpdateAppearance(uid, pump);
+ }
+
+ private void OnOutputPressureChangeMessage(EntityUid uid, GasPressurePumpComponent pump, GasPressurePumpChangeOutputPressureMessage args)
+ {
+ pump.TargetPressure = Math.Clamp(args.Pressure, 0f, Atmospherics.MaxOutputPressure);
+ _adminLogger.Add(LogType.AtmosPressureChanged, LogImpact.Medium,
+ $"{ToPrettyString(args.Actor):player} set the pressure on {ToPrettyString(uid):device} to {args.Pressure}kPa");
+ Dirty(uid, pump);
+ }
+
+ private void OnPumpLeaveAtmosphere(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceDisabledEvent args)
+ {
+ pump.Enabled = false;
+ Dirty(uid, pump);
+ UpdateAppearance(uid, pump);
+
+ UserInterfaceSystem.CloseUi(uid, GasPressurePumpUiKey.Key);
+ }
+}
using Robust.Shared.Serialization;
-namespace Content.Shared.Atmos.Piping.Binary.Components
-{
- [Serializable, NetSerializable]
- public enum GasPressurePumpUiKey
- {
- Key,
- }
-
- [Serializable, NetSerializable]
- public sealed class GasPressurePumpBoundUserInterfaceState : BoundUserInterfaceState
- {
- public string PumpLabel { get; }
- public float OutputPressure { get; }
- public bool Enabled { get; }
-
- public GasPressurePumpBoundUserInterfaceState(string pumpLabel, float outputPressure, bool enabled)
- {
- PumpLabel = pumpLabel;
- OutputPressure = outputPressure;
- Enabled = enabled;
- }
- }
+namespace Content.Shared.Atmos.Piping.Binary.Components;
- [Serializable, NetSerializable]
- public sealed class GasPressurePumpToggleStatusMessage : BoundUserInterfaceMessage
- {
- public bool Enabled { get; }
-
- public GasPressurePumpToggleStatusMessage(bool enabled)
- {
- Enabled = enabled;
- }
- }
+[Serializable, NetSerializable]
+public enum GasPressurePumpUiKey : byte
+{
+ Key,
+}
- [Serializable, NetSerializable]
- public sealed class GasPressurePumpChangeOutputPressureMessage : BoundUserInterfaceMessage
- {
- public float Pressure { get; }
+[Serializable, NetSerializable]
+public sealed class GasPressurePumpToggleStatusMessage(bool enabled) : BoundUserInterfaceMessage
+{
+ public bool Enabled { get; } = enabled;
+}
- public GasPressurePumpChangeOutputPressureMessage(float pressure)
- {
- Pressure = pressure;
- }
- }
+[Serializable, NetSerializable]
+public sealed class GasPressurePumpChangeOutputPressureMessage(float pressure) : BoundUserInterfaceMessage
+{
+ public float Pressure { get; } = pressure;
}
--- /dev/null
+namespace Content.Shared.Atmos.Piping.Components;
+
+/// <summary>
+/// Raised directed on an atmos device when it is enabled.
+/// </summary>
+[ByRefEvent]
+public readonly record struct AtmosDeviceDisabledEvent;
\ No newline at end of file
--- /dev/null
+namespace Content.Shared.Atmos.Piping.Components;
+
+/// <summary>
+/// Raised directed on an atmos device when it is enabled.
+/// </summary>
+[ByRefEvent]
+public readonly record struct AtmosDeviceEnabledEvent;
\ No newline at end of file
--- /dev/null
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.UserInterface;
+
+/// <summary>
+/// Specifies the entity as requiring anchoring to keep the ActivatableUI open.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+public sealed partial class ActivatableUIRequiresAnchorComponent : Component
+{
+ [DataField]
+ public LocId? Popup = "ui-needs-anchor";
+}
--- /dev/null
+using Content.Shared.Popups;
+
+namespace Content.Shared.UserInterface;
+
+/// <summary>
+/// <see cref="ActivatableUIRequiresAnchorComponent"/>
+/// </summary>
+public sealed class ActivatableUIRequiresAnchorSystem : EntitySystem
+{
+ [Dependency] private readonly SharedPopupSystem _popup = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent<ActivatableUIRequiresAnchorComponent, ActivatableUIOpenAttemptEvent>(OnActivatableUIOpenAttempt);
+ SubscribeLocalEvent<ActivatableUIRequiresAnchorComponent, BoundUserInterfaceCheckRangeEvent>(OnUICheck);
+ }
+
+ private void OnUICheck(Entity<ActivatableUIRequiresAnchorComponent> ent, ref BoundUserInterfaceCheckRangeEvent args)
+ {
+ if (args.Result == BoundUserInterfaceRangeResult.Fail)
+ return;
+
+ if (!Transform(ent.Owner).Anchored)
+ {
+ args.Result = BoundUserInterfaceRangeResult.Fail;
+ }
+ }
+
+ private void OnActivatableUIOpenAttempt(Entity<ActivatableUIRequiresAnchorComponent> ent, ref ActivatableUIOpenAttemptEvent args)
+ {
+ if (args.Cancelled)
+ return;
+
+ if (!Transform(ent.Owner).Anchored)
+ {
+ _popup.PopupClient(Loc.GetString("comp-gas-pump-ui-needs-anchor"), args.User);
+ args.Cancel();
+ }
+ }
+}
comp-gas-pump-ui-pump-output-pressure = Output Pressure (kPa):
comp-gas-pump-ui-pump-transfer-rate = Transfer Rate (L/s):
-
-comp-gas-pump-ui-needs-anchor = Anchor it first!
### Loc for the various UI-related verbs
ui-verb-toggle-open = Toggle UI
verb-instrument-openui = Play Music
+
+ui-needs-anchor = Anchor it first!
- type: PipeColorVisuals
- type: GasPressurePump
enabled: false
+ - type: ActivatableUI
+ key: enum.GasPressurePumpUiKey.Key
+ - type: ActivatableUIRequiresAnchor
- type: UserInterface
interfaces:
- enum.GasPressurePumpUiKey.Key:
- type: GasPressurePumpBoundUserInterface
+ enum.GasPressurePumpUiKey.Key:
+ type: GasPressurePumpBoundUserInterface
- type: Construction
graph: GasBinary
node: pressurepump