Files
Delta-v/Content.Shared/Atmos/EntitySystems/SharedAtmosphereSystem.Gases.cs
T
2026-06-29 12:43:46 +02:00

99 lines
4.5 KiB
C#

using System.Runtime.CompilerServices;
using Content.Shared.Atmos.Prototypes;
using Content.Shared.CCVar;
using JetBrains.Annotations;
namespace Content.Shared.Atmos.EntitySystems;
public abstract partial class SharedAtmosphereSystem
{
/*
Partial class for operations involving GasMixtures.
Sometimes methods here are abstract because they need different client/server implementations
due to sandboxing.
*/
/// <summary>
/// Cached array of gas specific heats.
/// </summary>
public float[] GasSpecificHeats => _gasSpecificHeats;
private float[] _gasSpecificHeats = new float[Atmospherics.TotalNumberOfGases];
public string?[] GasReagents = new string[Atmospherics.TotalNumberOfGases];
protected readonly GasPrototype[] GasPrototypes = new GasPrototype[Atmospherics.TotalNumberOfGases];
public virtual void InitializeGases()
{
foreach (var gas in Enum.GetValues<Gas>())
{
var idx = (int)gas;
// Log an error if the corresponding prototype isn't found
if (!_prototypeManager.TryIndex<GasPrototype>(gas.ToString(), out var gasPrototype))
{
Log.Error($"Failed to find corresponding {nameof(GasPrototype)} for gas ID {(int)gas} ({gas}) with expected ID \"{gas.ToString()}\". Is your prototype named correctly?");
continue;
}
GasPrototypes[idx] = gasPrototype;
GasReagents[idx] = gasPrototype.Reagent;
}
Array.Resize(ref _gasSpecificHeats, MathHelper.NextMultipleOf(Atmospherics.TotalNumberOfGases, 4));
for (var i = 0; i < GasPrototypes.Length; i++)
{
/*
As an optimization routine we pre-divide the specific heat by the heat scale here,
so we don't have to do it every time we calculate heat capacity.
Most usages are going to want the scaled value anyway.
If you would like the unscaled specific heat, you'd need to multiply by HeatScale again.
TODO ATMOS: please just make this 2 separate arrays instead of invoking multiplication every time.
*/
_gasSpecificHeats[i] = GasPrototypes[i].SpecificHeat / HeatScale;
}
}
/// <summary>
/// Calculates the heat capacity for a <see cref="GasMixture"/>.
/// </summary>
/// <param name="mixture">The <see cref="GasMixture"/> to calculate the heat capacity for.</param>
/// <param name="applyScaling">Whether to apply the heat capacity scaling factor.
/// This is an extremely important boolean to consider or else you will get heat transfer wrong.
/// See <see cref="CCVars.AtmosHeatScale"/> for more info.</param>
/// <returns>The heat capacity of the <see cref="GasMixture"/>.</returns>
[PublicAPI]
public float GetHeatCapacity(GasMixture mixture, bool applyScaling)
{
var scale = GetHeatCapacityCalculation(mixture.Moles, mixture.Immutable);
// By default GetHeatCapacityCalculation() has the heat-scale divisor pre-applied.
// So if we want the un-scaled heat capacity, we have to multiply by the scale.
return applyScaling ? scale : scale * HeatScale;
}
/// <summary>
/// Gets the heat capacity for a <see cref="GasMixture"/>.
/// </summary>
/// <param name="mixture">The <see cref="GasMixture"/> to calculate the heat capacity for.</param>
/// <returns>The heat capacity of the <see cref="GasMixture"/>.</returns>
/// <remarks>Note that the heat capacity of the mixture may be slightly different from
/// "real life" as we intentionally fake a heat capacity for space in <see cref="Atmospherics.SpaceHeatCapacity"/>
/// in order to allow Atmospherics to cool down space.</remarks>
protected float GetHeatCapacity(GasMixture mixture)
{
return GetHeatCapacityCalculation(mixture.Moles, mixture.Immutable);
}
/// <summary>
/// Gets the heat capacity for a <see cref="GasMixture"/>.
/// </summary>
/// <param name="moles">The moles array of the <see cref="GasMixture"/></param>
/// <param name="space">Whether this <see cref="GasMixture"/> represents space,
/// and thus experiences space-specific mechanics (we cheat and make it a bit cooler).
/// See <see cref="Atmospherics.SpaceHeatCapacity"/>.</param>
/// <returns>The heat capacity of the <see cref="GasMixture"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected abstract float GetHeatCapacityCalculation(float[] moles, bool space);
}