diff --git a/code/_globalvars/lists/reagents.dm b/code/_globalvars/lists/reagents.dm
index 68d63d97934..47b1008aa8a 100644
--- a/code/_globalvars/lists/reagents.dm
+++ b/code/_globalvars/lists/reagents.dm
@@ -63,8 +63,6 @@ GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list(
/turf/closed/indestructible, //indestructible turfs should be indestructible, metalgen transmutation to plasma allows them to be destroyed
/turf/open/indestructible
)))
-/// Names of human readable reagents used by plumbing UI.
-GLOBAL_LIST_INIT(chemical_name_list, init_chemical_name_list())
/// Map of reagent names to its datum path
GLOBAL_LIST_INIT(name2reagent, build_name2reagentlist())
@@ -81,16 +79,6 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagentlist())
return reagent_list
-/// Creates an list which is indexed by reagent name . used by plumbing reaction chamber and chemical filter UI
-/proc/init_chemical_name_list()
- var/list/name_list = list()
-
- for(var/X in GLOB.chemical_reagents_list)
- var/datum/reagent/Reagent = GLOB.chemical_reagents_list[X]
- name_list += Reagent.name
-
- return sort_list(name_list)
-
/**
* Chemical Reactions - Initialises all /datum/chemical_reaction into a list
* It is filtered into multiple lists within a list.
@@ -196,7 +184,19 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagentlist())
/// Builds map of reagent name to its datum path
/proc/build_name2reagentlist()
. = list()
- for (var/datum/reagent/R as anything in subtypesof(/datum/reagent))
- var/name = initial(R.name)
+
+ //build map with keys stored seperatly
+ var/list/name_to_reagent = list()
+ var/list/only_names = list()
+ for (var/datum/reagent/reagent as anything in GLOB.chemical_reagents_list)
+ var/name = initial(reagent.name)
if (length(name))
- .[ckey(name)] = R
+ name_to_reagent[name] = reagent
+ only_names += name
+
+ //sort keys
+ only_names = sort_list(only_names)
+
+ //build map with sorted keys
+ for(var/name as anything in only_names)
+ .[name] = name_to_reagent[name]
diff --git a/code/game/objects/items/devices/portable_chem_mixer.dm b/code/game/objects/items/devices/portable_chem_mixer.dm
index 18458f75697..c48e9fe8f1e 100644
--- a/code/game/objects/items/devices/portable_chem_mixer.dm
+++ b/code/game/objects/items/devices/portable_chem_mixer.dm
@@ -4,19 +4,18 @@
icon = 'icons/obj/medical/chemical.dmi'
icon_state = "portablechemicalmixer_open"
worn_icon_state = "portable_chem_mixer"
+ equip_sound = 'sound/items/equip/toolbelt_equip.ogg'
w_class = WEIGHT_CLASS_HUGE
slot_flags = ITEM_SLOT_BELT
- equip_sound = 'sound/items/equip/toolbelt_equip.ogg'
custom_price = PAYCHECK_CREW * 10
custom_premium_price = PAYCHECK_CREW * 14
- var/obj/item/reagent_containers/beaker = null ///Creating an empty slot for a beaker that can be added to dispense into
- var/amount = 30 ///The amount of reagent that is to be dispensed currently
-
- var/list/dispensable_reagents = list() ///List in which all currently dispensable reagents go
-
- ///If the UI has the pH meter shown
- var/show_ph = TRUE
+ ///Creating an empty slot for a beaker that can be added to dispense into
+ var/obj/item/reagent_containers/beaker = null
+ ///The amount of reagent that is to be dispensed currently
+ var/amount = 30
+ ///List in which all currently dispensable reagents go
+ var/list/dispensable_reagents = list()
/obj/item/storage/portable_chem_mixer/Initialize(mapload)
. = ..()
@@ -29,45 +28,56 @@
/obj/item/reagent_containers/cup/glass/waterbottle,
/obj/item/reagent_containers/condiment,
))
+ register_context()
/obj/item/storage/portable_chem_mixer/Destroy()
QDEL_NULL(beaker)
return ..()
+/obj/item/storage/portable_chem_mixer/add_context(atom/source, list/context, obj/item/held_item, mob/user)
+ . = ..()
+
+ context[SCREENTIP_CONTEXT_CTRL_LMB] = "[atom_storage.locked ? "Un" : ""]Lock storage"
+ if(atom_storage.locked && !QDELETED(beaker))
+ context[SCREENTIP_CONTEXT_ALT_LMB] = "Eject beaker"
+
+ if(!isnull(held_item))
+ if (!atom_storage.locked || \
+ (held_item.item_flags & ABSTRACT) || \
+ !is_reagent_container(held_item) || \
+ !held_item.is_open_container() \
+ )
+ return CONTEXTUAL_SCREENTIP_SET
+ context[SCREENTIP_CONTEXT_LMB] = "Insert beaker"
+
+ return CONTEXTUAL_SCREENTIP_SET
+
+/obj/item/storage/portable_chem_mixer/examine(mob/user)
+ . = ..()
+ if(!atom_storage.locked)
+ . += span_notice("Use [EXAMINE_HINT("ctrl click")] to lock in order to use its interface.")
+ else
+ . += span_notice("Its storage is locked, use [EXAMINE_HINT("ctrl click")] to unlock it.")
+ if(QDELETED(beaker))
+ . += span_notice("A beaker can be inserted to dispense reagents after it is locked.")
+ else
+ . += span_notice("A beaker of [beaker.reagents.maximum_volume] units capacity is inserted.")
+ . += span_notice("It can be ejected with [EXAMINE_HINT("alt click")].")
+
/obj/item/storage/portable_chem_mixer/ex_act(severity, target)
- if(severity > EXPLODE_LIGHT)
+ return severity > EXPLODE_LIGHT ? ..() : FALSE
+
+/obj/item/storage/portable_chem_mixer/attackby(obj/item/weapon, mob/user, params)
+ if (!atom_storage.locked || \
+ (weapon.item_flags & ABSTRACT) || \
+ !is_reagent_container(weapon) || \
+ !weapon.is_open_container() \
+ )
return ..()
- return FALSE
-
-/obj/item/storage/portable_chem_mixer/attackby(obj/item/I, mob/user, params)
- if (is_reagent_container(I) && !(I.item_flags & ABSTRACT) && I.is_open_container() && atom_storage.locked)
- var/obj/item/reagent_containers/B = I
- . = TRUE //no afterattack
- if(!user.transferItemToLoc(B, src))
- return
- replace_beaker(user, B)
- update_appearance()
- ui_interact(user)
- return
- return ..()
-
-/**
- * Updates the contents of the portable chemical mixer
- *
- * A list of dispensable reagents is created by iterating through each source beaker in the portable chemical beaker and reading its contents
- */
-/obj/item/storage/portable_chem_mixer/proc/update_contents()
- dispensable_reagents.Cut()
-
- for (var/obj/item/reagent_containers/B in contents)
- var/key = B.reagents.get_master_reagent_id()
- if (!(key in dispensable_reagents))
- dispensable_reagents[key] = list()
- dispensable_reagents[key]["reagents"] = list()
- dispensable_reagents[key]["reagents"] += B.reagents
-
- return
+ replace_beaker(user, weapon)
+ update_appearance()
+ return TRUE
/obj/item/storage/portable_chem_mixer/update_icon_state()
if(!atom_storage.locked)
@@ -79,28 +89,48 @@
icon_state = "portablechemicalmixer_empty"
return ..()
-
/obj/item/storage/portable_chem_mixer/AltClick(mob/living/user)
if(!atom_storage.locked)
+ balloon_alert(user, "lock first to use alt eject!")
return ..()
if(!can_interact(user) || !user.can_perform_action(src, FORBID_TELEKINESIS_REACH))
return
+
replace_beaker(user)
update_appearance()
/obj/item/storage/portable_chem_mixer/CtrlClick(mob/living/user)
- if(atom_storage.locked)
+ if(atom_storage.locked == STORAGE_FULLY_LOCKED)
atom_storage.locked = STORAGE_NOT_LOCKED
+ replace_beaker(user)
+ SStgui.close_all_uis()
else
atom_storage.locked = STORAGE_FULLY_LOCKED
- if (!atom_storage.locked)
- update_contents()
- if (atom_storage.locked)
atom_storage.hide_contents(usr)
- replace_beaker(user)
+
update_appearance()
- playsound(src, 'sound/items/screwdriver2.ogg', 50)
- return
+
+/obj/item/storage/portable_chem_mixer/Exited(atom/movable/gone, direction)
+ . = ..()
+ if(gone == beaker)
+ beaker = null
+ else
+ update_contents()
+
+/// Reload dispensable reagents from new contents
+/obj/item/storage/portable_chem_mixer/proc/update_contents()
+ dispensable_reagents.Cut()
+ for (var/obj/item/reagent_containers/container in contents)
+ var/key = container.reagents.get_master_reagent_id()
+ if (!(key in dispensable_reagents))
+ dispensable_reagents[key] = list()
+ dispensable_reagents[key]["reagents"] = list()
+ dispensable_reagents[key]["reagents"] += container.reagents
+
+/obj/item/storage/portable_chem_mixer/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs)
+ . = ..()
+ if(!atom_storage.locked)
+ update_contents()
/**
* Replaces the beaker of the portable chemical mixer with another beaker, or simply adds the new beaker if none is in currently
@@ -111,34 +141,12 @@
* * obj/item/reagent_containers/new_beaker - The new beaker that the user wants to put into the device
*/
/obj/item/storage/portable_chem_mixer/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
- if(!user)
- return FALSE
if(beaker)
user.put_in_hands(beaker)
- beaker = null
if(new_beaker)
+ if(!user.transferItemToLoc(new_beaker, src))
+ return
beaker = new_beaker
- return TRUE
-
-/obj/item/storage/portable_chem_mixer/attack_hand(mob/user, list/modifiers)
- if (loc != user)
- return ..()
- else
- if (!atom_storage.locked)
- return ..()
- if(atom_storage?.locked)
- ui_interact(user)
- return
-
-/obj/item/storage/portable_chem_mixer/attack_self(mob/user)
- if(loc == user)
- if (atom_storage.locked)
- ui_interact(user)
- return
- else
- to_chat(user, span_notice("It looks like this device can be worn as a belt for increased accessibility. A label indicates that the 'CTRL'-button on the device may be used to close it after it has been filled with bottles and beakers of chemicals."))
- return
- return
/obj/item/storage/portable_chem_mixer/MouseDrop(obj/over_object)
. = ..()
@@ -149,30 +157,29 @@
M.putItemFromInventoryInHandIfPossible(src, H.held_index)
/obj/item/storage/portable_chem_mixer/ui_interact(mob/user, datum/tgui/ui)
+ if(loc != user)
+ balloon_alert(user, "hold it in your hand!")
+ return
+ if(!atom_storage.locked)
+ balloon_alert(user, "lock it first!")
+ return
+
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "PortableChemMixer", name)
-
- var/is_hallucinating = FALSE
- if(isliving(user))
- var/mob/living/living_user = user
- is_hallucinating = !!living_user.has_status_effect(/datum/status_effect/hallucination)
-
- if(is_hallucinating)
- // to not ruin the immersion by constantly changing the fake chemicals
- ui.set_autoupdate(FALSE)
-
ui.open()
+ var/is_hallucinating = FALSE
+ if(isliving(user))
+ var/mob/living/living_user = user
+ is_hallucinating = !!living_user.has_status_effect(/datum/status_effect/hallucination)
+ ui.set_autoupdate(!is_hallucinating) // to not ruin the immersion by constantly changing the fake chemicals
+
/obj/item/storage/portable_chem_mixer/ui_data(mob/user)
- var/list/data = list()
- data["amount"] = amount
- data["isBeakerLoaded"] = beaker ? 1 : 0
- data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null
- data["beakerMaxVolume"] = beaker ? beaker.volume : null
- data["beakerTransferAmounts"] = beaker ? list(1,5,10,30,50,100) : null
- data["showpH"] = show_ph
- var/chemicals[0]
+ . = list()
+ .["amount"] = amount
+
+ var/list/chemicals = list()
var/is_hallucinating = FALSE
if(isliving(user))
var/mob/living/living_user = user
@@ -190,46 +197,54 @@
total_ph = rs.ph
if(is_hallucinating && prob(5))
chemname = "[pick_list_replacements("hallucination.json", "chemicals")]"
- chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name), "volume" = total_volume, "pH" = total_ph)))
- data["chemicals"] = chemicals
- var/beakerContents[0]
- if(beaker)
- for(var/datum/reagent/R in beaker.reagents.reagent_list)
- beakerContents.Add(list(list("name" = R.name, "id" = ckey(R.name), "volume" = R.volume, "pH" = R.ph))) // list in a list because Byond merges the first list...
- data["beakerCurrentpH"] = round(beaker.reagents.ph, 0.01)
- data["beakerContents"] = beakerContents
+ chemicals += list(list("title" = chemname, "id" = temp.name, "volume" = total_volume, "pH" = total_ph))
+ .["chemicals"] = chemicals
- return data
+ var/list/beaker_data = null
+ if(!QDELETED(beaker))
+ beaker_data = list()
+ beaker_data["maxVolume"] = beaker.volume
+ beaker_data["transferAmounts"] = beaker.possible_transfer_amounts
+ beaker_data["pH"] = round(beaker.reagents.ph, 0.01)
+ beaker_data["currentVolume"] = round(beaker.reagents.total_volume, 0.01)
+ var/list/beakerContents = list()
+ if(length(beaker?.reagents.reagent_list))
+ for(var/datum/reagent/reagent in beaker.reagents.reagent_list)
+ beakerContents += list(list("name" = reagent.name, "volume" = round(reagent.volume, 0.01))) // list in a list because Byond merges the first list...
+ beaker_data["contents"] = beakerContents
+ .["beaker"] = beaker_data
-/obj/item/storage/portable_chem_mixer/ui_act(action, params)
+/obj/item/storage/portable_chem_mixer/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
+
switch(action)
if("amount")
- var/target = text2num(params["target"])
- amount = target
- . = TRUE
+ amount = text2num(params["target"])
+ return TRUE
+
if("dispense")
- var/reagent_name = params["reagent"]
- var/datum/reagent/reagent = GLOB.name2reagent[reagent_name]
- var/entry = dispensable_reagents[reagent]
- if(beaker && beaker.loc == src)
- var/datum/reagents/R = beaker.reagents
- var/actual = min(amount, 1000, R.maximum_volume - R.total_volume)
- // todo: add check if we have enough reagent left
- for (var/datum/reagents/source in entry["reagents"])
+ var/datum/reagent/reagent = GLOB.name2reagent[params["reagent"]]
+ if(isnull(reagent))
+ return
+
+ if(!QDELETED(beaker))
+ var/datum/reagents/container = beaker.reagents
+ var/actual = min(amount, 1000, container.maximum_volume - container.total_volume)
+ for (var/datum/reagents/source in dispensable_reagents[reagent]["reagents"])
var/to_transfer = min(source.total_volume, actual)
- source.trans_to(beaker, to_transfer)
+ source.trans_to(beaker, to_transfer, transferred_by = ui.user)
actual -= to_transfer
if (actual <= 0)
break
- . = TRUE
+ return TRUE
+
if("remove")
- var/amount = text2num(params["amount"])
- beaker.reagents.remove_all(amount)
- . = TRUE
+ beaker.reagents.remove_all(text2num(params["amount"]))
+ return TRUE
+
if("eject")
- replace_beaker(usr)
+ replace_beaker(ui.user)
update_appearance()
- . = TRUE
+ return TRUE
diff --git a/code/modules/plumbing/plumbers/filter.dm b/code/modules/plumbing/plumbers/filter.dm
index 4e4a282bd1d..633f70830f0 100644
--- a/code/modules/plumbing/plumbers/filter.dm
+++ b/code/modules/plumbing/plumbers/filter.dm
@@ -38,11 +38,12 @@
switch(action)
if("add")
var/which = params["which"]
- var/selected_reagent = tgui_input_list(usr, "Select [which] reagent", "Reagent", GLOB.chemical_name_list)
+
+ var/selected_reagent = tgui_input_list(usr, "Select [which] reagent", "Reagent", GLOB.name2reagent)
if(!selected_reagent)
return TRUE
- var/chem_id = get_chem_id(selected_reagent)
+ var/datum/reagent/chem_id = GLOB.name2reagent[selected_reagent]
if(!chem_id)
return TRUE
diff --git a/code/modules/plumbing/plumbers/reaction_chamber.dm b/code/modules/plumbing/plumbers/reaction_chamber.dm
index 01a6b4a0b82..be7724ac554 100644
--- a/code/modules/plumbing/plumbers/reaction_chamber.dm
+++ b/code/modules/plumbing/plumbers/reaction_chamber.dm
@@ -4,7 +4,7 @@
#define HEATER_COEFFICIENT 0.05
/// maximum number of attempts the reaction chamber will make to balance the ph(More means better results but higher tick usage)
-#define MAX_PH_ADJUSTMENTS 5
+#define MAX_PH_ADJUSTMENTS 3
/obj/machinery/plumbing/reaction_chamber
name = "mixing chamber"
@@ -107,13 +107,13 @@
switch(action)
if("add")
- var/selected_reagent = tgui_input_list(ui.user, "Select reagent", "Reagent", GLOB.chemical_name_list)
+ var/selected_reagent = tgui_input_list(ui.user, "Select reagent", "Reagent", GLOB.name2reagent)
if(!selected_reagent)
- return TRUE
+ return FALSE
- var/input_reagent = get_chem_id(selected_reagent)
+ var/datum/reagent/input_reagent = GLOB.name2reagent[selected_reagent]
if(!input_reagent)
- return TRUE
+ return FALSE
if(!required_reagents.Find(input_reagent))
var/input_amount = text2num(params["amount"])
@@ -194,13 +194,15 @@
return
//transfer buffer and handle reactions
- var/ph_change = (reagents.ph > alkaline_limit ? (reagents.ph - alkaline_limit) : (acidic_limit - reagents.ph))
- var/buffer_amount = ((ph_change * reagents.total_volume) / (BUFFER_IONIZING_STRENGTH * num_of_reagents))
- if(!buffer.trans_to(reagents, buffer_amount * seconds_per_tick))
+ var/ph_change = max((reagents.ph > alkaline_limit ? (reagents.ph - alkaline_limit) : (acidic_limit - reagents.ph)), 0.25)
+ if(ph_change <= 0.7) //make big jumps towards the end so we can end our work quickly
+ ph_change *= 2
+ var/buffer_amount = ((ph_change * reagents.total_volume) / (BUFFER_IONIZING_STRENGTH * num_of_reagents)) * seconds_per_tick
+ if(!buffer.trans_to(reagents, buffer_amount))
return
//some power for accurate ph balancing & keep track of attempts made
- use_power(active_power_usage * 0.03 * buffer_amount * seconds_per_tick)
+ use_power(active_power_usage * 0.03 * buffer_amount)
ph_balance_attempts += 1
/obj/machinery/plumbing/reaction_chamber/chem/ui_interact(mob/user, datum/tgui/ui)
diff --git a/code/modules/plumbing/plumbers/synthesizer.dm b/code/modules/plumbing/plumbers/synthesizer.dm
index 3dddd648e61..0e9cb0c1b11 100644
--- a/code/modules/plumbing/plumbers/synthesizer.dm
+++ b/code/modules/plumbing/plumbers/synthesizer.dm
@@ -2,7 +2,6 @@
/obj/machinery/plumbing/synthesizer
name = "chemical synthesizer"
desc = "Produces a single chemical at a given volume. Must be plumbed. Most effective when working in unison with other chemical synthesizers, heaters and filters."
-
icon_state = "synthesizer"
icon = 'icons/obj/pipes_n_cables/hydrochem/plumbers.dmi'
active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2
@@ -52,10 +51,13 @@
/obj/machinery/plumbing/synthesizer/process(seconds_per_tick)
if(machine_stat & NOPOWER || !reagent_id || !amount)
return
- if(reagents.total_volume >= amount*seconds_per_tick*0.5) //otherwise we get leftovers, and we need this to be precise
+
+ //otherwise we get leftovers, and we need this to be precise
+ if(reagents.total_volume >= amount)
return
- reagents.add_reagent(reagent_id, amount*seconds_per_tick*0.5)
- use_power(active_power_usage * amount * seconds_per_tick * 0.5)
+ reagents.add_reagent(reagent_id, amount)
+
+ use_power(active_power_usage)
/obj/machinery/plumbing/synthesizer/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
@@ -63,8 +65,13 @@
ui = new(user, src, "ChemSynthesizer", name)
ui.open()
+/obj/machinery/plumbing/synthesizer/ui_static_data(mob/user)
+ . = ..()
+ .["possible_amounts"] = possible_amounts
+
/obj/machinery/plumbing/synthesizer/ui_data(mob/user)
- var/list/data = list()
+ . = list()
+ .["amount"] = amount
var/is_hallucinating = FALSE
if(isliving(user))
@@ -72,36 +79,35 @@
is_hallucinating = !!living_user.has_status_effect(/datum/status_effect/hallucination)
var/list/chemicals = list()
- for(var/A in dispensable_reagents)
- var/datum/reagent/R = GLOB.chemical_reagents_list[A]
- if(R)
- var/chemname = R.name
+ for(var/reagentID in dispensable_reagents)
+ var/datum/reagent/reagent = GLOB.chemical_reagents_list[reagentID]
+ if(reagent)
+ var/chemname = reagent.name
if(is_hallucinating && prob(5))
chemname = "[pick_list_replacements("hallucination.json", "chemicals")]"
- chemicals.Add(list(list("title" = chemname, "id" = ckey(R.name))))
- data["chemicals"] = chemicals
- data["amount"] = amount
- data["possible_amounts"] = possible_amounts
+ chemicals += list(list("title" = chemname, "id" = reagent.name))
+ .["chemicals"] = chemicals
- data["current_reagent"] = ckey(initial(reagent_id.name))
- return data
+ .["current_reagent"] = initial(reagent_id.name)
/obj/machinery/plumbing/synthesizer/ui_act(action, params)
. = ..()
if(.)
return
- . = TRUE
+
switch(action)
if("amount")
var/new_amount = text2num(params["target"])
if(new_amount in possible_amounts)
amount = new_amount
. = TRUE
+
if("select")
var/new_reagent = GLOB.name2reagent[params["reagent"]]
if(new_reagent in dispensable_reagents)
reagent_id = new_reagent
. = TRUE
+
update_appearance()
reagents.clear_reagents()
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index a3ed883551f..b677a8c02c9 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -1,16 +1,3 @@
-/proc/translate_legacy_chem_id(id)
- switch (id)
- if ("sacid")
- return "sulfuricacid"
- if ("facid")
- return "fluorosulfuricacid"
- if ("co2")
- return "carbondioxide"
- if ("mine_salve")
- return "minerssalve"
- else
- return ckey(id)
-
/obj/machinery/chem_dispenser
name = "chem dispenser"
desc = "Creates and dispenses chemicals."
@@ -23,21 +10,57 @@
circuit = /obj/item/circuitboard/machine/chem_dispenser
processing_flags = NONE
+ /// The cell used to dispense reagents
var/obj/item/stock_parts/cell/cell
+ /// Efficiency used when converting cell power to reagents
var/powerefficiency = 0.1
+ /// The current amount this machine is dispensing
var/amount = 30
+ /// The rate at which this machine recharges the power cell
var/recharge_amount = 10
+ /// Keep track of the intervals made during recharges
var/recharge_counter = 0
+ /// The temperature reagents are dispensed into the beaker
var/dispensed_temperature = DEFAULT_REAGENT_TEMPERATURE
- ///If the UI has the pH meter shown
+ /// If the UI has the pH meter shown
var/show_ph = TRUE
+ /// The overlay used to display the beaker on the machine
var/mutable_appearance/beaker_overlay
+ /// Icon to display when the machine is powered
var/working_state = "dispenser_working"
+ /// Icon to display when the machine is not powered
var/nopower_state = "dispenser_nopower"
+ /// Should we display the open panel overlay when the panel is opened with a screwdriver
var/has_panel_overlay = TRUE
+ /// The actual beaker inserted into this machine
var/obj/item/reagent_containers/beaker = null
- //dispensable_reagents is copypasted in plumbing synthesizers. Please update accordingly. (I didn't make it global because that would limit custom chem dispensers)
- var/list/dispensable_reagents = list(
+ /// Dispensable_reagents is copypasted in plumbing synthesizers. Please update accordingly. (I didn't make it global because that would limit custom chem dispensers)
+ var/list/dispensable_reagents = list()
+ /// These become available once the manipulator has been upgraded to tier 2 (nano) // SKYRAT EDIT CHANGE - ORIGINAL: /// These become available once the manipulator has been upgraded to tier 4 (femto)
+ var/list/upgrade_reagents = list()
+ // SKYRAT EDIT ADDITION BEGIN
+ /// These become available once the manipulator has been upgraded to tier 3 (pico)
+ var/list/upgrade2_reagents = list()
+ /// These become available once the manipulator has been upgraded to tier 4 (femto)
+ var/list/upgrade3_reagents = list()
+ // SKYRAT EDIT ADDITION END
+ /// These become available once the machine has been emaged
+ var/list/emagged_reagents = list()
+ /// Starting purity of the created reagents
+ var/base_reagent_purity = 1
+ /// Records the reagents dispensed by the user if this list is not null
+ var/list/recording_recipe
+ /// Saves all the recipes recorded by the machine
+ var/list/saved_recipes = list()
+ // SKYRAT EDIT ADDITION BEGIN
+ /// Used for custom transfer amounts
+ var/list/transferAmounts = list()
+ /// The custom transfer amount
+ var/customTransferAmount
+ // SKYRAT EDIT ADDITION END
+
+ /// The default list of dispensable_reagents
+ var/static/list/default_dispensable_reagents = list(
/datum/reagent/aluminium,
/datum/reagent/bromine,
/datum/reagent/carbon,
@@ -64,10 +87,11 @@
/datum/reagent/water,
/datum/reagent/fuel,
)
- //these become available once the manipulator has been upgraded to tier 4 (femto)
- //SKYRAT EDIT REMOVAL BEGIN - Skyrat-SS13/Skyrat-tg#1931
+
+ //SKYRAT EDIT CHANGE BEGIN - ORIGINAL
/*
- var/list/upgrade_reagents = list(
+ /// The default list of reagents upgrade_reagents
+ var/static/list/default_upgrade_reagents = list(
/datum/reagent/acetone,
/datum/reagent/ammonia,
/datum/reagent/ash,
@@ -75,7 +99,8 @@
/datum/reagent/fuel/oil,
/datum/reagent/saltpetre
)
- var/list/emagged_reagents = list(
+ /// The default list of reagents emagged_reagents
+ var/static/list/default_emagged_reagents = list(
/datum/reagent/toxin/carpotoxin,
/datum/reagent/medicine/mine_salve,
/datum/reagent/medicine/morphine,
@@ -83,26 +108,24 @@
/datum/reagent/toxin
)
*/
- //SKYRAT EDIT REMOVAL END
- //SKYRAT EDIT ADDITION BEGIN - Skyrat-SS13/Skyrat-tg#1931
- var/list/upgrade_reagents = list(
+ var/static/list/default_upgrade_reagents = list(
/datum/reagent/fuel/oil,
/datum/reagent/ammonia,
/datum/reagent/ash
)
- var/list/upgrade_reagents2 = list(
+ var/static/list/default_upgrade2_reagents = list(
/datum/reagent/acetone,
/datum/reagent/phenol,
/datum/reagent/diethylamine
)
- var/list/upgrade_reagents3 = list(
+ var/static/list/default_upgrade3_reagents = list(
/datum/reagent/medicine/mine_salve,
/datum/reagent/toxin
)
- var/list/emagged_reagents = list(
+ var/static/list/default_emagged_reagents = list(
/datum/reagent/drug/space_drugs,
/datum/reagent/toxin/plasma,
/datum/reagent/consumable/frostoil,
@@ -110,38 +133,42 @@
/datum/reagent/toxin/histamine,
/datum/reagent/medicine/morphine
)
- //SKYRAT EDIT ADDITION END
- /// Starting purity of the created reagents
- var/base_reagent_purity = 1
-
- var/list/recording_recipe
-
- var/list/saved_recipes = list()
- //SKYRAT EDIT BEGIN - CHEMISTRY QOL
- var/list/transferAmounts = list()
- var/customTransferAmount
- //SKYRAT EDIT END
+ //SKYRAT EDIT CHANGE END
/obj/machinery/chem_dispenser/Initialize(mapload)
. = ..()
- dispensable_reagents = sort_list(dispensable_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
- if(emagged_reagents)
- emagged_reagents = sort_list(emagged_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
+ if(dispensable_reagents != null && !dispensable_reagents.len)
+ dispensable_reagents = default_dispensable_reagents
+ if(dispensable_reagents)
+ dispensable_reagents = sort_list(dispensable_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
+
+ if(upgrade_reagents != null && !upgrade_reagents.len)
+ upgrade_reagents = default_upgrade_reagents
if(upgrade_reagents)
upgrade_reagents = sort_list(upgrade_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
- //SKYRAT EDIT ADDITION BEGIN - Skyrat-SS13/Skyrat-tg#1931
- if(upgrade_reagents2)
- upgrade_reagents2 = sort_list(upgrade_reagents2, GLOBAL_PROC_REF(cmp_reagents_asc))
- if(upgrade_reagents3)
- upgrade_reagents3 = sort_list(upgrade_reagents3, GLOBAL_PROC_REF(cmp_reagents_asc))
+ //SKYRAT EDIT ADDITION BEGIN
+ if(upgrade2_reagents != null && !upgrade2_reagents.len)
+ upgrade2_reagents = default_upgrade2_reagents
+ if(upgrade2_reagents)
+ upgrade2_reagents = sort_list(upgrade2_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
+ if(upgrade3_reagents != null && !upgrade3_reagents.len)
+ upgrade3_reagents = default_upgrade3_reagents
+ if(upgrade3_reagents)
+ upgrade3_reagents = sort_list(upgrade3_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
//SKYRAT EDIT ADDITION END
+
+ if(emagged_reagents != null && !emagged_reagents.len)
+ emagged_reagents = default_emagged_reagents
+ if(emagged_reagents)
+ emagged_reagents = sort_list(emagged_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
+
if(is_operational)
begin_processing()
update_appearance()
/obj/machinery/chem_dispenser/Destroy()
+ cell = null
QDEL_NULL(beaker)
- QDEL_NULL(cell)
return ..()
/obj/machinery/chem_dispenser/examine(mob/user)
@@ -151,17 +178,15 @@
if(in_range(user, src) || isobserver(user))
. += "The status display reads:\n\
Recharging [recharge_amount] power units per interval.\n\
- Power efficiency increased by [round((powerefficiency*1000)-100, 1)]%."
+ Power efficiency increased by [round((powerefficiency * 1000) -100, 1)]%."
. += span_notice("Use RMB to eject a stored beaker.")
-
/obj/machinery/chem_dispenser/on_set_is_operational(old_value)
if(old_value) //Turned off
end_processing()
else //Turned on
begin_processing()
-
/obj/machinery/chem_dispenser/process(seconds_per_tick)
if (recharge_counter >= 8)
var/usedpower = cell.give(recharge_amount)
@@ -194,7 +219,6 @@
beaker_overlay = display_beaker()
. += beaker_overlay
-
/obj/machinery/chem_dispenser/emag_act(mob/user, obj/item/card/emag/emag_card)
if(obj_flags & EMAGGED)
balloon_alert(user, "already emagged!")
@@ -205,12 +229,10 @@
return TRUE
/obj/machinery/chem_dispenser/ex_act(severity, target)
- if(severity <= EXPLODE_LIGHT)
- return FALSE
- return ..()
+ return severity <= EXPLODE_LIGHT ? FALSE : ..()
/obj/machinery/chem_dispenser/contents_explosion(severity, target)
- ..()
+ . = ..()
if(!beaker)
return
@@ -232,45 +254,25 @@
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ChemDispenser", name)
-
- var/is_hallucinating = FALSE
- if(isliving(user))
- var/mob/living/living_user = user
- is_hallucinating = !!living_user.has_status_effect(/datum/status_effect/hallucination)
-
- if(is_hallucinating)
- ui.set_autoupdate(FALSE) //to not ruin the immersion by constantly changing the fake chemicals
-
ui.open()
+ var/is_hallucinating = FALSE
+ if(isliving(user))
+ var/mob/living/living_user = user
+ is_hallucinating = !!living_user.has_status_effect(/datum/status_effect/hallucination)
+ ui.set_autoupdate(!is_hallucinating) //to not ruin the immersion by constantly changing the fake chemicals
+
+/obj/machinery/chem_dispenser/ui_static_data(mob/user)
+ . = ..()
+ .["showpH"] = show_ph
+
/obj/machinery/chem_dispenser/ui_data(mob/user)
- var/data = list()
- data["amount"] = amount
- data["energy"] = cell.charge ? cell.charge * powerefficiency : "0" //To prevent NaN in the UI.
- data["maxEnergy"] = cell.maxcharge * powerefficiency
- data["isBeakerLoaded"] = beaker ? 1 : 0
- data["showpH"] = show_ph
+ . = list()
+ .["amount"] = amount
+ .["energy"] = cell.charge ? cell.charge * powerefficiency : 0 //To prevent NaN in the UI.
+ .["maxEnergy"] = cell.maxcharge * powerefficiency
- var/beakerContents[0]
- var/beakerCurrentVolume = 0
- if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
- for(var/datum/reagent/R in beaker.reagents.reagent_list)
- beakerContents.Add(list(list("name" = R.name, "volume" = round(R.volume, 0.01), "pH" = R.ph, "purity" = R.purity))) // list in a list because Byond merges the first list...
- beakerCurrentVolume += R.volume
- data["beakerContents"] = beakerContents
-
- if (beaker)
- data["beakerCurrentVolume"] = round(beakerCurrentVolume, 0.01)
- data["beakerMaxVolume"] = beaker.volume
- data["beakerTransferAmounts"] = beaker.possible_transfer_amounts
- data["beakerCurrentpH"] = round(beaker.reagents.ph, 0.01)
- else
- data["beakerCurrentVolume"] = null
- data["beakerMaxVolume"] = null
- data["beakerTransferAmounts"] = null
- data["beakerCurrentpH"] = null
-
- var/chemicals[0]
+ var/list/chemicals = list()
var/is_hallucinating = FALSE
if(isliving(user))
var/mob/living/living_user = user
@@ -282,23 +284,37 @@
var/chemname = temp.name
if(is_hallucinating && prob(5))
chemname = "[pick_list_replacements("hallucination.json", "chemicals")]"
- chemicals.Add(list(list("title" = chemname, "id" = ckey(temp.name), "pH" = temp.ph, "pHCol" = convert_ph_to_readable_color(temp.ph))))
- data["chemicals"] = chemicals
- data["recipes"] = saved_recipes
+ chemicals += list(list("title" = chemname, "id" = temp.name, "pH" = temp.ph, "pHCol" = convert_ph_to_readable_color(temp.ph)))
+ .["chemicals"] = chemicals
+ .["recipes"] = saved_recipes
- data["recordingRecipe"] = recording_recipe
- data["recipeReagents"] = list()
+ .["recordingRecipe"] = recording_recipe
+ .["recipeReagents"] = list()
if(beaker?.reagents.ui_reaction_id)
var/datum/chemical_reaction/reaction = get_chemical_reaction(beaker.reagents.ui_reaction_id)
for(var/_reagent in reaction.required_reagents)
var/datum/reagent/reagent = find_reagent_object_from_type(_reagent)
- data["recipeReagents"] += ckey(reagent.name)
- return data
+ .["recipeReagents"] += reagent.name
-/obj/machinery/chem_dispenser/ui_act(action, params)
+ var/list/beaker_data = null
+ if(!QDELETED(beaker))
+ beaker_data = list()
+ beaker_data["maxVolume"] = beaker.volume
+ beaker_data["transferAmounts"] = beaker.possible_transfer_amounts
+ beaker_data["pH"] = round(beaker.reagents.ph, 0.01)
+ beaker_data["currentVolume"] = round(beaker.reagents.total_volume, 0.01)
+ var/list/beakerContents = list()
+ if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
+ for(var/datum/reagent/reagent in beaker.reagents.reagent_list)
+ beakerContents += list(list("name" = reagent.name, "volume" = round(reagent.volume, 0.01))) // list in a list because Byond merges the first list...
+ beaker_data["contents"] = beakerContents
+ .["beaker"] = beaker_data
+
+/obj/machinery/chem_dispenser/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
. = ..()
if(.)
return
+
switch(action)
if("amount")
if(!is_operational || QDELETED(beaker))
@@ -307,7 +323,8 @@
if(target in beaker.possible_transfer_amounts)
amount = target
work_animation()
- . = TRUE
+ return TRUE
+
if("dispense")
if(!is_operational || QDELETED(cell))
return
@@ -318,7 +335,7 @@
var/datum/reagents/holder = beaker.reagents
var/to_dispense = max(0, min(amount, holder.maximum_volume - holder.total_volume))
- if(!cell?.use(to_dispense / powerefficiency))
+ if(!cell.use(to_dispense / powerefficiency))
say("Not enough energy to complete operation!")
return
holder.add_reagent(reagent, to_dispense, reagtemp = dispensed_temperature, added_purity = base_reagent_purity)
@@ -326,7 +343,8 @@
work_animation()
else
recording_recipe[reagent_name] += amount
- . = TRUE
+ return TRUE
+
if("remove")
if(!is_operational || recording_recipe)
return
@@ -334,10 +352,12 @@
if(beaker && (amount in beaker.possible_transfer_amounts))
beaker.reagents.remove_all(amount)
work_animation()
- . = TRUE
+ return TRUE
+
if("eject")
- replace_beaker(usr)
- . = TRUE
+ replace_beaker(ui.user)
+ return TRUE
+
if("dispense_recipe")
if(!is_operational || QDELETED(cell))
return
@@ -346,7 +366,7 @@
if(!LAZYLEN(chemicals_to_dispense))
return
for(var/key in chemicals_to_dispense)
- var/reagent = GLOB.name2reagent[translate_legacy_chem_id(key)]
+ var/reagent = GLOB.name2reagent[key]
var/dispense_amount = chemicals_to_dispense[key]
if(!dispensable_reagents.Find(reagent))
return
@@ -358,50 +378,49 @@
var/to_dispense = max(0, min(dispense_amount, holder.maximum_volume - holder.total_volume))
if(!to_dispense)
continue
- if(!cell?.use(to_dispense / powerefficiency))
+ if(!cell.use(to_dispense / powerefficiency))
say("Not enough energy to complete operation!")
return
holder.add_reagent(reagent, to_dispense, reagtemp = dispensed_temperature, added_purity = base_reagent_purity)
work_animation()
else
recording_recipe[key] += dispense_amount
- . = TRUE
+ return TRUE
+
if("clear_recipes")
- if(!is_operational)
- return
- var/yesno = tgui_alert(usr, "Clear all recipes?",, list("Yes","No"))
- if(yesno == "Yes")
+ if(is_operational && tgui_alert(ui.user, "Clear all recipes?", "Clear?", list("Yes", "No")) == "Yes")
saved_recipes = list()
- . = TRUE
+ return TRUE
+
if("record_recipe")
- if(!is_operational)
- return
- recording_recipe = list()
- . = TRUE
+ if(is_operational)
+ recording_recipe = list()
+ return TRUE
+
if("save_recording")
if(!is_operational)
return
- var/name = tgui_input_text(usr, "What do you want to name this recipe?", "Recipe Name", MAX_NAME_LEN)
- if(!usr.can_perform_action(src, ALLOW_SILICON_REACH))
+ var/name = tgui_input_text(ui.user, "What do you want to name this recipe?", "Recipe Name", MAX_NAME_LEN)
+ if(!ui.user.can_perform_action(src, ALLOW_SILICON_REACH))
return
- if(saved_recipes[name] && tgui_alert(usr, "\"[name]\" already exists, do you want to overwrite it?",, list("Yes", "No")) == "No")
+ if(saved_recipes[name] && tgui_alert(ui.user, "\"[name]\" already exists, do you want to overwrite it?",, list("Yes", "No")) == "No")
return
if(name && recording_recipe)
for(var/reagent in recording_recipe)
- var/reagent_id = GLOB.name2reagent[translate_legacy_chem_id(reagent)]
+ var/reagent_id = GLOB.name2reagent[reagent]
if(!dispensable_reagents.Find(reagent_id))
visible_message(span_warning("[src] buzzes."), span_hear("You hear a faint buzz."))
- to_chat(usr, span_warning("[src] cannot find [reagent]!"))
+ to_chat(ui.user, span_warning("[src] cannot find [reagent]!"))
playsound(src, 'sound/machines/buzz-two.ogg', 50, TRUE)
return
saved_recipes[name] = recording_recipe
recording_recipe = null
- . = TRUE
+ return TRUE
+
if("cancel_recording")
- if(!is_operational)
- return
- recording_recipe = null
- . = TRUE
+ if(is_operational)
+ recording_recipe = null
+ return TRUE
//SKYRAT EDIT ADDITION BEGIN - CHEMISTRY QOL
if("custom_amount")
if(!beaker)
@@ -411,22 +430,30 @@
transferAmounts -= customTransferAmount
customTransferAmount = clamp(input(usr, "Please enter your desired transfer amount.", "Transfer amount", 0) as num|null, 0, beaker.volume)
transferAmounts += customTransferAmount
+ return TRUE
//SKYRAT EDIT ADDITION END
+
if("reaction_lookup")
if(beaker)
- beaker.reagents.ui_interact(usr)
+ beaker.reagents.ui_interact(ui.user)
/obj/machinery/chem_dispenser/wrench_act(mob/living/user, obj/item/tool)
. = ..()
- default_unfasten_wrench(user, tool)
- return TOOL_ACT_TOOLTYPE_SUCCESS
+ if(default_unfasten_wrench(user, tool) == SUCCESSFUL_UNFASTEN)
+ return TOOL_ACT_TOOLTYPE_SUCCESS
+
+/obj/machinery/chem_dispenser/screwdriver_act(mob/living/user, obj/item/tool)
+ . = ..()
+ if(default_deconstruction_screwdriver(user, icon_state, icon_state, tool))
+ update_appearance()
+ return TOOL_ACT_TOOLTYPE_SUCCESS
+
+/obj/machinery/chem_dispenser/crowbar_act(mob/living/user, obj/item/tool)
+ . = ..()
+ if(default_deconstruction_crowbar(tool))
+ return TOOL_ACT_TOOLTYPE_SUCCESS
/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/living/user, params)
- if(default_deconstruction_screwdriver(user, icon_state, icon_state, I))
- update_appearance()
- return
- if(default_deconstruction_crowbar(I))
- return
if(is_reagent_container(I) && !(I.item_flags & ABSTRACT) && I.is_open_container())
var/obj/item/reagent_containers/B = I
//SKYRAT EDIT BEGIN - CHEMISTRY QOL
@@ -496,14 +523,14 @@
dispensable_reagents -= upgrade_reagents
if (servo.tier > 2)
- dispensable_reagents |= upgrade_reagents2
+ dispensable_reagents |= upgrade2_reagents
else
- dispensable_reagents -= upgrade_reagents2
+ dispensable_reagents -= upgrade2_reagents
if (servo.tier > 3)
- dispensable_reagents |= upgrade_reagents3
+ dispensable_reagents |= upgrade3_reagents
else
- dispensable_reagents -= upgrade_reagents3
+ dispensable_reagents -= upgrade3_reagents
//SKYRAT EDIT END
parts_rating += servo.tier
powerefficiency = round(newpowereff, 0.01)
@@ -559,7 +586,8 @@
nopower_state = null
pass_flags = PASSTABLE
show_ph = FALSE
- dispensable_reagents = list(
+ /// The default list of reagents dispensable by the soda dispenser
+ var/static/list/drinks_dispensable_reagents = list(
/datum/reagent/consumable/coffee,
/datum/reagent/consumable/space_cola,
/datum/reagent/consumable/cream,
@@ -586,24 +614,26 @@
/datum/reagent/consumable/tonic,
/datum/reagent/water,
)
- //SKYRAT EDIT ADDITION BEGIN - Skyrat-SS13/Skyrat-tg#2429
- upgrade_reagents = list(
+ //SKYRAT EDIT ADDITION BEGIN
+ var/static/list/drink_upgrade_reagents = list(
/datum/reagent/consumable/applejuice,
/datum/reagent/consumable/pumpkinjuice,
/datum/reagent/consumable/vanilla
)
- upgrade_reagents2 = list(
+ var/static/list/drink_upgrade2_reagents = list(
/datum/reagent/consumable/banana,
/datum/reagent/consumable/berryjuice,
/datum/reagent/consumable/blumpkinjuice
)
- upgrade_reagents3 = list(
+ var/static/list/drink_upgrade3_reagents = list(
/datum/reagent/consumable/watermelonjuice,
/datum/reagent/consumable/peachjuice,
/datum/reagent/consumable/sol_dry
)
//SKYRAT EDIT ADDITION END
- emagged_reagents = list(
+ upgrade_reagents = null
+ /// The default list of emagged reagents dispensable by the soda dispenser
+ var/static/list/drink_emagged_reagents = list(
/datum/reagent/consumable/ethanol/thirteenloko,
/datum/reagent/consumable/ethanol/whiskey_cola,
/datum/reagent/toxin/mindbreaker,
@@ -612,6 +642,24 @@
base_reagent_purity = 0.5
/obj/machinery/chem_dispenser/drinks/Initialize(mapload)
+ if(dispensable_reagents != null && !dispensable_reagents.len)
+ dispensable_reagents = drinks_dispensable_reagents
+ if(emagged_reagents != null && !emagged_reagents.len)
+ emagged_reagents = drink_emagged_reagents
+ //SKYRAT EDIT ADDITION BEGIN
+ if(upgrade_reagents != null && !upgrade_reagents.len)
+ upgrade_reagents = drink_upgrade_reagents
+ if(upgrade_reagents)
+ upgrade_reagents = sort_list(upgrade_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
+ if(upgrade2_reagents != null && !upgrade2_reagents.len)
+ upgrade2_reagents = drink_upgrade2_reagents
+ if(upgrade2_reagents)
+ upgrade2_reagents = sort_list(upgrade2_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
+ if(upgrade3_reagents != null && !upgrade3_reagents.len)
+ upgrade3_reagents = drink_upgrade3_reagents
+ if(upgrade3_reagents)
+ upgrade3_reagents = sort_list(upgrade3_reagents, GLOBAL_PROC_REF(cmp_reagents_asc))
+ //SKYRAT EDIT ADDITION END
. = ..()
AddComponent(/datum/component/simple_rotation)
@@ -656,7 +704,8 @@
base_icon_state = "booze_dispenser"
dispensed_temperature = WATER_MATTERSTATE_CHANGE_TEMP
circuit = /obj/item/circuitboard/machine/chem_dispenser/drinks/beer
- dispensable_reagents = list(
+ /// The default list of reagents dispensable by the beer dispenser
+ var/static/list/beer_dispensable_reagents = list(
/datum/reagent/consumable/ethanol/absinthe,
/datum/reagent/consumable/ethanol/ale,
/datum/reagent/consumable/ethanol/applejack,
@@ -685,9 +734,10 @@
/datum/reagent/consumable/ethanol/yuyake,
)
upgrade_reagents = null
- upgrade_reagents2 = null //SKYRAT EDIT
- upgrade_reagents3 = null //SKYRAT EDIT
- emagged_reagents = list(
+ upgrade2_reagents = null //SKYRAT EDIT
+ upgrade3_reagents = null //SKYRAT EDIT
+ /// The default list of emagged reagents dispensable by the beer dispenser
+ var/static/list/beer_emagged_reagents = list(
/datum/reagent/consumable/ethanol,
/datum/reagent/iron,
/datum/reagent/consumable/mintextract,
@@ -695,6 +745,11 @@
/datum/reagent/consumable/ethanol/fernet
)
+/obj/machinery/chem_dispenser/drinks/beer/Initialize(mapload)
+ dispensable_reagents = beer_dispensable_reagents
+ emagged_reagents = beer_emagged_reagents
+ . = ..()
+
/obj/machinery/chem_dispenser/drinks/beer/fullupgrade //fully ugpraded stock parts, emagged
desc = "Contains a large reservoir of the good stuff. This model has had its safeties shorted out."
obj_flags = CAN_BE_HIT | EMAGGED
@@ -708,19 +763,25 @@
/obj/machinery/chem_dispenser/mutagen
name = "mutagen dispenser"
desc = "Creates and dispenses mutagen."
- dispensable_reagents = list(/datum/reagent/toxin/mutagen)
+ /// The default list of reagents dispensable by mutagen chem dispenser
+ var/static/list/mutagen_dispensable_reagents = list(/datum/reagent/toxin/mutagen)
upgrade_reagents = null
- emagged_reagents = list(/datum/reagent/toxin/plasma)
+ /// The default list of emagged reagents dispensable by mutagen chem dispenser
+ var/static/list/mutagen_emagged_reagents = list(/datum/reagent/toxin/plasma)
+/obj/machinery/chem_dispenser/mutagen/Initialize(mapload)
+ dispensable_reagents = mutagen_dispensable_reagents
+ emagged_reagents = mutagen_emagged_reagents
+ . = ..()
/obj/machinery/chem_dispenser/mutagensaltpeter
name = "botanical chemical dispenser"
desc = "Creates and dispenses chemicals useful for botany."
flags_1 = NODECONSTRUCT_1
-
circuit = /obj/item/circuitboard/machine/chem_dispenser/mutagensaltpeter
- dispensable_reagents = list(
+ /// The default list of dispensable reagents available in the mutagensaltpeter chem dispenser
+ var/static/list/mutagensaltpeter_dispensable_reagents = list(
/datum/reagent/toxin/mutagen,
/datum/reagent/saltpetre,
/datum/reagent/plantnutriment/eznutriment,
@@ -736,6 +797,10 @@
/datum/reagent/diethylamine)
upgrade_reagents = null
+/obj/machinery/chem_dispenser/mutagensaltpeter/Initialize(mapload)
+ dispensable_reagents = mutagensaltpeter_dispensable_reagents
+ . = ..()
+
/obj/machinery/chem_dispenser/fullupgrade //fully ugpraded stock parts, emagged
desc = "Creates and dispenses chemicals. This model has had its safeties shorted out."
obj_flags = CAN_BE_HIT | EMAGGED
@@ -757,7 +822,9 @@
working_state = null
nopower_state = null
use_power = NO_POWER_USE
- dispensable_reagents = list(
+
+ /// The default list of dispensable reagents available in the abductor chem dispenser
+ var/static/list/abductor_dispensable_reagents = list(
/datum/reagent/aluminium,
/datum/reagent/bromine,
/datum/reagent/carbon,
@@ -799,3 +866,7 @@
/datum/reagent/consumable/liquidelectricity/enriched,
/datum/reagent/medicine/c2/synthflesh
)
+
+/obj/machinery/chem_dispenser/abductor/Initialize(mapload)
+ dispensable_reagents = abductor_dispensable_reagents
+ . = ..()
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index c5f62883b5f..83b1b0705ef 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -597,33 +597,31 @@
ui.open()
/obj/item/blood_filter/ui_data(mob/user)
- var/list/data = list()
- var/list/chem_names = list()
+ . = list()
+
+ .["whitelist"] = list()
for(var/key in whitelist)
- chem_names += whitelist[key]
- data["whitelist"] = chem_names
- return data
+ .["whitelist"] += whitelist[key]
/obj/item/blood_filter/ui_act(action, params)
. = ..()
if(.)
return
+
. = TRUE
switch(action)
if("add")
- var/selected_reagent = tgui_input_list(usr, "Select reagent to filter", "Whitelist reagent", GLOB.chemical_name_list)
+ var/selected_reagent = tgui_input_list(usr, "Select reagent to filter", "Whitelist reagent", GLOB.name2reagent)
if(!selected_reagent)
- return TRUE
+ return FALSE
- var/chem_id = get_chem_id(selected_reagent)
+ var/datum/reagent/chem_id = GLOB.name2reagent[selected_reagent]
if(!chem_id)
- return TRUE
+ return FALSE
if(!(chem_id in whitelist))
whitelist[chem_id] = selected_reagent
-
-
if("remove")
var/chem_name = params["reagent"]
var/chem_id = get_chem_id(chem_name)
diff --git a/tgui/packages/tgui/interfaces/ChemDispenser.js b/tgui/packages/tgui/interfaces/ChemDispenser.tsx
similarity index 82%
rename from tgui/packages/tgui/interfaces/ChemDispenser.js
rename to tgui/packages/tgui/interfaces/ChemDispenser.tsx
index d1035900a32..c8dc25e943f 100644
--- a/tgui/packages/tgui/interfaces/ChemDispenser.js
+++ b/tgui/packages/tgui/interfaces/ChemDispenser.tsx
@@ -1,22 +1,49 @@
import { toFixed } from 'common/math';
+import { BooleanLike } from 'common/react';
import { toTitleCase } from 'common/string';
-import { Fragment } from 'inferno';
import { useBackend, useLocalState } from '../backend';
import { AnimatedNumber, Box, Button, Icon, LabeledList, ProgressBar, Section } from '../components';
import { Window } from '../layouts';
+export type BeakerReagent = {
+ name: string;
+ volume: number;
+};
+
+export type Beaker = {
+ maxVolume: number;
+ transferAmounts: number[];
+ pH: number;
+ currentVolume: number;
+ contents: BeakerReagent[];
+};
+
+type DispensableReagent = {
+ title: string;
+ id: string;
+ pH: number;
+ pHCol: string;
+};
+
+type Data = {
+ showpH: BooleanLike;
+ amount: number;
+ energy: number;
+ maxEnergy: number;
+ chemicals: DispensableReagent[];
+ recipes: string[];
+ recordingRecipe: string[];
+ recipeReagents: string[];
+ beaker: Beaker;
+};
+
export const ChemDispenser = (props, context) => {
- const { act, data } = useBackend(context);
+ const { act, data } = useBackend(context);
const recording = !!data.recordingRecipe;
- const { recipeReagents = [] } = data;
+ const { recipeReagents = [], recipes = [], beaker } = data;
const [hasCol, setHasCol] = useLocalState(context, 'has_col', false);
- // TODO: Change how this piece of shit is built on server side
- // It has to be a list, not a fucking OBJECT!
- const recipes = Object.keys(data.recipes).map((name) => ({
- name,
- contents: data.recipes[name],
- }));
- const beakerTransferAmounts = data.beakerTransferAmounts || [];
+
+ const beakerTransferAmounts = beaker ? beaker.transferAmounts : [];
const beakerContents =
(recording &&
Object.keys(data.recordingRecipe).map((id) => ({
@@ -24,7 +51,7 @@ export const ChemDispenser = (props, context) => {
name: toTitleCase(id.replace(/_/, ' ')),
volume: data.recordingRecipe[id],
}))) ||
- data.beakerContents ||
+ beaker?.contents ||
[];
return (
@@ -41,10 +68,10 @@ export const ChemDispenser = (props, context) => {
)}