/obj/machinery/chemical_dispenser name = "chemical dispenser" desc = "Automagically fabricates chemicals from electricity." icon = 'icons/obj/chemical.dmi' icon_state = "dispenser" clicksound = "switch" var/list/spawn_cartridges = null // Set to a list of types to spawn one of each on New() var/list/cartridges = list() // Associative, label -> cartridge var/obj/item/weapon/reagent_containers/container = null var/ui_title = "Chemical Dispenser" var/accept_drinking = 0 var/amount = 30 use_power = USE_POWER_IDLE idle_power_usage = 100 anchored = 1 /obj/machinery/chemical_dispenser/Initialize() . = ..() if(spawn_cartridges) for(var/type in spawn_cartridges) add_cartridge(new type(src)) /obj/machinery/chemical_dispenser/examine(mob/user) . = ..() . += "It has [cartridges.len] cartridges installed, and has space for [DISPENSER_MAX_CARTRIDGES - cartridges.len] more." /obj/machinery/chemical_dispenser/verb/rotate_clockwise() set name = "Rotate Dispenser Clockwise" set category = "Object" set src in oview(1) if (src.anchored || usr:stat) to_chat(usr, "It is fastened down!") return 0 src.set_dir(turn(src.dir, 270)) return 1 /obj/machinery/chemical_dispenser/proc/add_cartridge(obj/item/weapon/reagent_containers/chem_disp_cartridge/C, mob/user) if(!istype(C)) if(user) to_chat(user, "\The [C] will not fit in \the [src]!") return if(cartridges.len >= DISPENSER_MAX_CARTRIDGES) if(user) to_chat(user, "\The [src] does not have any slots open for \the [C] to fit into!") return if(!C.label) if(user) to_chat(user, "\The [C] does not have a label!") return if(cartridges[C.label]) if(user) to_chat(user, "\The [src] already contains a cartridge with that label!") return if(user) user.drop_from_inventory(C) to_chat(user, "You add \the [C] to \the [src].") C.loc = src cartridges[C.label] = C cartridges = sortAssoc(cartridges) SStgui.update_uis(src) /obj/machinery/chemical_dispenser/proc/remove_cartridge(label) . = cartridges[label] cartridges -= label SStgui.update_uis(src) /obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user) if(W.is_wrench()) playsound(src, W.usesound, 50, 1) to_chat(user, "You begin to [anchored ? "un" : ""]fasten \the [src].") if (do_after(user, 20 * W.toolspeed)) user.visible_message( "\The [user] [anchored ? "un" : ""]fastens \the [src].", "You have [anchored ? "un" : ""]fastened \the [src].", "You hear a ratchet.") anchored = !anchored else to_chat(user, "You decide not to [anchored ? "un" : ""]fasten \the [src].") else if(istype(W, /obj/item/weapon/reagent_containers/chem_disp_cartridge)) add_cartridge(W, user) else if(W.is_screwdriver()) var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges if(!label) return var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = remove_cartridge(label) if(C) to_chat(user, "You remove \the [C] from \the [src].") C.loc = loc playsound(src, W.usesound, 50, 1) else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food)) if(container) to_chat(user, "There is already \a [container] on \the [src]!") return var/obj/item/weapon/reagent_containers/RC = W if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food)) to_chat(user, "This machine only accepts beakers!") return if(!RC.is_open_container()) to_chat(user, "You don't see how \the [src] could dispense reagents into \the [RC].") return container = RC user.drop_from_inventory(RC) RC.loc = src to_chat(user, "You set \the [RC] on \the [src].") else return ..() /obj/machinery/chemical_dispenser/tgui_interact(mob/user, datum/tgui/ui = null) ui = SStgui.try_update_ui(user, src, ui) if(!ui) ui = new(user, src, "ChemDispenser", ui_title) // 390, 655 ui.open() /obj/machinery/chemical_dispenser/tgui_data(mob/user) var/data[0] data["amount"] = amount data["isBeakerLoaded"] = container ? 1 : 0 data["glass"] = accept_drinking var/beakerContents[0] if(container && container.reagents && container.reagents.reagent_list.len) for(var/datum/reagent/R in container.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 if(container) data["beakerCurrentVolume"] = container.reagents.total_volume data["beakerMaxVolume"] = container.reagents.maximum_volume else data["beakerCurrentVolume"] = null data["beakerMaxVolume"] = null var/chemicals[0] for(var/label in cartridges) var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list... data["chemicals"] = chemicals return data /obj/machinery/chemical_dispenser/tgui_act(action, params) if(..()) return TRUE . = TRUE switch(action) if("amount") amount = clamp(round(text2num(params["amount"]), 1), 0, 120) // round to nearest 1 and clamp 0 - 120 if("dispense") var/label = params["reagent"] if(cartridges[label] && container && container.is_open_container()) var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1) C.reagents.trans_to(container, amount) if("remove") var/amount = text2num(params["amount"]) if(!container || !amount) return var/datum/reagents/R = container.reagents var/id = params["reagent"] if(amount > 0) R.remove_reagent(id, amount) else if(amount == -1) // Isolate R.isolate_reagent(id) if("ejectBeaker") if(container) container.forceMove(get_turf(src)) if(Adjacent(usr)) // So the AI doesn't get a beaker somehow. usr.put_in_hands(container) container = null else return FALSE add_fingerprint(usr) /obj/machinery/chemical_dispenser/attack_ghost(mob/user) if(stat & BROKEN) return tgui_interact(user) /obj/machinery/chemical_dispenser/attack_ai(mob/user) attack_hand(user) /obj/machinery/chemical_dispenser/attack_hand(mob/user) if(stat & BROKEN) return tgui_interact(user)