Use archived gas mixture in gas exchange comparison (#32088)

The comparison for doing gas exchange used current and not archived
moles. This could lead to update order-dependent gas spreading effects.

To fix this, convert TileAtmosphere's MolesArchived and
TemperatureArchived to a AirArchived, and use that in the comparison
method.

---------

Co-authored-by: PraxisMapper <praxismapper@gmail.com>
Co-authored-by: Kevin Zheng <kevinz5000@gmail.com>
This commit is contained in:
drakewill-CRL
2024-09-30 01:14:07 -04:00
committed by GitHub
parent dd15a6862c
commit 7cf04dcb20
7 changed files with 47 additions and 27 deletions

View File

@@ -54,7 +54,7 @@ namespace Content.Server.Atmos.EntitySystems
}
shouldShareAir = true;
} else if (CompareExchange(tile.Air, enemyTile.Air) != GasCompareResult.NoExchange)
} else if (CompareExchange(tile, enemyTile) != GasCompareResult.NoExchange)
{
AddActiveTile(gridAtmosphere, enemyTile);
if (ExcitedGroups)
@@ -117,9 +117,8 @@ namespace Content.Server.Atmos.EntitySystems
private void Archive(TileAtmosphere tile, int fireCount)
{
if (tile.Air != null)
tile.Air.Moles.AsSpan().CopyTo(tile.MolesArchived.AsSpan());
tile.AirArchived = new GasMixture(tile.Air);
tile.TemperatureArchived = tile.Temperature;
tile.ArchivedCycle = fireCount;
}
@@ -184,10 +183,10 @@ namespace Content.Server.Atmos.EntitySystems
/// </summary>
public float GetHeatCapacityArchived(TileAtmosphere tile)
{
if (tile.Air == null)
if (tile.AirArchived == null)
return tile.HeatCapacity;
return GetHeatCapacityCalculation(tile.MolesArchived!, tile.Space);
return GetHeatCapacity(tile.AirArchived);
}
/// <summary>
@@ -195,10 +194,11 @@ namespace Content.Server.Atmos.EntitySystems
/// </summary>
public float Share(TileAtmosphere tileReceiver, TileAtmosphere tileSharer, int atmosAdjacentTurfs)
{
if (tileReceiver.Air is not {} receiver || tileSharer.Air is not {} sharer)
if (tileReceiver.Air is not {} receiver || tileSharer.Air is not {} sharer ||
tileReceiver.AirArchived == null || tileSharer.AirArchived == null)
return 0f;
var temperatureDelta = tileReceiver.TemperatureArchived - tileSharer.TemperatureArchived;
var temperatureDelta = tileReceiver.AirArchived.Temperature - tileSharer.AirArchived.Temperature;
var absTemperatureDelta = Math.Abs(temperatureDelta);
var oldHeatCapacity = 0f;
var oldSharerHeatCapacity = 0f;
@@ -249,12 +249,12 @@ namespace Content.Server.Atmos.EntitySystems
// Transfer of thermal energy (via changed heat capacity) between self and sharer.
if (!receiver.Immutable && newHeatCapacity > Atmospherics.MinimumHeatCapacity)
{
receiver.Temperature = ((oldHeatCapacity * receiver.Temperature) - (heatCapacityToSharer * tileReceiver.TemperatureArchived) + (heatCapacitySharerToThis * tileSharer.TemperatureArchived)) / newHeatCapacity;
receiver.Temperature = ((oldHeatCapacity * receiver.Temperature) - (heatCapacityToSharer * tileReceiver.AirArchived.Temperature) + (heatCapacitySharerToThis * tileSharer.AirArchived.Temperature)) / newHeatCapacity;
}
if (!sharer.Immutable && newSharerHeatCapacity > Atmospherics.MinimumHeatCapacity)
{
sharer.Temperature = ((oldSharerHeatCapacity * sharer.Temperature) - (heatCapacitySharerToThis * tileSharer.TemperatureArchived) + (heatCapacityToSharer * tileReceiver.TemperatureArchived)) / newSharerHeatCapacity;
sharer.Temperature = ((oldSharerHeatCapacity * sharer.Temperature) - (heatCapacitySharerToThis * tileSharer.AirArchived.Temperature) + (heatCapacityToSharer * tileReceiver.AirArchived.Temperature)) / newSharerHeatCapacity;
}
// Thermal energy of the system (self and sharer) is unchanged.
@@ -273,7 +273,7 @@ namespace Content.Server.Atmos.EntitySystems
var moles = receiver.TotalMoles;
var theirMoles = sharer.TotalMoles;
return (tileReceiver.TemperatureArchived * (moles + movedMoles)) - (tileSharer.TemperatureArchived * (theirMoles - movedMoles)) * Atmospherics.R / receiver.Volume;
return (tileReceiver.AirArchived.Temperature * (moles + movedMoles)) - (tileSharer.AirArchived.Temperature * (theirMoles - movedMoles)) * Atmospherics.R / receiver.Volume;
}
/// <summary>
@@ -281,10 +281,11 @@ namespace Content.Server.Atmos.EntitySystems
/// </summary>
public float TemperatureShare(TileAtmosphere tileReceiver, TileAtmosphere tileSharer, float conductionCoefficient)
{
if (tileReceiver.Air is not { } receiver || tileSharer.Air is not { } sharer)
if (tileReceiver.Air is not { } receiver || tileSharer.Air is not { } sharer ||
tileReceiver.AirArchived == null || tileSharer.AirArchived == null)
return 0f;
var temperatureDelta = tileReceiver.TemperatureArchived - tileSharer.TemperatureArchived;
var temperatureDelta = tileReceiver.AirArchived.Temperature - tileSharer.AirArchived.Temperature;
if (MathF.Abs(temperatureDelta) > Atmospherics.MinimumTemperatureDeltaToConsider)
{
var heatCapacity = GetHeatCapacityArchived(tileReceiver);
@@ -310,10 +311,10 @@ namespace Content.Server.Atmos.EntitySystems
/// </summary>
public float TemperatureShare(TileAtmosphere tileReceiver, float conductionCoefficient, float sharerTemperature, float sharerHeatCapacity)
{
if (tileReceiver.Air is not {} receiver)
if (tileReceiver.Air is not {} receiver || tileReceiver.AirArchived == null)
return 0;
var temperatureDelta = tileReceiver.TemperatureArchived - sharerTemperature;
var temperatureDelta = tileReceiver.AirArchived.Temperature - sharerTemperature;
if (MathF.Abs(temperatureDelta) > Atmospherics.MinimumTemperatureDeltaToConsider)
{
var heatCapacity = GetHeatCapacityArchived(tileReceiver);