From ccd47a00a3a26e11b7f93e09b6e3c6638c9a0bac Mon Sep 17 00:00:00 2001
From: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Date: Sat, 18 Oct 2025 19:06:08 +0200
Subject: [PATCH] Fix AddReagent modifying to solution being added in some
cases (#40959)
fix
---
.../Chemistry/Components/Solution.cs | 35 ++++++++++---------
.../SharedSolutionContainerSystem.cs | 24 +++++++------
2 files changed, 33 insertions(+), 26 deletions(-)
diff --git a/Content.Shared/Chemistry/Components/Solution.cs b/Content.Shared/Chemistry/Components/Solution.cs
index 38be03226d..2179469c08 100644
--- a/Content.Shared/Chemistry/Components/Solution.cs
+++ b/Content.Shared/Chemistry/Components/Solution.cs
@@ -37,7 +37,6 @@ namespace Content.Shared.Chemistry.Components
/// systems use this.
///
[DataField("maxVol")]
- [ViewVariables(VVAccess.ReadWrite)]
public FixedPoint2 MaxVolume { get; set; } = FixedPoint2.Zero;
public float FillFraction => MaxVolume == 0 ? 1 : Volume.Float() / MaxVolume.Float();
@@ -45,8 +44,7 @@ namespace Content.Shared.Chemistry.Components
///
/// If reactions will be checked for when adding reagents to the container.
///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("canReact")]
+ [DataField]
public bool CanReact { get; set; } = true;
///
@@ -58,8 +56,7 @@ namespace Content.Shared.Chemistry.Components
///
/// The temperature of the reagents in the solution.
///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("temperature")]
+ [DataField]
public float Temperature { get; set; } = 293.15f;
///
@@ -100,7 +97,7 @@ namespace Content.Shared.Chemistry.Components
_heatCapacity = 0;
foreach (var (reagent, quantity) in Contents)
{
- _heatCapacity += (float) quantity *
+ _heatCapacity += (float)quantity *
protoMan.Index(reagent.Prototype).SpecificHeat;
}
@@ -148,7 +145,7 @@ namespace Content.Shared.Chemistry.Components
///
/// The prototype ID of the reagent to add.
/// The quantity in milli-units.
- public Solution(string prototype, FixedPoint2 quantity, List? data = null) : this()
+ public Solution([ForbidLiteral] string prototype, FixedPoint2 quantity, List? data = null) : this()
{
AddReagent(new ReagentId(prototype, data), quantity);
}
@@ -190,7 +187,7 @@ namespace Content.Shared.Chemistry.Components
public void ValidateSolution()
{
// sandbox forbids: [Conditional("DEBUG")]
- #if DEBUG
+#if DEBUG
// Correct volume
DebugTools.Assert(Contents.Select(x => x.Quantity).Sum() == Volume);
@@ -208,7 +205,7 @@ namespace Content.Shared.Chemistry.Components
UpdateHeatCapacity(null);
DebugTools.Assert(MathHelper.CloseTo(_heatCapacity, cur, tolerance: 0.01));
}
- #endif
+#endif
}
void ISerializationHooks.AfterDeserialization()
@@ -223,7 +220,7 @@ namespace Content.Shared.Chemistry.Components
MaxVolume = Volume;
}
- public bool ContainsPrototype(string prototype)
+ public bool ContainsPrototype([ForbidLiteral] string prototype)
{
foreach (var (reagent, _) in Contents)
{
@@ -245,7 +242,7 @@ namespace Content.Shared.Chemistry.Components
return false;
}
- public bool ContainsReagent(string reagentId, List? data)
+ public bool ContainsReagent([ForbidLiteral] string reagentId, List? data)
=> ContainsReagent(new(reagentId, data));
public bool TryGetReagent(ReagentId id, out ReagentQuantity quantity)
@@ -352,7 +349,7 @@ namespace Content.Shared.Chemistry.Components
///
/// The prototype ID of the reagent to add.
/// The quantity in milli-units.
- public void AddReagent(string prototype, FixedPoint2 quantity, bool dirtyHeatCap = true)
+ public void AddReagent([ForbidLiteral] string prototype, FixedPoint2 quantity, bool dirtyHeatCap = true)
=> AddReagent(new ReagentId(prototype, null), quantity, dirtyHeatCap);
///
@@ -673,6 +670,12 @@ namespace Content.Shared.Chemistry.Components
return sol;
}
+ ///
+ /// Splits a solution into two by moving reagents from the given solution into a new one.
+ /// This modifies the original solution.
+ ///
+ /// The quantity of this solution to remove.
+ /// A new solution containing the removed reagents.
public Solution SplitSolution(FixedPoint2 toTake)
{
if (toTake <= FixedPoint2.Zero)
@@ -690,7 +693,7 @@ namespace Content.Shared.Chemistry.Components
var origVol = Volume;
var effVol = Volume.Value;
newSolution = new Solution(Contents.Count) { Temperature = Temperature };
- var remaining = (long) toTake.Value;
+ var remaining = (long)toTake.Value;
for (var i = Contents.Count - 1; i >= 0; i--) // iterate backwards because of remove swap.
{
@@ -706,7 +709,7 @@ namespace Content.Shared.Chemistry.Components
continue;
}
- var splitQuantity = FixedPoint2.FromCents((int) split);
+ var splitQuantity = FixedPoint2.FromCents((int)split);
var newQuantity = quantity - splitQuantity;
DebugTools.Assert(newQuantity >= 0);
@@ -753,7 +756,7 @@ namespace Content.Shared.Chemistry.Components
var effVol = Volume.Value;
Volume -= toTake;
- var remaining = (long) toTake.Value;
+ var remaining = (long)toTake.Value;
for (var i = Contents.Count - 1; i >= 0; i--)// iterate backwards because of remove swap.
{
var (reagent, quantity) = Contents[i];
@@ -768,7 +771,7 @@ namespace Content.Shared.Chemistry.Components
continue;
}
- var splitQuantity = FixedPoint2.FromCents((int) split);
+ var splitQuantity = FixedPoint2.FromCents((int)split);
var newQuantity = quantity - splitQuantity;
if (newQuantity > FixedPoint2.Zero)
diff --git a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs
index 671a30dec4..a245c0b606 100644
--- a/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs
+++ b/Content.Shared/Chemistry/EntitySystems/SharedSolutionContainerSystem.cs
@@ -588,7 +588,7 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem
/// Adds a solution to the container, if it can fully fit.
///
/// entity holding targetSolution
- /// entity holding targetSolution
+ /// entity holding targetSolution
/// solution being added
/// If the solution could be added.
public bool TryAddSolution(Entity soln, Solution toAdd)
@@ -606,40 +606,44 @@ public abstract partial class SharedSolutionContainerSystem : EntitySystem
}
///
- /// Adds as much of a solution to a container as can fit.
+ /// Adds as much of a solution to a container as can fit and updates the container.
///
/// The entity containing
/// The solution being added to.
- /// The solution being added to
+ /// The solution being added to . This solution is not modified.
/// The quantity of the solution actually added.
public FixedPoint2 AddSolution(Entity soln, Solution toAdd)
{
- var (uid, comp) = soln;
- var solution = comp.Solution;
+ var solution = soln.Comp.Solution;
if (toAdd.Volume == FixedPoint2.Zero)
return FixedPoint2.Zero;
var quantity = FixedPoint2.Max(FixedPoint2.Zero, FixedPoint2.Min(toAdd.Volume, solution.AvailableVolume));
if (quantity < toAdd.Volume)
- TryTransferSolution(soln, toAdd, quantity);
+ {
+ // TODO: This should be made into a function that directly transfers reagents.
+ // Currently this is quite inefficient.
+ solution.AddSolution(toAdd.Clone().SplitSolution(quantity), PrototypeManager);
+ }
else
- ForceAddSolution(soln, toAdd);
+ solution.AddSolution(toAdd, PrototypeManager);
+ UpdateChemicals(soln);
return quantity;
}
///
/// Adds a solution to a container and updates the container.
+ /// This can exceed the maximum volume of the solution added to.
///
/// The entity containing
/// The solution being added to.
- /// The solution being added to
+ /// The solution being added to . This solution is not modified.
/// Whether any reagents were added to the solution.
public bool ForceAddSolution(Entity soln, Solution toAdd)
{
- var (uid, comp) = soln;
- var solution = comp.Solution;
+ var solution = soln.Comp.Solution;
if (toAdd.Volume == FixedPoint2.Zero)
return false;