From cdc0c35f3f49bccce2207da57cb001e39a30a3ce Mon Sep 17 00:00:00 2001
From: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Date: Wed, 24 Dec 2025 00:15:10 -0800
Subject: [PATCH] AddMolsToMixture atmos helper (#42033)
---
.../EntitySystems/AtmosphereSystem.Gases.cs | 21 ++++++
.../Server/Atmos/AddMolsToMixtureTest.cs | 75 +++++++++++++++++++
2 files changed, 96 insertions(+)
create mode 100644 Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs
diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs
index 0c6a3a7daa..95d56c9ca6 100644
--- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs
+++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs
@@ -3,6 +3,7 @@ using System.Runtime.CompilerServices;
using Content.Server.Atmos.Reactions;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Reactions;
+using JetBrains.Annotations;
using Robust.Shared.Prototypes;
using DependencyAttribute = Robust.Shared.IoC.DependencyAttribute;
@@ -477,6 +478,26 @@ namespace Content.Server.Atmos.EntitySystems
return reaction;
}
+ ///
+ /// Adds an array of moles to a .
+ /// Guards against negative moles by clamping to zero.
+ ///
+ /// The to add moles to.
+ /// The of moles to add.
+ /// Thrown when the length of the
+ /// is not the same as the length of the gas array.
+ [PublicAPI]
+ public static void AddMolsToMixture(GasMixture mixture, ReadOnlySpan molsToAdd)
+ {
+ // Span length should be as long as the length of the gas array.
+ // Technically this is a redundant check because NumericsHelpers will do the same thing,
+ // but eh.
+ ArgumentOutOfRangeException.ThrowIfNotEqual(mixture.Moles.Length, molsToAdd.Length, nameof(mixture.Moles.Length));
+
+ NumericsHelpers.Add(mixture.Moles, molsToAdd);
+ NumericsHelpers.Max(mixture.Moles, 0f);
+ }
+
public enum GasCompareResult
{
NoExchange = -2,
diff --git a/Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs b/Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs
new file mode 100644
index 0000000000..07b45bfe11
--- /dev/null
+++ b/Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs
@@ -0,0 +1,75 @@
+using System;
+using Content.Server.Atmos.EntitySystems;
+using Content.Shared.Atmos;
+using NUnit.Framework;
+
+namespace Content.Tests.Server.Atmos;
+
+[TestFixture, TestOf(typeof(AtmosphereSystem))]
+[Parallelizable(ParallelScope.All)]
+public sealed class AddMolsToMixtureTest
+{
+ ///
+ /// Assert that an exception is thrown if the length of the array passed in
+ /// does not match the number of gases.
+ ///
+ [Test]
+ [TestCase(-1)]
+ [TestCase(1)]
+ public void AddMolsToMixture_Throws_OnLengthMismatch(int num)
+ {
+ var mixture = new GasMixture();
+ var wrongLength = new float[Atmospherics.AdjustedNumberOfGases + num];
+
+ var ex = Assert.Throws(() =>
+ AtmosphereSystem.AddMolsToMixture(mixture, wrongLength));
+
+ Assert.That(ex!.ParamName, Is.EqualTo("Length"));
+ }
+
+ ///
+ /// Assert that the added mols are correctly added.
+ ///
+ [Test]
+ public void AddMolsToMixture_Adds_CheckElementwise()
+ {
+ var mixture = new GasMixture();
+ mixture.SetMoles(Gas.Oxygen, 1f);
+ mixture.SetMoles(Gas.Nitrogen, 2f);
+
+ var add = new float[Atmospherics.AdjustedNumberOfGases];
+ add[(int)Gas.Oxygen] = 3f;
+ add[(int)Gas.Nitrogen] = 4f;
+
+ AtmosphereSystem.AddMolsToMixture(mixture, add);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(mixture.GetMoles(Gas.Oxygen), Is.EqualTo(4f));
+ Assert.That(mixture.GetMoles(Gas.Nitrogen), Is.EqualTo(6f));
+ }
+ }
+
+ ///
+ /// Assert that the added mols are correctly clamped at zero.
+ ///
+ [Test]
+ public void AddMolsToMixture_EnsureClamp()
+ {
+ var mixture = new GasMixture();
+ mixture.SetMoles(Gas.Oxygen, 1f);
+ mixture.SetMoles(Gas.Nitrogen, 2f);
+
+ var add = new float[Atmospherics.AdjustedNumberOfGases];
+ add[(int)Gas.Oxygen] = -2f; // would go to -1 without clamping
+ add[(int)Gas.Nitrogen] = -1f; // should become 1
+
+ AtmosphereSystem.AddMolsToMixture(mixture, add);
+
+ using (Assert.EnterMultipleScope())
+ {
+ Assert.That(mixture.GetMoles(Gas.Oxygen), Is.Zero);
+ Assert.That(mixture.GetMoles(Gas.Nitrogen), Is.EqualTo(1f));
+ }
+ }
+}
--
2.52.0