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>
This commit is contained in:
blueDev2
2024-09-12 06:29:11 -04:00
committed by GitHub
parent 2a6f15dd3e
commit c8f2ddc729
3 changed files with 30 additions and 2 deletions

View File

@@ -327,8 +327,23 @@ public sealed class InjectorSystem : SharedInjectorSystem
return false; 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 // 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); solution.AvailableVolume);
if (realTransferAmount <= 0) if (realTransferAmount <= 0)
@@ -350,6 +365,9 @@ public sealed class InjectorSystem : SharedInjectorSystem
// Move units from attackSolution to targetSolution // Move units from attackSolution to targetSolution
var removedSolution = SolutionContainers.Draw(target.Owner, targetSolution, realTransferAmount); 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)) if (!SolutionContainers.TryAddSolution(soln.Value, removedSolution))
{ {
return false; return false;

View File

@@ -1,7 +1,9 @@
using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.Chemistry.Reagent;
using Content.Shared.DoAfter; using Content.Shared.DoAfter;
using Content.Shared.FixedPoint; using Content.Shared.FixedPoint;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.Chemistry.Components; namespace Content.Shared.Chemistry.Components;
@@ -88,6 +90,14 @@ public sealed partial class InjectorComponent : Component
[DataField] [DataField]
public InjectorToggleMode ToggleState = InjectorToggleMode.Draw; public InjectorToggleMode ToggleState = InjectorToggleMode.Draw;
/// <summary>
/// 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.
/// </summary>
[DataField]
public List<ProtoId<ReagentPrototype>>? ReagentWhitelist = null;
#region Arguments for injection doafter #region Arguments for injection doafter
/// <inheritdoc cref=DoAfterArgs.NeedHand> /// <inheritdoc cref=DoAfterArgs.NeedHand>

View File

@@ -612,7 +612,7 @@ namespace Content.Shared.Chemistry.Components
} }
/// <summary> /// <summary>
/// Splits a solution without the specified reagent prototypes. /// Splits a solution with only the specified reagent prototypes.
/// </summary> /// </summary>
public Solution SplitSolutionWithOnly(FixedPoint2 toTake, params string[] includedPrototypes) public Solution SplitSolutionWithOnly(FixedPoint2 toTake, params string[] includedPrototypes)
{ {