diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom.dm index 02079493f1cbc..f41faf1ef0272 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom.dm @@ -115,7 +115,7 @@ #define COMSIG_ATOM_CREATEDBY_PROCESSING "atom_createdby_processing" ///when an atom is processed (mob/living/user, obj/item/I, list/atom/results) #define COMSIG_ATOM_PROCESSED "atom_processed" -///! called when teleporting into a protected turf: (channel, turf/origin) +///! from the base of atom/intercept_teleport: (channel, turf/origin, turf/destination) #define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" #define COMPONENT_BLOCK_TELEPORT 1 ///called when an atom starts orbiting another atom: (atom) diff --git a/code/__DEFINES/movement.dm b/code/__DEFINES/movement.dm index c34bcb82259a8..b1ba18d0fae79 100644 --- a/code/__DEFINES/movement.dm +++ b/code/__DEFINES/movement.dm @@ -57,14 +57,8 @@ #define TELEPORT_ALLOW_CLOCKWORK 2 /// Everyone but abductors is restricted #define TELEPORT_ALLOW_ABDUCTORS 3 - -//Teleport modes -/// Default teleport mode -#define TELEPORT_MODE_DEFAULT 0 -/// A clockwork teleport -#define TELEPORT_MODE_CLOCKWORK 2 -/// An abductor teleport -#define TELEPORT_MODE_ABDUCTORS 3 +/// Everyone but wizards is restricted +#define TELEPORT_ALLOW_WIZARD 4 // Jetpack Thrust /// Thrust needed with gravity diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 2f88159ad3296..50f22401bf52a 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -1,13 +1,85 @@ -// 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 -// no_effects: disable the default effectin/effectout of sparks -// forced: whether or not to ignore no_teleport -/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE, teleport_mode = TELEPORT_MODE_DEFAULT, commit = TRUE, no_wake = FALSE) +/** + * Returns FALSE if we SHOULDN'T do_teleport() with the given arguments + * + * Arguments: + * * teleatom: The atom to teleport + * * dest_turf: The destination turf for the atom to go + * * channel: Which teleport channel/type should we try to use (for blocking checks), defaults to TELEPORT_CHANNEL_BLUESPACE + * * bypass_area_restriction: Should we ignore SOFT atom and area TRAIT_NO_TELEPORT restriction and other area-related restrictions? Defaults to FALSE + * * teleport_mode: Teleport mode for religion/faction checks + */ +/proc/check_teleport(atom/movable/teleatom, turf/dest_turf, channel = TELEPORT_CHANNEL_BLUESPACE, bypass_area_restriction = FALSE, teleport_mode = TELEPORT_ALLOW_ALL) + var/turf/cur_turf = get_turf(teleatom) + + if(!istype(dest_turf)) + stack_trace("Destination [dest_turf] is not a turf.") + return FALSE + if(!istype(cur_turf) || dest_turf.is_transition_turf()) + return FALSE + + // Checks bluespace anchors + if(channel != TELEPORT_CHANNEL_WORMHOLE && channel != TELEPORT_CHANNEL_FREE) + var/cur_zlevel = cur_turf.get_virtual_z_level() + var/dest_zlevel = dest_turf.get_virtual_z_level() + for (var/obj/machinery/bluespace_anchor/anchor as() in GLOB.active_bluespace_anchors) + var/anchor_zlevel = anchor.get_virtual_z_level() + // Not in range of our current turf or destination turf + if((cur_zlevel != anchor_zlevel && get_dist(cur_turf, anchor) > anchor.range) && (dest_zlevel != anchor_zlevel && get_dist(dest_turf, anchor) > anchor.range)) + continue + + // Try to activate the anchor, this also does the effect + if(!anchor.try_activate()) + continue + + // We're anchored, return false + return FALSE + + // Checks antimagic + if(ismob(teleatom)) + var/mob/tele_mob = teleatom + if(channel == TELEPORT_CHANNEL_CULT && tele_mob.anti_magic_check(magic = FALSE, holy = TRUE, self = TRUE)) + return FALSE + if(channel == TELEPORT_CHANNEL_MAGIC && tele_mob.anti_magic_check(magic = TRUE, holy = FALSE, self = TRUE)) + return FALSE + + // Check for NO_TELEPORT restrictions + if(!bypass_area_restriction) + var/area/cur_area = cur_turf.loc + var/area/dest_area = dest_turf.loc + if(HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT)) + return FALSE + if(cur_area.teleport_restriction && cur_area.teleport_restriction != teleport_mode) + return FALSE + if(dest_area.teleport_restriction && dest_area.teleport_restriction != teleport_mode) + return FALSE + + // Check for intercepting the teleport + if(cur_turf.intercept_teleport(channel, cur_turf, dest_turf) == COMPONENT_BLOCK_TELEPORT) + return FALSE + if(dest_turf.intercept_teleport(channel, cur_turf, dest_turf) == COMPONENT_BLOCK_TELEPORT) + return FALSE + if(teleatom.intercept_teleport(channel, cur_turf, dest_turf) == COMPONENT_BLOCK_TELEPORT) + return FALSE + + return TRUE + +/** + * Returns TRUE if the teleport has been successful + * + * Arguments: + * * 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 + * * asoundin: soundfile to play before teleportation + * * asoundout: soundfile to play after teleportation + * * no_effects: disable the default effectin/effectout of sparks + * * channel: Which teleport channel/type should we try to use (for blocking checks) + * * ignore_check_teleport: Set this to true ONLY if you have already run check_teleport + * * bypass_area_restriction: Should we ignore SOFT atom and area TRAIT_NO_TELEPORT restriction and other area-related restrictions? Defaults to FALSE + * * no_wake: Whether or not we want a teleport wake to be created + */ +/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, bypass_area_restriction = FALSE, teleport_mode = TELEPORT_ALLOW_ALL, ignore_check_teleport = FALSE, no_wake = FALSE) // teleporting most effects just deletes them var/static/list/delete_atoms = typecacheof(list( /obj/effect, @@ -23,22 +95,6 @@ qdel(teleatom) return FALSE - //Check bluespace anchors - if(channel != TELEPORT_CHANNEL_WORMHOLE && channel != TELEPORT_CHANNEL_FREE) - for (var/obj/machinery/bluespace_anchor/anchor as() in GLOB.active_bluespace_anchors) - //Not nearby - if (anchor.get_virtual_z_level() != teleatom.get_virtual_z_level() || (get_dist(teleatom, anchor) > anchor.range && get_dist(destination, anchor) > anchor.range)) - continue - //Check it - if(!anchor.try_activate()) - continue - do_sparks(5, FALSE, teleatom) - playsound(anchor, 'sound/magic/repulse.ogg', 80, TRUE) - if(ismob(teleatom)) - to_chat(teleatom, "You feel like you are being held in place.") - //Anchored... - return FALSE - // argument handling // if the precision is not specified, default to 0, but apply BoH penalties if (isnull(precision)) @@ -48,8 +104,7 @@ 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) + var/list/bagholding = teleatom.GetAllContents(/obj/item/storage/backpack/holding) if(bagholding.len) precision = max(rand(1,100)*bagholding.len,100) if(isliving(teleatom)) @@ -69,34 +124,25 @@ var/turf/curturf = get_turf(teleatom) var/turf/destturf = get_teleport_turf(get_turf(destination), precision) - if(!destturf || !curturf || destturf.is_transition_turf()) - return FALSE - - var/area/A = get_area(curturf) - var/area/B = get_area(destturf) - if(!forced && (HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT))) - return FALSE - - //Either area has teleport restriction and teleport mode isn't allowed in that area - if(!forced && ((A.teleport_restriction && A.teleport_restriction != teleport_mode) || (B.teleport_restriction && B.teleport_restriction != teleport_mode))) - return FALSE - - if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf)) - return FALSE - if(isobserver(teleatom)) teleatom.abstract_move(destturf) return TRUE - if (!commit) - return TRUE + if(!ignore_check_teleport) // If we've already done it let's not check again + if(!check_teleport(teleatom, destturf, channel, bypass_area_restriction, teleport_mode)) + return FALSE // If we leave behind a wake, then create that here. // Only leave a wake if we are going to a location that we can actually teleport to. - if (!no_wake && (channel == TELEPORT_CHANNEL_BLUESPACE || channel == TELEPORT_CHANNEL_CULT || channel == TELEPORT_CHANNEL_MAGIC) && A.teleport_restriction == TELEPORT_MODE_DEFAULT && B.teleport_restriction == TELEPORT_MODE_DEFAULT && teleport_mode == TELEPORT_MODE_DEFAULT) - new /obj/effect/temp_visual/teleportation_wake(get_turf(teleatom), destturf) + if (!no_wake && (channel == TELEPORT_CHANNEL_BLUESPACE || channel == TELEPORT_CHANNEL_CULT || channel == TELEPORT_CHANNEL_MAGIC)) + var/area/cur_area = curturf.loc + var/area/dest_area = destturf.loc + if(cur_area.teleport_restriction == TELEPORT_ALLOW_ALL && dest_area.teleport_restriction == TELEPORT_ALLOW_ALL && teleport_mode == TELEPORT_ALLOW_ALL) + new /obj/effect/temp_visual/teleportation_wake(get_turf(teleatom), destturf) tele_play_specials(teleatom, curturf, effectin, asoundin) + + // Actually teleport them var/success = teleatom.forceMove(destturf) if (success) log_game("[key_name(teleatom)] has teleported from [loc_name(curturf)] to [loc_name(destturf)]") @@ -113,12 +159,13 @@ 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() + if (!istype(location) || isobserver(teleatom)) + return + 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, dense_atoms = TRUE) diff --git a/code/game/area/areas/centcom.dm b/code/game/area/areas/centcom.dm index 3f162914b61e5..fc94c7d60b48b 100644 --- a/code/game/area/areas/centcom.dm +++ b/code/game/area/areas/centcom.dm @@ -125,7 +125,7 @@ dynamic_lighting = DYNAMIC_LIGHTING_ENABLED requires_power = FALSE has_gravity = STANDARD_GRAVITY - teleport_restriction = TELEPORT_ALLOW_NONE + teleport_restriction = TELEPORT_ALLOW_WIZARD area_flags = VALID_TERRITORY | UNIQUE_AREA flags_1 = NONE network_root_id = "MAGIC_NET" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index c8ae188439383..c34be0707b21d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1010,6 +1010,27 @@ CREATION_TEST_IGNORE_SUBTYPES(/atom) /atom/proc/teleport_act() SEND_SIGNAL(src,COMSIG_ATOM_TELEPORT_ACT) +/** + * Intercept our atom being teleported if we need to + * + * return COMPONENT_BLOCK_TELEPORT to explicity block teleportation + */ +/atom/proc/intercept_teleport(channel, turf/origin, turf/destination) + . = SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, origin, destination) + + if(. == COMPONENT_BLOCK_TELEPORT) + return + + // Recursively check contents by default. This can be overriden if we want different behavior. + for(var/atom/thing in contents) + // For the purposes of intercepting teleports, mobs on the turf don't count. + // We're already doing logic for intercepting teleports on the teleatom-level + if(isturf(src) && ismob(thing)) + continue + var/result = thing.intercept_teleport(channel, origin, destination) + if(result == COMPONENT_BLOCK_TELEPORT) + return result + /** * Respond to our atom being checked by a virus extrapolator. * diff --git a/code/game/objects/items/scrolls.dm b/code/game/objects/items/scrolls.dm index 98a642cb88746..487a0aa3c815a 100644 --- a/code/game/objects/items/scrolls.dm +++ b/code/game/objects/items/scrolls.dm @@ -64,7 +64,7 @@ to_chat(user, "The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.") return - if(do_teleport(user, pick(L), channel = TELEPORT_CHANNEL_MAGIC, forced = TRUE)) + if(do_teleport(user, pick(L), channel = TELEPORT_CHANNEL_MAGIC, bypass_area_restriction = TRUE)) smoke.start() uses-- else diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 16cdba633ad81..852bc8c326261 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -200,13 +200,10 @@ qdel(target_effect) qdel(source_effect) return - var/area/A = get_area(teleport_target) - if(A.teleport_restriction) - to_chat(user, "\The [src] is malfunctioning.") - return current_location = get_turf(user) //Recheck. current_area = current_location.loc - if(!current_location || current_area.teleport_restriction || is_away_level(current_location.z) || is_centcom_level(current_location.z) || !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 + var/turf/dest_turf = get_teleport_turf(get_turf(teleport_target)) + if(isnull(current_area) || !check_teleport(user, dest_turf, channel = TELEPORT_CHANNEL_BLUESPACE) || is_away_level(current_location.z) || is_centcom_level(current_location.z))//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 var/list/obj/effect/portal/created = create_portal_pair(current_location, get_teleport_turf(get_turf(teleport_target)), src, 300, 1, null, atmos_link_override) @@ -359,7 +356,7 @@ // Check if we can move here current_area = current_location.loc - if(!do_teleport(C, current_location, no_effects = TRUE, channel = TELEPORT_CHANNEL_BLINK, commit = FALSE))//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 + if(!check_teleport(C, current_location, channel = TELEPORT_CHANNEL_BLINK))//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 current_location = previous break // If it contains objects, try to break it diff --git a/code/modules/antagonists/abductor/machinery/experiment.dm b/code/modules/antagonists/abductor/machinery/experiment.dm index 403a1e55bce35..bef2992c94f57 100644 --- a/code/modules/antagonists/abductor/machinery/experiment.dm +++ b/code/modules/antagonists/abductor/machinery/experiment.dm @@ -178,7 +178,7 @@ H.uncuff() H.cauterise_wounds() if(console && console.pad && console.pad.teleport_target) - do_teleport(H, console.pad.teleport_target, channel = TELEPORT_CHANNEL_BLINK, no_effects = TRUE, teleport_mode = TELEPORT_MODE_ABDUCTORS) + do_teleport(H, console.pad.teleport_target, channel = TELEPORT_CHANNEL_BLINK, no_effects = TRUE, teleport_mode = TELEPORT_ALLOW_ABDUCTORS) return //Area not chosen / It's not safe area - teleport to arrivals SSjob.SendToLateJoin(H, FALSE) diff --git a/code/modules/antagonists/abductor/machinery/pad.dm b/code/modules/antagonists/abductor/machinery/pad.dm index 9c08ed9c88828..b892b098630da 100644 --- a/code/modules/antagonists/abductor/machinery/pad.dm +++ b/code/modules/antagonists/abductor/machinery/pad.dm @@ -7,14 +7,14 @@ /obj/machinery/abductor/pad/proc/Warp(mob/living/target) if(!target.buckled) - do_teleport(target, get_turf(src), no_effects = TRUE, channel = TELEPORT_CHANNEL_BLINK, teleport_mode = TELEPORT_MODE_ABDUCTORS) + do_teleport(target, get_turf(src), no_effects = TRUE, channel = TELEPORT_CHANNEL_BLINK, teleport_mode = TELEPORT_ALLOW_ABDUCTORS) /obj/machinery/abductor/pad/proc/Send() if(teleport_target == null) teleport_target = GLOB.teleportlocs[pick(GLOB.teleportlocs)] flick("alien-pad", src) for(var/mob/living/target in loc) - do_teleport(target, teleport_target, no_effects = TRUE, channel = TELEPORT_CHANNEL_BLINK, teleport_mode = TELEPORT_MODE_ABDUCTORS) + do_teleport(target, teleport_target, no_effects = TRUE, channel = TELEPORT_CHANNEL_BLINK, teleport_mode = TELEPORT_ALLOW_ABDUCTORS) new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir) to_chat(target, "The instability of the warp leaves you disoriented!") target.SetSleeping(60) @@ -33,7 +33,7 @@ /obj/machinery/abductor/pad/proc/doMobToLoc(place, atom/movable/target) flick("alien-pad", src) - do_teleport(target, place, no_effects = TRUE, channel = TELEPORT_CHANNEL_BLINK, teleport_mode = TELEPORT_MODE_ABDUCTORS) + do_teleport(target, place, no_effects = TRUE, channel = TELEPORT_CHANNEL_BLINK, teleport_mode = TELEPORT_ALLOW_ABDUCTORS) new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir) /obj/machinery/abductor/pad/proc/MobToLoc(place,mob/living/target) @@ -43,7 +43,7 @@ /obj/machinery/abductor/pad/proc/doPadToLoc(place) flick("alien-pad", src) for(var/mob/living/target in get_turf(src)) - do_teleport(target, place, no_effects = TRUE, channel = TELEPORT_CHANNEL_BLINK, teleport_mode = TELEPORT_MODE_ABDUCTORS) + do_teleport(target, place, no_effects = TRUE, channel = TELEPORT_CHANNEL_BLINK, teleport_mode = TELEPORT_ALLOW_ABDUCTORS) new /obj/effect/temp_visual/dir_setting/ninja(get_turf(target), target.dir) /obj/machinery/abductor/pad/proc/PadToLoc(place) diff --git a/code/modules/antagonists/clock_cult/helpers/servant_warp.dm b/code/modules/antagonists/clock_cult/helpers/servant_warp.dm index ee6b570a1f24d..5dfdefee00976 100644 --- a/code/modules/antagonists/clock_cult/helpers/servant_warp.dm +++ b/code/modules/antagonists/clock_cult/helpers/servant_warp.dm @@ -10,10 +10,10 @@ playsound(target_location, 'sound/magic/magic_missile.ogg', 50, TRUE) do_sparks(5, TRUE, servant) do_sparks(5, TRUE, target_location) - do_teleport(M, target_location, channel = TELEPORT_CHANNEL_BLINK, no_effects = TRUE, teleport_mode = TELEPORT_MODE_CLOCKWORK) + do_teleport(M, target_location, channel = TELEPORT_CHANNEL_CULT, no_effects = TRUE, teleport_mode = TELEPORT_ALLOW_CLOCKWORK) new /obj/effect/temp_visual/ratvar/warp(target_location) to_chat(servant, "You warp to [get_area(target_location)].") if(istype(P) && bring_dragging) - do_teleport(P, target_location, channel = TELEPORT_CHANNEL_BLINK, no_effects = TRUE, teleport_mode = TELEPORT_MODE_CLOCKWORK) + do_teleport(P, target_location, channel = TELEPORT_CHANNEL_CULT, no_effects = TRUE, teleport_mode = TELEPORT_ALLOW_CLOCKWORK) P.Paralyze(30) to_chat(P, "You feel sick and confused...") diff --git a/code/modules/antagonists/clock_cult/structure/dimensional_rift.dm b/code/modules/antagonists/clock_cult/structure/dimensional_rift.dm index 5a904c68d3649..3bbe183833175 100644 --- a/code/modules/antagonists/clock_cult/structure/dimensional_rift.dm +++ b/code/modules/antagonists/clock_cult/structure/dimensional_rift.dm @@ -29,7 +29,7 @@ if(do_after(M, 50, target=src)) var/obj/effect/landmark/city_of_cogs/target_spawn = pick(GLOB.city_of_cogs_spawns) var/turf/T = get_turf(target_spawn) - do_teleport(M, T, no_effects = TRUE, channel = TELEPORT_CHANNEL_FREE, forced = TRUE) + do_teleport(M, T, no_effects = TRUE, channel = TELEPORT_CHANNEL_FREE, bypass_area_restriction = TRUE) var/mob/living/M_mob = M if(istype(M_mob)) if(M_mob.client) @@ -43,4 +43,4 @@ //So we can push crates in too var/obj/effect/landmark/city_of_cogs/target_spawn = pick(GLOB.city_of_cogs_spawns) var/turf/T = get_turf(target_spawn) - do_teleport(M, T, no_effects = TRUE, channel = TELEPORT_CHANNEL_FREE, forced = TRUE) + do_teleport(M, T, no_effects = TRUE, channel = TELEPORT_CHANNEL_FREE, bypass_area_restriction = TRUE) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 7b13e2af68e76..7bc21a124e288 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -466,7 +466,7 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/effect/rune/teleport) visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!", null, "You hear a sharp crack.") to_chat(user, "You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].") else - to_chat(user, "You[moveuserlater ? "r vision blurs briefly, but nothing happens":" try send everything above the rune away, but the teleportation fails"].") + to_chat(user, "You[moveuserlater ? "r vision blurs briefly, but nothing happens":" try send everything above the rune away, but the teleportation fails"].") if(is_mining_level(z) && !is_mining_level(target.z)) //No effect if you stay on lavaland actual_selected_rune.handle_portal("lava") else diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm index 45d07518cd1a8..5de108942ad72 100644 --- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm +++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm @@ -265,7 +265,7 @@ return // Send 'em to the destination. If the teleport fails, just disembowel them and stop the chain - if(!destination || !do_teleport(sac_target, destination, asoundin = 'sound/magic/repulse.ogg', asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = TRUE, no_wake = TRUE)) + if(!destination || !do_teleport(sac_target, destination, asoundin = 'sound/magic/repulse.ogg', asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_MAGIC, bypass_area_restriction = TRUE, no_wake = TRUE)) disembowel_target(sac_target) return @@ -374,7 +374,7 @@ safe_turf = get_turf(backup_loc) stack_trace("[type] - return_target was unable to find a safe turf for [sac_target] to return to. Defaulting to observer start turf.") - if(!do_teleport(sac_target, safe_turf, asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_FREE, forced = TRUE, no_wake = TRUE)) + if(!do_teleport(sac_target, safe_turf, asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_FREE, bypass_area_restriction = TRUE, no_wake = TRUE)) safe_turf = get_turf(backup_loc) sac_target.forceMove(safe_turf) stack_trace("[type] - return_target was unable to teleport [sac_target] to the observer start turf. Forcemoving.") diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm index 85b96e894dc64..9208c198a8a33 100644 --- a/code/modules/antagonists/revenant/revenant_abilities.dm +++ b/code/modules/antagonists/revenant/revenant_abilities.dm @@ -187,7 +187,7 @@ if(QDELETED(src)) // it's bad when someone spams this... return var/turf/targetturf = get_random_station_turf() - if(!do_teleport(user, targetturf, channel = TELEPORT_CHANNEL_CULT, forced=TRUE)) + if(!do_teleport(user, targetturf, channel = TELEPORT_CHANNEL_CULT, bypass_area_restriction=TRUE)) to_chat(user, "You have failed to recall yourself to the station... You should try again.") else user.reveal(80) diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index e78e9d1d2f941..710cdf672cd60 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -488,7 +488,7 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/effect/rend) while(breakout < 50) var/turf/potential_T = find_safe_turf() if(T.get_virtual_z_level() != potential_T.get_virtual_z_level() || abs(get_dist_euclidian(potential_T,T)) > 50 - breakout) - do_teleport(user, potential_T, channel = TELEPORT_CHANNEL_MAGIC) + do_teleport(user, potential_T, channel = TELEPORT_CHANNEL_MAGIC, teleport_mode = TELEPORT_ALLOW_WIZARD) T = potential_T break breakout += 1 diff --git a/code/modules/bluespace_anchor/bluespace_anchor.dm b/code/modules/bluespace_anchor/bluespace_anchor.dm index 0ab3ceffc12bf..d4b29d75e75fb 100644 --- a/code/modules/bluespace_anchor/bluespace_anchor.dm +++ b/code/modules/bluespace_anchor/bluespace_anchor.dm @@ -66,6 +66,11 @@ CREATION_TEST_IGNORE_SUBTYPES(/obj/machinery/bluespace_anchor) src.Beam(L, icon_state="lightning[rand(1,12)]", time=5, maxdistance = INFINITY) var/shock_damage = min(round(power_usage_per_teleport/600), 90) + rand(-5, 5) L.electrocute_act(shock_damage, src) + // Give feedback + do_sparks(5, FALSE, teleatom) + playsound(src, 'sound/magic/repulse.ogg', 80, TRUE) + if(ismob(teleatom)) + to_chat(teleatom, "You feel like you are being held in place.") return TRUE /obj/machinery/bluespace_anchor/proc/set_cell(cell) diff --git a/code/modules/mob/living/simple_animal/hostile/bread.dm b/code/modules/mob/living/simple_animal/hostile/bread.dm index 4c8ddba930b5b..7e62adfd45951 100644 --- a/code/modules/mob/living/simple_animal/hostile/bread.dm +++ b/code/modules/mob/living/simple_animal/hostile/bread.dm @@ -27,6 +27,8 @@ mobchatspan = "blob" /mob/living/simple_animal/hostile/breadloaf/teleport_act() + . = ..() + if(mutations == 0) mutationcap = rand(1,mutability) if(prob(90)) diff --git a/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm b/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm index 1252ca6c07f6e..e5261d797ff27 100644 --- a/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm +++ b/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm @@ -507,7 +507,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) return // Send 'em to the destination. If the teleport fails, do nothing. - if(!destination || !do_teleport(sac_target, destination, asoundin = 'sound/magic/repulse.ogg', asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = TRUE, no_wake = TRUE)) + if(!destination || !do_teleport(sac_target, destination, asoundin = 'sound/magic/repulse.ogg', asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_MAGIC, bypass_area_restriction = TRUE, no_wake = TRUE)) return // If our target died during the (short) wait timer, @@ -594,7 +594,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) safe_turf = get_turf(backup_loc) stack_trace("[type] - return_target was unable to find a safe turf for [sac_target] to return to. Defaulting to observer start turf.") - if(!do_teleport(sac_target, safe_turf, asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_FREE, forced = TRUE, no_wake = TRUE)) + if(!do_teleport(sac_target, safe_turf, asoundout = 'sound/magic/blind.ogg', no_effects = TRUE, channel = TELEPORT_CHANNEL_FREE, bypass_area_restriction = TRUE, no_wake = TRUE)) safe_turf = get_turf(backup_loc) sac_target.forceMove(safe_turf) stack_trace("[type] - return_target was unable to teleport [sac_target] to the observer start turf. Forcemoving.") diff --git a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm index c42e7457ff4a0..01bacdffe2c2d 100644 --- a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm +++ b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm @@ -114,7 +114,7 @@ It is possible to destroy the net by the occupant or someone else. // Teleport var/turf/picked_station_level = get_random_station_turf() //Don't want to limit this specifically to z 2 in case we get multi-z in rotation var/turf/safe_location = find_safe_turf(picked_station_level.z, extended_safety_checks = TRUE, dense_atoms = FALSE) - do_teleport(target, safe_location, channel = TELEPORT_CHANNEL_FREE, forced = TRUE) + do_teleport(target, safe_location, channel = TELEPORT_CHANNEL_FREE, bypass_area_restriction = TRUE) target.Unconscious(3 SECONDS) /obj/structure/energy_net/attack_paw(mob/user) diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm index ce80f3c01e65d..730186f0f3488 100644 --- a/code/modules/projectiles/guns/magic/wand.dm +++ b/code/modules/projectiles/guns/magic/wand.dm @@ -142,7 +142,7 @@ no_den_usage = TRUE /obj/item/gun/magic/wand/teleport/zap_self(mob/living/user) - if(do_teleport(user, user, 10, channel = TELEPORT_CHANNEL_MAGIC)) + if(do_teleport(user, user, 10, channel = TELEPORT_CHANNEL_MAGIC, teleport_mode = TELEPORT_ALLOW_WIZARD)) var/datum/effect_system/smoke_spread/smoke = new smoke.set_up(3, user.loc) smoke.start() @@ -162,7 +162,7 @@ var/turf/origin = get_turf(user) var/turf/destination = find_safe_turf() - if(do_teleport(user, destination, channel=TELEPORT_CHANNEL_MAGIC)) + if(do_teleport(user, destination, channel=TELEPORT_CHANNEL_MAGIC, teleport_mode = TELEPORT_ALLOW_WIZARD)) for(var/t in list(origin, destination)) var/datum/effect_system/smoke_spread/smoke = new smoke.set_up(0, t) diff --git a/code/modules/spells/spell_types/area_teleport.dm b/code/modules/spells/spell_types/area_teleport.dm index 2980830bd87f1..66362c4f43cae 100644 --- a/code/modules/spells/spell_types/area_teleport.dm +++ b/code/modules/spells/spell_types/area_teleport.dm @@ -60,7 +60,7 @@ var/success = FALSE while(tempL.len) attempt = pick(tempL) - do_teleport(target, attempt, channel = TELEPORT_CHANNEL_MAGIC) + do_teleport(target, attempt, channel = TELEPORT_CHANNEL_MAGIC, teleport_mode = TELEPORT_ALLOW_WIZARD) if(get_turf(target) == attempt) success = TRUE break @@ -68,7 +68,7 @@ tempL.Remove(attempt) if(!success) - do_teleport(target, L, channel = TELEPORT_CHANNEL_MAGIC) + do_teleport(target, L, channel = TELEPORT_CHANNEL_MAGIC, teleport_mode = TELEPORT_ALLOW_WIZARD) playsound(get_turf(user), sound2, 50,1) /obj/effect/proc_holder/spell/targeted/area_teleport/invocation(area/chosenarea = null,mob/living/user = usr) diff --git a/code/modules/spells/spell_types/turf_teleport.dm b/code/modules/spells/spell_types/turf_teleport.dm index 3dbe76e5cddc4..15efcc345c6b0 100644 --- a/code/modules/spells/spell_types/turf_teleport.dm +++ b/code/modules/spells/spell_types/turf_teleport.dm @@ -34,5 +34,5 @@ if(!picked || !isturf(picked)) return - if(do_teleport(user, picked, channel = TELEPORT_CHANNEL_MAGIC)) + if(do_teleport(user, picked, channel = TELEPORT_CHANNEL_MAGIC, teleport_mode = TELEPORT_ALLOW_WIZARD)) playsound(get_turf(user), sound1, 50,1)