diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm
index baf6d81e0f..cc988544b8 100644
--- a/code/datums/components/material_container.dm
+++ b/code/datums/components/material_container.dm
@@ -112,32 +112,87 @@
user_insert(I, user) //, mat_container_flags)
/// Proc used for when player inserts materials
-/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user)
+/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user, datum/component/remote_materials/remote = null)
set waitfor = FALSE
- var/requested_amount
var/active_held = user.get_active_held_item() // differs from I when using TK
- if(istype(I, /obj/item/stack) && precise_insertion)
- var/atom/current_parent = parent
+ var/inserted = 0
+
+ //handle stacks specially
+ if(istype(I, /obj/item/stack))
+ var/atom/current_parent = remote ? remote.parent : parent //is the user using a remote materials component?
var/obj/item/stack/S = I
- requested_amount = input(user, "How much do you want to insert?", "Inserting [S.singular_name]s") as num|null
+
+ //try to get ammount to use
+ var/requested_amount
+ if(precise_insertion)
+ requested_amount = input(user, "How much do you want to insert?", "Inserting [S.singular_name]s") as num|null
+ else
+ requested_amount= S.amount
+
if(isnull(requested_amount) || (requested_amount <= 0))
return
- if(QDELETED(I) || QDELETED(user) || QDELETED(src) || parent != current_parent || user.physical_can_use_topic(current_parent) < UI_INTERACTIVE || user.get_active_held_item() != active_held)
+ if(QDELETED(I) || QDELETED(user) || QDELETED(src) || user.get_active_held_item() != active_held)
return
- if(!user.temporarilyRemoveItemFromInventory(I))
- to_chat(user, "[I] is stuck to you and cannot be placed into [parent].")
- return
- var/inserted = insert_item(I, stack_amt = requested_amount)//, breakdown_flags= mat_container_flags)
+ //are we still in range after the user input?
+ if((remote ? remote.parent : parent) != current_parent || user.physical_can_use_topic(current_parent) < UI_INTERACTIVE)
+ return
+ inserted = insert_stack(S, requested_amount)
+ else
+ if(!user.temporarilyRemoveItemFromInventory(I))
+ to_chat(user, "[I] is stuck to you and cannot be placed into [parent].")
+ return
+ inserted = insert_item(I)
+ qdel(I)
+
if(inserted)
to_chat(user, "You insert a material total of [inserted] into [parent].")
- qdel(I)
if(after_insert)
after_insert.Invoke(I, last_inserted_id, inserted)
- else if(I == active_held)
- user.put_in_active_hand(I)
+ if(remote && remote.after_insert)
+ remote.after_insert.Invoke(I, last_inserted_id, inserted)
+
+//Inserts a number of sheets from a stack, returns the amount of sheets used.
+/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt, multiplier = 1)
+ if(isnull(amt))
+ amt = S.amount
+
+ if(amt <= 0)
+ return FALSE
+
+ if(amt > S.amount)
+ amt = S.amount
+
+ var/material_amt = get_item_material_amount(S)
+ if(!material_amt)
+ return FALSE
+
+ //get max number of sheets we have room to add
+ var/mat_per_sheet = material_amt/S.amount
+ amt = min(amt, round((max_amount - total_amount) / (mat_per_sheet)))
+ if(!amt)
+ return FALSE
+
+ //add the mats and keep track of how much was added
+ var/starting_total = total_amount
+ for(var/MAT in materials)
+ materials[MAT] += S.mats_per_unit[MAT] * amt * multiplier
+ total_amount += S.mats_per_unit[MAT] * amt * multiplier
+ var/total_added = total_amount - starting_total
+
+ //update last_inserted_id with mat making up majority of the stack
+ var/primary_mat
+ var/max_mat_value = 0
+ for(var/MAT in materials)
+ if(S.mats_per_unit[MAT] > max_mat_value)
+ max_mat_value = S.mats_per_unit[MAT]
+ primary_mat = MAT
+ last_inserted_id = primary_mat
+
+ S.use(amt)
+ return total_added
/// Proc specifically for inserting items, returns the amount of materials entered.
-/datum/component/material_container/proc/insert_item(obj/item/I, var/multiplier = 1, stack_amt)
+/datum/component/material_container/proc/insert_item(obj/item/I, var/multiplier = 1)
if(QDELETED(I))
return FALSE
@@ -198,6 +253,7 @@
var/total_amount_saved = total_amount
if(mat)
materials[mat] += amt
+ total_amount += amt
else
for(var/i in materials)
materials[i] += amt
diff --git a/code/datums/components/remote_materials.dm b/code/datums/components/remote_materials.dm
index 01038c11d3..b1d23ea3a8 100644
--- a/code/datums/components/remote_materials.dm
+++ b/code/datums/components/remote_materials.dm
@@ -15,13 +15,15 @@ handles linking back and forth.
var/category
var/allow_standalone
var/local_size = INFINITY
+ var/datum/callback/after_insert
-/datum/component/remote_materials/Initialize(category, mapload, allow_standalone = TRUE, force_connect = FALSE)
+/datum/component/remote_materials/Initialize(category, mapload, allow_standalone = TRUE, force_connect = FALSE, _after_insert)
if (!isatom(parent))
return COMPONENT_INCOMPATIBLE
src.category = category
src.allow_standalone = allow_standalone
+ after_insert = _after_insert
RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/OnAttackBy)
@@ -67,7 +69,7 @@ handles linking back and forth.
/datum/material/plastic,
)
- mat_container = parent.AddComponent(/datum/component/material_container, allowed_mats, local_size, allowed_types=/obj/item/stack)
+ mat_container = parent.AddComponent(/datum/component/material_container, allowed_mats, local_size, allowed_types=/obj/item/stack, _after_insert = after_insert)
/datum/component/remote_materials/proc/set_local_size(size)
local_size = size
@@ -103,7 +105,7 @@ handles linking back and forth.
return COMPONENT_NO_AFTERATTACK
else if(silo && istype(I, /obj/item/stack))
- if(silo.remote_attackby(parent, user, I))
+ if(silo.remote_attackby(parent, user, I, src))
return COMPONENT_NO_AFTERATTACK
/datum/component/remote_materials/proc/on_hold()
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 0303117b96..bbbfa7f1bd 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -65,7 +65,7 @@
/obj/machinery/mecha_part_fabricator/Initialize(mapload)
stored_research = new
- rmat = AddComponent(/datum/component/remote_materials, "mechfab", mapload && link_on_init)
+ rmat = AddComponent(/datum/component/remote_materials, "mechfab", mapload && link_on_init, _after_insert=CALLBACK(src, .proc/AfterMaterialInsert))
RefreshParts() //Recalculating local material sizes if the fab isn't linked
return ..()
diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm
index b0055204f9..34b349b198 100644
--- a/code/modules/mining/machine_silo.dm
+++ b/code/modules/mining/machine_silo.dm
@@ -47,7 +47,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
return ..()
-/obj/machinery/ore_silo/proc/remote_attackby(obj/machinery/M, mob/user, obj/item/stack/I)
+/obj/machinery/ore_silo/proc/remote_attackby(obj/machinery/M, mob/user, obj/item/stack/I, remote = null)
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
// stolen from /datum/component/material_container/proc/OnAttackBy
if(user.a_intent != INTENT_HELP)
@@ -63,7 +63,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
return
// assumes unlimited space...
var/amount = I.amount
- materials.user_insert(I, user)
+ materials.user_insert(I, user, remote)
silo_log(M, "deposited", amount, "sheets", item_mats)
return TRUE
diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm
index 072fa54c6f..319b4a2199 100644
--- a/code/modules/research/machinery/_production.dm
+++ b/code/modules/research/machinery/_production.dm
@@ -30,7 +30,7 @@
stored_research = new
host_research = SSresearch.science_tech
update_research()
- materials = AddComponent(/datum/component/remote_materials, "lathe", mapload)
+ materials = AddComponent(/datum/component/remote_materials, "lathe", mapload, _after_insert=CALLBACK(src, .proc/AfterMaterialInsert))
RefreshParts()
/obj/machinery/rnd/production/Destroy()
diff --git a/code/modules/research/machinery/circuit_imprinter.dm b/code/modules/research/machinery/circuit_imprinter.dm
index c1c386cb31..a8ce7305a3 100644
--- a/code/modules/research/machinery/circuit_imprinter.dm
+++ b/code/modules/research/machinery/circuit_imprinter.dm
@@ -22,3 +22,6 @@
/obj/machinery/rnd/production/circuit_imprinter/disconnect_console()
linked_console.linked_imprinter = null
..()
+
+/obj/machinery/rnd/production/circuit_imprinter/AfterMaterialInsert() //doesnt use have an animation like lathes do
+ return
diff --git a/code/modules/research/rdmachines.dm b/code/modules/research/rdmachines.dm
index 2237284a64..f39f5b1584 100644
--- a/code/modules/research/rdmachines.dm
+++ b/code/modules/research/rdmachines.dm
@@ -94,13 +94,13 @@
..()
/obj/machinery/rnd/proc/AfterMaterialInsert(item_inserted, id_inserted, amount_inserted)
- var/stack_name
+ var/mat_name
if(istype(item_inserted, /obj/item/stack/ore/bluespace_crystal))
- stack_name = "bluespace"
+ mat_name = "bluespace"
use_power(MINERAL_MATERIAL_AMOUNT / 10)
else
- var/obj/item/stack/S = item_inserted
- stack_name = S.name
+ var/datum/material/M = id_inserted
+ mat_name = M.name
use_power(min(1000, (amount_inserted / 100)))
- add_overlay("protolathe_[stack_name]")
- addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[stack_name]"), 10)
+ add_overlay("protolathe_[mat_name]")
+ addtimer(CALLBACK(src, /atom/proc/cut_overlay, "protolathe_[mat_name]"), 10)
diff --git a/icons/obj/machines/research.dmi b/icons/obj/machines/research.dmi
index 7dcd4e6bcb..8f9594c5dc 100644
Binary files a/icons/obj/machines/research.dmi and b/icons/obj/machines/research.dmi differ
diff --git a/icons/obj/robotics.dmi b/icons/obj/robotics.dmi
index 8d0627aa95..a9bf1fc261 100644
Binary files a/icons/obj/robotics.dmi and b/icons/obj/robotics.dmi differ