From fd03e4d59b63d90c11ca586f89b34461fece75fa Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Thu, 15 Oct 2015 10:18:55 +0200 Subject: [PATCH] Surgical kits can now contain their equipment. The surgical kit can now contain the equipment it came with. It can also not contain more items of a given type than it was spawned with. This means that even if the storage container otherwise has sufficient space it can, for example, still only ever contain 1 surgical saw. Fixes #11298. Fixes #11297. --- code/__HELPERS/lists.dm | 16 +++++++--- .../objects/items/weapons/storage/firstaid.dm | 6 ++-- .../objects/items/weapons/storage/storage.dm | 31 ++++++++++++++----- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index ed0f0c9780..a6b010dbc9 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -71,11 +71,17 @@ proc/isemptylist(list/list) return 1 return 0 -//Empties the list by setting the length to 0. Hopefully the elements get garbage collected -proc/clearlist(list/list) - if(istype(list)) - list.len = 0 - return +/proc/instances_of_type_in_list(var/atom/A, var/list/L) + var/instances = 0 + for(var/type in L) + if(istype(A, type)) + instances++ + return instances + +//Empties the list by .Cut(). Setting lenght = 0 has been confirmed to leak references. +proc/clearlist(var/list/L) + if(islist(L)) + L.Cut() //Removes any null entries from the list proc/listclearnulls(list/list) diff --git a/code/game/objects/items/weapons/storage/firstaid.dm b/code/game/objects/items/weapons/storage/firstaid.dm index c23dfcdb51..a76fb4f1a1 100644 --- a/code/game/objects/items/weapons/storage/firstaid.dm +++ b/code/game/objects/items/weapons/storage/firstaid.dm @@ -130,8 +130,7 @@ /obj/item/weapon/storage/firstaid/surgery name = "surgery kit" - desc = "Contains tools for surgery." - storage_slots = 10 + desc = "Contains tools for surgery. Has precise foam fitting for safe transport." /obj/item/weapon/storage/firstaid/surgery/New() ..() @@ -146,7 +145,8 @@ new /obj/item/weapon/bonegel(src) new /obj/item/weapon/FixOVein(src) new /obj/item/stack/medical/advanced/bruise_pack(src) - return + + make_exact_fit() /* * Pill Bottles diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 22277c33e2..6f2ba544ab 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -51,10 +51,10 @@ //there's got to be a better way of doing this. if (!(src.loc == usr) || (src.loc && src.loc.loc == usr)) return - + if (( usr.restrained() ) || ( usr.stat )) return - + if ((src.loc == usr) && !usr.unEquip(src)) return @@ -232,12 +232,16 @@ usr << "[src] is full, make some space." return 0 //Storage item is full - if(can_hold.len && !is_type_in_list(W, can_hold)) - if(!stop_messages) - if (istype(W, /obj/item/weapon/hand_labeler)) - return 0 - usr << "[src] cannot hold [W]." - return 0 + if(can_hold.len) + if(!is_type_in_list(W, can_hold)) + if(!stop_messages && ! istype(W, /obj/item/weapon/hand_labeler)) + usr << "[src] cannot hold [W]." + return 0 + var/max_instances = can_hold[W.type] + if(max_instances && instances_of_type_in_list(W, contents) >= max_instances) + if(!stop_messages && !istype(W, /obj/item/weapon/hand_labeler)) + usr << "[src] has no more space for an additional [W]." + return 0 if(cant_hold.len && is_type_in_list(W, cant_hold)) if(!stop_messages) @@ -449,6 +453,17 @@ var/obj/O = A O.hear_talk(M, text, verb, speaking) +/obj/item/weapon/storage/proc/make_exact_fit() + storage_slots = contents.len + + can_hold.Cut() + max_w_class = 0 + max_storage_space = 0 + for(var/obj/item/I in src) + max_w_class = max(I.w_class, max_w_class) + max_storage_space += I.get_storage_cost() + can_hold[I.type] = ++can_hold[I.type] + //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 container. /atom/proc/storage_depth(atom/container)