From c8fe437d948e9b042d703a5a96be5ee46bb74d2d Mon Sep 17 00:00:00 2001 From: Batrachophreno Date: Sat, 25 Jul 2026 09:00:13 -0400 Subject: [PATCH] Large Cage Bugfixes (#22895) Fixes large cages destroying the universe. changes: - bugfix: "Fixed captured creatures in large animal traps/cages potentially causing runtimes when the cage was placed on tables or racks." - bugfix: "Fixed dragging large animal traps/cages onto tables or racks being treated as the mover trying to step through the trap." --- code/game/objects/items/weapons/traps.dm | 63 +++++++++++++++++++----- code/modules/tables/interactions.dm | 5 ++ html/changelogs/Bat-CageBullshit.yml | 6 +++ 3 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 html/changelogs/Bat-CageBullshit.yml diff --git a/code/game/objects/items/weapons/traps.dm b/code/game/objects/items/weapons/traps.dm index bb185c09d0b..b3dd06f692b 100644 --- a/code/game/objects/items/weapons/traps.dm +++ b/code/game/objects/items/weapons/traps.dm @@ -443,6 +443,9 @@ /// A weakref to the mob currently held inside the trap var/datum/weakref/captured = null + /// TRUE while an entered signal has queued an async capture that has not finished yet. + var/tmp/capture_pending = FALSE + /obj/item/trap/animal/get_trap_examine_text(mob/user, distance, is_adjacent, infix, suffix) . = list() if(captured) @@ -486,10 +489,19 @@ if(!deployed || !anchored) return - if(captured) // just in case but this shouldn't happen + if(captured || capture_pending) // just in case but this shouldn't happen + return + + capture_pending = TRUE + INVOKE_ASYNC(src, PROC_REF(capture_from_entered), arrived) + +/obj/item/trap/animal/proc/capture_from_entered(atom/movable/arrived) + if(!deployed || !anchored || captured || arrived?.loc != loc) + capture_pending = FALSE return capture(arrived) + capture_pending = FALSE /obj/item/trap/animal/proc/capture(var/atom/movable/movable_atom, var/msg = 1) if(!isliving(movable_atom)) @@ -505,9 +517,14 @@ if(capturing_mob.loc != loc) capturing_mob.forceMove(loc) - captured = WEAKREF(capturing_mob) - INVOKE_ASYNC(src, PROC_REF(buckle), capturing_mob) + var/old_layer = layer layer = capturing_mob.layer + 0.1 + if(!buckle(capturing_mob)) + layer = old_layer + unbuckle() + return + + captured = WEAKREF(capturing_mob) playsound(src, 'sound/weapons/beartrap_shut.ogg', 100, 1) @@ -735,18 +752,32 @@ else ..() +/// Split behavior into its own proc because the original behavior only used to work on Move(), not forceMove(). +/obj/item/trap/animal/proc/sync_captured_mob() + if(!captured) + return + + var/datum/M = captured.resolve() + if(!isliving(M)) + captured = null + return + + var/mob/living/L = M + if(buckled == L && L.buckled_to == src) + if(L.loc != loc) + L.forceMove(loc) + else + captured = null + /obj/item/trap/animal/Move() . = ..() - if(captured) - var/datum/M = captured.resolve() - if(isliving(M)) - var/mob/living/L = M - if(L && buckled.buckled_to == src) - L.forceMove(loc) - else if(L) - captured = null - else - captured = null + if(.) + sync_captured_mob() + +/obj/item/trap/animal/forceMove(atom/destination) + . = ..() + if(.) + sync_captured_mob() /obj/item/trap/animal/attack_hand(mob/user) if(user.loc == src || captured) @@ -771,6 +802,9 @@ user.visible_message("[SPAN_BOLD("[user]")] successfully moves around \the [src] without triggering it.", SPAN_NOTICE("You successfully move around \the [src] without triggering it.")) /obj/item/trap/animal/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + if(over != user) + return ..() + if(!isliving(user) || !src.Adjacent(user)) return @@ -894,6 +928,9 @@ ..() /obj/item/trap/animal/large/mouse_drop_dragged(atom/over, mob/user, src_location, over_location, params) + if(over != user) + return ..() + if(captured) to_chat(user, SPAN_WARNING("The trap door's down, you can't get through there!")) return diff --git a/code/modules/tables/interactions.dm b/code/modules/tables/interactions.dm index 0da8dcf159e..b4b2a8b70c5 100644 --- a/code/modules/tables/interactions.dm +++ b/code/modules/tables/interactions.dm @@ -66,6 +66,11 @@ /obj/structure/table/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) SIGNAL_HANDLER + if(isliving(arrived)) + var/mob/living/L = arrived + if(L.buckled_to) + return + if(ishuman(arrived)) var/mob/living/carbon/human/H = arrived if(H.a_intent != I_HELP || H.m_intent == M_RUN) diff --git a/html/changelogs/Bat-CageBullshit.yml b/html/changelogs/Bat-CageBullshit.yml new file mode 100644 index 00000000000..1d8c5c1c00d --- /dev/null +++ b/html/changelogs/Bat-CageBullshit.yml @@ -0,0 +1,6 @@ +author: Batrachophrenoboocosmomachia +delete-after: True +changes: + - bugfix: "Fixed captured creatures in large animal traps/cages potentially causing runtimes when the cage was placed on tables." + - bugfix: "Fixed dragging large animal traps/cages onto tables being treated as the mover trying to step through the trap." + - bugfix: "Fixed captured creatures not following large animal traps/cages when the cage was dragged onto tables."