diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 1dc8336ae6..e3b9b18840 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -9,18 +9,26 @@
var/icon_closed = "closed"
var/icon_opened = "open"
var/opened = 0
- var/welded = 0
+ var/sealed = 0
+ var/seal_tool = /obj/item/weapon/weldingtool //Tool used to seal the closet, defaults to welder
var/wall_mounted = 0 //never solid (You can always pass over it)
var/health = 100
+
var/breakout = 0 //if someone is currently breaking out. mutex
+ var/breakout_time = 2 //2 minutes by default
+ var/breakout_sound = 'sound/effects/grillehit.ogg' //Sound that plays while breaking out
+
var/storage_capacity = 2 * MOB_MEDIUM //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.
+ var/storage_cost = 40 //How much space this closet takes up if it's stuffed in another closet
+
var/open_sound = 'sound/machines/click.ogg'
var/close_sound = 'sound/machines/click.ogg'
- var/store_misc = 1
- var/store_items = 1
- var/store_mobs = 1
+ var/store_misc = 1 //Chameleon item check
+ var/store_items = 1 //Will the closet store items?
+ var/store_mobs = 1 //Will the closet store mobs?
+ var/max_closets = 0 //Number of other closets allowed on tile before it won't close.
var/list/starts_with
@@ -41,7 +49,7 @@
content_size += Ceiling(I.w_class/2)
if(content_size > storage_capacity-5)
storage_capacity = content_size + 5
-
+ update_icon()
/obj/structure/closet/examine(mob/user)
if(..(user, 1) && !opened)
@@ -50,29 +58,33 @@
if(!I.anchored)
content_size += Ceiling(I.w_class/2)
if(!content_size)
- user << "It is empty."
+ to_chat(user, "It is empty.")
else if(storage_capacity > content_size*4)
- user << "It is barely filled."
+ to_chat(user, "It is barely filled.")
else if(storage_capacity > content_size*2)
- user << "It is less than half full."
+ to_chat(user, "It is less than half full.")
else if(storage_capacity > content_size)
- user << "There is still some free space."
+ to_chat(user, "There is still some free space.")
else
- user << "It is full."
+ to_chat(user, "It is full.")
/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(air_group || (height==0 || wall_mounted)) return 1
return (!density)
/obj/structure/closet/proc/can_open()
- if(src.welded)
+ if(src.sealed)
return 0
return 1
/obj/structure/closet/proc/can_close()
+ var/closet_count = 0
for(var/obj/structure/closet/closet in get_turf(src))
if(closet != src)
- return 0
+ if(!closet.anchored)
+ closet_count ++
+ if(closet_count > max_closets)
+ return 0
return 1
/obj/structure/closet/proc/dump_contents()
@@ -101,7 +113,7 @@
src.icon_state = src.icon_opened
src.opened = 1
playsound(src.loc, open_sound, 15, 1, -3)
- density = 0
+ density = !density
return 1
/obj/structure/closet/proc/close()
@@ -118,12 +130,14 @@
stored_units += store_items(stored_units)
if(store_mobs)
stored_units += store_mobs(stored_units)
+ if(max_closets)
+ stored_units += store_closets(stored_units)
src.icon_state = src.icon_closed
src.opened = 0
playsound(src.loc, close_sound, 15, 1, -3)
- density = 1
+ density = !density
return 1
//Cham Projector Exception
@@ -161,9 +175,25 @@
added_units += M.mob_size
return added_units
+/obj/structure/closet/proc/store_closets(var/stored_units)
+ var/added_units = 0
+ for(var/obj/structure/closet/C in src.loc)
+ if(C == src) //Don't store ourself
+ continue
+ if(C.anchored) //Don't worry about anchored things on the same tile
+ continue
+ if(C.max_closets) //Prevents recursive storage
+ continue
+ if(stored_units + added_units + storage_cost > storage_capacity)
+ break
+ C.forceMove(src)
+ added_units += storage_cost
+ return added_units
+
+
/obj/structure/closet/proc/toggle(mob/user as mob)
if(!(src.opened ? src.close() : src.open()))
- user << "It won't budge!"
+ to_chat(user, "It won't budge!")
return
update_icon()
@@ -221,7 +251,7 @@
if(!WT.isOn())
return
else
- user << "You need more welding fuel to complete this task."
+ to_chat(user, "You need more welding fuel to complete this task.")
return
playsound(src, WT.usesound, 50)
new /obj/item/stack/material/steel(src.loc)
@@ -247,21 +277,25 @@
W.forceMove(src.loc)
else if(istype(W, /obj/item/weapon/packageWrap))
return
- else if(istype(W, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = W
- if(!WT.remove_fuel(0,user))
- if(!WT.isOn())
- return
- else
- user << "You need more welding fuel to complete this task."
- return
- playsound(src, WT.usesound, 50)
- src.welded = !src.welded
- src.update_icon()
- for(var/mob/M in viewers(src))
- M.show_message("[src] has been [welded?"welded shut":"unwelded"] by [user.name].", 3, "You hear welding.", 2)
+ else if(seal_tool)
+ if(istype(W, seal_tool))
+ var/obj/item/weapon/S = W
+ if(istype(S, /obj/item/weapon/weldingtool))
+ var/obj/item/weapon/weldingtool/WT = S
+ if(!WT.remove_fuel(0,user))
+ if(!WT.isOn())
+ return
+ else
+ to_chat(user, "You need more welding fuel to complete this task.")
+ return
+ if(do_after(user, 20 * S.toolspeed))
+ playsound(src, S.usesound, 50)
+ src.sealed = !src.sealed
+ src.update_icon()
+ for(var/mob/M in viewers(src))
+ M.show_message("[src] has been [sealed?"sealed":"unsealed"] by [user.name].", 3)
else if(W.is_wrench())
- if(welded)
+ if(sealed)
if(anchored)
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
else
@@ -269,7 +303,7 @@
playsound(src, W.usesound, 50)
if(do_after(user, 20 * W.toolspeed))
if(!src) return
- user << "You [anchored? "un" : ""]secured \the [src]!"
+ to_chat(user, "You [anchored? "un" : ""]secured \the [src]!")
anchored = !anchored
else
src.attack_hand(user)
@@ -305,7 +339,7 @@
return
if(!src.open())
- user << "It won't budge!"
+ to_chat(user, "It won't budge!")
/obj/structure/closet/attack_hand(mob/user as mob)
src.add_fingerprint(user)
@@ -315,7 +349,7 @@
/obj/structure/closet/attack_self_tk(mob/user as mob)
src.add_fingerprint(user)
if(!src.toggle())
- usr << "It won't budge!"
+ to_chat(usr, "It won't budge!")
/obj/structure/closet/attack_ghost(mob/ghost)
if(ghost.client && ghost.client.inquisitive_ghost)
@@ -335,14 +369,14 @@
src.add_fingerprint(usr)
src.toggle(usr)
else
- usr << "This mob type can't use this verb."
+ to_chat(usr, "This mob type can't use this verb.")
-/obj/structure/closet/update_icon()//Putting the welded stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
+/obj/structure/closet/update_icon()//Putting the sealed stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
overlays.Cut()
if(!opened)
icon_state = icon_closed
- if(welded)
- overlays += "welded"
+ if(sealed)
+ overlays += "sealed"
else
icon_state = icon_opened
@@ -358,20 +392,19 @@
/obj/structure/closet/proc/req_breakout()
if(opened)
return 0 //Door's open... wait, why are you in it's contents then?
- if(!welded)
- return 0 //closed but not welded...
+ if(!sealed)
+ return 0 //closed but not sealed...
return 1
/obj/structure/closet/proc/mob_breakout(var/mob/living/escapee)
- var/breakout_time = 2 //2 minutes by default
if(breakout || !req_breakout())
return
escapee.setClickCooldown(100)
- //okay, so the closet is either welded or locked... resist!!!
- escapee << "You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)"
+ //okay, so the closet is either sealed or locked... resist!!!
+ to_chat(escapee, "You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)")
visible_message("\The [src] begins to shake violently!")
@@ -388,20 +421,20 @@
breakout = 0
return
- playsound(src.loc, 'sound/effects/grillehit.ogg', 100, 1)
+ playsound(src.loc, breakout_sound, 100, 1)
animate_shake()
add_fingerprint(escapee)
//Well then break it!
breakout = 0
- escapee << "You successfully break out!"
+ to_chat(escapee, "You successfully break out!")
visible_message("\The [escapee] successfully broke out of \the [src]!")
- playsound(src.loc, 'sound/effects/grillehit.ogg', 100, 1)
+ playsound(src.loc, breakout_sound, 100, 1)
break_open()
animate_shake()
/obj/structure/closet/proc/break_open()
- welded = 0
+ sealed = 0
update_icon()
//Do this to prevent contents from being opened into nullspace (read: bluespace)
if(istype(loc, /obj/structure/bigDelivery))
@@ -420,3 +453,9 @@
/obj/structure/closet/AllowDrop()
return TRUE
+
+/obj/structure/closet/return_air_for_internal_lifeform(var/mob/living/L)
+ if(src.loc)
+ if(istype(src.loc, /obj/structure/closet))
+ return (loc.return_air_for_internal_lifeform(L))
+ return return_air()
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets/coffin.dm b/code/game/objects/structures/crates_lockers/closets/coffin.dm
index 67de5d38b9..6d5df80ed8 100644
--- a/code/game/objects/structures/crates_lockers/closets/coffin.dm
+++ b/code/game/objects/structures/crates_lockers/closets/coffin.dm
@@ -4,9 +4,161 @@
icon_state = "coffin"
icon_closed = "coffin"
icon_opened = "coffin_open"
+ seal_tool = /obj/item/weapon/tool/screwdriver
+ breakout_sound = 'sound/weapons/tablehit1.ogg'
/obj/structure/closet/coffin/update_icon()
if(!opened)
icon_state = icon_closed
else
icon_state = icon_opened
+
+/* Graves */
+/obj/structure/closet/grave
+ name = "grave"
+ desc = "Dirt."
+ icon_state = "grave"
+ icon_closed = "grave"
+ icon_opened = "grave_open"
+ seal_tool = null
+ breakout_sound = 'sound/weapons/thudswoosh.ogg'
+ anchored = 1
+ max_closets = 1
+ opened = 1
+
+/obj/structure/closet/grave/attack_hand(mob/user as mob)
+ if(opened)
+ visible_message("[user] starts to climb into \the [src.name].", \
+ "You start to lower yourself into \the [src.name].")
+ if(do_after(user, 50))
+ user.forceMove(src.loc)
+ visible_message("[user] climbs into \the [src.name].", \
+ "You climb into \the [src.name].")
+ else
+ visible_message("[user] decides not to climb into \the [src.name].", \
+ "You stop climbing into \the [src.name].")
+ return
+
+/obj/structure/closet/grave/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(opened && ismob(mover))
+ var/mob/M = mover
+ add_fingerprint(M)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H.m_intent == "walk")
+ to_chat(H, "You stop at the edge of \the [src.name].")
+ return FALSE
+ else
+ to_chat(H, "You fall into \the [src.name]!")
+ fall_in(H)
+ return TRUE
+ if(isrobot(M))
+ var/mob/living/silicon/robot/R = M
+ if(R.a_intent == I_HELP)
+ to_chat(R, "You stop at the edge of \the [src.name].")
+ return FALSE
+ else
+ to_chat(R, "You enter \the [src.name].")
+ return TRUE
+ return TRUE //Everything else can move over the graves
+
+/obj/structure/closet/grave/proc/fall_in(mob/living/L) //Only called on humans for now, but still
+ L.Weaken(5)
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ var/limb_damage = rand(5,25)
+ H.adjustBruteLoss(limb_damage)
+
+/obj/structure/closet/grave/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(src.opened)
+ if(istype(W, /obj/item/weapon/shovel))
+ user.visible_message("[user] piles dirt into \the [src.name].", \
+ "You start to pile dirt into \the [src.name].", \
+ "You hear dirt being moved.")
+ if(do_after(user, 40 * W.toolspeed))
+ user.visible_message("[user] pats down the dirt on top of \the [src.name].", \
+ "You finish filling in \the [src.name].")
+ close()
+ return
+ else
+ user.visible_message("[user] stops filling in \the [src.name].", \
+ "You change your mind and stop filling in \the [src.name].")
+ return
+ if(istype(W, /obj/item/weapon/grab))
+ var/obj/item/weapon/grab/G = W
+ src.MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
+ return 0
+ if(istype(W,/obj/item/tk_grab))
+ return 0
+ if(istype(W, /obj/item/weapon/storage/laundry_basket) && W.contents.len)
+ var/obj/item/weapon/storage/laundry_basket/LB = W
+ var/turf/T = get_turf(src)
+ for(var/obj/item/I in LB.contents)
+ LB.remove_from_storage(I, T)
+ user.visible_message("[user] empties \the [LB] into \the [src].", \
+ "You empty \the [LB] into \the [src].", \
+ "You hear rustling of clothes.")
+ return
+ if(isrobot(user))
+ return
+ if(W.loc != user) // This should stop mounted modules ending up outside the module.
+ return
+ usr.drop_item()
+ if(W)
+ W.forceMove(src.loc)
+ else
+ if(istype(W, /obj/item/weapon/shovel))
+ if(user.a_intent == I_HURT) // Hurt intent means you're trying to kill someone, or just get rid of the grave
+ user.visible_message("[user] begins to smoothe out the dirt of \the [src.name].", \
+ "You start to smoothe out the dirt of \the [src.name].", \
+ "You hear dirt being moved.")
+ if(do_after(user, 40 * W.toolspeed))
+ user.visible_message("[user] finishes smoothing out \the [src.name].", \
+ "You finish smoothing out \the [src.name].")
+ if(LAZYLEN(contents))
+ alpha = 40 // If we've got stuff inside, like maybe a person, just make it hard to see us
+ else
+ qdel(src) // Else, go away
+ return
+ else
+ user.visible_message("[user] stops concealing \the [src.name].", \
+ "You stop concealing \the [src.name].")
+ return
+ else
+ user.visible_message("[user] begins to unearth \the [src.name].", \
+ "You start to unearth \the [src.name].", \
+ "You hear dirt being moved.")
+ if(do_after(user, 40 * W.toolspeed))
+ user.visible_message("[user] reaches the bottom of \the [src.name].", \
+ "You finish digging out \the [src.name].")
+ break_open()
+ return
+ else
+ user.visible_message("[user] stops digging out \the [src.name].", \
+ "You stop digging out \the [src.name].")
+ return
+ return
+
+/obj/structure/closet/grave/close()
+ ..()
+ if(!opened)
+ sealed = TRUE
+
+/obj/structure/closet/grave/open()
+ .=..()
+ alpha = 255 // Needed because of grave hiding
+
+/obj/structure/closet/grave/bullet_act(var/obj/item/projectile/P)
+ return PROJECTILE_CONTINUE // It's a hole in the ground, doesn't usually stop or even care about bullets
+
+/obj/structure/closet/grave/return_air_for_internal_lifeform(var/mob/living/L)
+ var/gasid = "carbon_dioxide"
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ if(H.species && H.species.exhale_type)
+ gasid = H.species.exhale_type
+ var/datum/gas_mixture/grave_breath = new()
+ var/datum/gas_mixture/above_air = return_air()
+ grave_breath.adjust_gas(gasid, BREATH_MOLES)
+ grave_breath.temperature = (above_air.temperature) - 30 //Underground
+ return grave_breath
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm b/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm
index c606151550..62497919fc 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/guncabinet.dm
@@ -43,8 +43,8 @@
overlays += icon(src.icon, "door")
- if(welded)
- overlays += icon(src.icon,"welded")
+ if(sealed)
+ overlays += icon(src.icon,"sealed")
if(broken)
overlays += icon(src.icon,"broken")
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
index 994fe0eca1..af07ceb9e5 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm
@@ -46,23 +46,23 @@
/obj/structure/closet/secure_closet/proc/togglelock(mob/user as mob)
if(src.opened)
- user << "Close the locker first."
+ to_chat(user, "Close the locker first.")
return
if(src.broken)
- user << "The locker appears to be broken."
+ to_chat(user, "The locker appears to be broken.")
return
if(user.loc == src)
- user << "You can't reach the lock from inside."
+ to_chat(user, "You can't reach the lock from inside.")
return
if(src.allowed(user))
src.locked = !src.locked
playsound(src.loc, 'sound/machines/click.ogg', 15, 1, -3)
for(var/mob/O in viewers(user, 3))
if((O.client && !( O.blinded )))
- O << "The locker has been [locked ? null : "un"]locked by [user]."
+ to_chat(O, "The locker has been [locked ? null : "un"]locked by [user].")
update_icon()
else
- user << "Access Denied"
+ to_chat(user, "Access Denied")
/obj/structure/closet/secure_closet/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(src.opened)
@@ -73,7 +73,7 @@
if(src.large)
src.MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
else
- user << "The locker is too small to stuff [G.affecting] into!"
+ to_chat(user, "The locker is too small to stuff [G.affecting] into!")
if(isrobot(user))
return
if(W.loc != user) // This should stop mounted modules ending up outside the module.
@@ -89,14 +89,14 @@
playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1)
playsound(src.loc, "sparks", 50, 1)
else if(W.is_wrench())
- if(welded)
+ if(sealed)
if(anchored)
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
else
user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
if(do_after(user, 20 * W.toolspeed))
if(!src) return
- user << "You [anchored? "un" : ""]secured \the [src]!"
+ to_chat(user, "You [anchored? "un" : ""]secured \the [src]!")
anchored = !anchored
return
else if(istype(W,/obj/item/weapon/packageWrap) || istype(W,/obj/item/weapon/weldingtool))
@@ -143,9 +143,9 @@
src.add_fingerprint(usr)
src.togglelock(usr)
else
- usr << "This mob type can't use this verb."
+ to_chat(usr, "This mob type can't use this verb.")
-/obj/structure/closet/secure_closet/update_icon()//Putting the welded stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
+/obj/structure/closet/secure_closet/update_icon()//Putting the sealed stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
overlays.Cut()
if(!opened)
@@ -155,8 +155,8 @@
icon_state = icon_locked
else
icon_state = icon_closed
- if(welded)
- overlays += "welded"
+ if(sealed)
+ overlays += "sealed"
else
icon_state = icon_opened
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index ddedd18b18..389209e52c 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -380,7 +380,7 @@
//Resisting out of closets
if(istype(loc,/obj/structure/closet))
var/obj/structure/closet/C = loc
- if(C.welded)
+ if(C.sealed)
handle_resist()
else
C.open()
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index 64f5b923ab..59b690f31a 100755
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -284,7 +284,7 @@
if (src.amount > 3 && !O.opened)
var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc))
P.wrapped = O
- O.welded = 1
+ O.sealed = 1
O.loc = P
src.amount -= 3
user.visible_message("\The [user] wraps \a [target] with \a [src].",\
@@ -311,7 +311,7 @@
wrapped.forceMove(get_turf(src))
if(istype(wrapped, /obj/structure/closet))
var/obj/structure/closet/O = wrapped
- O.welded = 0
+ O.sealed = 0
wrapped = null
var/turf/T = get_turf(src)
for(var/atom/movable/AM in contents)
diff --git a/html/changelogs/Anewbe - Graves.yml b/html/changelogs/Anewbe - Graves.yml
new file mode 100644
index 0000000000..fd7b71a680
--- /dev/null
+++ b/html/changelogs/Anewbe - Graves.yml
@@ -0,0 +1,36 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Anewbe
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Graves are now a thing in the code, will need some testing and probably more work before they get more common."
\ No newline at end of file
diff --git a/icons/obj/closet.dmi b/icons/obj/closet.dmi
index 5fd95e85d7..80fb1712be 100644
Binary files a/icons/obj/closet.dmi and b/icons/obj/closet.dmi differ