]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Allow chemical-fueled generators to use multiple reagents (#24258)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Sun, 21 Jan 2024 01:25:52 +0000 (20:25 -0500)
committerGitHub <noreply@github.com>
Sun, 21 Jan 2024 01:25:52 +0000 (17:25 -0800)
multi-reagent generators

Content.Server/Power/Generator/ChemicalFuelGeneratorAdapterComponent.cs
Content.Server/Power/Generator/GeneratorSystem.cs
Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml

index 20d714933254dabcb1231e55336ec9dd1c028eef..58e0e8b012a8f1e224e025bf7cdb1544c27e67f2 100644 (file)
@@ -2,6 +2,7 @@
 using Content.Shared.Chemistry.Components.SolutionManager;
 using Content.Shared.Chemistry.Reagent;
 using Content.Shared.FixedPoint;
+using Robust.Shared.Prototypes;
 using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
 
 namespace Content.Server.Power.Generator;
@@ -13,11 +14,10 @@ namespace Content.Server.Power.Generator;
 public sealed partial class ChemicalFuelGeneratorAdapterComponent : Component
 {
     /// <summary>
-    /// The reagent to accept as fuel.
+    /// A dictionary relating a reagent to accept as fuel to a value to multiply reagent amount by to get fuel amount.
     /// </summary>
-    [DataField("reagent", customTypeSerializer: typeof(PrototypeIdSerializer<ReagentPrototype>))]
-    [ViewVariables(VVAccess.ReadWrite)]
-    public string Reagent = "WeldingFuel";
+    [DataField]
+    public Dictionary<ProtoId<ReagentPrototype>, float> Reagents = new();
 
     /// <summary>
     /// The name of <see cref="Solution"/>.
@@ -32,16 +32,10 @@ public sealed partial class ChemicalFuelGeneratorAdapterComponent : Component
     [DataField("solutionRef")]
     public Entity<SolutionComponent>? Solution = null;
 
-    /// <summary>
-    /// Value to multiply reagent amount by to get fuel amount.
-    /// </summary>
-    [DataField("multiplier"), ViewVariables(VVAccess.ReadWrite)]
-    public float Multiplier = 1f;
-
     /// <summary>
     /// How much reagent (can be fractional) is left in the generator.
     /// Stored in units of <see cref="FixedPoint2.Epsilon"/>.
     /// </summary>
-    [DataField("fractionalReagent"), ViewVariables(VVAccess.ReadWrite)]
-    public float FractionalReagent;
+    [DataField]
+    public Dictionary<ProtoId<ReagentPrototype>, float> FractionalReagents = new();
 }
index a23b0b8eed23647233a32523e37ab4ffecc0dc11..fc6ac073400269981fed5f3f667092e3f41599f4 100644 (file)
@@ -1,4 +1,5 @@
-using Content.Server.Audio;
+using System.Linq;
+using Content.Server.Audio;
 using Content.Server.Chemistry.Containers.EntitySystems;
 using Content.Server.Fluids.EntitySystems;
 using Content.Server.Materials;
@@ -81,7 +82,7 @@ public sealed class GeneratorSystem : SharedGeneratorSystem
 
         foreach (var reagentQuantity in solution)
         {
-            if (reagentQuantity.Reagent.Prototype != entity.Comp.Reagent)
+            if (!entity.Comp.Reagents.ContainsKey(reagentQuantity.Reagent.Prototype))
             {
                 args.Clogged = true;
                 return;
@@ -94,14 +95,21 @@ public sealed class GeneratorSystem : SharedGeneratorSystem
         if (!_solutionContainer.ResolveSolution(entity.Owner, entity.Comp.SolutionName, ref entity.Comp.Solution, out var solution))
             return;
 
-        var availableReagent = solution.GetTotalPrototypeQuantity(entity.Comp.Reagent).Value;
-        var toRemove = RemoveFractionalFuel(
-            ref entity.Comp.FractionalReagent,
-            args.FuelUsed,
-            entity.Comp.Multiplier * FixedPoint2.Epsilon.Float(),
-            availableReagent);
-
-        _solutionContainer.RemoveReagent(entity.Comp.Solution.Value, entity.Comp.Reagent, FixedPoint2.FromCents(toRemove));
+        var totalAvailableReagents = solution.GetTotalPrototypeQuantity(entity.Comp.Reagents.Keys.Select(p => p.Id).ToArray()).Value;
+        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 toRemove = RemoveFractionalFuel(
+                ref fractionalReagent,
+                args.FuelUsed * removalPercentage,
+                multiplier * FixedPoint2.Epsilon.Float(),
+                availableReagent);
+
+            entity.Comp.FractionalReagents[reagentId] = fractionalReagent;
+            _solutionContainer.RemoveReagent(entity.Comp.Solution.Value, reagentId, FixedPoint2.FromCents(toRemove));
+        }
     }
 
     private void ChemicalGetFuel(Entity<ChemicalFuelGeneratorAdapterComponent> entity, ref GeneratorGetFuelEvent args)
@@ -109,9 +117,19 @@ public sealed class GeneratorSystem : SharedGeneratorSystem
         if (!_solutionContainer.ResolveSolution(entity.Owner, entity.Comp.SolutionName, ref entity.Comp.Solution, out var solution))
             return;
 
-        var availableReagent = solution.GetTotalPrototypeQuantity(entity.Comp.Reagent).Float();
-        var reagent = entity.Comp.FractionalReagent * FixedPoint2.Epsilon.Float() + availableReagent;
-        args.Fuel = reagent * entity.Comp.Multiplier;
+        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 = entity.Comp.FractionalReagents.GetValueOrDefault(reagentId) * FixedPoint2.Epsilon.Float() + fractionalReagent;
+            fuel += reagent * multiplier;
+        }
+
+        args.Fuel = fuel;
     }
 
     private void SolidUseFuel(EntityUid uid, SolidFuelGeneratorAdapterComponent component, GeneratorUseFuel args)
index d900d791d3e7aaea0bca622bc4e116d99dca87c8..d1f84f5b6e1cdd79cf4f3fbc3166537d82d7ddbb 100644 (file)
       fuelEfficiencyConstant: 0.3
     - type: ChemicalFuelGeneratorAdapter
       solution: tank
-      reagent: WeldingFuel
+      reagents:
+        WeldingFuel: 1
     - type: SolutionContainerManager
       solutions:
         tank: