diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 0ff66bd9b8a..dc3903226f0 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)
+/proc/do_teleport(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null, bypass_area_flag=FALSE)
var/datum/teleport/instant/science/D = new
if(D.start(arglist(args)))
return 1
@@ -14,14 +14,15 @@
var/soundin //soundfile to play before teleportation
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
-/datum/teleport/proc/start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
+/datum/teleport/proc/start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null, bypass_area_flag=FALSE)
if(!initTeleport(arglist(args)))
return 0
return 1
-/datum/teleport/proc/initTeleport(ateleatom,adestination,aprecision,afteleport,aeffectin,aeffectout,asoundin,asoundout)
+/datum/teleport/proc/initTeleport(ateleatom, adestination, aprecision, afteleport, aeffectin, aeffectout, asoundin, asoundout, bypass_area_flag=FALSE)
if(!setTeleatom(ateleatom))
return 0
if(!setDestination(adestination))
@@ -31,6 +32,7 @@
setEffects(aeffectin,aeffectout)
setForceTeleport(afteleport)
setSounds(asoundin,asoundout)
+ ignore_area_flag = bypass_area_flag
return 1
//must succeed
@@ -98,10 +100,6 @@
var/turf/destturf
var/turf/curturf = get_turf(teleatom)
var/area/curarea = get_area(curturf)
- var/area/destarea = get_area(destination)
-
- if(!is_teleport_allowed(curturf.z) || curarea.tele_proof || !is_teleport_allowed(destturf.z) || destarea.tele_proof)
- return 0
if(precision)
var/list/posturfs = list()
@@ -114,6 +112,17 @@
else
destturf = get_turf(destination)
+ if(!is_teleport_allowed(destturf.z))
+ return 0
+
+ var/area/destarea = get_area(destturf)
+
+ if(!ignore_area_flag)
+ if(curarea.tele_proof)
+ return 0
+ if(destarea.tele_proof)
+ return 0
+
if(!destturf || !curturf)
return 0
diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm
index 661453adfc3..f6f52af5b44 100644
--- a/code/game/machinery/Beacon.dm
+++ b/code/game/machinery/Beacon.dm
@@ -9,6 +9,7 @@
use_power = 1
idle_power_usage = 0
var/syndicate = 0
+ var/bypasses_area_teleport_lock = FALSE
var/obj/item/radio/beacon/Beacon
var/enabled = TRUE
@@ -64,6 +65,7 @@
/obj/machinery/bluespace_beacon/syndicate
syndicate = TRUE
enabled = FALSE
+ bypasses_area_teleport_lock = TRUE
var/obj/machinery/computer/syndicate_depot/teleporter/mycomputer
/obj/machinery/bluespace_beacon/syndicate/New()
diff --git a/code/game/machinery/computer/depot.dm b/code/game/machinery/computer/depot.dm
index 6bd5eadc822..009e5d92930 100644
--- a/code/game/machinery/computer/depot.dm
+++ b/code/game/machinery/computer/depot.dm
@@ -347,7 +347,7 @@
icon_screen = "telesci"
icon_keyboard = "teleport_key"
var/obj/machinery/bluespace_beacon/syndicate/mybeacon
- var/obj/effect/portal/myportal
+ var/obj/effect/portal/redspace/myportal
var/portal_enabled = FALSE
var/portaldir = WEST
@@ -401,7 +401,7 @@
if(!tele_target)
return
var/turf/portal_turf = get_step(src, portaldir)
- var/obj/effect/portal/P = new(portal_turf, tele_target, src, 0)
+ var/obj/effect/portal/redspace/P = new(portal_turf, tele_target, src, 0)
myportal = P
P.failchance = 0
P.icon_state = "portal1"
diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm
index 29c43304b38..fe46d2746c8 100644
--- a/code/game/machinery/quantum_pad.dm
+++ b/code/game/machinery/quantum_pad.dm
@@ -132,6 +132,7 @@
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
flick("qpad-beam", linked_pad)
playsound(get_turf(linked_pad), 'sound/weapons/emitter2.ogg', 25, 1, extrarange = 3, falloff = 5)
+ var/tele_success = TRUE
for(var/atom/movable/ROI in get_turf(src))
// if is anchored, don't let through
if(ROI.anchored)
@@ -145,4 +146,6 @@
continue
else if(!isobserver(ROI))
continue
- do_teleport(ROI, get_turf(linked_pad))
+ tele_success = do_teleport(ROI, get_turf(linked_pad))
+ if(!tele_success)
+ to_chat(user, "Teleport failed due to bluespace interference.")
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index 46671a9f4fa..dfbabb4338d 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -335,7 +335,10 @@
to_chat(T, "[pick(TPError)]")
return
else
- teleport(M)
+ if(!teleport(M))
+ visible_message("[src] emits a loud buzz, as its teleport portal flickers and fails!")
+ playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
+
use_power(5000)
//--FalseIncarnate
return
diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm
index 8692e65dc9d..c43d0272e90 100644
--- a/code/game/objects/effects/portals.dm
+++ b/code/game/objects/effects/portals.dm
@@ -11,6 +11,7 @@
anchored = 1
var/precision = 1 // how close to the portal you will teleport. 0 = on the portal, 1 = adjacent
var/can_multitool_to_remove = 0
+ var/ignore_tele_proof_area_setting = FALSE
/obj/effect/portal/Bumped(mob/M as mob|obj)
teleport(M)
@@ -42,12 +43,28 @@
qdel(src)
return
if(istype(M, /atom/movable))
- if(prob(failchance)) //oh dear a problem, put em in deep space
+ if(prob(failchance))
src.icon_state = "portal1"
- do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0)
+ if(!do_teleport(M, locate(rand(5, world.maxx - 5), rand(5, world.maxy -5), 3), 0, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to deep space.
+ invalid_teleport()
else
- do_teleport(M, target, precision) ///You will appear adjacent to the beacon
+ if(!do_teleport(M, target, precision, bypass_area_flag = ignore_tele_proof_area_setting)) // Try to send them to a turf adjacent to target.
+ invalid_teleport()
/obj/effect/portal/attackby(obj/item/A, mob/user)
if(istype(A, /obj/item/multitool) && can_multitool_to_remove)
- qdel(src)
\ No newline at end of file
+ qdel(src)
+
+/obj/effect/portal/proc/invalid_teleport()
+ visible_message("[src] flickers and fails due to bluespace interference!")
+ var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
+ spark_system.set_up(5, 0, loc)
+ spark_system.start()
+ qdel(src)
+
+
+/obj/effect/portal/redspace
+ name = "redspace portal"
+ desc = "A rare kind of subspace portal, capable of cutting through interference that can jam normal bluespace portals."
+ icon_state = "portal1"
+ ignore_tele_proof_area_setting = TRUE
\ No newline at end of file
diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm
index 5b4a35262d7..84db02cb89c 100644
--- a/code/modules/hydroponics/plant_genes.dm
+++ b/code/modules/hydroponics/plant_genes.dm
@@ -315,12 +315,16 @@
/datum/plant_gene/trait/teleport/on_slip(obj/item/reagent_containers/food/snacks/grown/G, mob/living/carbon/C)
var/teleport_radius = max(round(G.seed.potency / 10), 1)
var/turf/T = get_turf(C)
- to_chat(C, "You slip through spacetime!")
- do_teleport(C, T, teleport_radius)
- if(prob(50))
- do_teleport(G, T, teleport_radius)
+ if(do_teleport(C, T, teleport_radius))
+ to_chat(C, "You slip through spacetime!")
+ if(prob(50))
+ do_teleport(G, T, teleport_radius)
+ else
+ new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect...
+ qdel(G)
else
- new /obj/effect/decal/cleanable/molten_object(T) //Leave a pile of goo behind for dramatic effect...
+ to_chat(C, "[src] sparks, and burns up!")
+ new /obj/effect/decal/cleanable/molten_object(T)
qdel(G)
diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm
index bf9c5a67783..852bcd3edf3 100644
--- a/code/modules/mining/equipment_locker.dm
+++ b/code/modules/mining/equipment_locker.dm
@@ -664,6 +664,9 @@
var/turf/T = get_turf(H)
T.add_vomit_floor(H)
playsound(H, 'sound/effects/splat.ogg', 50, 1)
+ else
+ visible_message("[src] flickers and fails, due to bluespace interference!")
+ qdel(src)
/**********************Resonator**********************/
diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm
index b7cf78e5ed2..f0f1654ac30 100644
--- a/code/modules/telesci/telesci_computer.dm
+++ b/code/modules/telesci/telesci_computer.dm
@@ -311,7 +311,10 @@
return
if(teles_left > 0)
- doteleport(user)
+ if(!doteleport(user))
+ telefail()
+ temp_msg = "ERROR! Target destination unreachable due to interference."
+ return
else
telefail()
temp_msg = "ERROR!
Calibration required."