From 56212d2712e74a146f27b49cf7a569bc9dca69a8 Mon Sep 17 00:00:00 2001 From: SyncIt21 <110812394+SyncIt21@users.noreply.github.com> Date: Sat, 7 Mar 2026 15:09:20 +0530 Subject: [PATCH] Cleans up chemical reaction & reagent look up code (#95281) ## About The Pull Request - Removed global list `fake_reagent_blacklist` in favour of `abstract_type`. Saved memory - Removed proc `get_chemical_reaction()` in favor of `GLOB.chemical_reaction_list`. No proc overhead and faster access - Remove unused proc `remove_chemical_reaction()` - Removed proc `find_reagent()` in favour of `GLOB.chemical_reagents_list`. No proc overhead and faster access - Directly access name of reagents via `::` operator from typepaths instead of looking up the datum in global chemical reagents list for some operations. Faster variable access - Removed unit test `reagent_id_typos`. The typepaths will error at compile time because they aren't strings so there's no need for this test ## Changelog :cl: code: cleaned up code pertaining to reagent & reaction lookup /:cl: --- code/__HELPERS/reagents.dm | 39 +-------------- code/_globalvars/lists/reagents.dm | 22 ++------ .../subsystem/persistence/recipes.dm | 2 +- .../subsystem/processing/reagents.dm | 2 - code/datums/weather/weather.dm | 2 +- code/game/machinery/limbgrower.dm | 7 ++- .../reagents/chemistry/chem_wiki_render.dm | 2 +- .../reagents/chemistry/holder/ui_data.dm | 50 ++++++++----------- .../chemistry/machinery/chem_dispenser.dm | 7 ++- .../chemistry/machinery/chem_recipe_debug.dm | 5 +- code/modules/reagents/chemistry/reagents.dm | 2 + .../reagents/cat2_medicine_reagents.dm | 1 + .../chemistry/reagents/medicine_reagents.dm | 1 + .../reagents/reaction_agents_reagents.dm | 1 + .../reagents/chemistry/recipes/special.dm | 12 ++--- code/modules/unit_tests/_unit_tests.dm | 1 - code/modules/unit_tests/metabolizing.dm | 2 +- code/modules/unit_tests/reagent_id_typos.dm | 13 ----- code/modules/unit_tests/reagent_names.dm | 2 +- 19 files changed, 52 insertions(+), 121 deletions(-) delete mode 100644 code/modules/unit_tests/reagent_id_typos.dm diff --git a/code/__HELPERS/reagents.dm b/code/__HELPERS/reagents.dm index d616bdbd5cb..5c194b01319 100644 --- a/code/__HELPERS/reagents.dm +++ b/code/__HELPERS/reagents.dm @@ -58,21 +58,6 @@ //if we got this far, the longer reaction will be impossible to create if the shorter one is earlier in GLOB.chemical_reactions_list_reactant_index, and will require the reagents to be added in a particular order otherwise return TRUE -/proc/get_chemical_reaction(id) - if(!GLOB.chemical_reactions_list_reactant_index) - return - for(var/reagent in GLOB.chemical_reactions_list_reactant_index) - for(var/R in GLOB.chemical_reactions_list_reactant_index[reagent]) - var/datum/reac = R - if(reac.type == id) - return R - -/proc/remove_chemical_reaction(datum/chemical_reaction/R) - if(!GLOB.chemical_reactions_list_reactant_index || !R) - return - for(var/rid in R.required_reagents) - GLOB.chemical_reactions_list_reactant_index[rid] -= R - //see build_chemical_reactions_list in holder.dm for explanations /proc/add_chemical_reaction(datum/chemical_reaction/add) if(!GLOB.chemical_reactions_list_reactant_index || !add.required_reagents || !add.required_reagents.len) @@ -81,6 +66,7 @@ if(!GLOB.chemical_reactions_list_reactant_index[rand_reagent]) GLOB.chemical_reactions_list_reactant_index[rand_reagent] = list() GLOB.chemical_reactions_list_reactant_index[rand_reagent] += add + GLOB.chemical_reactions_list[add.type] = add //Creates foam from the reagent. Metaltype is for metal foam, notification is what to show people in textbox /datum/reagents/proc/create_foam(foamtype, foam_volume, result_type = null, notification = null, log = FALSE) @@ -166,23 +152,9 @@ if(shortcuts[input_reagent]) input_reagent = shortcuts[input_reagent] else - input_reagent = find_reagent(input_reagent) + input_reagent = get_chem_id(input_reagent) return input_reagent -///Returns reagent datum from typepath -/proc/find_reagent(input) - . = FALSE - if(GLOB.chemical_reagents_list[input]) //prefer IDs! - return input - else - return get_chem_id(input) - -/proc/find_reagent_object_from_type(input) - if(GLOB.chemical_reagents_list[input]) //prefer IDs! - return GLOB.chemical_reagents_list[input] - else - return null - ///Returns a random reagent object, with the option to blacklist reagents. /proc/get_random_reagent_id(list/blacklist) var/static/list/reagent_static_list = list() //This is static, and will be used by default if a blacklist is not passed. @@ -219,13 +191,6 @@ if(ckey(chem_name) == ckey(LOWER_TEXT(R.name))) return X -///Takes a type in and returns a list of associated recipes -/proc/get_recipe_from_reagent_product(input_type) - if(!input_type) - return - var/list/matching_reactions = GLOB.chemical_reactions_list_product_index[input_type] - return matching_reactions - /proc/reagent_paths_list_to_text(list/reagents, addendum) var/list/temp = list() for(var/datum/reagent/R as anything in reagents) diff --git a/code/_globalvars/lists/reagents.dm b/code/_globalvars/lists/reagents.dm index 96c0e4d4fd4..847bdd7167c 100644 --- a/code/_globalvars/lists/reagents.dm +++ b/code/_globalvars/lists/reagents.dm @@ -47,8 +47,6 @@ GLOBAL_LIST(chemical_reactions_list_product_index) GLOBAL_LIST_INIT(chemical_reagents_list, init_chemical_reagent_list()) /// list of all reactions with their associated product and result ids. Used for reaction lookups GLOBAL_LIST(chemical_reactions_results_lookup_list) -/// list of all reagents that are parent types used to define a bunch of children - but aren't used themselves as anything. -GLOBAL_LIST(fake_reagent_blacklist) /// Turfs metalgen can't touch 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 @@ -73,9 +71,7 @@ GLOBAL_LIST_INIT(stacked_metabolization_effect, init_chemical_side_effects()) /proc/init_chemical_reagent_list() var/list/reagent_list = list() - for(var/datum/reagent/path as anything in subtypesof(/datum/reagent)) - if(path in GLOB.fake_reagent_blacklist) - continue + for(var/datum/reagent/path as anything in valid_subtypesof(/datum/reagent)) var/datum/reagent/target_object = new path() target_object.mass = rand(10, 800) reagent_list[path] = target_object @@ -152,19 +148,11 @@ GLOBAL_LIST_INIT(stacked_metabolization_effect, init_chemical_side_effects()) GLOB.chemical_reactions_list[reaction.type] = reaction - for(var/reagent_path in reaction.required_reagents) - var/datum/reagent/reagent = find_reagent_object_from_type(reagent_path) - if(!istype(reagent)) - stack_trace("Invalid reagent found in [reaction] required_reagents: [reagent_path]") - continue - reagents += list(list("name" = reagent.name, "id" = reagent.type)) + for(var/datum/reagent/reagent as anything in reaction.required_reagents) + reagents += list(list("name" = reagent::name, "id" = reagent)) - for(var/product in reaction.results) - var/datum/reagent/reagent = find_reagent_object_from_type(product) - if(!istype(reagent)) - stack_trace("Invalid reagent found in [reaction] results: [product]") - continue - product_names += reagent.name + for(var/datum/reagent/product as anything in reaction.results) + product_names += product::name product_ids += product var/product_name diff --git a/code/controllers/subsystem/persistence/recipes.dm b/code/controllers/subsystem/persistence/recipes.dm index 84145b26aab..0b0d16b2e84 100644 --- a/code/controllers/subsystem/persistence/recipes.dm +++ b/code/controllers/subsystem/persistence/recipes.dm @@ -30,7 +30,7 @@ //asert globchems done for(var/randomized_type in subtypesof(/datum/chemical_reaction/randomized)) - var/datum/chemical_reaction/randomized/R = get_chemical_reaction(randomized_type) //ew, would be nice to add some simple tracking + var/datum/chemical_reaction/randomized/R = GLOB.chemical_reactions_list[randomized_type] if(R?.persistent) var/list/recipe_data = R.SaveOldRecipe() file_data["[R.type]"] = recipe_data diff --git a/code/controllers/subsystem/processing/reagents.dm b/code/controllers/subsystem/processing/reagents.dm index 5e64e259db4..b116d859709 100644 --- a/code/controllers/subsystem/processing/reagents.dm +++ b/code/controllers/subsystem/processing/reagents.dm @@ -13,8 +13,6 @@ PROCESSING_SUBSYSTEM_DEF(reagents) /datum/controller/subsystem/processing/reagents/Initialize() //So our first step isn't insane previous_world_time = world.time - ///Blacklists these reagents from being added to the master list. the exact type only. Children are not blacklisted. - GLOB.fake_reagent_blacklist = list(/datum/reagent/medicine/c2, /datum/reagent/medicine, /datum/reagent/reaction_agent) //Build GLOB lists - see holder.dm build_chemical_reactions_lists() return SS_INIT_SUCCESS diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index f0a87956c56..c744d148140 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -152,7 +152,7 @@ reagent_id = get_random_reagent_id(blacklist_weather_reagents) if(reagent_id) - weather_reagent = find_reagent_object_from_type(reagent_id) + weather_reagent = GLOB.chemical_reagents_list[reagent_id] weather_color = weather_reagent.color weather_reagent_holder = new(null) // spawns in nullspace weather_reagent_holder.create_reagents(WEATHER_REAGENT_VOLUME, NO_REACT) diff --git a/code/game/machinery/limbgrower.dm b/code/game/machinery/limbgrower.dm index 39564a41609..d8a7109bbca 100644 --- a/code/game/machinery/limbgrower.dm +++ b/code/game/machinery/limbgrower.dm @@ -117,11 +117,10 @@ ) for(var/datum/design/found_design in species_categories[category]) var/list/all_reagents = list() - for(var/reagent_typepath in found_design.reagents_list) - var/datum/reagent/reagent_id = find_reagent_object_from_type(reagent_typepath) + for(var/datum/reagent/reagent_id as anything in found_design.reagents_list) var/list/reagent_data = list( - name = reagent_id.name, - amount = (found_design.reagents_list[reagent_typepath] * production_coefficient), + name = reagent_id::name, + amount = (found_design.reagents_list[reagent_id] * production_coefficient), ) all_reagents += list(reagent_data) diff --git a/code/modules/reagents/chemistry/chem_wiki_render.dm b/code/modules/reagents/chemistry/chem_wiki_render.dm index 70617b7e191..f265879057c 100644 --- a/code/modules/reagents/chemistry/chem_wiki_render.dm +++ b/code/modules/reagents/chemistry/chem_wiki_render.dm @@ -22,7 +22,7 @@ ADMIN_VERB(generate_wikichem_list, R_DEBUG, "Parse Wikichems", "Parse and genera var/list/names = splittext("[input_text]", ",") for(var/name in names) - var/datum/reagent/reagent = find_reagent_object_from_type(get_chem_id(name)) + var/datum/reagent/reagent = GLOB.chemical_reagents_list[get_chem_id(name)] if(!reagent) to_chat(user, "Could not find [name]. Skipping.") continue diff --git a/code/modules/reagents/chemistry/holder/ui_data.dm b/code/modules/reagents/chemistry/holder/ui_data.dm index da1d73e6a7d..74f77238d40 100644 --- a/code/modules/reagents/chemistry/holder/ui_data.dm +++ b/code/modules/reagents/chemistry/holder/ui_data.dm @@ -129,7 +129,7 @@ //reagent lookup data if(ui_reagent_id) - var/datum/reagent/reagent = find_reagent_object_from_type(ui_reagent_id) + var/datum/reagent/reagent = GLOB.chemical_reagents_list[ui_reagent_id] if(!reagent) to_chat(user, "Could not find reagent!") ui_reagent_id = null @@ -149,8 +149,7 @@ //reaction lookup data if (ui_reaction_id) - - var/datum/chemical_reaction/reaction = get_chemical_reaction(ui_reaction_id) + var/datum/chemical_reaction/reaction = GLOB.chemical_reactions_list[ui_reaction_id] if(!reaction) to_chat(user, "Could not find reaction!") ui_reaction_id = null @@ -174,7 +173,7 @@ //If we do have a product then we find it else //Find out if we have multiple reactions for the same product - var/datum/reagent/primary_reagent = find_reagent_object_from_type(reaction.results[1])//We use the first product - though it might be worth changing this + var/datum/reagent/primary_reagent = GLOB.chemical_reagents_list[reaction.results[1]]//We use the first product - though it might be worth changing this //If we're syncing from the beaker var/list/sub_reactions = list() if(ui_beaker_sync && reaction_list) @@ -183,7 +182,7 @@ var/ongoing_r = ongoing_eq.reaction sub_reactions += ongoing_r else - sub_reactions = get_recipe_from_reagent_product(primary_reagent.type) + sub_reactions = GLOB.chemical_reactions_list_product_index[primary_reagent.type] var/sub_reaction_length = length(sub_reactions) var/i = 1 for(var/datum/chemical_reaction/sub_reaction in sub_reactions) @@ -195,21 +194,19 @@ //Results sweep var/has_reagent = "default" - for(var/_reagent in reaction.results) - var/datum/reagent/reagent = find_reagent_object_from_type(_reagent) - if(has_reagent(_reagent)) + for(var/datum/reagent/reagent as anything in reaction.results) + if(has_reagent(reagent)) has_reagent = "green" - data["reagent_mode_recipe"]["products"] += list(list("name" = reagent.name, "id" = reagent.type, "ratio" = reaction.results[reagent.type], "hasReagentCol" = has_reagent)) + data["reagent_mode_recipe"]["products"] += list(list("name" = reagent::name, "id" = reagent, "ratio" = reaction.results[reagent], "hasReagentCol" = has_reagent)) //Reactant sweep - for(var/_reagent in reaction.required_reagents) - var/datum/reagent/reagent = find_reagent_object_from_type(_reagent) + for(var/datum/reagent/reagent as anything in reaction.required_reagents) var/color_r = "default" //If the holder is missing the reagent, it's displayed in orange - if(has_reagent(reagent.type)) + if(has_reagent(reagent)) color_r = "green" //It's green if it's present var/tooltip var/tooltip_bool = FALSE - var/list/sub_reactions = get_recipe_from_reagent_product(reagent.type) + var/list/sub_reactions = GLOB.chemical_reactions_list_product_index[reagent] //Get sub reaction possibilities, but ignore ones that need a specific holder atom var/sub_index = 0 for(var/datum/chemical_reaction/sub_reaction as anything in sub_reactions) @@ -221,29 +218,26 @@ if(sub_index) var/datum/chemical_reaction/sub_reaction = sub_reactions[sub_index] //Subreactions sweep (if any) - for(var/_sub_reagent in sub_reaction.required_reagents) - var/datum/reagent/sub_reagent = find_reagent_object_from_type(_sub_reagent) - tooltip += "[sub_reaction.required_reagents[_sub_reagent]]u [sub_reagent.name]\n" //I forgot the better way of doing this - fix this after this works + for(var/datum/reagent/sub_reagent as anything in sub_reaction.required_reagents) + tooltip += "[sub_reaction.required_reagents[sub_reagent]]u [sub_reagent::name]\n" tooltip_bool = TRUE - data["reagent_mode_recipe"]["reactants"] += list(list("name" = reagent.name, "id" = reagent.type, "ratio" = reaction.required_reagents[reagent.type], "color" = color_r, "tooltipBool" = tooltip_bool, "tooltip" = tooltip)) + data["reagent_mode_recipe"]["reactants"] += list(list("name" = reagent::name, "id" = reagent, "ratio" = reaction.required_reagents[reagent], "color" = color_r, "tooltipBool" = tooltip_bool, "tooltip" = tooltip)) //Catalyst sweep - for(var/_reagent in reaction.required_catalysts) - var/datum/reagent/reagent = find_reagent_object_from_type(_reagent) + for(var/datum/reagent/reagent as anything in reaction.required_catalysts) var/color_r = "default" - if(has_reagent(reagent.type)) + if(has_reagent(reagent)) color_r = "green" var/tooltip var/tooltip_bool = FALSE - var/list/sub_reactions = get_recipe_from_reagent_product(reagent.type) + var/list/sub_reactions = GLOB.chemical_reactions_list_product_index[reagent] if(length(sub_reactions)) var/datum/chemical_reaction/sub_reaction = sub_reactions[1] //Subreactions sweep (if any) - for(var/_sub_reagent in sub_reaction.required_reagents) - var/datum/reagent/sub_reagent = find_reagent_object_from_type(_sub_reagent) - tooltip += "[sub_reaction.required_reagents[_sub_reagent]]u [sub_reagent.name]\n" //I forgot the better way of doing this - fix this after this works + for(var/datum/reagent/sub_reagent as anything in sub_reaction.required_reagents) + tooltip += "[sub_reaction.required_reagents[sub_reagent]]u [sub_reagent::name]\n" tooltip_bool = TRUE - data["reagent_mode_recipe"]["catalysts"] += list(list("name" = reagent.name, "id" = reagent.type, "ratio" = reaction.required_catalysts[reagent.type], "color" = color_r, "tooltipBool" = tooltip_bool, "tooltip" = tooltip)) + data["reagent_mode_recipe"]["catalysts"] += list(list("name" = reagent::name, "id" = reagent, "ratio" = reaction.required_catalysts[reagent], "color" = color_r, "tooltipBool" = tooltip_bool, "tooltip" = tooltip)) data["reagent_mode_recipe"]["isColdRecipe"] = reaction.is_cold_recipe else data["reagent_mode_recipe"] = null @@ -267,7 +261,7 @@ /datum/reagents/proc/get_reaction_from_indexed_possibilities(path, index = null) if(index) ui_reaction_index = index - var/list/sub_reactions = get_recipe_from_reagent_product(path) + var/list/sub_reactions = GLOB.chemical_reactions_list_product_index[path] if(!length(sub_reactions)) to_chat(usr, "There is no recipe associated with this product.") return FALSE @@ -293,7 +287,7 @@ if("search_reagents") var/input_reagent = tgui_input_list(usr, "Select reagent", "Reagent", GLOB.name2reagent) input_reagent = get_reagent_type_from_product_string(input_reagent) //from string to type - var/datum/reagent/reagent = find_reagent_object_from_type(input_reagent) + var/datum/reagent/reagent = GLOB.chemical_reagents_list[input_reagent] if(!reagent) to_chat(usr, "Could not find reagent!") return FALSE @@ -302,7 +296,7 @@ if("search_recipe") var/input_reagent = (input("Enter the name of product reagent", "Input") as text|null) input_reagent = get_reagent_type_from_product_string(input_reagent) //from string to type - var/datum/reagent/reagent = find_reagent_object_from_type(input_reagent) + var/datum/reagent/reagent = GLOB.chemical_reagents_list[input_reagent] if(!reagent) to_chat(usr, "Could not find product reagent!") return diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index e6cc4ebb86d..21687ea36eb 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -244,10 +244,9 @@ .["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) - .["recipeReagents"] += reagent.name + var/datum/chemical_reaction/reaction = GLOB.chemical_reactions_list[beaker.reagents.ui_reaction_id] + for(var/datum/reagent/reagent as anything in reaction.required_reagents) + .["recipeReagents"] += reagent::name var/list/beaker_data = null if(!QDELETED(beaker)) diff --git a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm index f83c5a1ad0d..f4b44d5e8ce 100644 --- a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm +++ b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm @@ -77,9 +77,8 @@ if(isnull(all_reaction_list)) all_reaction_list = list() - for(var/datum/reagent/reagent as anything in GLOB.chemical_reactions_list_reactant_index) - for(var/datum/chemical_reaction/reaction as anything in GLOB.chemical_reactions_list_reactant_index[reagent]) - all_reaction_list[extract_reaction_name(reaction)] = reaction + for(var/reaction, datum in GLOB.chemical_reactions_list) + all_reaction_list[extract_reaction_name(datum)] = datum /obj/machinery/chem_recipe_debug/Destroy() reactions_to_test.Cut() diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 78897d6b09f..2a00b8c9a32 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -1,5 +1,7 @@ /// A single reagent /datum/reagent + abstract_type = /datum/reagent + /// datums don't have names by default var/name = "" /// nor do they have descriptions diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index 6a7ad214695..a6f4f369d08 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -1,5 +1,6 @@ // Category 2 medicines are medicines that have an ill effect regardless of volume/OD to dissuade doping. Mostly used as emergency chemicals OR to convert damage (and heal a bit in the process). The type is used to prompt borgs that the medicine is harmful. /datum/reagent/medicine/c2 + abstract_type = /datum/reagent/medicine/c2 metabolization_rate = 0.5 * REAGENTS_METABOLISM inverse_chem = null //Some of these use inverse chems - we're just defining them all to null here to avoid repetition, eventually this will be moved up to parent creation_purity = REAGENT_STANDARD_PURITY//All sources by default are 0.75 - reactions are primed to resolve to roughly the same with no intervention for these. diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index cae2113fa16..69c421c6dce 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -8,6 +8,7 @@ /datum/reagent/medicine taste_description = "bitterness" + abstract_type = /datum/reagent/medicine /datum/reagent/medicine/New() . = ..() diff --git a/code/modules/reagents/chemistry/reagents/reaction_agents_reagents.dm b/code/modules/reagents/chemistry/reagents/reaction_agents_reagents.dm index d35d503daaa..4b3f6fff275 100644 --- a/code/modules/reagents/chemistry/reagents/reaction_agents_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/reaction_agents_reagents.dm @@ -1,4 +1,5 @@ /datum/reagent/reaction_agent + abstract_type = /datum/reagent/reaction_agent name = "Reaction Agent" description = "Hello! I am a bugged reagent. Please report me for my crimes. Thank you!!" diff --git a/code/modules/reagents/chemistry/recipes/special.dm b/code/modules/reagents/chemistry/recipes/special.dm index d4a0b8bd693..4ae6a1aafa0 100644 --- a/code/modules/reagents/chemistry/recipes/special.dm +++ b/code/modules/reagents/chemistry/recipes/special.dm @@ -317,21 +317,19 @@ GLOBAL_LIST_INIT(medicine_reagents, build_medicine_reagents()) qui officia deserunt mollit anim id est laborum." /obj/item/paper/secretrecipe/proc/UpdateInfo() - var/datum/chemical_reaction/recipe = get_chemical_reaction(recipe_id) + var/datum/chemical_reaction/recipe = GLOB.chemical_reactions_list[recipe_id] if(!recipe) add_raw_text("This recipe is illegible.") update_appearance() return var/list/dat = list("" if(recipe.required_catalysts.len) dat += "With following present: " dat += "Mix slowly