diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 9e91e254950..411a2d68d84 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -591,6 +591,16 @@ to destroy them and players will be able to make replacements.
/obj/item/stock_parts/micro_laser = 1,
/obj/item/stock_parts/console_screen = 1)
+/obj/item/circuitboard/reagentgrinder
+ name = "circuit board (All-In-One Grinder)"
+ build_path = /obj/machinery/reagentgrinder/empty
+ board_type = "machine"
+ origin_tech = "materials=2;engineering=2;biotech=2"
+ frame_desc = "Requires 2 Manipulators and 1 Matter Bin."
+ req_components = list(
+ /obj/item/stock_parts/manipulator = 2,
+ /obj/item/stock_parts/matter_bin = 1)
+
//Almost the same recipe as destructive analyzer to give people choices.
/obj/item/circuitboard/experimentor
name = "circuit board (E.X.P.E.R.I-MENTOR)"
diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
index 9ea55dd5af7..1e3bcb92db5 100644
--- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
+++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm
@@ -9,8 +9,9 @@
active_power_usage = 100
pass_flags = PASSTABLE
var/operating = 0
- var/obj/item/reagent_containers/beaker = null
- var/limit = 10
+ var/obj/item/reagent_containers/beaker = new /obj/item/reagent_containers/glass/beaker/large
+ var/limit = null
+ var/efficiency = null
//IMPORTANT NOTE! A negative number is a multiplier, a positive number is a flat amount to add. 0 means equal to the amount of the original reagent
var/list/blend_items = list (
@@ -88,10 +89,28 @@
var/list/holdingitems = list()
+/obj/machinery/reagentgrinder/empty
+ icon_state = "juicer0"
+ beaker = null
+
/obj/machinery/reagentgrinder/New()
..()
- beaker = new /obj/item/reagent_containers/glass/beaker/large(src)
- return
+ component_parts = list()
+ component_parts += new /obj/item/circuitboard/reagentgrinder(null)
+ component_parts += new /obj/item/stock_parts/manipulator(null)
+ component_parts += new /obj/item/stock_parts/manipulator(null)
+ component_parts += new /obj/item/stock_parts/matter_bin(null)
+ RefreshParts()
+
+/obj/machinery/reagentgrinder/RefreshParts()
+ var/H
+ var/T
+ for(var/obj/item/stock_parts/matter_bin/M in component_parts)
+ H += M.rating
+ for(var/obj/item/stock_parts/manipulator/M in component_parts)
+ T += M.rating
+ limit = 10*H
+ efficiency = 0.8+T*0.1
/obj/machinery/reagentgrinder/Destroy()
QDEL_NULL(beaker)
@@ -112,16 +131,29 @@
if(default_unfasten_wrench(user, I))
return
+ if(exchange_parts(user, I))
+ return
+
+ if(anchored && !beaker)
+ if(default_deconstruction_screwdriver(user, "juicer_open", "juicer0", I))
+ return
+
+ if(panel_open && istype(I, /obj/item/crowbar))
+ default_deconstruction_crowbar(I)
+ return
+
if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER) )
- if (!beaker)
+ if(beaker)
+ to_chat(user, "There's already a container inside.")
+ else if(panel_open)
+ to_chat(user, "Close the maintenance panel first.")
+ else
if(!user.drop_item())
return 1
beaker = I
beaker.loc = src
update_icon()
src.updateUsrDialog()
- else
- to_chat(user, "There's already a container inside.")
return 1 //no afterattack
if(is_type_in_list(I, dried_items))
@@ -331,7 +363,7 @@
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
var/amount = get_juice_amount(O)
- beaker.reagents.add_reagent(r_id, min(amount, space))
+ beaker.reagents.add_reagent(r_id, min(amount*efficiency, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
@@ -371,17 +403,17 @@
if(amount <= 0)
if(amount == 0)
if (O.reagents != null && O.reagents.has_reagent("nutriment"))
- beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space))
+ beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment")*efficiency, space))
O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space))
if (O.reagents != null && O.reagents.has_reagent("plantmatter"))
- beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("plantmatter"), space))
+ beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("plantmatter")*efficiency, space))
O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space))
else
if (O.reagents != null && O.reagents.has_reagent("nutriment"))
- beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space))
+ beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)*efficiency), space))
O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space))
if (O.reagents != null && O.reagents.has_reagent("plantmatter"))
- beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("plantmatter")*abs(amount)), space))
+ beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("plantmatter")*abs(amount)*efficiency), space))
O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space))
@@ -403,7 +435,7 @@
for (var/r_id in allowed)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
var/amount = allowed[r_id]
- beaker.reagents.add_reagent(r_id,min(amount, space))
+ beaker.reagents.add_reagent(r_id,min(amount*efficiency, space))
if (space < amount)
break
if (i == round(O.amount, 1))
@@ -419,9 +451,9 @@
var/amount = allowed[r_id]
if (amount == 0)
if (O.reagents != null && O.reagents.has_reagent(r_id))
- beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space))
+ beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id)*efficiency, space))
else
- beaker.reagents.add_reagent(r_id,min(amount, space))
+ beaker.reagents.add_reagent(r_id,min(amount*efficiency, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
@@ -436,7 +468,7 @@
var/amount = O.reagents.total_volume
O.reagents.trans_to(beaker, min(amount, space))
if (O.Uses > 0)
- beaker.reagents.add_reagent("slimejelly",min(20, space))
+ beaker.reagents.add_reagent("slimejelly",min(20*efficiency, space))
remove_object(O)
//Everything else - Transfers reagents from it into beaker
diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm
index c604105dc04..f50b3527aa2 100644
--- a/code/modules/research/designs/machine_designs.dm
+++ b/code/modules/research/designs/machine_designs.dm
@@ -182,6 +182,16 @@
build_path = /obj/item/circuitboard/chem_heater
category = list ("Medical Machinery")
+/datum/design/reagentgrinder
+ name = "Machine Design (All-In-One Grinder)"
+ desc = "The circuit board for an All-In-One Grinder."
+ id = "reagentgrinder"
+ req_tech = list("biotech" = 2, "materials" = 2, "programming" = 2)
+ build_type = IMPRINTER
+ materials = list(MAT_GLASS = 1000)
+ build_path = /obj/item/circuitboard/reagentgrinder
+ category = list ("Medical Machinery")
+
/datum/design/sleeper
name = "Machine Board (Sleeper)"
desc = "Allows for the construction of circuit boards used to build a Sleeper."
diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi
index b39c3668294..0e9ee4649ac 100644
Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ