From 25a042014739e902cc70d4f370ba5edcfdbb2bee Mon Sep 17 00:00:00 2001 From: tonty <39193182+tontyGH@users.noreply.github.com> Date: Sat, 9 Nov 2024 11:03:47 -0500 Subject: [PATCH] Teleporting while buckled to something will take you with it (#87725) ## About The Pull Request closes #35872 (this bug is 6+ years old) `/proc/do_teleport(...)` now has extra checks for atoms with buckled mobs attempting to pass through it, assuring that they also pass through with the vehicle `/atom/movable/proc/is_buckle_possible(...)` will skip density checks if the bucklable and the target share the same tile, because at that point it doesn't really matter (it also interfered with density checks when teleporting) ## Gleeble ![fucked-up-dog-geeble](https://github.com/user-attachments/assets/6ef814c2-d8f2-48fc-82a3-98517bf6a492) ## Changelog :cl: fix: Teleporting while buckled to something now works as expected fix: You can buckle to anything if you share the same tile (cause at that point it doesn't matter if there's a wall, right?) /:cl: --- code/datums/helper_datums/teleport.dm | 33 ++++++++++++++++++++++----- code/game/objects/buckling.dm | 24 ++++++++++--------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index b979c9cda0f..b51f7097a9f 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -23,7 +23,7 @@ // argument handling // if the precision is not specified, default to 0, but apply BoH penalties - if (isnull(precision)) + if(isnull(precision)) precision = 0 switch(channel) @@ -40,7 +40,7 @@ to_chat(MM, span_warning("The bluespace interface on your bag of holding interferes with the teleport!")) // if effects are not specified and not explicitly disabled, sparks - if ((!effectin || !effectout) && !no_effects) + if((!effectin || !effectout) && !no_effects) var/datum/effect_system/spark_spread/sparks = new sparks.set_up(5, 1, teleatom) if (!effectin) @@ -78,10 +78,16 @@ return TRUE tele_play_specials(teleatom, curturf, effectin, asoundin) + var/success = teleatom.forceMove(destturf) - if(success) - log_game("[key_name(teleatom)] has teleported from [loc_name(curturf)] to [loc_name(destturf)]") - tele_play_specials(teleatom, destturf, effectout, asoundout) + if(!success) + return FALSE + + . = TRUE + /* Past this point, the teleport is successful and you can assume that they're already there */ + + log_game("[key_name(teleatom)] has teleported from [loc_name(curturf)] to [loc_name(destturf)]") + tele_play_specials(teleatom, destturf, effectout, asoundout) if(ismob(teleatom)) var/mob/M = teleatom @@ -90,7 +96,22 @@ SEND_SIGNAL(teleatom, COMSIG_MOVABLE_POST_TELEPORT, destination, channel) - return TRUE + //We need to be sure that the buckled mobs can teleport too + if(teleatom.has_buckled_mobs()) + for(var/mob/living/rider in teleatom.buckled_mobs) + //just in case it fails, but the mob gets unbuckled anyways even if it passes + teleatom.unbuckle_mob(rider, TRUE, FALSE) + + var/rider_success = do_teleport(rider, destturf, precision, channel=channel, no_effects=TRUE) + if(!rider_success) + continue + + if(get_turf(rider) != destturf) //precision made them teleport somewhere else + to_chat(rider, span_warning("As you reorient your senses, you realize you aren't riding [teleatom] anymore!")) + continue + + // [mob/living].forceMove() forces mobs to unbuckle, so we need to buckle them again + teleatom.buckle_mob(rider, force=TRUE) /proc/tele_play_specials(atom/movable/teleatom, atom/location, datum/effect_system/effect, sound) if(!location) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index f06ac5d9209..4104367a73e 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -215,23 +215,25 @@ if(target == src) return FALSE - // Check if the target to buckle isn't INSIDE OF A WALL - if(!isopenturf(loc) || !isopenturf(target.loc)) - return FALSE - - // Check if the target to buckle isn't A SOLID OBJECT (not including vehicles) var/turf/ground = get_turf(src) - if(ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src)) - return FALSE + // If we're not already on the same turf as our target... + if(get_turf(target) != ground) + // Check if the target to buckle isn't INSIDE OF A WALL + if(!isopenturf(loc) || !isopenturf(target.loc)) + return FALSE + + // Check if the target to buckle isn't INSIDE A SOLID OBJECT (not including vehicles) + if(ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src)) + return FALSE + + // If we're checking the loc, make sure the target is on the thing we're bucking them to. + if(check_loc && !target.Adjacent(src)) + return FALSE // Check if this atom can have things buckled to it. if(!can_buckle && !force) return FALSE - // If we're checking the loc, make sure the target is on the thing we're bucking them to. - if(check_loc && !target.Adjacent(src)) - return FALSE - // Make sure the target isn't already buckled to something. if(target.buckled) return FALSE