BorgSystem.Transponder.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using Content.Shared.DeviceNetwork;
  2. using Content.Shared.Emag.Components;
  3. using Content.Shared.Movement.Components;
  4. using Content.Shared.Popups;
  5. using Content.Shared.Robotics;
  6. using Content.Shared.Silicons.Borgs.Components;
  7. using Content.Server.DeviceNetwork;
  8. using Content.Server.DeviceNetwork.Components;
  9. using Content.Server.DeviceNetwork.Systems;
  10. using Content.Server.Explosion.Components;
  11. using Content.Shared.Emag.Systems;
  12. using Robust.Shared.Utility;
  13. namespace Content.Server.Silicons.Borgs;
  14. /// <inheritdoc/>
  15. public sealed partial class BorgSystem
  16. {
  17. [Dependency] private readonly EmagSystem _emag = default!;
  18. private void InitializeTransponder()
  19. {
  20. SubscribeLocalEvent<BorgTransponderComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
  21. }
  22. public override void Update(float frameTime)
  23. {
  24. base.Update(frameTime);
  25. var now = _timing.CurTime;
  26. var query = EntityQueryEnumerator<BorgTransponderComponent, BorgChassisComponent, DeviceNetworkComponent, MetaDataComponent>();
  27. while (query.MoveNext(out var uid, out var comp, out var chassis, out var device, out var meta))
  28. {
  29. if (comp.NextDisable is {} nextDisable && now >= nextDisable)
  30. DoDisable((uid, comp, chassis, meta));
  31. if (now < comp.NextBroadcast)
  32. continue;
  33. var charge = 0f;
  34. if (_powerCell.TryGetBatteryFromSlot(uid, out var battery))
  35. charge = battery.CurrentCharge / battery.MaxCharge;
  36. var hasBrain = chassis.BrainEntity != null && !comp.FakeDisabled;
  37. var canDisable = comp.NextDisable == null && !comp.FakeDisabling;
  38. var data = new CyborgControlData(
  39. comp.Sprite,
  40. comp.Name,
  41. meta.EntityName,
  42. charge,
  43. chassis.ModuleCount,
  44. hasBrain,
  45. canDisable);
  46. var payload = new NetworkPayload()
  47. {
  48. [DeviceNetworkConstants.Command] = DeviceNetworkConstants.CmdUpdatedState,
  49. [RoboticsConsoleConstants.NET_CYBORG_DATA] = data
  50. };
  51. _deviceNetwork.QueuePacket(uid, null, payload, device: device);
  52. comp.NextBroadcast = now + comp.BroadcastDelay;
  53. }
  54. }
  55. private void DoDisable(Entity<BorgTransponderComponent, BorgChassisComponent, MetaDataComponent> ent)
  56. {
  57. ent.Comp1.NextDisable = null;
  58. if (ent.Comp1.FakeDisabling)
  59. {
  60. ent.Comp1.FakeDisabled = true;
  61. ent.Comp1.FakeDisabling = false;
  62. return;
  63. }
  64. if (ent.Comp2.BrainEntity is not {} brain)
  65. return;
  66. var message = Loc.GetString(ent.Comp1.DisabledPopup, ("name", Name(ent, ent.Comp3)));
  67. Popup.PopupEntity(message, ent);
  68. _container.Remove(brain, ent.Comp2.BrainContainer);
  69. }
  70. private void OnPacketReceived(Entity<BorgTransponderComponent> ent, ref DeviceNetworkPacketEvent args)
  71. {
  72. var payload = args.Data;
  73. if (!payload.TryGetValue(DeviceNetworkConstants.Command, out string? command))
  74. return;
  75. if (command == RoboticsConsoleConstants.NET_DISABLE_COMMAND)
  76. Disable(ent);
  77. else if (command == RoboticsConsoleConstants.NET_DESTROY_COMMAND)
  78. Destroy(ent);
  79. }
  80. private void Disable(Entity<BorgTransponderComponent, BorgChassisComponent?> ent)
  81. {
  82. if (!Resolve(ent, ref ent.Comp2) || ent.Comp2.BrainEntity == null || ent.Comp1.NextDisable != null)
  83. return;
  84. // update ui immediately
  85. ent.Comp1.NextBroadcast = _timing.CurTime;
  86. // pretend the borg is being disabled forever now
  87. if (CheckEmagged(ent, "disabled"))
  88. ent.Comp1.FakeDisabling = true;
  89. else
  90. Popup.PopupEntity(Loc.GetString(ent.Comp1.DisablingPopup), ent);
  91. ent.Comp1.NextDisable = _timing.CurTime + ent.Comp1.DisableDelay;
  92. }
  93. private void Destroy(Entity<BorgTransponderComponent> ent)
  94. {
  95. // this is stealthy until someone realises you havent exploded
  96. if (CheckEmagged(ent, "destroyed"))
  97. {
  98. // prevent reappearing on the console a few seconds later
  99. RemComp<BorgTransponderComponent>(ent);
  100. return;
  101. }
  102. var message = Loc.GetString(ent.Comp.DestroyingPopup, ("name", Name(ent)));
  103. Popup.PopupEntity(message, ent);
  104. _trigger.StartTimer(ent.Owner, user: null);
  105. // prevent a shitter borg running into people
  106. RemComp<InputMoverComponent>(ent);
  107. }
  108. private bool CheckEmagged(EntityUid uid, string name)
  109. {
  110. if (_emag.CheckFlag(uid, EmagType.Interaction))
  111. {
  112. Popup.PopupEntity(Loc.GetString($"borg-transponder-emagged-{name}-popup"), uid, uid, PopupType.LargeCaution);
  113. return true;
  114. }
  115. return false;
  116. }
  117. /// <summary>
  118. /// Sets <see cref="BorgTransponderComponent.Sprite"/>.
  119. /// </summary>
  120. public void SetTransponderSprite(Entity<BorgTransponderComponent> ent, SpriteSpecifier sprite)
  121. {
  122. ent.Comp.Sprite = sprite;
  123. }
  124. /// <summary>
  125. /// Sets <see cref="BorgTransponderComponent.Name"/>.
  126. /// </summary>
  127. public void SetTransponderName(Entity<BorgTransponderComponent> ent, string name)
  128. {
  129. ent.Comp.Name = name;
  130. }
  131. }