Refactors the AtmosphereSystem public-facing API to allow for multiple atmos backends. (#8134)
* Refactors the entirety of the AtmosphereSystem public-facing API to allow for multiple atmos backends. * actually compiles * Remove commented out code * funny bracket * Move archived moles, temperature from GasMixture to TileAtmosphere. * WIP customizable map default mixture still VERY buggy * broken mess aaaaaaaaaaaaa * Fix lattice, etc not being considered space * visualization for "IsSpace" * help * Update Content.Client/Atmos/Overlays/AtmosDebugOverlay.cs Co-authored-by: Moony <moonheart08@users.noreply.github.com> * Holy SHIT it compiles AGAIN * Fix AtmosDeviceSystem crash at shutdown * Fix immutable tiles on map blueprints not being fixed by fixgridatmos/revalidate. * Use space instead of gasmixture immutable for heat capacity calculations * Remove all LINDA-specific code from GasMixture, move it to TileAtmosphere/AtmosphereSystem instead. * Fix roundstart tiles not processing * Update Content.Server/Atmos/Commands/SetTemperatureCommand.cs Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Update Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs Changed Files tab is so large I can't commit both suggestions at once mfw Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: Moony <moonheart08@users.noreply.github.com> Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
43216a000f
commit
aa9281d667
@@ -48,19 +48,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
return GetHeatCapacityCalculation(mixture.Moles, mixture.Immutable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the heat capacity for a gas mixture, using the archived values.
|
||||
/// </summary>
|
||||
public float GetHeatCapacityArchived(GasMixture mixture)
|
||||
{
|
||||
return GetHeatCapacityCalculation(mixture.MolesArchived, mixture.Immutable);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private float GetHeatCapacityCalculation(float[] moles, bool immutable)
|
||||
private float GetHeatCapacityCalculation(float[] moles, bool space)
|
||||
{
|
||||
// Little hack to make space gas mixtures have heat capacity, therefore allowing them to cool down rooms.
|
||||
if (immutable && MathHelper.CloseTo(NumericsHelpers.HorizontalAdd(moles), 0f))
|
||||
if (space && MathHelper.CloseTo(NumericsHelpers.HorizontalAdd(moles), 0f))
|
||||
{
|
||||
return Atmospherics.SpaceHeatCapacity;
|
||||
}
|
||||
@@ -136,7 +128,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
if (MathF.Abs(receiver.Temperature - source.Temperature) > Atmospherics.MinimumTemperatureDeltaToConsider)
|
||||
{
|
||||
// Often this divides a pipe net into new and completely empty pipe nets
|
||||
if (receiver.TotalMoles == 0)
|
||||
if (receiver.TotalMoles == 0)
|
||||
receiver.Temperature = source.Temperature;
|
||||
else
|
||||
{
|
||||
@@ -154,140 +146,6 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shares gas between two gas mixtures. Part of LINDA.
|
||||
/// </summary>
|
||||
public float Share(GasMixture receiver, GasMixture sharer, int atmosAdjacentTurfs)
|
||||
{
|
||||
var temperatureDelta = receiver.TemperatureArchived - sharer.TemperatureArchived;
|
||||
var absTemperatureDelta = Math.Abs(temperatureDelta);
|
||||
var oldHeatCapacity = 0f;
|
||||
var oldSharerHeatCapacity = 0f;
|
||||
|
||||
if (absTemperatureDelta > Atmospherics.MinimumTemperatureDeltaToConsider)
|
||||
{
|
||||
oldHeatCapacity = GetHeatCapacity(receiver);
|
||||
oldSharerHeatCapacity = GetHeatCapacity(sharer);
|
||||
}
|
||||
|
||||
var heatCapacityToSharer = 0f;
|
||||
var heatCapacitySharerToThis = 0f;
|
||||
var movedMoles = 0f;
|
||||
var absMovedMoles = 0f;
|
||||
|
||||
for(var i = 0; i < Atmospherics.TotalNumberOfGases; i++)
|
||||
{
|
||||
var thisValue = receiver.Moles[i];
|
||||
var sharerValue = sharer.Moles[i];
|
||||
var delta = (thisValue - sharerValue) / (atmosAdjacentTurfs + 1);
|
||||
if (!(MathF.Abs(delta) >= Atmospherics.GasMinMoles)) continue;
|
||||
if (absTemperatureDelta > Atmospherics.MinimumTemperatureDeltaToConsider)
|
||||
{
|
||||
var gasHeatCapacity = delta * GasSpecificHeats[i];
|
||||
if (delta > 0)
|
||||
{
|
||||
heatCapacityToSharer += gasHeatCapacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
heatCapacitySharerToThis -= gasHeatCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
if (!receiver.Immutable) receiver.Moles[i] -= delta;
|
||||
if (!sharer.Immutable) sharer.Moles[i] += delta;
|
||||
movedMoles += delta;
|
||||
absMovedMoles += MathF.Abs(delta);
|
||||
}
|
||||
|
||||
receiver.LastShare = absMovedMoles;
|
||||
|
||||
if (absTemperatureDelta > Atmospherics.MinimumTemperatureDeltaToConsider)
|
||||
{
|
||||
var newHeatCapacity = oldHeatCapacity + heatCapacitySharerToThis - heatCapacityToSharer;
|
||||
var newSharerHeatCapacity = oldSharerHeatCapacity + heatCapacityToSharer - heatCapacitySharerToThis;
|
||||
|
||||
// Transfer of thermal energy (via changed heat capacity) between self and sharer.
|
||||
if (!receiver.Immutable && newHeatCapacity > Atmospherics.MinimumHeatCapacity)
|
||||
{
|
||||
receiver.Temperature = ((oldHeatCapacity * receiver.Temperature) - (heatCapacityToSharer * receiver.TemperatureArchived) + (heatCapacitySharerToThis * sharer.TemperatureArchived)) / newHeatCapacity;
|
||||
}
|
||||
|
||||
if (!sharer.Immutable && newSharerHeatCapacity > Atmospherics.MinimumHeatCapacity)
|
||||
{
|
||||
sharer.Temperature = ((oldSharerHeatCapacity * sharer.Temperature) - (heatCapacitySharerToThis * sharer.TemperatureArchived) + (heatCapacityToSharer*receiver.TemperatureArchived)) / newSharerHeatCapacity;
|
||||
}
|
||||
|
||||
// Thermal energy of the system (self and sharer) is unchanged.
|
||||
|
||||
if (MathF.Abs(oldSharerHeatCapacity) > Atmospherics.MinimumHeatCapacity)
|
||||
{
|
||||
if (MathF.Abs(newSharerHeatCapacity / oldSharerHeatCapacity - 1) < 0.1)
|
||||
{
|
||||
TemperatureShare(receiver, sharer, Atmospherics.OpenHeatTransferCoefficient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(temperatureDelta > Atmospherics.MinimumTemperatureToMove) &&
|
||||
!(MathF.Abs(movedMoles) > Atmospherics.MinimumMolesDeltaToMove)) return 0f;
|
||||
var moles = receiver.TotalMoles;
|
||||
var theirMoles = sharer.TotalMoles;
|
||||
|
||||
return (receiver.TemperatureArchived * (moles + movedMoles)) - (sharer.TemperatureArchived * (theirMoles - movedMoles)) * Atmospherics.R / receiver.Volume;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shares temperature between two mixtures, taking a conduction coefficient into account.
|
||||
/// </summary>
|
||||
public float TemperatureShare(GasMixture receiver, GasMixture sharer, float conductionCoefficient)
|
||||
{
|
||||
var temperatureDelta = receiver.TemperatureArchived - sharer.TemperatureArchived;
|
||||
if (MathF.Abs(temperatureDelta) > Atmospherics.MinimumTemperatureDeltaToConsider)
|
||||
{
|
||||
var heatCapacity = GetHeatCapacityArchived(receiver);
|
||||
var sharerHeatCapacity = GetHeatCapacityArchived(sharer);
|
||||
|
||||
if (sharerHeatCapacity > Atmospherics.MinimumHeatCapacity && heatCapacity > Atmospherics.MinimumHeatCapacity)
|
||||
{
|
||||
var heat = conductionCoefficient * temperatureDelta * (heatCapacity * sharerHeatCapacity / (heatCapacity + sharerHeatCapacity));
|
||||
|
||||
if (!receiver.Immutable)
|
||||
receiver.Temperature = MathF.Abs(MathF.Max(receiver.Temperature - heat / heatCapacity, Atmospherics.TCMB));
|
||||
|
||||
if (!sharer.Immutable)
|
||||
sharer.Temperature = MathF.Abs(MathF.Max(sharer.Temperature + heat / sharerHeatCapacity, Atmospherics.TCMB));
|
||||
}
|
||||
}
|
||||
|
||||
return sharer.Temperature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shares temperature between a gas mixture and an abstract sharer, taking a conduction coefficient into account.
|
||||
/// </summary>
|
||||
public float TemperatureShare(GasMixture receiver, float conductionCoefficient, float sharerTemperature, float sharerHeatCapacity)
|
||||
{
|
||||
var temperatureDelta = receiver.TemperatureArchived - sharerTemperature;
|
||||
if (MathF.Abs(temperatureDelta) > Atmospherics.MinimumTemperatureDeltaToConsider)
|
||||
{
|
||||
var heatCapacity = GetHeatCapacityArchived(receiver);
|
||||
|
||||
if (sharerHeatCapacity > Atmospherics.MinimumHeatCapacity && heatCapacity > Atmospherics.MinimumHeatCapacity)
|
||||
{
|
||||
var heat = conductionCoefficient * temperatureDelta * (heatCapacity * sharerHeatCapacity / (heatCapacity + sharerHeatCapacity));
|
||||
|
||||
if (!receiver.Immutable)
|
||||
receiver.Temperature = MathF.Abs(MathF.Max(receiver.Temperature - heat / heatCapacity, Atmospherics.TCMB));
|
||||
|
||||
sharerTemperature = MathF.Abs(MathF.Max(sharerTemperature + heat / sharerHeatCapacity, Atmospherics.TCMB));
|
||||
}
|
||||
}
|
||||
|
||||
return sharerTemperature;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases gas from this mixture to the output mixture.
|
||||
/// If the output mixture is null, then this is being released into space.
|
||||
@@ -362,6 +220,62 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
Merge(destination, buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a gas mixture is probably safe.
|
||||
/// This only checks temperature and pressure, not gas composition.
|
||||
/// </summary>
|
||||
/// <param name="air">Mixture to be checked.</param>
|
||||
/// <returns>Whether the mixture is probably safe.</returns>
|
||||
public bool IsMixtureProbablySafe(GasMixture? air)
|
||||
{
|
||||
// Note that oxygen mix isn't checked, but survival boxes make that not necessary.
|
||||
if (air == null)
|
||||
return false;
|
||||
|
||||
switch (air.Pressure)
|
||||
{
|
||||
case <= Atmospherics.WarningLowPressure:
|
||||
case >= Atmospherics.WarningHighPressure:
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (air.Temperature)
|
||||
{
|
||||
case <= 260:
|
||||
case >= 360:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two gas mixtures to see if they are within acceptable ranges for group processing to be enabled.
|
||||
/// </summary>
|
||||
public GasCompareResult CompareExchange(GasMixture sample, GasMixture otherSample)
|
||||
{
|
||||
var moles = 0f;
|
||||
|
||||
for(var i = 0; i < Atmospherics.TotalNumberOfGases; i++)
|
||||
{
|
||||
var gasMoles = sample.Moles[i];
|
||||
var delta = MathF.Abs(gasMoles - otherSample.Moles[i]);
|
||||
if (delta > Atmospherics.MinimumMolesDeltaToMove && (delta > gasMoles * Atmospherics.MinimumAirRatioToMove))
|
||||
return (GasCompareResult)i; // We can move gases!
|
||||
moles += gasMoles;
|
||||
}
|
||||
|
||||
if (moles > Atmospherics.MinimumMolesDeltaToMove)
|
||||
{
|
||||
var tempDelta = MathF.Abs(sample.Temperature - otherSample.Temperature);
|
||||
if (tempDelta > Atmospherics.MinimumTemperatureDeltaToSuspend)
|
||||
return GasCompareResult.TemperatureExchange; // There can be temperature exchange.
|
||||
}
|
||||
|
||||
// No exchange at all!
|
||||
return GasCompareResult.NoExchange;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs reactions for a given gas mixture on an optional holder.
|
||||
/// </summary>
|
||||
@@ -401,5 +315,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
return reaction;
|
||||
}
|
||||
|
||||
public enum GasCompareResult
|
||||
{
|
||||
NoExchange = -2,
|
||||
TemperatureExchange = -1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user