No more magical transformation of condiment containers on reagent change (#54102)

* Removal of magical transformation of condiment containers on reagent change.

Instead allows to set specific style for condiment bottle when creating via CondiMaster.

* Codestyle fixes

* DMDOC comments.

Also removed var/useramount and proc/isgoodnumber from /chem_master

* Recompiled tgui.bundle.js after rebase
This commit is contained in:
MIK517
2020-10-03 09:36:10 +03:00
committed by GitHub
parent 5c4829a2eb
commit 192e9aa941
23 changed files with 313 additions and 105 deletions
@@ -1,3 +1,9 @@
/**
* Machine that allows to identify and separate reagents in fitting container
* as well as to create new containers with separated reagents in it.
*
* Contains logic for both ChemMaster and CondiMaster, switched by "condi".
*/
/obj/machinery/chem_master
name = "ChemMaster 3000"
desc = "Used to separate chemicals and distribute them in a variety of forms."
@@ -10,27 +16,40 @@
resistance_flags = FIRE_PROOF | ACID_PROOF
circuit = /obj/item/circuitboard/machine/chem_master
var/obj/item/reagent_containers/beaker = null
var/obj/item/storage/pill_bottle/bottle = null
/// Input reagents container
var/obj/item/reagent_containers/beaker
/// Pill bottle for newly created pills
var/obj/item/storage/pill_bottle/bottle
/// Whether separated reagents should be moved back to container or destroyed. 1 - move, 0 - destroy
var/mode = 1
/// Decides what UI to show. If TRUE shows UI of CondiMaster, if FALSE - ChemMaster
var/condi = FALSE
var/chosenPillStyle = 1
/// Currently selected pill style
var/chosen_pill_style = 1
/// Currently selected condiment bottle style
var/chosen_condi_style = CONDIMASTER_STYLE_AUTO
/// Current UI screen. On the moment of writing this comment there were two: 'home' - main screen, and 'analyze' - info about specific reagent
var/screen = "home"
var/analyzeVars[0]
var/useramount = 30 // Last used amount
var/list/pillStyles = null
/// Info to display on 'analyze' screen
var/analyze_vars[0]
/// List of available pill styles for UI
var/list/pill_styles
/// List of available condibottle styles for UI
var/list/condi_styles
/obj/machinery/chem_master/Initialize()
create_reagents(100)
//Calculate the span tags and ids fo all the available pill icons
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
pillStyles = list()
pill_styles = list()
for (var/x in 1 to PILL_STYLE_COUNT)
var/list/SL = list()
SL["id"] = x
SL["className"] = assets.icon_class_name("pill[x]")
pillStyles += list(SL)
pill_styles += list(SL)
condi_styles = strip_condi_styles_to_icons(get_condi_styles())
. = ..()
@@ -131,6 +150,17 @@
return
replace_beaker(user)
/**
* Handles process of moving input reagents containers in/from machine
*
* When called checks for previously inserted beaker and gives it to user.
* Then, if new_beaker provided, places it into src.beaker.
* Returns `boolean`. TRUE if user provided (ignoring whether threre was any beaker change) and FALSE if not.
*
* Arguments:
* * user - Mob that initialized replacement, gets previously inserted beaker if there's any
* * new_beaker - New beaker to insert. Optional
*/
/obj/machinery/chem_master/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(!user)
return FALSE
@@ -153,6 +183,7 @@
/obj/machinery/chem_master/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/simple/pills),
get_asset_datum(/datum/asset/spritesheet/simple/condiments),
)
/obj/machinery/chem_master/ui_interact(mob/user, datum/tgui/ui)
@@ -169,28 +200,31 @@
data["mode"] = mode
data["condi"] = condi
data["screen"] = screen
data["analyzeVars"] = analyzeVars
data["chosenPillStyle"] = chosenPillStyle
data["analyzeVars"] = analyze_vars
data["chosenPillStyle"] = chosen_pill_style
data["chosenCondiStyle"] = chosen_condi_style
data["autoCondiStyle"] = CONDIMASTER_STYLE_AUTO
data["isPillBottleLoaded"] = bottle ? 1 : 0
if(bottle)
var/datum/component/storage/STRB = bottle.GetComponent(/datum/component/storage)
data["pillBottleCurrentAmount"] = bottle.contents.len
data["pillBottleMaxAmount"] = STRB.max_items
var/beakerContents[0]
var/beaker_contents[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))) // list in a list because Byond merges the first list...
data["beakerContents"] = beakerContents
beaker_contents.Add(list(list("name" = R.name, "id" = ckey(R.name), "volume" = R.volume))) // list in a list because Byond merges the first list...
data["beakerContents"] = beaker_contents
var/bufferContents[0]
var/buffer_contents[0]
if(reagents.total_volume)
for(var/datum/reagent/N in reagents.reagent_list)
bufferContents.Add(list(list("name" = N.name, "id" = ckey(N.name), "volume" = N.volume))) // ^
data["bufferContents"] = bufferContents
buffer_contents.Add(list(list("name" = N.name, "id" = ckey(N.name), "volume" = N.volume))) // ^
data["bufferContents"] = buffer_contents
//Calculated at init time as it never changes
data["pillStyles"] = pillStyles
data["pillStyles"] = pill_styles
data["condiStyles"] = condi_styles
return data
/obj/machinery/chem_master/ui_act(action, params)
@@ -240,7 +274,11 @@
if(action == "pillStyle")
var/id = text2num(params["id"])
chosenPillStyle = id
chosen_pill_style = id
return TRUE
if(action == "condiStyle")
chosen_condi_style = params["id"]
return TRUE
if(action == "create")
@@ -260,6 +298,8 @@
var/vol_each = text2num(params["volume"])
var/vol_each_text = params["volume"]
var/vol_each_max = reagents.total_volume / amount
var/list/style
if (item_type == "pill")
vol_each_max = min(50, vol_each_max)
else if (item_type == "patch")
@@ -269,6 +309,11 @@
else if (item_type == "condimentPack")
vol_each_max = min(10, vol_each_max)
else if (item_type == "condimentBottle")
var/list/styles = get_condi_styles()
if (chosen_condi_style == CONDIMASTER_STYLE_AUTO || !(chosen_condi_style in styles))
style = guess_condi_style(reagents)
else
style = styles[chosen_condi_style]
vol_each_max = min(50, vol_each_max)
else
return FALSE
@@ -286,7 +331,11 @@
var/name = params["name"]
var/name_has_units = item_type == "pill" || item_type == "patch"
if(!name)
var/name_default = reagents.get_master_reagent_name()
var/name_default
if (style && style["name"] && !style["generate_name"])
name_default = style["name"]
else
name_default = reagents.get_master_reagent_name()
if (name_has_units)
name_default += " ([vol_each]u)"
name = stripped_input(usr,
@@ -312,10 +361,10 @@
else
P = new/obj/item/reagent_containers/pill(drop_location())
P.name = trim("[name] pill")
if(chosenPillStyle == RANDOM_PILL_STYLE)
if(chosen_pill_style == RANDOM_PILL_STYLE)
P.icon_state ="pill[rand(1,21)]"
else
P.icon_state = "pill[chosenPillStyle]"
P.icon_state = "pill[chosen_pill_style]"
if(P.icon_state == "pill4")
P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality."
adjust_item_drop_location(P)
@@ -350,8 +399,10 @@
var/obj/item/reagent_containers/food/condiment/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/food/condiment(drop_location())
P.originalname = name
P.name = trim("[name] bottle")
if (style)
apply_condi_style(P, style)
P.renamedByPlayer = TRUE
P.name = name
reagents.trans_to(P, vol_each, transfered_by = usr)
return TRUE
return FALSE
@@ -368,7 +419,7 @@
state = "Gas"
var/const/P = 3 //The number of seconds between life ticks
var/T = initial(R.metabolization_rate) * (60 / P)
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
analyze_vars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
screen = "analyze"
return TRUE
@@ -378,20 +429,6 @@
return FALSE
/obj/machinery/chem_master/proc/isgoodnumber(num)
if(isnum(num))
if(num > 200)
num = 200
else if(num < 0)
num = 0
else
num = round(num)
return num
else
return 0
/obj/machinery/chem_master/adjust_item_drop_location(atom/movable/AM) // Special version for chemmasters and condimasters
if (AM == beaker)
AM.pixel_x = -8
@@ -412,6 +449,131 @@
AM.pixel_x = ((.%3)*6)
AM.pixel_y = -8 + (round( . / 3)*8)
/**
* Translates styles data into UI compatible format
*
* Expects to receive list of availables condiment styles in its complete format, and transforms them in simplified form with enough data to get UI going.
* Returns list(list("id" = <key>, "className" = <icon class>, "title" = <name and desc>),..).
*
* Arguments:
* * styles - List of styles for condiment bottles in internal format: [/obj/machinery/chem_master/proc/get_condi_styles]
*/
/obj/machinery/chem_master/proc/strip_condi_styles_to_icons(list/styles)
var/list/icons = list()
for (var/s in styles)
if (styles[s] && styles[s]["class_name"])
var/list/icon = list()
var/list/style = styles[s]
icon["id"] = s
icon["className"] = style["class_name"]
icon["title"] = "[style["name"]]\n[style["desc"]]"
icons += list(icon)
return icons
/**
* Defines and provides list of available condiment bottle styles
*
* Uses typelist() for styles storage after initialization.
* For fallback style must provide style with key (const) CONDIMASTER_STYLE_FALLBACK
* Returns list(
* <key> = list(
* "icon_state" = <bottle icon_state>,
* "name" = <bottle name>,
* "desc" = <bottle desc>,
* ?"generate_name" = <if truthy, autogenerates default name from reagents instead of using "name">,
* ?"icon_empty" = <icon_state when empty>,
* ?"fill_icon_thresholds" = <list of thresholds for reagentfillings, no tresholds if not provided or falsy>,
* ?"inhand_icon_state" = <inhand icon_state, falsy - no icon, not provided - whatever is initial (currently "beer")>,
* ?"lefthand_file" = <file for inhand icon for left hand, ignored if "inhand_icon_state" not provided>,
* ?"righthand_file" = <same as "lefthand_file" but for right hand>,
* ),
* ..
* )
*
*/
/obj/machinery/chem_master/proc/get_condi_styles()
var/list/styles = typelist("condi_styles")
if (!styles.len)
//Possible_states has the reagent type as key and a list of, in order, the icon_state, the name and the desc as values. Was used in the condiment/on_reagent_change(changetype) to change names, descs and sprites.
styles += list(
CONDIMASTER_STYLE_FALLBACK = list("icon_state" = "emptycondiment", "icon_empty" = "", "name" = "condiment bottle", "desc" = "Just your average condiment bottle.", "fill_icon_thresholds" = list(0, 10, 25, 50, 75, 100), "generate_name" = TRUE),
"enzyme" = list("icon_state" = "enzyme", "icon_empty" = "", "name" = "universal enzyme bottle", "desc" = "Used in cooking various dishes."),
"flour" = list("icon_state" = "flour", "icon_empty" = "", "name" = "flour sack", "desc" = "A big bag of flour. Good for baking!"),
"mayonnaise" = list("icon_state" = "mayonnaise", "icon_empty" = "", "name" = "mayonnaise jar", "desc" = "An oily condiment made from egg yolks."),
"milk" = list("icon_state" = "milk", "icon_empty" = "", "name" = "space milk", "desc" = "It's milk. White and nutritious goodness!"),
"blackpepper" = list("icon_state" = "peppermillsmall", "inhand_icon_state" = "", "icon_empty" = "emptyshaker", "name" = "pepper mill", "desc" = "Often used to flavor food or make people sneeze."),
"rice" = list("icon_state" = "rice", "icon_empty" = "", "name" = "rice sack", "desc" = "A big bag of rice. Good for cooking!"),
"sodiumchloride" = list("icon_state" = "saltshakersmall", "inhand_icon_state" = "", "icon_empty" = "emptyshaker", "name" = "salt shaker", "desc" = "Salt. From dead crew, presumably."),
"soymilk" = list("icon_state" = "soymilk", "icon_empty" = "", "name" = "soy milk", "desc" = "It's soy milk. White and nutritious goodness!"),
"soysauce" = list("icon_state" = "soysauce", "inhand_icon_state" = "", "icon_empty" = "", "name" = "soy sauce bottle", "desc" = "A salty soy-based flavoring."),
"sugar" = list("icon_state" = "sugar", "icon_empty" = "", "name" = "sugar sack", "desc" = "Tasty spacey sugar!"),
"ketchup" = list("icon_state" = "ketchup", "icon_empty" = "", "name" = "ketchup bottle", "desc" = "You feel more American already."),
"capsaicin" = list("icon_state" = "hotsauce", "icon_empty" = "", "name" = "hotsauce bottle", "desc" = "You can almost TASTE the stomach ulcers!"),
"frostoil" = list("icon_state" = "coldsauce", "icon_empty" = "", "name" = "coldsauce bottle", "desc" = "Leaves the tongue numb from its passage."),
"cornoil" = list("icon_state" = "oliveoil", "icon_empty" = "", "name" = "corn oil bottle", "desc" = "A delicious oil used in cooking. Made from corn."),
"bbqsauce" = list("icon_state" = "bbqsauce", "icon_empty" = "", "name" = "bbq sauce bottle", "desc" = "Hand wipes not included.")
)
var/list/carton_in_hand = list(
"inhand_icon_state" = "carton",
"lefthand_file" = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi',
"righthand_file" = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
)
for (var/style_reagent in list("flour", "milk", "rice", "soymilk", "sugar"))
if (style_reagent in styles)
styles[style_reagent] += carton_in_hand
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/condiments)
for (var/reagent in styles)
styles[reagent]["class_name"] = assets.icon_class_name(reagent)
return styles
/**
* Provides condiment bottle style based on reagents.
*
* Gets style from available by key, using last part of main reagent type (eg. "rice" for /datum/reagent/consumable/rice) as key.
* If not available returns fallback style, or null if no such thing.
* Returns list that is one of condibottle styles from [/obj/machinery/chem_master/proc/get_condi_styles]
*/
/obj/machinery/chem_master/proc/guess_condi_style(datum/reagents/reagents)
var/list/styles = get_condi_styles()
if (reagents.reagent_list.len > 0)
var/main_reagent = reagents.get_master_reagent_id()
if (main_reagent)
var/list/path = splittext("[main_reagent]", "/")
main_reagent = path[path.len]
if(main_reagent in styles)
return styles[main_reagent]
return styles[CONDIMASTER_STYLE_FALLBACK]
/**
* Applies style to condiment bottle.
*
* Applies props provided in "style" assuming that "container" is freshly created with no styles applied before.
* User specified name for bottle applied after this method during bottle creation,
* so container.name overwritten here for consistency rather than with some purpose in mind.
*
* Arguments:
* * container - condiment bottle that gets style applied to it
* * style - assoc list, must probably one from [/obj/machinery/chem_master/proc/get_condi_styles]
*/
/obj/machinery/chem_master/proc/apply_condi_style(obj/item/reagent_containers/food/condiment/container, list/style)
container.name = style["name"]
container.desc = style["desc"]
container.icon_state = style["icon_state"]
container.icon_empty = style["icon_empty"]
container.fill_icon_thresholds = style["fill_icon_thresholds"]
if ("inhand_icon_state" in style)
container.inhand_icon_state = style["inhand_icon_state"]
if (style["lefthand_file"] || style["righthand_file"])
container.lefthand_file = style["lefthand_file"]
container.righthand_file = style["righthand_file"]
/**
* Machine that allows to identify and separate reagents in fitting container
* as well as to create new containers with separated reagents in it.
*
* All logic related to this is in [/obj/machinery/chem_master] and condimaster specific UI enabled by "condi = TRUE"
*/
/obj/machinery/chem_master/condimaster
name = "CondiMaster 3000"
desc = "Used to create condiments and other cooking supplies."