diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index bbc86cb9e87..e109a30594d 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -1,11 +1,31 @@ #define ADDICTION_TIME 4800 //8 minutes -/////////////////////////////////////////////////////////////////////////////////// - +/** + * # Reagents Holder + * + * The holder is the datum that holds a list of all reagents + * currently in the object. + * + * By default, all atom have an empty reagents var. If you want to use + * an object for the chemistry system you'll need to add something like this in + * its new proc: + * + * // Create a new datum, 100 is the maximum_volume of the new holder datum. + * var/datum/reagents/R = new/datum/reagents(100) + * reagents = R // Assign the new datum to the objects reagents var + * R.my_atom = src // set the holders my_atom to src so that we know where we are. + * + * This can also be done by calling a convenience proc e.g. + * /atom/proc/create_reagents(max_volume) + */ /datum/reagents + /// All contained reagents. More specifically, references to the reagent datums. var/list/datum/reagent/reagent_list = new/list() + /// The total volume of all reagents in this holder. var/total_volume = 0 + /// This is the maximum volume of the holder. var/maximum_volume = 100 + /// This is the atom the holder is 'in'. Useful if you need to find the location. (i.e. for explosions) var/atom/my_atom = null var/chem_temp = T20C var/temperature_min = 0 @@ -53,6 +73,11 @@ GLOB.chemical_reactions_list[id] += D break // Don't bother adding ourselves to other reagent ids, it is redundant. +/** + * Removes reagents from the holder until the passed amount is matched. + * + * It'll try to remove some of ALL reagents contained. + */ /datum/reagents/proc/remove_any(amount = 1) var/list/cached_reagents = reagent_list var/total_transfered = 0 @@ -124,7 +149,17 @@ return the_id -/datum/reagents/proc/trans_to(target, amount = 1, multiplier = 1, preserve_data = TRUE, no_react = FALSE) //if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred. +/** + * Equally transfer the contents of the holder to another objects holder. + * + * You need to pass it the object (not the holder) you want to transfer to and + * the amount you want to transfer. Its return value is the actual amount + * transfered (if one of the objects is full/empty). + * + * If `preserve_data = FALSE`, the reagents data will be lost. Useful if you use + * data for some strange stuff and don't want it to be transferred. + */ +/datum/reagents/proc/trans_to(target, amount = 1, multiplier = 1, preserve_data = TRUE, no_react = FALSE) if(!target) return if(total_volume <= 0) @@ -212,6 +247,12 @@ handle_reactions() +/** + * Same as [/datum/reagents/proc/trans_to] but only for a specific reagent in + * the reagent list. If the specified amount is greater than what is available, + * it will use the amount of the reagent that is available. If no reagent + * exists, returns null. + */ /datum/reagents/proc/trans_id_to(obj/target, reagent, amount = 1, preserve_data = TRUE) //Not sure why this proc didn't exist before. It does now! /N if(!target) return @@ -248,6 +289,9 @@ if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.dna.species.reagent_tag & PROCESS_DUO)) return TRUE +/** + * Called by `/mob/living/proc/Life`. You shouldn't have to use this one directly. + */ /datum/reagents/proc/metabolize(mob/living/M) if(M) temperature_reagents(M.bodytemperature - 30) @@ -346,6 +390,9 @@ var/datum/reagent/R = A R.on_mob_death(M) +/** + * Returns a list of all the chemical IDs in the reagent holder that are overdosing. + */ /datum/reagents/proc/overdose_list() var/od_chems[0] for(var/A in reagent_list) @@ -372,6 +419,14 @@ R.on_update(A) update_total() +/** + * Check all recipes and, on a match, uses them. + * + * It will also call the recipe's on_reaction proc (for explosions or w/e). + * Currently, this proc is automatically called by [/datum/reagents/proc/trans_to]. + * Modified from the original to preserve reagent data across reactions + * (originally for xenoarchaeology). + */ /datum/reagents/proc/handle_reactions() if(flags & REAGENT_NOREACT) return //Yup, no reactions here. No siree. @@ -468,6 +523,9 @@ update_total() return FALSE +/** + * Remove all reagents but the specified one. + */ /datum/reagents/proc/isolate_reagent(reagent) for(var/A in reagent_list) var/datum/reagent/R = A @@ -475,6 +533,9 @@ del_reagent(R.id) update_total() +/** + * Completely remove the reagent with the matching ID. + */ /datum/reagents/proc/del_reagent(reagent) var/list/cached_reagents = reagent_list for(var/A in cached_reagents) @@ -491,6 +552,9 @@ return FALSE return TRUE +/** + * Update the total volume of the holder (the volume of all reagents added together). + */ /datum/reagents/proc/update_total() total_volume = 0 for(var/A in reagent_list) @@ -501,6 +565,9 @@ total_volume += R.volume return FALSE +/** + * Remove all reagents from the holder. + */ /datum/reagents/proc/clear_reagents() for(var/A in reagent_list) var/datum/reagent/R = A @@ -526,6 +593,22 @@ can_process = TRUE return can_process +/** + * Calls the appropriate reaction procs of the reagents. + * + * I.e. if A is an object, it will call the reagent's reaction_obj + * proc. The method var is used for reaction on mobs. It simply tells + * us if the mob TOUCHed the reagent or if it INGESTed the reagent. + * + * Since the volume can be checked in a reagents proc, you might want to + * use the volume_modifier var to modifiy the passed value without actually + * changing the volume of the reagents. + * + * If you're not sure if you need to use this the answer is very most likely 'No'. + * + * You'll want to use this proc whenever an atom first comes in contact + * with the reagents of a holder. (in the 'splash' part of a beaker i.e.) + */ /datum/reagents/proc/reaction(atom/A, method = REAGENT_TOUCH, volume_modifier = 1, show_message = TRUE) var/react_type if(isliving(A)) @@ -583,6 +666,11 @@ var/amt = list_reagents[r_id] add_reagent(r_id, amt, data) +/** + * Attempts to add X of the matching reagent to the holder. + * + * You won't use this much. Mostly in new procs for pre-filled objects. + */ /datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = T20C, no_react = FALSE) if(!isnum(amount)) return TRUE @@ -637,6 +725,12 @@ add_reagent(reagent, add) return TRUE +/** + * The exact opposite of the add_reagent proc. + * + * Modified from original to return the reagent's data, in order to preserve + * reagent data across reactions (originally for xenoarchaeology). + */ /datum/reagents/proc/remove_reagent(reagent, amount, safety) //Added a safety check for the trans_id_to if(!isnum(amount)) return TRUE @@ -653,6 +747,11 @@ return FALSE return TRUE +/** + * Return whether the holder contains the reagent. + * + * If you pass it an amount it will additionally check if the amount is matched. + */ /datum/reagents/proc/has_reagent(reagent, amount = -1) for(var/A in reagent_list) var/datum/reagent/R = A @@ -666,6 +765,11 @@ return FALSE return FALSE +/** + * Returns the amount of the matching reagent inside the holder. + * + * Returns FALSE if the reagent is missing. + */ /datum/reagents/proc/get_reagent_amount(reagent) for(var/A in reagent_list) var/datum/reagent/R = A diff --git a/code/modules/reagents/chemistry/readme.dm b/code/modules/reagents/chemistry/readme.dm deleted file mode 100644 index ddcdb8a123e..00000000000 --- a/code/modules/reagents/chemistry/readme.dm +++ /dev/null @@ -1,241 +0,0 @@ -/* -NOTE: IF YOU UPDATE THE REAGENT-SYSTEM, ALSO UPDATE THIS README. - -Structure: /////////////////// ////////////////////////// - // Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents. - /////////////////// ////////////////////////// - | | - The object that holds everything. V - reagent_list var (list) A List of datums, each datum is a reagent. - - | | | - V V V - - reagents (datums) Reagents. I.e. Water , antitoxins or mercury. - - -Random important notes: - - An objects on_reagent_change will be called every time the objects reagents change. - Useful if you want to update the objects icon etc. - -About the Holder: - - The holder (reagents datum) is the datum that holds a list of all reagents - currently in the object.It also has all the procs needed to manipulate reagents - - remove_any(amount) - This proc removes reagents from the holder until the passed amount - is matched. It'll try to remove some of ALL reagents contained. - - trans_to(obj/target, amount) - This proc equally transfers the contents of the holder to another - objects holder. You need to pass it the object (not the holder) you want - to transfer to and the amount you want to transfer. Its return value is the - actual amount transfered (if one of the objects is full/empty) - - trans_id_to(obj/target, reagent, amount) - Same as above but only for a specific reagent in the reagent list. - If the specified amount is greater than what is available, it will use - the amount of the reagent that is available. If no reagent exists, returns null. - - metabolize(mob/living/M) - This proc is called by the mobs life proc. It simply calls on_mob_life for - all contained reagents. You shouldnt have to use this one directly. - - handle_reactions() - This proc check all recipes and, on a match, uses them. - It will also call the recipe's on_reaction proc (for explosions or w/e). - Currently, this proc is automatically called by trans_to. - - Modified from the original to preserve reagent data across reactions (originally for xenoarchaeology) - - isolate_reagent(reagent) - Pass it a reagent id and it will remove all reagents but that one. - It's that simple. - - del_reagent(reagent) - Completely remove the reagent with the matching id. - - update_total() - This one simply updates the total volume of the holder. - (the volume of all reagents added together) - - clear_reagents() - This proc removes ALL reagents from the holder. - - reaction(atom/A, method=TOUCH, volume_modifier=0) - This proc calls the appropriate reaction procs of the reagents. - I.e. if A is an object, it will call the reagents reaction_obj - proc. The method var is used for reaction on mobs. It simply tells - us if the mob TOUCHed the reagent or if it INGESTed the reagent. - Since the volume can be checked in a reagents proc, you might want to - use the volume_modifier var to modifiy the passed value without actually - changing the volume of the reagents. - If you're not sure if you need to use this the answer is very most likely 'No'. - You'll want to use this proc whenever an atom first comes in - contact with the reagents of a holder. (in the 'splash' part of a beaker i.e.) - More on the reaction in the reagent part of this readme. - - add_reagent(reagent, amount, data) - Attempts to add X of the matching reagent to the holder. - You wont use this much. Mostly in new procs for pre-filled - objects. - - remove_reagent(reagent, amount) - The exact opposite of the add_reagent proc. - - Modified from original to return the reagent's data, in order to preserve reagent data across reactions (originally for xenoarchaeology) - - has_reagent(reagent, amount) - Returns 1 if the holder contains this reagent. - Or 0 if not. - If you pass it an amount it will additionally check - if the amount is matched. This is optional. - - get_reagent_amount(reagent) - Returns the amount of the matching reagent inside the - holder. Returns 0 if the reagent is missing. - - overdose_list() - Returns a list of all the chemical IDs in the reagent holder that are overdosing - - Important variables: - - total_volume - This variable contains the total volume of all reagents in this holder. - - reagent_list - This is a list of all contained reagents. More specifically, references - to the reagent datums. - - maximum_volume - This is the maximum volume of the holder. - - my_atom - This is the atom the holder is 'in'. Useful if you need to find the location. - (i.e. for explosions) - - -About Reagents: - - Reagents are all the things you can mix and fille in bottles etc. This can be anything from - rejuvs over water to ... iron. Each reagent also has a few procs - i'll explain those below. - - reaction_mob(mob/living/M, method=TOUCH) - This is called by the holder's reation proc. - This version is only called when the reagent - reacts with a mob. The method var can be either - TOUCH or INGEST. You'll want to put stuff like - acid-facemelting in here. Should only ever be - called, directly, on living mobs. - - reaction_obj(obj/O) - This is called by the holder's reation proc. - This version is called when the reagents reacts - with an object. You'll want to put stuff like - object melting in here ... or something. i dunno. - - reaction_turf(turf/T) - This is called by the holder's reation proc. - This version is called when the reagents reacts - with a turf. You'll want to put stuff like extra - slippery floors for lube or something in here. - - on_mob_life(mob/living/M) - This proc is called everytime the mobs life proc executes. - This is the place where you put damage for toxins , - drowsyness for sleep toxins etc etc. - You'll want to call the parents proc by using ..() . - If you dont, the chemical will stay in the mob forever - - unless you write your own piece of code to slowly remove it. - (Should be pretty easy, 1 line of code) - - Important variables: - - holder - This variable contains a reference to the holder the chemical is 'in' - - volume - This is the volume of the reagent. - - id - The id of the reagent - - name - The name of the reagent. - - data - This var can be used for whatever the fuck you want.You could use this - for DNA in a blood reagent or ... well whatever you want. - - color - This is a hexadecimal color that represents the reagent outside of containers, - you define it as "#RRGGBB", or, red green blue. You can also define it using the - rgb() proc, which returns a hexadecimal value too. The color is black by default. - - A good website for color calculations: http://www.psyclops.com/tools/rgb/ - - - - -About Recipes: - - Recipes are simple datums that contain a list of required reagents and a result. - They also have a proc that is called when the recipe is matched. - - on_reaction(datum/reagents/holder, created_volume) - This proc is called when the recipe is matched. - You'll want to add explosions etc here. - To find the location you'll have to do something - like get_turf(holder.my_atom) - - name & id - Should be pretty obvious. - - result - This var contains the id of the resulting reagent. - - required_reagents - This is a list of ids of the required reagents. - Each id also needs an associated value that gives us the minimum required amount - of that reagent. The handle_reaction proc can detect mutiples of the same recipes - so for most cases you want to set the required amount to 1. - - required_catalysts (Added May 2011) - This is a list of the ids of the required catalysts. - Functionally similar to required_reagents, it is a list of reagents that are required - for the reaction. However, unlike required_reagents, catalysts are NOT consumed. - They mearly have to be present in the container. - - result_amount - This is the amount of the resulting reagent this recipe will produce. - I recommend you set this to the total volume of all required reagent. - - required_container - The container the recipe has to take place in in order to happen. Leave this blank/null - if you want the reaction to happen anywhere. - - required_other - Basically like a reagent's data variable. You can set extra requirements for a - reaction with this. - - -About the Tools: - - By default, all atom have a reagents var - but its empty. if you want to use an object for the chem. - system you'll need to add something like this in its new proc: - - var/datum/reagents/R = new/datum/reagents(100), <<< create a new datum, 100 is the maximum_volume of the new holder datum. - reagents = R, <<< assign the new datum to the objects reagents var - R.my_atom = src, <<< set the holders my_atom to src so that we know where we are. - - This can also be done by calling a convenience proc: - atom/proc/create_reagents(max_volume) - - Other important stuff: - - amount_per_transfer_from_this var - This var is mostly used by beakers and bottles. - It simply tells us how much to transfer when - 'pouring' our reagents into something else. - -*/ diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 3ee7cc3e226..cda47f9b9ea 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -2,11 +2,13 @@ var/name = "Reagent" var/id = "reagent" var/description = "" + /// A reference to the holder the chemical is 'in'. var/datum/reagents/holder = null var/reagent_state = SOLID var/list/data = null var/volume = 0 var/metabolization_rate = REAGENTS_METABOLISM + /// The color of the agent outside of containers. var/color = "#000000" // rgb: 0, 0, 0 (does not support alpha channels - yet!) var/shock_reduction = 0 var/heart_rate_increase = 0 @@ -45,7 +47,15 @@ /datum/reagent/proc/reaction_temperature(exposed_temperature, exposed_volume) //By default we do nothing. return -/datum/reagent/proc/reaction_mob(mob/living/M, method = REAGENT_TOUCH, volume, show_message = TRUE) //Some reagents transfer on touch, others don't; dependent on if they penetrate the skin or not. +/** + * React with a mob. + * + * The method var can be either `REAGENT_TOUCH` or `REAGENT_INGEST`. Some + * reagents transfer on touch, others don't; dependent on if they penetrate the + * skin or not. You'll want to put stuff like acid-facemelting in here. Should + * only ever be called, directly, on living mobs. + */ +/datum/reagent/proc/reaction_mob(mob/living/M, method = REAGENT_TOUCH, volume, show_message = TRUE) if(!holder) //for catching rare runtimes return if(method == REAGENT_TOUCH && penetrates_skin) @@ -73,9 +83,17 @@ // This one only matters if the mob is dead. M.absorb_blood() +/** + * React with an object. + */ /datum/reagent/proc/reaction_obj(obj/O, volume) return +/** + * React with a turf. + * + * You'll want to put stuff like extra slippery floors for lube or something in here. + */ /datum/reagent/proc/reaction_turf(turf/T, volume, color) return diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 9b98a849032..3a759640931 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -3,13 +3,26 @@ var/name = null var/id = null var/result = null + /// A list of IDs of the required reagents. + /// + /// Each ID also needs an associated value that gives us the minimum + /// required amount / of that reagent. The handle_reaction proc can detect + /// mutiples of the same recipes / so for most cases you want to set the + /// required amount to 1. var/list/required_reagents = list() var/list/required_catalysts = list() - // Both of these variables are mostly going to be used with slime cores - but if you want to, you can use them for other things - var/atom/required_container = null // the container required for the reaction to happen - var/required_other = FALSE // extra requirements for the reaction to happen + // Both of these variables are mostly going to be used with slime cores + // but if you want to, you can use them for other things + /// The container required for the reaction to happen. + /// Leave this null if you want the reaction to happen anywhere. + var/atom/required_container = null + /// Extra requirements for the reaction to happen. + var/required_other = FALSE + + /// This is the amount of the resulting reagent this recipe will produce. + /// It's recommended you set this to the total volume of all required reagents. var/result_amount = 0 var/list/secondary_results = list() //additional reagents produced by the reaction var/min_temp = 0 //Minimum temperature required for the reaction to occur (heat to/above this). min_temp = 0 means no requirement diff --git a/paradise.dme b/paradise.dme index 5f26b7203c4..92cd3cae6a4 100644 --- a/paradise.dme +++ b/paradise.dme @@ -2371,7 +2371,6 @@ #include "code\modules\reagents\reagent_dispenser.dm" #include "code\modules\reagents\chemistry\colors.dm" #include "code\modules\reagents\chemistry\holder.dm" -#include "code\modules\reagents\chemistry\readme.dm" #include "code\modules\reagents\chemistry\reagents.dm" #include "code\modules\reagents\chemistry\recipes.dm" #include "code\modules\reagents\chemistry\machinery\chem_dispenser.dm"