AtmosDeviceSystem.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using Content.Server.Atmos.Components;
  2. using Content.Server.Atmos.EntitySystems;
  3. using Content.Server.Atmos.Piping.Components;
  4. using Content.Shared.Atmos.Piping.Components;
  5. using JetBrains.Annotations;
  6. using Robust.Shared.Timing;
  7. using Robust.Shared.Utility;
  8. namespace Content.Server.Atmos.Piping.EntitySystems
  9. {
  10. [UsedImplicitly]
  11. public sealed class AtmosDeviceSystem : EntitySystem
  12. {
  13. [Dependency] private readonly IGameTiming _gameTiming = default!;
  14. [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
  15. private float _timer;
  16. // Set of atmos devices that are off-grid but have JoinSystem set.
  17. private readonly HashSet<Entity<AtmosDeviceComponent>> _joinedDevices = new();
  18. private static AtmosDeviceDisabledEvent _disabledEv = new();
  19. private static AtmosDeviceEnabledEvent _enabledEv = new();
  20. public override void Initialize()
  21. {
  22. base.Initialize();
  23. SubscribeLocalEvent<AtmosDeviceComponent, ComponentInit>(OnDeviceInitialize);
  24. SubscribeLocalEvent<AtmosDeviceComponent, ComponentShutdown>(OnDeviceShutdown);
  25. // Re-anchoring should be handled by the parent change.
  26. SubscribeLocalEvent<AtmosDeviceComponent, EntParentChangedMessage>(OnDeviceParentChanged);
  27. SubscribeLocalEvent<AtmosDeviceComponent, AnchorStateChangedEvent>(OnDeviceAnchorChanged);
  28. }
  29. public void JoinAtmosphere(Entity<AtmosDeviceComponent> ent)
  30. {
  31. if (ent.Comp.JoinedGrid != null)
  32. {
  33. DebugTools.Assert(HasComp<GridAtmosphereComponent>(ent.Comp.JoinedGrid));
  34. DebugTools.Assert(Transform(ent).GridUid == ent.Comp.JoinedGrid);
  35. DebugTools.Assert(ent.Comp.RequireAnchored == Transform(ent).Anchored);
  36. return;
  37. }
  38. var component = ent.Comp;
  39. var transform = Transform(ent);
  40. if (component.RequireAnchored && !transform.Anchored)
  41. return;
  42. // Attempt to add device to a grid atmosphere.
  43. bool onGrid = (transform.GridUid != null) && _atmosphereSystem.AddAtmosDevice(transform.GridUid!.Value, ent);
  44. if (!onGrid && component.JoinSystem)
  45. {
  46. _joinedDevices.Add(ent);
  47. component.JoinedSystem = true;
  48. }
  49. component.LastProcess = _gameTiming.CurTime;
  50. RaiseLocalEvent(ent, ref _enabledEv);
  51. }
  52. public void LeaveAtmosphere(Entity<AtmosDeviceComponent> ent)
  53. {
  54. var component = ent.Comp;
  55. // Try to remove the component from an atmosphere, and if not
  56. if (component.JoinedGrid != null && !_atmosphereSystem.RemoveAtmosDevice(component.JoinedGrid.Value, ent))
  57. {
  58. // The grid might have been removed but not us... This usually shouldn't happen.
  59. component.JoinedGrid = null;
  60. return;
  61. }
  62. if (component.JoinedSystem)
  63. {
  64. _joinedDevices.Remove(ent);
  65. component.JoinedSystem = false;
  66. }
  67. component.LastProcess = TimeSpan.Zero;
  68. RaiseLocalEvent(ent, ref _disabledEv);
  69. }
  70. public void RejoinAtmosphere(Entity<AtmosDeviceComponent> component)
  71. {
  72. LeaveAtmosphere(component);
  73. JoinAtmosphere(component);
  74. }
  75. private void OnDeviceInitialize(Entity<AtmosDeviceComponent> ent, ref ComponentInit args)
  76. {
  77. JoinAtmosphere(ent);
  78. }
  79. private void OnDeviceShutdown(Entity<AtmosDeviceComponent> ent, ref ComponentShutdown args)
  80. {
  81. LeaveAtmosphere(ent);
  82. }
  83. private void OnDeviceAnchorChanged(Entity<AtmosDeviceComponent> ent, ref AnchorStateChangedEvent args)
  84. {
  85. // Do nothing if the component doesn't require being anchored to function.
  86. if (!ent.Comp.RequireAnchored)
  87. return;
  88. if (args.Anchored)
  89. JoinAtmosphere(ent);
  90. else
  91. LeaveAtmosphere(ent);
  92. }
  93. private void OnDeviceParentChanged(Entity<AtmosDeviceComponent> ent, ref EntParentChangedMessage args)
  94. {
  95. RejoinAtmosphere(ent);
  96. }
  97. /// <summary>
  98. /// Update atmos devices that are off-grid but have JoinSystem set. For devices updates when
  99. /// a device is on a grid, see AtmosphereSystem:UpdateProcessing().
  100. /// </summary>
  101. public override void Update(float frameTime)
  102. {
  103. _timer += frameTime;
  104. if (_timer < _atmosphereSystem.AtmosTime)
  105. return;
  106. _timer -= _atmosphereSystem.AtmosTime;
  107. var time = _gameTiming.CurTime;
  108. var ev = new AtmosDeviceUpdateEvent(_atmosphereSystem.AtmosTime, null, null);
  109. foreach (var device in _joinedDevices)
  110. {
  111. var deviceGrid = Transform(device).GridUid;
  112. if (HasComp<GridAtmosphereComponent>(deviceGrid))
  113. {
  114. RejoinAtmosphere(device);
  115. }
  116. RaiseLocalEvent(device, ref ev);
  117. device.Comp.LastProcess = time;
  118. }
  119. }
  120. public bool IsJoinedOffGrid(Entity<AtmosDeviceComponent> device)
  121. {
  122. return _joinedDevices.Contains(device);
  123. }
  124. }
  125. }