From c3f9b5c74d53e0348750b2150fbd9fb10023921e Mon Sep 17 00:00:00 2001 From: Tom Leys Date: Fri, 5 May 2023 12:34:15 +1200 Subject: [PATCH] [tweak] Vents leak slowly, limit their max pressure (#15931) * Vents leak slowly, limit their max pressure * Set leak rate low enough that auto pressurize takes 30 minutes --- .../Unary/Components/GasVentPumpComponent.cs | 30 ++++++++++++++++++- .../Unary/EntitySystems/GasVentPumpSystem.cs | 26 +++++++++++----- 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs b/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs index c9e838f30b..88c4476301 100644 --- a/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs +++ b/Content.Server/Atmos/Piping/Unary/Components/GasVentPumpComponent.cs @@ -42,7 +42,24 @@ namespace Content.Server.Atmos.Piping.Unary.Components /// [ViewVariables(VVAccess.ReadWrite)] [DataField("underPressureLockoutThreshold")] - public float UnderPressureLockoutThreshold = 1; + public float UnderPressureLockoutThreshold = 2; + + /// + /// Pressure locked vents still leak a little (leading to eventual pressurization of sealed sections) + /// + /// + /// Ratio of pressure difference between pipes and atmosphere that will leak each second, in moles. + /// If the pipes are 200 kPa and the room is spaced, at 0.01 UnderPressureLockoutLeaking, the room will fill + /// at a rate of 2 moles / sec. It will then reach 2 kPa (UnderPressureLockoutThreshold) and begin normal + /// filling after about 20 seconds (depending on room size). + /// + /// Since we want to prevent automating the work of atmos, the leaking rate of 0.0001f is set to make auto + /// repressurizing of the development map take about 30 minutes using an oxygen tank (high pressure) + /// + + [ViewVariables(VVAccess.ReadWrite)] + [DataField("underPressureLockoutLeaking")] + public float UnderPressureLockoutLeaking = 0.0001f; [ViewVariables(VVAccess.ReadWrite)] [DataField("externalPressureBound")] @@ -89,6 +106,17 @@ namespace Content.Server.Atmos.Piping.Unary.Components [DataField("targetPressureChange")] public float TargetPressureChange = Atmospherics.OneAtmosphere; + /// + /// Ratio of max output air pressure and pipe pressure, representing the vent's ability to increase pressure + /// + /// + /// 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")] + public float PumpPower = 2.0f; + #region Machine Linking /// /// Whether or not machine linking is enabled for this component. diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs index 53ce579b1c..d14bc43d16 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs @@ -88,15 +88,18 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems if (environment.Pressure > vent.MaxPressure) return; - if (environment.Pressure < vent.UnderPressureLockoutThreshold) - { - vent.UnderPressureLockout = true; - return; - } - vent.UnderPressureLockout = false; + vent.UnderPressureLockout = (environment.Pressure < vent.UnderPressureLockoutThreshold); if ((vent.PressureChecks & VentPressureBound.ExternalBound) != 0) - pressureDelta = MathF.Min(pressureDelta, vent.ExternalPressureBound - environment.Pressure); + { + // Vents cannot supply high pressures from an almost empty pipe, instead it's proportional to the pipe + // pressure, up to a limit. + // This also means supply pipe pressure indicates minimum pressure on the station, with lower pressure + // sections getting air first. + var supplyPressure = MathF.Min(pipe.Air.Pressure * vent.PumpPower, vent.ExternalPressureBound); + // Calculate the ratio of supply pressure to current pressure. + pressureDelta = MathF.Min(pressureDelta, supplyPressure - environment.Pressure); + } if (pressureDelta <= 0) return; @@ -105,6 +108,15 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems // (ignoring temperature differences because I am lazy) var transferMoles = pressureDelta * environment.Volume / (pipe.Air.Temperature * Atmospherics.R); + if (vent.UnderPressureLockout) + { + // Leak only a small amount of gas as a proportion of supply pipe pressure. + var pipeDelta = pipe.Air.Pressure - environment.Pressure; + transferMoles = (float)timeDelta * pipeDelta * vent.UnderPressureLockoutLeaking; + if (transferMoles < 0.0) + return; + } + // limit transferMoles so the source doesn't go below its bound. if ((vent.PressureChecks & VentPressureBound.InternalBound) != 0) {