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"