diff --git a/code/__DEFINES/dcs/signals/signals_material_container.dm b/code/__DEFINES/dcs/signals/signals_material_container.dm
new file mode 100644
index 00000000000..3f9ab395175
--- /dev/null
+++ b/code/__DEFINES/dcs/signals/signals_material_container.dm
@@ -0,0 +1,11 @@
+//Material Container Signals
+/// Called from datum/component/material_container/proc/can_hold_material() : (mat)
+#define COMSIG_MATCONTAINER_MAT_CHECK "matcontainer_mat_check"
+ #define MATCONTAINER_ALLOW_MAT (1<<0)
+/// Called from datum/component/material_container/proc/user_insert() : (held_item, user)
+#define COMSIG_MATCONTAINER_PRE_USER_INSERT "matcontainer_pre_user_insert"
+ #define MATCONTAINER_BLOCK_INSERT (1<<1)
+/// Called from datum/component/material_container/proc/insert_item() : (target, last_inserted_id, material_amount, container)
+#define COMSIG_MATCONTAINER_ITEM_CONSUMED "matcontainer_item_consumed"
+/// Called from datum/component/material_container/proc/retrieve_sheets() : (sheets)
+#define COMSIG_MATCONTAINER_SHEETS_RETRIVED "matcontainer_sheets_retrived"
diff --git a/code/__DEFINES/materials.dm b/code/__DEFINES/materials.dm
index f58ec028dbb..08b88324826 100644
--- a/code/__DEFINES/materials.dm
+++ b/code/__DEFINES/materials.dm
@@ -15,6 +15,9 @@
/// Used to make a material type able to be instantiated on demand after roundstart.
#define MATERIAL_INIT_BESPOKE (1<<1)
+/// Makes sure only integer values are used when consuming, removing & checking for mats
+#define OPTIMAL_COST(cost)(max(1, round(cost)))
+
//Material Container Flags.
///If the container shows the amount of contained materials on examine.
#define MATCONTAINER_EXAMINE (1<<0)
diff --git a/code/__HELPERS/construction.dm b/code/__HELPERS/construction.dm
index ad9f24cef3c..add76c0f9ce 100644
--- a/code/__HELPERS/construction.dm
+++ b/code/__HELPERS/construction.dm
@@ -8,3 +8,44 @@
)
else
return defaults
+
+/**
+ * Turns material amount into the number of sheets, returning FALSE if the number is less than SHEET_MATERIAL_AMOUNT
+ *
+ * Arguments:
+ * - amt: amount to convert
+ */
+/proc/amount2sheet(amt)
+ if(amt >= SHEET_MATERIAL_AMOUNT)
+ return round(amt / SHEET_MATERIAL_AMOUNT)
+ return 0
+
+/**
+ * Turns number of sheets into material amount, returning FALSE if the number is <= 0
+ *
+ * Arguments:
+ * - amt: amount to convert
+ */
+/proc/sheet2amount(sheet_amt)
+ if(sheet_amt > 0)
+ return sheet_amt * SHEET_MATERIAL_AMOUNT
+ return 0
+
+/**
+ * Splits a stack. we don't use /obj/item/stack/proc/fast_split_stack because Byond complains that should only be called asynchronously.
+ * This proc is also more faster because it doesn't deal with mobs, copying evidences or refreshing atom storages
+ * Has special internal uses for e.g. by the material container
+ *
+ * Arguments:
+ * - [target][obj/item]: the stack to splot
+ * - [amount]: amount to split by
+ */
+/datum/component/material_container/proc/fast_split_stack(obj/item/stack/target, amount)
+ if(!target.use(amount, TRUE, FALSE))
+ return null
+
+ . = new target.type(target.drop_location(), amount, FALSE, target.mats_per_unit)
+ target.loc.atom_storage?.refresh_views()
+
+ target.is_zero_amount(delete_if_zero = TRUE)
+
diff --git a/code/datums/components/material_container.dm b/code/datums/components/material/material_container.dm
similarity index 66%
rename from code/datums/components/material_container.dm
rename to code/datums/components/material/material_container.dm
index af9b3f32903..02d73b51055 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material/material_container.dm
@@ -10,8 +10,6 @@
*/
/datum/component/material_container
- /// The total amount of materials this material container contains
- var/total_amount = 0
/// The maximum amount of materials this material container can contain
var/max_amount
/// Map of material ref -> amount
@@ -20,31 +18,22 @@
var/list/allowed_materials
/// The typecache of things that this material container can accept
var/list/allowed_item_typecache
- /// The last main material that was inserted into this container
- var/last_inserted_id
/// Whether or not this material container allows specific amounts from sheets to be inserted
var/precise_insertion = FALSE
- /// A callback for checking wheter we can insert a material into this container
- var/datum/callback/insertion_check
- /// A callback invoked before materials are inserted into this container
- var/datum/callback/precondition
- /// A callback invoked after materials are inserted into this container
- var/datum/callback/after_insert
- /// A callback invoked after sheets are retrieve from this container
- var/datum/callback/after_retrieve
/// The material container flags. See __DEFINES/materials.dm.
var/mat_container_flags
+ /// Signals that are registered with this contained
+ var/list/registered_signals
/// Sets up the proper signals and fills the list of materials with the appropriate references.
-/datum/component/material_container/Initialize(list/init_mats,
+/datum/component/material_container/Initialize(
+ list/init_mats,
max_amt = 0,
- _mat_container_flags=NONE,
- list/allowed_mats=init_mats,
+ _mat_container_flags = NONE,
+ list/allowed_mats = init_mats,
list/allowed_items,
- datum/callback/_insertion_check,
- datum/callback/_precondition,
- datum/callback/_after_insert,
- datum/callback/_after_retrieve)
+ list/container_signals
+ )
if(!isatom(parent))
return COMPONENT_INCOMPATIBLE
@@ -60,11 +49,6 @@
else
allowed_item_typecache = typecacheof(allowed_items)
- insertion_check = _insertion_check
- precondition = _precondition
- after_insert = _after_insert
- after_retrieve = _after_retrieve
-
for(var/mat in init_mats) //Make the assoc list material reference -> amount
var/mat_ref = GET_MATERIAL_REF(mat)
if(isnull(mat_ref))
@@ -74,6 +58,11 @@
mat_amt = 0
materials[mat_ref] += mat_amt
+ //all user handled signals
+ if(length(container_signals))
+ for(var/signal in container_signals)
+ parent.RegisterSignal(src, signal, container_signals[signal])
+
if(_mat_container_flags & MATCONTAINER_NO_INSERT)
return
@@ -83,19 +72,11 @@
RegisterSignal(atom_target, COMSIG_ATOM_REQUESTING_CONTEXT_FROM_ITEM, PROC_REF(on_requesting_context_from_item))
/datum/component/material_container/Destroy(force, silent)
+ retrieve_all()
materials = null
allowed_materials = null
- if(insertion_check)
- QDEL_NULL(insertion_check)
- if(precondition)
- QDEL_NULL(precondition)
- if(after_insert)
- QDEL_NULL(after_insert)
- if(after_retrieve)
- QDEL_NULL(after_retrieve)
return ..()
-
/datum/component/material_container/RegisterWithParent()
. = ..()
@@ -104,6 +85,14 @@
if(mat_container_flags & MATCONTAINER_EXAMINE)
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
+/datum/component/material_container/proc/on_examine(datum/source, mob/user, list/examine_texts)
+ SIGNAL_HANDLER
+
+ for(var/I in materials)
+ var/datum/material/M = I
+ var/amt = materials[I] / SHEET_MATERIAL_AMOUNT
+ if(amt)
+ examine_texts += span_notice("It has [amt] sheets of [lowertext(M.name)] stored.")
/datum/component/material_container/vv_edit_var(var_name, var_value)
var/old_flags = mat_container_flags
@@ -119,27 +108,137 @@
else if(!(old_flags & MATCONTAINER_NO_INSERT) && mat_container_flags & MATCONTAINER_NO_INSERT)
UnregisterSignal(parent, COMSIG_ATOM_ATTACKBY)
+/**
+ * 3 Types of Procs
+ * Material Insertion : Insert materials into the container
+ * Material Validation : Checks how much materials are available, Extracts materials from items if the container can hold them
+ * Material Removal : Removes material from the container
+ *
+ * Each Proc furthur belongs to a specific category
+ * LOW LEVEL: Procs that are used internally & should not be used anywhere else unless you know what your doing
+ * MID LEVEL: Procs that can be used by machines(like recycler, stacking machines) to bypass majority of checks
+ * HIGH LEVEL: Procs that can be used by anyone publically and guarentees safty checks & limits
+ */
-/datum/component/material_container/proc/on_examine(datum/source, mob/user, list/examine_texts)
- SIGNAL_HANDLER
+//================================Material Insertion procs==============================
- for(var/I in materials)
- var/datum/material/M = I
- var/amt = materials[I]
- if(amt)
- examine_texts += span_notice("It has [amt] units of [lowertext(M.name)] stored.")
+//======================================LOW LEVEL=========================================
+/**
+ * Inserts the relevant materials from an item into this material container.
+ * This low level proc should not be used directly by anyone
+ *
+ * Arguments:
+ * - [source][/obj/item]: The source of the materials we are inserting.
+ * - multiplier: The multiplier for the materials extract from this item being inserted.
+ * - breakdown_flags: The breakdown bitflags that will be used to retrieve the materials from the source
+ */
+/datum/component/material_container/proc/insert_item_materials(obj/item/source, multiplier = 1, breakdown_flags = mat_container_flags)
+ var/primary_mat
+ var/max_mat_value = 0
-/// Proc that allows players to fill the parent with mats
-/datum/component/material_container/proc/on_attackby(datum/source, obj/item/weapon, mob/living/user)
- SIGNAL_HANDLER
+ var/list/item_materials = source.get_material_composition(breakdown_flags)
+ for(var/MAT in item_materials)
+ if(!can_hold_material(MAT))
+ continue
+ materials[MAT] += OPTIMAL_COST(item_materials[MAT] * multiplier)
+ if(item_materials[MAT] > max_mat_value)
+ max_mat_value = item_materials[MAT]
+ primary_mat = MAT
- user_insert(weapon, user)
+ return primary_mat
+//===================================================================================
- return COMPONENT_NO_AFTERATTACK
+
+//===============================MID LEVEL===================================================
+/**
+ * For inserting an amount of material. Use this to add materials to the container directly
+ *
+ * Arguments:
+ * - amt: amount of said material to insert
+ * - mat: the material type to insert
+ */
+/datum/component/material_container/proc/insert_amount_mat(amt, datum/material/mat)
+ if(amt <= 0)
+ return 0
+ amt = OPTIMAL_COST(amt)
+ if(!has_space(amt))
+ return 0
+
+ var/total_amount_saved = total_amount()
+ if(mat)
+ if(!istype(mat))
+ mat = GET_MATERIAL_REF(mat)
+ materials[mat] += amt
+ else
+ var/num_materials = length(materials)
+ if(!num_materials)
+ return 0
+
+ amt /= num_materials
+ for(var/i in materials)
+ materials[i] += amt
+ return (total_amount() - total_amount_saved)
+/**
+ * Proc specifically for inserting items, use this when you want to insert any item into the container
+ * this bypasses most of the material flag checks so much be used by machines like recycler, stacking machine etc that
+ * does not care for such checks
+ *
+ * Arguments:
+ * - [weapon][obj/item]: the item you are trying to insert
+ * - multiplier: The multiplier for the materials being inserted
+ * - breakdown_flags: The breakdown bitflags that will be used to retrieve the materials from the source
+ */
+/datum/component/material_container/proc/insert_item(obj/item/weapon, multiplier = 1, breakdown_flags = mat_container_flags)
+ if(QDELETED(weapon))
+ return MATERIAL_INSERT_ITEM_NO_MATS
+ multiplier = CEILING(multiplier, 0.01)
+
+ var/obj/item/target = weapon
+
+ var/material_amount = get_item_material_amount(target, breakdown_flags) * multiplier
+ if(!material_amount)
+ return MATERIAL_INSERT_ITEM_NO_MATS
+ var/obj/item/stack/item_stack
+ if(isstack(weapon) && !has_space(material_amount)) //not enough space split and feed as many sheets possible
+ item_stack = weapon
+ var/space_left = max_amount - total_amount()
+ if(!space_left)
+ return MATERIAL_INSERT_ITEM_NO_SPACE
+ var/material_per_sheet = material_amount / item_stack.amount
+ var/sheets_to_insert = round(space_left / material_per_sheet)
+ if(!sheets_to_insert)
+ return MATERIAL_INSERT_ITEM_NO_SPACE
+ target = fast_split_stack(item_stack, sheets_to_insert)
+ material_amount = get_item_material_amount(target, breakdown_flags) * multiplier
+ material_amount = OPTIMAL_COST(material_amount)
+
+ //not enough space, time to bail
+ if(!has_space(material_amount))
+ return MATERIAL_INSERT_ITEM_NO_SPACE
+
+ //do the insert
+ var/last_inserted_id = insert_item_materials(target, multiplier, breakdown_flags)
+ if(!isnull(last_inserted_id))
+ SEND_SIGNAL(src, COMSIG_MATCONTAINER_ITEM_CONSUMED, target, last_inserted_id, material_amount, src)
+ qdel(target) //item gone
+ return material_amount
+ else if(!isnull(item_stack) && item_stack != target) //insertion failed, merge the split stack back into the original
+ var/obj/item/stack/inserting_stack = target
+ item_stack.add(inserting_stack.amount)
+ qdel(inserting_stack)
+
+ return MATERIAL_INSERT_ITEM_FAILURE
+//============================================================================================
+
+
+//===================================HIGH LEVEL===================================================
/**
* inserts an item from the players hand into the container. Loops through all the contents inside reccursively
- * Arguments
+ * Does all explicit checking for mat flags & callbacks to check if insertion is valid
+ * This proc is what you should be using for almost all cases
+ *
+ * Arguments:
* * held_item - the item to insert
* * user - the mob inserting this item
* * breakdown_flags - how this item and all it's contents inside are broken down during insertion. This is unique to the machine doing the insertion
@@ -160,7 +259,7 @@
if(held_item.resistance_flags & INDESTRUCTIBLE)
return
//user defined conditions
- if(precondition && !precondition.Invoke(user))
+ if(SEND_SIGNAL(src, COMSIG_MATCONTAINER_PRE_USER_INSERT, held_item, user) & MATCONTAINER_BLOCK_INSERT)
return
//get all contents of this item reccursively
@@ -216,7 +315,7 @@
if(parent != current_parent || user.get_active_held_item() != active_held)
continue
if(requested_amount != item_stack.amount) //only split if its not the whole amount
- target = split_stack(item_stack, requested_amount) //split off the requested amount
+ target = fast_split_stack(item_stack, requested_amount) //split off the requested amount
requested_amount = 0
//is this item a stack and was it split by the player?
@@ -235,6 +334,7 @@
var/inserted = insert_item(target, breakdown_flags = mat_container_flags)
if(inserted > 0)
. += inserted
+ inserted /= SHEET_MATERIAL_AMOUNT // display units inserted as sheets for improved readability
var/message = null
//stack was either split by the container(!QDELETED(target) means the container only consumed a part of it) or by the player, put whats left back of the original stack back in players hand
@@ -249,21 +349,23 @@
//was this the original item in the players hand? put what's left back in the player's hand
if(!isnull(original_item))
user.put_in_active_hand(original_item)
- message = "Only [inserted] amount of [item_name] was consumed by [parent]."
+ message = "Only [inserted] sheets of [item_name] was consumed by [parent]."
//collect all messages to print later
if(!message)
- message = "[item_name] worth [inserted] material was consumed by [parent]."
+ message = "[item_name] worth [inserted] sheets of material was consumed by [parent]."
if(inserts[message])
inserts[message] += 1
else
inserts[message] = 1
else
var/error_msg
- if(inserted == -2)
+ if(inserted == MATERIAL_INSERT_ITEM_NO_SPACE)
error_msg = "[parent] has insufficient space to accept [target]"
- else
+ else if(inserted == MATERIAL_INSERT_ITEM_NO_MATS)
error_msg = "[target] has insufficient materials to be accepted by [parent]"
+ else
+ error_msg = "[parent] refuses to accept [target]"
//collect all messages to print later
if(errors[error_msg])
@@ -293,79 +395,27 @@
for(var/i in 1 to count)
to_chat(user, span_warning(error_msg))
+/// Proc that allows players to fill the parent with mats
+/datum/component/material_container/proc/on_attackby(datum/source, obj/item/weapon, mob/living/user)
+ SIGNAL_HANDLER
+
+ user_insert(weapon, user)
+
+ return COMPONENT_NO_AFTERATTACK
+//===============================================================================================
+
+
+//======================================Material Validation=======================================
+
+//=========================================LOW LEVEL===================================
/**
- * Splits a stack. we don't use /obj/item/stack/proc/split_stack because Byond complains that should only be called asynchronously.
- * This proc is also more faster because it doesn't deal with mobs, copying evidences or refreshing atom storages
- */
-/datum/component/material_container/proc/split_stack(obj/item/stack/target, amount)
- if(!target.use(amount, TRUE, FALSE))
- return null
-
- . = new target.type(target.drop_location(), amount, FALSE, target.mats_per_unit)
- target.loc.atom_storage?.refresh_views()
-
- target.is_zero_amount(delete_if_zero = TRUE)
-
-/// Proc specifically for inserting items, returns the amount of materials entered.
-/datum/component/material_container/proc/insert_item(obj/item/weapon, multiplier = 1, breakdown_flags = mat_container_flags)
- if(QDELETED(weapon))
- return MATERIAL_INSERT_ITEM_NO_MATS
- multiplier = CEILING(multiplier, 0.01)
-
- var/obj/item/target = weapon
-
- var/material_amount = get_item_material_amount(target, breakdown_flags) * multiplier
- if(!material_amount)
- return MATERIAL_INSERT_ITEM_NO_MATS
- var/obj/item/stack/item_stack
- if(isstack(weapon) && !has_space(material_amount)) //not enugh space split and feed as many sheets possible
- item_stack = weapon
- var/space_left = max_amount - total_amount
- if(!space_left)
- return MATERIAL_INSERT_ITEM_NO_SPACE
- var/material_per_sheet = material_amount / item_stack.amount
- var/sheets_to_insert = round(space_left / material_per_sheet)
- if(!sheets_to_insert)
- return MATERIAL_INSERT_ITEM_NO_SPACE
- target = split_stack(item_stack, sheets_to_insert)
- material_amount = get_item_material_amount(target, breakdown_flags) * multiplier
- if(!has_space(material_amount))
- return MATERIAL_INSERT_ITEM_NO_SPACE
-
- last_inserted_id = insert_item_materials(target, multiplier, breakdown_flags)
- if(!isnull(last_inserted_id))
- if(after_insert)
- after_insert.Invoke(target, last_inserted_id, material_amount, src)
- qdel(target) //item gone
- return material_amount
- else if(!isnull(item_stack) && item_stack != target) //insertion failed, merge the split stack back into the original
- var/obj/item/stack/inserting_stack = target
- item_stack.add(inserting_stack.amount)
- qdel(inserting_stack)
- return MATERIAL_INSERT_ITEM_FAILURE
-
-/**
- * Inserts the relevant materials from an item into this material container.
+ * Proc that returns TRUE if the container has space
*
* Arguments:
- * - [source][/obj/item]: The source of the materials we are inserting.
- * - multiplier: The multiplier for the materials being inserted.
- * - breakdown_flags: The breakdown bitflags that will be used to retrieve the materials from the source
+ * - amt: can this container hold this much amount of materials
*/
-/datum/component/material_container/proc/insert_item_materials(obj/item/source, multiplier = 1, breakdown_flags = mat_container_flags)
- var/primary_mat
- var/max_mat_value = 0
- var/list/item_materials = source.get_material_composition(breakdown_flags)
- for(var/MAT in item_materials)
- if(!can_hold_material(MAT))
- continue
- materials[MAT] += item_materials[MAT] * multiplier
- total_amount += item_materials[MAT] * multiplier
- if(item_materials[MAT] > max_mat_value)
- max_mat_value = item_materials[MAT]
- primary_mat = MAT
-
- return primary_mat
+/datum/component/material_container/proc/has_space(amt = 0)
+ return (total_amount() + amt) <= max_amount
/**
* The default check for whether we can add materials to this material container.
@@ -379,102 +429,146 @@
if(istype(mat) && ((mat.id in allowed_materials) || (mat.type in allowed_materials)))
allowed_materials += mat // This could get messy with passing lists by ref... but if you're doing that the list expansion is probably being taken care of elsewhere anyway...
return TRUE
- if(insertion_check?.Invoke(mat))
+ if(SEND_SIGNAL(src, COMSIG_MATCONTAINER_MAT_CHECK, mat) & MATCONTAINER_ALLOW_MAT)
allowed_materials += mat
return TRUE
return FALSE
+//========================================================================================
-/// For inserting an amount of material
-/datum/component/material_container/proc/insert_amount_mat(amt, datum/material/mat)
- if(amt <= 0 || !has_space(amt))
- return 0
- var/total_amount_saved = total_amount
- if(mat)
- if(!istype(mat))
- mat = GET_MATERIAL_REF(mat)
- materials[mat] += amt
- else
- var/num_materials = length(materials)
- if(!num_materials)
- return 0
-
- amt /= num_materials
- for(var/i in materials)
- materials[i] += amt
- total_amount += amt
- return (total_amount - total_amount_saved)
-
-/// Uses an amount of a specific material, effectively removing it.
-/datum/component/material_container/proc/use_amount_mat(amt, datum/material/mat)
+//===================================MID LEVEL=============================================
+/**
+ * Returns the amount of a specific material in this container.
+ *
+ * Arguments:
+ * -[mat][datum/material] : the material type to check for 3 cases
+ * a) If it's an path its ref is retrived
+ * b) If it's text then its an category material & there is no way to deal with it so return 0
+ * c) If normal material proceeds as usual
+ */
+/datum/component/material_container/proc/get_material_amount(datum/material/mat)
if(!istype(mat))
mat = GET_MATERIAL_REF(mat)
+ return materials[mat]
- if(!mat)
- return 0
- var/amount = materials[mat]
- if(amount < amt)
+/**
+ * Returns the amount of material relevant to this container;
+ * if this container does not support glass, any glass in 'I' will not be taken into account
+ *
+ * Arguments:
+ * - [I][obj/item]: the item whos materials must be retrived
+ * - breakdown_flags: how this item must be broken down to retrive its materials
+ */
+/datum/component/material_container/proc/get_item_material_amount(obj/item/I, breakdown_flags = mat_container_flags)
+ if(!istype(I) || !I.custom_materials)
return 0
+ var/material_amount = 0
+ var/list/item_materials = I.get_material_composition(breakdown_flags)
+ for(var/MAT in item_materials)
+ if(!can_hold_material(MAT))
+ continue
+ material_amount += item_materials[MAT]
+ return material_amount
+//================================================================================================
- materials[mat] -= amt
- total_amount -= amt
- return amt
-/// Proc for transfering materials to another container.
-/datum/component/material_container/proc/transer_amt_to(datum/component/material_container/T, amt, datum/material/mat)
- if(!istype(mat))
- mat = GET_MATERIAL_REF(mat)
- if((amt == 0) || (!T) || (!mat))
+//=========================================HIGH LEVEL==========================================
+/// returns the total amount of material in the container
+/datum/component/material_container/proc/total_amount()
+ . = 0
+ for(var/i in materials)
+ . += get_material_amount(i)
+
+/**
+ * Returns TRUE if you have enough of the specified material.
+ *
+ * Arguments:
+ * - [req_mat][datum/material]: the material to check for
+ * - amount: how much material do we need
+ */
+/datum/component/material_container/proc/has_enough_of_material(datum/material/req_mat, amount = 1)
+ return get_material_amount(req_mat) >= OPTIMAL_COST(amount)
+
+
+/**
+ * Checks if its possible to afford a certain amount of materials. Takes a dictionary of materials.
+ * coefficient can be thought of as the machines efficiency & multiplier as the print quantity
+ *
+ * Arguments:
+ * - mats: list of materials(key=material, value= 1 unit of material) to check for
+ * - coefficient: scaling applied to 1 unit of material in the mats list
+ * - multiplier: how many units(after scaling) do we require
+ */
+/datum/component/material_container/proc/has_materials(list/mats, coefficient = 1, multiplier = 1)
+ if(!length(mats))
return FALSE
- if(amt<0)
- return T.transer_amt_to(src, -amt, mat)
- var/tr = min(amt, materials[mat], T.can_insert_amount_mat(amt, mat))
- if(tr)
- use_amount_mat(tr, mat)
- T.insert_amount_mat(tr, mat)
- return tr
- return FALSE
-/// Proc for checking if there is room in the component, returning the amount or else the amount lacking.
-/datum/component/material_container/proc/can_insert_amount_mat(amt, datum/material/mat)
- if(!amt || !mat)
+ for(var/x in mats) //Loop through all required materials
+ if(!has_enough_of_material(x, OPTIMAL_COST(mats[x] * coefficient) * multiplier))//Not a category, so just check the normal way
+ return FALSE
+
+ return TRUE
+//==========================================================================================================
+
+
+//================================================Material Usage============================================
+
+//==================================================LOW LEVEL=======================================
+/**
+ * Uses an amount of a specific material, effectively removing it.
+ *
+ * Arguments:
+ * - amt: amount of said material to use
+ * - [mat][datum/material]: type of mat to use
+ */
+/datum/component/material_container/proc/use_amount_mat(amt, datum/material/mat)
+ //round amount
+ amt = OPTIMAL_COST(amt)
+
+ //get ref if nessassary
+ if(!istype(mat))
+ mat = GET_MATERIAL_REF(mat)
+
+ //check if sufficient is available
+ if(materials[mat] < amt)
return 0
- if((total_amount + amt) <= max_amount)
- return amt
- else
- return (max_amount - total_amount)
+ //consume & return amount consumed
+ materials[mat] -= amt
+ return amt
+//==============================================================================================
-
-/// For consuming a dictionary of materials. mats is the map of materials to use and the corresponding amounts, example: list(M/datum/material/glass =100, datum/material/iron=SMALL_MATERIAL_AMOUNT * 2)
-/datum/component/material_container/proc/use_materials(list/mats, multiplier=1)
+//=========================================MID LEVEL==========================================
+/**
+ * For consuming a dictionary of materials.
+ *
+ * Arguments:
+ * - mats: map of materials to consume(key = material type, value = amount)
+ * - coefficient: how much fraction of unit material in the mats list must be consumed. This is usually your machines efficiency
+ * - multiplier: how many units of material in the mats list(after each unit is multiplied and rounded with coefficient) must be consumed, This is usually your print quantity
+ */
+/datum/component/material_container/proc/use_materials(list/mats, coefficient = 1, multiplier = 1)
if(!mats || !length(mats))
return FALSE
- var/list/mats_to_remove = list() //Assoc list MAT | AMOUNT
+ var/amount_removed = 0
+ for(var/i in mats)
+ amount_removed += use_amount_mat(OPTIMAL_COST(mats[i] * coefficient) * multiplier, i)
- for(var/x in mats) //Loop through all required materials
- var/datum/material/req_mat = x
- if(!istype(req_mat))
- req_mat = GET_MATERIAL_REF(req_mat) //Get the ref if necesary
- if(!materials[req_mat]) //Do we have the resource?
- return FALSE //Can't afford it
- var/amount_required = mats[x] * multiplier
- if(amount_required < 0)
- return FALSE //No negative mats
- if(!(materials[req_mat] >= amount_required)) // do we have enough of the resource?
- return FALSE //Can't afford it
- mats_to_remove[req_mat] += amount_required //Add it to the assoc list of things to remove
- continue
+ return amount_removed
+//============================================================================================
- var/total_amount_save = total_amount
- for(var/i in mats_to_remove)
- total_amount_save -= use_amount_mat(mats_to_remove[i], i)
+//===========================================HIGH LEVEL=======================================
- return total_amount_save - total_amount
-
-/// For spawning mineral sheets at a specific location. Used by machines to output sheets.
+/**
+ * For spawning mineral sheets at a specific location. Used by machines to output sheets.
+ *
+ * Arguments:
+ * sheet_amt: number of sheets to extract
+ * [material][datum/material]: type of sheets present in this container to extract
+ * [target][atom]: drop location
+ */
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, datum/material/material, atom/target = null)
if(!material.sheet_type)
return 0 //Add greyscale sheet handling here later
@@ -489,108 +583,32 @@
var/count = 0
while(sheet_amt > MAX_STACK_SIZE)
var/obj/item/stack/sheet/new_sheets = new material.sheet_type(target, MAX_STACK_SIZE, null, list((material) = SHEET_MATERIAL_AMOUNT))
- after_retrieve?.Invoke(new_sheets)
count += MAX_STACK_SIZE
use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, material)
sheet_amt -= MAX_STACK_SIZE
+ SEND_SIGNAL(src, COMSIG_MATCONTAINER_SHEETS_RETRIVED, new_sheets)
if(sheet_amt >= 1)
var/obj/item/stack/sheet/new_sheets = new material.sheet_type(target, sheet_amt, null, list((material) = SHEET_MATERIAL_AMOUNT))
- after_retrieve?.Invoke(new_sheets)
count += sheet_amt
use_amount_mat(sheet_amt * SHEET_MATERIAL_AMOUNT, material)
+ SEND_SIGNAL(src, COMSIG_MATCONTAINER_SHEETS_RETRIVED, new_sheets)
return count
-/// Proc to get all the materials and dump them as sheets
+/**
+ * Proc to get all the materials and dump them as sheets
+ *
+ * Arguments:
+ * - target: drop location of the sheets
+ */
/datum/component/material_container/proc/retrieve_all(target = null)
var/result = 0
for(var/MAT in materials)
var/amount = materials[MAT]
result += retrieve_sheets(amount2sheet(amount), MAT, target)
return result
+//============================================================================================
-/// Proc that returns TRUE if the container has space
-/datum/component/material_container/proc/has_space(amt = 0)
- return (total_amount + amt) <= max_amount
-
-/// Checks if its possible to afford a certain amount of materials. Takes a dictionary of materials.
-/datum/component/material_container/proc/has_materials(list/mats, multiplier=1)
- if(!mats || !mats.len)
- return FALSE
-
- for(var/x in mats) //Loop through all required materials
- var/datum/material/req_mat = x
- if(!istype(req_mat))
- if(ispath(req_mat)) //Is this an actual material, or is it a category?
- req_mat = GET_MATERIAL_REF(req_mat) //Get the ref
-
- else // Its a category. (For example MAT_CATEGORY_RIGID)
- if(!has_enough_of_category(req_mat, mats[x], multiplier)) //Do we have enough of this category?
- return FALSE
- else
- continue
-
- if(!has_enough_of_material(req_mat, mats[x], multiplier))//Not a category, so just check the normal way
- return FALSE
-
- return TRUE
-
-/// Returns all the categories in a recipe.
-/datum/component/material_container/proc/get_categories(list/mats)
- var/list/categories = list()
- for(var/x in mats) //Loop through all required materials
- if(!istext(x)) //This means its not a category
- continue
- categories += x
- return categories
-
-/// Returns TRUE if you have enough of the specified material.
-/datum/component/material_container/proc/has_enough_of_material(datum/material/req_mat, amount, multiplier=1)
- if(!materials[req_mat]) //Do we have the resource?
- return FALSE //Can't afford it
- var/amount_required = amount * multiplier
- if(materials[req_mat] >= amount_required) // do we have enough of the resource?
- return TRUE
- return FALSE //Can't afford it
-
-/// Returns TRUE if you have enough of a specified material category (Which could be multiple materials)
-/datum/component/material_container/proc/has_enough_of_category(category, amount, multiplier=1)
- for(var/i in SSmaterials.materials_by_category[category])
- var/datum/material/mat = i
- if(materials[mat] >= amount) //we have enough
- return TRUE
- return FALSE
-
-/// Turns a material amount into the amount of sheets it should output
-/datum/component/material_container/proc/amount2sheet(amt)
- if(amt >= SHEET_MATERIAL_AMOUNT)
- return round(amt / SHEET_MATERIAL_AMOUNT)
- return FALSE
-
-/// Turns an amount of sheets into the amount of material amount it should output
-/datum/component/material_container/proc/sheet2amount(sheet_amt)
- if(sheet_amt > 0)
- return sheet_amt * SHEET_MATERIAL_AMOUNT
- return FALSE
-
-
-///returns the amount of material relevant to this container; if this container does not support glass, any glass in 'I' will not be taken into account
-/datum/component/material_container/proc/get_item_material_amount(obj/item/I, breakdown_flags = mat_container_flags)
- if(!istype(I) || !I.custom_materials)
- return 0
- var/material_amount = 0
- var/list/item_materials = I.get_material_composition(breakdown_flags)
- for(var/MAT in item_materials)
- if(!can_hold_material(MAT))
- continue
- material_amount += item_materials[MAT]
- return material_amount
-
-/// Returns the amount of a specific material in this container.
-/datum/component/material_container/proc/get_material_amount(datum/material/mat)
- if(!istype(mat))
- mat = GET_MATERIAL_REF(mat)
- return materials[mat]
/datum/component/material_container/ui_static_data(mob/user)
var/list/data = list()
@@ -608,8 +626,6 @@
"name" = material.name,
"ref" = REF(material),
"amount" = amount,
- "sheets" = round(amount / SHEET_MATERIAL_AMOUNT),
- "removable" = amount >= SHEET_MATERIAL_AMOUNT,
"color" = material.greyscale_colors
))
diff --git a/code/datums/components/remote_materials.dm b/code/datums/components/material/remote_materials.dm
similarity index 77%
rename from code/datums/components/remote_materials.dm
rename to code/datums/components/material/remote_materials.dm
index a3c61221c6f..e20a4dbdaec 100644
--- a/code/datums/components/remote_materials.dm
+++ b/code/datums/components/material/remote_materials.dm
@@ -10,19 +10,24 @@ handles linking back and forth.
// 1. silo exists, materials is parented to silo
// 2. silo is null, materials is parented to parent
// 3. silo is null, materials is null
+
+ /// The silo machine this container is connected to
var/obj/machinery/ore_silo/silo
+ //material container. the value is either the silo or local
var/datum/component/material_container/mat_container
- var/category
+ //should we create a local storage if we can't connect to silo
var/allow_standalone
+ //are we trying to connect to the silo
+ var/connecting
+ //local size of container when silo = null
var/local_size = INFINITY
///Flags used when converting inserted materials into their component materials.
var/mat_container_flags = NONE
-/datum/component/remote_materials/Initialize(category, mapload, allow_standalone = TRUE, force_connect = FALSE, mat_container_flags=NONE)
+/datum/component/remote_materials/Initialize(mapload, allow_standalone = TRUE, force_connect = FALSE, mat_container_flags = NONE)
if (!isatom(parent))
return COMPONENT_INCOMPATIBLE
- src.category = category
src.allow_standalone = allow_standalone
src.mat_container_flags = mat_container_flags
@@ -30,30 +35,26 @@ handles linking back and forth.
RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_MULTITOOL), PROC_REF(OnMultitool))
var/turf/T = get_turf(parent)
- if (force_connect || (mapload && is_station_level(T.z)))
- addtimer(CALLBACK(src, PROC_REF(LateInitialize)))
- else if (allow_standalone)
- _MakeLocal()
+ if(force_connect || (mapload && is_station_level(T.z)))
+ connecting = TRUE
-/datum/component/remote_materials/proc/LateInitialize()
- silo = GLOB.ore_silo_default
- if (silo)
- silo.ore_connected_machines += src
- mat_container = silo.GetComponent(/datum/component/material_container)
- else
+/datum/component/remote_materials/RegisterWithParent()
+ if (connecting)
+ silo = GLOB.ore_silo_default
+ if (silo)
+ silo.ore_connected_machines += src
+ mat_container = silo.GetComponent(/datum/component/material_container)
+ connecting = FALSE
+ if (!mat_container && allow_standalone)
_MakeLocal()
/datum/component/remote_materials/Destroy()
if (silo)
silo.ore_connected_machines -= src
+ silo.holds -= src
silo.updateUsrDialog()
silo = null
- mat_container = null
- else if (mat_container)
- // specify explicitly in case the other component is deleted first
- var/atom/P = parent
- mat_container.retrieve_all(P.drop_location())
- QDEL_NULL(mat_container)
+ mat_container = null
return ..()
/datum/component/remote_materials/proc/_MakeLocal()
@@ -71,9 +72,15 @@ handles linking back and forth.
/datum/material/titanium,
/datum/material/bluespace,
/datum/material/plastic,
- )
+ )
- mat_container = parent.AddComponent(/datum/component/material_container, allowed_mats, local_size, mat_container_flags, allowed_items=/obj/item/stack)
+ mat_container = parent.AddComponent( \
+ /datum/component/material_container, \
+ allowed_mats, \
+ local_size, \
+ mat_container_flags, \
+ allowed_items = /obj/item/stack \
+ )
/datum/component/remote_materials/proc/toggle_holding(force_hold = FALSE)
if(isnull(silo))
@@ -123,9 +130,9 @@ handles linking back and forth.
return COMPONENT_BLOCK_TOOL_ATTACK
if (silo)
silo.ore_connected_machines -= src
+ silo.holds -= src
silo.updateUsrDialog()
else if (mat_container)
- mat_container.retrieve_all()
qdel(mat_container)
silo = M.buffer
silo.ore_connected_machines += src
@@ -150,7 +157,7 @@ handles linking back and forth.
/datum/component/remote_materials/proc/on_hold()
if(!check_z_level())
return FALSE
- return silo.holds["[get_area(parent)]/[category]"]
+ return silo.holds[src]
/datum/component/remote_materials/proc/silo_log(obj/machinery/M, action, amount, noun, list/mats)
if (silo)
@@ -158,7 +165,7 @@ handles linking back and forth.
/datum/component/remote_materials/proc/format_amount()
if (mat_container)
- return "[mat_container.total_amount] / [mat_container.max_amount == INFINITY ? "Unlimited" : mat_container.max_amount] ([silo ? "remote" : "local"])"
+ return "[mat_container.total_amount()] / [mat_container.max_amount == INFINITY ? "Unlimited" : mat_container.max_amount] ([silo ? "remote" : "local"])"
else
return "0 / 0"
@@ -179,10 +186,3 @@ handles linking back and forth.
matlist[material_ref] = eject_amount
silo_log(parent, "ejected", -count, "sheets", matlist)
return count
-
-/// Returns `TRUE` if and only if the given material ref can be inserted/removed from this component
-/datum/component/remote_materials/proc/can_hold_material(datum/material/material_ref)
- if(!mat_container)
- return FALSE
-
- return mat_container.can_hold_material(material_ref)
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index d1a7de25556..6ad97655c4c 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -22,15 +22,26 @@
///Designs imported from technology disks that we can print.
var/list/imported_designs = list()
+ ///The container to hold materials
+ var/datum/component/material_container/materials
+
/obj/machinery/autolathe/Initialize(mapload)
- AddComponent(/datum/component/material_container, SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], 0, MATCONTAINER_EXAMINE, _after_insert = CALLBACK(src, PROC_REF(AfterMaterialInsert)))
+ materials = AddComponent( \
+ /datum/component/material_container, \
+ SSmaterials.materials_by_category[MAT_CATEGORY_ITEM_MATERIAL], \
+ 0, \
+ MATCONTAINER_EXAMINE, \
+ container_signals = list(COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/autolathe, AfterMaterialInsert)) \
+ )
. = ..()
+
set_wires(new /datum/wires/autolathe(src))
if(!GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe])
GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe] = new /datum/techweb/autounlocking/autolathe
stored_research = GLOB.autounlock_techwebs[/datum/techweb/autounlocking/autolathe]
/obj/machinery/autolathe/Destroy()
+ materials = null
QDEL_NULL(wires)
return ..()
@@ -48,7 +59,7 @@
ui.open()
/obj/machinery/autolathe/ui_static_data(mob/user)
- var/list/data = list()
+ var/list/data = materials.ui_static_data()
data["designs"] = handle_designs(stored_research.researched_designs)
if(imported_designs.len)
@@ -62,10 +73,7 @@
var/list/data = list()
data["materials"] = list()
-
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
-
- data["materialtotal"] = materials.total_amount
+ data["materialtotal"] = materials.total_amount()
data["materialsmax"] = materials.max_amount
data["active"] = busy
data["materials"] = materials.ui_data()
@@ -78,63 +86,38 @@
var/datum/asset/spritesheet/research_designs/spritesheet = get_asset_datum(/datum/asset/spritesheet/research_designs)
var/size32x32 = "[spritesheet.name]32x32"
+ var/max_multiplier = INFINITY
for(var/design_id in designs)
var/datum/design/design = SSresearch.techweb_design_by_id(design_id)
+ if(design.make_reagent)
+ continue
- var/unbuildable = FALSE // we can't build the design currently
- var/m10 = FALSE // 10x mult
- var/m25 = FALSE // 25x mult
- var/m50 = FALSE // 50x mult
- var/m5 = FALSE // 5x mult
- var/sheets = FALSE // sheets or no?
+ //compute cost & maximum number of printable items
+ max_multiplier = INFINITY
+ var/coeff = (ispath(design.build_path, /obj/item/stack) ? 1 : creation_efficiency)
+ var/list/cost = list()
+ for(var/i in design.materials)
+ var/datum/material/mat = i
- if(disabled || !can_build(design))
- unbuildable = TRUE
+ var/design_cost = OPTIMAL_COST(design.materials[i] * coeff)
+ if(istype(mat))
+ cost[mat.name] = design_cost
+ else
+ cost[i] = design_cost
- var/max_multiplier = unbuildable ? 0 : 1
-
- if(ispath(design.build_path, /obj/item/stack))
- sheets = TRUE
-
- if(!unbuildable)
- var/datum/component/material_container/mats = GetComponent(/datum/component/material_container)
-
- for(var/datum/material/mat in design.materials)
- max_multiplier = min(design.maxstack, round(mats.get_material_amount(mat) / design.materials[mat]))
- if (max_multiplier >= 10 && !disabled)
- m10 = TRUE
- if (max_multiplier >= 25 && !disabled)
- m25 = TRUE
- else
- if(!unbuildable)
- if(!disabled && can_build(design, 5))
- m5 = TRUE
- if(!disabled && can_build(design, 10))
- m10 = TRUE
-
- var/datum/component/material_container/mats = GetComponent(/datum/component/material_container)
-
- for(var/datum/material/mat in design.materials)
- max_multiplier = min(50, round(mats.get_material_amount(mat) / (design.materials[mat] * creation_efficiency)))
+ max_multiplier = min(max_multiplier, 50, round((istype(mat) ? materials.get_material_amount(i) : 0) / design_cost))
+ //create & send ui data
var/icon_size = spritesheet.icon_size_id(design.id)
-
var/list/design_data = list(
"name" = design.name,
"desc" = design.get_description(),
- "cost" = get_design_cost(design),
+ "cost" = cost,
"id" = design.id,
"categories" = design.category,
"icon" = "[icon_size == size32x32 ? "" : "[icon_size] "][design.id]",
"constructionTime" = -1,
-
- "buildable" = unbuildable,
- "mult5" = m5,
- "mult10" = m10,
- "mult25" = m25,
- "mult50" = m50,
- "sheet" = sheets,
- "maxmult" = max_multiplier,
+ "maxmult" = max_multiplier
)
output += list(design_data)
@@ -153,85 +136,78 @@
return
if(action == "make")
+ if(disabled)
+ say("The autolathe wires are disabled.")
+ return
+ if(busy)
+ say("The autolathe is busy. Please wait for completion of previous operation.")
+ return
+
var/design_id = params["id"]
if(!istext(design_id))
return
-
if(!stored_research.researched_designs.Find(design_id) && !stored_research.hacked_designs.Find(design_id) && !imported_designs.Find(design_id))
return
-
var/datum/design/design = SSresearch.techweb_design_by_id(design_id)
-
if(!(design.build_type & AUTOLATHE) || design.id != design_id)
return
- if (busy)
- to_chat(usr, span_alert("The autolathe is busy. Please wait for completion of previous operation."))
- return
-
being_built = design
+ var/is_stack = ispath(being_built.build_path, /obj/item/stack)
+ var/coeff = (is_stack ? 1 : creation_efficiency) // Stacks are unaffected by production coefficient
var/multiplier = round(text2num(params["multiplier"]))
-
if(!multiplier || !IS_FINITE(multiplier))
return
-
- var/is_stack = ispath(being_built.build_path, /obj/item/stack)
multiplier = clamp(multiplier, 1, 50)
- var/coeff = (is_stack ? 1 : creation_efficiency) // Stacks are unaffected by production coefficient
- var/total_amount = 0
-
- for(var/material in being_built.materials)
- total_amount += being_built.materials[material]
-
- var/power = max(active_power_usage, (total_amount)*multiplier/5) // Change this to use all materials
-
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
-
+ //check for materials
var/list/materials_used = list()
var/list/custom_materials = list() // These will apply their material effect, should usually only be one.
-
for(var/mat in being_built.materials)
var/datum/material/used_material = mat
- var/amount_needed = being_built.materials[mat] * coeff * multiplier
+ var/amount_needed = being_built.materials[mat]
if(istext(used_material)) // This means its a category
var/list/list_to_show = list()
-
+ //list all materials in said category
for(var/i in SSmaterials.materials_by_category[used_material])
if(materials.materials[i] > 0)
list_to_show += i
-
+ //ask user to pick specific material from list
used_material = tgui_input_list(
usr,
"Choose [used_material]",
"Custom Material",
sort_list(list_to_show, GLOBAL_PROC_REF(cmp_typepaths_asc))
)
-
if(isnull(used_material))
- // Didn't pick any material, so you can't build shit either.
return
-
+ //the item composition will be made of these materials
custom_materials[used_material] += amount_needed
-
materials_used[used_material] = amount_needed
- if(materials.has_materials(materials_used))
- busy = TRUE
- to_chat(usr, span_notice("You print [multiplier] item(s) from the [src]"))
- use_power(power)
- icon_state = "autolathe_n"
- var/time = is_stack ? 32 : (32 * coeff * multiplier) ** 0.8
- addtimer(CALLBACK(src, PROC_REF(make_item), power, materials_used, custom_materials, multiplier, coeff, is_stack, usr), time)
- . = TRUE
- else
- to_chat(usr, span_alert("Not enough materials for this operation."))
+ if(!materials.has_materials(materials_used, coeff, multiplier))
+ say("Not enough materials for this operation!.")
+ return
-/obj/machinery/autolathe/on_deconstruction()
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- materials.retrieve_all()
+ //use power
+ var/total_amount = 0
+ for(var/material in being_built.materials)
+ total_amount += being_built.materials[material]
+ use_power(max(active_power_usage, (total_amount) * multiplier / 5))
+
+ //use materials
+ materials.use_materials(materials_used, coeff, multiplier)
+ busy = TRUE
+ to_chat(usr, span_notice("You print [multiplier] item(s) from the [src]"))
+ update_static_data_for_all_viewers()
+ //print item
+ icon_state = "autolathe_n"
+ var/time = is_stack ? 32 : (32 * coeff * multiplier) ** 0.8
+ addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/autolathe, make_item), custom_materials, multiplier, is_stack, usr), time)
+
+ return TRUE
/obj/machinery/autolathe/attackby(obj/item/attacking_item, mob/living/user, params)
if(busy)
@@ -303,8 +279,10 @@
return SECONDARY_ATTACK_CALL_NORMAL
-/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/item/item_inserted, id_inserted, amount_inserted)
- if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
+/obj/machinery/autolathe/proc/AfterMaterialInsert(obj/machinery/machine, obj/item/item_inserted, last_inserted_id, amount_inserted, container)
+ SIGNAL_HANDLER
+
+ if(ispath(item_inserted, /obj/item/stack/ore/bluespace_crystal))
use_power(SHEET_MATERIAL_AMOUNT / 10)
else if(item_inserted.has_material_type(/datum/material/glass))
flick("autolathe_r", src)//plays glass insertion animation by default otherwise
@@ -312,13 +290,10 @@
flick("autolathe_o", src)//plays metal insertion animation
use_power(min(active_power_usage * 0.25, amount_inserted / 100))
+ update_static_data_for_all_viewers()
-/obj/machinery/autolathe/proc/make_item(power, list/materials_used, list/picked_materials, multiplier, coeff, is_stack, mob/user)
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
+/obj/machinery/autolathe/proc/make_item(list/picked_materials, multiplier, is_stack, mob/user)
var/atom/A = drop_location()
- use_power(power)
-
- materials.use_materials(materials_used)
if(is_stack)
var/obj/item/stack/N = new being_built.build_path(A, multiplier, FALSE)
@@ -334,7 +309,6 @@
if(!istype(M, /datum/material/glass) && !istype(M, /datum/material/iron))
user.client.give_award(/datum/award/achievement/misc/getting_an_upgrade, user)
-
icon_state = "autolathe"
busy = FALSE
@@ -343,7 +317,6 @@
var/mat_capacity = 0
for(var/datum/stock_part/matter_bin/new_matter_bin in component_parts)
mat_capacity += new_matter_bin.tier * (37.5*SHEET_MATERIAL_AMOUNT)
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.max_amount = mat_capacity
var/efficiency=1.8
@@ -353,40 +326,9 @@
/obj/machinery/autolathe/examine(mob/user)
. += ..()
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(in_range(user, src) || isobserver(user))
. += span_notice("The status display reads: Storing up to [materials.max_amount] material units.
Material consumption at [creation_efficiency*100]%.")
-/obj/machinery/autolathe/proc/can_build(datum/design/D, amount = 1)
- if(D.make_reagent)
- return FALSE
-
- var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : creation_efficiency)
-
- var/list/required_materials = list()
-
- for(var/i in D.materials)
- required_materials[i] = D.materials[i] * coeff * amount
-
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
-
- return materials.has_materials(required_materials)
-
-
-/obj/machinery/autolathe/proc/get_design_cost(datum/design/design)
- var/coeff = (ispath(design.build_path, /obj/item/stack) ? 1 : creation_efficiency)
- var/list/cost = list()
-
- for(var/material in design.materials)
- if (istext(material))
- // Wildcard materials
- cost[material] = design.materials[material] * coeff
- else
- var/datum/material/cast = material
- cost[cast.name] = design.materials[cast] * coeff
-
- return cost
-
/obj/machinery/autolathe/proc/reset(wire)
switch(wire)
if(WIRE_HACK)
diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm
index 8b4ba250a43..4b3c2a37d50 100644
--- a/code/game/machinery/droneDispenser.dm
+++ b/code/game/machinery/droneDispenser.dm
@@ -21,8 +21,8 @@
var/list/using_materials
var/starting_amount = 0
- var/iron_cost =HALF_SHEET_MATERIAL_AMOUNT
- var/glass_cost =HALF_SHEET_MATERIAL_AMOUNT
+ var/iron_cost = HALF_SHEET_MATERIAL_AMOUNT
+ var/glass_cost = HALF_SHEET_MATERIAL_AMOUNT
var/power_used = 1000
var/mode = DRONE_READY
@@ -48,16 +48,28 @@
var/break_message = "lets out a tinny alarm before falling dark."
var/break_sound = 'sound/machines/warning-buzzer.ogg'
+ var/datum/component/material_container/materials
+
/obj/machinery/drone_dispenser/Initialize(mapload)
. = ..()
- var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(/datum/material/iron, /datum/material/glass), SHEET_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, MATCONTAINER_EXAMINE|BREAKDOWN_FLAGS_DRONE_DISPENSER, allowed_items=/obj/item/stack)
+ materials = AddComponent( \
+ /datum/component/material_container, \
+ list(/datum/material/iron, /datum/material/glass), \
+ SHEET_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, \
+ MATCONTAINER_EXAMINE|BREAKDOWN_FLAGS_DRONE_DISPENSER, \
+ allowed_items=/obj/item/stack \
+ )
materials.insert_amount_mat(starting_amount)
materials.precise_insertion = TRUE
using_materials = list(/datum/material/iron = iron_cost, /datum/material/glass = glass_cost)
REGISTER_REQUIRED_MAP_ITEM(1, 1)
+/obj/machinery/drone_dispenser/Destroy()
+ materials = null
+ return ..()
+
/obj/machinery/drone_dispenser/preloaded
- starting_amount = 5000
+ starting_amount = SHEET_MATERIAL_AMOUNT * 2.5
/obj/machinery/drone_dispenser/syndrone //Please forgive me
name = "syndrone shell dispenser"
@@ -66,7 +78,7 @@
//If we're gonna be a jackass, go the full mile - 10 second recharge timer
cooldownTime = 100
end_create_message = "dispenses a suspicious drone shell."
- starting_amount = 25000
+ starting_amount = SHEET_MATERIAL_AMOUNT * 12.5
/obj/machinery/drone_dispenser/syndrone/badass //Please forgive me
name = "badass syndrone shell dispenser"
@@ -81,10 +93,10 @@
dispense_type = /obj/effect/mob_spawn/ghost_role/drone/snowflake
end_create_message = "dispenses a snowflake drone shell."
// Those holoprojectors aren't cheap
- iron_cost =SHEET_MATERIAL_AMOUNT
- glass_cost =SHEET_MATERIAL_AMOUNT
+ iron_cost = SHEET_MATERIAL_AMOUNT
+ glass_cost = SHEET_MATERIAL_AMOUNT
power_used = 2000
- starting_amount = 10000
+ starting_amount = SHEET_MATERIAL_AMOUNT * 5
// If the derelict gets lonely, make more friends.
/obj/machinery/drone_dispenser/derelict
@@ -92,8 +104,8 @@
desc = "A rusty machine that, when supplied with iron and glass, will periodically create a derelict drone shell. Does not need to be manually operated."
dispense_type = /obj/effect/mob_spawn/ghost_role/drone/derelict
end_create_message = "dispenses a derelict drone shell."
- iron_cost = 10000
- glass_cost = 5000
+ iron_cost = SHEET_MATERIAL_AMOUNT * 5
+ glass_cost = SHEET_MATERIAL_AMOUNT * 2.5
starting_amount = 0
cooldownTime = 600
@@ -128,11 +140,11 @@
. = ..()
var/material_requirement_string = "It needs "
if (iron_cost > 0)
- material_requirement_string += "[iron_cost] iron "
+ material_requirement_string += "[iron_cost / SHEET_MATERIAL_AMOUNT] iron sheets "
if (glass_cost > 0)
material_requirement_string += "and "
if (glass_cost > 0)
- material_requirement_string += "[glass_cost] glass "
+ material_requirement_string += "[glass_cost / SHEET_MATERIAL_AMOUNT] glass sheets "
if (iron_cost > 0 || glass_cost > 0)
material_requirement_string += "to produce one drone shell."
. += span_notice(material_requirement_string)
@@ -144,7 +156,6 @@
if((machine_stat & (NOPOWER|BROKEN)) || !anchored)
return
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(!materials.has_materials(using_materials))
return // We require more minerals
@@ -212,7 +223,6 @@
/obj/machinery/drone_dispenser/attackby(obj/item/I, mob/living/user)
if(I.tool_behaviour == TOOL_CROWBAR)
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
I.play_tool_sound(src)
to_chat(user, span_notice("You retrieve the materials from [src]."))
diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm
index 16af9a22423..415dacc9f17 100644
--- a/code/game/machinery/rechargestation.dm
+++ b/code/game/machinery/rechargestation.dm
@@ -21,7 +21,6 @@
materials = AddComponent(
/datum/component/remote_materials, \
- "charger", \
mapload, \
mat_container_flags = MATCONTAINER_NO_INSERT, \
)
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index fa75e70506c..3e78f2dfe54 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -17,6 +17,7 @@
var/crush_damage = 1000
var/eat_victim_items = TRUE
var/item_recycle_sound = 'sound/items/welder.ogg'
+ var/datum/component/material_container/materials
/obj/machinery/recycler/Initialize(mapload)
var/list/allowed_materials = list(
@@ -32,7 +33,7 @@
/datum/material/titanium,
/datum/material/bluespace
)
- AddComponent(/datum/component/material_container, allowed_materials, INFINITY, MATCONTAINER_NO_INSERT|BREAKDOWN_FLAGS_RECYCLER)
+ materials = AddComponent(/datum/component/material_container, allowed_materials, INFINITY, MATCONTAINER_NO_INSERT|BREAKDOWN_FLAGS_RECYCLER)
AddComponent(/datum/component/butchering/recycler, \
speed = 0.1 SECONDS, \
effectiveness = amount_produced, \
@@ -50,6 +51,10 @@
)
AddElement(/datum/element/connect_loc, loc_connections)
+/obj/machinery/recycler/Destroy()
+ materials = null
+ return ..()
+
/obj/machinery/recycler/RefreshParts()
. = ..()
var/amt_made = 0
@@ -183,7 +188,6 @@
new wood.plank_type(loc, 1 + seed_modifier)
. = TRUE
else
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/retrived = materials.insert_item(weapon, multiplier = (amount_produced / 100), breakdown_flags=BREAKDOWN_FLAGS_RECYCLER)
if(retrived > 0) //item was salvaged i.e. deleted
materials.retrieve_all()
diff --git a/code/game/machinery/sheetifier.dm b/code/game/machinery/sheetifier.dm
index 5b01dd99018..57decf63ae4 100644
--- a/code/game/machinery/sheetifier.dm
+++ b/code/game/machinery/sheetifier.dm
@@ -7,11 +7,25 @@
circuit = /obj/item/circuitboard/machine/sheetifier
layer = BELOW_OBJ_LAYER
var/busy_processing = FALSE
+ var/datum/component/material_container/materials
/obj/machinery/sheetifier/Initialize(mapload)
. = ..()
+ materials = AddComponent( \
+ /datum/component/material_container, \
+ list(/datum/material/meat, /datum/material/hauntium), \
+ SHEET_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, \
+ MATCONTAINER_EXAMINE|BREAKDOWN_FLAGS_SHEETIFIER, \
+ typesof(/datum/material/meat) + /datum/material/hauntium, list(/obj/item/food/meat, /obj/item/photo), \
+ container_signals = list(
+ COMSIG_MATCONTAINER_PRE_USER_INSERT = TYPE_PROC_REF(/obj/machinery/sheetifier, CanInsertMaterials),
+ COMSIG_MATCONTAINER_ITEM_CONSUMED = TYPE_PROC_REF(/obj/machinery/sheetifier, AfterInsertMaterials)
+ ) \
+ )
- AddComponent(/datum/component/material_container, list(/datum/material/meat, /datum/material/hauntium), SHEET_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, MATCONTAINER_EXAMINE|BREAKDOWN_FLAGS_SHEETIFIER, typesof(/datum/material/meat) + /datum/material/hauntium, list(/obj/item/food/meat, /obj/item/photo), null, CALLBACK(src, PROC_REF(CanInsertMaterials)), CALLBACK(src, PROC_REF(AfterInsertMaterials)))
+/obj/machinery/sheetifier/Destroy()
+ materials = null
+ return ..()
/obj/machinery/sheetifier/update_overlays()
. = ..()
@@ -24,10 +38,12 @@
icon_state = "base_machine[busy_processing ? "_processing" : ""]"
return ..()
-/obj/machinery/sheetifier/proc/CanInsertMaterials()
- return !busy_processing
+/obj/machinery/sheetifier/proc/CanInsertMaterials(obj/machinery/machine, held_item, user)
+ SIGNAL_HANDLER
-/obj/machinery/sheetifier/proc/AfterInsertMaterials(item_inserted, id_inserted, amount_inserted)
+ return busy_processing ? MATCONTAINER_BLOCK_INSERT : TRUE
+
+/obj/machinery/sheetifier/proc/AfterInsertMaterials(obj/machinery/machine, item_inserted, id_inserted, amount_inserted, container)
busy_processing = TRUE
update_appearance()
var/datum/material/last_inserted_material = id_inserted
@@ -39,7 +55,6 @@
/obj/machinery/sheetifier/proc/finish_processing()
busy_processing = FALSE
update_appearance()
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all() //Returns all as sheets
use_power(active_power_usage)
diff --git a/code/game/objects/items/rcd/RHD.dm b/code/game/objects/items/rcd/RHD.dm
index a296eefa973..68355267315 100644
--- a/code/game/objects/items/rcd/RHD.dm
+++ b/code/game/objects/items/rcd/RHD.dm
@@ -1,5 +1,7 @@
//RAPID HANDHELD DEVICE. the base for all rapid devices
+#define SILO_USE_AMOUNT (SHEET_MATERIAL_AMOUNT / 4)
+
/obj/item/construction
name = "not for ingame use"
desc = "A device used to rapidly build and deconstruct. Reload with iron, plasteel, glass or compressed matter cartridges."
@@ -13,7 +15,7 @@
throw_speed = 3
throw_range = 5
w_class = WEIGHT_CLASS_NORMAL
- custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT*50)
+ custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 50)
req_access = list(ACCESS_ENGINE_EQUIP)
armor_type = /datum/armor/item_construction
resistance_flags = FIRE_PROOF
@@ -46,13 +48,13 @@
spark_system.set_up(5, 0, src)
spark_system.attach(src)
if(upgrade & RCD_UPGRADE_SILO_LINK)
- silo_mats = AddComponent(/datum/component/remote_materials, "RCD", mapload, FALSE)
+ silo_mats = AddComponent(/datum/component/remote_materials, mapload, FALSE)
update_appearance()
///used for examining the RCD and for its UI
/obj/item/construction/proc/get_silo_iron()
if(silo_link && silo_mats.mat_container && !silo_mats.on_hold())
- return silo_mats.mat_container.get_material_amount(/datum/material/iron)/500
+ return silo_mats.mat_container.get_material_amount(/datum/material/iron) / SILO_USE_AMOUNT
return FALSE
///returns local matter units available. overriden by rcd borg to return power units available
@@ -99,7 +101,7 @@
return
upgrade |= design_disk.upgrade
if((design_disk.upgrade & RCD_UPGRADE_SILO_LINK) && !silo_mats)
- silo_mats = AddComponent(/datum/component/remote_materials, "RCD", FALSE, FALSE)
+ silo_mats = AddComponent(/datum/component/remote_materials, FALSE, FALSE)
playsound(loc, 'sound/machines/click.ogg', 50, TRUE)
qdel(design_disk)
@@ -171,16 +173,17 @@
balloon_alert(user, "silo on hold!")
return FALSE
if(!silo_mats.mat_container)
- balloon_alert(user, "no silo detected!")
+ if(user)
+ balloon_alert(user, "no silo detected!")
return FALSE
- if(!silo_mats.mat_container.has_materials(list(/datum/material/iron = 500), amount))
+ if(!silo_mats.mat_container.has_materials(list(/datum/material/iron = SILO_USE_AMOUNT), multiplier = amount))
if(user)
balloon_alert(user, "not enough silo material!")
return FALSE
var/list/materials = list()
- materials[GET_MATERIAL_REF(/datum/material/iron)] = 500
- silo_mats.mat_container.use_materials(materials, amount)
+ materials[GET_MATERIAL_REF(/datum/material/iron)] = SILO_USE_AMOUNT
+ silo_mats.mat_container.use_materials(materials, multiplier = amount)
silo_mats.silo_log(src, "consume", -amount, "build", materials)
return TRUE
@@ -235,7 +238,7 @@
if(user)
balloon_alert(user, "silo on hold!")
return FALSE
- . = silo_mats.mat_container.has_materials(list(/datum/material/iron = 500), amount)
+ . = silo_mats.mat_container.has_materials(list(/datum/material/iron = SILO_USE_AMOUNT), multiplier = amount)
if(!. && user)
balloon_alert(user, "low ammo!")
if(has_ammobar)
@@ -295,3 +298,4 @@
name = "Destruction Scan"
desc = "Scans the surrounding area for destruction. Scanned structures will rebuild significantly faster."
+#undef SILO_USE_AMOUNT
diff --git a/code/modules/antagonists/clown_ops/clown_weapons.dm b/code/modules/antagonists/clown_ops/clown_weapons.dm
index 5341a9db5ba..1c55e5416e2 100644
--- a/code/modules/antagonists/clown_ops/clown_weapons.dm
+++ b/code/modules/antagonists/clown_ops/clown_weapons.dm
@@ -64,13 +64,11 @@
. = ..()
create_storage(storage_type = /datum/storage/pockets/shoes)
-
- var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
bananium.insert_amount_mat(BANANA_SHOES_MAX_CHARGE, /datum/material/bananium)
+
START_PROCESSING(SSobj, src)
/obj/item/clothing/shoes/clown_shoes/banana_shoes/combat/process(seconds_per_tick)
- var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
var/bananium_amount = bananium.get_material_amount(/datum/material/bananium)
if(bananium_amount < BANANA_SHOES_MAX_CHARGE)
bananium.insert_amount_mat(min(BANANA_SHOES_RECHARGE_RATE * seconds_per_tick, BANANA_SHOES_MAX_CHARGE - bananium_amount), /datum/material/bananium)
diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm
index 46e98db0a8c..0c280eb2f3b 100644
--- a/code/modules/clothing/shoes/bananashoes.dm
+++ b/code/modules/clothing/shoes/bananashoes.dm
@@ -13,16 +13,22 @@
var/material_per_banana =SMALL_MATERIAL_AMOUNT
/// Typepath of created banana
var/banana_type = /obj/item/grown/bananapeel/specialpeel
+ /// Material container for bananium
+ var/datum/component/material_container/bananium
/obj/item/clothing/shoes/clown_shoes/banana_shoes/Initialize(mapload)
. = ..()
AddElement(/datum/element/update_icon_updates_onmob)
- AddComponent(/datum/component/material_container, list(/datum/material/bananium), 100 * SHEET_MATERIAL_AMOUNT, MATCONTAINER_EXAMINE|MATCONTAINER_ANY_INTENT|MATCONTAINER_SILENT, allowed_items=/obj/item/stack)
+ bananium = AddComponent(/datum/component/material_container, list(/datum/material/bananium), 100 * SHEET_MATERIAL_AMOUNT, MATCONTAINER_EXAMINE|MATCONTAINER_ANY_INTENT|MATCONTAINER_SILENT, allowed_items=/obj/item/stack)
AddComponent(/datum/component/squeak, list('sound/items/bikehorn.ogg'=1), 75, falloff_exponent = 20)
RegisterSignal(src, COMSIG_SHOES_STEP_ACTION, PROC_REF(on_step))
if(always_noslip)
LAZYOR(clothing_traits, TRAIT_NO_SLIP_WATER)
+/obj/item/clothing/shoes/clown_shoes/banana_shoes/Destroy()
+ bananium = null
+ return ..()
+
/obj/item/clothing/shoes/clown_shoes/banana_shoes/proc/toggle_clowning_action()
on = !on
update_appearance()
@@ -38,7 +44,6 @@
SIGNAL_HANDLER
var/mob/wearer = loc
- var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
if(!on || !istype(wearer))
return
@@ -50,7 +55,6 @@
to_chat(wearer, span_warning("You ran out of bananium!"))
/obj/item/clothing/shoes/clown_shoes/banana_shoes/attack_self(mob/user)
- var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
var/sheet_amount = bananium.retrieve_all()
if(sheet_amount)
to_chat(user, span_notice("You retrieve [sheet_amount] sheets of bananium from the prototype shoes."))
@@ -62,7 +66,6 @@
. += span_notice("The shoes are [on ? "enabled" : "disabled"].")
/obj/item/clothing/shoes/clown_shoes/banana_shoes/ui_action_click(mob/user)
- var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
if(bananium.get_material_amount(/datum/material/bananium) >= material_per_banana)
toggle_clowning_action()
to_chat(user, span_notice("You [on ? "activate" : "deactivate"] the prototype shoes."))
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index b89083824fd..41fdf228939 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -136,6 +136,8 @@
var/datum/techweb/stored_research
///Proximity monitor associated with this atom, needed for proximity checks.
var/datum/proximity_monitor/proximity_monitor
+ ///Material container for materials
+ var/datum/component/material_container/materials
/obj/machinery/mineral/processing_unit/Initialize(mapload)
. = ..()
@@ -152,13 +154,20 @@
/datum/material/titanium,
/datum/material/bluespace,
)
- AddComponent(/datum/component/material_container, allowed_materials, INFINITY, MATCONTAINER_EXAMINE|BREAKDOWN_FLAGS_ORE_PROCESSOR, allowed_items=/obj/item/stack)
+ materials = AddComponent( \
+ /datum/component/material_container, \
+ allowed_materials, \
+ INFINITY, \
+ MATCONTAINER_EXAMINE | BREAKDOWN_FLAGS_ORE_PROCESSOR, \
+ allowed_items = /obj/item/stack \
+ )
if(!GLOB.autounlock_techwebs[/datum/techweb/autounlocking/smelter])
GLOB.autounlock_techwebs[/datum/techweb/autounlocking/smelter] = new /datum/techweb/autounlocking/smelter
stored_research = GLOB.autounlock_techwebs[/datum/techweb/autounlocking/smelter]
selected_material = GET_MATERIAL_REF(/datum/material/iron)
/obj/machinery/mineral/processing_unit/Destroy()
+ materials = null
mineral_machine = null
stored_research = null
return ..()
@@ -166,7 +175,6 @@
/obj/machinery/mineral/processing_unit/proc/process_ore(obj/item/stack/ore/O)
if(QDELETED(O))
return
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/material_amount = materials.get_item_material_amount(O, BREAKDOWN_FLAGS_ORE_PROCESSOR)
if(!materials.has_space(material_amount))
unload_mineral(O)
@@ -177,7 +185,6 @@
/obj/machinery/mineral/processing_unit/proc/get_machine_data()
var/dat = "Smelter control console
"
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/datum/material/all_materials as anything in materials.materials)
var/amount = materials.materials[all_materials]
dat += "[all_materials.name]: [amount] cm³"
@@ -231,7 +238,6 @@
mineral_machine.updateUsrDialog()
/obj/machinery/mineral/processing_unit/proc/smelt_ore(seconds_per_tick = 2)
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/datum/material/mat = selected_material
if(!mat)
return
@@ -254,8 +260,7 @@
on = FALSE
return
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- materials.use_materials(alloy.materials, amount)
+ materials.use_materials(alloy.materials, multiplier = amount)
generate_mineral(alloy.build_path)
@@ -265,8 +270,6 @@
var/build_amount = SMELT_AMOUNT * seconds_per_tick
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
-
for(var/mat_cat in D.materials)
var/required_amount = D.materials[mat_cat]
var/amount = materials.materials[mat_cat]
@@ -279,9 +282,4 @@
var/O = new P(src)
unload_mineral(O)
-/obj/machinery/mineral/processing_unit/on_deconstruction()
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- materials.retrieve_all()
- return ..()
-
#undef SMELT_AMOUNT
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index 9ed337f9d56..03ec725dc31 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -52,7 +52,11 @@
if(!GLOB.autounlock_techwebs[/datum/techweb/autounlocking/smelter])
GLOB.autounlock_techwebs[/datum/techweb/autounlocking/smelter] = new /datum/techweb/autounlocking/smelter
stored_research = GLOB.autounlock_techwebs[/datum/techweb/autounlocking/smelter]
- materials = AddComponent(/datum/component/remote_materials, "orm", mapload, mat_container_flags=BREAKDOWN_FLAGS_ORM)
+ materials = AddComponent(
+ /datum/component/remote_materials, \
+ mapload, \
+ mat_container_flags = BREAKDOWN_FLAGS_ORM \
+ )
/obj/machinery/mineral/ore_redemption/Destroy()
stored_research = null
@@ -375,7 +379,7 @@
var/amount = round(min(text2num(params["sheets"]), 50, can_smelt_alloy(alloy)))
if(amount < 1) //no negative mats
return
- mat_container.use_materials(alloy.materials, amount)
+ mat_container.use_materials(alloy.materials, multiplier = amount)
materials.silo_log(src, "released", -amount, "sheets", alloy.materials)
var/output
if(ispath(alloy.build_path, /obj/item/stack/sheet))
diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm
index 2af363335e5..b06188fb2c6 100644
--- a/code/modules/mining/machine_silo.dm
+++ b/code/modules/mining/machine_silo.dm
@@ -15,6 +15,8 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
var/list/holds = list()
/// List of all components that are sharing ores with this silo.
var/list/datum/component/remote_materials/ore_connected_machines = list()
+ /// Material Container
+ var/datum/component/material_container/materials
/obj/machinery/ore_silo/Initialize(mapload)
. = ..()
@@ -31,7 +33,13 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
/datum/material/bluespace,
/datum/material/plastic,
)
- AddComponent(/datum/component/material_container, materials_list, INFINITY, MATCONTAINER_NO_INSERT, allowed_items=/obj/item/stack)
+ materials = AddComponent( \
+ /datum/component/material_container, \
+ materials_list, \
+ INFINITY, \
+ MATCONTAINER_NO_INSERT, \
+ allowed_items = /obj/item/stack \
+ )
if (!GLOB.ore_silo_default && mapload && is_station_level(z))
GLOB.ore_silo_default = src
@@ -43,15 +51,11 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
mats.disconnect_from(src)
ore_connected_machines = null
-
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- materials.retrieve_all()
+ materials = null
return ..()
/obj/machinery/ore_silo/proc/remote_attackby(obj/machinery/M, mob/living/user, obj/item/stack/I, breakdown_flags=NONE)
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- // stolen from /datum/component/material_container/proc/OnAttackBy
if(user.combat_mode)
return
if(I.item_flags & ABSTRACT)
@@ -92,7 +96,6 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
popup.open()
/obj/machinery/ore_silo/proc/generate_ui()
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/list/ui = list("