From 7fc9f27eeb461842d9d38892daf295bcad716c8c Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Fri, 6 Feb 2026 18:24:22 -0500 Subject: [PATCH] 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 --- .../structures/stool_bed_chair_nest/bed.dm | 1 + code/modules/heavy_vehicle/mecha.dm | 2 +- .../mob/living/simple_animal/simple_animal.dm | 2 +- code/modules/mob/mob_movement.dm | 48 ++++++++++++------- code/modules/vehicles/train.dm | 20 ++++++++ config/example/game_options.txt | 15 ++++-- .../hellfirejag-smooth-move-fixes.yml | 8 ++++ 7 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 html/changelogs/hellfirejag-smooth-move-fixes.yml diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index 90461b050f2..0e7c2962650 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -624,6 +624,7 @@ . = ..() if(buckled) if(buckled.buckled_to == src) + buckled.set_glide_size(glide_size) buckled.forceMove(src.loc) else buckled = null diff --git a/code/modules/heavy_vehicle/mecha.dm b/code/modules/heavy_vehicle/mecha.dm index f02841c1886..f88ec5c4d7e 100644 --- a/code/modules/heavy_vehicle/mecha.dm +++ b/code/modules/heavy_vehicle/mecha.dm @@ -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 diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 0f92e9e049a..f592b13f6c2 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -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 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 6c4c63b247b..3bbaa730632 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -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. diff --git a/code/modules/vehicles/train.dm b/code/modules/vehicles/train.dm index de83edb8413..9f47d0dfce5 100644 --- a/code/modules/vehicles/train.dm +++ b/code/modules/vehicles/train.dm @@ -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)) diff --git a/config/example/game_options.txt b/config/example/game_options.txt index 2197515e050..30ee357014c 100644 --- a/config/example/game_options.txt +++ b/config/example/game_options.txt @@ -45,11 +45,18 @@ RUN_DELAY_MULTIPLIER 1 VEHICLE_DELAY_MULTIPLIER 1 ## The variables below affect the movement of specific mob types. +## These are summed with all other delay modifiers to form the "Base" movement delay. + +# All Mob/living/carbon/human HUMAN_DELAY 0 -ROBOT_DELAY 0 -MONKEY_DELAY 0 -ALIEN_DELAY 0 -ANIMAL_DELAY 0 +# Unused +ROBOT_DELAY 1 +# Unused +MONKEY_DELAY 1 +# Unused +ALIEN_DELAY 1 +# All Simple Mobs +ANIMAL_DELAY 1 ### Miscellaneous ### diff --git a/html/changelogs/hellfirejag-smooth-move-fixes.yml b/html/changelogs/hellfirejag-smooth-move-fixes.yml new file mode 100644 index 00000000000..3208e00358d --- /dev/null +++ b/html/changelogs/hellfirejag-smooth-move-fixes.yml @@ -0,0 +1,8 @@ +author: Hellfirejag +delete-after: True +changes: + - bugfix: "Fixed mobs other than humans not moving smoothly." + - bugfix: "Fixed mobs cheating their movement speed on diagonals." + - bugfix: "Fixed smooth movement not working on mechs." + - bugfix: "Fixed smooth movement not working on wheelchairs/rollerbeds/vehicles in general." + - bugfix: "Fixed mobs moving at lightspeed."