Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hopefully fix atmos issues #656

Merged
merged 4 commits into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Content.Server.Atmos.EntitySystems
public sealed partial class AtmosphereSystem
{
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly GenericGasReactionSystem _reaction = default!;

private GasReactionPrototype[] _gasReactions = Array.Empty<GasReactionPrototype>();
private float[] _gasSpecificHeats = new float[Atmospherics.TotalNumberOfGases];
Expand Down Expand Up @@ -123,7 +122,7 @@ public void Merge(GasMixture receiver, GasMixture giver)
var receiverHeatCapacity = GetHeatCapacity(receiver);
var giverHeatCapacity = GetHeatCapacity(giver);
var combinedHeatCapacity = receiverHeatCapacity + giverHeatCapacity;
if (combinedHeatCapacity > 0f)
if (combinedHeatCapacity > Atmospherics.MinimumHeatCapacity)
{
receiver.Temperature = (GetThermalEnergy(giver, giverHeatCapacity) + GetThermalEnergy(receiver, receiverHeatCapacity)) / combinedHeatCapacity;
}
Expand Down Expand Up @@ -167,7 +166,7 @@ public void DivideInto(GasMixture source, List<GasMixture> receivers)
sourceHeatCapacity ??= GetHeatCapacity(source);
var receiverHeatCapacity = GetHeatCapacity(receiver);
var combinedHeatCapacity = receiverHeatCapacity + sourceHeatCapacity.Value * fraction;
if (combinedHeatCapacity > 0f)
if (combinedHeatCapacity > Atmospherics.MinimumHeatCapacity)
receiver.Temperature = (GetThermalEnergy(source, sourceHeatCapacity.Value * fraction) + GetThermalEnergy(receiver, receiverHeatCapacity)) / combinedHeatCapacity;
}
}
Expand Down Expand Up @@ -347,7 +346,7 @@ public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder)
break;
}

return _reaction.ReactAll(GasReactions, mixture, holder);
return reaction;
}

public enum GasCompareResult
Expand Down
130 changes: 0 additions & 130 deletions Content.Server/Atmos/EntitySystems/GenericGasReactionSystem.cs

This file was deleted.

13 changes: 6 additions & 7 deletions Content.Server/Atmos/GasMixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Content.Server.Atmos.Reactions;
using Content.Shared.Atmos;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;

namespace Content.Server.Atmos
{
Expand Down Expand Up @@ -58,8 +59,9 @@ public float Temperature
get => _temperature;
set
{
DebugTools.Assert(!float.IsNaN(_temperature));
if (Immutable) return;
_temperature = MathF.Max(value, Atmospherics.TCMB);
_temperature = MathF.Min(MathF.Max(value, Atmospherics.TCMB), Atmospherics.Tmax);
}
}

Expand Down Expand Up @@ -120,12 +122,9 @@ public void AdjustMoles(int gasId, float quantity)
if (!float.IsFinite(quantity))
throw new ArgumentException($"Invalid quantity \"{quantity}\" specified!", nameof(quantity));

Moles[gasId] += quantity;

var moles = Moles[gasId];

if (!float.IsFinite(moles) || float.IsNegative(moles))
throw new Exception($"Invalid mole quantity \"{moles}\" in gas Id {gasId} after adjusting moles with \"{quantity}\"!");
// Clamping is needed because x - x can be negative with floating point numbers. If we don't
// clamp here, the caller always has to call GetMoles(), clamp, then SetMoles().
Moles[gasId] = MathF.Max(Moles[gasId] + quantity, 0);
}
}

Expand Down
33 changes: 33 additions & 0 deletions Content.Server/Atmos/Reactions/AmmoniaOxygenReaction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using JetBrains.Annotations;

namespace Content.Server.Atmos.Reactions;

[UsedImplicitly]
public sealed partial class AmmoniaOxygenReaction : IGasReactionEffect
{
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{
var nAmmonia = mixture.GetMoles(Gas.Ammonia);
var nOxygen = mixture.GetMoles(Gas.Oxygen);
var nTotal = mixture.TotalMoles;

// Concentration-dependent reaction rate
var fAmmonia = nAmmonia/nTotal;
var fOxygen = nOxygen/nTotal;
var rate = MathF.Pow(fAmmonia, 2) * MathF.Pow(fOxygen, 2);

var deltaMoles = nAmmonia / Atmospherics.AmmoniaOxygenReactionRate * 2 * rate;

if (deltaMoles <= 0 || nAmmonia - deltaMoles < 0)
return ReactionResult.NoReaction;

mixture.AdjustMoles(Gas.Ammonia, -deltaMoles);
mixture.AdjustMoles(Gas.Oxygen, -deltaMoles);
mixture.AdjustMoles(Gas.NitrousOxide, deltaMoles / 2);
mixture.AdjustMoles(Gas.WaterVapor, deltaMoles * 1.5f);

return ReactionResult.Reacting;
}
}
58 changes: 58 additions & 0 deletions Content.Server/Atmos/Reactions/FrezonCoolantReaction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using JetBrains.Annotations;

namespace Content.Server.Atmos.Reactions;

/// <summary>
/// Takes in nitrogen and frezon and cools down the surrounding area.
/// </summary>
[UsedImplicitly]
public sealed partial class FrezonCoolantReaction : IGasReactionEffect
{
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{
var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
var temperature = mixture.Temperature;

var energyModifier = 1f;
var scale = (temperature - Atmospherics.FrezonCoolLowerTemperature) /
(Atmospherics.FrezonCoolMidTemperature - Atmospherics.FrezonCoolLowerTemperature);

if (scale > 1f)
{
// Scale energy but not frezon usage if we're in a very, very hot place
energyModifier = Math.Min(scale, Atmospherics.FrezonCoolMaximumEnergyModifier);
scale = 1f;
}

if (scale <= 0)
return ReactionResult.NoReaction;

var initialNit = mixture.GetMoles(Gas.Nitrogen);
var initialFrezon = mixture.GetMoles(Gas.Frezon);

var burnRate = initialFrezon * scale / Atmospherics.FrezonCoolRateModifier;

var energyReleased = 0f;
if (burnRate > Atmospherics.MinimumHeatCapacity)
{
var nitAmt = Math.Min(burnRate * Atmospherics.FrezonNitrogenCoolRatio, initialNit);
var frezonAmt = Math.Min(burnRate, initialFrezon);
mixture.AdjustMoles(Gas.Nitrogen, -nitAmt);
mixture.AdjustMoles(Gas.Frezon, -frezonAmt);
mixture.AdjustMoles(Gas.NitrousOxide, nitAmt + frezonAmt);
energyReleased = burnRate * Atmospherics.FrezonCoolEnergyReleased * energyModifier;
}

energyReleased /= heatScale; // adjust energy to make sure speedup doesn't cause mega temperature rise
if (energyReleased >= 0f)
return ReactionResult.NoReaction;

var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
if (newHeatCapacity > Atmospherics.MinimumHeatCapacity)
mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity;

return ReactionResult.Reacting;
}
}
35 changes: 1 addition & 34 deletions Content.Server/Atmos/Reactions/GasReactionPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ public sealed partial class GasReactionPrototype : IPrototype
public string ID { get; private set; } = default!;

/// <summary>
/// Minimum gas amount requirements. Reactions that meet these minimum mole requirements
/// have their reaction effects run. Generic gas reactions do not have minimum requirements.
/// Minimum gas amount requirements.
/// </summary>
[DataField("minimumRequirements")]
public float[] MinimumRequirements { get; private set; } = new float[Atmospherics.TotalNumberOfGases];
Expand All @@ -43,13 +42,6 @@ public sealed partial class GasReactionPrototype : IPrototype
[DataField("minimumTemperature")]
public float MinimumTemperatureRequirement { get; private set; } = Atmospherics.TCMB;

/// <summary>
/// If this is a generic gas reaction, multiply the initial rate by this. The default is reasonable for
/// synthesis reactions. Consider raising this for fires.
/// </summary>
[DataField("rateMultiplier")]
public float RateMultiplier = 1f;

/// <summary>
/// Minimum energy requirement.
/// </summary>
Expand All @@ -68,31 +60,6 @@ public sealed partial class GasReactionPrototype : IPrototype
/// </summary>
[DataField("effects")] private List<IGasReactionEffect> _effects = new();

/// <summary>
/// Energy released by the reaction.
/// </summary>
[DataField("enthalpy")]
public float Enthalpy;

/// <summary>
/// Integer gas IDs and integer ratios required in the reaction. If this is defined, the
/// generic gas reaction will run.
/// </summary>
[DataField("reactants")]
public Dictionary<Gas, int> Reactants = new();

/// <summary>
/// Integer gas IDs and integer ratios of reaction products.
/// </summary>
[DataField("products")]
public Dictionary<Gas, int> Products = new();

/// <summary>
/// Integer gas IDs and how much they modify the activation energy (J/mol).
/// </summary>
[DataField("catalysts")]
public Dictionary<Gas, int> Catalysts = new();

/// <summary>
/// Process all reaction effects.
/// </summary>
Expand Down
28 changes: 28 additions & 0 deletions Content.Server/Atmos/Reactions/N2ODecompositionReaction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Content.Server.Atmos.EntitySystems;
using Content.Shared.Atmos;
using JetBrains.Annotations;

namespace Content.Server.Atmos.Reactions;

/// <summary>
/// Decomposes Nitrous Oxide into Nitrogen and Oxygen.
/// </summary>
[UsedImplicitly]
public sealed partial class N2ODecompositionReaction : IGasReactionEffect
{
public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
{
var cacheN2O = mixture.GetMoles(Gas.NitrousOxide);

var burnedFuel = cacheN2O / Atmospherics.N2ODecompositionRate;

if (burnedFuel <= 0 || cacheN2O - burnedFuel < 0)
return ReactionResult.NoReaction;

mixture.AdjustMoles(Gas.NitrousOxide, -burnedFuel);
mixture.AdjustMoles(Gas.Nitrogen, burnedFuel);
mixture.AdjustMoles(Gas.Oxygen, burnedFuel / 2);

return ReactionResult.Reacting;
}
}
Loading
Loading