diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 9f86412101b..ffaef501f36 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -8,7 +8,7 @@
var/climbable
/// Determines if a structure adds the TRAIT_TURF_COVERED to its turf.
var/creates_cover = FALSE
- var/mob/living/climber
+ var/list/mob/living/climbers = list()
var/broken = FALSE
/// How long this takes to unbuckle yourself from.
var/unbuckle_time = 0 SECONDS
@@ -32,6 +32,7 @@
return ..()
/obj/structure/Destroy()
+ climbers = null
if(SSticker)
GLOB.cameranet.updateVisibility(src)
if(smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
@@ -58,7 +59,7 @@
if(..())
return TRUE
if(C == user)
- INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/structure, do_climb), user)
+ INVOKE_ASYNC(src, TYPE_PROC_REF(/obj/structure, start_climb), user)
return TRUE
/obj/structure/proc/density_check()
@@ -93,12 +94,25 @@
if(!can_touch(user) || !climbable)
return FALSE
- user.forceMove(get_turf(src))
- if(get_turf(user) == get_turf(src))
+ return TRUE
+
+/obj/structure/proc/start_climb(mob/living/user)
+ climbers += user
+ RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(remove_climber)) // Just in case the climber is deleted before finishing
+ if(do_climb(user))
+ user.forceMove(get_turf(src))
if(HAS_MIND_TRAIT(user, TRAIT_TABLE_LEAP))
user.visible_message("[user] leaps up onto [src]!")
else
user.visible_message("[user] climbs onto [src]!")
+ climbers -= user
+ UnregisterSignal(user, COMSIG_PARENT_QDELETING)
+
+/obj/structure/proc/remove_climber(mob/living/climber)
+ SIGNAL_HANDLER // COMSIG_PARENT_QDELETING
+
+ climbers -= climber
+ UnregisterSignal(climber, COMSIG_PARENT_QDELETING)
/obj/structure/proc/structure_shaken()
for(var/mob/living/M in get_turf(src))
diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm
index 437fa7ddc6e..4be0439ea3d 100644
--- a/code/game/objects/structures/railings.dm
+++ b/code/game/objects/structures/railings.dm
@@ -165,7 +165,7 @@
return TRUE
return FALSE
-/obj/structure/railing/do_climb(mob/living/user)
+/obj/structure/railing/start_climb(mob/living/user)
var/initial_mob_loc = get_turf(user)
. = ..()
if(.)
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index 6556a100f30..22287c20f7b 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -103,15 +103,16 @@
new /obj/structure/table/wood(loc)
qdel(src)
-/obj/structure/table/do_climb(mob/living/user)
+/obj/structure/table/start_climb(mob/living/user)
. = ..()
item_placed(user)
/obj/structure/table/attack_hand(mob/living/user)
..()
- if(climber)
- climber.Weaken(4 SECONDS)
- climber.visible_message("[climber.name] has been knocked off the table", "You've been knocked off the table", "You hear [climber.name] get knocked off the table")
+ if(length(climbers))
+ for(var/mob/living/climber as anything in climbers)
+ climber.Weaken(4 SECONDS)
+ climber.visible_message("[climber.name] has been knocked off the table", "You've been knocked off the table", "You hear [climber.name] get knocked off the table")
else if(Adjacent(user) && user.pulling && user.pulling.pass_flags & PASSTABLE)
user.Move_Pulled(src)
if(user.pulling.loc == loc)