#define PILL_STYLE_COUNT 22 //Update this if you add more pill icons or you die #define RANDOM_PILL_STYLE 22 //Dont change this one though /obj/machinery/chem_master name = "ChemMaster 3000" desc = "Used to separate chemicals and distribute them in a variety of forms." density = TRUE layer = BELOW_OBJ_LAYER icon = 'icons/obj/chemical.dmi' icon_state = "mixer0" use_power = IDLE_POWER_USE idle_power_usage = 20 resistance_flags = FIRE_PROOF | ACID_PROOF circuit = /obj/item/circuitboard/machine/chem_master var/obj/item/reagent_containers/beaker = null var/obj/item/storage/pill_bottle/bottle = null var/mode = 1 var/condi = FALSE var/chosenPillStyle = 1 var/screen = "home" var/analyzeVars[0] var/useramount = 30 // Last used amount var/list/pillStyles /obj/machinery/chem_master/Initialize() create_reagents(100) //Calculate the span tags and ids fo all the available pill icons var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) pillStyles = list() for (var/x in 1 to PILL_STYLE_COUNT) var/list/SL = list() SL["id"] = x SL["htmltag"] = assets.icon_tag("pill[x]") pillStyles += list(SL) . = ..() /obj/machinery/chem_master/Destroy() QDEL_NULL(beaker) QDEL_NULL(bottle) return ..() /obj/machinery/chem_master/RefreshParts() reagents.maximum_volume = 0 for(var/obj/item/reagent_containers/glass/beaker/B in component_parts) reagents.maximum_volume += B.reagents.maximum_volume /obj/machinery/chem_master/ex_act(severity, target) if(severity < 3) ..() /obj/machinery/chem_master/contents_explosion(severity, target) ..() if(beaker) beaker.ex_act(severity, target) if(bottle) bottle.ex_act(severity, target) /obj/machinery/chem_master/handle_atom_del(atom/A) ..() if(A == beaker) beaker = null reagents.clear_reagents() update_icon() else if(A == bottle) bottle = null /obj/machinery/chem_master/update_icon() cut_overlays() if (stat & BROKEN) add_overlay("waitlight") if(beaker) icon_state = "mixer1" else icon_state = "mixer0" /obj/machinery/chem_master/blob_act(obj/structure/blob/B) if (prob(50)) qdel(src) /obj/machinery/chem_master/attackby(obj/item/I, mob/user, params) if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", I)) return else if(default_deconstruction_crowbar(I)) return if(default_unfasten_wrench(user, I)) return if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container()) . = TRUE // no afterattack if(panel_open) to_chat(user, "You can't use the [src.name] while its panel is opened!") return var/obj/item/reagent_containers/B = I if(!user.transferItemToLoc(B, src)) return replace_beaker(user, B) to_chat(user, "You add [B] to [src].") updateUsrDialog() update_icon() else if(!condi && istype(I, /obj/item/storage/pill_bottle)) if(bottle) to_chat(user, "A pill bottle is already loaded into [src]!") return if(!user.transferItemToLoc(I, src)) return bottle = I to_chat(user, "You add [I] into the dispenser slot.") updateUsrDialog() else return ..() /obj/machinery/chem_master/AltClick(mob/living/user) if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) return replace_beaker(user) return /obj/machinery/chem_master/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) if(beaker) beaker.forceMove(drop_location()) if(user && Adjacent(user) && !issiliconoradminghost(user)) user.put_in_hands(beaker) if(new_beaker) beaker = new_beaker else beaker = null update_icon() return TRUE /obj/machinery/chem_master/on_deconstruction() replace_beaker(usr) if(bottle) bottle.forceMove(drop_location()) adjust_item_drop_location(bottle) bottle = null return ..() /obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) assets.send(user) ui = new(user, src, ui_key, "chem_master", name, 500, 550, master_ui, state) ui.open() //Insert our custom spritesheet css link into the html /obj/machinery/chem_master/ui_base_html(html) var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) . = replacetext(html, "", assets.css_tag()) /obj/machinery/chem_master/ui_data(mob/user) var/list/data = list() data["isBeakerLoaded"] = beaker ? 1 : 0 data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null data["beakerMaxVolume"] = beaker ? beaker.volume : null data["mode"] = mode data["condi"] = condi data["screen"] = screen data["analyzeVars"] = analyzeVars data["chosenPillStyle"] = chosenPillStyle data["isPillBottleLoaded"] = bottle ? 1 : 0 if(bottle) GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle) data["pillBotContent"] = bottle.contents.len data["pillBotMaxContent"] = STRB.max_items var/beakerContents[0] if(beaker) for(var/datum/reagent/R in beaker.reagents.reagent_list) beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list... data["beakerContents"] = beakerContents var/bufferContents[0] if(reagents.total_volume) for(var/datum/reagent/N in reagents.reagent_list) bufferContents.Add(list(list("name" = N.name, "id" = N.id, "volume" = N.volume))) // ^ data["bufferContents"] = bufferContents //Calculated at init time as it never changes data["pillStyles"] = pillStyles return data /obj/machinery/chem_master/ui_act(action, params) if(..()) return switch(action) if("eject") replace_beaker(usr) . = TRUE if("ejectp") if(bottle) bottle.forceMove(drop_location()) adjust_item_drop_location(bottle) bottle = null . = TRUE if("transferToBuffer") if(beaker) var/id = params["id"] var/amount = text2num(params["amount"]) if (amount > 0) end_fermi_reaction() beaker.reagents.trans_id_to(src, id, amount) . = TRUE else if (amount == -1) // -1 means custom amount useramount = input("Enter the Amount you want to transfer:", name, useramount) as num|null if (useramount > 0) end_fermi_reaction() beaker.reagents.trans_id_to(src, id, useramount) . = TRUE if("transferFromBuffer") var/id = params["id"] var/amount = text2num(params["amount"]) if (amount > 0) if(mode) reagents.trans_id_to(beaker, id, amount) . = TRUE else reagents.remove_reagent(id, amount) . = TRUE if("toggleMode") mode = !mode . = TRUE if("createPill") var/many = params["many"] if(reagents.total_volume == 0) return if(!condi) var/amount = 1 var/vol_each = min(reagents.total_volume, 50) if(text2num(many)) amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0, 10) if(!amount) return vol_each = min(reagents.total_volume / amount, 50) var/name = stripped_input(usr,"Name:","Name your pill!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN) if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return var/obj/item/reagent_containers/pill/P var/target_loc = drop_location() var/drop_threshold = INFINITY if(bottle) GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle) if(STRB) drop_threshold = STRB.max_items - bottle.contents.len for(var/i = 0; i < amount; i++) if(i < drop_threshold) P = new(target_loc) else P = new(drop_location()) P.name = trim("[name] pill") if(chosenPillStyle == RANDOM_PILL_STYLE) P.icon_state ="pill[rand(1,21)]" else P.icon_state = "pill[chosenPillStyle]" if(P.icon_state == "pill4") P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality." adjust_item_drop_location(P) reagents.trans_to(P,vol_each) else var/name = stripped_input(usr, "Name:", "Name your pack!", reagents.get_master_reagent_name(), MAX_NAME_LEN) if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return var/obj/item/reagent_containers/food/condiment/pack/P = new/obj/item/reagent_containers/food/condiment/pack(drop_location()) P.originalname = name P.name = trim("[name] pack") P.desc = "A small condiment pack. The label says it contains [name]." reagents.trans_to(P,10) . = TRUE if("pillStyle") var/id = text2num(params["id"]) chosenPillStyle = id if("createPatch") var/many = params["many"] if(reagents.total_volume == 0) return var/amount = 1 var/vol_each = min(reagents.total_volume, 40) if(text2num(many)) amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0, 10) if(!amount) return vol_each = min(reagents.total_volume / amount, 40) var/name = stripped_input(usr,"Name:","Name your patch!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN) if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return var/obj/item/reagent_containers/pill/P for(var/i = 0; i < amount; i++) P = new/obj/item/reagent_containers/pill/patch(drop_location()) P.name = trim("[name] patch") adjust_item_drop_location(P) reagents.trans_to(P,vol_each) . = TRUE if("createBottle") var/many = params["many"] if(reagents.total_volume == 0) return if(condi) var/name = stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN) if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return var/obj/item/reagent_containers/food/condiment/P = new(drop_location()) P.originalname = name P.name = trim("[name] bottle") reagents.trans_to(P, P.volume) else var/amount_full = 0 var/vol_part = min(reagents.total_volume, 30) if(text2num(many)) amount_full = round(reagents.total_volume / 30) vol_part = reagents.total_volume % 30 var/name = stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN) if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return var/obj/item/reagent_containers/glass/bottle/P for(var/i = 0; i < amount_full; i++) P = new/obj/item/reagent_containers/glass/bottle(drop_location()) P.name = trim("[name] bottle") adjust_item_drop_location(P) reagents.trans_to(P, 30) if(vol_part) P = new/obj/item/reagent_containers/glass/bottle(drop_location()) P.name = trim("[name] bottle") adjust_item_drop_location(P) reagents.trans_to(P, vol_part) . = TRUE //CITADEL ADD Hypospray Vials if("createVial") var/many = params["many"] if(reagents.total_volume == 0) return var/amount_full = 0 var/vol_part = min(reagents.total_volume, 30) if(text2num(many)) amount_full = round(reagents.total_volume / 30) vol_part = reagents.total_volume % 30 var/name = stripped_input(usr, "Name:","Name your hypovial!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN) if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr))) return var/obj/item/reagent_containers/glass/bottle/vial/small/P for(var/i = 0; i < amount_full; i++) P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location()) P.name = trim("[name] hypovial") adjust_item_drop_location(P) reagents.trans_to(P, 30) if(vol_part) P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location()) P.name = trim("[name] hypovial") adjust_item_drop_location(P) reagents.trans_to(P, vol_part) . = TRUE //END CITADEL ADDITIONS if("analyze") var/datum/reagent/R = GLOB.chemical_reagents_list[params["id"]] if(R) var/state = "Unknown" if(initial(R.reagent_state) == 1) state = "Solid" else if(initial(R.reagent_state) == 2) state = "Liquid" else if(initial(R.reagent_state) == 3) state = "Gas" var/const/P = 3 //The number of seconds between life ticks var/T = initial(R.metabolization_rate) * (60 / P) analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold)) screen = "analyze" return if("goScreen") screen = params["screen"] . = TRUE /obj/machinery/chem_master/proc/end_fermi_reaction()//Ends any reactions upon moving. if(beaker.reagents.fermiIsReacting) beaker.reagents.fermiEnd() /obj/machinery/chem_master/proc/isgoodnumber(num) if(isnum(num)) if(num > 200) num = 200 else if(num < 0) num = 0 else num = round(num) return num else return 0 /obj/machinery/chem_master/adjust_item_drop_location(atom/movable/AM) // Special version for chemmasters and condimasters if (AM == beaker) AM.pixel_x = -8 AM.pixel_y = 8 return null else if (AM == bottle) if (length(bottle.contents)) AM.pixel_x = -13 else AM.pixel_x = -7 AM.pixel_y = -8 return null else var/md5 = md5(AM.name) for (var/i in 1 to 32) . += hex2num(md5[i]) . = . % 9 AM.pixel_x = ((.%3)*6) AM.pixel_y = -8 + (round( . / 3)*8) /obj/machinery/chem_master/condimaster name = "CondiMaster 3000" desc = "Used to create condiments and other cooking supplies." condi = TRUE #undef PILL_STYLE_COUNT #undef RANDOM_PILL_STYLE