diff --git a/baystation12.dme b/baystation12.dme
index 997494b4b05..6de05f60e0b 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -560,6 +560,7 @@
#include "code\game\objects\items\weapons\storage\briefcase.dm"
#include "code\game\objects\items\weapons\storage\fancy.dm"
#include "code\game\objects\items\weapons\storage\firstaid.dm"
+#include "code\game\objects\items\weapons\storage\internal.dm"
#include "code\game\objects\items\weapons\storage\lockbox.dm"
#include "code\game\objects\items\weapons\storage\secure.dm"
#include "code\game\objects\items\weapons\storage\storage.dm"
@@ -570,7 +571,6 @@
#include "code\game\objects\items\weapons\tanks\tank_types.dm"
#include "code\game\objects\items\weapons\tanks\tanks.dm"
#include "code\game\objects\random\random.dm"
-#include "code\game\objects\storage\coat.dm"
#include "code\game\objects\structures\barsign.dm"
#include "code\game\objects\structures\bedsheet_bin.dm"
#include "code\game\objects\structures\coathanger.dm"
@@ -760,6 +760,7 @@
#include "code\modules\clothing\suits\jobs.dm"
#include "code\modules\clothing\suits\labcoat.dm"
#include "code\modules\clothing\suits\miscellaneous.dm"
+#include "code\modules\clothing\suits\storage.dm"
#include "code\modules\clothing\suits\utility.dm"
#include "code\modules\clothing\suits\wiz_robe.dm"
#include "code\modules\clothing\under\chameleon.dm"
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index fd0b658aa0b..02406ed507e 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -92,8 +92,9 @@
return
- // operate two levels deep here (item in backpack in src; NOT item in box in backpack in src)
- if(A == loc || (A in loc) || (A in contents) || (A.loc in contents))
+ // operate two STORAGE levels deep here (item in backpack in src; NOT item in box in backpack in src)
+ var/sdepth = A.storage_depth(src)
+ if(A == loc || (A in loc) || (sdepth != -1 && sdepth <= 1))
// faster access to objects already on you
if(A in contents)
diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm
index 7d24790c523..996ea857acf 100644
--- a/code/_onclick/hud/screen_objects.dm
+++ b/code/_onclick/hud/screen_objects.dm
@@ -36,9 +36,6 @@
if(istype(master, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = master
S.close(usr)
- else if(istype(master,/obj/item/clothing/suit/storage))
- var/obj/item/clothing/suit/storage/S = master
- S.close(usr)
return 1
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index f2b5e850f41..d0afa8a5764 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -237,18 +237,6 @@
/obj/item/proc/equipped(var/mob/user, var/slot)
return
-//returns 1 if the item is equipped by a mob, 0 otherwise.
-//This might need some error trapping, not sure if get_equipped_items() is safe for non-human mobs.
-/obj/item/proc/is_equipped()
- if(!ismob(loc))
- return 0
-
- var/mob/M = loc
- if(src in M.get_equipped_items())
- return 1
- else
- return 0
-
//the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't.
//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen.
//Set disable_warning to 1 if you wish it to not give you outputs.
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index acfde88e2b3..60a1845f18b 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -15,9 +15,22 @@
max_combined_w_class = 21
/obj/item/weapon/storage/backpack/attackby(obj/item/weapon/W as obj, mob/user as mob)
- playsound(src.loc, "rustle", 50, 1, -5)
+ if (src.use_sound)
+ playsound(src.loc, src.use_sound, 50, 1, -5)
..()
+/obj/item/weapon/storage/backpack/equipped(var/mob/user, var/slot)
+ if (slot == slot_back && src.use_sound)
+ playsound(src.loc, src.use_sound, 50, 1, -5)
+ ..(user, slot)
+
+/*
+/obj/item/weapon/storage/backpack/dropped(mob/user as mob)
+ if (loc == user && src.use_sound)
+ playsound(src.loc, src.use_sound, 50, 1, -5)
+ ..(user)
+*/
+
/*
* Backpack Types
*/
diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm
index 8bdae5d8532..2c1a9977fde 100644
--- a/code/game/objects/items/weapons/storage/belt.dm
+++ b/code/game/objects/items/weapons/storage/belt.dm
@@ -8,29 +8,6 @@
slot_flags = SLOT_BELT
attack_verb = list("whipped", "lashed", "disciplined")
-
-/obj/item/weapon/storage/belt/proc/can_use()
- return is_equipped()
-
-
-/obj/item/weapon/storage/belt/MouseDrop(obj/over_object as obj, src_location, over_location)
- var/mob/M = usr
- if(!istype(over_object, /obj/screen))
- return ..()
- playsound(src.loc, "rustle", 50, 1, -5)
- if (!M.restrained() && !M.stat && can_use())
- switch(over_object.name)
- if("r_hand")
- M.u_equip(src)
- M.put_in_r_hand(src)
- if("l_hand")
- M.u_equip(src)
- M.put_in_l_hand(src)
- src.add_fingerprint(usr)
- return
-
-
-
/obj/item/weapon/storage/belt/utility
name = "tool-belt" //Carn: utility belt is nicer, but it bamboozles the text parsing.
desc = "Can hold various tools."
diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm
index 0e3642b4aa1..0545f85d21b 100644
--- a/code/game/objects/items/weapons/storage/bible.dm
+++ b/code/game/objects/items/weapons/storage/bible.dm
@@ -102,5 +102,6 @@
A.reagents.add_reagent("holywater",water2holy)
/obj/item/weapon/storage/bible/attackby(obj/item/weapon/W as obj, mob/user as mob)
- playsound(src.loc, "rustle", 50, 1, -5)
+ if (src.use_sound)
+ playsound(src.loc, src.use_sound, 50, 1, -5)
..()
diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm
index 40e6e17e80d..b0e8f6eb2f6 100644
--- a/code/game/objects/items/weapons/storage/firstaid.dm
+++ b/code/game/objects/items/weapons/storage/firstaid.dm
@@ -124,29 +124,7 @@
allow_quick_gather = 1
use_to_pickup = 1
storage_slots = 14
-
-/obj/item/weapon/storage/pill_bottle/MouseDrop(obj/over_object as obj) //Quick pillbottle fix. -Agouri
-
- if (ishuman(usr) || ismonkey(usr)) //Can monkeys even place items in the pocket slots? Leaving this in just in case~
- var/mob/M = usr
- if (!( istype(over_object, /obj/screen) ))
- return ..()
- if ((!( M.restrained() ) && !( M.stat ) /*&& M.pocket == src*/))
- switch(over_object.name)
- if("r_hand")
- M.u_equip(src)
- M.put_in_r_hand(src)
- if("l_hand")
- M.u_equip(src)
- M.put_in_l_hand(src)
- src.add_fingerprint(usr)
- return
- if(over_object == usr && in_range(src, usr) || usr.contents.Find(src))
- if (usr.s_active)
- usr.s_active.close(usr)
- src.show_to(usr)
- return
- return
+ use_sound = null
/obj/item/weapon/storage/pill_bottle/kelotane
name = "bottle of kelotane pills"
diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm
new file mode 100644
index 00000000000..11058f0dc56
--- /dev/null
+++ b/code/game/objects/items/weapons/storage/internal.dm
@@ -0,0 +1,87 @@
+//A storage item intended to be used by other items to provide storage functionality.
+//Types that use this should consider overriding emp_act() and hear_talk(), unless they shield their contents somehow.
+/obj/item/weapon/storage/internal
+ var/obj/item/master_item
+
+/obj/item/weapon/storage/internal/New(obj/item/MI)
+ master_item = MI
+ loc = master_item
+ name = master_item.name
+ verbs -= /obj/item/verb/verb_pickup //make sure this is never picked up.
+ ..()
+
+/obj/item/weapon/storage/internal/attack_hand()
+ return //make sure this is never picked up
+
+/obj/item/weapon/storage/internal/mob_can_equip()
+ return 0 //make sure this is never picked up
+
+//Helper procs to cleanly implement internal storages - storage items that provide inventory slots for other items.
+//These procs are completely optional, it is up to the master item to decide when it's storage get's opened by calling open()
+//However they are helpful for allowing the master item to pretend it is a storage item itself.
+//If you are using these you will probably want to override attackby() as well.
+//See /obj/item/clothing/suit/storage for an example.
+
+//items that use internal storage have the option of calling this to emulate default storage MouseDrop behaviour.
+//returns 1 if the master item's parent's MouseDrop() should be called, 0 otherwise. It's strange, but no other way of
+//doing it without the ability to call another proc's parent, really.
+/obj/item/weapon/storage/internal/proc/handle_mousedrop(mob/user as mob, obj/over_object as obj)
+ if (ishuman(user) || ismonkey(user)) //so monkeys can take off their backpacks -- Urist
+
+ if (istype(user.loc,/obj/mecha)) // stops inventory actions in a mech
+ return 0
+
+ if(over_object == user && Adjacent(user)) // this must come before the screen objects only block
+ src.open(user)
+ return 0
+
+ if (!( istype(over_object, /obj/screen) ))
+ return 1
+
+ //makes sure master_item is equipped before putting it in hand, so that we can't drag it into our hand from miles away.
+ //there's got to be a better way of doing this...
+ if (!(master_item.loc == user) || (master_item.loc && master_item.loc.loc == user))
+ return 0
+
+ if (!( user.restrained() ) && !( user.stat ))
+ switch(over_object.name)
+ if("r_hand")
+ user.u_equip(master_item)
+ user.put_in_r_hand(master_item)
+ if("l_hand")
+ user.u_equip(master_item)
+ user.put_in_l_hand(master_item)
+ master_item.add_fingerprint(user)
+ return 0
+ return 0
+
+//items that use internal storage have the option of calling this to emulate default storage attack_hand behaviour.
+//returns 1 if the master item's parent's attack_hand() should be called, 0 otherwise.
+//It's strange, but no other way of doing it without the ability to call another proc's parent, really.
+/obj/item/weapon/storage/internal/proc/handle_attack_hand(mob/user as mob)
+
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(H.l_store == master_item && !H.get_active_hand()) //Prevents opening if it's in a pocket.
+ H.put_in_hands(master_item)
+ H.l_store = null
+ return 0
+ if(H.r_store == master_item && !H.get_active_hand())
+ H.put_in_hands(master_item)
+ H.r_store = null
+ return 0
+
+ src.add_fingerprint(user)
+ if (master_item.loc == user)
+ src.open(user)
+ return 0
+
+ for(var/mob/M in range(1, master_item.loc))
+ if (M.s_active == src)
+ src.close(M)
+ return 1
+
+
+
+
+
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index 8fa93d9f6ac..a30168479aa 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -167,16 +167,12 @@
if ((src.loc == user) && (src.locked == 1))
usr << "\red [src] is locked and cannot be opened!"
else if ((src.loc == user) && (!src.locked))
- playsound(src.loc, "rustle", 50, 1, -5)
- if (user.s_active)
- user.s_active.close(user) //Close and re-open
- src.show_to(user)
+ src.open(usr)
else
..()
for(var/mob/M in range(1))
if (M.s_active == src)
src.close(M)
- src.orient2hud(user)
src.add_fingerprint(user)
return
@@ -245,4 +241,4 @@
/obj/item/weapon/storage/secure/safe/HoS/New()
..()
- //new /obj/item/weapon/storage/lockbox/clusterbang(src) This item is currently broken... and probably shouldnt exist to begin with (even though it's cool)
\ No newline at end of file
+ //new /obj/item/weapon/storage/lockbox/clusterbang(src) This item is currently broken... and probably shouldnt exist to begin with (even though it's cool)
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index 1831309b975..a4c56445981 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -22,41 +22,36 @@
var/allow_quick_gather //Set this variable to allow the object to have the 'toggle mode' verb, which quickly collects all items from a tile.
var/collection_mode = 1; //0 = pick one at a time, 1 = pick all on tile
var/foldable = null // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard
+ var/use_sound = "rustle" //sound played when used. null for no sound.
/obj/item/weapon/storage/MouseDrop(obj/over_object as obj)
if (ishuman(usr) || ismonkey(usr)) //so monkeys can take off their backpacks -- Urist
- var/mob/M = usr
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
return
- if(over_object == M && Adjacent(M)) // this must come before the screen objects only block
- orient2hud(M) // dunno why it wasn't before
- if(M.s_active)
- M.s_active.close(M)
- show_to(M)
+ if(over_object == usr && Adjacent(usr)) // this must come before the screen objects only block
+ src.open(usr)
return
if (!( istype(over_object, /obj/screen) ))
return ..()
+
+ //makes sure that the storage is equipped, so that we can't drag it into our hand from miles away.
+ //there's got to be a better way of doing this.
if (!(src.loc == usr) || (src.loc && src.loc.loc == usr))
return
- playsound(src.loc, "rustle", 50, 1, -5)
- if (!( M.restrained() ) && !( M.stat ))
+
+ if (!( usr.restrained() ) && !( usr.stat ))
switch(over_object.name)
if("r_hand")
- M.u_equip(src)
- M.put_in_r_hand(src)
+ usr.u_equip(src)
+ usr.put_in_r_hand(src)
if("l_hand")
- M.u_equip(src)
- M.put_in_l_hand(src)
+ usr.u_equip(src)
+ usr.put_in_l_hand(src)
src.add_fingerprint(usr)
return
- if(over_object == usr && in_range(src, usr) || usr.contents.Find(src))
- if (usr.s_active)
- usr.s_active.close(usr)
- src.show_to(usr)
- return
return
@@ -101,6 +96,15 @@
user.s_active = null
return
+/obj/item/weapon/storage/proc/open(mob/user as mob)
+ if (src.use_sound)
+ playsound(src.loc, src.use_sound, 50, 1, -5)
+
+ orient2hud(user)
+ if (user.s_active)
+ user.s_active.close(user)
+ show_to(user)
+
/obj/item/weapon/storage/proc/close(mob/user as mob)
src.hide_from(user)
@@ -313,17 +317,17 @@
if(isrobot(user))
user << "\blue You're a robot. No."
- return 1 //Robots can't interact with storage items.
+ return //Robots can't interact with storage items.
if(!can_be_inserted(W))
- return 0
+ return
if(istype(W, /obj/item/weapon/tray))
var/obj/item/weapon/tray/T = W
if(T.calc_carry() > 0)
if(prob(85))
user << "\red The tray won't fit in [src]."
- return 1
+ return
else
W.loc = user.loc
if ((user.client && user.s_active != src))
@@ -331,15 +335,14 @@
W.dropped(user)
user << "\red God damnit!"
+ W.add_fingerprint(user)
handle_item_insertion(W)
- return 1
+ return
/obj/item/weapon/storage/dropped(mob/user as mob)
return
/obj/item/weapon/storage/attack_hand(mob/user as mob)
- playsound(src.loc, "rustle", 50, 1, -5)
-
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.l_store == src && !H.get_active_hand()) //Prevents opening if it's in a pocket.
@@ -350,12 +353,9 @@
H.put_in_hands(src)
H.r_store = null
return
-
- src.orient2hud(user)
+
if (src.loc == user)
- if (user.s_active)
- user.s_active.close(user)
- src.show_to(user)
+ src.open(user)
else
..()
for(var/mob/M in range(1))
@@ -455,4 +455,20 @@
var/obj/O = A
O.hear_talk(M, text)
-
+//Returns the storage depth of an atom. This is the number of storage items the atom is contained in before reaching toplevel (the area).
+//Returns -1 if the atom was not found on user.
+/atom/proc/storage_depth(mob/user)
+ var/depth = 0
+ var/atom/cur_atom = src
+
+ while (cur_atom && !(cur_atom in user.contents))
+ if (isarea(cur_atom))
+ return -1
+ if (istype(cur_atom.loc, /obj/item/weapon/storage))
+ depth++
+ cur_atom = cur_atom.loc
+
+ if (!cur_atom)
+ return -1 //inside something with a null loc.
+
+ return depth
diff --git a/code/game/objects/storage/coat.dm b/code/game/objects/storage/coat.dm
deleted file mode 100644
index e7457e2497b..00000000000
--- a/code/game/objects/storage/coat.dm
+++ /dev/null
@@ -1,228 +0,0 @@
-/obj/item/clothing/suit/storage
- var/list/can_hold = new/list() //List of objects which this item can store (if set, it can't store anything else)
- var/list/cant_hold = new/list() //List of objects which this item can't store (in effect only if can_hold isn't set)
- var/max_w_class = 2 //Max size of objects that this object can store (in effect only if can_hold isn't set)
- var/max_combined_w_class = 4 //The sum of the w_classes of all the items in this storage item.
- var/storage_slots = 2 //The number of storage slots in this container.
- var/obj/screen/storage/boxes = null
- var/obj/screen/close/closer = null
-
-/obj/item/clothing/suit/storage/proc/return_inv()
-
- var/list/L = list( )
-
- L += src.contents
-
- for(var/obj/item/weapon/storage/S in src)
- L += S.return_inv()
- for(var/obj/item/weapon/gift/G in src)
- L += G.gift
- if (istype(G.gift, /obj/item/weapon/storage))
- L += G.gift:return_inv()
- return L
-
-/obj/item/clothing/suit/storage/proc/show_to(mob/user as mob)
- user.client.screen -= src.boxes
- user.client.screen -= src.closer
- user.client.screen -= src.contents
- user.client.screen += src.boxes
- user.client.screen += src.closer
- user.client.screen += src.contents
- user.s_active = src
- return
-
-/obj/item/clothing/suit/storage/proc/hide_from(mob/user as mob)
-
- if(!user.client)
- return
- user.client.screen -= src.boxes
- user.client.screen -= src.closer
- user.client.screen -= src.contents
- return
-
-/obj/item/clothing/suit/storage/proc/close(mob/user as mob)
-
- src.hide_from(user)
- user.s_active = null
- return
-
-//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right.
-//The numbers are calculated from the bottom-left The bottom-left slot being 1,1.
-/obj/item/clothing/suit/storage/proc/orient_objs(tx, ty, mx, my)
- var/cx = tx
- var/cy = ty
- src.boxes.screen_loc = text("[tx]:,[ty] to [mx],[my]")
- for(var/obj/O in src.contents)
- O.screen_loc = text("[cx],[cy]")
- O.layer = 20
- cx++
- if (cx > mx)
- cx = tx
- cy--
- src.closer.screen_loc = text("[mx+1],[my]")
- return
-
-//This proc draws out the inventory and places the items on it. It uses the standard position.
-/obj/item/clothing/suit/storage/proc/standard_orient_objs(var/rows,var/cols)
- var/cx = 4
- var/cy = 2+rows
- src.boxes.screen_loc = text("4:16,2:16 to [4+cols]:16,[2+rows]:16")
- for(var/obj/O in src.contents)
- O.screen_loc = text("[cx]:16,[cy]:16")
- O.layer = 20
- cx++
- if (cx > (4+cols))
- cx = 4
- cy--
- src.closer.screen_loc = text("[4+cols+1]:16,2:16")
- return
-
-//This proc determins the size of the inventory to be displayed. Please touch it only if you know what you're doing.
-/obj/item/clothing/suit/storage/proc/orient2hud(mob/user as mob)
- //var/mob/living/carbon/human/H = user
- var/row_num = 0
- var/col_count = min(7,storage_slots) -1
- if (contents.len > 7)
- row_num = round((contents.len-1) / 7) // 7 is the maximum allowed width.
- src.standard_orient_objs(row_num,col_count)
- return
-
-//This proc is called when you want to place an item into the storage item.
-/obj/item/clothing/suit/storage/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W,/obj/item/weapon/evidencebag) && src.loc != user)
- return
-
- ..()
- if(isrobot(user))
- user << "\blue You're a robot. No."
- return //Robots can't interact with storage items.
-
- if(src.loc == W)
- return //Means the item is already in the storage item
-
- if(contents.len >= storage_slots)
- user << "\red \The [src] is full, make some space."
- return //Storage item is full
-
- if(can_hold.len)
- var/ok = 0
- for(var/A in can_hold)
- if(istype(W, text2path(A) ))
- ok = 1
- break
- if(!ok)
- user << "\red \The [src] cannot hold \the [W]."
- return
-
- for(var/A in cant_hold) //Check for specific items which this container can't hold.
- if(istype(W, text2path(A) ))
- user << "\red \The [src] cannot hold \the [W]."
- return
-
- if (W.w_class > max_w_class)
- user << "\red \The [W] is too big for \the [src]"
- return
-
- var/sum_w_class = W.w_class
- for(var/obj/item/I in contents)
- sum_w_class += I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it.
-
- if(sum_w_class > max_combined_w_class)
- user << "\red \The [src] is full, make some space."
- return
-
- if(W.w_class >= src.w_class && (istype(W, /obj/item/weapon/storage)))
- if(!istype(src, /obj/item/weapon/storage/backpack/holding)) //bohs should be able to hold backpacks again. The override for putting a boh in a boh is in backpack.dm.
- user << "\red \The [src] cannot hold \the [W] as it's a storage item of the same size."
- return //To prevent the stacking of the same sized items.
-
- user.u_equip(W)
- playsound(src.loc, "rustle", 50, 1, -5)
- W.loc = src
- if ((user.client && user.s_active != src))
- user.client.screen -= W
- src.orient2hud(user)
- W.dropped(user)
- add_fingerprint(user)
- show_to(user)
-
-
-/obj/item/weapon/storage/dropped(mob/user as mob)
- return
-
-/obj/item/clothing/suit/storage/MouseDrop(atom/over_object)
- if(ishuman(usr))
- var/mob/living/carbon/human/M = usr
- if (!( istype(over_object, /obj/screen) ))
- return ..()
- playsound(src.loc, "rustle", 50, 1, -5)
- if ((!( M.restrained() ) && !( M.stat ) && M.wear_suit == src))
- if (over_object.name == "r_hand")
- M.u_equip(src)
- M.put_in_r_hand(src)
- // if (!( M.r_hand ))
- // M.u_equip(src)
- // M.r_hand = src
- else if (over_object.name == "l_hand")
- M.u_equip(src)
- M.put_in_l_hand(src)
- // if (!( M.l_hand ))
- // M.u_equip(src)
- // M.l_hand = src
- M.update_inv_wear_suit()
- src.add_fingerprint(usr)
- return
- if( (over_object == usr && in_range(src, usr) || usr.contents.Find(src)) && usr.s_active)
- usr.s_active.close(usr)
- src.show_to(usr)
- return
-
-/obj/item/clothing/suit/storage/attack_paw(mob/user as mob)
- //playsound(src.loc, "rustle", 50, 1, -5) // what
- return src.attack_hand(user)
-
-/obj/item/clothing/suit/storage/attack_hand(mob/user as mob)
- playsound(src.loc, "rustle", 50, 1, -5)
- src.orient2hud(user)
- if (src.loc == user)
- if (user.s_active)
- user.s_active.close(user)
- src.show_to(user)
- else
- ..()
- for(var/mob/M in range(1))
- if (M.s_active == src)
- src.close(M)
- src.add_fingerprint(user)
- return
-
-/obj/item/clothing/suit/storage/New()
-
- src.boxes = new /obj/screen/storage( )
- src.boxes.name = "storage"
- src.boxes.master = src
- src.boxes.icon_state = "block"
- src.boxes.screen_loc = "7,7 to 10,8"
- src.boxes.layer = 19
- src.closer = new /obj/screen/close( )
- src.closer.master = src
- src.closer.icon_state = "x"
- src.closer.layer = 20
- orient2hud()
- return
-
-/obj/item/clothing/suit/emp_act(severity)
- if(!istype(src.loc, /mob/living))
- for(var/obj/O in contents)
- O.emp_act(severity)
- ..()
-
-/*
-
-/obj/item/clothing/suit/hear_talk(mob/M, var/msg)
- for (var/atom/A in src)
- if(istype(A,/obj/))
- var/obj/O = A
- O.hear_talk(M, msg)
-
-*/
\ No newline at end of file
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 8dfa25d0a6a..516fde34cb4 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -134,6 +134,7 @@ BLIND // can't see anything
/obj/item/clothing/gloves/emp_act(severity)
if(cell)
+ //why is this not part of the powercell code?
cell.charge -= 1000 / severity
if (cell.charge < 0)
cell.charge = 0
@@ -151,6 +152,7 @@ BLIND // can't see anything
icon = 'icons/obj/clothing/hats.dmi'
body_parts_covered = HEAD
slot_flags = SLOT_HEAD
+ w_class = 2.0
//Mask
@@ -186,6 +188,7 @@ BLIND // can't see anything
slot_flags = SLOT_OCLOTHING
var/blood_overlay_type = "suit"
siemens_coefficient = 0.9
+ w_class = 3
//Spacesuit
//Note: Everything in modules/clothing/spacesuits should have the entire suit grouped together.
@@ -232,6 +235,7 @@ BLIND // can't see anything
flags = FPRINT | TABLEPASS
slot_flags = SLOT_ICLOTHING
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
+ w_class = 3
var/has_sensor = 1//For the crew computer 2 = unable to change mode
var/sensor_mode = 0
/*
@@ -246,17 +250,14 @@ BLIND // can't see anything
/obj/item/clothing/under/attackby(obj/item/I, mob/user)
+ if(hastie)
+ hastie.attackby(I, user)
+ return
+
if(!hastie && istype(I, /obj/item/clothing/tie))
user.drop_item()
hastie = I
- I.loc = src
- user << "You attach [I] to [src]."
-
- if (istype(hastie,/obj/item/clothing/tie/holster))
- verbs += /obj/item/clothing/under/proc/holster
-
- if (istype(hastie,/obj/item/clothing/tie/storage))
- verbs += /obj/item/clothing/under/proc/storage
+ hastie.attach_to(src, user)
if(istype(loc, /mob/living/carbon/human))
var/mob/living/carbon/human/H = loc
@@ -265,6 +266,32 @@ BLIND // can't see anything
return
..()
+
+/obj/item/clothing/under/attack_hand(mob/user as mob)
+ //only forward to the attached accessory if the clothing is equipped (not in a storage)
+ if(hastie && src.loc == user)
+ hastie.attack_hand(user)
+ return
+ ..()
+
+//This is to allow people to take off suits when there is an attached accessory
+/obj/item/clothing/under/MouseDrop(obj/over_object as obj)
+ if (ishuman(usr) || ismonkey(usr))
+ //makes sure that the clothing is equipped so that we can't drag it into our hand from miles away.
+ if (!(src.loc == usr))
+ return
+
+ if (!( usr.restrained() ) && !( usr.stat ))
+ switch(over_object.name)
+ if("r_hand")
+ usr.u_equip(src)
+ usr.put_in_r_hand(src)
+ if("l_hand")
+ usr.u_equip(src)
+ usr.put_in_l_hand(src)
+ src.add_fingerprint(usr)
+ return
+ return
/obj/item/clothing/under/examine()
set src in view()
@@ -333,16 +360,7 @@ BLIND // can't see anything
if(usr.stat) return
if(hastie)
- if (istype(hastie,/obj/item/clothing/tie/holster))
- verbs -= /obj/item/clothing/under/proc/holster
-
- if (istype(hastie,/obj/item/clothing/tie/storage))
- verbs -= /obj/item/clothing/under/proc/storage
- var/obj/item/clothing/tie/storage/W = hastie
- if (W.hold)
- W.hold.close(usr)
-
- usr.put_in_hands(hastie)
+ hastie.remove(usr)
hastie = null
if(istype(loc, /mob/living/carbon/human))
@@ -353,59 +371,4 @@ BLIND // can't see anything
sensor_mode = pick(0,1,2,3)
..()
-/obj/item/clothing/under/proc/holster()
- set name = "Holster"
- set category = "Object"
- set src in usr
- if(!istype(usr, /mob/living)) return
- if(usr.stat) return
-
- if (!hastie || !istype(hastie,/obj/item/clothing/tie/holster))
- usr << "\red You need a holster for that!"
- return
- var/obj/item/clothing/tie/holster/H = hastie
-
- if(!H.holstered)
- if(!istype(usr.get_active_hand(), /obj/item/weapon/gun))
- usr << "\blue You need your gun equiped to holster it."
- return
- var/obj/item/weapon/gun/W = usr.get_active_hand()
- if (!W.isHandgun())
- usr << "\red This gun won't fit in \the [H]!"
- return
- H.holstered = usr.get_active_hand()
- usr.drop_item()
- H.holstered.loc = src
- usr.visible_message("\blue \The [usr] holsters \the [H.holstered].", "You holster \the [H.holstered].")
- else
- if(istype(usr.get_active_hand(),/obj) && istype(usr.get_inactive_hand(),/obj))
- usr << "\red You need an empty hand to draw the gun!"
- else
- if(usr.a_intent == "hurt")
- usr.visible_message("\red \The [usr] draws \the [H.holstered], ready to shoot!", \
- "\red You draw \the [H.holstered], ready to shoot!")
- else
- usr.visible_message("\blue \The [usr] draws \the [H.holstered], pointing it at the ground.", \
- "\blue You draw \the [H.holstered], pointing it at the ground.")
- usr.put_in_hands(H.holstered)
- H.holstered = null
-
-/obj/item/clothing/under/proc/storage()
- set name = "Look in storage"
- set category = "Object"
- set src in usr
- if(!istype(usr, /mob/living)) return
- if(usr.stat) return
-
- if (!hastie || !istype(hastie,/obj/item/clothing/tie/storage))
- usr << "\red You need something to store items in for that!"
- return
- var/obj/item/clothing/tie/storage/W = hastie
-
- if (!istype(W.hold))
- return
-
- W.hold.loc = usr
- W.hold.attack_hand(usr)
-
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index c4b3c6224f5..e5791516f90 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -11,6 +11,7 @@
heat_protection = HEAD
max_heat_protection_temperature = HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
siemens_coefficient = 0.7
+ w_class = 3
/obj/item/clothing/head/helmet/warden
name = "warden's hat"
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 2da4be52525..649541774d7 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -24,6 +24,7 @@
flags_inv = (HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE)
icon_action_button = "action_welding"
siemens_coefficient = 0.9
+ w_class = 3
/obj/item/clothing/head/welding/attack_self()
toggle()
@@ -125,6 +126,7 @@
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
var/brightness_on = 2 //luminosity when on
var/on = 0
+ w_class = 3
attack_self(mob/user)
if(!isturf(user.loc))
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 67aebf872dc..766cc96f05a 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -114,12 +114,14 @@
icon_state = "slippers"
item_state = "slippers"
species_restricted = null
+ w_class = 2
/obj/item/clothing/shoes/slippers_worn
name = "worn bunny slippers"
desc = "Fluffy..."
icon_state = "slippers_worn"
item_state = "slippers_worn"
+ w_class = 2
/obj/item/clothing/shoes/laceup
name = "laceup shoes"
diff --git a/code/modules/clothing/spacesuits/alien.dm b/code/modules/clothing/spacesuits/alien.dm
index f038aa4456e..8016a99e72f 100644
--- a/code/modules/clothing/spacesuits/alien.dm
+++ b/code/modules/clothing/spacesuits/alien.dm
@@ -206,10 +206,14 @@
user << "You relax your deathgrip on the flooring."
else
//make sure these can only be used when equipped.
- if (!is_equipped())
+ if(!ishuman(user))
+ return
+ var/mob/living/carbon/human/H = user
+ if (H.shoes != src)
user << "You will have to put on the [src] before you can do that."
return
+
flags |= NOSLIP
magpulse = 1
canremove = 0 //kinda hard to take off magclaws when you are gripping them tightly.
diff --git a/code/modules/clothing/suits/storage.dm b/code/modules/clothing/suits/storage.dm
new file mode 100644
index 00000000000..cb03feb5997
--- /dev/null
+++ b/code/modules/clothing/suits/storage.dm
@@ -0,0 +1,29 @@
+/obj/item/clothing/suit/storage
+ var/obj/item/weapon/storage/internal/pockets
+
+/obj/item/clothing/suit/storage/New()
+ ..()
+ pockets = new/obj/item/weapon/storage/internal(src)
+ pockets.storage_slots = 2 //two slots
+ pockets.max_w_class = 2 //fit only pocket sized items
+ pockets.max_combined_w_class = 4
+
+/obj/item/clothing/suit/storage/attack_hand(mob/user as mob)
+ if (pockets.handle_attack_hand(user))
+ ..(user)
+
+/obj/item/clothing/suit/storage/MouseDrop(obj/over_object as obj)
+ if (pockets.handle_mousedrop(usr, over_object))
+ ..(over_object)
+
+/obj/item/clothing/suit/storage/attackby(obj/item/W as obj, mob/user as mob)
+ ..()
+ pockets.attackby(W, user)
+
+/obj/item/clothing/suit/storage/emp_act(severity)
+ pockets.emp_act(severity)
+ ..()
+
+/obj/item/clothing/suit/storage/hear_talk(mob/M, var/msg)
+ pockets.hear_talk(M, msg)
+ ..()
\ No newline at end of file
diff --git a/code/modules/clothing/under/ties.dm b/code/modules/clothing/under/ties.dm
index d4564649a4d..9f45d7a53d0 100644
--- a/code/modules/clothing/under/ties.dm
+++ b/code/modules/clothing/under/ties.dm
@@ -8,6 +8,23 @@
flags = FPRINT | TABLEPASS
slot_flags = 0
w_class = 2.0
+ var/obj/item/clothing/under/has_suit = null //the suit the tie may be attached to
+
+//when user attached an accessory to S
+/obj/item/clothing/tie/proc/attach_to(obj/item/clothing/under/S, mob/user as mob)
+ if(!istype(S))
+ return
+ has_suit = S
+ loc = has_suit
+ user << "You attach [src] to [has_suit]."
+ src.add_fingerprint(user)
+
+/obj/item/clothing/tie/proc/remove(mob/user as mob)
+ if(!has_suit)
+ return
+ has_suit = null
+ usr.put_in_hands(src)
+ src.add_fingerprint(user)
/obj/item/clothing/tie/blue
name = "blue tie"
@@ -116,7 +133,7 @@
//Armbands
/obj/item/clothing/tie/armband
name = "red armband"
- desc = "An fancy red armband!"
+ desc = "A fancy red armband!"
icon_state = "red"
item_color = "red"
@@ -156,6 +173,7 @@
icon_state = "medgreen"
item_color = "medgreen"
+//holsters
/obj/item/clothing/tie/holster
name = "shoulder holster"
desc = "A handgun holster."
@@ -163,6 +181,105 @@
item_color = "holster"
var/obj/item/weapon/gun/holstered = null
+//subtypes can override this to specify what can be holstered
+/obj/item/clothing/tie/holster/proc/can_holster(obj/item/weapon/gun/W)
+ return W.isHandgun()
+
+/obj/item/clothing/tie/holster/proc/holster(obj/item/I, mob/user as mob)
+ if(holstered)
+ user << "\red There is already a [holstered] holstered here!"
+
+ if (!istype(I, /obj/item/weapon/gun))
+ user << "\red Only guns can be holstered!"
+
+ var/obj/item/weapon/gun/W = I
+ if (!can_holster(W))
+ user << "\red This [W] won't fit in the [src]!"
+ return
+
+ holstered = W
+ user.drop_from_inventory(holstered)
+ holstered.loc = src
+ holstered.add_fingerprint(user)
+ user.visible_message("\blue [user] holsters the [holstered].", "You holster the [holstered].")
+
+/obj/item/clothing/tie/holster/proc/unholster(mob/user as mob)
+ if(!holstered)
+ return
+
+ if(istype(user.get_active_hand(),/obj) && istype(user.get_inactive_hand(),/obj))
+ user << "\red You need an empty hand to draw the [holstered]!"
+ else
+ if(user.a_intent == "hurt")
+ usr.visible_message("\red [user] draws the [holstered], ready to shoot!", \
+ "\red You draw the [holstered], ready to shoot!")
+ else
+ user.visible_message("\blue [user] draws the [holstered], pointing it at the ground.", \
+ "\blue You draw the [holstered], pointing it at the ground.")
+ user.put_in_hands(holstered)
+ holstered.add_fingerprint(user)
+ holstered = null
+
+/obj/item/clothing/tie/holster/attack_hand(mob/user as mob)
+ if (has_suit) //if we are part of a suit
+ if (holstered)
+ unholster(user)
+ return
+
+ ..(user)
+
+/obj/item/clothing/tie/holster/attackby(obj/item/W as obj, mob/user as mob)
+ holster(W, user)
+
+/obj/item/clothing/tie/holster/emp_act(severity)
+ if (holstered)
+ holstered.emp_act(severity)
+ ..()
+
+/obj/item/clothing/tie/holster/examine()
+ set src in view()
+ ..()
+ if (holstered)
+ usr << "A [holstered] is holstered here."
+ else
+ usr << "It is empty."
+
+/obj/item/clothing/tie/holster/attach_to(obj/item/clothing/under/S, mob/user as mob)
+ ..()
+ has_suit.verbs += /obj/item/clothing/tie/holster/verb/holster_verb
+
+/obj/item/clothing/tie/holster/remove(mob/user as mob)
+ has_suit.verbs -= /obj/item/clothing/tie/holster/verb/holster_verb
+ ..()
+
+//For the holster hotkey
+/obj/item/clothing/tie/holster/verb/holster_verb()
+ set name = "Holster"
+ set category = "Object"
+ set src in usr
+ if(!istype(usr, /mob/living)) return
+ if(usr.stat) return
+
+ var/obj/item/clothing/tie/holster/H = null
+ if (istype(src, /obj/item/clothing/tie/holster))
+ H = src
+ else if (istype(src, /obj/item/clothing/under))
+ var/obj/item/clothing/under/S = src
+ if (S.hastie)
+ H = S.hastie
+
+ if (!H)
+ usr << "/red Something is very wrong."
+
+ if(!H.holstered)
+ if(!istype(usr.get_active_hand(), /obj/item/weapon/gun))
+ usr << "\blue You need your gun equiped to holster it."
+ return
+ var/obj/item/weapon/gun/W = usr.get_active_hand()
+ H.holster(W, usr)
+ else
+ H.unholster(usr)
+
/obj/item/clothing/tie/holster/armpit
name = "shoulder holster"
desc = "A worn-out handgun holster. Perfect for concealed carry"
@@ -177,17 +294,43 @@
/obj/item/clothing/tie/storage
name = "load bearing equipment"
- desc = "Used to hold things when you don't have enough hands for that."
+ desc = "Used to hold things when you don't have enough hands."
icon_state = "webbing"
item_color = "webbing"
var/slots = 3
- var/obj/item/weapon/storage/pockets/hold
+ var/obj/item/weapon/storage/internal/hold
/obj/item/clothing/tie/storage/New()
- hold = new /obj/item/weapon/storage/pockets(src)
- hold.master_item = src
+ ..()
+ hold = new/obj/item/weapon/storage/internal(src)
hold.storage_slots = slots
+/obj/item/clothing/tie/storage/attack_hand(mob/user as mob)
+ if (has_suit) //if we are part of a suit
+ hold.open(user)
+ return
+
+ if (hold.handle_attack_hand(user)) //otherwise interact as a regular storage item
+ ..(user)
+
+/obj/item/clothing/tie/storage/MouseDrop(obj/over_object as obj)
+ if (has_suit)
+ return
+
+ if (hold.handle_mousedrop(usr, over_object))
+ ..(over_object)
+
+/obj/item/clothing/tie/storage/attackby(obj/item/W as obj, mob/user as mob)
+ hold.attackby(W, user)
+
+/obj/item/clothing/tie/storage/emp_act(severity)
+ hold.emp_act(severity)
+ ..()
+
+/obj/item/clothing/tie/storage/hear_talk(mob/M, var/msg)
+ hold.hear_talk(M, msg)
+ ..()
+
/obj/item/clothing/tie/storage/attack_self(mob/user as mob)
user << "You empty [src]."
var/turf/T = get_turf(src)
@@ -196,18 +339,6 @@
hold.remove_from_storage(I, T)
src.add_fingerprint(user)
-/obj/item/clothing/tie/storage/attackby(obj/item/weapon/W as obj, mob/user as mob)
- hold.attackby(W,user)
- src.add_fingerprint(user)
-
-/obj/item/weapon/storage/pockets
- name = "storage"
- var/master_item //item it belongs to
-
-/obj/item/weapon/storage/pockets/close(mob/user as mob)
- ..()
- loc = master_item
-
/obj/item/clothing/tie/storage/webbing
name = "webbing"
desc = "Strudy mess of synthcotton belts and buckles, ready to share your burden."
@@ -311,27 +442,14 @@
item_color = "unathiharness2"
slots = 2
-/obj/item/clothing/tie/storage/knifeharness/attackby(var/obj/item/O as obj, mob/user as mob)
- ..()
- update()
-
-/obj/item/clothing/tie/storage/knifeharness/proc/update()
- var/count = 0
- for(var/obj/item/I in hold)
- if(istype(I,/obj/item/weapon/hatchet/unathiknife))
- count++
- if(count>2) count = 2
- item_state = "unathiharness[count]"
- icon_state = item_state
- item_color = item_state
-
- if(istype(loc, /obj/item/clothing))
- var/obj/item/clothing/U = loc
- if(istype(U.loc, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = U.loc
- H.update_inv_w_uniform()
-
/obj/item/clothing/tie/storage/knifeharness/New()
..()
+ hold.max_combined_w_class = 4
+ hold.can_hold = list("/obj/item/weapon/hatchet/unathiknife",\
+ "/obj/item/weapon/kitchen/utensil/knife",\
+ "/obj/item/weapon/kitchen/utensil/pknife",\
+ "/obj/item/weapon/kitchenknife",\
+ "/obj/item/weapon/kitchenknife/ritual")
+
+ new /obj/item/weapon/hatchet/unathiknife(hold)
new /obj/item/weapon/hatchet/unathiknife(hold)
- new /obj/item/weapon/hatchet/unathiknife(hold)
\ No newline at end of file