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
🆑 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.
/🆑

---------

Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
This commit is contained in:
Bangle
2026-01-17 16:50:04 -08:00
committed by GitHub
co-authored by LT3
parent 12b3869b08
commit 0de30be7df
3 changed files with 65 additions and 22 deletions
@@ -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
@@ -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))
@@ -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