diff --git a/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs b/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs
index 7d702904fbe83b..fcf3ddf969c76b 100644
--- a/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs
+++ b/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs
@@ -6,6 +6,7 @@
namespace Content.Server.Atmos.Piping.Unary.Components
{
// The world if people documented their shit.
+ [AutoGenerateComponentPause]
[RegisterComponent]
public sealed partial class GasVentPumpComponent : Component
{
@@ -15,31 +16,25 @@ public sealed partial class GasVentPumpComponent : Component
[ViewVariables]
public bool IsDirty { get; set; } = false;
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("inlet")]
+ [DataField]
public string Inlet { get; set; } = "pipe";
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("outlet")]
+ [DataField]
public string Outlet { get; set; } = "pipe";
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("pumpDirection")]
+ [DataField]
public VentPumpDirection PumpDirection { get; set; } = VentPumpDirection.Releasing;
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("pressureChecks")]
+ [DataField]
public VentPressureBound PressureChecks { get; set; } = VentPressureBound.ExternalBound;
- [ViewVariables(VVAccess.ReadOnly)]
- [DataField("underPressureLockout")]
+ [DataField]
public bool UnderPressureLockout { get; set; } = false;
///
/// In releasing mode, do not pump when environment pressure is below this limit.
///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("underPressureLockoutThreshold")]
+ [DataField]
public float UnderPressureLockoutThreshold = 80; // this must be tuned in conjunction with atmos.mmos_spacing_speed
///
@@ -55,12 +50,30 @@ public sealed partial class GasVentPumpComponent : Component
/// repressurizing of the development map take about 30 minutes using an oxygen tank (high pressure)
///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("underPressureLockoutLeaking")]
+ [DataField]
public float UnderPressureLockoutLeaking = 0.0001f;
+ ///
+ /// Is the vent pressure lockout currently manually disabled?
+ ///
+ [DataField]
+ public bool IsPressureLockoutManuallyDisabled = false;
+ ///
+ /// The time when the manual pressure lockout will be reenabled.
+ ///
+ [DataField]
+ [AutoPausedField]
+ public TimeSpan ManualLockoutReenabledAt;
+ ///
+ /// How long the lockout should remain manually disabled after being interacted with.
+ ///
+ [DataField]
+ public TimeSpan ManualLockoutDisabledDuration = TimeSpan.FromSeconds(30); // Enough time to fill a 5x5 room
+ ///
+ /// How long the doAfter should take when attempting to manually disable the pressure lockout.
+ ///
+ public float ManualLockoutDisableDoAfter = 2.0f;
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("externalPressureBound")]
+ [DataField]
public float ExternalPressureBound
{
get => _externalPressureBound;
@@ -72,8 +85,7 @@ public float ExternalPressureBound
private float _externalPressureBound = Atmospherics.OneAtmosphere;
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("internalPressureBound")]
+ [DataField]
public float InternalPressureBound
{
get => _internalPressureBound;
@@ -88,8 +100,7 @@ public float InternalPressureBound
///
/// Max pressure of the target gas (NOT relative to source).
///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("maxPressure")]
+ [DataField]
public float MaxPressure = Atmospherics.MaxOutputPressure;
///
@@ -100,8 +111,7 @@ public float InternalPressureBound
/// is too high, and the vent is connected to a large pipe-net, then someone can nearly instantly flood a
/// room with gas.
///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("targetPressureChange")]
+ [DataField]
public float TargetPressureChange = Atmospherics.OneAtmosphere;
///
@@ -111,29 +121,26 @@ public float InternalPressureBound
/// Vents cannot suck a pipe completely empty, instead pressurizing a section to a max of
/// pipe pressure * PumpPower (in kPa). So a 51 kPa pipe is required for 101 kPA sections at PumpPower 2.0
///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("PumpPower")]
+ [DataField]
public float PumpPower = 2.0f;
#region Machine Linking
///
/// Whether or not machine linking is enabled for this component.
///
- [DataField("canLink")]
+ [DataField]
public bool CanLink = false;
- [DataField("pressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))]
public string PressurizePort = "Pressurize";
- [DataField("depressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))]
public string DepressurizePort = "Depressurize";
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("pressurizePressure")]
+ [DataField]
public float PressurizePressure = Atmospherics.OneAtmosphere;
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("depressurizePressure")]
+ [DataField]
public float DepressurizePressure = 0;
// When true, ignore under-pressure lockout. Used to re-fill rooms in air alarm "Fill" mode.
diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs
index dbbbf2d00830e2..9d9862ff1dde88 100644
--- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs
+++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs
@@ -7,21 +7,22 @@
using Content.Server.DeviceNetwork;
using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems;
-using Content.Server.NodeContainer;
using Content.Server.NodeContainer.EntitySystems;
using Content.Server.NodeContainer.Nodes;
-using Content.Server.Power.Components;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
+using Content.Shared.Atmos.Piping.Unary;
using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.Atmos.Visuals;
using Content.Shared.Audio;
using Content.Shared.DeviceNetwork;
+using Content.Shared.DoAfter;
using Content.Shared.Examine;
+using Content.Shared.Interaction;
using Content.Shared.Power;
using Content.Shared.Tools.Systems;
using JetBrains.Annotations;
-using Robust.Server.GameObjects;
+using Robust.Shared.Timing;
namespace Content.Server.Atmos.Piping.Unary.EntitySystems
{
@@ -35,7 +36,9 @@ public sealed class GasVentPumpSystem : EntitySystem
[Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly WeldableSystem _weldable = default!;
-
+ [Dependency] private readonly SharedToolSystem _toolSystem = default!;
+ [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
+ [Dependency] private readonly IGameTiming _timing = default!;
public override void Initialize()
{
base.Initialize();
@@ -51,6 +54,8 @@ public override void Initialize()
SubscribeLocalEvent(OnSignalReceived);
SubscribeLocalEvent(OnAnalyzed);
SubscribeLocalEvent(OnWeldChanged);
+ SubscribeLocalEvent(OnInteractUsing);
+ SubscribeLocalEvent(OnVentScrewed);
}
private void OnGasVentPumpUpdated(EntityUid uid, GasVentPumpComponent vent, ref AtmosDeviceUpdateEvent args)
@@ -80,11 +85,16 @@ private void OnGasVentPumpUpdated(EntityUid uid, GasVentPumpComponent vent, ref
{
return;
}
+ // If the lockout has expired, disable it.
+ if (vent.IsPressureLockoutManuallyDisabled && _timing.CurTime >= vent.ManualLockoutReenabledAt)
+ {
+ vent.IsPressureLockoutManuallyDisabled = false;
+ }
var timeDelta = args.dt;
var pressureDelta = timeDelta * vent.TargetPressureChange;
- var lockout = (environment.Pressure < vent.UnderPressureLockoutThreshold);
+ var lockout = (environment.Pressure < vent.UnderPressureLockoutThreshold) && !vent.IsPressureLockoutManuallyDisabled;
if (vent.UnderPressureLockout != lockout) // update visuals only if this changes
{
vent.UnderPressureLockout = lockout;
@@ -115,7 +125,7 @@ private void OnGasVentPumpUpdated(EntityUid uid, GasVentPumpComponent vent, ref
var transferMoles = pressureDelta * environment.Volume / (pipe.Air.Temperature * Atmospherics.R);
// Only run if the device is under lockout and not being overriden
- if (vent.UnderPressureLockout & !vent.PressureLockoutOverride)
+ if (vent.UnderPressureLockout & !vent.PressureLockoutOverride & !vent.IsPressureLockoutManuallyDisabled)
{
// Leak only a small amount of gas as a proportion of supply pipe pressure.
var pipeDelta = pipe.Air.Pressure - environment.Pressure;
@@ -273,7 +283,7 @@ private void UpdateState(EntityUid uid, GasVentPumpComponent vent, AppearanceCom
}
else if (vent.PumpDirection == VentPumpDirection.Releasing)
{
- if (vent.UnderPressureLockout & !vent.PressureLockoutOverride)
+ if (vent.UnderPressureLockout & !vent.PressureLockoutOverride & !vent.IsPressureLockoutManuallyDisabled)
_appearance.SetData(uid, VentPumpVisuals.State, VentPumpState.Lockout, appearance);
else
_appearance.SetData(uid, VentPumpVisuals.State, VentPumpState.Out, appearance);
@@ -290,7 +300,7 @@ private void OnExamine(EntityUid uid, GasVentPumpComponent component, ExaminedEv
return;
if (args.IsInDetailsRange)
{
- if (pumpComponent.PumpDirection == VentPumpDirection.Releasing & pumpComponent.UnderPressureLockout & !pumpComponent.PressureLockoutOverride)
+ if (pumpComponent.PumpDirection == VentPumpDirection.Releasing & pumpComponent.UnderPressureLockout & !pumpComponent.PressureLockoutOverride & !pumpComponent.IsPressureLockoutManuallyDisabled)
{
args.PushMarkup(Loc.GetString("gas-vent-pump-uvlo"));
}
@@ -325,5 +335,25 @@ private void OnWeldChanged(EntityUid uid, GasVentPumpComponent component, ref We
{
UpdateState(uid, component);
}
+ private void OnInteractUsing(EntityUid uid, GasVentPumpComponent component, InteractUsingEvent args)
+ {
+ if (args.Handled
+ || component.UnderPressureLockout == false
+ || !_toolSystem.HasQuality(args.Used, "Screwing")
+ || !Transform(uid).Anchored
+ )
+ {
+ return;
+ }
+
+ args.Handled = true;
+
+ _doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, component.ManualLockoutDisableDoAfter, new VentScrewedDoAfterEvent(), uid, uid, args.Used));
+ }
+ private void OnVentScrewed(EntityUid uid, GasVentPumpComponent component, VentScrewedDoAfterEvent args)
+ {
+ component.ManualLockoutReenabledAt = _timing.CurTime + component.ManualLockoutDisabledDuration;
+ component.IsPressureLockoutManuallyDisabled = true;
+ }
}
}
diff --git a/Content.Shared/Atmos/Piping/Unary/VentScrewedDoAfterEvent.cs b/Content.Shared/Atmos/Piping/Unary/VentScrewedDoAfterEvent.cs
new file mode 100644
index 00000000000000..1fdc69bcf68b4a
--- /dev/null
+++ b/Content.Shared/Atmos/Piping/Unary/VentScrewedDoAfterEvent.cs
@@ -0,0 +1,9 @@
+using Content.Shared.DoAfter;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Atmos.Piping.Unary;
+
+[Serializable, NetSerializable]
+public sealed partial class VentScrewedDoAfterEvent : SimpleDoAfterEvent
+{
+}