From: Guillaume E <262623+quatre@users.noreply.github.com> Date: Sat, 29 Jun 2024 18:44:32 +0000 (+0200) Subject: Improve gas miner's output bounds checks (#29569) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=83e048ee45b3e320e274745279266a7f820ad635;p=space-station-14.git Improve gas miner's output bounds checks (#29569) Miners now can produce a fraction of their SpawnAmount corresponding to the "remaining space" available in their environment according to their MaxExternalPressure and MaxExternalAmount. --- diff --git a/Content.Server/Atmos/Piping/Other/EntitySystems/GasMinerSystem.cs b/Content.Server/Atmos/Piping/Other/EntitySystems/GasMinerSystem.cs index 2505c8189f..251ee79764 100644 --- a/Content.Server/Atmos/Piping/Other/EntitySystems/GasMinerSystem.cs +++ b/Content.Server/Atmos/Piping/Other/EntitySystems/GasMinerSystem.cs @@ -26,9 +26,9 @@ namespace Content.Server.Atmos.Piping.Other.EntitySystems var miner = ent.Comp; // SpawnAmount is declared in mol/s so to get the amount of gas we hope to mine, we have to multiply this by - // how long we have been waiting to spawn it. - var toSpawn = miner.SpawnAmount * args.dt; - if (!CheckMinerOperation(ent, toSpawn, out var environment) || !miner.Enabled || !miner.SpawnGas.HasValue || toSpawn <= 0f) + // how long we have been waiting to spawn it and further cap the number according to the miner's state. + var toSpawn = CapSpawnAmount(ent, miner.SpawnAmount * args.dt, out var environment); + if (toSpawn <= 0f || environment == null || !miner.Enabled || !miner.SpawnGas.HasValue) return; // Time to mine some gas. @@ -39,7 +39,7 @@ namespace Content.Server.Atmos.Piping.Other.EntitySystems _atmosphereSystem.Merge(environment, merger); } - private bool CheckMinerOperation(Entity ent, float toSpawn, [NotNullWhen(true)] out GasMixture? environment) + private float CapSpawnAmount(Entity ent, float toSpawnTarget, [NotNullWhen(true)] out GasMixture? environment) { var (uid, miner) = ent; var transform = Transform(uid); @@ -51,33 +51,30 @@ namespace Content.Server.Atmos.Piping.Other.EntitySystems if (_atmosphereSystem.IsTileSpace(transform.GridUid, transform.MapUid, position)) { miner.Broken = true; - return false; + return 0f; } // Air-blocked location. if (environment == null) { miner.Broken = true; - return false; + return 0f; } - // External pressure above threshold. - if (!float.IsInfinity(miner.MaxExternalPressure) && - environment.Pressure > miner.MaxExternalPressure - toSpawn * miner.SpawnTemperature * Atmospherics.R / environment.Volume) - { - miner.Broken = true; - return false; - } + // How many moles could we theoretically spawn. Cap by pressure and amount. + var allowableMoles = Math.Min( + (miner.MaxExternalPressure - environment.Pressure) * environment.Volume / (miner.SpawnTemperature * Atmospherics.R), + miner.MaxExternalAmount - environment.TotalMoles); - // External gas amount above threshold. - if (!float.IsInfinity(miner.MaxExternalAmount) && environment.TotalMoles > miner.MaxExternalAmount) - { + var toSpawnReal = Math.Clamp(allowableMoles, 0f, toSpawnTarget); + + if (toSpawnReal < Atmospherics.GasMinMoles) { miner.Broken = true; - return false; + return 0f; } miner.Broken = false; - return true; + return toSpawnReal; } } }