Allows you to choose how much to insert into protolathe/exofab/circuitprinter/dronedispenser (#31399)

* precision

* precision

* sanity checks

* itt kevinz doesn't know how cyberboss procs work

* fixes

* allows user cancellation

* im dumb

* itt: im still dumb

* fixes stuff, makes it set on init

* refactors reagentgrinder code

* more fixes, prevents melee attacks from going anyways

* ...? wtf is with usetopic

* Finally found out what's wrongw ith this thing.

* fixes a mistake
This commit is contained in:
kevinz000
2017-10-10 01:11:22 -07:00
committed by CitadelStationBot
parent eb9737912c
commit a6ac800db0
7 changed files with 424 additions and 426 deletions
+2
View File
@@ -8,6 +8,8 @@
#define ismovableatom(A) (istype(A, /atom/movable))
#define isatom(A) (istype(A, /atom))
//Turfs
//#define isturf(A) (istype(A, /turf)) This is actually a byond built-in. Added here for completeness sake.
+38 -23
View File
@@ -20,6 +20,7 @@
var/last_inserted_id
var/last_amount_inserted
var/last_insert_success
var/precise_insertion = FALSE
var/datum/callback/precondition
//MAX_STACK_SIZE = 50
//MINERAL_MATERIAL_AMOUNT = 2000
@@ -70,10 +71,21 @@
if(!has_space(material_amount))
to_chat(user, "<span class='warning'>[parent] is full. Please remove metal or glass from [parent] in order to insert more.</span>")
return
INVOKE_ASYNC(src, .proc/user_insert, I, user)
/datum/component/material_container/proc/user_insert(obj/item/I, mob/living/user)
var/requested_amount
if(istype(I, /obj/item/stack) && precise_insertion)
var/atom/current_parent = parent
requested_amount = input(user, "How much do you want to insert?", "Inserting sheets") as num|null
if(isnull(requested_amount) || (requested_amount <= 0))
return
if(QDELETED(I) || QDELETED(user) || QDELETED(src) || parent != current_parent || !user.canUseTopic(current_parent) || !user.is_holding(I) || !user.Adjacent(current_parent))
return
if(!user.temporarilyRemoveItemFromInventory(I))
to_chat(user, "<span class='warning'>[I] is stuck to you and cannot be placed into [parent].</span>")
return
var/inserted = insert_item(I)
var/inserted = insert_item(I, stack_amt = requested_amount)
if(inserted)
last_insert_success = TRUE
if(istype(I, /obj/item/stack))
@@ -84,7 +96,7 @@
to_chat(user, "<span class='notice'>You insert a material total of [inserted] into [parent].</span>")
qdel(I)
else
user.put_in_active_hand(I)
user.put_in_active_hand(I)
//For inserting an amount of material
/datum/component/material_container/proc/insert_amount(amt, id = null)
@@ -101,21 +113,25 @@
M.amount += amt
total_amount += amt
return (total_amount - total_amount_saved)
return 0
return FALSE
/datum/component/material_container/proc/insert_stack(obj/item/stack/S, amt = 0)
if(isnull(amt))
amt = S.amount
if(amt <= 0)
return 0
return FALSE
if(amt > S.amount)
amt = S.amount
var/material_amt = get_item_material_amount(S)
if(!material_amt)
return 0
return FALSE
amt = min(amt, round(((max_amount - total_amount) / material_amt)))
if(!amt)
return 0
return FALSE
last_inserted_id = insert_materials(S,amt)
last_inserted_type = S.type
@@ -123,16 +139,15 @@
last_amount_inserted = amt
return amt
/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1)
/datum/component/material_container/proc/insert_item(obj/item/I, multiplier = 1, stack_amt)
if(!I)
return 0
return FALSE
if(istype(I, /obj/item/stack))
var/obj/item/stack/S = I
return insert_stack(I, S.amount)
return insert_stack(I, stack_amt)
var/material_amount = get_item_material_amount(I)
if(!material_amount || !has_space(material_amount))
return 0
return FALSE
last_inserted_id = insert_materials(I, multiplier)
last_inserted_type = I.type
@@ -155,13 +170,13 @@
//mats is a list of types of material to use and the corresponding amounts, example: list(MAT_METAL=100, MAT_GLASS=200)
/datum/component/material_container/proc/use_amount(list/mats, multiplier=1)
if(!mats || !mats.len)
return 0
return FALSE
var/datum/material/M
for(var/MAT in materials)
M = materials[MAT]
if(M.amount < (mats[MAT] * multiplier))
return 0
return FALSE
var/total_amount_save = total_amount
for(var/MAT in materials)
@@ -179,7 +194,7 @@
M.amount -= amt
total_amount -= amt
return amt
return 0
return FALSE
/datum/component/material_container/proc/can_use_amount(amt, id, list/mats)
if(amt && id)
@@ -198,7 +213,7 @@
//For spawning mineral sheets; internal use only
/datum/component/material_container/proc/retrieve(sheet_amt, datum/material/M, target = null)
if(!M.sheet_type)
return 0
return FALSE
if(sheet_amt > 0)
if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
@@ -215,12 +230,12 @@
count += sheet_amt
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
return count
return 0
return FALSE
/datum/component/material_container/proc/retrieve_sheets(sheet_amt, id, target = null)
if(materials[id])
return retrieve(sheet_amt, materials[id], target)
return 0
return FALSE
/datum/component/material_container/proc/retrieve_amount(amt, id, target)
return retrieve_sheets(amount2sheet(amt), id, target)
@@ -238,24 +253,24 @@
/datum/component/material_container/proc/has_materials(list/mats, multiplier=1)
if(!mats || !mats.len)
return 0
return FALSE
var/datum/material/M
for(var/MAT in mats)
M = materials[MAT]
if(M.amount < (mats[MAT] * multiplier))
return 0
return 1
return FALSE
return TRUE
/datum/component/material_container/proc/amount2sheet(amt)
if(amt >= MINERAL_MATERIAL_AMOUNT)
return round(amt / MINERAL_MATERIAL_AMOUNT)
return 0
return FALSE
/datum/component/material_container/proc/sheet2amount(sheet_amt)
if(sheet_amt > 0)
return sheet_amt * MINERAL_MATERIAL_AMOUNT
return 0
return FALSE
/datum/component/material_container/proc/amount(id)
var/datum/material/M = materials[id]
@@ -265,7 +280,7 @@
//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))
return 0
return FALSE
var/material_amount = 0
for(var/MAT in materials)
material_amount += I.materials[MAT]
+1
View File
@@ -56,6 +56,7 @@
. = ..()
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS), MINERAL_MATERIAL_AMOUNT * MAX_STACK_SIZE * 2, TRUE)
materials.insert_amount(starting_amount)
materials.precise_insertion = TRUE
using_materials = list(MAT_METAL=metal_cost, MAT_GLASS=glass_cost)
/obj/machinery/droneDispenser/preloaded
+2 -1
View File
@@ -35,9 +35,10 @@
)
/obj/machinery/mecha_part_fabricator/Initialize()
AddComponent(/datum/component/material_container,
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE),
FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready))
materials.precise_insertion = TRUE
. = ..()
files = new /datum/research(src) //Setup the research data holder.
@@ -1,94 +1,99 @@
#define MILK_TO_BUTTER_COEFF 15
/obj/machinery/reagentgrinder
name = "All-In-One Grinder"
desc = "From BlenderTech. Will It Blend? Let's test it out!"
icon = 'icons/obj/kitchen.dmi'
icon_state = "juicer1"
layer = BELOW_OBJ_LAYER
anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 5
active_power_usage = 100
pass_flags = PASSTABLE
resistance_flags = ACID_PROOF
var/operating = FALSE
var/obj/item/reagent_containers/beaker = null
var/limit = 10
name = "All-In-One Grinder"
desc = "From BlenderTech. Will It Blend? Let's test it out!"
icon = 'icons/obj/kitchen.dmi'
icon_state = "juicer1"
layer = BELOW_OBJ_LAYER
anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 5
active_power_usage = 100
pass_flags = PASSTABLE
resistance_flags = ACID_PROOF
var/operating = FALSE
var/obj/item/reagent_containers/beaker = null
var/limit = 10
var/static/list/blend_items = list(
//Sheets
/obj/item/stack/sheet/mineral/plasma = list("plasma" = 20),
/obj/item/stack/sheet/metal = list("iron" = 20),
/obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20),
/obj/item/stack/sheet/mineral/wood = list("carbon" = 20),
/obj/item/stack/sheet/glass = list("silicon" = 20),
/obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20),
/obj/item/stack/sheet/mineral/uranium = list("uranium" = 20),
/obj/item/stack/sheet/mineral/bananium = list("banana" = 20),
/obj/item/stack/sheet/mineral/silver = list("silver" = 20),
/obj/item/stack/sheet/mineral/gold = list("gold" = 20),
/obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20),
/obj/item/ore/bluespace_crystal = list("bluespace" = 20),
/obj/item/grown/nettle/basic = list("sacid" = 0),
/obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0),
/obj/item/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0),
//Blender Stuff
/obj/item/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0),
/obj/item/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0),
/obj/item/reagent_containers/food/snacks/grown/wheat = list("flour" = -5),
/obj/item/reagent_containers/food/snacks/grown/oat = list("flour" = -5),
/obj/item/reagent_containers/food/snacks/grown/rice = list("rice" = -5),
/obj/item/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1),
/obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
/obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0),
/obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5),
//Grinder stuff, but only if dry
/obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
/obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0),
//All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
/obj/item/slime_extract = list(),
/obj/item/reagent_containers/pill = list(),
/obj/item/reagent_containers/food = list(),
/obj/item/reagent_containers/honeycomb = list(),
/obj/item/toy/crayon = list())
var/static/list/blend_items = list(
//Sheets
/obj/item/stack/sheet/mineral/plasma = list("plasma" = 20),
/obj/item/stack/sheet/metal = list("iron" = 20),
/obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20),
/obj/item/stack/sheet/mineral/wood = list("carbon" = 20),
/obj/item/stack/sheet/glass = list("silicon" = 20),
/obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20),
/obj/item/stack/sheet/mineral/uranium = list("uranium" = 20),
/obj/item/stack/sheet/mineral/bananium = list("banana" = 20),
/obj/item/stack/sheet/mineral/silver = list("silver" = 20),
/obj/item/stack/sheet/mineral/gold = list("gold" = 20),
/obj/item/stack/sheet/bluespace_crystal = list("bluespace" = 20),
/obj/item/ore/bluespace_crystal = list("bluespace" = 20),
/obj/item/grown/nettle/basic = list("sacid" = 0),
/obj/item/grown/nettle/death = list("facid" = 0, "sacid" = 0),
/obj/item/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0),
//Blender Stuff
/obj/item/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0),
/obj/item/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0),
/obj/item/reagent_containers/food/snacks/grown/wheat = list("flour" = -5),
/obj/item/reagent_containers/food/snacks/grown/oat = list("flour" = -5),
/obj/item/reagent_containers/food/snacks/grown/rice = list("rice" = -5),
/obj/item/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1),
/obj/item/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
/obj/item/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0),
/obj/item/reagent_containers/food/snacks/egg = list("eggyolk" = -5),
//Grinder stuff, but only if dry
/obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
/obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0),
//All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
/obj/item/slime_extract = list(),
/obj/item/reagent_containers/pill = list(),
/obj/item/reagent_containers/food = list(),
/obj/item/reagent_containers/honeycomb = list(),
/obj/item/toy/crayon = list())
var/static/list/juice_items = list(
//Juicer Stuff
/obj/item/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0),
/obj/item/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/banana = list("banana" = 0),
/obj/item/reagent_containers/food/snacks/grown/potato = list("potato" = 0),
/obj/item/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0),
/obj/item/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0))
var/static/list/juice_items = list(
//Juicer Stuff
/obj/item/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0),
/obj/item/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/banana = list("banana" = 0),
/obj/item/reagent_containers/food/snacks/grown/potato = list("potato" = 0),
/obj/item/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0),
/obj/item/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/apple = list("applejuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/grapes = list("grapejuice" = 0),
/obj/item/reagent_containers/food/snacks/grown/grapes/green = list("grapejuice" = 0))
var/static/list/dried_items = list(
//Grinder stuff, but only if dry,
/obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
/obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0))
var/static/list/dried_items = list(
//Grinder stuff, but only if dry,
/obj/item/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
/obj/item/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
/obj/item/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0))
var/list/holdingitems = list()
var/list/holdingitems
/obj/machinery/reagentgrinder/Initialize()
. = ..()
holdingitems = list()
beaker = new /obj/item/reagent_containers/glass/beaker/large(src)
beaker.desc += " May contain blended dust. Don't breathe this in!"
/obj/machinery/reagentgrinder/Destroy()
QDEL_NULL(beaker)
drop_all_items()
return ..()
/obj/machinery/reagentgrinder/contents_explosion(severity, target)
@@ -96,14 +101,22 @@
beaker.ex_act(severity, target)
/obj/machinery/reagentgrinder/handle_atom_del(atom/A)
..()
. = ..()
if(A == beaker)
beaker = null
update_icon()
updateUsrDialog()
if(holdingitems[A])
holdingitems -= A
/obj/machinery/reagentgrinder/proc/drop_all_items()
for(var/i in holdingitems)
var/atom/movable/AM = i
AM.forceMove(drop_location())
holdingitems = list()
/obj/machinery/reagentgrinder/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 3)
new /obj/item/stack/sheet/metal (drop_location(), 3)
qdel(src)
/obj/machinery/reagentgrinder/update_icon()
@@ -113,380 +126,344 @@
icon_state = "juicer0"
/obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params)
if(default_unfasten_wrench(user, I))
return
if(default_unfasten_wrench(user, I))
return
if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1) )
if (!beaker)
if(!user.transferItemToLoc(I, src))
return 1
beaker = I
update_icon()
src.updateUsrDialog()
else
to_chat(user, "<span class='warning'>There's already a container inside [src].</span>")
return 1 //no afterattack
if (istype(I, /obj/item/reagent_containers) && (I.container_type & OPENCONTAINER_1) )
if (!beaker)
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
return TRUE
beaker = I
update_icon()
updateUsrDialog()
else
to_chat(user, "<span class='warning'>There's already a container inside [src].</span>")
return TRUE //no afterattack
if(is_type_in_list(I, dried_items))
if(istype(I, /obj/item/reagent_containers/food/snacks/grown))
var/obj/item/reagent_containers/food/snacks/grown/G = I
if(!G.dry)
to_chat(user, "<span class='warning'>You must dry [G] first!</span>")
return 1
if(is_type_in_list(I, dried_items))
if(istype(I, /obj/item/reagent_containers/food/snacks/grown))
var/obj/item/reagent_containers/food/snacks/grown/G = I
if(!G.dry)
to_chat(user, "<span class='warning'>You must dry [G] first!</span>")
return TRUE
if(holdingitems && holdingitems.len >= limit)
to_chat(usr, "The machine cannot hold anymore items.")
return 1
if(length(holdingitems) >= limit)
to_chat(user, "The machine cannot hold anymore items.")
return TRUE
//Fill machine with a bag!
if(istype(I, /obj/item/storage/bag))
var/obj/item/storage/bag/B = I
for (var/obj/item/reagent_containers/food/snacks/grown/G in B.contents)
B.remove_from_storage(G, src)
holdingitems += G
if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill
to_chat(user, "<span class='notice'>You fill [src] to the brim.</span>")
break
//Fill machine with a bag!
if(istype(I, /obj/item/storage/bag))
var/obj/item/storage/bag/B = I
for (var/obj/item/reagent_containers/food/snacks/grown/G in B.contents)
B.remove_from_storage(G, src)
holdingitems[G] = TRUE
if(length(holdingitems) >= limit) //Sanity checking so the blender doesn't overfill
to_chat(user, "<span class='notice'>You fill [src] to the brim.</span>")
break
if(!I.contents.len)
to_chat(user, "<span class='notice'>You empty [I] into [src].</span>")
if(!I.contents.len)
to_chat(user, "<span class='notice'>You empty [I] into [src].</span>")
src.updateUsrDialog()
return 1
updateUsrDialog()
return TRUE
if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items))
if(user.a_intent == INTENT_HARM)
return ..()
else
to_chat(user, "<span class='warning'>Cannot refine into a reagent!</span>")
return 1
if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items))
if(user.a_intent == INTENT_HARM)
return ..()
else
to_chat(user, "<span class='warning'>Cannot refine into a reagent!</span>")
return TRUE
if(user.transferItemToLoc(I, src))
holdingitems += I
src.updateUsrDialog()
return 0
if(user.transferItemToLoc(I, src))
holdingitems[I] = TRUE
updateUsrDialog()
return FALSE
/obj/machinery/reagentgrinder/attack_paw(mob/user)
return src.attack_hand(user)
return attack_hand(user)
/obj/machinery/reagentgrinder/attack_ai(mob/user)
return 0
return FALSE
/obj/machinery/reagentgrinder/attack_hand(mob/user)
user.set_machine(src)
interact(user)
user.set_machine(src)
interact(user)
/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu
var/is_chamber_empty = 0
var/is_beaker_ready = 0
var/processing_chamber = ""
var/beaker_contents = ""
var/dat = ""
var/is_chamber_empty = FALSE
var/is_beaker_ready = FALSE
var/processing_chamber = ""
var/beaker_contents = ""
var/dat = ""
if(!operating)
for (var/obj/item/O in holdingitems)
processing_chamber += "\A [O.name]<BR>"
if(!operating)
for (var/i in holdingitems)
var/obj/item/O = i
processing_chamber += "\A [O.name]<BR>"
if (!processing_chamber)
is_chamber_empty = 1
processing_chamber = "Nothing."
if (!beaker)
beaker_contents = "<B>No beaker attached.</B><br>"
else
is_beaker_ready = 1
beaker_contents = "<B>The beaker contains:</B><br>"
var/anything = 0
for(var/datum/reagent/R in beaker.reagents.reagent_list)
anything = 1
beaker_contents += "[R.volume] - [R.name]<br>"
if(!anything)
beaker_contents += "Nothing<br>"
dat = {"
<b>Processing chamber contains:</b><br>
[processing_chamber]<br>
[beaker_contents]<hr>
"}
if (is_beaker_ready)
if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN)))
dat += "<A href='?src=\ref[src];action=grind'>Grind the reagents</a><BR>"
dat += "<A href='?src=\ref[src];action=juice'>Juice the reagents</a><BR><BR>"
else if (beaker.reagents.total_volume)
dat += "<A href='?src=\ref[src];action=mix'>Mix the reagents</a><BR><BR>"
if(holdingitems && holdingitems.len > 0)
dat += "<A href='?src=\ref[src];action=eject'>Eject the reagents</a><BR>"
if (beaker)
dat += "<A href='?src=\ref[src];action=detach'>Detach the beaker</a><BR>"
if (!processing_chamber)
is_chamber_empty = TRUE
processing_chamber = "Nothing."
if (!beaker)
beaker_contents = "<B>No beaker attached.</B><br>"
else
dat += "Please wait..."
is_beaker_ready = TRUE
beaker_contents = "<B>The beaker contains:</B><br>"
var/anything = FALSE
for(var/datum/reagent/R in beaker.reagents.reagent_list)
anything = TRUE
beaker_contents += "[R.volume] - [R.name]<br>"
if(!anything)
beaker_contents += "Nothing<br>"
var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open(1)
return
dat = {"
<b>Processing chamber contains:</b><br>
[processing_chamber]<br>
[beaker_contents]<hr>
"}
if (is_beaker_ready)
if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN)))
dat += "<A href='?src=\ref[src];action=grind'>Grind the reagents</a><BR>"
dat += "<A href='?src=\ref[src];action=juice'>Juice the reagents</a><BR><BR>"
else if (beaker.reagents.total_volume)
dat += "<A href='?src=\ref[src];action=mix'>Mix the reagents</a><BR><BR>"
if(length(holdingitems))
dat += "<A href='?src=\ref[src];action=eject'>Eject the reagents</a><BR>"
if(beaker)
dat += "<A href='?src=\ref[src];action=detach'>Detach the beaker</a><BR>"
else
dat += "Please wait..."
var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open(1)
return
/obj/machinery/reagentgrinder/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
var/mob/user = usr
if(!user.canUseTopic(src))
return
if(stat & (NOPOWER|BROKEN))
return
user.set_machine(src)
if(operating)
updateUsrDialog()
return
switch(href_list["action"])
if ("grind")
grind()
grind(user)
if("juice")
juice()
juice(user)
if("mix")
mix()
mix(user)
if("eject")
eject()
if ("detach")
detach()
eject(user)
if("detach")
detach(user)
updateUsrDialog()
/obj/machinery/reagentgrinder/proc/detach()
/obj/machinery/reagentgrinder/proc/detach(mob/user)
if(!beaker)
return
beaker.forceMove(drop_location())
beaker = null
update_icon()
updateUsrDialog()
if (usr.stat != 0)
return
if (!beaker)
return
beaker.loc = src.loc
beaker = null
update_icon()
updateUsrDialog()
/obj/machinery/reagentgrinder/proc/eject(mob/user)
if(!length(holdingitems))
return
for(var/i in holdingitems)
var/obj/item/O = i
O.forceMove(drop_location())
holdingitems -= O
updateUsrDialog()
/obj/machinery/reagentgrinder/proc/eject()
/obj/machinery/reagentgrinder/proc/get_allowed_by_obj(obj/item/O)
return blend_items[O.type]
if (usr.stat != 0)
return
if (holdingitems && holdingitems.len == 0)
return
for(var/obj/item/O in holdingitems)
O.loc = src.loc
holdingitems -= O
holdingitems = list()
updateUsrDialog()
/obj/machinery/reagentgrinder/proc/is_allowed(obj/item/reagent_containers/O)
for (var/i in blend_items)
if(istype(O, i))
return 1
return 0
/obj/machinery/reagentgrinder/proc/get_allowed_by_id(obj/item/O)
for (var/i in blend_items)
if (istype(O, i))
return blend_items[i]
/obj/machinery/reagentgrinder/proc/get_allowed_snack_by_id(obj/item/reagent_containers/food/snacks/O)
for(var/i in blend_items)
if(istype(O, i))
return blend_items[i]
/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_id(obj/item/reagent_containers/food/snacks/O)
for(var/i in juice_items)
if(istype(O, i))
return juice_items[i]
/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_obj(obj/item/reagent_containers/food/snacks/O)
for(var/i in juice_items)
if(istype(O, i))
return juice_items[i]
/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/grown/O)
if (!istype(O) || !O.seed)
return 5
else if (O.seed.potency == -1)
return 5
else
return round(O.seed.potency)
if (!istype(O) || !O.seed)
return 5
else if (O.seed.potency == -1)
return 5
else
return round(O.seed.potency)
/obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/reagent_containers/food/snacks/grown/O)
if (!istype(O) || !O.seed)
return 5
else if (O.seed.potency == -1)
return 5
else
return round(5*sqrt(O.seed.potency))
if (!istype(O) || !O.seed)
return 5
else if (O.seed.potency == -1)
return 5
else
return round(5*sqrt(O.seed.potency))
/obj/machinery/reagentgrinder/proc/remove_object(obj/item/O)
holdingitems -= O
qdel(O)
holdingitems -= O
qdel(O)
/obj/machinery/reagentgrinder/proc/juice()
power_change()
if(stat & (NOPOWER|BROKEN))
return
if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
return
playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1)
var/offset = prob(50) ? -2 : 2
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking
operating = TRUE
updateUsrDialog()
spawn(50)
pixel_x = initial(pixel_x) //return to its spot after shaking
operating = FALSE
updateUsrDialog()
power_change()
if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)))
return
operate_for(50, juicing = TRUE)
//Snacks
for (var/obj/item/reagent_containers/food/snacks/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
//Snacks
for(var/obj/item/i in holdingitems)
var/obj/item/I = i
if(istype(I, /obj/item/reagent_containers/food/snacks))
var/obj/item/reagent_containers/food/snacks/O = I
if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/list/allowed = get_allowed_juice_by_obj(O)
if(isnull(allowed))
break
for(var/r_id in allowed)
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))
if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
remove_object(O)
var/allowed = get_allowed_juice_by_id(O)
if(isnull(allowed))
break
/obj/machinery/reagentgrinder/proc/shake_for(duration)
var/offset = prob(50) ? -2 : 2
var/old_pixel_x = pixel_x
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = -1) //start shaking
addtimer(CALLBACK(src, .proc/stop_shaking, old_pixel_x), duration)
for (var/r_id in allowed)
/obj/machinery/reagentgrinder/proc/stop_shaking(old_px)
animate(src)
pixel_x = old_px
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
var/amount = get_juice_amount(O)
/obj/machinery/reagentgrinder/proc/operate_for(time, silent = FALSE, juicing = FALSE)
shake_for(time)
updateUsrDialog()
operating = TRUE
if(!silent)
if(!juicing)
playsound(src, 'sound/machines/blender.ogg', 50, 1)
else
playsound(src, 'sound/machines/juicer.ogg', 20, 1)
addtimer(CALLBACK(src, .proc/stop_operating), time)
beaker.reagents.add_reagent(r_id, min(amount, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
remove_object(O)
/obj/machinery/reagentgrinder/proc/stop_operating()
operating = FALSE
updateUsrDialog()
/obj/machinery/reagentgrinder/proc/grind()
power_change()
if(stat & (NOPOWER|BROKEN))
return
if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
return
playsound(src.loc, 'sound/machines/blender.ogg', 50, 1)
var/offset = prob(50) ? -2 : 2
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking
operating = TRUE
updateUsrDialog()
spawn(60)
pixel_x = initial(pixel_x) //return to its spot after shaking
operating = FALSE
updateUsrDialog()
//Snacks and Plants
for (var/obj/item/reagent_containers/food/snacks/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/allowed = get_allowed_snack_by_id(O)
if(isnull(allowed))
break
for (var/r_id in allowed)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
var/amount = allowed[r_id]
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))
O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), 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))
O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space))
else
O.reagents.trans_id_to(beaker, r_id, min(amount, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
if(O.reagents.reagent_list.len == 0)
remove_object(O)
//Sheets
for (var/obj/item/stack/sheet/O in holdingitems)
var/allowed = get_allowed_by_id(O)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
for(var/i = 1; i <= round(O.amount, 1); i++)
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))
if (space < amount)
break
if (i == round(O.amount, 1))
remove_object(O)
break
//Plants
for (var/obj/item/grown/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/allowed = get_allowed_by_id(O)
for (var/r_id in allowed)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
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))
else
beaker.reagents.add_reagent(r_id,min(amount, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
remove_object(O)
//Slime Extractis
for (var/obj/item/slime_extract/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
power_change()
if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
return
operate_for(60)
for(var/i in holdingitems)
if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/obj/item/I = i
//Snacks
if(istype(I, /obj/item/reagent_containers/food/snacks))
var/obj/item/reagent_containers/food/snacks/O = I
var/list/allowed = get_allowed_by_obj(O)
if(isnull(allowed))
continue
for(var/r_id in allowed)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
if (O.reagents != null)
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))
var/amount = allowed[r_id]
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))
O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), 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))
O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space))
else
O.reagents.trans_id_to(beaker, r_id, min(amount, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
if(O.reagents.reagent_list.len == 0)
remove_object(O)
//Sheets
else if(istype(I, /obj/item/stack/sheet))
var/obj/item/stack/sheet/O = I
var/list/allowed = get_allowed_by_obj(O)
for(var/t in 1 to round(O.amount, 1))
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))
if (space < amount)
break
if(t == round(O.amount, 1))
remove_object(O)
break
//Plants
else if(istype(I, /obj/item/grown))
var/obj/item/grown/O = I
var/list/allowed = get_allowed_by_obj(O)
for (var/r_id in allowed)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
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))
else
beaker.reagents.add_reagent(r_id,min(amount, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
remove_object(O)
else if(istype(I, /obj/item/slime_extract))
var/obj/item/slime_extract/O = I
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
if (O.reagents != null)
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))
remove_object(O)
else if(istype(I, /obj/item/reagent_containers))
var/obj/item/reagent_containers/O = I
var/amount = O.reagents.total_volume
O.reagents.trans_to(beaker, amount)
if(!O.reagents.total_volume)
remove_object(O)
else if(istype(I, /obj/item/toy/crayon))
var/obj/item/toy/crayon/O = I
for (var/r_id in O.reagent_contents)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
if(!space)
break
beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space))
remove_object(O)
//Everything else - Transfers reagents from it into beaker
for (var/obj/item/reagent_containers/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/amount = O.reagents.total_volume
O.reagents.trans_to(beaker, amount)
if(!O.reagents.total_volume)
remove_object(O)
for (var/obj/item/toy/crayon/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
for (var/r_id in O.reagent_contents)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
if (space == 0)
break
beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space))
remove_object(O)
/obj/machinery/reagentgrinder/proc/mix()
//For butter and other things that would change upon shaking or mixing
power_change()
if(stat & (NOPOWER|BROKEN))
return
if (!beaker)
return
playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1)
var/offset = prob(50) ? -2 : 2
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking
operating = TRUE
updateUsrDialog()
addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50)
/obj/machinery/reagentgrinder/proc/mix(mob/user)
//For butter and other things that would change upon shaking or mixing
power_change()
if(!beaker)
return
operate_for(50, juicing = TRUE)
addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50)
/obj/machinery/reagentgrinder/proc/mix_complete()
pixel_x = initial(pixel_x) //return to its spot after shaking
operating = FALSE
updateUsrDialog()
if (beaker.reagents.total_volume)
//Recipe to make Butter
while(beaker.reagents.get_reagent_amount("milk") >= 15)
beaker.reagents.remove_reagent("milk", 15)
new /obj/item/reagent_containers/food/snacks/butter(src.loc)
//Recipe to make Mayonnaise
if (beaker.reagents.has_reagent("eggyolk"))
var/amount = beaker.reagents.get_reagent_amount("eggyolk")
beaker.reagents.remove_reagent("eggyolk", amount)
beaker.reagents.add_reagent("mayonnaise", amount)
if(beaker && beaker.reagents.total_volume)
//Recipe to make Butter
var/butter_amt = Floor(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF)
beaker.reagents.remove_reagent("milk", MILK_TO_BUTTER_COEFF * butter_amt)
for(var/i in 1 to butter_amt)
new /obj/item/reagent_containers/food/snacks/butter(drop_location())
//Recipe to make Mayonnaise
if (beaker.reagents.has_reagent("eggyolk"))
var/amount = beaker.reagents.get_reagent_amount("eggyolk")
beaker.reagents.remove_reagent("eggyolk", amount)
beaker.reagents.add_reagent("mayonnaise", amount)
+2 -1
View File
@@ -28,8 +28,9 @@ using metal and glass, it uses glass and reagents (usually sulfuric acis).
)
/obj/machinery/r_n_d/circuit_imprinter/Initialize()
AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE),
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container, list(MAT_GLASS, MAT_GOLD, MAT_DIAMOND, MAT_METAL, MAT_BLUESPACE),
FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready))
materials.precise_insertion = TRUE
create_reagents(0)
return ..()
+2 -1
View File
@@ -33,9 +33,10 @@ Note: Must be placed west/left of and R&D console to function.
/obj/machinery/r_n_d/protolathe/Initialize()
create_reagents(0)
AddComponent(/datum/component/material_container,
var/datum/component/material_container/materials = AddComponent(/datum/component/material_container,
list(MAT_METAL, MAT_GLASS, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_PLASMA, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM, MAT_BLUESPACE),
FALSE, list(/obj/item/stack, /obj/item/ore/bluespace_crystal), CALLBACK(src, .proc/is_insertion_ready))
materials.precise_insertion = TRUE
return ..()
/obj/machinery/r_n_d/protolathe/RefreshParts()