diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 27878e321a5..ba7db4c6547 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -1,5 +1,5 @@
//wrapper
-/proc/do_teleport(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null, bypass_area_flag=FALSE)
+/proc/do_teleport(ateleatom, adestination, aprecision = 0, afteleport = 1, aeffectin = null, aeffectout = null, asoundin = null, asoundout = null, bypass_area_flag = FALSE, safe_turf_pick = FALSE)
var/datum/teleport/instant/science/D = new
if(D.start(arglist(args)))
return 1
@@ -15,18 +15,19 @@
var/soundout //soundfile to play after teleportation
var/force_teleport = 1 //if false, teleport will use Move() proc (dense objects will prevent teleportation)
var/ignore_area_flag = FALSE
+ var/safe_turf_first = FALSE //If the teleport isn't precise and this is TRUE, only non-space, non-dense turfs will be selected, unless there's no other option for teleportation.
-
-/datum/teleport/proc/start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null, bypass_area_flag=FALSE)
+/datum/teleport/proc/start(ateleatom, adestination, aprecision = 0, afteleport = 1, aeffectin = null, aeffectout = null, asoundin = null, asoundout = null, bypass_area_flag = FALSE, safe_turf_pick = FALSE)
if(!initTeleport(arglist(args)))
return 0
return 1
-/datum/teleport/proc/initTeleport(ateleatom, adestination, aprecision, afteleport, aeffectin, aeffectout, asoundin, asoundout, bypass_area_flag=FALSE)
+/datum/teleport/proc/initTeleport(ateleatom, adestination, aprecision, afteleport, aeffectin, aeffectout, asoundin, asoundout, bypass_area_flag = FALSE, safe_turf_pick = FALSE)
if(!setTeleatom(ateleatom))
return 0
if(!setDestination(adestination))
return 0
+ safe_turf_first = safe_turf_pick //before precision for bag of holding interference
if(!setPrecision(aprecision))
return 0
setEffects(aeffectin,aeffectout)
@@ -104,8 +105,16 @@
var/center = get_turf(destination)
if(!center)
center = destination
- for(var/turf/T in range(precision,center))
- posturfs.Add(T)
+ if(safe_turf_first)
+ for(var/turf/T in range(precision, center))
+ if(istype(T, /turf/space))
+ continue
+ if(T.density)
+ continue
+ posturfs.Add(T)
+ if(!length(posturfs)) //This is either an unsafe teleport or we didnt find a single safe turf for a safe teleport
+ for(var/turf/T in range(precision, center))
+ posturfs.Add(T)
destturf = safepick(posturfs)
else
destturf = get_turf(destination)
@@ -177,7 +186,11 @@
var/list/bagholding = teleatom.search_contents_for(/obj/item/storage/backpack/holding)
if(bagholding.len)
- precision = max(rand(1, 100)*bagholding.len, 100)
+ if(safe_turf_first) //If this is true, this is already a random teleport. Make it unsafe but do not touch the precision.
+ safe_turf_first = FALSE
+ else
+ precision = max(rand(1, 100) * length(bagholding), 100)
+
if(istype(teleatom, /mob/living))
var/mob/living/MM = teleatom
to_chat(MM, "The bluespace interface on your bag of holding interferes with the teleport!")
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index a0cbc9f5f58..f6df77bae6a 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -335,27 +335,12 @@
/obj/item/clothing/suit/armor/reactive/teleport/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(!active)
return 0
- if(reaction_check(hitby))
+ if(reaction_check(hitby) && is_teleport_allowed(owner.z))
var/mob/living/carbon/human/H = owner
- owner.visible_message("The reactive teleport system flings [H] clear of [attack_text]!")
- var/list/turfs = new/list()
- for(var/turf/T in orange(tele_range, H))
- if(istype(T, /turf/space))
- continue
- if(T.density)
- continue
- if(T.x>world.maxx-tele_range || T.xworld.maxy-tele_range || T.yThe reactive teleport system flings [H] clear of [attack_text]!")
+ return TRUE
+ return FALSE
return FALSE
/obj/item/clothing/suit/armor/reactive/fire