From 0de30be7df0abbf76c3dd3c3b488b6a98a089092 Mon Sep 17 00:00:00 2001 From: Bangle <140950607+Offwrldr@users.noreply.github.com> Date: Sat, 17 Jan 2026 19:50:04 -0500 Subject: [PATCH] My 600-lb Hotfixes: How I Learned to Love Bugfixing (#5135) ## About The Pull Request Fix for teleportation glitch with mounting tables. Fix for diagonal seating movement exploit. Added more conditions to re-render 1x sprite, involving equippables being changed and other such things. It's not perfect, but it's _much better_ now. ## Why It's Good For The Game Because players should not teleport during shuttle rides. ## Proof Of Testing https://github.com/user-attachments/assets/b2fd15bf-32ea-4ab8-9440-ec646509de6b Tested and verified no further teleportation issues, no diag movement glitches and more re-renders. This should be merged ASAP to fix/prevent exploits. ## Changelog :cl: Bangle qol: Further updates to lil' guy rendering, more conditions will proc re-render, swapping hands, dropping things, etc. fix: Fixed oversized teleportation. You can now ride shuttles without being teleported back to your original location of mounting. /:cl: --------- Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com> --- .../datums/actions/oversized_self_view.dm | 23 ++++++++++- .../code/datums/elements/climbable.dm | 23 +++++++---- .../game/objects/structures/tables_racks.dm | 41 +++++++++++++------ 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/modular_zubbers/code/datums/actions/oversized_self_view.dm b/modular_zubbers/code/datums/actions/oversized_self_view.dm index 8df53386940..c69a93a20ab 100644 --- a/modular_zubbers/code/datums/actions/oversized_self_view.dm +++ b/modular_zubbers/code/datums/actions/oversized_self_view.dm @@ -51,6 +51,12 @@ // Register signals to update when needed RegisterSignal(human_owner, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_z_change)) RegisterSignal(human_owner, COMSIG_ATOM_POST_DIR_CHANGE, PROC_REF(on_dir_change)) + RegisterSignal(human_owner, COMSIG_ATOM_UPDATED_ICON, PROC_REF(on_appearance_update)) + RegisterSignal(human_owner, COMSIG_MOB_EQUIPPED_ITEM, PROC_REF(on_appearance_update)) + RegisterSignal(human_owner, COMSIG_MOB_UNEQUIPPED_ITEM, PROC_REF(on_appearance_update)) + RegisterSignal(human_owner, COMSIG_MOB_DROPPED_ITEM, PROC_REF(on_appearance_update)) + RegisterSignal(human_owner, COMSIG_LIVING_PICKED_UP_ITEM, PROC_REF(on_appearance_update)) + RegisterSignal(human_owner, COMSIG_MOB_SWAP_HANDS, PROC_REF(on_appearance_update)) active = TRUE to_chat(human_owner, span_notice("You now see yourself at normal size.")) @@ -65,7 +71,13 @@ UnregisterSignal(human_owner, list( COMSIG_MOVABLE_Z_CHANGED, - COMSIG_ATOM_POST_DIR_CHANGE + COMSIG_ATOM_POST_DIR_CHANGE, + COMSIG_ATOM_UPDATED_ICON, + COMSIG_MOB_EQUIPPED_ITEM, + COMSIG_MOB_UNEQUIPPED_ITEM, + COMSIG_MOB_DROPPED_ITEM, + COMSIG_LIVING_PICKED_UP_ITEM, + COMSIG_MOB_SWAP_HANDS )) normal_size_image = null @@ -85,6 +97,15 @@ // Update the image to reflect the new direction update_normal_size_image() +/// Updates the overlay when appearance changes (equipment, hands, etc.) +/datum/action/oversized_self_view/proc/on_appearance_update(mob/living/carbon/human/source, ...) + SIGNAL_HANDLER + if(!active || !source.client) + return + + // Update the image to reflect any appearance changes + update_normal_size_image() + /// Creates or updates the normal-size image with proper scaling and foot alignment /datum/action/oversized_self_view/proc/update_normal_size_image() var/mob/living/carbon/human/human_owner = owner diff --git a/modular_zubbers/code/datums/elements/climbable.dm b/modular_zubbers/code/datums/elements/climbable.dm index c0ef4b1de3c..33ef7268345 100644 --- a/modular_zubbers/code/datums/elements/climbable.dm +++ b/modular_zubbers/code/datums/elements/climbable.dm @@ -20,15 +20,15 @@ var/turf/table_turf = get_turf(target_table) var/approach_dir = NORTH // Default fallback - // Store the original turf position so they can return there when standing - LAZYINITLIST(target_table.oversized_sit_original_turfs) - target_table.oversized_sit_original_turfs[user] = user_turf - if(user_turf != table_turf) // User is on a different turf, use direction from table to user approach_dir = get_dir(table_turf, user_turf) - // Convert to closest cardinal direction if diagonal - if(approach_dir & (approach_dir - 1)) // If diagonal + // Only allow mounting from cardinal directions, not diagonals + if(ISDIAGONALDIR(approach_dir)) + to_chat(user, span_warning("You can only sit on [target_table] from the north, south, east, or west side!")) + return + // Convert to closest cardinal direction if not already cardinal (safety check) + if(approach_dir & (approach_dir - 1)) // If diagonal (shouldn't happen after above check, but just in case) // Pick the dominant direction based on distance if(approach_dir & NORTH && approach_dir & EAST) approach_dir = (abs(user_turf.x - table_turf.x) > abs(user_turf.y - table_turf.y)) ? EAST : NORTH @@ -39,11 +39,17 @@ else if(approach_dir & SOUTH && approach_dir & WEST) approach_dir = (abs(user_turf.x - table_turf.x) > abs(user_turf.y - table_turf.y)) ? WEST : SOUTH else if(!(approach_dir in GLOB.cardinals)) - // Fallback to user's facing direction + // Fallback to user's facing direction (must be cardinal) approach_dir = user.dir + if(ISDIAGONALDIR(approach_dir) || !(approach_dir in GLOB.cardinals)) + // If user is facing diagonally or invalid direction, default to NORTH + approach_dir = NORTH else - // User is already on the table turf, use their facing direction + // User is already on the table turf, use their facing direction (must be cardinal) approach_dir = user.dir + if(ISDIAGONALDIR(approach_dir) || !(approach_dir in GLOB.cardinals)) + // If user is facing diagonally or invalid direction, default to NORTH + approach_dir = NORTH // Store the approach direction for post_buckle_mob LAZYINITLIST(target_table.oversized_sit_directions) @@ -56,7 +62,6 @@ if(user.loc != target_table.loc) if(!do_after(user, 1 SECONDS, target_table)) LAZYREMOVE(target_table.oversized_sit_directions, user) - LAZYREMOVE(target_table.oversized_sit_original_turfs, user) return // Move to the table's turf user.forceMove(get_turf(target_table)) diff --git a/modular_zubbers/code/game/objects/structures/tables_racks.dm b/modular_zubbers/code/game/objects/structures/tables_racks.dm index 96384e5690d..f05e3715dfa 100644 --- a/modular_zubbers/code/game/objects/structures/tables_racks.dm +++ b/modular_zubbers/code/game/objects/structures/tables_racks.dm @@ -26,8 +26,6 @@ /// Stores the approach direction for Oversized players sitting on tables /obj/structure/table/var/list/oversized_sit_directions = null -/// Stores the original turf position for Oversized players sitting on tables (so they can return there when standing) -/obj/structure/table/var/list/oversized_sit_original_turfs = null /// Position Oversized players at the edge of the table they approached from /obj/structure/table/post_buckle_mob(mob/living/buckled) @@ -74,7 +72,7 @@ // Face away from the table edge (toward the direction they came from) buckled.setDir(approach_dir) -/// Clean up stored directions and return Oversized players to their original position when unbuckling +/// Clean up stored directions and place Oversized players adjacent to the table when unbuckling /obj/structure/table/post_unbuckle_mob(mob/living/unbuckled) . = ..() // Only handle Oversized players on regular tables @@ -86,18 +84,37 @@ // Remove offsets unbuckled.remove_offsets(type) - // Get the original turf position - var/turf/original_turf = LAZYACCESS(oversized_sit_original_turfs, unbuckled) - if(original_turf && isturf(original_turf)) - // Move them back to their original position - unbuckled.forceMove(original_turf) + // Find the nearest unblocked, maneuverable location adjacent to the table + var/turf/table_turf = get_turf(src) + var/turf/destination_turf = null + + // Try to use the approach direction first, otherwise try all cardinal directions + var/approach_dir = LAZYACCESS(oversized_sit_directions, unbuckled) + var/list/dirs_to_try = list() + if(approach_dir && (approach_dir in GLOB.cardinals)) + dirs_to_try += approach_dir + // Add remaining cardinal directions + for(var/dir in GLOB.cardinals) + if(dir != approach_dir) + dirs_to_try += dir + + // Find the first unblocked, maneuverable turf + for(var/dir in dirs_to_try) + var/turf/test_turf = get_step(table_turf, dir) + if(test_turf && !test_turf.is_blocked_turf(exclude_mobs = FALSE, source_atom = unbuckled)) + destination_turf = test_turf + break + + // If no adjacent turf is available, try the table's own turf as last resort + if(!destination_turf) + if(!table_turf.is_blocked_turf(exclude_mobs = TRUE, source_atom = unbuckled)) + destination_turf = table_turf + + if(destination_turf) + unbuckled.forceMove(destination_turf) // Clean up stored data if(oversized_sit_directions) LAZYREMOVE(oversized_sit_directions, unbuckled) if(!length(oversized_sit_directions)) oversized_sit_directions = null - if(oversized_sit_original_turfs) - LAZYREMOVE(oversized_sit_original_turfs, unbuckled) - if(!length(oversized_sit_original_turfs)) - oversized_sit_original_turfs = null