PlasmaFireReaction.cs 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using Content.Server.Atmos.EntitySystems;
  2. using Content.Shared.Atmos;
  3. using Content.Shared.Atmos.Reactions;
  4. using JetBrains.Annotations;
  5. namespace Content.Server.Atmos.Reactions
  6. {
  7. [UsedImplicitly]
  8. [DataDefinition]
  9. public sealed partial class PlasmaFireReaction : IGasReactionEffect
  10. {
  11. public ReactionResult React(GasMixture mixture, IGasMixtureHolder? holder, AtmosphereSystem atmosphereSystem, float heatScale)
  12. {
  13. var energyReleased = 0f;
  14. var oldHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
  15. var temperature = mixture.Temperature;
  16. var location = holder as TileAtmosphere;
  17. mixture.ReactionResults[(byte)GasReaction.Fire] = 0;
  18. // More plasma released at higher temperatures.
  19. var temperatureScale = 0f;
  20. if (temperature > Atmospherics.PlasmaUpperTemperature)
  21. temperatureScale = 1f;
  22. else
  23. {
  24. temperatureScale = (temperature - Atmospherics.PlasmaMinimumBurnTemperature) /
  25. (Atmospherics.PlasmaUpperTemperature - Atmospherics.PlasmaMinimumBurnTemperature);
  26. }
  27. if (temperatureScale > 0)
  28. {
  29. var oxygenBurnRate = Atmospherics.OxygenBurnRateBase - temperatureScale;
  30. var plasmaBurnRate = 0f;
  31. var initialOxygenMoles = mixture.GetMoles(Gas.Oxygen);
  32. var initialPlasmaMoles = mixture.GetMoles(Gas.Plasma);
  33. // Supersaturation makes tritium.
  34. var oxyRatio = initialOxygenMoles / initialPlasmaMoles;
  35. // Efficiency of reaction decreases from 1% Plasma to 3% plasma:
  36. var supersaturation = Math.Clamp((oxyRatio - Atmospherics.SuperSaturationEnds) /
  37. (Atmospherics.SuperSaturationThreshold -
  38. Atmospherics.SuperSaturationEnds), 0.0f, 1.0f);
  39. if (initialOxygenMoles > initialPlasmaMoles * Atmospherics.PlasmaOxygenFullburn)
  40. plasmaBurnRate = initialPlasmaMoles * temperatureScale / Atmospherics.PlasmaBurnRateDelta;
  41. else
  42. plasmaBurnRate = temperatureScale * (initialOxygenMoles / Atmospherics.PlasmaOxygenFullburn) / Atmospherics.PlasmaBurnRateDelta;
  43. if (plasmaBurnRate > Atmospherics.MinimumHeatCapacity)
  44. {
  45. plasmaBurnRate = MathF.Min(plasmaBurnRate, MathF.Min(initialPlasmaMoles, initialOxygenMoles / oxygenBurnRate));
  46. mixture.SetMoles(Gas.Plasma, initialPlasmaMoles - plasmaBurnRate);
  47. mixture.SetMoles(Gas.Oxygen, initialOxygenMoles - plasmaBurnRate * oxygenBurnRate);
  48. // supersaturation adjusts the ratio of produced tritium to unwanted CO2
  49. mixture.AdjustMoles(Gas.Tritium, plasmaBurnRate * supersaturation);
  50. mixture.AdjustMoles(Gas.CarbonDioxide, plasmaBurnRate * (1.0f - supersaturation));
  51. energyReleased += Atmospherics.FirePlasmaEnergyReleased * plasmaBurnRate;
  52. energyReleased /= heatScale; // adjust energy to make sure speedup doesn't cause mega temperature rise
  53. mixture.ReactionResults[(byte)GasReaction.Fire] += plasmaBurnRate * (1 + oxygenBurnRate);
  54. }
  55. }
  56. if (energyReleased > 0)
  57. {
  58. var newHeatCapacity = atmosphereSystem.GetHeatCapacity(mixture, true);
  59. if (newHeatCapacity > Atmospherics.MinimumHeatCapacity)
  60. mixture.Temperature = (temperature * oldHeatCapacity + energyReleased) / newHeatCapacity;
  61. }
  62. if (location != null)
  63. {
  64. var mixTemperature = mixture.Temperature;
  65. if (mixTemperature > Atmospherics.FireMinimumTemperatureToExist)
  66. {
  67. atmosphereSystem.HotspotExpose(location, mixTemperature, mixture.Volume);
  68. }
  69. }
  70. return mixture.ReactionResults[(byte)GasReaction.Fire] != 0 ? ReactionResult.Reacting : ReactionResult.NoReaction;
  71. }
  72. }
  73. }