LocalTeleportSystem.cs 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using System.Linq;
  2. using Content.Shared._Stalker.Teleport;
  3. using Content.Shared.Access.Systems;
  4. using Content.Shared.Movement.Pulling.Systems;
  5. using Content.Shared.Teleportation.Components;
  6. using Content.Shared.Teleportation.Systems;
  7. using Robust.Shared.Physics.Events;
  8. using Robust.Shared.Random;
  9. using Content.Shared.Movement.Pulling.Components;
  10. namespace Content.Server._Stalker.Teleports.LocalTeleport;
  11. /// <summary>
  12. /// Use to teleport entities between maps/grids/tiles. Just spawn two portals with the same name.
  13. /// </summary>
  14. public sealed class LocalTeleportSystem : SharedTeleportSystem
  15. {
  16. [Dependency] private readonly PullingSystem _pulling = default!;
  17. [Dependency] private readonly IRobustRandom _random = default!;
  18. [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
  19. [Dependency] private readonly LinkedEntitySystem _linkedEntitySystem = default!;
  20. [Dependency] private readonly IEntityManager _entMan = default!;
  21. [Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
  22. public override void Initialize()
  23. {
  24. SubscribeLocalEvent<LocalTeleportComponent, StartCollideEvent>(OnStartCollide);
  25. SubscribeLocalEvent<LocalTeleportComponent, EndCollideEvent>(OnEndCollide);
  26. }
  27. private void OnStartCollide(EntityUid uid, LocalTeleportComponent component, ref StartCollideEvent args)
  28. {
  29. var subject = args.OtherEntity;
  30. // Check for access
  31. if (!component.AllowAll)
  32. {
  33. if (!_accessReaderSystem.IsAllowed(args.OtherEntity, args.OurEntity))
  34. return;
  35. }
  36. // Asked to remove, testing now - Reenabled for civ14 because dragging items through is buggy
  37. if (TryComp<PullableComponent>(subject, out var pullable) && pullable.BeingPulled)
  38. _pulling.TryStopPull(subject, pullable);
  39. if (TryComp<PullerComponent>(subject, out var pulling)
  40. && pulling.Pulling != null && TryComp<PullableComponent>(pulling.Pulling.Value, out var subjectPulling))
  41. _pulling.TryStopPull(subject, subjectPulling);
  42. // Remove Timeout from other portal
  43. if (HasComp<PortalTimeoutComponent>(subject))
  44. return;
  45. // If there are no linked entity - link one
  46. if (!TryComp<LinkedEntityComponent>(uid, out var link))
  47. {
  48. var ents = _entMan.GetEntities();
  49. foreach (var ent in ents)
  50. {
  51. if (!TryComp<LocalTeleportComponent>(ent, out var local))
  52. continue;
  53. if (local.PortalName != component.PortalName || uid == ent)
  54. continue;
  55. _linkedEntitySystem.TryLink(uid, ent, true);
  56. }
  57. }
  58. if (link == null)
  59. return;
  60. if (!link.LinkedEntities.Any())
  61. return;
  62. var target = _random.Pick(link.LinkedEntities);
  63. // Setup Timeout for an entity to not teleport it after teleport...
  64. var timeout = EnsureComp<PortalTimeoutComponent>(subject);
  65. timeout.EnteredPortal = uid;
  66. Dirty(subject, timeout);
  67. var xform = Transform(target);
  68. TeleportEntity(subject, xform.Coordinates);
  69. }
  70. private void OnEndCollide(EntityUid uid, LocalTeleportComponent component, ref EndCollideEvent args)
  71. {
  72. var subject = args.OtherEntity;
  73. // Remove Timeout set by other portal.
  74. if (TryComp<PortalTimeoutComponent>(subject, out var timeout) && timeout.EnteredPortal != uid)
  75. {
  76. RemCompDeferred<PortalTimeoutComponent>(subject);
  77. }
  78. }
  79. }