Jaunting no longer allows you to end up inside a wall (#59520)

Jaunting now keeps track of the last five non-blocked tiles you moved across while in the jaunt. Upon exit, it will attempt to deposit you into the last unblocked tile. Should it run out of tiles to try, you will be returned to your starting location. As such, jaunting mobs can no longer end up inside walls or dense objects. Tables, and anything else with the climbable element, are still allowed.

Added support to /turf/proc/is_blocked_turf() to allow ignoring climbable atoms.

Added the TRAIT_CLIMBABLE trait, applied by the climbable element, to accomplish the above.
This commit is contained in:
zxaber
2021-06-28 07:03:22 -07:00
committed by GitHub
parent f7ac03beb0
commit 24be009e96
4 changed files with 55 additions and 0 deletions
+3
View File
@@ -380,6 +380,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
*/
#define TRAIT_AREA_SENSITIVE "area-sensitive"
/// Climbable trait, given and taken by the climbable element when added or removed. Exists to be easily checked via HAS_TRAIT().
#define TRAIT_CLIMBABLE "trait_climbable"
///Used for managing KEEP_TOGETHER in [/atom/var/appearance_flags]
#define TRAIT_KEEP_TOGETHER "keep-together"
+2
View File
@@ -22,9 +22,11 @@
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine)
RegisterSignal(target, COMSIG_MOUSEDROPPED_ONTO, .proc/mousedrop_receive)
RegisterSignal(target, COMSIG_ATOM_BUMPED, .proc/try_speedrun)
ADD_TRAIT(target, TRAIT_CLIMBABLE, src)
/datum/element/climbable/Detach(datum/target)
UnregisterSignal(target, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_PARENT_EXAMINE, COMSIG_MOUSEDROPPED_ONTO, COMSIG_ATOM_BUMPED))
REMOVE_TRAIT(target, TRAIT_CLIMBABLE, src)
return ..()
/datum/element/climbable/proc/on_examine(atom/source, mob/user, list/examine_texts)
+14
View File
@@ -212,6 +212,20 @@ GLOBAL_LIST_EMPTY(station_turfs)
return TRUE
return FALSE
/**
* Checks whether the specified turf is blocked by something dense inside it, but ignores anything with the climbable trait
*
* Works similar to is_blocked_turf(), but ignores climbables and has less options. Primarily added for jaunting checks
*/
/turf/proc/is_blocked_turf_ignore_climbable()
if(density)
return TRUE
for(var/atom/movable/atom_content as anything in contents)
if(atom_content.density && !(atom_content.flags_1 & ON_BORDER_1) && !HAS_TRAIT(atom_content, TRAIT_CLIMBABLE))
return TRUE
return FALSE
//zPassIn doesn't necessarily pass an atom!
//direction is direction of travel of air
/turf/proc/zPassIn(atom/movable/A, direction, turf/source)
@@ -22,6 +22,8 @@
var/jaunt_in_type = /obj/effect/temp_visual/wizard
/// Visual for exiting the jaunt
var/jaunt_out_type = /obj/effect/temp_visual/wizard/out
/// List of valid exit points
var/list/exit_point_list
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/cast_check(skipcharge = 0,mob/user = usr)
. = ..()
@@ -51,11 +53,28 @@
ADD_TRAIT(target, TRAIT_IMMOBILIZED, type)
sleep(jaunt_out_time)
REMOVE_TRAIT(target, TRAIT_IMMOBILIZED, type)
var/turf/exit_point = get_turf(holder) //Hopefully this gets updated, otherwise this is our fallback
LAZYINITLIST(exit_point_list)
RegisterSignal(holder, COMSIG_MOVABLE_MOVED, .proc/update_exit_point, target)
sleep(jaunt_duration)
UnregisterSignal(holder, COMSIG_MOVABLE_MOVED)
if(target.loc != holder) //mob warped out of the warp
qdel(holder)
return
var/found_exit = FALSE
for(var/turf/possible_exit as anything in exit_point_list)
if(possible_exit.is_blocked_turf_ignore_climbable())
continue
exit_point = possible_exit
found_exit = TRUE
break
if(!found_exit)
to_chat(target, "<span='danger'>Unable to find an unobstructed space, you find yourself ripped back to where you started.</span>")
exit_point_list.Cut()
holder.forceMove(exit_point)
mobloc = get_turf(target.loc)
jaunt_steam(mobloc)
ADD_TRAIT(target, TRAIT_IMMOBILIZED, type)
@@ -75,6 +94,23 @@
break
REMOVE_TRAIT(target, TRAIT_IMMOBILIZED, type)
/**
* Updates the exit point of the jaunt
*
* Called when the jaunting mob holder moves, this updates the backup exit-jaunt
* location, in case the jaunt ends with the mob still in a wall. Five
* spots are kept in the list, in case the last few changed since we passed
* by (doors closing, engineers building walls, etc)
*/
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/update_exit_point(mob/living/target)
SIGNAL_HANDLER
var/turf/location = get_turf(target)
if(location.is_blocked_turf_ignore_climbable())
return
exit_point_list.Insert(1, location)
if(length(exit_point_list) >= 5)
exit_point_list.Cut(5)
/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/proc/jaunt_steam(mobloc)
var/datum/effect_system/steam_spread/steam = new /datum/effect_system/steam_spread()
steam.set_up(10, 0, mobloc)