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)