diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index cb2747d4f4b..0f26751f306 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -188,6 +188,14 @@ /// This reaction is produces a product that affects plants #define REACTION_TAG_COMPETITIVE (1<<21) +//flags used by holder.dm to locate an reagent +///Direct type +#define REAGENT_STRICT_TYPE (1<<0) +///Parent type but not sub types for e.g. if param is obj/item it will look for obj/item/stack but not obj/item/stack/sheet +#define REAGENT_PARENT_TYPE (1<<1) +///same as istype() check +#define REAGENT_SUB_TYPE (1<<2) + #define RNGCHEM_INPUT "input" #define RNGCHEM_CATALYSTS "catalysts" #define RNGCHEM_OUTPUT "output" diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 79f101cb74c..b99d9a1b912 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -268,7 +268,7 @@ var/datum/reagent/RGNT while(amt > 0) var/obj/item/reagent_containers/RC = locate() in surroundings - RG = RC.reagents.get_reagent(path_key) + RG = RC.reagents.has_reagent(path_key) if(RG) if(!locate(RG.type) in Deletion) Deletion += new RG.type() diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index 1ddcb57feaf..fccb6a5d8f5 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -1006,7 +1006,7 @@ victim.blood_volume -= 5 * seconds_between_ticks // This has been hell to try and balance so that you'll actually get anything out of it victim.reagents.add_reagent(/datum/reagent/gold/cursed, amount = seconds_between_ticks * goldscale, no_react = TRUE) - var/current_gold_amount = victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE) + var/current_gold_amount = victim.reagents.get_reagent_amount(/datum/reagent/gold, type_check = REAGENT_SUB_TYPE) switch(current_gold_amount) if(-INFINITY to 50) victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/soft, update = TRUE) diff --git a/code/game/objects/items/hand_items.dm b/code/game/objects/items/hand_items.dm index 786824e7af2..c6dc9cb7a2f 100644 --- a/code/game/objects/items/hand_items.dm +++ b/code/game/objects/items/hand_items.dm @@ -660,7 +660,7 @@ to_chat(firer, span_warning("You've already blessed [target.name] with your heart and soul.")) return - var/amount_nutriment = target.reagents.get_multiple_reagent_amounts(typesof(/datum/reagent/consumable/nutriment)) + var/amount_nutriment = target.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment, type_check = REAGENT_PARENT_TYPE) if(amount_nutriment <= 0) to_chat(firer, span_warning("There's not enough nutrition in [target.name] for it to be a proper meal.")) return diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm index 8a59c8c8326..4c8bf08cac6 100644 --- a/code/game/objects/items/mop.dm +++ b/code/game/objects/items/mop.dm @@ -50,7 +50,7 @@ if(reagents.total_volume < 0.1) cleaner.balloon_alert(cleaner, "mop is dry!") return DO_NOT_CLEAN - return reagents.has_chemical_flag(REAGENT_CLEANS, 1) + return reagents.has_reagent(amount = 1, chemical_flags = REAGENT_CLEANS) /** * Applies reagents to the cleaned floor and removes them from the mop. diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 67256249732..f37b8a644bf 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -340,10 +340,7 @@ * subsequently be deleted. */ /obj/machinery/biogenerator/proc/convert_to_biomass(obj/item/food/food_to_convert) - var/static/list/nutrient_subtypes = typesof(/datum/reagent/consumable/nutriment) - var/nutriments = 0 - - nutriments += ROUND_UP(food_to_convert.reagents.get_multiple_reagent_amounts(nutrient_subtypes)) + var/nutriments = ROUND_UP(food_to_convert.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment, type_check = REAGENT_PARENT_TYPE)) qdel(food_to_convert) current_item_count = max(current_item_count - 1, 0) biomass += nutriments * productivity diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index b872fc0ec37..c0fdbcd4607 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -146,7 +146,7 @@ var/grind_results_num = LAZYLEN(grind_results) if(grind_results_num) var/average_purity = reagents.get_average_purity() - var/total_nutriment_amount = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment, include_subtypes = TRUE) + var/total_nutriment_amount = reagents.get_reagent_amount(/datum/reagent/consumable/nutriment, type_check = REAGENT_SUB_TYPE) var/single_reagent_amount = grind_results_num > 1 ? round(total_nutriment_amount / grind_results_num, CHEMICAL_QUANTISATION_LEVEL) : total_nutriment_amount reagents.remove_reagent(/datum/reagent/consumable/nutriment, total_nutriment_amount, include_subtypes = TRUE) for(var/reagent in grind_results) diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm index 100d5c3da65..2aeb97a89fe 100644 --- a/code/modules/mob/living/silicon/robot/robot_model.dm +++ b/code/modules/mob/living/silicon/robot/robot_model.dm @@ -616,7 +616,7 @@ var/turf/our_turf = get_turf(robot_owner) - if(reagents.has_chemical_flag(REAGENT_CLEANS, 1)) + if(reagents.has_reagent(amount = 1, chemical_flags = REAGENT_CLEANS)) our_turf.wash(CLEAN_SCRUB) reagents.expose(our_turf, TOUCH, min(1, 10 / reagents.total_volume)) diff --git a/code/modules/projectiles/guns/special/hand_of_midas.dm b/code/modules/projectiles/guns/special/hand_of_midas.dm index d515c252baf..5c9cb1fd978 100644 --- a/code/modules/projectiles/guns/special/hand_of_midas.dm +++ b/code/modules/projectiles/guns/special/hand_of_midas.dm @@ -46,7 +46,7 @@ if(!victim.reagents) return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - var/gold_amount = victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE) + var/gold_amount = victim.reagents.get_reagent_amount(/datum/reagent/gold, type_check = REAGENT_SUB_TYPE) if(!gold_amount) balloon_alert(user, "no gold in bloodstream") return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 8236a17fb58..e57f228e104 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -375,7 +375,7 @@ remove_reagent(reagent.type, reagent.volume * multiplier) reagent_purity = weighted_purity / reagent_amount else - var/datum/reagent/source_reagent = get_reagent(source_reagent_typepath) + var/datum/reagent/source_reagent = has_reagent(source_reagent_typepath) reagent_amount = source_reagent.volume reagent_purity = source_reagent.purity reagent_ph = source_reagent.ph @@ -394,63 +394,53 @@ SEND_SIGNAL(src, COMSIG_REAGENTS_CLEAR_REAGENTS) /** - * Check if this holder contains this reagent. Reagent takes a PATH to a reagent - * Needs matabolizing takes into consideration if the chemical is metabolizing when it's checked. + * Returns a reagent from this holder if it matches all the specified arguments * Arguments * - * * [target_reagent][datum/reagent] - the reagent typepath to check for + * * [target_reagent][datum/reagent] - the reagent typepath to check for. can be null to return any reagent * * amount - checks for having a specific amount of that chemical * * needs_metabolizing - takes into consideration if the chemical is matabolizing when it's checked. * * check_subtypes - controls whether it should it should also include subtypes: ispath(type, reagent) versus type == reagent. + * * chemical_flags - checks for reagent flags. */ /datum/reagents/proc/has_reagent( datum/reagent/target_reagent, amount = -1, needs_metabolizing = FALSE, - check_subtypes = FALSE + check_subtypes = FALSE, + chemical_flags = NONE ) - if(!ispath(target_reagent)) + if(!isnull(target_reagent) && !ispath(target_reagent)) stack_trace("invalid reagent path passed to has reagent [target_reagent]") return FALSE var/list/cached_reagents = reagent_list for(var/datum/reagent/holder_reagent as anything in cached_reagents) - if (check_subtypes ? ispath(holder_reagent.type, target_reagent) : holder_reagent.type == target_reagent) - if(!amount) - if(needs_metabolizing && !holder_reagent.metabolizing) - if(check_subtypes) - continue - return FALSE - return holder_reagent - else - if(holder_reagent.volume >= amount) - if(needs_metabolizing && !holder_reagent.metabolizing) - if(check_subtypes) - continue - return FALSE - return holder_reagent - else if(!check_subtypes) - return FALSE - return FALSE + //finding for a specific reagent + if(!isnull(target_reagent)) + //first find for specific type or subtype + if(!check_subtypes) + if(holder_reagent.type != target_reagent) + continue + else if(!istype(holder_reagent, target_reagent)) + continue -/** - * Check if this holder contains a reagent with a chemical_flags containing this flag - * Reagent takes the bitflag to search for - * - * Arguments - * * chemical_flag - the flag to check for - * * amount - checks for having a specific amount of reagents matching that chemical - */ -/datum/reagents/proc/has_chemical_flag(chemical_flag, amount = 0) - var/found_amount = 0 - var/list/cached_reagents = reagent_list - for(var/datum/reagent/holder_reagent as anything in cached_reagents) - if (holder_reagent.chemical_flags & chemical_flag) - found_amount += holder_reagent.volume - if(found_amount >= amount) - return TRUE - return FALSE + //next check if we have the requested amount + if(amount > 0 && holder_reagent.volume < amount) + continue + + //next check for metabolization + if(needs_metabolizing && !holder_reagent.metabolizing) + continue + + //next check if it has the specified flag + if(chemical_flags && !(holder_reagent.chemical_flags & chemical_flags)) + continue + + //after all that if we get here then we have found our reagent + return holder_reagent + return FALSE /** * Transfer some stuff from this holder to a target object @@ -1326,32 +1316,32 @@ * Get the amount of this reagent or the sum of all its subtypes if specified * Arguments * * [reagent][datum/reagent] - the typepath of the reagent to look for - * * include_subtypes - if TRUE returns the sum of volumes of all subtypes of the above param reagent + * * type_check - see defines under reagents.dm file */ -/datum/reagents/proc/get_reagent_amount(datum/reagent/reagent, include_subtypes = FALSE) +/datum/reagents/proc/get_reagent_amount(datum/reagent/reagent, type_check = REAGENT_STRICT_TYPE) if(!ispath(reagent)) stack_trace("invalid path passed to get_reagent_amount [reagent]") return 0 - var/list/cached_reagents = reagent_list + var/total_amount = 0 for(var/datum/reagent/cached_reagent as anything in cached_reagents) - if((!include_subtypes && cached_reagent.type == reagent) || (include_subtypes && ispath(cached_reagent.type, reagent))) - total_amount += cached_reagent.volume + switch(type_check) + if(REAGENT_STRICT_TYPE) + if(cached_reagent.type != reagent) + continue + if(REAGENT_PARENT_TYPE) //to simulate typesof() which returns the type and then child types + if(cached_reagent.type != reagent && type2parent(cached_reagent.type) != reagent) + continue + else + if(!istype(cached_reagent, reagent)) + continue - return round(total_amount, CHEMICAL_VOLUME_ROUNDING) + total_amount += cached_reagent.volume -/** - * Gets the sum of volumes of all reagent type paths present in the list - * Arguments - * * [reagents][list] - list of reagent typepaths - */ -/datum/reagents/proc/get_multiple_reagent_amounts(list/reagents) - var/list/cached_reagents = reagent_list - var/total_amount = 0 - for(var/datum/reagent/cached_reagent as anything in cached_reagents) - if(cached_reagent.type in reagents) - total_amount += cached_reagent.volume + //short cut to break when we have found our one exact type + if(type_check == REAGENT_STRICT_TYPE) + break return round(total_amount, CHEMICAL_VOLUME_ROUNDING) @@ -1424,15 +1414,6 @@ return trans_data -/** - * Get a reference to the reagent if it exists - * Arguments - * * [type][datum/reagent] - the typepath of the reagent to look up - */ -/datum/reagents/proc/get_reagent(datum/reagent/type) - var/list/cached_reagents = reagent_list - . = locate(type) in cached_reagents - /** * Returns what this holder's reagents taste like * @@ -1552,7 +1533,7 @@ * * value - How much to adjust the base pH by */ /datum/reagents/proc/adjust_specific_reagent_ph(input_reagent, value) - var/datum/reagent/reagent = get_reagent(input_reagent) + var/datum/reagent/reagent = has_reagent(input_reagent) if(!reagent) //We can call this with missing reagents. return FALSE reagent.ph = clamp(reagent.ph + value, CHEMICAL_MIN_PH, CHEMICAL_MAX_PH) diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index 2461f8eb90b..1e2b06e0f62 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -273,7 +273,7 @@ if(!equilibrium.reaction.results)//Incase of no result reactions continue var/_reagent = equilibrium.reaction.results[1] - var/datum/reagent/reagent = beaker?.reagents.get_reagent(_reagent) //Reactions are named after their primary products + var/datum/reagent/reagent = beaker?.reagents.has_reagent(_reagent) //Reactions are named after their primary products if(!reagent) continue var/overheat = FALSE @@ -438,11 +438,11 @@ To continue set your target temperature to 390K."} return if(buffer_type == "acid") if(volume < 0) - var/datum/reagent/acid_reagent = beaker.reagents.get_reagent(/datum/reagent/reaction_agent/acidic_buffer) + var/datum/reagent/acid_reagent = beaker.reagents.has_reagent(/datum/reagent/reaction_agent/acidic_buffer) if(!acid_reagent) say("Unable to find acidic buffer in beaker to draw from! Please insert a beaker containing acidic buffer.") return - var/datum/reagent/acid_reagent_heater = reagents.get_reagent(/datum/reagent/reaction_agent/acidic_buffer) + var/datum/reagent/acid_reagent_heater = reagents.has_reagent(/datum/reagent/reaction_agent/acidic_buffer) var/cur_vol = 0 if(acid_reagent_heater) cur_vol = acid_reagent_heater.volume @@ -455,11 +455,11 @@ To continue set your target temperature to 390K."} if(buffer_type == "basic") if(volume < 0) - var/datum/reagent/basic_reagent = beaker.reagents.get_reagent(/datum/reagent/reaction_agent/basic_buffer) + var/datum/reagent/basic_reagent = beaker.reagents.has_reagent(/datum/reagent/reaction_agent/basic_buffer) if(!basic_reagent) say("Unable to find basic buffer in beaker to draw from! Please insert a beaker containing basic buffer.") return - var/datum/reagent/basic_reagent_heater = reagents.get_reagent(/datum/reagent/reaction_agent/basic_buffer) + var/datum/reagent/basic_reagent_heater = reagents.has_reagent(/datum/reagent/reaction_agent/basic_buffer) var/cur_vol = 0 if(basic_reagent_heater) cur_vol = basic_reagent_heater.volume @@ -472,7 +472,7 @@ To continue set your target temperature to 390K."} /obj/machinery/chem_heater/proc/get_purity_color(datum/equilibrium/equilibrium) var/_reagent = equilibrium.reaction.results[1] - var/datum/reagent/reagent = equilibrium.holder.get_reagent(_reagent) + var/datum/reagent/reagent = equilibrium.holder.has_reagent(_reagent) // Can't be a switch due to http://www.byond.com/forum/post/2750423 if(reagent.purity in 1 to INFINITY) return "blue" diff --git a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm index ce409dd29a8..b5f2d31dfa5 100644 --- a/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm +++ b/code/modules/reagents/chemistry/machinery/chem_recipe_debug.dm @@ -128,7 +128,7 @@ say("Reaction completed for [cached_reactions[index]] final temperature = [reagents.chem_temp], ph = [reagents.ph], time taken = [react_time]s.") var/datum/chemical_reaction/reaction = cached_reactions[index] for(var/reagent_type in reaction.results) - var/datum/reagent/reagent = reagents.get_reagent(reagent_type) + var/datum/reagent/reagent = reagents.has_reagent(reagent_type) if(!reagent) say(span_warning("Unable to find product [reagent_type] in holder after reaction! reagents found are:")) for(var/other_reagent in reagents.reagent_list) @@ -231,7 +231,7 @@ continue if(!equilibrium.reaction.results)//Incase of no result reactions continue - var/datum/reagent/reagent = reagents.get_reagent(equilibrium.reaction.results[1]) //Reactions are named after their primary products + var/datum/reagent/reagent = reagents.has_reagent(equilibrium.reaction.results[1]) //Reactions are named after their primary products if(!reagent) continue var/overheat = FALSE diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 5f57de94b4d..62dc148bba2 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -186,7 +186,7 @@ */ /datum/chemical_reaction/proc/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added) for(var/id in results) - var/datum/reagent/reagent = holder.get_reagent(id) + var/datum/reagent/reagent = holder.has_reagent(id) if(!reagent) return reagent.volume = round((reagent.volume*0.98), 0.01) //Slowly lower yield per tick @@ -206,7 +206,7 @@ /datum/chemical_reaction/proc/overly_impure(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added) var/affected_list = results + required_reagents for(var/_reagent in affected_list) - var/datum/reagent/reagent = holder.get_reagent(_reagent) + var/datum/reagent/reagent = holder.has_reagent(_reagent) if(!reagent) continue reagent.purity = clamp((reagent.purity-0.01), 0, 1) //slowly reduce purity of reagents diff --git a/code/modules/reagents/chemistry/recipes/cat2_medicines.dm b/code/modules/reagents/chemistry/recipes/cat2_medicines.dm index ea93cc82e1a..c61a7739377 100644 --- a/code/modules/reagents/chemistry/recipes/cat2_medicines.dm +++ b/code/modules/reagents/chemistry/recipes/cat2_medicines.dm @@ -25,7 +25,7 @@ /datum/chemical_reaction/medicine/helbital/overly_impure(datum/reagents/holder, datum/equilibrium/equilibrium, step_volume_added) explode_fire_vortex(holder, equilibrium, 1, 1, "impure") holder.chem_temp += 2.5 - var/datum/reagent/helbital = holder.get_reagent(/datum/reagent/medicine/c2/helbital) + var/datum/reagent/helbital = holder.has_reagent(/datum/reagent/medicine/c2/helbital) if(!helbital) return if(helbital.purity <= 0.25) @@ -41,7 +41,7 @@ /datum/chemical_reaction/medicine/helbital/reaction_finish(datum/reagents/holder, datum/equilibrium/reaction, react_vol) . = ..() - var/datum/reagent/helbital = holder.get_reagent(/datum/reagent/medicine/c2/helbital) + var/datum/reagent/helbital = holder.has_reagent(/datum/reagent/medicine/c2/helbital) if(!helbital) return if(helbital.purity <= 0.1) //So people don't ezmode this by keeping it at min diff --git a/code/modules/reagents/chemistry/recipes/drugs.dm b/code/modules/reagents/chemistry/recipes/drugs.dm index 8822aa78705..3d25fa5e2b1 100644 --- a/code/modules/reagents/chemistry/recipes/drugs.dm +++ b/code/modules/reagents/chemistry/recipes/drugs.dm @@ -30,7 +30,7 @@ //The less pure it is, the faster it heats up. tg please don't hate me for making your meth even more dangerous /datum/chemical_reaction/methamphetamine/reaction_step(datum/reagents/holder, datum/equilibrium/reaction, delta_t, delta_ph, step_reaction_vol) - var/datum/reagent/meth = holder.get_reagent(/datum/reagent/drug/methamphetamine) + var/datum/reagent/meth = holder.has_reagent(/datum/reagent/drug/methamphetamine) if(!meth)//First step reaction.thermic_mod = (1-delta_ph)*5 return @@ -45,7 +45,7 @@ temp_meth_explosion(holder, equilibrium.reacted_vol) /datum/chemical_reaction/methamphetamine/reaction_finish(datum/reagents/holder, datum/equilibrium/reaction, react_vol) - var/datum/reagent/meth = holder.get_reagent(/datum/reagent/drug/methamphetamine) + var/datum/reagent/meth = holder.has_reagent(/datum/reagent/drug/methamphetamine) if(!meth)//Other procs before this can already blow us up return ..() if(meth.purity < purity_min) diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index d3ad4bd6ce5..c87a6196835 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -730,7 +730,7 @@ reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE /datum/chemical_reaction/metalgen_imprint/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume) - var/datum/reagent/metalgen/MM = holder.get_reagent(/datum/reagent/metalgen) + var/datum/reagent/metalgen/MM = holder.has_reagent(/datum/reagent/metalgen) for(var/datum/reagent/R in holder.reagent_list) if(R.material && R.volume >= 40) MM.data["material"] = R.material diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_organs.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_organs.dm index 51b4df93049..7a0e972f3d8 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_organs.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/hemophage/hemophage_organs.dm @@ -82,7 +82,7 @@ // I didn't feel like moving this behavior onto the component, it was just too annoying to do. /obj/item/organ/internal/stomach/hemophage/on_life(seconds_per_tick, times_fired) - var/datum/reagent/blood/blood = reagents.get_reagent(/datum/reagent/blood) + var/datum/reagent/blood/blood = reagents.has_reagent(/datum/reagent/blood) if(blood) blood.metabolization_rate = BLOOD_METABOLIZATION_RATE