diff --git a/baystation12.dme b/baystation12.dme index dde7faf436..121a598e72 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -559,6 +559,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" @@ -569,7 +570,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" @@ -759,6 +759,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 fd0b658aa0..e827ef5757 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -92,8 +92,8 @@ 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) + if(A == loc || (A in loc) || A.storage_depth(src) <= 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 7d24790c52..996ea857ac 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/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm index 6cce5858bc..59f2e7b2aa 100644 --- a/code/game/objects/items/weapons/storage/internal.dm +++ b/code/game/objects/items/weapons/storage/internal.dm @@ -1,4 +1,5 @@ //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 @@ -18,26 +19,30 @@ //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. -//Mostly just copypasta'd from /obj/item/weapon/storage. Not sure how else to do it. +//Mostly just copypasta'd from /obj/item/weapon/storage. Not sure how else to do it, other than moving all of this into storage.dm +//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 + return 0 if(over_object == user && Adjacent(user)) // this must come before the screen objects only block src.open(user) - return + return 0 if (!( istype(over_object, /obj/screen) )) - return ..() - + 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 + return 0 if (!( user.restrained() ) && !( user.stat )) switch(over_object.name) @@ -48,12 +53,12 @@ user.u_equip(master_item) user.put_in_l_hand(master_item) master_item.add_fingerprint(user) - return - return + 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. -//Strange, but no other way of doing it without the ability to call another proc's parent, really. +//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)) @@ -72,7 +77,7 @@ src.open(user) return 0 - for(var/mob/M in range(1)) + for(var/mob/M in range(1, master_item.loc)) if (M.s_active == src) src.close(M) return 1 diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index b0196360cc..7da16bc368 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -454,4 +454,15 @@ 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). +//If user is specified, this proc returns the storage depth to the user's contents. +/atom/proc/storage_depth(mob/user=null) + var/depth = 0 + var/atom/cur_atom = src + + while (cur_atom && !isarea(cur_atom) && (!(user) || !(cur_atom in user.contents))) + if (istype(cur_atom.loc, /obj/item/weapon/storage)) + depth++ + cur_atom = cur_atom.loc + + return depth diff --git a/code/game/objects/storage/coat.dm b/code/game/objects/storage/coat.dm deleted file mode 100644 index e7457e2497..0000000000 --- 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/suits/storage.dm b/code/modules/clothing/suits/storage.dm new file mode 100644 index 0000000000..cb03feb599 --- /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