diff --git a/Content.Server/Teleportation/HandTeleporterSystem.cs b/Content.Server/Teleportation/HandTeleporterSystem.cs
index 29cde5d741d..c285b43be6c 100644
--- a/Content.Server/Teleportation/HandTeleporterSystem.cs
+++ b/Content.Server/Teleportation/HandTeleporterSystem.cs
@@ -1,7 +1,9 @@
using Content.Server.Administration.Logs;
+using Content.Server.Popups;
using Content.Shared.DoAfter;
using Content.Shared.Database;
using Content.Shared.Interaction.Events;
+using Content.Shared.Popups;
using Content.Shared.Teleportation.Components;
using Content.Shared.Teleportation.Systems;
using Robust.Server.Audio;
@@ -18,6 +20,7 @@ public sealed class HandTeleporterSystem : EntitySystem
[Dependency] private readonly LinkedEntitySystem _link = default!;
[Dependency] private readonly AudioSystem _audio = default!;
[Dependency] private readonly SharedDoAfterSystem _doafter = default!;
+ [Dependency] private readonly PopupSystem _popup = default!;
///
public override void Initialize()
@@ -92,6 +95,16 @@ private void HandlePortalUpdating(EntityUid uid, HandTeleporterComponent compone
}
else if (Deleted(component.SecondPortal))
{
+ if (xform.ParentUid != xform.GridUid) // Still, don't portal.
+ return;
+
+ if (xform.ParentUid != Transform(component.FirstPortal!.Value).ParentUid)
+ {
+ // Whoops. Fizzle time. Crime time too because yippee I'm not refactoring this logic right now (I started to, I'm not going to.)
+ FizzlePortals(uid, component, user, true);
+ return;
+ }
+
var timeout = EnsureComp(user);
timeout.EnteredPortal = null;
component.SecondPortal = Spawn(component.SecondPortalPrototype, Transform(user).Coordinates);
@@ -101,22 +114,32 @@ private void HandlePortalUpdating(EntityUid uid, HandTeleporterComponent compone
}
else
{
- // Logging
- var portalStrings = "";
- portalStrings += ToPrettyString(component.FirstPortal!.Value);
- if (portalStrings != "")
- portalStrings += " and ";
- portalStrings += ToPrettyString(component.SecondPortal!.Value);
- if (portalStrings != "")
- _adminLogger.Add(LogType.EntityDelete, LogImpact.Low, $"{ToPrettyString(user):player} closed {portalStrings} with {ToPrettyString(uid)}");
-
- // Clear both portals
- QueueDel(component.FirstPortal!.Value);
- QueueDel(component.SecondPortal!.Value);
-
- component.FirstPortal = null;
- component.SecondPortal = null;
- _audio.PlayPvs(component.ClearPortalsSound, uid);
+ FizzlePortals(uid, component, user, false);
}
}
+
+ private void FizzlePortals(EntityUid uid, HandTeleporterComponent component, EntityUid user, bool instability)
+ {
+ // Logging
+ var portalStrings = "";
+ portalStrings += ToPrettyString(component.FirstPortal);
+ if (portalStrings != "")
+ portalStrings += " and ";
+ portalStrings += ToPrettyString(component.SecondPortal);
+ if (portalStrings != "")
+ _adminLogger.Add(LogType.EntityDelete, LogImpact.Low, $"{ToPrettyString(user):player} closed {portalStrings} with {ToPrettyString(uid)}");
+
+ // Clear both portals
+ if (!Deleted(component.FirstPortal))
+ QueueDel(component.FirstPortal.Value);
+ if (!Deleted(component.SecondPortal))
+ QueueDel(component.SecondPortal.Value);
+
+ component.FirstPortal = null;
+ component.SecondPortal = null;
+ _audio.PlayPvs(component.ClearPortalsSound, uid);
+
+ if (instability)
+ _popup.PopupEntity(Loc.GetString("handheld-teleporter-instability-fizzle"), uid, user, PopupType.MediumCaution);
+ }
}
diff --git a/Resources/Locale/en-US/teleportation/handheld-teleporter.ftl b/Resources/Locale/en-US/teleportation/handheld-teleporter.ftl
new file mode 100644
index 00000000000..28f526f0d52
--- /dev/null
+++ b/Resources/Locale/en-US/teleportation/handheld-teleporter.ftl
@@ -0,0 +1 @@
+handheld-teleporter-instability-fizzle = The portal fizzles as you try to place it, destroying both ends!