GasRecyclerSystem.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using Content.Server.Atmos.EntitySystems;
  2. using Content.Server.Atmos.Piping.Binary.Components;
  3. using Content.Server.Atmos.Piping.Components;
  4. using Content.Server.NodeContainer;
  5. using Content.Server.NodeContainer.EntitySystems;
  6. using Content.Server.NodeContainer.Nodes;
  7. using Content.Shared.Atmos;
  8. using Content.Shared.Atmos.Piping;
  9. using Content.Shared.Atmos.Piping.Components;
  10. using Content.Shared.Audio;
  11. using Content.Shared.Examine;
  12. using JetBrains.Annotations;
  13. using Robust.Server.GameObjects;
  14. namespace Content.Server.Atmos.Piping.Binary.EntitySystems
  15. {
  16. [UsedImplicitly]
  17. public sealed class GasReyclerSystem : EntitySystem
  18. {
  19. [Dependency] private readonly AppearanceSystem _appearance = default!;
  20. [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
  21. [Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
  22. [Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
  23. public override void Initialize()
  24. {
  25. base.Initialize();
  26. SubscribeLocalEvent<GasRecyclerComponent, AtmosDeviceEnabledEvent>(OnEnabled);
  27. SubscribeLocalEvent<GasRecyclerComponent, AtmosDeviceUpdateEvent>(OnUpdate);
  28. SubscribeLocalEvent<GasRecyclerComponent, AtmosDeviceDisabledEvent>(OnDisabled);
  29. SubscribeLocalEvent<GasRecyclerComponent, ExaminedEvent>(OnExamined);
  30. }
  31. private void OnEnabled(EntityUid uid, GasRecyclerComponent comp, ref AtmosDeviceEnabledEvent args)
  32. {
  33. UpdateAppearance(uid, comp);
  34. }
  35. private void OnExamined(Entity<GasRecyclerComponent> ent, ref ExaminedEvent args)
  36. {
  37. var comp = ent.Comp;
  38. if (!EntityManager.GetComponent<TransformComponent>(ent).Anchored || !args.IsInDetailsRange) // Not anchored? Out of range? No status.
  39. return;
  40. if (!_nodeContainer.TryGetNode(ent.Owner, comp.InletName, out PipeNode? inlet))
  41. return;
  42. using (args.PushGroup(nameof(GasRecyclerComponent)))
  43. {
  44. if (comp.Reacting)
  45. {
  46. args.PushMarkup(Loc.GetString("gas-recycler-reacting"));
  47. }
  48. else
  49. {
  50. if (inlet.Air.Pressure < comp.MinPressure)
  51. {
  52. args.PushMarkup(Loc.GetString("gas-recycler-low-pressure"));
  53. }
  54. if (inlet.Air.Temperature < comp.MinTemp)
  55. {
  56. args.PushMarkup(Loc.GetString("gas-recycler-low-temperature"));
  57. }
  58. }
  59. }
  60. }
  61. private void OnUpdate(Entity<GasRecyclerComponent> ent, ref AtmosDeviceUpdateEvent args)
  62. {
  63. var comp = ent.Comp;
  64. if (!_nodeContainer.TryGetNodes(ent.Owner, comp.InletName, comp.OutletName, out PipeNode? inlet, out PipeNode? outlet))
  65. {
  66. _ambientSoundSystem.SetAmbience(ent, false);
  67. return;
  68. }
  69. // The gas recycler is a passive device, so it permits gas flow even if nothing is being reacted.
  70. comp.Reacting = inlet.Air.Temperature >= comp.MinTemp && inlet.Air.Pressure >= comp.MinPressure;
  71. var removed = inlet.Air.RemoveVolume(PassiveTransferVol(inlet.Air, outlet.Air));
  72. if (comp.Reacting)
  73. {
  74. var nCO2 = removed.GetMoles(Gas.CarbonDioxide);
  75. removed.AdjustMoles(Gas.CarbonDioxide, -nCO2);
  76. removed.AdjustMoles(Gas.Oxygen, nCO2);
  77. var nN2O = removed.GetMoles(Gas.NitrousOxide);
  78. removed.AdjustMoles(Gas.NitrousOxide, -nN2O);
  79. removed.AdjustMoles(Gas.Nitrogen, nN2O);
  80. }
  81. _atmosphereSystem.Merge(outlet.Air, removed);
  82. UpdateAppearance(ent, comp);
  83. _ambientSoundSystem.SetAmbience(ent, true);
  84. }
  85. public float PassiveTransferVol(GasMixture inlet, GasMixture outlet)
  86. {
  87. if (inlet.Pressure < outlet.Pressure)
  88. {
  89. return 0;
  90. }
  91. float overPressConst = 300; // pressure difference (in atm) to get 200 L/sec transfer rate
  92. float alpha = Atmospherics.MaxTransferRate * _atmosphereSystem.PumpSpeedup() / (float)Math.Sqrt(overPressConst*Atmospherics.OneAtmosphere);
  93. return alpha * (float)Math.Sqrt(inlet.Pressure - outlet.Pressure);
  94. }
  95. private void OnDisabled(EntityUid uid, GasRecyclerComponent comp, ref AtmosDeviceDisabledEvent args)
  96. {
  97. comp.Reacting = false;
  98. UpdateAppearance(uid, comp);
  99. }
  100. private void UpdateAppearance(EntityUid uid, GasRecyclerComponent? comp = null)
  101. {
  102. if (!Resolve(uid, ref comp, false))
  103. return;
  104. _appearance.SetData(uid, PumpVisuals.Enabled, comp.Reacting);
  105. }
  106. }
  107. }