ShuttleConsoleSystem.FTL.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. using Content.Server.Shuttles.Components;
  2. using Content.Server.Shuttles.Events;
  3. using Content.Shared.Shuttles.BUIStates;
  4. using Content.Shared.Shuttles.Components;
  5. using Content.Shared.Shuttles.Events;
  6. using Content.Shared.Shuttles.UI.MapObjects;
  7. using Robust.Shared.Map;
  8. using Robust.Shared.Map.Components;
  9. using Robust.Shared.Physics.Components;
  10. namespace Content.Server.Shuttles.Systems;
  11. public sealed partial class ShuttleConsoleSystem
  12. {
  13. private void InitializeFTL()
  14. {
  15. SubscribeLocalEvent<FTLBeaconComponent, ComponentStartup>(OnBeaconStartup);
  16. SubscribeLocalEvent<FTLBeaconComponent, AnchorStateChangedEvent>(OnBeaconAnchorChanged);
  17. SubscribeLocalEvent<FTLExclusionComponent, ComponentStartup>(OnExclusionStartup);
  18. }
  19. private void OnExclusionStartup(Entity<FTLExclusionComponent> ent, ref ComponentStartup args)
  20. {
  21. RefreshShuttleConsoles();
  22. }
  23. private void OnBeaconStartup(Entity<FTLBeaconComponent> ent, ref ComponentStartup args)
  24. {
  25. RefreshShuttleConsoles();
  26. }
  27. private void OnBeaconAnchorChanged(Entity<FTLBeaconComponent> ent, ref AnchorStateChangedEvent args)
  28. {
  29. RefreshShuttleConsoles();
  30. }
  31. private void OnBeaconFTLMessage(Entity<ShuttleConsoleComponent> ent, ref ShuttleConsoleFTLBeaconMessage args)
  32. {
  33. var beaconEnt = GetEntity(args.Beacon);
  34. if (!_xformQuery.TryGetComponent(beaconEnt, out var targetXform))
  35. {
  36. return;
  37. }
  38. var nCoordinates = new NetCoordinates(GetNetEntity(targetXform.ParentUid), targetXform.LocalPosition);
  39. if (targetXform.ParentUid == EntityUid.Invalid)
  40. {
  41. nCoordinates = new NetCoordinates(GetNetEntity(beaconEnt), targetXform.LocalPosition);
  42. }
  43. // Check target exists
  44. if (!_shuttle.CanFTLBeacon(nCoordinates))
  45. {
  46. return;
  47. }
  48. var angle = args.Angle.Reduced();
  49. var targetCoordinates = new EntityCoordinates(targetXform.MapUid!.Value, _transform.GetWorldPosition(targetXform));
  50. ConsoleFTL(ent, targetCoordinates, angle, targetXform.MapID);
  51. }
  52. private void OnPositionFTLMessage(Entity<ShuttleConsoleComponent> entity, ref ShuttleConsoleFTLPositionMessage args)
  53. {
  54. var mapUid = _mapSystem.GetMap(args.Coordinates.MapId);
  55. // If it's beacons only block all position messages.
  56. if (!Exists(mapUid) || _shuttle.IsBeaconMap(mapUid))
  57. {
  58. return;
  59. }
  60. var targetCoordinates = new EntityCoordinates(mapUid, args.Coordinates.Position);
  61. var angle = args.Angle.Reduced();
  62. ConsoleFTL(entity, targetCoordinates, angle, args.Coordinates.MapId);
  63. }
  64. private void GetBeacons(ref List<ShuttleBeaconObject>? beacons)
  65. {
  66. var beaconQuery = AllEntityQuery<FTLBeaconComponent>();
  67. while (beaconQuery.MoveNext(out var destUid, out _))
  68. {
  69. var meta = _metaQuery.GetComponent(destUid);
  70. var name = meta.EntityName;
  71. if (string.IsNullOrEmpty(name))
  72. name = Loc.GetString("shuttle-console-unknown");
  73. // Can't travel to same map (yet)
  74. var destXform = _xformQuery.GetComponent(destUid);
  75. beacons ??= new List<ShuttleBeaconObject>();
  76. beacons.Add(new ShuttleBeaconObject(GetNetEntity(destUid), GetNetCoordinates(destXform.Coordinates), name));
  77. }
  78. }
  79. private void GetExclusions(ref List<ShuttleExclusionObject>? exclusions)
  80. {
  81. var query = AllEntityQuery<FTLExclusionComponent, TransformComponent>();
  82. while (query.MoveNext(out var comp, out var xform))
  83. {
  84. if (!comp.Enabled)
  85. continue;
  86. exclusions ??= new List<ShuttleExclusionObject>();
  87. exclusions.Add(new ShuttleExclusionObject(GetNetCoordinates(xform.Coordinates), comp.Range, Loc.GetString("shuttle-console-exclusion")));
  88. }
  89. }
  90. /// <summary>
  91. /// Handles shuttle console FTLs.
  92. /// </summary>
  93. private void ConsoleFTL(Entity<ShuttleConsoleComponent> ent, EntityCoordinates targetCoordinates, Angle targetAngle, MapId targetMap)
  94. {
  95. var consoleUid = GetDroneConsole(ent.Owner);
  96. if (consoleUid == null)
  97. return;
  98. var shuttleUid = _xformQuery.GetComponent(consoleUid.Value).GridUid;
  99. if (!TryComp(shuttleUid, out ShuttleComponent? shuttleComp))
  100. return;
  101. if (shuttleComp.Enabled == false)
  102. return;
  103. // Check shuttle can even FTL
  104. if (!_shuttle.CanFTL(shuttleUid.Value, out var reason))
  105. {
  106. // TODO: Session popup
  107. return;
  108. }
  109. // Check shuttle can FTL to this target.
  110. if (!_shuttle.CanFTLTo(shuttleUid.Value, targetMap, ent))
  111. {
  112. return;
  113. }
  114. List<ShuttleExclusionObject>? exclusions = null;
  115. GetExclusions(ref exclusions);
  116. if (!_shuttle.FTLFree(shuttleUid.Value, targetCoordinates, targetAngle, exclusions))
  117. {
  118. return;
  119. }
  120. if (!TryComp(shuttleUid.Value, out PhysicsComponent? shuttlePhysics))
  121. {
  122. return;
  123. }
  124. // Client sends the "adjusted" coordinates and we adjust it back to get the actual transform coordinates.
  125. var adjustedCoordinates = targetCoordinates.Offset(targetAngle.RotateVec(-shuttlePhysics.LocalCenter));
  126. var tagEv = new FTLTagEvent();
  127. RaiseLocalEvent(shuttleUid.Value, ref tagEv);
  128. var ev = new ShuttleConsoleFTLTravelStartEvent(ent.Owner);
  129. RaiseLocalEvent(ref ev);
  130. _shuttle.FTLToCoordinates(shuttleUid.Value, shuttleComp, adjustedCoordinates, targetAngle);
  131. }
  132. }