]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Improve gas miner's output bounds checks (#29569)
authorGuillaume E <262623+quatre@users.noreply.github.com>
Sat, 29 Jun 2024 18:44:32 +0000 (20:44 +0200)
committerGitHub <noreply@github.com>
Sat, 29 Jun 2024 18:44:32 +0000 (11:44 -0700)
Miners now can produce a fraction of their SpawnAmount corresponding
to the "remaining space" available in their environment according to
their MaxExternalPressure and MaxExternalAmount.

Content.Server/Atmos/Piping/Other/EntitySystems/GasMinerSystem.cs

index 2505c8189f88aa3a12d0c4819b6ad353b22a8fae..251ee797647a57bd2fda2b8dd1ad8c477cbcfd0f 100644 (file)
@@ -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<GasMinerComponent> ent, float toSpawn, [NotNullWhen(true)] out GasMixture? environment)
+        private float CapSpawnAmount(Entity<GasMinerComponent> 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;
         }
     }
 }