Fix Various Movement Bugs (#21823)

This PR fixes a variety of bugs related to smooth movement. See the
changelog for more details. I have actually tested this PR.

Mechs and Mobs:


https://github.com/user-attachments/assets/77cd6d92-2616-409f-a909-d19565dfc718

Trains:


https://github.com/user-attachments/assets/0a12bc9a-6c45-471b-98fa-a91717cd85be

Pulling stuff in general:


https://github.com/user-attachments/assets/e2a7cdaa-2fcd-443c-bd76-bcd74e696c72

Rollerbeds:


https://github.com/user-attachments/assets/d0d35153-f406-45e9-afaf-ad19499098fe
This commit is contained in:
VMSolidus
2026-02-06 23:24:22 +00:00
committed by GitHub
parent 407c7e346a
commit 7fc9f27eeb
7 changed files with 74 additions and 22 deletions
+1 -1
View File
@@ -9,7 +9,7 @@
mob_push_flags = ALLMOBS
can_be_buckled = FALSE
accent = ACCENT_TTS
appearance_flags = KEEP_TOGETHER
appearance_flags = KEEP_TOGETHER | DEFAULT_APPEARANCE_FLAGS | TILE_BOUND | LONG_GLIDE
pass_flags_self = PASSVEHICLE
var/decal
@@ -26,7 +26,7 @@
/// We only try to show a gibbing animation if this exists
var/icon_gib = null
appearance_flags = KEEP_TOGETHER
appearance_flags = KEEP_TOGETHER | DEFAULT_APPEARANCE_FLAGS | TILE_BOUND | LONG_GLIDE
/// Blood colour for impact visuals
var/blood_type = COLOR_HUMAN_BLOOD
+32 -16
View File
@@ -192,6 +192,7 @@
var/mob/living/L = mob
if(L.incorporeal_move && isturf(mob.loc))//Move though walls
mob.recalculate_glide_size(old_move_delay, move_delay, direct)
Process_Incorpmove(direct, mob)
return
if(mob.client && ((mob.client.view != world.view) || (mob.client.pixel_x != 0) || (mob.client.pixel_y != 0))) // If mob moves while zoomed in with device, unzoom them.
@@ -228,8 +229,9 @@
mob.lastarea = get_area(mob.loc)
if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we are moving out
var/atom/O = mob.loc
var/atom/movable/O = mob.loc
move_delay += (mob.movement_delay() + GLOB.config.walk_speed) * GLOB.config.walk_delay_multiplier
O.recalculate_glide_size(old_move_delay, move_delay, direct)
return O.relaymove(mob, direct)
if(isturf(mob.loc))
@@ -258,12 +260,14 @@
if(mob.buckled_to)
if(istype(mob.buckled_to, /obj/vehicle))
//manually set move_delay for vehicles so we don't inherit any mob movement penalties
//specific vehicle move delays are set in code\modules\vehicles\vehicle.dm
move_delay = (old_move_delay + world.tick_lag > world.time) ? old_move_delay : world.time
//drunk driving
if(mob.confused && prob(25))
direct = pick(GLOB.cardinals)
var/obj/vehicle/vehicle = mob.buckled_to
move_delay += vehicle.move_delay
var/vehicle_glide_size = vehicle.recalculate_glide_size(old_move_delay, move_delay, direct)
mob.set_glide_size(vehicle_glide_size)
return mob.buckled_to.relaymove(mob,direct)
//TODO: Fuck wheelchairs.
@@ -281,6 +285,8 @@
if(mob.confused && prob(25))
direct = pick(GLOB.cardinals)
move_delay += max((mob.movement_delay() + GLOB.config.walk_speed) * GLOB.config.walk_delay_multiplier, min_move_delay)
var/wheelchair_glide_size = mob.buckled_to.recalculate_glide_size(old_move_delay, move_delay, direct)
mob.set_glide_size(wheelchair_glide_size)
return mob.buckled_to.relaymove(mob,direct)
var/tally = mob.movement_delay() + GLOB.config.walk_speed
@@ -309,30 +315,25 @@
if(crawl_tally >= 120)
return FALSE
if(istype(mob.machine, /obj/machinery))
if(mob.machine.relaymove(mob,direct))
return
//Wheelchair pushing goes here for now.
//TODO: Fuck wheelchairs.
if(istype(mob.pulledby, /obj/structure/bed/stool/chair/office/wheelchair) || istype(mob.pulledby, /obj/structure/cart))
if(istype(mob.pulledby, /obj/structure))
var/obj/structure/S = mob.pulledby
move_delay += S.slowdown
var/cart_glide_size = mob.pulledby.recalculate_glide_size(old_move_delay, move_delay, direct)
mob.set_glide_size(cart_glide_size)
return mob.pulledby.relaymove(mob, direct)
var/old_loc = mob.loc
//We are now going to move
moving = 1
var/new_glide_size = mob.recalculate_glide_size(old_move_delay, move_delay, direct)
var/new_glide_size = mob.glide_size
if(old_move_delay + world.tick_lag > world.time)
new_glide_size = DELAY_TO_GLIDE_SIZE((move_delay - old_move_delay) * ( (NSCOMPONENT(direct) && EWCOMPONENT(direct)) ? sqrt(2) : 1 ) )
else
new_glide_size = DELAY_TO_GLIDE_SIZE((move_delay - world.time) * ( (NSCOMPONENT(direct) && EWCOMPONENT(direct)) ? sqrt(2) : 1 ) )
mob.set_glide_size(new_glide_size) // set it now in case of pulled objects
if (mob.pulling)
mob.pulling.set_glide_size(new_glide_size)
mob.pulling.relaymove(mob, direct)
if(mob_is_human)
for(var/obj/item/grab/G in list(mob.l_hand, mob.r_hand))
@@ -377,6 +378,21 @@
var/obj/item/organ/external/lfoot = organs_by_name[BP_L_FOOT]
. += limb_check(lfoot)
/**
* Updates the glide size of a mob attempting to travel in a specific direction.
* Also returns the new glide size.
*/
/atom/movable/proc/recalculate_glide_size(var/old_move_delay, var/move_delay, var/direction)
var/new_glide_size = glide_size
if(old_move_delay + world.tick_lag > world.time)
new_glide_size = DELAY_TO_GLIDE_SIZE((move_delay - old_move_delay) * ( (NSCOMPONENT(direction) && EWCOMPONENT(direction)) ? sqrt(2) : 1 ) )
else
new_glide_size = DELAY_TO_GLIDE_SIZE((move_delay - world.time) * ( (NSCOMPONENT(direction) && EWCOMPONENT(direction)) ? sqrt(2) : 1 ) )
set_glide_size(new_glide_size) // set it now in case of pulled objects
return new_glide_size
// Checks status of limb, returns an amount to
/mob/living/carbon/human/proc/limb_check(var/obj/item/organ/external/limb)
if(!limb) // Limb is null, thus missing.
+20
View File
@@ -50,6 +50,26 @@
unattach()
return 0
/// Trains need to recursively recalculate their glide size for all their towed objects.
/obj/vehicle/train/recalculate_glide_size(old_move_delay, move_delay, direction)
var/new_glide_size = glide_size
if(old_move_delay + world.tick_lag > world.time)
new_glide_size = DELAY_TO_GLIDE_SIZE((move_delay - old_move_delay) * ( (NSCOMPONENT(direction) && EWCOMPONENT(direction)) ? sqrt(2) : 1 ) )
else
new_glide_size = DELAY_TO_GLIDE_SIZE((move_delay - world.time) * ( (NSCOMPONENT(direction) && EWCOMPONENT(direction)) ? sqrt(2) : 1 ) )
recurse_glide_size(new_glide_size) // set it now in case of pulled objects
return new_glide_size
/// Sets the glide size of the entire train.
/obj/vehicle/train/proc/recurse_glide_size(var/glide_size)
set_glide_size(glide_size)
if (!tow)
return
tow.recurse_glide_size(glide_size)
/obj/vehicle/train/Collide(atom/Obstacle)
. = ..()
if(!istype(Obstacle, /atom/movable))