PressureControlledValveSystem.cs 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using Content.Server.Atmos.EntitySystems;
  2. using Content.Server.Atmos.Piping.Components;
  3. using Content.Server.Atmos.Piping.Trinary.Components;
  4. using Content.Server.NodeContainer;
  5. using Content.Server.NodeContainer.EntitySystems;
  6. using Content.Server.NodeContainer.Nodes;
  7. using Content.Shared.Atmos.Piping;
  8. using Content.Shared.Atmos.Piping.Components;
  9. using Content.Shared.Audio;
  10. using JetBrains.Annotations;
  11. namespace Content.Server.Atmos.Piping.Trinary.EntitySystems
  12. {
  13. [UsedImplicitly]
  14. public sealed class PressureControlledValveSystem : EntitySystem
  15. {
  16. [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
  17. [Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!;
  18. [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
  19. [Dependency] private readonly NodeContainerSystem _nodeContainer = default!;
  20. public override void Initialize()
  21. {
  22. base.Initialize();
  23. SubscribeLocalEvent<PressureControlledValveComponent, ComponentInit>(OnInit);
  24. SubscribeLocalEvent<PressureControlledValveComponent, AtmosDeviceUpdateEvent>(OnUpdate);
  25. SubscribeLocalEvent<PressureControlledValveComponent, AtmosDeviceDisabledEvent>(OnFilterLeaveAtmosphere);
  26. }
  27. private void OnInit(EntityUid uid, PressureControlledValveComponent comp, ComponentInit args)
  28. {
  29. UpdateAppearance(uid, comp);
  30. }
  31. private void OnUpdate(EntityUid uid, PressureControlledValveComponent comp, ref AtmosDeviceUpdateEvent args)
  32. {
  33. if (!_nodeContainer.TryGetNodes(uid, comp.InletName, comp.ControlName, comp.OutletName, out PipeNode? inletNode, out PipeNode? controlNode, out PipeNode? outletNode))
  34. {
  35. _ambientSoundSystem.SetAmbience(uid, false);
  36. comp.Enabled = false;
  37. return;
  38. }
  39. // If output is higher than input, flip input/output to enable bidirectional flow.
  40. if (outletNode.Air.Pressure > inletNode.Air.Pressure)
  41. {
  42. PipeNode temp = outletNode;
  43. outletNode = inletNode;
  44. inletNode = temp;
  45. }
  46. float control = (controlNode.Air.Pressure - outletNode.Air.Pressure) - comp.Threshold;
  47. float transferRate;
  48. if (control < 0)
  49. {
  50. comp.Enabled = false;
  51. transferRate = 0;
  52. }
  53. else
  54. {
  55. comp.Enabled = true;
  56. transferRate = Math.Min(control * comp.Gain, comp.MaxTransferRate * _atmosphereSystem.PumpSpeedup());
  57. }
  58. UpdateAppearance(uid, comp);
  59. // We multiply the transfer rate in L/s by the seconds passed since the last process to get the liters.
  60. var transferVolume = transferRate * args.dt;
  61. if (transferVolume <= 0)
  62. {
  63. _ambientSoundSystem.SetAmbience(uid, false);
  64. return;
  65. }
  66. _ambientSoundSystem.SetAmbience(uid, true);
  67. var removed = inletNode.Air.RemoveVolume(transferVolume);
  68. _atmosphereSystem.Merge(outletNode.Air, removed);
  69. }
  70. private void OnFilterLeaveAtmosphere(EntityUid uid, PressureControlledValveComponent comp, ref AtmosDeviceDisabledEvent args)
  71. {
  72. comp.Enabled = false;
  73. UpdateAppearance(uid, comp);
  74. _ambientSoundSystem.SetAmbience(uid, false);
  75. }
  76. private void UpdateAppearance(EntityUid uid, PressureControlledValveComponent? comp = null, AppearanceComponent? appearance = null)
  77. {
  78. if (!Resolve(uid, ref comp, ref appearance, false))
  79. return;
  80. _appearance.SetData(uid, FilterVisuals.Enabled, comp.Enabled, appearance);
  81. }
  82. }
  83. }