diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index e5d43fd02b..26a0a0f414 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -1,171 +1,73 @@
-//wrapper
-/proc/do_teleport(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
- var/datum/teleport/instant/science/D = new
- if(D.start(arglist(args)))
- return TRUE
- return FALSE
+// teleatom: atom to teleport
+// destination: destination to teleport to
+// precision: teleport precision (0 is most precise, the default)
+// effectin: effect to show right before teleportation
+// effectout: effect to show right after teleportation
+// asoundin: soundfile to play before teleportation
+// asoundout: soundfile to play after teleportation
+// force_teleport: if false, teleport will use Move() proc (dense objects will prevent teleportation)
+// no_effects: disable the default effectin/effectout of sparks
+/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, force_teleport=TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE)
+ // teleporting most effects just deletes them
+ if(iseffect(teleatom) && !istype(teleatom, /obj/effect/dummy/chameleon))
+ qdel(teleatom)
+ return FALSE
-/datum/teleport
- var/atom/movable/teleatom //atom to teleport
- var/atom/destination //destination to teleport to
- var/precision = 0 //teleport precision
- var/datum/effect_system/effectin //effect to show right before teleportation
- var/datum/effect_system/effectout //effect to show right after teleportation
- 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)
+ // argument handling
+ // if the precision is not specified, default to 0, but apply BoH penalties
+ if (isnull(precision))
+ precision = 0
+ if(istype(teleatom, /obj/item/storage/backpack/holding))
+ precision = rand(1,100)
-/datum/teleport/proc/start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
- if(!initTeleport(arglist(args)))
- return 0
- return 1
+ var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding)
+ var/list/bagholding = typecache_filter_list(teleatom.GetAllContents(), bag_cache)
+ if(bagholding.len)
+ precision = max(rand(1,100)*bagholding.len,100)
+ if(isliving(teleatom))
+ var/mob/living/MM = teleatom
+ to_chat(MM, "The bluespace interface on your bag of holding interferes with the teleport!")
-/datum/teleport/proc/initTeleport(ateleatom,adestination,aprecision,afteleport,aeffectin,aeffectout,asoundin,asoundout)
- if(!setTeleatom(ateleatom))
- return 0
- if(!setDestination(adestination))
- return 0
- if(!setPrecision(aprecision))
- return 0
- setEffects(aeffectin,aeffectout)
- setForceTeleport(afteleport)
- setSounds(asoundin,asoundout)
- return 1
+ // if effects are not specified and not explicitly disabled, sparks
+ if ((!effectin || !effectout) && !no_effects)
+ var/datum/effect_system/spark_spread/sparks = new
+ sparks.set_up(5, 1, teleatom)
+ if (!effectin)
+ effectin = sparks
+ if (!effectout)
+ effectout = sparks
-//must succeed
-/datum/teleport/proc/setPrecision(aprecision)
- if(isnum(aprecision))
- precision = aprecision
- return 1
- return 0
-
-//must succeed
-/datum/teleport/proc/setDestination(atom/adestination)
- if(istype(adestination))
- destination = adestination
- return 1
- return 0
-
-//must succeed in most cases
-/datum/teleport/proc/setTeleatom(atom/movable/ateleatom)
- if(iseffect(ateleatom) && !istype(ateleatom, /obj/effect/dummy/chameleon))
- qdel(ateleatom)
- return 0
- if(istype(ateleatom))
- teleatom = ateleatom
- return 1
- return 0
-
-//custom effects must be properly set up first for instant-type teleports
-//optional
-/datum/teleport/proc/setEffects(datum/effect_system/aeffectin=null,datum/effect_system/aeffectout=null)
- effectin = istype(aeffectin) ? aeffectin : null
- effectout = istype(aeffectout) ? aeffectout : null
- return 1
-
-//optional
-/datum/teleport/proc/setForceTeleport(afteleport)
- force_teleport = afteleport
- return 1
-
-//optional
-/datum/teleport/proc/setSounds(asoundin=null,asoundout=null)
- soundin = isfile(asoundin) ? asoundin : null
- soundout = isfile(asoundout) ? asoundout : null
- return 1
-
-//placeholder
-/datum/teleport/proc/teleportChecks()
- return 1
-
-/datum/teleport/proc/playSpecials(atom/location,datum/effect_system/effect,sound)
- if(location && !isobserver(teleatom))
- if(effect)
- INVOKE_ASYNC(src, .proc/do_effect, location, effect)
- if(sound)
- INVOKE_ASYNC(src, .proc/do_sound, location, sound)
-
-/datum/teleport/proc/do_effect(atom/location, datum/effect_system/effect)
- src = null
- effect.attach(location)
- effect.start()
-
-/datum/teleport/proc/do_sound(atom/location, sound)
- src = null
- playsound(location, sound, 60, 1)
-
-//do the monkey dance
-/datum/teleport/proc/doTeleport()
-
- var/turf/destturf
+ // perform the teleport
var/turf/curturf = get_turf(teleatom)
- destturf = get_teleport_turf(get_turf(destination), precision)
+ var/turf/destturf = get_teleport_turf(get_turf(destination), precision)
if(!destturf || !curturf || destturf.is_transition_turf())
- return 0
+ return FALSE
var/area/A = get_area(curturf)
if(A.noteleport)
- return 0
+ return FALSE
- playSpecials(curturf,effectin,soundin)
- if(force_teleport)
- teleatom.forceMove(destturf)
+ tele_play_specials(teleatom, curturf, effectin, asoundin)
+ var/success = force_teleport ? teleatom.forceMove(destturf) : teleatom.Move(destturf)
+ if (success)
+ tele_play_specials(teleatom, destturf, effectout, asoundout)
if(ismegafauna(teleatom))
message_admins("[teleatom] [ADMIN_FLW(teleatom)] has teleported from [ADMIN_VERBOSEJMP(curturf)] to [ADMIN_VERBOSEJMP(destturf)].")
- playSpecials(destturf,effectout,soundout)
- else
- if(teleatom.Move(destturf))
- playSpecials(destturf,effectout,soundout)
- if(ismegafauna(teleatom))
- message_admins("[teleatom] [ADMIN_FLW(teleatom)] has teleported from [ADMIN_VERBOSEJMP(curturf)] to [ADMIN_VERBOSEJMP(destturf)].")
+
if(ismob(teleatom))
var/mob/M = teleatom
M.cancel_camera()
- return 1
-/datum/teleport/proc/teleport()
- if(teleportChecks())
- return doTeleport()
- return 0
-
-/datum/teleport/instant //teleports when datum is created
-
- start(ateleatom, adestination, aprecision=0, afteleport=1, aeffectin=null, aeffectout=null, asoundin=null, asoundout=null)
- if(..())
- if(teleport())
- return 1
- return 0
-
-
-/datum/teleport/instant/science
-
-/datum/teleport/instant/science/setEffects(datum/effect_system/aeffectin,datum/effect_system/aeffectout)
- if(aeffectin==null || aeffectout==null)
- var/datum/effect_system/spark_spread/aeffect = new
- aeffect.set_up(5, 1, teleatom)
- effectin = effectin || aeffect
- effectout = effectout || aeffect
- return 1
- else
- return ..()
-
-/datum/teleport/instant/science/setPrecision(aprecision)
- ..()
- if(istype(teleatom, /obj/item/storage/backpack/holding))
- precision = rand(1,100)
-
- var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding)
- var/list/bagholding = typecache_filter_list(teleatom.GetAllContents(), bag_cache)
- if(bagholding.len)
- precision = max(rand(1,100)*bagholding.len,100)
- if(isliving(teleatom))
- var/mob/living/MM = teleatom
- to_chat(MM, "The bluespace interface on your bag of holding interferes with the teleport!")
- return TRUE
+/proc/tele_play_specials(atom/movable/teleatom, atom/location, datum/effect_system/effect, sound)
+ if (location && !isobserver(teleatom))
+ if (sound)
+ playsound(location, sound, 60, 1)
+ if (effect)
+ effect.attach(location)
+ effect.start()
// Safe location finder
-
/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE)
if(!zlevels)
if (zlevel)
diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm
index 54bf0cf36e..0c1b67a63c 100644
--- a/code/game/machinery/launch_pad.dm
+++ b/code/game/machinery/launch_pad.dm
@@ -88,10 +88,12 @@
dest = target
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1)
+ var/first = TRUE
for(var/atom/movable/ROI in source)
if(ROI == src)
continue
// if it's anchored, don't teleport
+ var/on_chair = ""
if(ROI.anchored)
if(isliving(ROI))
var/mob/living/L = ROI
@@ -100,35 +102,36 @@
if(L.buckled.anchored)
continue
- log_msg += "[key_name(L)] (on a chair), "
+ on_chair = " (on a chair)"
else
continue
else if(!isobserver(ROI))
continue
+ if(!first)
+ log_msg += ", "
if(ismob(ROI))
var/mob/T = ROI
- log_msg += "[key_name(T)], "
+ log_msg += "[key_name(T)][on_chair]"
else
log_msg += "[ROI.name]"
if (istype(ROI, /obj/structure/closet))
- var/obj/structure/closet/C = ROI
log_msg += " ("
- for(var/atom/movable/Q as mob|obj in C)
+ var/first_inner = TRUE
+ for(var/atom/movable/Q as mob|obj in ROI)
+ if(!first_inner)
+ log_msg += ", "
+ first_inner = FALSE
if(ismob(Q))
- log_msg += "[key_name(Q)], "
+ log_msg += "[key_name(Q)]"
else
- log_msg += "[Q.name], "
- if (dd_hassuffix(log_msg, "("))
- log_msg += "empty)"
- else
- log_msg = dd_limittext(log_msg, length(log_msg) - 2)
- log_msg += ")"
- log_msg += ", "
- do_teleport(ROI, dest)
+ log_msg += "[Q.name]"
+ if(first_inner)
+ log_msg += "empty"
+ log_msg += ")"
+ do_teleport(ROI, dest, no_effects = !first)
+ first = FALSE
- if (dd_hassuffix(log_msg, ", "))
- log_msg = dd_limittext(log_msg, length(log_msg) - 2)
- else
+ if (first)
log_msg += "nothing"
log_msg += " [sending ? "to" : "from"] [target_x], [target_y], [z] ([A ? A.name : "null area"])"
investigate_log(log_msg.Join(), INVESTIGATE_TELESCI)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 81d55830d2..81818554ef 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -960,9 +960,12 @@
to_chat(M, "You feel unstable...")
M.Jitter(2)
current_cycle = 1
- addtimer(CALLBACK(GLOBAL_PROC, .proc/do_teleport, M, get_turf(M), 5, null, null, null, 'sound/effects/phasein.ogg'), 30)
+ addtimer(CALLBACK(M, /mob/living/proc/bluespace_shuffle), 30)
..()
+/mob/living/proc/bluespace_shuffle()
+ do_teleport(src, get_turf(src), 5, asoundin = 'sound/effects/phasein.ogg')
+
/datum/reagent/aluminium
name = "Aluminium"
id = "aluminium"