Files
tbd-station-14/Content.Server/Atmos/Reactions/PlasmaFireReaction.cs
2022-05-13 17:59:03 +10:00

76 lines
3.5 KiB
C#

using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using JetBrains.Annotations;
namespace Content.Server.Atmos.Reactions
{
[UsedImplicitly]
[DataDefinition]
public sealed class PlasmaFireReaction : IGasReactionEffect
{
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem)
{
var energyReleased = 0f;
var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture);
var temperature = mixture.Temperature;
var location = holder as TileAtmosphere;
mixture.ReactionResults[GasReaction.Fire] = 0;
// More plasma released at higher temperatures.
var temperatureScale = 0f;
if (temperature > Atmospherics.PlasmaUpperTemperature)
temperatureScale = 1f;
else
temperatureScale = (temperature - Atmospherics.PlasmaMinimumBurnTemperature) /
(Atmospherics.PlasmaUpperTemperature - Atmospherics.PlasmaMinimumBurnTemperature);
if (temperatureScale > 0)
{
var oxygenBurnRate = Atmospherics.OxygenBurnRateBase - temperatureScale;
var plasmaBurnRate = 0f;
var initialOxygenMoles = mixture.GetMoles(Gas.Oxygen);
var initialPlasmaMoles = mixture.GetMoles(Gas.Plasma);
// Supersaturation makes tritium.
var supersaturation = initialOxygenMoles / initialPlasmaMoles > Atmospherics.SuperSaturationThreshold;
if (initialOxygenMoles > initialPlasmaMoles * Atmospherics.PlasmaOxygenFullburn)
plasmaBurnRate = initialPlasmaMoles * temperatureScale / Atmospherics.PlasmaBurnRateDelta;
else
plasmaBurnRate = temperatureScale * (initialOxygenMoles / Atmospherics.PlasmaOxygenFullburn) / Atmospherics.PlasmaBurnRateDelta;
if (plasmaBurnRate > Atmospherics.MinimumHeatCapacity)
{
plasmaBurnRate = MathF.Min(plasmaBurnRate, MathF.Min(initialPlasmaMoles, initialOxygenMoles / oxygenBurnRate));
mixture.SetMoles(Gas.Plasma, initialPlasmaMoles - plasmaBurnRate);
mixture.SetMoles(Gas.Oxygen, initialOxygenMoles - plasmaBurnRate * oxygenBurnRate);
mixture.AdjustMoles(supersaturation ? Gas.Tritium : Gas.CarbonDioxide, plasmaBurnRate);
energyReleased += Atmospherics.FirePlasmaEnergyReleased * plasmaBurnRate;
mixture.ReactionResults[GasReaction.Fire] += plasmaBurnRate * (1 + oxygenBurnRate);
}
}
if (energyReleased > 0)
{
var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture);
if (newHeatCapacity > Atmospherics.MinimumHeatCapacity)
mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity;
}
if (location != null)
{
var mixTemperature = mixture.Temperature;
if (mixTemperature > Atmospherics.FireMinimumTemperatureToExist)
{
atmosphereSystem.HotspotExpose(location.GridIndex, location.GridIndices, mixTemperature, mixture.Volume);
}
}
return mixture.ReactionResults[GasReaction.Fire] != 0 ? ReactionResult.Reacting : ReactionResult.NoReaction;
}
}
}