From c8f2ddc72985172992570fd5f1d60300948b33ed Mon Sep 17 00:00:00 2001
From: blueDev2 <89804215+blueDev2@users.noreply.github.com>
Date: Thu, 12 Sep 2024 06:29:11 -0400
Subject: [PATCH] Add ReagentWhitelist to Injector component and system
(#28262)
* Add reagent whitelist to Injector component and system
* Apply suggested Changes
* Remove LINQ function for performance
* Update Content.Server/Chemistry/EntitySystems/InjectorSystem.cs
Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
---------
Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
---
.../Chemistry/EntitySystems/InjectorSystem.cs | 20 ++++++++++++++++++-
.../Chemistry/Components/InjectorComponent.cs | 10 ++++++++++
.../Chemistry/Components/Solution.cs | 2 +-
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/Content.Server/Chemistry/EntitySystems/InjectorSystem.cs b/Content.Server/Chemistry/EntitySystems/InjectorSystem.cs
index d94faa8123..c5c45daa5b 100644
--- a/Content.Server/Chemistry/EntitySystems/InjectorSystem.cs
+++ b/Content.Server/Chemistry/EntitySystems/InjectorSystem.cs
@@ -327,8 +327,23 @@ public sealed class InjectorSystem : SharedInjectorSystem
return false;
}
+ var applicableTargetSolution = targetSolution.Comp.Solution;
+ // If a whitelist exists, remove all non-whitelisted reagents from the target solution temporarily
+ var temporarilyRemovedSolution = new Solution();
+ if (injector.Comp.ReagentWhitelist is { } reagentWhitelist)
+ {
+ string[] reagentPrototypeWhitelistArray = new string[reagentWhitelist.Count];
+ var i = 0;
+ foreach (var reagent in reagentWhitelist)
+ {
+ reagentPrototypeWhitelistArray[i] = reagent;
+ ++i;
+ }
+ temporarilyRemovedSolution = applicableTargetSolution.SplitSolutionWithout(applicableTargetSolution.Volume, reagentPrototypeWhitelistArray);
+ }
+
// Get transfer amount. May be smaller than _transferAmount if not enough room, also make sure there's room in the injector
- var realTransferAmount = FixedPoint2.Min(injector.Comp.TransferAmount, targetSolution.Comp.Solution.Volume,
+ var realTransferAmount = FixedPoint2.Min(injector.Comp.TransferAmount, applicableTargetSolution.Volume,
solution.AvailableVolume);
if (realTransferAmount <= 0)
@@ -350,6 +365,9 @@ public sealed class InjectorSystem : SharedInjectorSystem
// Move units from attackSolution to targetSolution
var removedSolution = SolutionContainers.Draw(target.Owner, targetSolution, realTransferAmount);
+ // Add back non-whitelisted reagents to the target solution
+ applicableTargetSolution.AddSolution(temporarilyRemovedSolution, null);
+
if (!SolutionContainers.TryAddSolution(soln.Value, removedSolution))
{
return false;
diff --git a/Content.Shared/Chemistry/Components/InjectorComponent.cs b/Content.Shared/Chemistry/Components/InjectorComponent.cs
index 1f2716356c..17a65ef1c1 100644
--- a/Content.Shared/Chemistry/Components/InjectorComponent.cs
+++ b/Content.Shared/Chemistry/Components/InjectorComponent.cs
@@ -1,7 +1,9 @@
using Content.Shared.Chemistry.EntitySystems;
+using Content.Shared.Chemistry.Reagent;
using Content.Shared.DoAfter;
using Content.Shared.FixedPoint;
using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Chemistry.Components;
@@ -88,6 +90,14 @@ public sealed partial class InjectorComponent : Component
[DataField]
public InjectorToggleMode ToggleState = InjectorToggleMode.Draw;
+ ///
+ /// Reagents that are allowed to be within this injector.
+ /// If a solution has both allowed and non-allowed reagents, only allowed reagents will be drawn into this injector.
+ /// A null ReagentWhitelist indicates all reagents are allowed.
+ ///
+ [DataField]
+ public List>? ReagentWhitelist = null;
+
#region Arguments for injection doafter
///
diff --git a/Content.Shared/Chemistry/Components/Solution.cs b/Content.Shared/Chemistry/Components/Solution.cs
index fc25781005..c65ba0e80e 100644
--- a/Content.Shared/Chemistry/Components/Solution.cs
+++ b/Content.Shared/Chemistry/Components/Solution.cs
@@ -612,7 +612,7 @@ namespace Content.Shared.Chemistry.Components
}
///
- /// Splits a solution without the specified reagent prototypes.
+ /// Splits a solution with only the specified reagent prototypes.
///
public Solution SplitSolutionWithOnly(FixedPoint2 toTake, params string[] includedPrototypes)
{
--
2.52.0