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

🆑
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?)
/🆑
This commit is contained in:
tonty
2024-11-09 17:03:47 +01:00
committed by GitHub
parent af9859529f
commit 25a0420147
2 changed files with 40 additions and 17 deletions
+27 -6
View File
@@ -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)
+13 -11
View File
@@ -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