diff --git a/code/__HELPERS/materials.dm b/code/__HELPERS/materials.dm
new file mode 100644
index 0000000000..96b9b5edc8
--- /dev/null
+++ b/code/__HELPERS/materials.dm
@@ -0,0 +1,11 @@
+/// Turns a material amount into the amount of sheets it should output
+/proc/amount2sheet(amount)
+ if(amount >= MINERAL_MATERIAL_AMOUNT)
+ return round(amount / MINERAL_MATERIAL_AMOUNT)
+ return FALSE
+
+/// Turns an amount of sheets into the amount of material amount it should output
+/proc/sheet2amount(sheet_amount)
+ if(sheet_amount > 0)
+ return sheet_amount * MINERAL_MATERIAL_AMOUNT
+ return FALSE
diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
index aac8075209..ec847d515b 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material_container.dm
@@ -326,7 +326,7 @@
return total_amount_save - total_amount
/// For spawning mineral sheets at a specific location. Used by machines to output sheets.
-/datum/component/material_container/proc/retrieve_sheets(sheet_amt, var/datum/material/M, target = null)
+/datum/component/material_container/proc/retrieve_sheets(sheet_amt, datum/material/M, target = null)
if(!M.sheet_type)
return FALSE //Add greyscale sheet handling here later
if(sheet_amt <= 0)
@@ -410,19 +410,6 @@
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 >= MINERAL_MATERIAL_AMOUNT)
- return round(amt / MINERAL_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 * MINERAL_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)
if(!istype(I) || !I.custom_materials)
diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm
index c81f766d88..e75a925529 100644
--- a/code/modules/integrated_electronics/subtypes/input.dm
+++ b/code/modules/integrated_electronics/subtypes/input.dm
@@ -1122,14 +1122,14 @@
return
var/datum/component/material_container/scanned_storage = scanned_thing.GetComponent(/datum/component/material_container)
if(!scanned_storage) //Invalid input
- activate_pin(PIN_ACTIVATOR_OUTPUT_NOT_SCANNED)
- return
+ var/datum/component/remote_materials/remote_storage = scanned_thing.GetComponent(/datum/component/remote_materials)
+ if(QDELETED(remote_storage))
+ activate_pin(PIN_ACTIVATOR_OUTPUT_NOT_SCANNED)
+ return
+ scanned_storage = remote_storage.mat_container
if(scanned_thing in view(drop_location())) // This is a camera. It can't examine thngs,that it can't see.
- for(var/material_iterator in length(mtypes))
- if(material_iterator in scanned_storage.materials)
- set_pin_data(IC_OUTPUT, material_iterator, scanned_storage.materials[SSmaterials.GetMaterialRef(mtypes[material_iterator])] || 0)
- else
- set_pin_data(IC_OUTPUT, material_iterator, null)
+ for(var/material_iterator in 1 to length(mtypes))
+ set_pin_data(IC_OUTPUT, material_iterator, scanned_storage.materials[SSmaterials.GetMaterialRef(mtypes[material_iterator])] || 0)
push_data()
activate_pin(PIN_ACTIVATOR_OUTPUT_ON_SCANNED)
else
diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm
index 1ce8d05662..2d259099fd 100644
--- a/code/modules/integrated_electronics/subtypes/manipulation.dm
+++ b/code/modules/integrated_electronics/subtypes/manipulation.dm
@@ -362,11 +362,15 @@
/obj/item/integrated_circuit/manipulation/matman
name = "material manager"
desc = "This circuit is designed for automatic storage and distribution of materials."
- extended_desc = "The first input takes a ref of a machine with a material container. \
- Second input is used for inserting material stacks into the internal material storage. \
- Inputs 3-13 are used to transfer materials between target machine and circuit storage. \
- Positive values will take that number of materials from another machine. \
- Negative values will fill another machine from internal storage. Outputs show current stored amounts of mats."
+ extended_desc = \
+ "The first input takes a ref of a machine with a material container.
\
+ Second input is used for inserting material stacks into the internal material storage.
\
+ Inputs 3-13 are used to transfer materials between target machine and circuit storage.
\
+ Positive values will take that number of materials from another machine.
\
+ Negative values will fill another machine from internal storage.
\
+ Unless target is null, which will have the machine drop the material on the floor.
\
+ Outputs show current stored amounts of mats.
\
+ Corporate note, %MINERAL_MATERIAL_AMOUNT%cm³ makes a sheet, any less than that cannot be retrieved."
icon_state = "grabber"
complexity = 16
inputs = list(
@@ -425,6 +429,10 @@
/datum/material/plastic,
)
+/obj/item/integrated_circuit/manipulation/matman/Initialize(mapload)
+ . = ..()
+ extended_desc = replacetext(extended_desc, "%MINERAL_MATERIAL_AMOUNT%", MINERAL_MATERIAL_AMOUNT)
+
/obj/item/integrated_circuit/manipulation/matman/ComponentInitialize()
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, mtypes.Copy(), 100000, FALSE, /obj/item/stack, CALLBACK(src, PROC_REF(is_insertion_ready)), CALLBACK(src, PROC_REF(AfterMaterialInsert)))
materials.precise_insertion = TRUE
@@ -444,16 +452,13 @@
/obj/item/integrated_circuit/manipulation/matman/do_work(activated_input_pin)
var/datum/component/material_container/local_storage = GetComponent(/datum/component/material_container)
var/atom/movable/scanned_thing = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
- if(QDELETED(scanned_thing))
- activate_pin(PIN_ACTIVATOR_OUTPUT_ON_FAILURE)
- return
- if(!check_target(scanned_thing))
- activate_pin(PIN_ACTIVATOR_OUTPUT_ON_FAILURE)
- return
switch(activated_input_pin)
if(PIN_ACTIVATOR_INPUT_INSERT_SHEET)
var/obj/item/stack/sheet/sheet = scanned_thing
- if(QDELETED(sheet))
+ if(QDELETED(sheet) || !istype(sheet))
+ activate_pin(PIN_ACTIVATOR_OUTPUT_ON_FAILURE)
+ return
+ if(!check_target(scanned_thing, exclude_components = TRUE, exclude_self = TRUE))
activate_pin(PIN_ACTIVATOR_OUTPUT_ON_FAILURE)
return
if(local_storage.insert_stack(sheet, clamp(get_pin_data(IC_INPUT, 2),0,100), 1))
@@ -462,7 +467,11 @@
else
activate_pin(PIN_ACTIVATOR_OUTPUT_ON_FAILURE)
if(PIN_ACTIVATOR_INPUT_TRANSFER_MATS)
- var/datum/component/material_container/scanned_storage = scanned_thing.GetComponent(/datum/component/material_container)
+ var/datum/component/material_container/scanned_storage = scanned_thing?.GetComponent(/datum/component/material_container)
+ if(QDELETED(scanned_storage))
+ var/datum/component/remote_materials/remote_storage = scanned_thing?.GetComponent(/datum/component/remote_materials)
+ if(!QDELETED(remote_storage))
+ scanned_storage = remote_storage.mat_container
var/successful_transfer
for(var/material_iterator in 1 to length(mtypes))
var/datum/material/material_to_transfer = SSmaterials.GetMaterialRef(mtypes[material_iterator])
@@ -470,13 +479,22 @@
var/amount = clamp(get_pin_data(IC_INPUT, material_iterator + 2), -100000, 100000)
if(!amount)
continue
- if(!scanned_storage) //Invalid input
+ if(isnull(scanned_thing))
if(amount > 0)
- if(local_storage.retrieve_sheets(amount, material_to_transfer, drop_location()))
+ if(local_storage.retrieve_sheets(amount2sheet(amount), material_to_transfer, drop_location()))
successful_transfer = TRUE
- else
+ else if(!QDELETED(scanned_storage))
+ if(QDELETED(scanned_thing))
+ activate_pin(PIN_ACTIVATOR_OUTPUT_ON_FAILURE)
+ return
+ // exclude_contents = FALSE, if someone EVER makes literal tom's storage in SS13, i'm evilly giving you this.
+ if(!check_target(scanned_thing, exclude_components = TRUE, exclude_self = TRUE))
+ activate_pin(PIN_ACTIVATOR_OUTPUT_ON_FAILURE)
+ return
if(scanned_storage.transer_amt_to(local_storage, amount, material_to_transfer))
successful_transfer = TRUE
+ else
+ activate_pin(PIN_ACTIVATOR_OUTPUT_ON_FAILURE)
if(successful_transfer)
AfterMaterialInsert()
activate_pin(PIN_ACTIVATOR_OUTPUT_ON_SUCCESS)
diff --git a/tgstation.dme b/tgstation.dme
index 14b128e4c8..a6e2d53bf3 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -218,6 +218,7 @@
#include "code\__HELPERS\level_traits.dm"
#include "code\__HELPERS\lighting.dm"
#include "code\__HELPERS\markov.dm"
+#include "code\__HELPERS\materials.dm"
#include "code\__HELPERS\matrices.dm"
#include "code\__HELPERS\mobs.dm"
#include "code\__HELPERS\mouse_control.dm"