#define SOLID 1 #define LIQUID 2 #define GAS 3 #define BOTTLE_SPRITES list("bottle-1", "bottle-2", "bottle-3", "bottle-4") //list of available bottle sprites #define REAGENTS_PER_SHEET 20 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /obj/machinery/chem_master name = "ChemMaster 3000" density = 1 anchored = 1 icon = 'icons/obj/chemical.dmi' icon_state = "mixer0" use_power = 1 idle_power_usage = 20 var/beaker = null var/obj/item/weapon/storage/pill_bottle/loaded_pill_bottle = null var/mode = 0 var/condi = 0 var/useramount = 30 // Last used amount var/pillamount = 10 var/bottlesprite = "bottle-1" //yes, strings var/pillsprite = "1" var/client/has_sprites = list() var/max_pill_count = 20 /obj/machinery/chem_master/New() ..() var/datum/reagents/R = new/datum/reagents(120) reagents = R R.my_atom = src /obj/machinery/chem_master/ex_act(severity) switch(severity) if(1.0) qdel(src) return if(2.0) if (prob(50)) qdel(src) return /obj/machinery/chem_master/blob_act() if (prob(50)) qdel(src) /obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) if(istype(B, /obj/item/weapon/reagent_containers/glass)) if(src.beaker) user << "A beaker is already loaded into the machine." return src.beaker = B user.drop_item() B.loc = src user << "You add the beaker to the machine!" src.updateUsrDialog() icon_state = "mixer1" else if(istype(B, /obj/item/weapon/storage/pill_bottle)) if(src.loaded_pill_bottle) user << "A pill bottle is already loaded into the machine." return src.loaded_pill_bottle = B user.drop_item() B.loc = src user << "You add the pill bottle into the dispenser slot!" src.updateUsrDialog() return /obj/machinery/chem_master/Topic(href, href_list) if(stat & (BROKEN|NOPOWER)) return if(usr.stat || usr.restrained()) return if(!in_range(src, usr)) return src.add_fingerprint(usr) usr.set_machine(src) if (href_list["ejectp"]) if(loaded_pill_bottle) loaded_pill_bottle.loc = src.loc loaded_pill_bottle = null else if(href_list["close"]) usr << browse(null, "window=chemmaster") usr.unset_machine() return if(beaker) var/datum/reagents/R = beaker:reagents if (href_list["analyze"]) var/dat = "" if(!condi) if(href_list["name"] == "Blood") var/datum/reagent/blood/G for(var/datum/reagent/F in R.reagent_list) if(F.name == href_list["name"]) G = F break var/A = G.name var/B = G.data["blood_type"] var/C = G.data["blood_DNA"] dat += "Chemmaster 3000Chemical infos:

Name:
[A]

Description:
Blood Type: [B]
DNA: [C]


(Back)" else dat += "Chemmaster 3000Chemical infos:

Name:
[href_list["name"]]

Description:
[href_list["desc"]]


(Back)" else dat += "Condimaster 3000Condiment infos:

Name:
[href_list["name"]]

Description:
[href_list["desc"]]


(Back)" usr << browse(dat, "window=chem_master;size=575x400") return else if (href_list["add"]) if(href_list["amount"]) var/id = href_list["add"] var/amount = isgoodnumber(text2num(href_list["amount"])) R.trans_id_to(src, id, amount) else if (href_list["addcustom"]) var/id = href_list["addcustom"] useramount = input("Select the amount to transfer.", 30, useramount) as num useramount = isgoodnumber(useramount) src.Topic(null, list("amount" = "[useramount]", "add" = "[id]")) else if (href_list["remove"]) if(href_list["amount"]) var/id = href_list["remove"] var/amount = isgoodnumber(text2num(href_list["amount"])) if(mode) reagents.trans_id_to(beaker, id, amount) else reagents.remove_reagent(id, amount) else if (href_list["removecustom"]) var/id = href_list["removecustom"] useramount = input("Select the amount to transfer.", 30, useramount) as num useramount = isgoodnumber(useramount) src.Topic(null, list("amount" = "[useramount]", "remove" = "[id]")) else if (href_list["toggle"]) mode = !mode else if (href_list["main"]) attack_hand(usr) return else if (href_list["eject"]) if(beaker) beaker:loc = src.loc beaker = null reagents.clear_reagents() icon_state = "mixer0" else if (href_list["createpill"] || href_list["createpill_multiple"]) var/count = 1 if(reagents.total_volume/count < 1) //Sanity checking. return if (href_list["createpill_multiple"]) count = Clamp(isgoodnumber(input("Select the number of pills to make.", 10, pillamount) as num),1,max_pill_count) if(reagents.total_volume/count < 1) //Sanity checking. return var/amount_per_pill = reagents.total_volume/count if (amount_per_pill > 60) amount_per_pill = 60 var/name = sanitizeSafe(input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill] units)"), MAX_NAME_LEN) if(reagents.total_volume/count < 1) //Sanity checking. return while (count--) var/obj/item/weapon/reagent_containers/pill/P = new/obj/item/weapon/reagent_containers/pill(src.loc) if(!name) name = reagents.get_master_reagent_name() P.name = "[name] pill" P.pixel_x = rand(-7, 7) //random position P.pixel_y = rand(-7, 7) P.icon_state = "pill"+pillsprite reagents.trans_to_obj(P,amount_per_pill) if(src.loaded_pill_bottle) if(loaded_pill_bottle.contents.len < loaded_pill_bottle.storage_slots) P.loc = loaded_pill_bottle src.updateUsrDialog() else if (href_list["createbottle"]) if(!condi) var/name = sanitizeSafe(input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()), MAX_NAME_LEN) var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) if(!name) name = reagents.get_master_reagent_name() P.name = "[name] bottle" P.pixel_x = rand(-7, 7) //random position P.pixel_y = rand(-7, 7) P.icon_state = bottlesprite reagents.trans_to_obj(P,60) P.update_icon() else var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(src.loc) reagents.trans_to_obj(P,50) else if(href_list["change_pill"]) #define MAX_PILL_SPRITE 20 //max icon state of the pill sprites var/dat = "" for(var/i = 1 to MAX_PILL_SPRITE) dat += "" dat += "
" usr << browse(dat, "window=chem_master") return else if(href_list["change_bottle"]) var/dat = "" for(var/sprite in BOTTLE_SPRITES) dat += "" dat += "
" usr << browse(dat, "window=chem_master") return else if(href_list["pill_sprite"]) pillsprite = href_list["pill_sprite"] else if(href_list["bottle_sprite"]) bottlesprite = href_list["bottle_sprite"] src.updateUsrDialog() return /obj/machinery/chem_master/attack_ai(mob/user as mob) return src.attack_hand(user) /obj/machinery/chem_master/attack_hand(mob/user as mob) if(stat & BROKEN) return user.set_machine(src) if(!(user.client in has_sprites)) spawn() has_sprites += user.client for(var/i = 1 to MAX_PILL_SPRITE) usr << browse_rsc(icon('icons/obj/chemical.dmi', "pill" + num2text(i)), "pill[i].png") for(var/sprite in BOTTLE_SPRITES) usr << browse_rsc(icon('icons/obj/chemical.dmi', sprite), "[sprite].png") var/dat = "" if(!beaker) dat = "Please insert beaker.
" if(src.loaded_pill_bottle) dat += "Eject Pill Bottle \[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\]

" else dat += "No pill bottle inserted.

" dat += "Close" else var/datum/reagents/R = beaker:reagents dat += "Eject beaker and Clear Buffer
" if(src.loaded_pill_bottle) dat += "Eject Pill Bottle \[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\]

" else dat += "No pill bottle inserted.

" if(!R.total_volume) dat += "Beaker is empty." else dat += "Add to buffer:
" for(var/datum/reagent/G in R.reagent_list) dat += "[G.name] , [G.volume] Units - " dat += "(Analyze) " dat += "(1) " dat += "(5) " dat += "(10) " dat += "(All) " dat += "(Custom)
" dat += "
Transfer to [(!mode ? "disposal" : "beaker")]:
" if(reagents.total_volume) for(var/datum/reagent/N in reagents.reagent_list) dat += "[N.name] , [N.volume] Units - " dat += "(Analyze) " dat += "(1) " dat += "(5) " dat += "(10) " dat += "(All) " dat += "(Custom)
" else dat += "Empty
" if(!condi) dat += "

Create pill (60 units max)
" dat += "Create multiple pills
" dat += "Create bottle (60 units max)" else dat += "Create bottle (50 units max)" if(!condi) user << browse("Chemmaster 3000Chemmaster menu:

[dat]", "window=chem_master;size=575x400") else user << browse("Condimaster 3000Condimaster menu:

[dat]", "window=chem_master;size=575x400") onclose(user, "chem_master") return /obj/machinery/chem_master/proc/isgoodnumber(var/num) if(isnum(num)) return Clamp(round(num), 0, 200) else return 0 /obj/machinery/chem_master/condimaster name = "CondiMaster 3000" condi = 1 //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /obj/machinery/computer/pandemic name = "PanD.E.M.I.C 2200" density = 1 anchored = 1 icon = 'icons/obj/chemical.dmi' icon_state = "mixer0" circuit = /obj/item/weapon/circuitboard/pandemic //use_power = 1 //idle_power_usage = 20 //defaults make more sense. var/temphtml = "" var/wait = null var/obj/item/weapon/reagent_containers/glass/beaker = null /obj/machinery/computer/pandemic/set_broken() icon_state = (src.beaker?"mixer1_b":"mixer0_b") stat |= BROKEN /obj/machinery/computer/pandemic/power_change() ..() if(stat & BROKEN) icon_state = (src.beaker?"mixer1_b":"mixer0_b") else if(!(stat & NOPOWER)) icon_state = (src.beaker?"mixer1":"mixer0") else spawn(rand(0, 15)) src.icon_state = (src.beaker?"mixer1_nopower":"mixer0_nopower") /obj/machinery/computer/pandemic/Topic(href, href_list) if(stat & (NOPOWER|BROKEN)) return if(usr.stat || usr.restrained()) return if(!in_range(src, usr)) return usr.set_machine(src) if(!beaker) return if (href_list["create_vaccine"]) if(!src.wait) var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) if(B) var/path = href_list["create_vaccine"] var/vaccine_type = text2path(path) var/datum/disease/D = null if(!vaccine_type) D = archive_diseases[path] vaccine_type = path else if(vaccine_type in diseases) D = new vaccine_type(0, null) if(D) B.name = "[D.name] vaccine bottle" B.reagents.add_reagent("vaccine",15,vaccine_type) wait = 1 var/datum/reagents/R = beaker.reagents var/datum/reagent/blood/Blood = null for(var/datum/reagent/blood/L in R.reagent_list) if(L) Blood = L break var/list/res = Blood.data["resistances"] spawn(res.len*200) src.wait = null else src.temphtml = "The replicator is not ready yet." src.updateUsrDialog() return else if (href_list["create_virus_culture"]) if(!wait) var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) B.icon_state = "bottle-1" var/type = text2path(href_list["create_virus_culture"])//the path is received as string - converting var/datum/disease/D = null if(!type) var/datum/disease/advance/A = archive_diseases[href_list["create_virus_culture"]] if(A) D = new A.type(0, A) else if(type in diseases) // Make sure this is a disease D = new type(0, null) var/list/data = list("viruses"=list(D)) var/name = sanitizeSafe(input(usr,"Name:","Name the culture",D.name), MAX_NAME_LEN) if(!name || name == " ") name = D.name B.name = "[name] culture bottle" B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium." B.reagents.add_reagent("blood",20,data) B.update_icon() src.updateUsrDialog() wait = 1 spawn(1000) src.wait = null else src.temphtml = "The replicator is not ready yet." src.updateUsrDialog() return else if (href_list["empty_beaker"]) beaker.reagents.clear_reagents() src.updateUsrDialog() return else if (href_list["eject"]) beaker:loc = src.loc beaker = null icon_state = "mixer0" src.updateUsrDialog() return else if(href_list["clear"]) src.temphtml = "" src.updateUsrDialog() return else if(href_list["name_disease"]) var/new_name = sanitizeSafe(input(usr, "Name the Disease", "New Name", ""), MAX_NAME_LEN) if(stat & (NOPOWER|BROKEN)) return if(usr.stat || usr.restrained()) return if(!in_range(src, usr)) return var/id = href_list["name_disease"] if(archive_diseases[id]) var/datum/disease/advance/A = archive_diseases[id] A.AssignName(new_name) for(var/datum/disease/advance/AD in active_diseases) AD.Refresh() src.updateUsrDialog() else usr << browse(null, "window=pandemic") src.updateUsrDialog() return src.add_fingerprint(usr) return /obj/machinery/computer/pandemic/attack_ai(mob/user as mob) return src.attack_hand(user) /obj/machinery/computer/pandemic/attack_hand(mob/user as mob) if(stat & (NOPOWER|BROKEN)) return user.set_machine(src) var/dat = "" if(src.temphtml) dat = "[src.temphtml]

Main Menu" else if(!beaker) dat += "Please insert beaker.
" dat += "Close" else var/datum/reagents/R = beaker.reagents var/datum/reagent/blood/Blood = null for(var/datum/reagent/blood/B in R.reagent_list) if(B) Blood = B break if(!R.total_volume||!R.reagent_list.len) dat += "The beaker is empty
" else if(!Blood) dat += "No blood sample found in beaker" else if(!Blood.data) dat += "No blood data found in beaker." else dat += "

Blood sample data:

" dat += "Blood DNA: [(Blood.data["blood_DNA"]||"none")]
" dat += "Blood Type: [(Blood.data["blood_type"]||"none")]
" if(Blood.data["viruses"]) var/list/vir = Blood.data["viruses"] if(vir.len) for(var/datum/disease/D in Blood.data["viruses"]) if(!D.hidden[PANDEMIC]) var/disease_creation = D.type if(istype(D, /datum/disease/advance)) var/datum/disease/advance/A = D D = archive_diseases[A.GetDiseaseID()] disease_creation = A.GetDiseaseID() if(D.name == "Unknown") dat += "Name Disease
" if(!D) CRASH("We weren't able to get the advance disease from the archive.") dat += "Disease Agent: [D?"[D.agent] - Create virus culture bottle":"none"]
" dat += "Common name: [(D.name||"none")]
" dat += "Description: [(D.desc||"none")]
" dat += "Spread: [(D.spread||"none")]
" dat += "Possible cure: [(D.cure||"none")]

" if(istype(D, /datum/disease/advance)) var/datum/disease/advance/A = D dat += "Symptoms: " var/english_symptoms = list() for(var/datum/symptom/S in A.symptoms) english_symptoms += S.name dat += english_list(english_symptoms) dat += "
Contains antibodies to: " if(Blood.data["resistances"]) var/list/res = Blood.data["resistances"] if(res.len) dat += "
" else dat += "nothing
" else dat += "nothing
" dat += "
Eject beaker[((R.total_volume&&R.reagent_list.len) ? "-- Empty beaker":"")]
" dat += "Close" user << browse("[src.name]
[dat]", "window=pandemic;size=575x400") onclose(user, "pandemic") return /obj/machinery/computer/pandemic/attackby(var/obj/I as obj, var/mob/user as mob) if(istype(I, /obj/item/weapon/reagent_containers/glass)) if(stat & (NOPOWER|BROKEN)) return if(src.beaker) user << "A beaker is already loaded into the machine." return src.beaker = I user.drop_item() I.loc = src user << "You add the beaker to the machine!" src.updateUsrDialog() icon_state = "mixer1" else ..() return //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /obj/machinery/reagentgrinder name = "All-In-One Grinder" icon = 'icons/obj/kitchen.dmi' icon_state = "juicer1" layer = 2.9 density = 0 anchored = 0 use_power = 1 idle_power_usage = 5 active_power_usage = 100 var/inuse = 0 var/obj/item/weapon/reagent_containers/beaker = null var/limit = 10 var/list/holdingitems = list() var/list/sheet_reagents = list( /obj/item/stack/material/iron = "iron", /obj/item/stack/material/uranium = "uranium", /obj/item/stack/material/phoron = "phoron", /obj/item/stack/material/gold = "gold", /obj/item/stack/material/silver = "silver", /obj/item/stack/material/mhydrogen = "hydrogen" ) /obj/machinery/reagentgrinder/New() ..() beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) return /obj/machinery/reagentgrinder/update_icon() icon_state = "juicer"+num2text(!isnull(beaker)) return /obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob) if (istype(O,/obj/item/weapon/reagent_containers/glass) || \ istype(O,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass) || \ istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) if (beaker) return 1 else src.beaker = O user.drop_item() O.loc = src update_icon() src.updateUsrDialog() return 0 if(holdingitems && holdingitems.len >= limit) usr << "The machine cannot hold anymore items." return 1 if(!istype(O)) return if(istype(O,/obj/item/weapon/storage/bag/plants)) var/failed = 1 for(var/obj/item/G in O.contents) if(!G.reagents || !G.reagents.total_volume) continue failed = 0 O.contents -= G G.loc = src holdingitems += G if(holdingitems && holdingitems.len >= limit) break if(failed) user << "Nothing in the plant bag is usable." return 1 if(!O.contents.len) user << "You empty \the [O] into \the [src]." else user << "You fill \the [src] from \the [O]." src.updateUsrDialog() return 0 if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume)) user << "\The [O] is not suitable for blending." return 1 user.remove_from_mob(O) O.loc = src holdingitems += O src.updateUsrDialog() return 0 /obj/machinery/reagentgrinder/attack_ai(mob/user as mob) return 0 /obj/machinery/reagentgrinder/attack_hand(mob/user as mob) user.set_machine(src) interact(user) /obj/machinery/reagentgrinder/interact(mob/user as mob) // The microwave Menu var/is_chamber_empty = 0 var/is_beaker_ready = 0 var/processing_chamber = "" var/beaker_contents = "" var/dat = "" if(!inuse) for (var/obj/item/O in holdingitems) processing_chamber += "\A [O.name]
" if (!processing_chamber) is_chamber_empty = 1 processing_chamber = "Nothing." if (!beaker) beaker_contents = "No beaker attached.
" else is_beaker_ready = 1 beaker_contents = "The beaker contains:
" var/anything = 0 for(var/datum/reagent/R in beaker.reagents.reagent_list) anything = 1 beaker_contents += "[R.volume] - [R.name]
" if(!anything) beaker_contents += "Nothing
" dat = {" Processing chamber contains:
[processing_chamber]
[beaker_contents]
"} if (is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) dat += "Process the reagents
" if(holdingitems && holdingitems.len > 0) dat += "Eject the reagents
" if (beaker) dat += "Detach the beaker
" else dat += "Please wait..." user << browse("All-In-One Grinder[dat]", "window=reagentgrinder") onclose(user, "reagentgrinder") return /obj/machinery/reagentgrinder/Topic(href, href_list) if(..()) return usr.set_machine(src) switch(href_list["action"]) if ("grind") grind() if("eject") eject() if ("detach") detach() src.updateUsrDialog() return /obj/machinery/reagentgrinder/proc/detach() if (usr.stat != 0) return if (!beaker) return beaker.loc = src.loc beaker = null update_icon() /obj/machinery/reagentgrinder/proc/eject() 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.Cut() /obj/machinery/reagentgrinder/proc/grind() power_change() if(stat & (NOPOWER|BROKEN)) return // Sanity check. if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) return playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) inuse = 1 // Reset the machine. spawn(60) inuse = 0 interact(usr) // Process. for (var/obj/item/O in holdingitems) var/remaining_volume = beaker.reagents.maximum_volume - beaker.reagents.total_volume if(remaining_volume <= 0) break if(sheet_reagents[O.type]) var/obj/item/stack/stack = O if(istype(stack)) var/amount_to_take = max(0,min(stack.amount,round(remaining_volume/REAGENTS_PER_SHEET))) if(amount_to_take) stack.use(amount_to_take) if(deleted(stack)) holdingitems -= stack beaker.reagents.add_reagent(sheet_reagents[stack.type], (amount_to_take*REAGENTS_PER_SHEET)) continue if(O.reagents) O.reagents.trans_to(beaker, min(O.reagents.total_volume, remaining_volume)) if(O.reagents.total_volume == 0) holdingitems -= O qdel(O) if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) break #undef REAGENTS_PER_SHEET