diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 0d060d3784c..f8a20b9f64f 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -2,6 +2,7 @@
icon = 'icons/obj/structures.dmi'
pressure_resistance = 8
var/climb_time = 20
+ var/climb_stun = 2
var/climbable = FALSE
var/mob/structureclimber
@@ -77,18 +78,18 @@
src.add_fingerprint(user)
user.visible_message("[user] starts climbing onto [src].", \
"You start climbing onto [src]...")
- var/climb_time = 20
+ var/adjusted_climb_time = climb_time
if(user.restrained()) //climbing takes twice as long when restrained.
- climb_time *= 2
+ adjusted_climb_time *= 2
structureclimber = user
- if(do_mob(user, user, climb_time))
+ if(do_mob(user, user, adjusted_climb_time))
if(src.loc) //Checking if structure has been destroyed
density = 0
if(step(user,get_dir(user,src.loc)))
user.visible_message("[user] climbs onto [src].", \
"You climb onto [src].")
add_logs(user, src, "climbed onto")
- user.Stun(2)
+ user.Stun(climb_stun)
else
user << "You fail to climb onto [src]."
density = 1
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 3b70fd76585..7e8b4e1d20c 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -20,6 +20,7 @@
var/horizontal = FALSE
var/allow_objects = FALSE
var/allow_dense = FALSE
+ var/dense_when_open = FALSE //if it's dense when open or not
var/max_mob_size = MOB_SIZE_HUMAN //Biggest mob_size accepted by the container
var/mob_storage_capacity = 3 // how many human sized mob/living can fit together inside a closet.
var/storage_capacity = 30 //This is so that someone can't pack hundreds of items in a locker/crate then open it in a populated area to crash clients.
@@ -81,15 +82,27 @@
return 1
return !density
-/obj/structure/closet/proc/can_open()
+/obj/structure/closet/proc/can_open(mob/living/user)
if(welded || locked)
return 0
+ var/turf/T = get_turf(src)
+ for(var/mob/living/L in T)
+ if(horizontal && L.mob_size > MOB_SIZE_TINY)
+ if(user)
+ user << "There's something large on top of [src], preventing it from opening." //you... think? there's something standing on it ffs
+ return 0
return 1
-/obj/structure/closet/proc/can_close()
- for(var/obj/structure/closet/closet in get_turf(src))
+/obj/structure/closet/proc/can_close(mob/living/user)
+ var/turf/T = get_turf(src)
+ for(var/obj/structure/closet/closet in T)
if(closet != src && !closet.wall_mounted)
return 0
+ for(var/mob/living/L in T)
+ if(horizontal && L.mob_size > MOB_SIZE_TINY && !L.lying)
+ if(user)
+ user << "There's something large in [src], preventing it from closing."
+ return 0
return 1
/obj/structure/closet/proc/dump_contents()
@@ -107,12 +120,14 @@
if(insert(AM) == -1) // limit reached
break
-/obj/structure/closet/proc/open()
- if(opened || !can_open())
+/obj/structure/closet/proc/open(mob/living/user)
+ if(opened || !can_open(user))
return
playsound(loc, open_sound, 15, 1, -3)
opened = 1
- density = 0
+ if(!dense_when_open)
+ density = 0
+ climb_time *= 0.5 //it's faster to climb onto an open thing
dump_contents()
update_icon()
return 1
@@ -154,21 +169,22 @@
return 1
-/obj/structure/closet/proc/close()
- if(!opened || !can_close())
+/obj/structure/closet/proc/close(mob/living/user)
+ if(!opened || !can_close(user))
return 0
take_contents()
playsound(loc, close_sound, 15, 1, -3)
+ climb_time = initial(climb_time)
opened = 0
density = 1
update_icon()
return 1
-/obj/structure/closet/proc/toggle()
+/obj/structure/closet/proc/toggle(mob/living/user)
if(opened)
- return close()
+ return close(user)
else
- return open()
+ return open(user)
/obj/structure/closet/ex_act(severity, target)
contents_explosion(severity, target)
@@ -245,26 +261,29 @@
return
if(!Adjacent(user) || !user.Adjacent(O))
return
+ if(user == O) //try to climb onto it
+ return ..()
if(!opened || istype(O, /obj/structure/closet))
return
- if(user == O)
- return
-
var/list/targets = list(O, src)
add_fingerprint(user)
- user.visible_message("[user] tries to stuff [O] into [src].", \
- "You try to stuff [O] into [src].", \
+ var/mob/living/L = O
+ var/actuallyismob = istype(L)
+ user.visible_message("[user] [actuallyismob ? "tries to ":""]stuff [O] into [src].", \
+ "You [actuallyismob ? "try to ":""]stuff [O] into [src].", \
"You hear clanging.")
- if(do_after_mob(user, targets, 40))
- user.visible_message("[user] stuffs [O] into [src].", \
- "You stuff [O] into [src].", \
- "You hear a loud metal bang.")
- var/mob/living/L = O
- if(istype(L) && !issilicon(L))
- L.Weaken(2)
- O.loc = src.loc
- close()
+ if(actuallyismob)
+ if(do_after_mob(user, targets, 40))
+ user.visible_message("[user] stuffs [O] into [src].", \
+ "You stuff [O] into [src].", \
+ "You hear a loud metal bang.")
+ if(!issilicon(L))
+ L.Weaken(2)
+ O.forceMove(get_turf(src))
+ close()
+ else
+ O.forceMove(get_turf(src))
return 1
/obj/structure/closet/relaymove(mob/user)
@@ -280,11 +299,11 @@
M.show_message("BANG, bang!", 2)
/obj/structure/closet/attack_hand(mob/user)
- add_fingerprint(user)
+ ..()
if(user.lying && get_dist(src, user) > 0)
return
- if(!toggle())
+ if(!toggle(user))
togglelock(user)
return
@@ -310,7 +329,8 @@
// should be independently resolved, but this is also an interesting twist.
/obj/structure/closet/Exit(atom/movable/AM)
open()
- if(AM.loc == src) return 0
+ if(AM.loc == src)
+ return 0
return 1
/obj/structure/closet/container_resist(mob/living/user)
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index af8cfb1f9ef..5dae69433ab 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -8,12 +8,26 @@
horizontal = TRUE
allow_objects = TRUE
allow_dense = TRUE
+ dense_when_open = TRUE
+ climbable = TRUE
+ climb_time = 10 //real fast, because let's be honest stepping into or onto a crate is easy
+ climb_stun = 0 //climbing onto crates isn't hard, guys
var/obj/item/weapon/paper/manifest/manifest
/obj/structure/closet/crate/New()
..()
update_icon()
+/obj/structure/closet/crate/CanPass(atom/movable/mover, turf/target, height=0)
+ if(!istype(mover, /obj/structure/closet))
+ var/obj/structure/closet/crate/locatedcrate = locate(/obj/structure/closet/crate) in get_turf(mover)
+ if(locatedcrate) //you can walk on it like tables, if you're not in an open crate trying to move to a closed crate
+ if(opened) //if we're open, allow entering regardless of located crate openness
+ return 1
+ if(!locatedcrate.opened) //otherwise, if the located crate is closed, allow entering
+ return 1
+ return !density
+
/obj/structure/closet/crate/update_icon()
icon_state = "[initial(icon_state)][opened ? "open" : ""]"
@@ -22,12 +36,10 @@
overlays += "manifest"
/obj/structure/closet/crate/attack_hand(mob/user)
- add_fingerprint(user)
if(manifest)
tear_manifest(user)
return
- if(!toggle())
- togglelock(user)
+ ..()
/obj/structure/closet/crate/proc/tear_manifest(mob/user)
user << "You tear the manifest off of the crate."