mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-21 04:57:57 +01:00
[MIRROR] Reagent machinery code maintainence [MDB IGNORE] (#24859)
* Reagent machinery code maintainence * Modular * Modular * Modular * Modular * Modular * Modular * Update chem_dispenser.dm * Update chem_dispenser.dm * Update chem_dispenser.dm * Update chem_dispenser.dm --------- Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Co-authored-by: Giz <13398309+vinylspiders@users.noreply.github.com>
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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))
|
||||
. += "<span class='notice'>The status display reads:\n\
|
||||
Recharging <b>[recharge_amount]</b> power units per interval.\n\
|
||||
Power efficiency increased by <b>[round((powerefficiency*1000)-100, 1)]%</b>.</span>"
|
||||
Power efficiency increased by <b>[round((powerefficiency * 1000) -100, 1)]%</b>.</span>"
|
||||
. += span_notice("Use <b>RMB</b> 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 <b>[reagent]</b>!"))
|
||||
to_chat(ui.user, span_warning("[src] cannot find <b>[reagent]</b>!"))
|
||||
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
|
||||
. = ..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
+51
-28
@@ -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<Data>(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 (
|
||||
<Window width={565} height={620}>
|
||||
@@ -41,10 +68,10 @@ export const ChemDispenser = (props, context) => {
|
||||
)}
|
||||
<Button
|
||||
icon="book"
|
||||
disabled={!data.isBeakerLoaded}
|
||||
disabled={!beaker}
|
||||
content={'Reaction search'}
|
||||
tooltip={
|
||||
data.isBeakerLoaded
|
||||
beaker
|
||||
? 'Look up recipes and reagents!'
|
||||
: 'Please insert a beaker!'
|
||||
}
|
||||
@@ -84,7 +111,7 @@ export const ChemDispenser = (props, context) => {
|
||||
{!recording && (
|
||||
<Button
|
||||
icon="circle"
|
||||
disabled={!data.isBeakerLoaded}
|
||||
disabled={!beaker}
|
||||
content="Record"
|
||||
onClick={() => act('record_recipe')}
|
||||
/>
|
||||
@@ -108,16 +135,16 @@ export const ChemDispenser = (props, context) => {
|
||||
</>
|
||||
}>
|
||||
<Box mr={-1}>
|
||||
{recipes.map((recipe) => (
|
||||
{Object.keys(recipes).map((recipe) => (
|
||||
<Button
|
||||
key={recipe.name}
|
||||
key={recipe}
|
||||
icon="tint"
|
||||
width="129.5px"
|
||||
lineHeight={1.75}
|
||||
content={recipe.name}
|
||||
content={recipe}
|
||||
onClick={() =>
|
||||
act('dispense_recipe', {
|
||||
recipe: recipe.name,
|
||||
recipe: recipe,
|
||||
})
|
||||
}
|
||||
/>
|
||||
@@ -187,30 +214,26 @@ export const ChemDispenser = (props, context) => {
|
||||
<LabeledList.Item
|
||||
label="Beaker"
|
||||
buttons={
|
||||
!!data.isBeakerLoaded && (
|
||||
!!beaker && (
|
||||
<Button
|
||||
icon="eject"
|
||||
content="Eject"
|
||||
disabled={!data.isBeakerLoaded}
|
||||
onClick={() => act('eject')}
|
||||
/>
|
||||
)
|
||||
}>
|
||||
{(recording && 'Virtual beaker') ||
|
||||
(data.isBeakerLoaded && (
|
||||
(!!beaker && (
|
||||
<>
|
||||
<AnimatedNumber
|
||||
initial={0}
|
||||
value={data.beakerCurrentVolume}
|
||||
/>
|
||||
/{data.beakerMaxVolume} units
|
||||
<AnimatedNumber initial={0} value={beaker.currentVolume} />/
|
||||
{beaker.maxVolume} units
|
||||
</>
|
||||
)) ||
|
||||
'No beaker'}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Contents">
|
||||
<Box color="label">
|
||||
{(!data.isBeakerLoaded && !recording && 'N/A') ||
|
||||
{(!beaker && !recording && 'N/A') ||
|
||||
(beakerContents.length === 0 && 'Nothing')}
|
||||
</Box>
|
||||
{beakerContents.map((chemical) => (
|
||||
@@ -222,7 +245,7 @@ export const ChemDispenser = (props, context) => {
|
||||
{beakerContents.length > 0 && !!data.showpH && (
|
||||
<Box>
|
||||
pH:
|
||||
<AnimatedNumber value={data.beakerCurrentpH} />
|
||||
<AnimatedNumber value={beaker.pH} />
|
||||
</Box>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
+34
-33
@@ -1,28 +1,35 @@
|
||||
import { sortBy } from 'common/collections';
|
||||
import { toTitleCase } from 'common/string';
|
||||
import { Beaker } from './ChemDispenser';
|
||||
import { useBackend } from '../backend';
|
||||
import { AnimatedNumber, Box, Button, LabeledList, Section } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
type DispensableReagent = {
|
||||
title: string;
|
||||
id: string;
|
||||
volume: number;
|
||||
pH: number;
|
||||
};
|
||||
|
||||
type Data = {
|
||||
amount: number;
|
||||
chemicals: DispensableReagent[];
|
||||
beaker: Beaker;
|
||||
};
|
||||
|
||||
export const PortableChemMixer = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const recording = !!data.recordingRecipe;
|
||||
const beakerTransferAmounts = data.beakerTransferAmounts || [];
|
||||
const beakerContents =
|
||||
(recording &&
|
||||
Object.keys(data.recordingRecipe).map((id) => ({
|
||||
id,
|
||||
name: toTitleCase(id.replace(/_/, ' ')),
|
||||
volume: data.recordingRecipe[id],
|
||||
}))) ||
|
||||
data.beakerContents ||
|
||||
[];
|
||||
const chemicals = sortBy((chem) => chem.title)(data.chemicals);
|
||||
const { act, data } = useBackend<Data>(context);
|
||||
const { beaker } = data;
|
||||
const beakerTransferAmounts = beaker ? beaker.transferAmounts : [];
|
||||
const beakerContents = beaker ? beaker.contents : [];
|
||||
const chemicals = sortBy((chem: DispensableReagent) => chem.id)(
|
||||
data.chemicals
|
||||
);
|
||||
return (
|
||||
<Window width={465} height={550}>
|
||||
<Window width={500} height={500}>
|
||||
<Window.Content scrollable>
|
||||
<Section
|
||||
title="Dispense"
|
||||
title="Dispense Controls"
|
||||
buttons={beakerTransferAmounts.map((amount) => (
|
||||
<Button
|
||||
key={amount}
|
||||
@@ -55,12 +62,11 @@ export const PortableChemMixer = (props, context) => {
|
||||
</Box>
|
||||
</Section>
|
||||
<Section
|
||||
title="Disposal controls"
|
||||
title="Disposal Controls"
|
||||
buttons={beakerTransferAmounts.map((amount) => (
|
||||
<Button
|
||||
key={amount}
|
||||
icon="minus"
|
||||
disabled={recording}
|
||||
content={amount}
|
||||
onClick={() => act('remove', { amount })}
|
||||
/>
|
||||
@@ -69,30 +75,25 @@ export const PortableChemMixer = (props, context) => {
|
||||
<LabeledList.Item
|
||||
label="Beaker"
|
||||
buttons={
|
||||
!!data.isBeakerLoaded && (
|
||||
!!beaker && (
|
||||
<Button
|
||||
icon="eject"
|
||||
content="Eject"
|
||||
disabled={!data.isBeakerLoaded}
|
||||
onClick={() => act('eject')}
|
||||
/>
|
||||
)
|
||||
}>
|
||||
{(recording && 'Virtual beaker') ||
|
||||
(data.isBeakerLoaded && (
|
||||
<>
|
||||
<AnimatedNumber
|
||||
initial={0}
|
||||
value={data.beakerCurrentVolume}
|
||||
/>
|
||||
/{data.beakerMaxVolume} units
|
||||
</>
|
||||
)) ||
|
||||
{(!!beaker && (
|
||||
<>
|
||||
<AnimatedNumber initial={0} value={beaker.currentVolume} />/
|
||||
{beaker.maxVolume} units
|
||||
</>
|
||||
)) ||
|
||||
'No beaker'}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Contents">
|
||||
<Box color="label">
|
||||
{(!data.isBeakerLoaded && !recording && 'N/A') ||
|
||||
{(!beaker && 'N/A') ||
|
||||
(beakerContents.length === 0 && 'Nothing')}
|
||||
</Box>
|
||||
{beakerContents.map((chemical) => (
|
||||
@@ -101,10 +102,10 @@ export const PortableChemMixer = (props, context) => {
|
||||
of {chemical.name}
|
||||
</Box>
|
||||
))}
|
||||
{beakerContents.length > 0 && !!data.showpH && (
|
||||
{beakerContents.length > 0 && (
|
||||
<Box>
|
||||
pH:
|
||||
<AnimatedNumber value={data.beakerCurrentpH} />
|
||||
<AnimatedNumber value={beaker.pH} />
|
||||
</Box>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
Reference in New Issue
Block a user