* Make ReactionResults an array We're making the dictionaries fixed-size anyway. Alternatively could use a frozendictionary but not sure on the perf difference. Worst case whoever adds another reactionresult makes a minor adjustment * apply conventions --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
87 lines
4.2 KiB
C#
87 lines
4.2 KiB
C#
using Content.Server.Atmos.EntitySystems;
|
|
using Content.Shared.Atmos;
|
|
using Content.Shared.Atmos.Reactions;
|
|
using JetBrains.Annotations;
|
|
|
|
namespace Content.Server.Atmos.Reactions
|
|
{
|
|
[UsedImplicitly]
|
|
[DataDefinition]
|
|
public sealed partial class PlasmaFireReaction : IGasReactionEffect
|
|
{
|
|
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
|
|
{
|
|
var energyReleased = 0f;
|
|
var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
|
|
var temperature = mixture.Temperature;
|
|
var location = holder as TileAtmosphere;
|
|
mixture.ReactionResults[(byte)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 oxyRatio = initialOxygenMoles / initialPlasmaMoles;
|
|
// Efficiency of reaction decreases from 1% Plasma to 3% plasma:
|
|
var supersaturation = Math.Clamp((oxyRatio - Atmospherics.SuperSaturationEnds) /
|
|
(Atmospherics.SuperSaturationThreshold -
|
|
Atmospherics.SuperSaturationEnds), 0.0f, 1.0f);
|
|
|
|
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);
|
|
|
|
// supersaturation adjusts the ratio of produced tritium to unwanted CO2
|
|
mixture.AdjustMoles(Gas.Tritium, plasmaBurnRate * supersaturation);
|
|
mixture.AdjustMoles(Gas.CarbonDioxide, plasmaBurnRate * (1.0f - supersaturation));
|
|
|
|
energyReleased += Atmospherics.FirePlasmaEnergyReleased * plasmaBurnRate;
|
|
energyReleased /= heatScale; // adjust energy to make sure speedup doesn't cause mega temperature rise
|
|
mixture.ReactionResults[(byte)GasReaction.Fire] += plasmaBurnRate * (1 + oxygenBurnRate);
|
|
}
|
|
}
|
|
|
|
if (energyReleased > 0)
|
|
{
|
|
var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
|
|
if (newHeatCapacity > Atmospherics.MinimumHeatCapacity)
|
|
mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity;
|
|
}
|
|
|
|
if (location != null)
|
|
{
|
|
var mixTemperature = mixture.Temperature;
|
|
if (mixTemperature > Atmospherics.FireMinimumTemperatureToExist)
|
|
{
|
|
atmosphereSystem.HotspotExpose(location, mixTemperature, mixture.Volume);
|
|
}
|
|
}
|
|
|
|
return mixture.ReactionResults[(byte)GasReaction.Fire] != 0 ? ReactionResult.Reacting : ReactionResult.NoReaction;
|
|
}
|
|
}
|
|
}
|