]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix chemical fuel generator division by zero (#24793)
authorPieter-Jan Briers <pieterjan.briers+git@gmail.com>
Thu, 1 Feb 2024 03:36:41 +0000 (04:36 +0100)
committerGitHub <noreply@github.com>
Thu, 1 Feb 2024 03:36:41 +0000 (14:36 +1100)
This would happen when they run out of fuel.

Content.Server/Power/Generator/GeneratorSystem.cs

index a9ec2e642bcdbace07aff940ce2fb4407c5869e4..a75d1e4113def8dc765d72af814da44ba1d3aae8 100644 (file)
@@ -92,17 +92,28 @@ public sealed class GeneratorSystem : SharedGeneratorSystem
         if (!_solutionContainer.ResolveSolution(entity.Owner, entity.Comp.SolutionName, ref entity.Comp.Solution, out var solution))
             return;
 
-        var totalAvailableReagents = solution.GetTotalPrototypeQuantity(entity.Comp.Reagents.Keys.Select(p => p.Id).ToArray()).Value;
+        var totalReagent = 0f;
+        foreach (var (reagentId, _) in entity.Comp.Reagents)
+        {
+            totalReagent += solution.GetTotalPrototypeQuantity(reagentId).Float();
+            totalReagent += entity.Comp.FractionalReagents.GetValueOrDefault(reagentId);
+        }
+
+        if (totalReagent == 0)
+            return;
+
         foreach (var (reagentId, multiplier) in entity.Comp.Reagents)
         {
-            var availableReagent = solution.GetTotalPrototypeQuantity(reagentId).Value;
-            var removalPercentage = availableReagent / totalAvailableReagents;
             var fractionalReagent = entity.Comp.FractionalReagents.GetValueOrDefault(reagentId);
+            var availableReagent = solution.GetTotalPrototypeQuantity(reagentId);
+            var availForRatio = fractionalReagent + availableReagent.Float();
+            var removalPercentage = availForRatio / totalReagent;
+
             var toRemove = RemoveFractionalFuel(
                 ref fractionalReagent,
                 args.FuelUsed * removalPercentage,
                 multiplier * FixedPoint2.Epsilon.Float(),
-                availableReagent);
+                availableReagent.Value);
 
             entity.Comp.FractionalReagents[reagentId] = fractionalReagent;
             _solutionContainer.RemoveReagent(entity.Comp.Solution.Value, reagentId, FixedPoint2.FromCents(toRemove));
@@ -114,15 +125,12 @@ public sealed class GeneratorSystem : SharedGeneratorSystem
         if (!_solutionContainer.ResolveSolution(entity.Owner, entity.Comp.SolutionName, ref entity.Comp.Solution, out var solution))
             return;
 
-        var totalAvailableReagents = solution.GetTotalPrototypeQuantity(entity.Comp.Reagents.Keys.Select(p => p.Id).ToArray());
         var fuel = 0f;
         foreach (var (reagentId, multiplier) in entity.Comp.Reagents)
         {
-            var availableReagent = solution.GetTotalPrototypeQuantity(reagentId);
-            var percentage = availableReagent / totalAvailableReagents;
-            var fractionalReagent = (availableReagent * percentage).Float();
+            var reagent = solution.GetTotalPrototypeQuantity(reagentId).Float();
+            reagent += entity.Comp.FractionalReagents.GetValueOrDefault(reagentId) * FixedPoint2.Epsilon.Float();
 
-            var reagent = entity.Comp.FractionalReagents.GetValueOrDefault(reagentId) * FixedPoint2.Epsilon.Float() + fractionalReagent;
             fuel += reagent * multiplier;
         }
 
@@ -143,6 +151,10 @@ public sealed class GeneratorSystem : SharedGeneratorSystem
 
     private int RemoveFractionalFuel(ref float fractional, float fuelUsed, float multiplier, int availableQuantity)
     {
+        // Just a sanity thing since I got worried this might be possible.
+        if (!float.IsFinite(fractional))
+            fractional = 0;
+
         fractional -= fuelUsed / multiplier;
         if (fractional >= 0)
             return 0;