diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm
index 025b7a0ff6..5ca74b8eee 100644
--- a/code/_onclick/observer.dm
+++ b/code/_onclick/observer.dm
@@ -66,10 +66,6 @@
// And here are some good things for free:
// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu
-/obj/effect/portal/attack_ghost(mob/user)
- if(linked)
- user.forceMove(get_turf(linked))
-
/obj/machinery/gateway/centerstation/attack_ghost(mob/user)
if(awaygate)
user.forceMove(awaygate.loc)
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index 2332c0d8b7..f932ec9830 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -24,6 +24,7 @@
var/atmos_link = FALSE //Link source/destination atmos.
var/turf/open/atmos_source //Atmos link source
var/turf/open/atmos_destination //Atmos link destination
+ var/allow_anchored = FALSE
/obj/effect/portal/anom
name = "wormhole"
@@ -42,6 +43,8 @@
user.forceMove(get_turf(src))
/obj/effect/portal/Crossed(atom/movable/AM, oldloc)
+ if(isobserver(AM))
+ return ..()
if(linked && (get_turf(oldloc) == get_turf(linked)))
return ..()
if(!teleport(AM))
@@ -51,6 +54,8 @@
return
/obj/effect/portal/attack_hand(mob/user)
+ if(get_turf(user) == get_turf(src))
+ teleport(user)
if(Adjacent(user))
user.forceMove(get_turf(src))
@@ -123,12 +128,18 @@
linked = null
return ..()
+/obj/effect/portal/attack_ghost(mob/dead/observer/O)
+ if(!teleport(O))
+ return ..()
+
/obj/effect/portal/proc/teleport(atom/movable/M)
- if(!istype(M) || istype(M, /obj/effect) || isobserver(M) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
+ if(!istype(M) || istype(M, /obj/effect) || (ismecha(M) && !mech_sized) || (!isobj(M) && !ismob(M))) //Things that shouldn't teleport.
return
var/turf/real_target = get_link_target_turf()
if(!istype(real_target))
return FALSE
+ if(!ismecha(M) && M.anchored && !allow_anchored)
+ return
if(ismegafauna(M))
message_admins("[M] has used a portal at [ADMIN_COORDJMP(src)] made by [usr].")
if(do_teleport(M, real_target, 0))
diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm
index 9266074e1a..2b1216b6da 100644
--- a/code/game/objects/items/teleportation.dm
+++ b/code/game/objects/items/teleportation.dm
@@ -205,6 +205,11 @@ Frequency:
if(A.noteleport)
to_chat(user, "\The [src] is malfunctioning.")
return
+ current_location = get_turf(user) //Recheck.
+ current_area = current_location.loc
+ if(!current_location || current_area.noteleport || current_location.z > ZLEVEL_SPACEMAX || !isturf(user.loc))//If turf was not found or they're on z level 2 or >7 which does not currently exist. or if user is not located on a turf
+ to_chat(user, "\The [src] is malfunctioning.")
+ return
user.show_message("Locked In.", 2)
var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(T)), src, 300, 1)
if(!(LAZYLEN(created) == 2))