From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com>
Date: Fri, 16 Aug 2024 10:47:53 +0000 (+0200)
Subject: Fix reagents with ReagentData being duplicated (#30983)
X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=49dd17dcab3f6a6e327f6b3cc1f0ccd1afef66bf;p=space-station-14.git
Fix reagents with ReagentData being duplicated (#30983)
Initial commit
---
diff --git a/Content.Shared/Chemistry/Components/Solution.cs b/Content.Shared/Chemistry/Components/Solution.cs
index 725a685a8b..35ab28f34a 100644
--- a/Content.Shared/Chemistry/Components/Solution.cs
+++ b/Content.Shared/Chemistry/Components/Solution.cs
@@ -480,41 +480,72 @@ namespace Content.Shared.Chemistry.Components
///
/// The reagent to be removed.
/// How much reagent was actually removed. Zero if the reagent is not present on the solution.
- public FixedPoint2 RemoveReagent(ReagentQuantity toRemove, bool preserveOrder = false)
+ public FixedPoint2 RemoveReagent(ReagentQuantity toRemove, bool preserveOrder = false, bool ignoreReagentData = false)
{
if (toRemove.Quantity <= FixedPoint2.Zero)
return FixedPoint2.Zero;
+ List reagentIndices = new List();
+ int totalRemoveVolume = 0;
+
for (var i = 0; i < Contents.Count; i++)
{
- var (reagent, curQuantity) = Contents[i];
+ var (reagent, quantity) = Contents[i];
- if(reagent.Prototype != toRemove.Reagent.Prototype)
- continue;
+ if (ignoreReagentData)
+ {
+ if (reagent.Prototype != toRemove.Reagent.Prototype)
+ continue;
+ }
+ else
+ {
+ if (reagent != toRemove.Reagent)
+ continue;
+ }
+ //We prepend instead of add to handle the Contents list back-to-front later down.
+ //It makes RemoveSwap safe to use.
+ totalRemoveVolume += quantity.Value;
+ reagentIndices.Insert(0, i);
+ }
+
+ if (totalRemoveVolume <= 0)
+ {
+ // Reagent is not on the solution...
+ return FixedPoint2.Zero;
+ }
+
+ FixedPoint2 removedQuantity = 0;
+ for (var i = 0; i < reagentIndices.Count; i++)
+ {
+ var (reagent, curQuantity) = Contents[reagentIndices[i]];
+
+ // This is set up such that integer rounding will tend to take more reagents.
+ var split = ((long)toRemove.Quantity.Value) * curQuantity.Value / totalRemoveVolume;
+
+ var splitQuantity = FixedPoint2.FromCents((int)split);
- var newQuantity = curQuantity - toRemove.Quantity;
+ var newQuantity = curQuantity - splitQuantity;
_heatCapacityDirty = true;
if (newQuantity <= 0)
{
if (!preserveOrder)
- Contents.RemoveSwap(i);
+ Contents.RemoveSwap(reagentIndices[i]);
else
- Contents.RemoveAt(i);
+ Contents.RemoveAt(reagentIndices[i]);
Volume -= curQuantity;
- ValidateSolution();
- return curQuantity;
+ removedQuantity += curQuantity;
+ continue;
}
- Contents[i] = new ReagentQuantity(reagent, newQuantity);
- Volume -= toRemove.Quantity;
- ValidateSolution();
- return toRemove.Quantity;
+ Contents[reagentIndices[i]] = new ReagentQuantity(reagent, newQuantity);
+ Volume -= splitQuantity;
+ removedQuantity += splitQuantity;
}
+ ValidateSolution();
- // Reagent is not on the solution...
- return FixedPoint2.Zero;
+ return removedQuantity;
}
///
@@ -523,9 +554,9 @@ namespace Content.Shared.Chemistry.Components
/// The prototype of the reagent to be removed.
/// The amount of reagent to remove.
/// How much reagent was actually removed. Zero if the reagent is not present on the solution.
- public FixedPoint2 RemoveReagent(string prototype, FixedPoint2 quantity, List? data = null)
+ public FixedPoint2 RemoveReagent(string prototype, FixedPoint2 quantity, List? data = null, bool ignoreReagentData = false)
{
- return RemoveReagent(new ReagentQuantity(prototype, quantity, data));
+ return RemoveReagent(new ReagentQuantity(prototype, quantity, data), ignoreReagentData: ignoreReagentData);
}
///
@@ -534,9 +565,9 @@ namespace Content.Shared.Chemistry.Components
/// The reagent to be removed.
/// The amount of reagent to remove.
/// How much reagent was actually removed. Zero if the reagent is not present on the solution.
- public FixedPoint2 RemoveReagent(ReagentId reagentId, FixedPoint2 quantity, bool preserveOrder = false)
+ public FixedPoint2 RemoveReagent(ReagentId reagentId, FixedPoint2 quantity, bool preserveOrder = false, bool ignoreReagentData = false)
{
- return RemoveReagent(new ReagentQuantity(reagentId, quantity), preserveOrder);
+ return RemoveReagent(new ReagentQuantity(reagentId, quantity), preserveOrder, ignoreReagentData);
}
public void RemoveAllSolution()
diff --git a/Content.Shared/Chemistry/Reaction/ChemicalReactionSystem.cs b/Content.Shared/Chemistry/Reaction/ChemicalReactionSystem.cs
index f9dfa9b273..534b6ba9f6 100644
--- a/Content.Shared/Chemistry/Reaction/ChemicalReactionSystem.cs
+++ b/Content.Shared/Chemistry/Reaction/ChemicalReactionSystem.cs
@@ -172,7 +172,7 @@ namespace Content.Shared.Chemistry.Reaction
if (!reactant.Value.Catalyst)
{
var amountToRemove = unitReactions * reactant.Value.Amount;
- solution.RemoveReagent(reactant.Key, amountToRemove);
+ solution.RemoveReagent(reactant.Key, amountToRemove, ignoreReagentData: true);
}
}