1
0

PowerSensorSystem.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using Content.Server.DeviceLinking.Components;
  2. using Content.Server.NodeContainer;
  3. using Content.Server.Power.EntitySystems;
  4. using Content.Server.Power.Nodes;
  5. using Content.Server.Power.NodeGroups;
  6. using Content.Shared.Examine;
  7. using Content.Shared.Interaction;
  8. using Content.Shared.Popups;
  9. using Content.Shared.Power.Generator;
  10. using Content.Shared.Timing;
  11. using Content.Shared.Tools.Systems;
  12. using Robust.Shared.Audio.Systems;
  13. using Robust.Shared.Map.Components;
  14. using Robust.Shared.Timing;
  15. namespace Content.Server.DeviceLinking.Systems;
  16. public sealed class PowerSensorSystem : EntitySystem
  17. {
  18. [Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
  19. [Dependency] private readonly IGameTiming _timing = default!;
  20. [Dependency] private readonly PowerNetSystem _powerNet = default!;
  21. [Dependency] private readonly SharedAudioSystem _audio = default!;
  22. [Dependency] private readonly SharedPopupSystem _popup = default!;
  23. [Dependency] private readonly SharedToolSystem _tool = default!;
  24. [Dependency] private readonly UseDelaySystem _useDelay = default!;
  25. private EntityQuery<NodeContainerComponent> _nodeQuery;
  26. private EntityQuery<TransformComponent> _xformQuery;
  27. public override void Initialize()
  28. {
  29. base.Initialize();
  30. _nodeQuery = GetEntityQuery<NodeContainerComponent>();
  31. _xformQuery = GetEntityQuery<TransformComponent>();
  32. SubscribeLocalEvent<PowerSensorComponent, ComponentInit>(OnInit);
  33. SubscribeLocalEvent<PowerSensorComponent, ExaminedEvent>(OnExamined);
  34. SubscribeLocalEvent<PowerSensorComponent, InteractUsingEvent>(OnInteractUsing);
  35. }
  36. public override void Update(float deltaTime)
  37. {
  38. var query = EntityQueryEnumerator<PowerSensorComponent>();
  39. while (query.MoveNext(out var uid, out var comp))
  40. {
  41. var now = _timing.CurTime;
  42. if (comp.NextCheck > now)
  43. continue;
  44. comp.NextCheck = now + comp.CheckDelay;
  45. UpdateOutputs(uid, comp);
  46. }
  47. }
  48. private void OnInit(EntityUid uid, PowerSensorComponent comp, ComponentInit args)
  49. {
  50. _deviceLink.EnsureSourcePorts(uid, comp.ChargingPort, comp.DischargingPort);
  51. }
  52. private void OnExamined(EntityUid uid, PowerSensorComponent comp, ExaminedEvent args)
  53. {
  54. if (!args.IsInDetailsRange)
  55. return;
  56. args.PushMarkup(Loc.GetString("power-sensor-examine", ("output", comp.Output)));
  57. }
  58. private void OnInteractUsing(EntityUid uid, PowerSensorComponent comp, InteractUsingEvent args)
  59. {
  60. if (args.Handled || !_tool.HasQuality(args.Used, comp.SwitchQuality))
  61. return;
  62. // no sound spamming
  63. if (TryComp<UseDelayComponent>(uid, out var useDelay)
  64. && !_useDelay.TryResetDelay((uid, useDelay), true))
  65. return;
  66. // switch between input and output mode.
  67. comp.Output = !comp.Output;
  68. // since the battery to be checked changed the output probably has too, update it
  69. UpdateOutputs(uid, comp);
  70. // notify the user
  71. _audio.PlayPvs(comp.SwitchSound, uid);
  72. var msg = Loc.GetString("power-sensor-switch", ("output", comp.Output));
  73. _popup.PopupEntity(msg, uid, args.User);
  74. }
  75. private void UpdateOutputs(EntityUid uid, PowerSensorComponent comp)
  76. {
  77. // get power stats on the power network that's been switched to
  78. var powerSwitchable = Comp<PowerSwitchableComponent>(uid);
  79. var cable = powerSwitchable.Cables[powerSwitchable.ActiveIndex];
  80. var nodeContainer = Comp<NodeContainerComponent>(uid);
  81. var deviceNode = (CableDeviceNode) nodeContainer.Nodes[cable.Node];
  82. var charge = 0f;
  83. var chargingState = false;
  84. var dischargingState = false;
  85. // update state based on the power stats retrieved from the selected power network
  86. var xform = _xformQuery.GetComponent(uid);
  87. if (!TryComp(xform.GridUid, out MapGridComponent? grid))
  88. return;
  89. var cables = deviceNode.GetReachableNodes(xform, _nodeQuery, _xformQuery, grid, EntityManager);
  90. foreach (var node in cables)
  91. {
  92. if (node.NodeGroup == null)
  93. continue;
  94. var group = (IBasePowerNet) node.NodeGroup;
  95. var stats = _powerNet.GetNetworkStatistics(group.NetworkNode);
  96. charge = comp.Output ? stats.OutStorageCurrent : stats.InStorageCurrent;
  97. chargingState = charge > comp.LastCharge;
  98. dischargingState = charge < comp.LastCharge;
  99. break;
  100. }
  101. comp.LastCharge = charge;
  102. // send new signals if changed
  103. if (comp.ChargingState != chargingState)
  104. {
  105. comp.ChargingState = chargingState;
  106. _deviceLink.SendSignal(uid, comp.ChargingPort, chargingState);
  107. }
  108. if (comp.DischargingState != dischargingState)
  109. {
  110. comp.DischargingState = dischargingState;
  111. _deviceLink.SendSignal(uid, comp.DischargingPort, dischargingState);
  112. }
  113. }
  114. }