Atmos scaling cvar changes (#22501)

This commit is contained in:
Leon Friedrich
2023-12-15 17:02:21 -05:00
committed by GitHub
parent a88730fcfa
commit 477327f952
16 changed files with 76 additions and 40 deletions

View File

@@ -43,11 +43,22 @@ namespace Content.Server.Atmos.EntitySystems
/// <summary> /// <summary>
/// Calculates the heat capacity for a gas mixture. /// Calculates the heat capacity for a gas mixture.
/// </summary> /// </summary>
public float GetHeatCapacity(GasMixture mixture) /// <param name="mixture">The mixture whose heat capacity should be calculated</param>
/// <param name="applyScaling"> Whether the internal heat capacity scaling should be applied. This should not be
/// used outside of atmospheric related heat transfer.</param>
/// <returns></returns>
public float GetHeatCapacity(GasMixture mixture, bool applyScaling)
{ {
return GetHeatCapacityCalculation(mixture.Moles, mixture.Immutable); 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;
} }
private float GetHeatCapacity(GasMixture mixture)
=> GetHeatCapacityCalculation(mixture.Moles, mixture.Immutable);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private float GetHeatCapacityCalculation(float[] moles, bool space) private float GetHeatCapacityCalculation(float[] moles, bool space)
{ {
@@ -320,7 +331,9 @@ namespace Content.Server.Atmos.EntitySystems
var req = prototype.MinimumRequirements[i]; var req = prototype.MinimumRequirements[i];
if (!(mixture.GetMoles(i) < req)) continue; if (!(mixture.GetMoles(i) < req))
continue;
doReaction = false; doReaction = false;
break; break;
} }
@@ -328,7 +341,7 @@ namespace Content.Server.Atmos.EntitySystems
if (!doReaction) if (!doReaction)
continue; continue;
reaction = prototype.React(mixture, holder, this); reaction = prototype.React(mixture, holder, this, HeatScale);
if(reaction.HasFlag(ReactionResult.StopReactions)) if(reaction.HasFlag(ReactionResult.StopReactions))
break; break;
} }

View File

@@ -3,6 +3,7 @@ using Content.Server.Atmos.Components;
using Content.Server.Atmos.Reactions; using Content.Server.Atmos.Reactions;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.Components; using Content.Shared.Atmos.Components;
using Robust.Shared.Map;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -558,4 +559,12 @@ public sealed partial class AtmosphereSystem
InvalidateVisuals(uid, position, overlay); InvalidateVisuals(uid, position, overlay);
} }
} }
public TileRef GetTileRef(TileAtmosphere tile)
{
if (!TryComp(tile.GridIndex, out MapGridComponent? grid))
return default;
_map.TryGetTileRef(tile.GridIndex, grid, tile.GridIndices, out var tileRef);
return tileRef;
}
} }

View File

@@ -1,13 +1,12 @@
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.Atmos.Components; using Content.Server.Atmos.Components;
using Content.Server.Body.Systems; using Content.Server.Body.Systems;
using Content.Server.Maps; using Content.Server.Fluids.EntitySystems;
using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.EntitySystems;
using Content.Shared.Atmos.EntitySystems; using Content.Shared.Atmos.EntitySystems;
using Content.Shared.Maps; using Content.Shared.Maps;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems; using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Map; using Robust.Shared.Map;
@@ -33,6 +32,8 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly TransformSystem _transformSystem = default!; [Dependency] private readonly TransformSystem _transformSystem = default!;
[Dependency] private readonly TileSystem _tile = default!; [Dependency] private readonly TileSystem _tile = default!;
[Dependency] private readonly MapSystem _map = default!;
[Dependency] public readonly PuddleSystem Puddle = default!;
private const float ExposedUpdateDelay = 1f; private const float ExposedUpdateDelay = 1f;
private float _exposedTimer = 0f; private float _exposedTimer = 0f;
@@ -80,7 +81,7 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem
return; return;
var query = EntityQueryEnumerator<AtmosExposedComponent, TransformComponent>(); var query = EntityQueryEnumerator<AtmosExposedComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var exposed, out var transform)) while (query.MoveNext(out var uid, out _, out var transform))
{ {
var air = GetContainingMixture(uid, transform:transform); var air = GetContainingMixture(uid, transform:transform);

View File

@@ -83,7 +83,7 @@ public sealed class HeatExchangerSystem : EntitySystem
else else
xfer = outlet.Air.Remove(-n); xfer = outlet.Air.Remove(-n);
float CXfer = _atmosphereSystem.GetHeatCapacity(xfer); float CXfer = _atmosphereSystem.GetHeatCapacity(xfer, true);
if (CXfer < Atmospherics.MinimumHeatCapacity) if (CXfer < Atmospherics.MinimumHeatCapacity)
return; return;
@@ -94,7 +94,7 @@ public sealed class HeatExchangerSystem : EntitySystem
float CEnv = 0f; float CEnv = 0f;
if (environment != null) if (environment != null)
{ {
CEnv = _atmosphereSystem.GetHeatCapacity(environment); CEnv = _atmosphereSystem.GetHeatCapacity(environment, true);
hasEnv = CEnv >= Atmospherics.MinimumHeatCapacity && environment.TotalMoles > 0f; hasEnv = CEnv >= Atmospherics.MinimumHeatCapacity && environment.TotalMoles > 0f;
if (hasEnv) if (hasEnv)
radTemp = environment.Temperature; radTemp = environment.Temperature;

View File

@@ -6,6 +6,14 @@ namespace Content.Server.Atmos
[ImplicitDataDefinitionForInheritors] [ImplicitDataDefinitionForInheritors]
public partial interface IGasReactionEffect public partial interface IGasReactionEffect
{ {
ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem); /// <summary>
/// Process this reaction effect.
/// </summary>
/// <param name="mixture">The gas mixture to react</param>
/// <param name="holder">The container of this gas mixture</param>
/// <param name="atmosphereSystem">The atmosphere system</param>
/// <param name="heatScale">Scaling factor that should be applied to all heat input or outputs.</param>
ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem,
float heatScale);
} }
} }

View File

@@ -64,7 +64,7 @@ public sealed class GasCondenserSystem : EntitySystem
public float NumberOfMolesToConvert(ApcPowerReceiverComponent comp, GasMixture mix, float dt) public float NumberOfMolesToConvert(ApcPowerReceiverComponent comp, GasMixture mix, float dt)
{ {
var hc = _atmosphereSystem.GetHeatCapacity(mix); var hc = _atmosphereSystem.GetHeatCapacity(mix, true);
var alpha = 0.8f; // tuned to give us 1-ish u/second of reagent conversion var alpha = 0.8f; // tuned to give us 1-ish u/second of reagent conversion
// ignores the energy needed to cool down the solution to the condensation point, but that probably adds too much difficulty and so let's not simulate that // ignores the energy needed to cool down the solution to the condensation point, but that probably adds too much difficulty and so let's not simulate that
var energy = comp.Load * dt; var energy = comp.Load * dt;

View File

@@ -80,7 +80,7 @@ namespace Content.Server.Atmos.Piping.Unary.EntitySystems
float dQ = thermoMachine.HeatCapacity * thermoMachine.Cp * args.dt; float dQ = thermoMachine.HeatCapacity * thermoMachine.Cp * args.dt;
// Clamps the heat transferred to not overshoot // Clamps the heat transferred to not overshoot
float Cin = _atmosphereSystem.GetHeatCapacity(inlet.Air); float Cin = _atmosphereSystem.GetHeatCapacity(inlet.Air, true);
float dT = targetTemp - temp; float dT = targetTemp - temp;
float dQLim = dT * Cin; float dQLim = dT * Cin;
float scale = 1f; float scale = 1f;

View File

@@ -10,9 +10,9 @@ namespace Content.Server.Atmos.Reactions;
[UsedImplicitly] [UsedImplicitly]
public sealed partial class FrezonCoolantReaction : IGasReactionEffect public sealed partial class FrezonCoolantReaction : IGasReactionEffect
{ {
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem) public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{ {
var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
var temperature = mixture.Temperature; var temperature = mixture.Temperature;
var energyModifier = 1f; var energyModifier = 1f;
@@ -45,11 +45,11 @@ public sealed partial class FrezonCoolantReaction : IGasReactionEffect
energyReleased = burnRate * Atmospherics.FrezonCoolEnergyReleased * energyModifier; energyReleased = burnRate * Atmospherics.FrezonCoolEnergyReleased * energyModifier;
} }
energyReleased /= atmosphereSystem.HeatScale; // adjust energy to make sure speedup doesn't cause mega temperature rise energyReleased /= heatScale; // adjust energy to make sure speedup doesn't cause mega temperature rise
if (energyReleased >= 0f) if (energyReleased >= 0f)
return ReactionResult.NoReaction; return ReactionResult.NoReaction;
var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
if (newHeatCapacity > Atmospherics.MinimumHeatCapacity) if (newHeatCapacity > Atmospherics.MinimumHeatCapacity)
mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity; mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity;

View File

@@ -11,7 +11,7 @@ namespace Content.Server.Atmos.Reactions;
[UsedImplicitly] [UsedImplicitly]
public sealed partial class FrezonProductionReaction : IGasReactionEffect public sealed partial class FrezonProductionReaction : IGasReactionEffect
{ {
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem) public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{ {
var initialN2 = mixture.GetMoles(Gas.Nitrogen); var initialN2 = mixture.GetMoles(Gas.Nitrogen);
var initialOxy = mixture.GetMoles(Gas.Oxygen); var initialOxy = mixture.GetMoles(Gas.Oxygen);
@@ -28,7 +28,6 @@ public sealed partial class FrezonProductionReaction : IGasReactionEffect
// Amount of tritium & oxygen that are reacting // Amount of tritium & oxygen that are reacting
var tritBurned = Math.Min(oxyLimit, initialTrit); var tritBurned = Math.Min(oxyLimit, initialTrit);
var oxyBurned = tritBurned * Atmospherics.FrezonProductionTritRatio; var oxyBurned = tritBurned * Atmospherics.FrezonProductionTritRatio;
var burnRatio = tritBurned / initialTrit;
var oxyConversion = oxyBurned / Atmospherics.FrezonProductionConversionRate; var oxyConversion = oxyBurned / Atmospherics.FrezonProductionConversionRate;
var tritConversion = tritBurned / Atmospherics.FrezonProductionConversionRate; var tritConversion = tritBurned / Atmospherics.FrezonProductionConversionRate;

View File

@@ -60,13 +60,20 @@ namespace Content.Server.Atmos.Reactions
/// </summary> /// </summary>
[DataField("effects")] private List<IGasReactionEffect> _effects = new(); [DataField("effects")] private List<IGasReactionEffect> _effects = new();
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem) /// <summary>
/// Process all reaction effects.
/// </summary>
/// <param name="mixture">The gas mixture to react</param>
/// <param name="holder">The container of this gas mixture</param>
/// <param name="atmosphereSystem">The atmosphere system</param>
/// <param name="heatScale">Scaling factor that should be applied to all heat input or outputs.</param>
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{ {
var result = ReactionResult.NoReaction; var result = ReactionResult.NoReaction;
foreach (var effect in _effects) foreach (var effect in _effects)
{ {
result |= effect.React(mixture, holder, atmosphereSystem); result |= effect.React(mixture, holder, atmosphereSystem, heatScale);
} }
return result; return result;

View File

@@ -10,7 +10,7 @@ namespace Content.Server.Atmos.Reactions;
[UsedImplicitly] [UsedImplicitly]
public sealed partial class MiasmicSubsumationReaction : IGasReactionEffect public sealed partial class MiasmicSubsumationReaction : IGasReactionEffect
{ {
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem) public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{ {
var initialMiasma = mixture.GetMoles(Gas.Miasma); var initialMiasma = mixture.GetMoles(Gas.Miasma);
var initialFrezon = mixture.GetMoles(Gas.Frezon); var initialFrezon = mixture.GetMoles(Gas.Frezon);

View File

@@ -8,10 +8,10 @@ namespace Content.Server.Atmos.Reactions
[DataDefinition] [DataDefinition]
public sealed partial class PlasmaFireReaction : IGasReactionEffect public sealed partial class PlasmaFireReaction : IGasReactionEffect
{ {
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem) public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{ {
var energyReleased = 0f; var energyReleased = 0f;
var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
var temperature = mixture.Temperature; var temperature = mixture.Temperature;
var location = holder as TileAtmosphere; var location = holder as TileAtmosphere;
mixture.ReactionResults[GasReaction.Fire] = 0; mixture.ReactionResults[GasReaction.Fire] = 0;
@@ -22,8 +22,10 @@ namespace Content.Server.Atmos.Reactions
if (temperature > Atmospherics.PlasmaUpperTemperature) if (temperature > Atmospherics.PlasmaUpperTemperature)
temperatureScale = 1f; temperatureScale = 1f;
else else
{
temperatureScale = (temperature - Atmospherics.PlasmaMinimumBurnTemperature) / temperatureScale = (temperature - Atmospherics.PlasmaMinimumBurnTemperature) /
(Atmospherics.PlasmaUpperTemperature - Atmospherics.PlasmaMinimumBurnTemperature); (Atmospherics.PlasmaUpperTemperature - Atmospherics.PlasmaMinimumBurnTemperature);
}
if (temperatureScale > 0) if (temperatureScale > 0)
{ {
@@ -56,14 +58,14 @@ namespace Content.Server.Atmos.Reactions
mixture.AdjustMoles(Gas.CarbonDioxide, plasmaBurnRate * (1.0f - supersaturation)); mixture.AdjustMoles(Gas.CarbonDioxide, plasmaBurnRate * (1.0f - supersaturation));
energyReleased += Atmospherics.FirePlasmaEnergyReleased * plasmaBurnRate; energyReleased += Atmospherics.FirePlasmaEnergyReleased * plasmaBurnRate;
energyReleased /= atmosphereSystem.HeatScale; // adjust energy to make sure speedup doesn't cause mega temperature rise energyReleased /= heatScale; // adjust energy to make sure speedup doesn't cause mega temperature rise
mixture.ReactionResults[GasReaction.Fire] += plasmaBurnRate * (1 + oxygenBurnRate); mixture.ReactionResults[GasReaction.Fire] += plasmaBurnRate * (1 + oxygenBurnRate);
} }
} }
if (energyReleased > 0) if (energyReleased > 0)
{ {
var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
if (newHeatCapacity > Atmospherics.MinimumHeatCapacity) if (newHeatCapacity > Atmospherics.MinimumHeatCapacity)
mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity; mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity;
} }

View File

@@ -8,10 +8,10 @@ namespace Content.Server.Atmos.Reactions
[DataDefinition] [DataDefinition]
public sealed partial class TritiumFireReaction : IGasReactionEffect public sealed partial class TritiumFireReaction : IGasReactionEffect
{ {
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem) public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{ {
var energyReleased = 0f; var energyReleased = 0f;
var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
var temperature = mixture.Temperature; var temperature = mixture.Temperature;
var location = holder as TileAtmosphere; var location = holder as TileAtmosphere;
mixture.ReactionResults[GasReaction.Fire] = 0f; mixture.ReactionResults[GasReaction.Fire] = 0f;
@@ -47,10 +47,10 @@ namespace Content.Server.Atmos.Reactions
mixture.ReactionResults[GasReaction.Fire] += burnedFuel; mixture.ReactionResults[GasReaction.Fire] += burnedFuel;
} }
energyReleased /= atmosphereSystem.HeatScale; // adjust energy to make sure speedup doesn't cause mega temperature rise energyReleased /= heatScale; // adjust energy to make sure speedup doesn't cause mega temperature rise
if (energyReleased > 0) if (energyReleased > 0)
{ {
var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture); var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
if (newHeatCapacity > Atmospherics.MinimumHeatCapacity) if (newHeatCapacity > Atmospherics.MinimumHeatCapacity)
mixture.Temperature = ((temperature * oldHeatCapacity + energyReleased) / newHeatCapacity); mixture.Temperature = ((temperature * oldHeatCapacity + energyReleased) / newHeatCapacity);
} }

View File

@@ -17,7 +17,7 @@ namespace Content.Server.Atmos.Reactions
[DataField("molesPerUnit")] public float MolesPerUnit { get; private set; } = 1; [DataField("molesPerUnit")] public float MolesPerUnit { get; private set; } = 1;
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem) public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{ {
// If any of the prototypes is invalid, we do nothing. // If any of the prototypes is invalid, we do nothing.
if (string.IsNullOrEmpty(Reagent)) if (string.IsNullOrEmpty(Reagent))
@@ -34,9 +34,8 @@ namespace Content.Server.Atmos.Reactions
// Remove the moles from the mixture... // Remove the moles from the mixture...
mixture.AdjustMoles(GasId, -MolesPerUnit); mixture.AdjustMoles(GasId, -MolesPerUnit);
var tileRef = tile.GridIndices.GetTileRef(tile.GridIndex); var tileRef = atmosphereSystem.GetTileRef(tile);
EntitySystem.Get<PuddleSystem>() atmosphereSystem.Puddle.TrySpillAt(tileRef, new Solution(Reagent, FixedPoint2.New(MolesPerUnit)), out _, sound: false);
.TrySpillAt(tileRef, new Solution(Reagent, FixedPoint2.New(MolesPerUnit)), out _, sound: false);
return ReactionResult.Reacting; return ReactionResult.Reacting;
} }

View File

@@ -120,8 +120,8 @@ public sealed class TegSystem : EntitySystem
var (airA, δpA) = GetCirculatorAirTransfer(inletA.Air, outletA.Air); var (airA, δpA) = GetCirculatorAirTransfer(inletA.Air, outletA.Air);
var (airB, δpB) = GetCirculatorAirTransfer(inletB.Air, outletB.Air); var (airB, δpB) = GetCirculatorAirTransfer(inletB.Air, outletB.Air);
var cA = _atmosphere.GetHeatCapacity(airA); var cA = _atmosphere.GetHeatCapacity(airA, true);
var cB = _atmosphere.GetHeatCapacity(airB); var cB = _atmosphere.GetHeatCapacity(airB, true);
// Shift ramp position based on demand and generation from previous tick. // Shift ramp position based on demand and generation from previous tick.
var curRamp = component.RampPosition; var curRamp = component.RampPosition;

View File

@@ -149,13 +149,11 @@ public sealed class TemperatureSystem : EntitySystem
if (transform.MapUid == null) if (transform.MapUid == null)
return; return;
var position = _transform.GetGridTilePositionOrDefault((uid, transform));
var temperatureDelta = args.GasMixture.Temperature - temperature.CurrentTemperature; var temperatureDelta = args.GasMixture.Temperature - temperature.CurrentTemperature;
var tileHeatCapacity = var airHeatCapacity = _atmosphere.GetHeatCapacity(args.GasMixture, false);
_atmosphere.GetTileHeatCapacity(transform.GridUid, transform.MapUid.Value, position);
var heatCapacity = GetHeatCapacity(uid, temperature); var heatCapacity = GetHeatCapacity(uid, temperature);
var heat = temperatureDelta * (tileHeatCapacity * heatCapacity / var heat = temperatureDelta * (airHeatCapacity * heatCapacity /
(tileHeatCapacity + heatCapacity)); (airHeatCapacity + heatCapacity));
ChangeHeat(uid, heat * temperature.AtmosTemperatureTransferEfficiency, temperature: temperature); ChangeHeat(uid, heat * temperature.AtmosTemperatureTransferEfficiency, temperature: temperature);
} }