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 +{ +}