diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm index 0976ed5ea3..f1de2ddd45 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -49,3 +49,11 @@ var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglyce var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate. var/list/heartstopper = list("potassium_chlorophoride", "zombie_powder") // This stops the heart. var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional + +#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites +#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites +#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once +#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill +#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch +#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume) +#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever \ No newline at end of file diff --git a/code/controllers/subsystems/chemistry.dm b/code/controllers/subsystems/chemistry.dm new file mode 100644 index 0000000000..148e975542 --- /dev/null +++ b/code/controllers/subsystems/chemistry.dm @@ -0,0 +1,58 @@ +SUBSYSTEM_DEF(chemistry) + name = "Chemistry" + wait = 20 + flags = SS_NO_FIRE + init_order = INIT_ORDER_CHEMISTRY + + var/list/chemical_reactions = list() + var/list/instant_reactions_by_reagent = list() + var/list/distilled_reactions_by_reagent = list() +// var/list/fusion_reactions_by_reagent = list() // TODO: Fusion reactions as chemical reactions + var/list/chemical_reagents = list() + +/datum/controller/subsystem/chemistry/Recover() + log_debug("[name] subsystem Recover().") + chemical_reactions = SSchemistry.chemical_reactions + chemical_reagents = SSchemistry.chemical_reagents + +/datum/controller/subsystem/chemistry/Initialize() + initialize_chemical_reagents() + initialize_chemical_reactions() + ..() + +/datum/controller/subsystem/chemistry/stat_entry() + ..("C: [chemical_reagents.len] | R: [chemical_reactions.len]") + +//Chemical Reactions - Initialises all /decl/chemical_reaction into a list +// It is filtered into multiple lists within a list. +// For example: +// chemical_reactions_by_reagent["phoron"] is a list of all reactions relating to phoron +// Note that entries in the list are NOT duplicated. So if a reaction pertains to +// more than one chemical it will still only appear in only one of the sublists. +/datum/controller/subsystem/chemistry/proc/initialize_chemical_reactions() + var/list/paths = decls_repository.get_decls_of_subtype(/decl/chemical_reaction) + + for(var/path in paths) + var/decl/chemical_reaction/D = paths[path] + chemical_reactions += D + if(D.required_reagents && D.required_reagents.len) + var/reagent_id = D.required_reagents[1] + + var/list/add_to = instant_reactions_by_reagent // Default to instant reactions list, if something's gone wrong +// if(istype(D, /decl/chemical_reaction/fusion)) // TODO: fusion reactions as chemical reactions +// add_to = fusion_reactions_by_reagent + if(istype(D, /decl/chemical_reaction/distilling)) + add_to = distilled_reactions_by_reagent + + LAZYINITLIST(add_to[reagent_id]) + add_to[reagent_id] += D + +//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id +/datum/controller/subsystem/chemistry/proc/initialize_chemical_reagents() + var/paths = subtypesof(/datum/reagent) + chemical_reagents = list() + for(var/path in paths) + var/datum/reagent/D = new path() + if(!D.name) + continue + chemical_reagents[D.id] = D diff --git a/code/controllers/subsystems/processing/chemistry.dm b/code/controllers/subsystems/processing/chemistry.dm deleted file mode 100644 index b4641ba7e0..0000000000 --- a/code/controllers/subsystems/processing/chemistry.dm +++ /dev/null @@ -1,54 +0,0 @@ -PROCESSING_SUBSYSTEM_DEF(chemistry) - name = "Chemistry" - wait = 20 - flags = SS_BACKGROUND|SS_POST_FIRE_TIMING - init_order = INIT_ORDER_CHEMISTRY - var/list/chemical_reactions = list() - var/list/chemical_reactions_by_reagent = list() - var/list/chemical_reagents = list() - -/datum/controller/subsystem/processing/chemistry/Recover() - log_debug("[name] subsystem Recover().") - if(SSchemistry.current_thing) - log_debug("current_thing was: (\ref[SSchemistry.current_thing])[SSchemistry.current_thing]([SSchemistry.current_thing.type]) - currentrun: [SSchemistry.currentrun.len] vs total: [SSchemistry.processing.len]") - var/list/old_processing = SSchemistry.processing.Copy() - for(var/datum/D in old_processing) - if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING)) - processing |= D - - chemical_reactions = SSchemistry.chemical_reactions - chemical_reagents = SSchemistry.chemical_reagents - -/datum/controller/subsystem/processing/chemistry/Initialize() - initialize_chemical_reactions() - initialize_chemical_reagents() - ..() - -//Chemical Reactions - Initialises all /datum/chemical_reaction into a list -// It is filtered into multiple lists within a list. -// For example: -// chemical_reaction_list["phoron"] is a list of all reactions relating to phoron -// Note that entries in the list are NOT duplicated. So if a reaction pertains to -// more than one chemical it will still only appear in only one of the sublists. -/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reactions() - var/paths = typesof(/datum/chemical_reaction) - /datum/chemical_reaction - chemical_reactions = list() - chemical_reactions_by_reagent = list() - - for(var/path in paths) - var/datum/chemical_reaction/D = new path - chemical_reactions += D - if(D.required_reagents && D.required_reagents.len) - var/reagent_id = D.required_reagents[1] - LAZYINITLIST(chemical_reactions_by_reagent[reagent_id]) - chemical_reactions_by_reagent[reagent_id] += D - -//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id -/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reagents() - var/paths = typesof(/datum/reagent) - /datum/reagent - chemical_reagents = list() - for(var/path in paths) - var/datum/reagent/D = new path() - if(!D.name) - continue - chemical_reagents[D.id] = D diff --git a/code/modules/blob2/core_chunk.dm b/code/modules/blob2/core_chunk.dm index 4abc06843e..15db91e89e 100644 --- a/code/modules/blob2/core_chunk.dm +++ b/code/modules/blob2/core_chunk.dm @@ -118,19 +118,19 @@ return FALSE -/datum/chemical_reaction/blob_reconstitution +/decl/chemical_reaction/instant/blob_reconstitution name = "Hostile Blob Revival" id = "blob_revival" result = null required_reagents = list("phoron" = 60) result_amount = 1 -/datum/chemical_reaction/blob_reconstitution/can_happen(var/datum/reagents/holder) +/decl/chemical_reaction/instant/blob_reconstitution/can_happen(var/datum/reagents/holder) if(holder.my_atom && istype(holder.my_atom, /obj/item/weapon/blobcore_chunk)) return ..() return FALSE -/datum/chemical_reaction/blob_reconstitution/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/blob_reconstitution/on_reaction(var/datum/reagents/holder) var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom if(chunk.can_genesis && chunk.regen()) chunk.visible_message("[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!") @@ -138,14 +138,14 @@ else chunk.visible_message("[chunk] shifts strangely, but falls still.") -/datum/chemical_reaction/blob_reconstitution/domination +/decl/chemical_reaction/instant/blob_reconstitution/domination name = "Allied Blob Revival" id = "blob_friend" result = null required_reagents = list("hydrophoron" = 40, "peridaxon" = 20, "mutagen" = 20) result_amount = 1 -/datum/chemical_reaction/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder) var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom if(chunk.can_genesis && chunk.regen("neutral")) chunk.visible_message("[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!") diff --git a/code/modules/economy/price_list.dm b/code/modules/economy/price_list.dm index 9e3fb438d8..839148ebaf 100644 --- a/code/modules/economy/price_list.dm +++ b/code/modules/economy/price_list.dm @@ -13,7 +13,7 @@ //---Beverages---// //***************// -/datum/reagent/var/price_tag = null +/datum/reagent/var/price_tag = 0 // Juices, soda and similar // diff --git a/code/modules/food/recipe_dump.dm b/code/modules/food/recipe_dump.dm index df0e6874aa..63dc510eb9 100644 --- a/code/modules/food/recipe_dump.dm +++ b/code/modules/food/recipe_dump.dm @@ -8,13 +8,11 @@ //////////////////////// DRINK var/list/drink_recipes = list() - for(var/path in typesof(/datum/chemical_reaction/drinks) - /datum/chemical_reaction/drinks) - var/datum/chemical_reaction/drinks/CR = new path() - drink_recipes[path] = list("Result" = CR.name, + for(var/decl/chemical_reaction/instant/drinks/CR in SSchemistry.chemical_reactions) + drink_recipes[CR.type] = list("Result" = CR.name, "ResAmt" = CR.result_amount, "Reagents" = CR.required_reagents, "Catalysts" = CR.catalysts) - qdel(CR) //////////////////////// FOOD var/list/food_recipes = typesof(/datum/recipe) - /datum/recipe @@ -43,16 +41,14 @@ qdel(R) //////////////////////// FOOD+ (basically condiments, tofu, cheese, soysauce, etc) - for(var/path in typesof(/datum/chemical_reaction/food) - /datum/chemical_reaction/food) - var/datum/chemical_reaction/food/CR = new path() - food_recipes[path] = list("Result" = CR.name, + for(var/decl/chemical_reaction/instant/food/CR in SSchemistry.chemical_reactions) + food_recipes[CR.type] = list("Result" = CR.name, "ResAmt" = CR.result_amount, "Reagents" = CR.required_reagents, "Catalysts" = CR.catalysts, "Fruit" = list(), "Ingredients" = list(), "Image" = null) - qdel(CR) //////////////////////// PROCESSING //Items needs further processing into human-readability. diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index f822dc274b..e3e34474b5 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -272,19 +272,19 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain) qdel(src) return 1 -/datum/chemical_reaction/promethean_brain_revival +/decl/chemical_reaction/instant/promethean_brain_revival name = "Promethean Revival" id = "prom_revival" result = null required_reagents = list("phoron" = 40) result_amount = 1 -/datum/chemical_reaction/promethean_brain_revival/can_happen(var/datum/reagents/holder) +/decl/chemical_reaction/instant/promethean_brain_revival/can_happen(var/datum/reagents/holder) if(holder.my_atom && istype(holder.my_atom, /obj/item/organ/internal/brain/slime)) return ..() return FALSE -/datum/chemical_reaction/promethean_brain_revival/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/promethean_brain_revival/on_reaction(var/datum/reagents/holder) var/obj/item/organ/internal/brain/slime/brain = holder.my_atom if(brain.reviveBody()) brain.visible_message("[brain] bubbles, surrounding itself with a rapidly expanding mass of slime!") diff --git a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm index 91c08513a5..89b11da6c1 100644 --- a/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm +++ b/code/modules/power/fusion/fuel_assembly/fuel_compressor.dm @@ -1,3 +1,4 @@ +#define FUSION_ROD_SHEET_AMT 15 /obj/machinery/fusion_fuel_compressor name = "fuel compressor" icon = 'icons/obj/machines/power/fusion.dmi' @@ -53,15 +54,17 @@ if(!mat.is_fusion_fuel) to_chat(user, "It would be pointless to make a fuel rod out of [mat.use_name].") return - if(M.get_amount() < 15) + if(M.get_amount() < FUSION_ROD_SHEET_AMT) to_chat(user, "You need at least 25 [mat.sheet_plural_name] to make a fuel rod.") return var/obj/item/weapon/fuel_assembly/F = new(get_turf(src), mat.name) visible_message("\The [src] compresses the [mat.use_name] into a new fuel assembly.") - M.use(15) + M.use(FUSION_ROD_SHEET_AMT) user.put_in_hands(F) else if(do_special_fuel_compression(thing, user)) return - return ..() \ No newline at end of file + return ..() + +#undef FUSION_ROD_SHEET_AMT \ No newline at end of file diff --git a/code/modules/power/fusion/fusion_reagents.dm b/code/modules/power/fusion/fusion_reagents.dm deleted file mode 100644 index 80b1cbb336..0000000000 --- a/code/modules/power/fusion/fusion_reagents.dm +++ /dev/null @@ -1,18 +0,0 @@ -//Additional fusion reagents. These likely don't have any other use aside from the RUST, but if you want to make stuff with 'em, be my guest. - -/datum/reagent/helium3 - name = "helium-3" - description = "A colorless, odorless, tasteless and generally inert gas used in fusion reactors. Non-radioactive." - id = "helium-3" - reagent_state = GAS - color = "#808080" - -/obj/structure/reagent_dispensers/he3 - name = "fueltank" - desc = "A fueltank." - icon = 'icons/obj/objects.dmi' - icon_state = "weldtank" - amount_per_transfer_from_this = 10 - New() - ..() - reagents.add_reagent("helium-3",1000) \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Logging.dm b/code/modules/reagents/Chemistry-Logging.dm index cccf37bb6f..4c7b2343ad 100644 --- a/code/modules/reagents/Chemistry-Logging.dm +++ b/code/modules/reagents/Chemistry-Logging.dm @@ -1,7 +1,7 @@ /var/list/chemical_reaction_logs = list() -/proc/log_chemical_reaction(atom/A, datum/chemical_reaction/R, multiplier) +/proc/log_chemical_reaction(atom/A, decl/chemical_reaction/R, multiplier) if(!A || !R) return diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm deleted file mode 100644 index f2f00ac350..0000000000 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ /dev/null @@ -1,2667 +0,0 @@ -//helper that ensures the reaction rate holds after iterating -//Ex. REACTION_RATE(0.3) means that 30% of the reagents will react each chemistry tick (~2 seconds by default). -#define REACTION_RATE(rate) (1.0 - (1.0-rate)**(1.0/PROCESS_REACTION_ITER)) - -//helper to define reaction rate in terms of half-life -//Ex. -//HALF_LIFE(0) -> Reaction completes immediately (default chems) -//HALF_LIFE(1) -> Half of the reagents react immediately, the rest over the following ticks. -//HALF_LIFE(2) -> Half of the reagents are consumed after 2 chemistry ticks. -//HALF_LIFE(3) -> Half of the reagents are consumed after 3 chemistry ticks. -#define HALF_LIFE(ticks) (ticks? 1.0 - (0.5)**(1.0/(ticks*PROCESS_REACTION_ITER)) : 1.0) - -/datum/chemical_reaction - var/name = null - var/id = null - var/result = null - var/list/required_reagents = list() - var/list/catalysts = list() - var/list/inhibitors = list() - var/result_amount = 0 - - //how far the reaction proceeds each time it is processed. Used with either REACTION_RATE or HALF_LIFE macros. - var/reaction_rate = HALF_LIFE(0) - - //if less than 1, the reaction will be inhibited if the ratio of products/reagents is too high. - //0.5 = 50% yield -> reaction will only proceed halfway until products are removed. - var/yield = 1.0 - - //If limits on reaction rate would leave less than this amount of any reagent (adjusted by the reaction ratios), - //the reaction goes to completion. This is to prevent reactions from going on forever with tiny reagent amounts. - var/min_reaction = 2 - - var/mix_message = "The solution begins to bubble." - var/reaction_sound = 'sound/effects/bubbles.ogg' - - var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file. - -/datum/chemical_reaction/proc/can_happen(var/datum/reagents/holder) - //check that all the required reagents are present - if(!holder.has_all_reagents(required_reagents)) - return 0 - - //check that all the required catalysts are present in the required amount - if(!holder.has_all_reagents(catalysts)) - return 0 - - //check that none of the inhibitors are present in the required amount - if(holder.has_any_reagent(inhibitors)) - return 0 - - return 1 - -/datum/chemical_reaction/proc/calc_reaction_progress(var/datum/reagents/holder, var/reaction_limit) - var/progress = reaction_limit * reaction_rate //simple exponential progression - - //calculate yield - if(1-yield > 0.001) //if yield ratio is big enough just assume it goes to completion - /* - Determine the max amount of product by applying the yield condition: - (max_product/result_amount) / reaction_limit == yield/(1-yield) - - We make use of the fact that: - reaction_limit = (holder.get_reagent_amount(reactant) / required_reagents[reactant]) of the limiting reagent. - */ - var/yield_ratio = yield/(1-yield) - var/max_product = yield_ratio * reaction_limit * result_amount //rearrange to obtain max_product - var/yield_limit = max(0, max_product - holder.get_reagent_amount(result))/result_amount - - progress = min(progress, yield_limit) //apply yield limit - - //apply min reaction progress - wasn't sure if this should go before or after applying yield - //I guess people can just have their miniscule reactions go to completion regardless of yield. - for(var/reactant in required_reagents) - var/remainder = holder.get_reagent_amount(reactant) - progress*required_reagents[reactant] - if(remainder <= min_reaction*required_reagents[reactant]) - progress = reaction_limit - break - - return progress - -/datum/chemical_reaction/process(var/datum/reagents/holder) - //determine how far the reaction can proceed - var/list/reaction_limits = list() - for(var/reactant in required_reagents) - reaction_limits += holder.get_reagent_amount(reactant) / required_reagents[reactant] - - //determine how far the reaction proceeds - var/reaction_limit = min(reaction_limits) - var/progress_limit = calc_reaction_progress(holder, reaction_limit) - - var/reaction_progress = min(reaction_limit, progress_limit) //no matter what, the reaction progress cannot exceed the stoichiometric limit. - - //need to obtain the new reagent's data before anything is altered - var/data = send_data(holder, reaction_progress) - - //remove the reactants - for(var/reactant in required_reagents) - var/amt_used = required_reagents[reactant] * reaction_progress - holder.remove_reagent(reactant, amt_used, safety = 1) - - //add the product - var/amt_produced = result_amount * reaction_progress - if(result) - holder.add_reagent(result, amt_produced, data, safety = 1) - - on_reaction(holder, amt_produced) - - return reaction_progress - -//called when a reaction processes -/datum/chemical_reaction/proc/on_reaction(var/datum/reagents/holder, var/created_volume) - return - -//called after processing reactions, if they occurred -/datum/chemical_reaction/proc/post_reaction(var/datum/reagents/holder) - var/atom/container = holder.my_atom - if(mix_message && container && !ismob(container)) - var/turf/T = get_turf(container) - var/list/seen = viewers(4, T) - for(var/mob/M in seen) - M.show_message("[bicon(container)] [mix_message]", 1) - playsound(T, reaction_sound, 80, 1) - -//obtains any special data that will be provided to the reaction products -//this is called just before reactants are removed. -/datum/chemical_reaction/proc/send_data(var/datum/reagents/holder, var/reaction_limit) - return null - -/* Common reactions */ - -/datum/chemical_reaction/inaprovaline - name = "Inaprovaline" - id = "inaprovaline" - result = "inaprovaline" - required_reagents = list("oxygen" = 1, "carbon" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/dylovene - name = "Dylovene" - id = "anti_toxin" - result = "anti_toxin" - required_reagents = list("silicon" = 1, "potassium" = 1, "nitrogen" = 1) - result_amount = 3 - -/datum/chemical_reaction/carthatoline - name = "Carthatoline" - id = "carthatoline" - result = "carthatoline" - required_reagents = list("anti_toxin" = 1, "carbon" = 2, "phoron" = 0.1) - catalysts = list("phoron" = 1) - result_amount = 2 - -/datum/chemical_reaction/paracetamol - name = "Paracetamol" - id = "paracetamol" - result = "paracetamol" - required_reagents = list("inaprovaline" = 1, "nitrogen" = 1, "water" = 1) - result_amount = 2 - -/datum/chemical_reaction/tramadol - name = "Tramadol" - id = "tramadol" - result = "tramadol" - required_reagents = list("paracetamol" = 1, "ethanol" = 1, "oxygen" = 1) - result_amount = 3 - -/datum/chemical_reaction/oxycodone - name = "Oxycodone" - id = "oxycodone" - result = "oxycodone" - required_reagents = list("ethanol" = 1, "tramadol" = 1) - catalysts = list("phoron" = 5) - result_amount = 1 - -/datum/chemical_reaction/sterilizine - name = "Sterilizine" - id = "sterilizine" - result = "sterilizine" - required_reagents = list("ethanol" = 1, "anti_toxin" = 1, "chlorine" = 1) - result_amount = 3 - -/datum/chemical_reaction/silicate - name = "Silicate" - id = "silicate" - result = "silicate" - required_reagents = list("aluminum" = 1, "silicon" = 1, "oxygen" = 1) - result_amount = 3 - -/datum/chemical_reaction/mutagen - name = "Unstable mutagen" - id = "mutagen" - result = "mutagen" - required_reagents = list("radium" = 1, "phosphorus" = 1, "chlorine" = 1) - result_amount = 3 - -/datum/chemical_reaction/water - name = "Water" - id = "water" - result = "water" - required_reagents = list("oxygen" = 1, "hydrogen" = 2) - result_amount = 1 - -/datum/chemical_reaction/thermite - name = "Thermite" - id = "thermite" - result = "thermite" - required_reagents = list("aluminum" = 1, "iron" = 1, "oxygen" = 1) - result_amount = 3 - -/datum/chemical_reaction/space_drugs - name = "Space Drugs" - id = "space_drugs" - result = "space_drugs" - required_reagents = list("mercury" = 1, "sugar" = 1, "lithium" = 1) - result_amount = 3 - -/datum/chemical_reaction/lube - name = "Space Lube" - id = "lube" - result = "lube" - required_reagents = list("water" = 1, "silicon" = 1, "oxygen" = 1) - result_amount = 4 - -/datum/chemical_reaction/pacid - name = "Polytrinic acid" - id = "pacid" - result = "pacid" - required_reagents = list("sacid" = 1, "chlorine" = 1, "potassium" = 1) - result_amount = 3 - -/datum/chemical_reaction/synaptizine - name = "Synaptizine" - id = "synaptizine" - result = "synaptizine" - required_reagents = list("sugar" = 1, "lithium" = 1, "water" = 1) - result_amount = 3 - -/datum/chemical_reaction/hyronalin - name = "Hyronalin" - id = "hyronalin" - result = "hyronalin" - required_reagents = list("radium" = 1, "anti_toxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/arithrazine - name = "Arithrazine" - id = "arithrazine" - result = "arithrazine" - required_reagents = list("hyronalin" = 1, "hydrogen" = 1) - result_amount = 2 - -/datum/chemical_reaction/impedrezene - name = "Impedrezene" - id = "impedrezene" - result = "impedrezene" - required_reagents = list("mercury" = 1, "oxygen" = 1, "sugar" = 1) - result_amount = 2 - -/datum/chemical_reaction/kelotane - name = "Kelotane" - id = "kelotane" - result = "kelotane" - required_reagents = list("silicon" = 1, "carbon" = 1) - result_amount = 2 - log_is_important = 1 - -/datum/chemical_reaction/peridaxon - name = "Peridaxon" - id = "peridaxon" - result = "peridaxon" - required_reagents = list("bicaridine" = 2, "clonexadone" = 2) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/osteodaxon - name = "Osteodaxon" - id = "osteodaxon" - result = "osteodaxon" - required_reagents = list("bicaridine" = 2, "phoron" = 0.1, "carpotoxin" = 1) - catalysts = list("phoron" = 5) - inhibitors = list("clonexadone" = 1) // Messes with cryox - result_amount = 2 - -/datum/chemical_reaction/respirodaxon - name = "Respirodaxon" - id = "respirodaxon" - result = "respirodaxon" - required_reagents = list("dexalinp" = 2, "biomass" = 2, "phoron" = 1) - catalysts = list("phoron" = 5) - inhibitors = list("dexalin" = 1) - result_amount = 2 - -/datum/chemical_reaction/gastirodaxon - name = "Gastirodaxon" - id = "gastirodaxon" - result = "gastirodaxon" - required_reagents = list("carthatoline" = 1, "biomass" = 2, "tungsten" = 2) - catalysts = list("phoron" = 5) - inhibitors = list("lithium" = 1) - result_amount = 3 - -/datum/chemical_reaction/hepanephrodaxon - name = "Hepanephrodaxon" - id = "hepanephrodaxon" - result = "hepanephrodaxon" - required_reagents = list("carthatoline" = 2, "biomass" = 2, "lithium" = 1) - catalysts = list("phoron" = 5) - inhibitors = list("tungsten" = 1) - result_amount = 2 - -/datum/chemical_reaction/cordradaxon - name = "Cordradaxon" - id = "cordradaxon" - result = "cordradaxon" - required_reagents = list("potassium_chlorophoride" = 1, "biomass" = 2, "bicaridine" = 2) - catalysts = list("phoron" = 5) - inhibitors = list("clonexadone" = 1) - result_amount = 2 - -/datum/chemical_reaction/virus_food - name = "Virus Food" - id = "virusfood" - result = "virusfood" - required_reagents = list("water" = 1, "milk" = 1) - result_amount = 5 - -/datum/chemical_reaction/leporazine - name = "Leporazine" - id = "leporazine" - result = "leporazine" - required_reagents = list("silicon" = 1, "copper" = 1) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/cryptobiolin - name = "Cryptobiolin" - id = "cryptobiolin" - result = "cryptobiolin" - required_reagents = list("potassium" = 1, "oxygen" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/tricordrazine - name = "Tricordrazine" - id = "tricordrazine" - result = "tricordrazine" - required_reagents = list("inaprovaline" = 1, "anti_toxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/alkysine - name = "Alkysine" - id = "alkysine" - result = "alkysine" - required_reagents = list("chlorine" = 1, "nitrogen" = 1, "anti_toxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/dexalin - name = "Dexalin" - id = "dexalin" - result = "dexalin" - required_reagents = list("oxygen" = 2, "phoron" = 0.1) - catalysts = list("phoron" = 1) - inhibitors = list("water" = 1) // Messes with cryox - result_amount = 1 - -/datum/chemical_reaction/dermaline - name = "Dermaline" - id = "dermaline" - result = "dermaline" - required_reagents = list("oxygen" = 1, "phosphorus" = 1, "kelotane" = 1) - result_amount = 3 - -/datum/chemical_reaction/dexalinp - name = "Dexalin Plus" - id = "dexalinp" - result = "dexalinp" - required_reagents = list("dexalin" = 1, "carbon" = 1, "iron" = 1) - result_amount = 3 - -/datum/chemical_reaction/bicaridine - name = "Bicaridine" - id = "bicaridine" - result = "bicaridine" - required_reagents = list("inaprovaline" = 1, "carbon" = 1) - inhibitors = list("sugar" = 1) // Messes up with inaprovaline - result_amount = 2 - -/datum/chemical_reaction/myelamine - name = "Myelamine" - id = "myelamine" - result = "myelamine" - required_reagents = list("bicaridine" = 1, "iron" = 2, "spidertoxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/hyperzine - name = "Hyperzine" - id = "hyperzine" - result = "hyperzine" - required_reagents = list("sugar" = 1, "phosphorus" = 1, "sulfur" = 1) - result_amount = 3 - -/datum/chemical_reaction/stimm - name = "Stimm" - id = "stimm" - result = "stimm" - required_reagents = list("left4zed" = 1, "fuel" = 1) - catalysts = list("fuel" = 5) - result_amount = 2 - -/datum/chemical_reaction/ryetalyn - name = "Ryetalyn" - id = "ryetalyn" - result = "ryetalyn" - required_reagents = list("arithrazine" = 1, "carbon" = 1) - result_amount = 2 - -/datum/chemical_reaction/cryoxadone - name = "Cryoxadone" - id = "cryoxadone" - result = "cryoxadone" - required_reagents = list("dexalin" = 1, "water" = 1, "oxygen" = 1) - result_amount = 3 - -/datum/chemical_reaction/clonexadone - name = "Clonexadone" - id = "clonexadone" - result = "clonexadone" - required_reagents = list("cryoxadone" = 1, "sodium" = 1, "phoron" = 0.1) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/mortiferin - name = "Mortiferin" - id = "mortiferin" - result = "mortiferin" - required_reagents = list("cryptobiolin" = 1, "clonexadone" = 1, "corophizine" = 1) - result_amount = 2 - catalysts = list("phoron" = 5) - -/datum/chemical_reaction/spaceacillin - name = "Spaceacillin" - id = "spaceacillin" - result = "spaceacillin" - required_reagents = list("cryptobiolin" = 1, "inaprovaline" = 1) - result_amount = 2 - -/datum/chemical_reaction/corophizine - name = "Corophizine" - id = "corophizine" - result = "corophizine" - required_reagents = list("spaceacillin" = 1, "carbon" = 1, "phoron" = 0.1) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/immunosuprizine - name = "Immunosuprizine" - id = "immunosuprizine" - result = "immunosuprizine" - required_reagents = list("corophizine" = 1, "tungsten" = 1, "sacid" = 1) - catalysts = list("phoron" = 5) - result_amount = 2 - -/datum/chemical_reaction/imidazoline - name = "imidazoline" - id = "imidazoline" - result = "imidazoline" - required_reagents = list("carbon" = 1, "hydrogen" = 1, "anti_toxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/ethylredoxrazine - name = "Ethylredoxrazine" - id = "ethylredoxrazine" - result = "ethylredoxrazine" - required_reagents = list("oxygen" = 1, "anti_toxin" = 1, "carbon" = 1) - result_amount = 3 - -/datum/chemical_reaction/calciumcarbonate - name = "Calcium Carbonate" - id = "calciumcarbonate" - result = "calciumcarbonate" - required_reagents = list("oxygen" = 3, "calcium" = 1, "carbon" = 1) - result_amount = 2 - -/datum/chemical_reaction/soporific - name = "Soporific" - id = "stoxin" - result = "stoxin" - required_reagents = list("chloralhydrate" = 1, "sugar" = 4) - inhibitors = list("phosphorus") // Messes with the smoke - result_amount = 5 - -/datum/chemical_reaction/chloralhydrate - name = "Chloral Hydrate" - id = "chloralhydrate" - result = "chloralhydrate" - required_reagents = list("ethanol" = 1, "chlorine" = 3, "water" = 1) - result_amount = 1 - -/datum/chemical_reaction/potassium_chloride - name = "Potassium Chloride" - id = "potassium_chloride" - result = "potassium_chloride" - required_reagents = list("sodiumchloride" = 1, "potassium" = 1) - result_amount = 2 - -/datum/chemical_reaction/potassium_chlorophoride - name = "Potassium Chlorophoride" - id = "potassium_chlorophoride" - result = "potassium_chlorophoride" - required_reagents = list("potassium_chloride" = 1, "phoron" = 1, "chloralhydrate" = 1) - result_amount = 4 - -/datum/chemical_reaction/zombiepowder - name = "Zombie Powder" - id = "zombiepowder" - result = "zombiepowder" - required_reagents = list("carpotoxin" = 5, "stoxin" = 5, "copper" = 5) - result_amount = 2 - -/datum/chemical_reaction/carpotoxin - name = "Carpotoxin" - id = "carpotoxin" - result = "carpotoxin" - required_reagents = list("spidertoxin" = 2, "biomass" = 1, "sifsap" = 2) - catalysts = list("sifsap" = 10) - inhibitors = list("radium" = 1) - result_amount = 2 - -/datum/chemical_reaction/mindbreaker - name = "Mindbreaker Toxin" - id = "mindbreaker" - result = "mindbreaker" - required_reagents = list("silicon" = 1, "hydrogen" = 1, "anti_toxin" = 1) - result_amount = 3 - -/datum/chemical_reaction/lipozine - name = "Lipozine" - id = "Lipozine" - result = "lipozine" - required_reagents = list("sodiumchloride" = 1, "ethanol" = 1, "radium" = 1) - result_amount = 3 - -/datum/chemical_reaction/surfactant - name = "Foam surfactant" - id = "foam surfactant" - result = "fluorosurfactant" - required_reagents = list("fluorine" = 2, "carbon" = 2, "sacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/ammonia - name = "Ammonia" - id = "ammonia" - result = "ammonia" - required_reagents = list("hydrogen" = 3, "nitrogen" = 1) - inhibitors = list("phoron" = 1) // Messes with lexorin - result_amount = 3 - -/datum/chemical_reaction/diethylamine - name = "Diethylamine" - id = "diethylamine" - result = "diethylamine" - required_reagents = list ("ammonia" = 1, "ethanol" = 1) - result_amount = 2 - -/datum/chemical_reaction/left4zed - name = "Left4Zed" - id = "left4zed" - result = "left4zed" - required_reagents = list ("diethylamine" = 2, "mutagen" = 1) - result_amount = 3 - -/datum/chemical_reaction/robustharvest - name = "RobustHarvest" - id = "robustharvest" - result = "robustharvest" - required_reagents = list ("ammonia" = 1, "calcium" = 1, "neurotoxic_protein" = 1) - result_amount = 3 - -/datum/chemical_reaction/space_cleaner - name = "Space cleaner" - id = "cleaner" - result = "cleaner" - required_reagents = list("ammonia" = 1, "water" = 1) - result_amount = 2 - -/datum/chemical_reaction/plantbgone - name = "Plant-B-Gone" - id = "plantbgone" - result = "plantbgone" - required_reagents = list("toxin" = 1, "water" = 4) - result_amount = 5 - -/datum/chemical_reaction/foaming_agent - name = "Foaming Agent" - id = "foaming_agent" - result = "foaming_agent" - required_reagents = list("lithium" = 1, "hydrogen" = 1) - result_amount = 1 - -/datum/chemical_reaction/glycerol - name = "Glycerol" - id = "glycerol" - result = "glycerol" - required_reagents = list("cornoil" = 3, "sacid" = 1) - result_amount = 1 - -/datum/chemical_reaction/sodiumchloride - name = "Sodium Chloride" - id = "sodiumchloride" - result = "sodiumchloride" - required_reagents = list("sodium" = 1, "chlorine" = 1) - result_amount = 2 - -/datum/chemical_reaction/condensedcapsaicin - name = "Condensed Capsaicin" - id = "condensedcapsaicin" - result = "condensedcapsaicin" - required_reagents = list("capsaicin" = 2) - catalysts = list("phoron" = 5) - result_amount = 1 - -/datum/chemical_reaction/coolant - name = "Coolant" - id = "coolant" - result = "coolant" - required_reagents = list("tungsten" = 1, "oxygen" = 1, "water" = 1) - result_amount = 3 - log_is_important = 1 - -/datum/chemical_reaction/rezadone - name = "Rezadone" - id = "rezadone" - result = "rezadone" - required_reagents = list("carpotoxin" = 1, "cryptobiolin" = 1, "copper" = 1) - result_amount = 3 - -/datum/chemical_reaction/lexorin - name = "Lexorin" - id = "lexorin" - result = "lexorin" - required_reagents = list("phoron" = 1, "hydrogen" = 1, "nitrogen" = 1) - result_amount = 3 - -/datum/chemical_reaction/methylphenidate - name = "Methylphenidate" - id = "methylphenidate" - result = "methylphenidate" - required_reagents = list("mindbreaker" = 1, "hydrogen" = 1) - result_amount = 3 - -/datum/chemical_reaction/citalopram - name = "Citalopram" - id = "citalopram" - result = "citalopram" - required_reagents = list("mindbreaker" = 1, "carbon" = 1) - result_amount = 3 - -/datum/chemical_reaction/paroxetine - name = "Paroxetine" - id = "paroxetine" - result = "paroxetine" - required_reagents = list("mindbreaker" = 1, "oxygen" = 1, "inaprovaline" = 1) - result_amount = 3 - -/datum/chemical_reaction/neurotoxin - name = "Neurotoxin" - id = "neurotoxin" - result = "neurotoxin" - required_reagents = list("gargleblaster" = 1, "stoxin" = 1) - result_amount = 2 - -/datum/chemical_reaction/luminol - name = "Luminol" - id = "luminol" - result = "luminol" - required_reagents = list("hydrogen" = 2, "carbon" = 2, "ammonia" = 2) - result_amount = 6 - -/* Solidification */ - -/datum/chemical_reaction/solidification - name = "Solid Iron" - id = "solidiron" - result = null - required_reagents = list("frostoil" = 5, "iron" = REAGENTS_PER_SHEET) - result_amount = 1 - var/sheet_to_give = /obj/item/stack/material/iron - -/datum/chemical_reaction/solidification/on_reaction(var/datum/reagents/holder, var/created_volume) - new sheet_to_give(get_turf(holder.my_atom), created_volume) - return - - -/datum/chemical_reaction/solidification/phoron - name = "Solid Phoron" - id = "solidphoron" - required_reagents = list("frostoil" = 5, "phoron" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/phoron - - -/datum/chemical_reaction/solidification/silver - name = "Solid Silver" - id = "solidsilver" - required_reagents = list("frostoil" = 5, "silver" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/silver - - -/datum/chemical_reaction/solidification/gold - name = "Solid Gold" - id = "solidgold" - required_reagents = list("frostoil" = 5, "gold" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/gold - - -/datum/chemical_reaction/solidification/platinum - name = "Solid Platinum" - id = "solidplatinum" - required_reagents = list("frostoil" = 5, "platinum" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/platinum - - -/datum/chemical_reaction/solidification/uranium - name = "Solid Uranium" - id = "soliduranium" - required_reagents = list("frostoil" = 5, "uranium" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/uranium - - -/datum/chemical_reaction/solidification/hydrogen - name = "Solid Hydrogen" - id = "solidhydrogen" - required_reagents = list("frostoil" = 100, "hydrogen" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/mhydrogen - - -// These are from Xenobio. -/datum/chemical_reaction/solidification/steel - name = "Solid Steel" - id = "solidsteel" - required_reagents = list("frostoil" = 5, "steel" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/steel - - -/datum/chemical_reaction/solidification/plasteel - name = "Solid Plasteel" - id = "solidplasteel" - required_reagents = list("frostoil" = 10, "plasteel" = REAGENTS_PER_SHEET) - sheet_to_give = /obj/item/stack/material/plasteel - - -/datum/chemical_reaction/plastication - name = "Plastic" - id = "solidplastic" - result = null - required_reagents = list("pacid" = 1, "plasticide" = 2) - result_amount = 1 - -/datum/chemical_reaction/plastication/on_reaction(var/datum/reagents/holder, var/created_volume) - new /obj/item/stack/material/plastic(get_turf(holder.my_atom), created_volume) - return - -/* Grenade reactions */ - -/datum/chemical_reaction/explosion_potassium - name = "Explosion" - id = "explosion_potassium" - result = null - required_reagents = list("water" = 1, "potassium" = 1) - result_amount = 2 - mix_message = null - -/datum/chemical_reaction/explosion_potassium/on_reaction(var/datum/reagents/holder, var/created_volume) - var/datum/effect/effect/system/reagents_explosion/e = new() - e.set_up(round (created_volume/10, 1), holder.my_atom, 0, 0) - if(isliving(holder.my_atom)) - e.amount *= 0.5 - var/mob/living/L = holder.my_atom - if(L.stat != DEAD) - e.amount *= 0.5 - e.start() - holder.clear_reagents() - return - -/datum/chemical_reaction/flash_powder - name = "Flash powder" - id = "flash_powder" - result = null - required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1 ) - result_amount = null - -/datum/chemical_reaction/flash_powder/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread - s.set_up(2, 1, location) - s.start() - for(var/mob/living/carbon/M in viewers(world.view, location)) - switch(get_dist(M, location)) - if(0 to 3) - if(hasvar(M, "glasses")) - if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) - continue - - M.flash_eyes() - M.Weaken(15) - - if(4 to 5) - if(hasvar(M, "glasses")) - if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) - continue - - M.flash_eyes() - M.Stun(5) - -/datum/chemical_reaction/emp_pulse - name = "EMP Pulse" - id = "emp_pulse" - result = null - required_reagents = list("uranium" = 1, "iron" = 1) // Yes, laugh, it's the best recipe I could think of that makes a little bit of sense - result_amount = 2 - -/datum/chemical_reaction/emp_pulse/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - // 100 created volume = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes. - // 200 created volume = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades. - empulse(location, round(created_volume / 24), round(created_volume / 20), round(created_volume / 18), round(created_volume / 14), 1) - holder.clear_reagents() - return - -/datum/chemical_reaction/nitroglycerin - name = "Nitroglycerin" - id = "nitroglycerin" - result = "nitroglycerin" - required_reagents = list("glycerol" = 1, "pacid" = 1, "sacid" = 1) - result_amount = 2 - log_is_important = 1 - -/datum/chemical_reaction/nitroglycerin/on_reaction(var/datum/reagents/holder, var/created_volume) - var/datum/effect/effect/system/reagents_explosion/e = new() - e.set_up(round (created_volume/2, 1), holder.my_atom, 0, 0) - if(isliving(holder.my_atom)) - e.amount *= 0.5 - var/mob/living/L = holder.my_atom - if(L.stat!=DEAD) - e.amount *= 0.5 - e.start() - - holder.clear_reagents() - return - -/datum/chemical_reaction/napalm - name = "Napalm" - id = "napalm" - result = null - required_reagents = list("aluminum" = 1, "phoron" = 1, "sacid" = 1 ) - result_amount = 1 - -/datum/chemical_reaction/napalm/on_reaction(var/datum/reagents/holder, var/created_volume) - var/turf/location = get_turf(holder.my_atom.loc) - for(var/turf/simulated/floor/target_tile in range(0,location)) - target_tile.assume_gas("volatile_fuel", created_volume, 400+T0C) - spawn (0) target_tile.hotspot_expose(700, 400) - holder.del_reagent("napalm") - return - -/datum/chemical_reaction/chemsmoke - name = "Chemsmoke" - id = "chemsmoke" - result = null - required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1) - result_amount = 0.4 - -/datum/chemical_reaction/chemsmoke/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem - S.attach(location) - S.set_up(holder, created_volume, 0, location) - playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) - spawn(0) - S.start() - holder.clear_reagents() - return - -/datum/chemical_reaction/foam - name = "Foam" - id = "foam" - result = null - required_reagents = list("fluorosurfactant" = 1, "water" = 1) - result_amount = 2 - mix_message = "The solution violently bubbles!" - -/datum/chemical_reaction/foam/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - - for(var/mob/M in viewers(5, location)) - to_chat(M, "The solution spews out foam!") - - var/datum/effect/effect/system/foam_spread/s = new() - s.set_up(created_volume, location, holder, 0) - s.start() - holder.clear_reagents() - return - -/datum/chemical_reaction/metalfoam - name = "Metal Foam" - id = "metalfoam" - result = null - required_reagents = list("aluminum" = 3, "foaming_agent" = 1, "pacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/metalfoam/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - - for(var/mob/M in viewers(5, location)) - to_chat(M, "The solution spews out a metalic foam!") - - var/datum/effect/effect/system/foam_spread/s = new() - s.set_up(created_volume, location, holder, 1) - s.start() - return - -/datum/chemical_reaction/ironfoam - name = "Iron Foam" - id = "ironlfoam" - result = null - required_reagents = list("iron" = 3, "foaming_agent" = 1, "pacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/ironfoam/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - - for(var/mob/M in viewers(5, location)) - to_chat(M, "The solution spews out a metalic foam!") - - var/datum/effect/effect/system/foam_spread/s = new() - s.set_up(created_volume, location, holder, 2) - s.start() - return - -/* Paint */ - -/datum/chemical_reaction/red_paint - name = "Red paint" - id = "red_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_red" = 1) - result_amount = 5 - -/datum/chemical_reaction/red_paint/send_data() - return "#FE191A" - -/datum/chemical_reaction/orange_paint - name = "Orange paint" - id = "orange_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_orange" = 1) - result_amount = 5 - -/datum/chemical_reaction/orange_paint/send_data() - return "#FFBE4F" - -/datum/chemical_reaction/yellow_paint - name = "Yellow paint" - id = "yellow_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_yellow" = 1) - result_amount = 5 - -/datum/chemical_reaction/yellow_paint/send_data() - return "#FDFE7D" - -/datum/chemical_reaction/green_paint - name = "Green paint" - id = "green_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_green" = 1) - result_amount = 5 - -/datum/chemical_reaction/green_paint/send_data() - return "#18A31A" - -/datum/chemical_reaction/blue_paint - name = "Blue paint" - id = "blue_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_blue" = 1) - result_amount = 5 - -/datum/chemical_reaction/blue_paint/send_data() - return "#247CFF" - -/datum/chemical_reaction/purple_paint - name = "Purple paint" - id = "purple_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_purple" = 1) - result_amount = 5 - -/datum/chemical_reaction/purple_paint/send_data() - return "#CC0099" - -/datum/chemical_reaction/grey_paint //mime - name = "Grey paint" - id = "grey_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_grey" = 1) - result_amount = 5 - -/datum/chemical_reaction/grey_paint/send_data() - return "#808080" - -/datum/chemical_reaction/brown_paint - name = "Brown paint" - id = "brown_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_brown" = 1) - result_amount = 5 - -/datum/chemical_reaction/brown_paint/send_data() - return "#846F35" - -/datum/chemical_reaction/blood_paint - name = "Blood paint" - id = "blood_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "blood" = 2) - result_amount = 5 - -/datum/chemical_reaction/blood_paint/send_data(var/datum/reagents/T) - var/t = T.get_data("blood") - if(t && t["blood_colour"]) - return t["blood_colour"] - return "#FE191A" // Probably red - -/datum/chemical_reaction/milk_paint - name = "Milk paint" - id = "milk_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "milk" = 5) - result_amount = 5 - -/datum/chemical_reaction/milk_paint/send_data() - return "#F0F8FF" - -/datum/chemical_reaction/orange_juice_paint - name = "Orange juice paint" - id = "orange_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "orangejuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/orange_juice_paint/send_data() - return "#E78108" - -/datum/chemical_reaction/tomato_juice_paint - name = "Tomato juice paint" - id = "tomato_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "tomatojuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/tomato_juice_paint/send_data() - return "#731008" - -/datum/chemical_reaction/lime_juice_paint - name = "Lime juice paint" - id = "lime_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "limejuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/lime_juice_paint/send_data() - return "#365E30" - -/datum/chemical_reaction/carrot_juice_paint - name = "Carrot juice paint" - id = "carrot_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "carrotjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/carrot_juice_paint/send_data() - return "#973800" - -/datum/chemical_reaction/berry_juice_paint - name = "Berry juice paint" - id = "berry_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "berryjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/berry_juice_paint/send_data() - return "#990066" - -/datum/chemical_reaction/grape_juice_paint - name = "Grape juice paint" - id = "grape_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "grapejuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/grape_juice_paint/send_data() - return "#863333" - -/datum/chemical_reaction/poisonberry_juice_paint - name = "Poison berry juice paint" - id = "poisonberry_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "poisonberryjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/poisonberry_juice_paint/send_data() - return "#863353" - -/datum/chemical_reaction/watermelon_juice_paint - name = "Watermelon juice paint" - id = "watermelon_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "watermelonjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/watermelon_juice_paint/send_data() - return "#B83333" - -/datum/chemical_reaction/lemon_juice_paint - name = "Lemon juice paint" - id = "lemon_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "lemonjuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/lemon_juice_paint/send_data() - return "#AFAF00" - -/datum/chemical_reaction/banana_juice_paint - name = "Banana juice paint" - id = "banana_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "banana" = 5) - result_amount = 5 - -/datum/chemical_reaction/banana_juice_paint/send_data() - return "#C3AF00" - -/datum/chemical_reaction/potato_juice_paint - name = "Potato juice paint" - id = "potato_juice_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "potatojuice" = 5) - result_amount = 5 - -/datum/chemical_reaction/potato_juice_paint/send_data() - return "#302000" - -/datum/chemical_reaction/carbon_paint - name = "Carbon paint" - id = "carbon_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "carbon" = 1) - result_amount = 5 - -/datum/chemical_reaction/carbon_paint/send_data() - return "#333333" - -/datum/chemical_reaction/aluminum_paint - name = "Aluminum paint" - id = "aluminum_paint" - result = "paint" - required_reagents = list("plasticide" = 1, "water" = 3, "aluminum" = 1) - result_amount = 5 - -/datum/chemical_reaction/aluminum_paint/send_data() - return "#F0F8FF" - -/* Food */ - -/datum/chemical_reaction/food/tofu - name = "Tofu" - id = "tofu" - result = null - required_reagents = list("soymilk" = 10) - catalysts = list("enzyme" = 5) - result_amount = 1 - -/datum/chemical_reaction/food/tofu/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/tofu(location) - return - -/datum/chemical_reaction/food/chocolate_bar - name = "Chocolate Bar" - id = "chocolate_bar" - result = null - required_reagents = list("soymilk" = 2, "coco" = 2, "sugar" = 2) - result_amount = 1 - -/datum/chemical_reaction/food/chocolate_bar/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) - return - -/datum/chemical_reaction/food/chocolate_bar2 - name = "Chocolate Bar" - id = "chocolate_bar" - result = null - required_reagents = list("milk" = 2, "coco" = 2, "sugar" = 2) - result_amount = 1 - -/datum/chemical_reaction/food/chocolate_bar2/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) - return - -/datum/chemical_reaction/drinks/coffee - name = "Coffee" - id = "coffee" - result = "coffee" - required_reagents = list("water" = 5, "coffeepowder" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/tea - name = "Black tea" - id = "tea" - result = "tea" - required_reagents = list("water" = 5, "teapowder" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/hot_coco - name = "Hot Coco" - id = "hot_coco" - result = "hot_coco" - required_reagents = list("water" = 5, "coco" = 1) - result_amount = 5 - -/datum/chemical_reaction/food/soysauce - name = "Soy Sauce" - id = "soysauce" - result = "soysauce" - required_reagents = list("soymilk" = 4, "sacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/grapejuice - name = "Grape Juice" - id = "grapejuice" - result = "grapejuice" - required_reagents = list("water" = 3, "instantgrape" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/orangejuice - name = "Orange Juice" - id = "orangejuice" - result = "orangejuice" - required_reagents = list("water" = 3, "instantorange" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/watermelonjuice - name = "Watermelon Juice" - id = "watermelonjuice" - result = "watermelonjuice" - required_reagents = list("water" = 3, "instantwatermelon" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/applejuice - name = "Apple Juice" - id = "applejuice" - result = "applejuice" - required_reagents = list("water" = 3, "instantapple" = 1) - result_amount = 3 - -/datum/chemical_reaction/food/ketchup - name = "Ketchup" - id = "ketchup" - result = "ketchup" - required_reagents = list("tomatojuice" = 2, "water" = 1, "sugar" = 1) - result_amount = 4 - -/datum/chemical_reaction/food/barbecue - name = "Barbeque Sauce" - id = "barbecue" - result = "barbecue" - required_reagents = list("tomatojuice" = 2, "applejuice" = 1, "sugar" = 1, "spacespice" = 1) - result_amount = 4 - -/datum/chemical_reaction/food/peanutbutter - name = "Peanut Butter" - id = "peanutbutter" - result = "peanutbutter" - required_reagents = list("peanutoil" = 2, "sugar" = 1, "sodiumchloride" = 1) - catalysts = list("enzyme" = 5) - result_amount = 3 - -/datum/chemical_reaction/food/mayonnaise - name = "mayonnaise" - id = "mayo" - result = "mayo" - required_reagents = list("egg" = 9, "cornoil" = 5, "lemonjuice" = 5, "sodiumchloride" = 1) - result_amount = 15 - -/datum/chemical_reaction/food/cheesewheel - name = "Cheesewheel" - id = "cheesewheel" - result = null - required_reagents = list("milk" = 40) - catalysts = list("enzyme" = 5) - result_amount = 1 - -/datum/chemical_reaction/food/cheesewheel/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel(location) - return - -/datum/chemical_reaction/food/meatball - name = "Meatball" - id = "meatball" - result = null - required_reagents = list("protein" = 3, "flour" = 5) - result_amount = 3 - -/datum/chemical_reaction/food/meatball/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/meatball(location) - return - -/datum/chemical_reaction/food/dough - name = "Dough" - id = "dough" - result = null - required_reagents = list("egg" = 3, "flour" = 10) - inhibitors = list("water" = 1, "beer" = 1) //To prevent it messing with batter recipes - result_amount = 1 - -/datum/chemical_reaction/food/dough/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/dough(location) - return - -/datum/chemical_reaction/food/syntiflesh - name = "Syntiflesh" - id = "syntiflesh" - result = null - required_reagents = list("blood" = 5, "clonexadone" = 5) - result_amount = 1 - -/datum/chemical_reaction/food/syntiflesh/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh(location) - return - -/datum/chemical_reaction/hot_ramen - name = "Hot Ramen" - id = "hot_ramen" - result = "hot_ramen" - required_reagents = list("water" = 1, "dry_ramen" = 3) - result_amount = 3 - -/datum/chemical_reaction/hell_ramen - name = "Hell Ramen" - id = "hell_ramen" - result = "hell_ramen" - required_reagents = list("capsaicin" = 1, "hot_ramen" = 6) - result_amount = 6 - -/* Alcohol */ - -/datum/chemical_reaction/drinks/goldschlager - name = "Goldschlager" - id = "goldschlager" - result = "goldschlager" - required_reagents = list("vodka" = 10, "gold" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/patron - name = "Patron" - id = "patron" - result = "patron" - required_reagents = list("tequilla" = 10, "silver" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/bilk - name = "Bilk" - id = "bilk" - result = "bilk" - required_reagents = list("milk" = 1, "beer" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/icetea - name = "Iced Tea" - id = "icetea" - result = "icetea" - required_reagents = list("ice" = 1, "tea" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/icecoffee - name = "Iced Coffee" - id = "icecoffee" - result = "icecoffee" - required_reagents = list("ice" = 1, "coffee" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/nuka_cola - name = "Nuclear Cola" - id = "nuka_cola" - result = "nuka_cola" - required_reagents = list("uranium" = 1, "cola" = 5) - result_amount = 5 - -/datum/chemical_reaction/drinks/moonshine - name = "Moonshine" - id = "moonshine" - result = "moonshine" - required_reagents = list("nutriment" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/grenadine - name = "Grenadine Syrup" - id = "grenadine" - result = "grenadine" - required_reagents = list("berryjuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/wine - name = "Wine" - id = "wine" - result = "wine" - required_reagents = list("grapejuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/pwine - name = "Poison Wine" - id = "pwine" - result = "pwine" - required_reagents = list("poisonberryjuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/melonliquor - name = "Melon Liquor" - id = "melonliquor" - result = "melonliquor" - required_reagents = list("watermelonjuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/bluecuracao - name = "Blue Curacao" - id = "bluecuracao" - result = "bluecuracao" - required_reagents = list("orangejuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/spacebeer - name = "Space Beer" - id = "spacebeer" - result = "beer" - required_reagents = list("cornoil" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/vodka - name = "Vodka" - id = "vodka" - result = "vodka" - required_reagents = list("potatojuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/cider - name = "Cider" - id = "cider" - result = "cider" - required_reagents = list("applejuice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - - -/datum/chemical_reaction/drinks/sake - name = "Sake" - id = "sake" - result = "sake" - required_reagents = list("rice" = 10) - catalysts = list("enzyme" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/kahlua - name = "Kahlua" - id = "kahlua" - result = "kahlua" - required_reagents = list("coffee" = 5, "sugar" = 5) - catalysts = list("enzyme" = 5) - result_amount = 5 - -/datum/chemical_reaction/drinks/gin_tonic - name = "Gin and Tonic" - id = "gintonic" - result = "gintonic" - required_reagents = list("gin" = 2, "tonic" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/cuba_libre - name = "Cuba Libre" - id = "cubalibre" - result = "cubalibre" - required_reagents = list("rum" = 2, "cola" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/martini - name = "Classic Martini" - id = "martini" - result = "martini" - required_reagents = list("gin" = 2, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/vodkamartini - name = "Vodka Martini" - id = "vodkamartini" - result = "vodkamartini" - required_reagents = list("vodka" = 2, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/white_russian - name = "White Russian" - id = "whiterussian" - result = "whiterussian" - required_reagents = list("blackrussian" = 2, "cream" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/whiskey_cola - name = "Whiskey Cola" - id = "whiskeycola" - result = "whiskeycola" - required_reagents = list("whiskey" = 2, "cola" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/screwdriver - name = "Screwdriver" - id = "screwdrivercocktail" - result = "screwdrivercocktail" - required_reagents = list("vodka" = 2, "orangejuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/bloody_mary - name = "Bloody Mary" - id = "bloodymary" - result = "bloodymary" - required_reagents = list("vodka" = 2, "tomatojuice" = 3, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/gargle_blaster - name = "Pan-Galactic Gargle Blaster" - id = "gargleblaster" - result = "gargleblaster" - required_reagents = list("vodka" = 2, "gin" = 1, "whiskey" = 1, "cognac" = 1, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/brave_bull - name = "Brave Bull" - id = "bravebull" - result = "bravebull" - required_reagents = list("tequilla" = 2, "kahlua" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/tequilla_sunrise - name = "Tequilla Sunrise" - id = "tequillasunrise" - result = "tequillasunrise" - required_reagents = list("tequilla" = 2, "orangejuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/phoron_special - name = "Toxins Special" - id = "phoronspecial" - result = "phoronspecial" - required_reagents = list("rum" = 2, "vermouth" = 2, "phoron" = 2) - result_amount = 6 - -/datum/chemical_reaction/drinks/beepsky_smash - name = "Beepksy Smash" - id = "beepksysmash" - result = "beepskysmash" - required_reagents = list("limejuice" = 1, "whiskey" = 1, "iron" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/doctor_delight - name = "The Doctor's Delight" - id = "doctordelight" - result = "doctorsdelight" - required_reagents = list("limejuice" = 1, "tomatojuice" = 1, "orangejuice" = 1, "cream" = 2, "tricordrazine" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/irish_cream - name = "Irish Cream" - id = "irishcream" - result = "irishcream" - required_reagents = list("whiskey" = 2, "cream" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/manly_dorf - name = "The Manly Dorf" - id = "manlydorf" - result = "manlydorf" - required_reagents = list ("beer" = 1, "ale" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/hooch - name = "Hooch" - id = "hooch" - result = "hooch" - required_reagents = list ("sugar" = 1, "ethanol" = 2, "fuel" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/irish_coffee - name = "Irish Coffee" - id = "irishcoffee" - result = "irishcoffee" - required_reagents = list("irishcream" = 1, "coffee" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/b52 - name = "B-52" - id = "b52" - result = "b52" - required_reagents = list("irishcream" = 1, "kahlua" = 1, "cognac" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/atomicbomb - name = "Atomic Bomb" - id = "atomicbomb" - result = "atomicbomb" - required_reagents = list("b52" = 10, "uranium" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/margarita - name = "Margarita" - id = "margarita" - result = "margarita" - required_reagents = list("tequilla" = 2, "limejuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/longislandicedtea - name = "Long Island Iced Tea" - id = "longislandicedtea" - result = "longislandicedtea" - required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 3) - result_amount = 6 - -/datum/chemical_reaction/drinks/icedtea - name = "Long Island Iced Tea" - id = "longislandicedtea" - result = "longislandicedtea" - required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 3) - result_amount = 6 - -/datum/chemical_reaction/drinks/threemileisland - name = "Three Mile Island Iced Tea" - id = "threemileisland" - result = "threemileisland" - required_reagents = list("longislandicedtea" = 10, "uranium" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/whiskeysoda - name = "Whiskey Soda" - id = "whiskeysoda" - result = "whiskeysoda" - required_reagents = list("whiskey" = 2, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/black_russian - name = "Black Russian" - id = "blackrussian" - result = "blackrussian" - required_reagents = list("vodka" = 2, "kahlua" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/manhattan - name = "Manhattan" - id = "manhattan" - result = "manhattan" - required_reagents = list("whiskey" = 2, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/manhattan_proj - name = "Manhattan Project" - id = "manhattan_proj" - result = "manhattan_proj" - required_reagents = list("manhattan" = 10, "uranium" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/vodka_tonic - name = "Vodka and Tonic" - id = "vodkatonic" - result = "vodkatonic" - required_reagents = list("vodka" = 2, "tonic" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/gin_fizz - name = "Gin Fizz" - id = "ginfizz" - result = "ginfizz" - required_reagents = list("gin" = 1, "sodawater" = 1, "limejuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/bahama_mama - name = "Bahama mama" - id = "bahama_mama" - result = "bahama_mama" - required_reagents = list("rum" = 2, "orangejuice" = 2, "limejuice" = 1, "ice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/singulo - name = "Singulo" - id = "singulo" - result = "singulo" - required_reagents = list("vodka" = 5, "radium" = 1, "wine" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/alliescocktail - name = "Allies Cocktail" - id = "alliescocktail" - result = "alliescocktail" - required_reagents = list("martini" = 1, "vodka" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/demonsblood - name = "Demons Blood" - id = "demonsblood" - result = "demonsblood" - required_reagents = list("rum" = 3, "spacemountainwind" = 1, "blood" = 1, "dr_gibb" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/booger - name = "Booger" - id = "booger" - result = "booger" - required_reagents = list("cream" = 2, "banana" = 1, "rum" = 1, "watermelonjuice" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/antifreeze - name = "Anti-freeze" - id = "antifreeze" - result = "antifreeze" - required_reagents = list("vodka" = 1, "cream" = 1, "ice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/barefoot - name = "Barefoot" - id = "barefoot" - result = "barefoot" - required_reagents = list("berryjuice" = 1, "cream" = 1, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/grapesoda - name = "Grape Soda" - id = "grapesoda" - result = "grapesoda" - required_reagents = list("grapejuice" = 2, "cola" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/sbiten - name = "Sbiten" - id = "sbiten" - result = "sbiten" - required_reagents = list("vodka" = 10, "capsaicin" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/red_mead - name = "Red Mead" - id = "red_mead" - result = "red_mead" - required_reagents = list("blood" = 1, "mead" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/mead - name = "Mead" - id = "mead" - result = "mead" - required_reagents = list("sugar" = 1, "water" = 1) - catalysts = list("enzyme" = 5) - result_amount = 2 - -/datum/chemical_reaction/drinks/iced_beer - name = "Iced Beer" - id = "iced_beer" - result = "iced_beer" - required_reagents = list("beer" = 10, "frostoil" = 1) - result_amount = 10 - -/datum/chemical_reaction/drinks/iced_beer2 - name = "Iced Beer" - id = "iced_beer" - result = "iced_beer" - required_reagents = list("beer" = 5, "ice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/grog - name = "Grog" - id = "grog" - result = "grog" - required_reagents = list("rum" = 1, "water" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/soy_latte - name = "Soy Latte" - id = "soy_latte" - result = "soy_latte" - required_reagents = list("coffee" = 1, "soymilk" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/cafe_latte - name = "Cafe Latte" - id = "cafe_latte" - result = "cafe_latte" - required_reagents = list("coffee" = 1, "milk" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/acidspit - name = "Acid Spit" - id = "acidspit" - result = "acidspit" - required_reagents = list("sacid" = 1, "wine" = 5) - result_amount = 6 - -/datum/chemical_reaction/drinks/amasec - name = "Amasec" - id = "amasec" - result = "amasec" - required_reagents = list("iron" = 1, "wine" = 5, "vodka" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/changelingsting - name = "Changeling Sting" - id = "changelingsting" - result = "changelingsting" - required_reagents = list("screwdrivercocktail" = 1, "limejuice" = 1, "lemonjuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/aloe - name = "Aloe" - id = "aloe" - result = "aloe" - required_reagents = list("cream" = 1, "whiskey" = 1, "watermelonjuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/andalusia - name = "Andalusia" - id = "andalusia" - result = "andalusia" - required_reagents = list("rum" = 1, "whiskey" = 1, "lemonjuice" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/snowwhite - name = "Snow White" - id = "snowwhite" - result = "snowwhite" - required_reagents = list("beer" = 1, "lemon_lime" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/irishcarbomb - name = "Irish Car Bomb" - id = "irishcarbomb" - result = "irishcarbomb" - required_reagents = list("ale" = 1, "irishcream" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/syndicatebomb - name = "Syndicate Bomb" - id = "syndicatebomb" - result = "syndicatebomb" - required_reagents = list("beer" = 1, "whiskeycola" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/erikasurprise - name = "Erika Surprise" - id = "erikasurprise" - result = "erikasurprise" - required_reagents = list("ale" = 2, "limejuice" = 1, "whiskey" = 1, "banana" = 1, "ice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/devilskiss - name = "Devils Kiss" - id = "devilskiss" - result = "devilskiss" - required_reagents = list("blood" = 1, "kahlua" = 1, "rum" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/hippiesdelight - name = "Hippies Delight" - id = "hippiesdelight" - result = "hippiesdelight" - required_reagents = list("psilocybin" = 1, "gargleblaster" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/bananahonk - name = "Banana Honk" - id = "bananahonk" - result = "bananahonk" - required_reagents = list("banana" = 1, "cream" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/silencer - name = "Silencer" - id = "silencer" - result = "silencer" - required_reagents = list("nothing" = 1, "cream" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/driestmartini - name = "Driest Martini" - id = "driestmartini" - result = "driestmartini" - required_reagents = list("nothing" = 1, "gin" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/lemonade - name = "Lemonade" - id = "lemonade" - result = "lemonade" - required_reagents = list("lemonjuice" = 1, "sugar" = 1, "water" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/melonade - name = "Melonade" - id = "melonade" - result = "melonade" - required_reagents = list("watermelonjuice" = 1, "sugar" = 1, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/appleade - name = "Appleade" - id = "appleade" - result = "appleade" - required_reagents = list("applejuice" = 1, "sugar" = 1, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/pineappleade - name = "Pineappleade" - id = "pineappleade" - result = "pineappleade" - required_reagents = list("pineapplejuice" = 2, "limejuice" = 1, "sodawater" = 2, "honey" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/driverspunch - name = "Driver`s Punch" - id = "driverspunch" - result = "driverspunch" - required_reagents = list("appleade" = 2, "orangejuice" = 1, "mint" = 1, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/mintapplesparkle - name = "Mint Apple Sparkle" - id = "mintapplesparkle" - result = "mintapplesparkle" - required_reagents = list("appleade" = 2, "mint" = 1) - inhibitors = list("sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/berrycordial - name = "Berry Cordial" - id = "berrycordial" - result = "berrycordial" - required_reagents = list("berryjuice" = 4, "sugar" = 1, "lemonjuice" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/tropicalfizz - name = "Tropical Fizz" - id = "tropicalfizz" - result = "tropicalfizz" - required_reagents = list("sodawater" = 6, "berryjuice" = 1, "mint" = 1, "limejuice" = 1, "lemonjuice" = 1, "pineapplejuice" = 1) - inhibitors = list("sugar" = 1) - result_amount = 8 - -/datum/chemical_reaction/drinks/melonspritzer - name = "Melon Spritzer" - id = "melonspritzer" - result = "melonspritzer" - required_reagents = list("watermelonjuice" = 2, "wine" = 2, "applejuice" = 1, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/fauxfizz - name = "Faux Fizz" - id = "fauxfizz" - result = "fauxfizz" - required_reagents = list("sodawater" = 2, "berryjuice" = 1, "applejuice" = 1, "limejuice" = 1, "honey" = 1) - inhibitors = list("sugar" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/firepunch - name = "Fire Punch" - id = "firepunch" - result = "firepunch" - required_reagents = list("sugar" = 1, "rum" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/kiraspecial - name = "Kira Special" - id = "kiraspecial" - result = "kiraspecial" - required_reagents = list("orangejuice" = 1, "limejuice" = 1, "sodawater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/brownstar - name = "Brown Star" - id = "brownstar" - result = "brownstar" - required_reagents = list("orangejuice" = 2, "cola" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/milkshake - name = "Milkshake" - id = "milkshake" - result = "milkshake" - required_reagents = list("cream" = 1, "ice" = 2, "milk" = 2) - result_amount = 5 - -/datum/chemical_reaction/drinks/peanutmilkshake - name = "Peanutbutter Milkshake" - id = "peanutmilkshake" - result = "peanutmilkshake" - required_reagents = list("cream" = 1, "ice" = 1, "peanutbutter" = 2, "milk" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/rewriter - name = "Rewriter" - id = "rewriter" - result = "rewriter" - required_reagents = list("spacemountainwind" = 1, "coffee" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/suidream - name = "Sui Dream" - id = "suidream" - result = "suidream" - required_reagents = list("space_up" = 1, "bluecuracao" = 1, "melonliquor" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/shirleytemple - name = "Shirley Temple" - id = "shirley_temple" - result = "shirley_temple" - required_reagents = list("gingerale" = 4, "grenadine" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/royrogers - name = "Roy Rogers" - id = "roy_rogers" - result = "roy_rogers" - required_reagents = list("shirley_temple" = 5, "lemon_lime" = 2) - result_amount = 7 - -/datum/chemical_reaction/drinks/collinsmix - name = "Collins Mix" - id = "collins_mix" - result = "collins_mix" - required_reagents = list("lemon_lime" = 3, "sodawater" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/arnoldpalmer - name = "Arnold Palmer" - id = "arnold_palmer" - result = "arnold_palmer" - required_reagents = list("icetea" = 1, "lemonade" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/minttea - name = "Mint Tea" - id = "minttea" - result = "minttea" - required_reagents = list("tea" = 5, "mint" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/lemontea - name = "Lemon Tea" - id = "lemontea" - result = "lemontea" - required_reagents = list("tea" = 5, "lemonjuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/limetea - name = "Lime Tea" - id = "limetea" - result = "limetea" - required_reagents = list("tea" = 5, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/orangetea - name = "Orange Tea" - id = "orangetea" - result = "orangetea" - required_reagents = list("tea" = 5, "orangejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/berrytea - name = "Berry Tea" - id = "berrytea" - result = "berrytea" - required_reagents = list("tea" = 5, "berryjuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/sakebomb - name = "Sake Bomb" - id = "sakebomb" - result = "sakebomb" - required_reagents = list("beer" = 2, "sake" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/tamagozake - name = "Tamagozake" - id = "tamagozake" - result = "tamagozake" - required_reagents = list("sake" = 10, "sugar" = 5, "egg" = 3) - result_amount = 15 - -/datum/chemical_reaction/drinks/ginzamary - name = "Ginza Mary" - id = "ginzamary" - result = "ginzamary" - required_reagents = list("sake" = 2, "vodka" = 2, "tomatojuice" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/tokyorose - name = "Tokyo Rose" - id = "tokyorose" - result = "tokyorose" - required_reagents = list("sake" = 1, "berryjuice" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/saketini - name = "Saketini" - id = "saketini" - result = "saketini" - required_reagents = list("sake" = 1, "gin" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/elysiumfacepunch - name = "Elysium Facepunch" - id = "elysiumfacepunch" - result = "elysiumfacepunch" - required_reagents = list("kahlua" = 1, "lemonjuice" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/erebusmoonrise - name = "Erebus Moonrise" - id = "erebusmoonrise" - result = "erebusmoonrise" - required_reagents = list("whiskey" = 1, "vodka" = 1, "tequilla" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/balloon - name = "Balloon" - id = "balloon" - result = "balloon" - required_reagents = list("cream" = 1, "bluecuracao" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/natunabrandy - name = "Natuna Brandy" - id = "natunabrandy" - result = "natunabrandy" - required_reagents = list("beer" = 1, "sodawater" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/euphoria - name = "Euphoria" - id = "euphoria" - result = "euphoria" - required_reagents = list("specialwhiskey" = 1, "cognac" = 2) - result_amount = 3 - -/datum/chemical_reaction/drinks/xanaducannon - name = "Xanadu Cannon" - id = "xanaducannon" - result = "xanaducannon" - required_reagents = list("ale" = 1, "dr_gibb" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/debugger - name = "Debugger" - id = "debugger" - result = "debugger" - required_reagents = list("fuel" = 1, "sugar" = 2, "cornoil" = 2) - result_amount = 5 - -/datum/chemical_reaction/drinks/spacersbrew - name = "Spacer's Brew" - id = "spacersbrew" - result = "spacersbrew" - required_reagents = list("brownstar" = 4, "ethanol" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/binmanbliss - name = "Binman Bliss" - id = "binmanbliss" - result = "binmanbliss" - required_reagents = list("sake" = 1, "tequilla" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/chrysanthemum - name = "Chrysanthemum" - id = "chrysanthemum" - result = "chrysanthemum" - required_reagents = list("sake" = 1, "melonliquor" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/deathbell - name = "Deathbell" - id = "deathbell" - result = "deathbell" - required_reagents = list("antifreeze" = 1, "gargleblaster" = 1, "syndicatebomb" =1) - result_amount = 3 - -/datum/chemical_reaction/bitters - name = "Bitters" - id = "bitters" - result = "bitters" - required_reagents = list("mint" = 5) - catalysts = list("enzyme" = 5) - result_amount = 5 - -/datum/chemical_reaction/drinks/soemmerfire - name = "Soemmer Fire" - id = "soemmerfire" - result = "soemmerfire" - required_reagents = list("manhattan" = 2, "condensedcapsaicin" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/winebrandy - name = "Wine brandy" - id = "winebrandy" - result = "winebrandy" - required_reagents = list("wine" = 10) - catalysts = list("enzyme" = 10) //10u enzyme so it requires more than is usually added. Stops overlap with wine recipe - result_amount = 5 - -/datum/chemical_reaction/drinks/lovepotion - name = "Love Potion" - id = "lovepotion" - result = "lovepotion" - required_reagents = list("cream" = 1, "berryjuice" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/morningafter - name = "Morning After" - id = "morningafter" - result = "morningafter" - required_reagents = list("sbiten" = 1, "coffee" = 5) - result_amount = 6 - -/datum/chemical_reaction/drinks/vesper - name = "Vesper" - id = "vesper" - result = "vesper" - required_reagents = list("gin" = 3, "vodka" = 1, "wine" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/rotgut - name = "Rotgut Fever Dream" - id = "rotgut" - result = "rotgut" - required_reagents = list("vodka" = 3, "rum" = 1, "whiskey" = 1, "cola" = 3) - result_amount = 8 - -/datum/chemical_reaction/drinks/entdraught - name = "Ent's Draught" - id = "entdraught" - result = "entdraught" - required_reagents = list("tonic" = 1, "holywater" = 1, "honey" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/voxdelight - name = "Vox's Delight" - id = "voxdelight" - result = "voxdelight" - required_reagents = list("phoron" = 3, "fuel" = 1, "water" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/screamingviking - name = "Screaming Viking" - id = "screamingviking" - result = "screamingviking" - required_reagents = list("martini" = 2, "vodkatonic" = 2, "limejuice" = 1, "rum" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/vilelemon - name = "Vile Lemon" - id = "vilelemon" - result = "vilelemon" - required_reagents = list("lemonade" = 5, "spacemountainwind" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/dreamcream - name = "Dream Cream" - id = "dreamcream" - result = "dreamcream" - required_reagents = list("milk" = 2, "cream" = 1, "honey" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/robustin - name = "Robustin" - id = "robustin" - result = "robustin" - required_reagents = list("antifreeze" = 1, "phoron" = 1, "fuel" = 1, "vodka" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/virginsip - name = "Virgin Sip" - id = "virginsip" - result = "virginsip" - required_reagents = list("driestmartini" = 1, "water" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/chocoshake - name = "Chocolate Milkshake" - id = "chocoshake" - result = "chocoshake" - required_reagents = list("milkshake" = 1, "coco" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/berryshake - name = "Berry Milkshake" - id = "berryshake" - result = "berryshake" - required_reagents = list("milkshake" = 1, "berryjuice" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/coffeeshake - name = "Coffee Milkshake" - id = "coffeeshake" - result = "coffeeshake" - required_reagents = list("milkshake" = 1, "coffee" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/jellyshot - name = "Jelly Shot" - id = "jellyshot" - result = "jellyshot" - required_reagents = list("cherryjelly" = 4, "vodka" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/slimeshot - name = "Named Bullet" - id = "slimeshot" - result = "slimeshot" - required_reagents = list("slimejelly" = 4, "vodka" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/negroni - name = "Negroni" - id = "negroni" - result = "negroni" - required_reagents = list("gin" = 1, "bitters" = 1, "vermouth" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/cloverclub - name = "Clover Club" - id = "cloverclub" - result = "cloverclub" - required_reagents = list("berryjuice" = 1, "lemonjuice" = 1, "gin" = 3) - result_amount = 5 - -/datum/chemical_reaction/drinks/oldfashioned - name = "Old Fashioned" - id = "oldfashioned" - result = "oldfashioned" - required_reagents = list("whiskey" = 3, "bitters" = 1, "sugar" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/whiskeysour - name = "Whiskey Sour" - id = "whiskeysour" - result = "whiskeysour" - required_reagents = list("whiskey" = 2, "lemonjuice" = 1, "sugar" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/daiquiri - name = "Daiquiri" - id = "daiquiri" - result = "daiquiri" - required_reagents = list("rum" = 3, "limejuice" = 2, "sugar" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/mintjulep - name = "Mint Julep" - id = "mintjulep" - result = "mintjulep" - required_reagents = list("whiskey" = 2, "water" = 1, "mint" = 1) - result_amount = 4 - -/datum/chemical_reaction/drinks/paloma - name = "Paloma" - id = "paloma" - result = "paloma" - required_reagents = list("orangejuice" = 1, "sodawater" = 1, "tequilla" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/mojito - name = "Mojito" - id = "mojito" - result = "mojito" - required_reagents = list("rum" = 3, "limejuice" = 1, "mint" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/virginmojito - name = "Mojito" - id = "virginmojito" - result = "virginmojito" - required_reagents = list("sodawater" = 3, "limejuice" = 1, "mint" = 1, "sugar" = 1) - result_amount = 5 - -/datum/chemical_reaction/drinks/piscosour - name = "Pisco Sour" - id = "piscosour" - result = "piscosour" - required_reagents = list("winebrandy" = 1, "lemonjuice" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/coldfront - name = "Cold Front" - id = "coldfront" - result = "coldfront" - required_reagents = list("icecoffee" = 1, "whiskey" = 1, "mint" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/godsake - name = "Gods Sake" - id = "godsake" - result = "godsake" - required_reagents = list("sake" = 2, "holywater" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/godka //Why you would put this in your body, I don't know. - name = "Godka" - id = "godka" - result = "godka" - required_reagents = list("vodka" = 1, "holywater" = 1, "ethanol" = 1, "carthatoline" = 1) - catalysts = list("enzyme" = 5, "holywater" = 5) - result_amount = 1 - -/datum/chemical_reaction/drinks/holywine - name = "Angel Ichor" - id = "holywine" - result = "holywine" - required_reagents = list("grapejuice" = 5, "gold" = 5) - catalysts = list("holywater" = 5) - result_amount = 10 - -/datum/chemical_reaction/drinks/holy_mary - name = "Holy Mary" - id = "holymary" - result = "holymary" - required_reagents = list("vodka" = 2, "holywine" = 3, "limejuice" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/angelskiss - name = "Angels Kiss" - id = "angelskiss" - result = "angelskiss" - required_reagents = list("holywine" = 1, "kahlua" = 1, "rum" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/angelswrath - name = "Angels Wrath" - id = "angelswrath" - result = "angelswrath" - required_reagents = list("rum" = 3, "spacemountainwind" = 1, "holywine" = 1, "dr_gibb" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/ichor_mead - name = "Ichor Mead" - id = "ichor_mead" - result = "ichor_mead" - required_reagents = list("holywine" = 1, "mead" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/oilslick - name = "Oil Slick" - id = "oilslick" - result = "oilslick" - required_reagents = list("cornoil" = 2, "honey" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/slimeslam - name = "Slick Slime Slammer" - id = "slimeslammer" - result = "slimeslammer" - required_reagents = list("cornoil" = 2, "peanutbutter" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/virginsexonthebeach - name = "Virgin Sex On The Beach" - id = "virginsexonthebeach" - result = "virginsexonthebeach" - required_reagents = list("orangejuice" = 3, "grenadine" = 2) - result_amount = 5 - -/datum/chemical_reaction/drinks/sexonthebeach - name = "Sex On The Beach" - id = "sexonthebeach" - result = "sexonthebeach" - required_reagents = list("virginsexonthebeach" = 5, "vodka" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/eggnog - name = "Eggnog" - id = "eggnog" - result = "eggnog" - required_reagents = list("milk" = 5, "cream" = 5, "sugar" = 5, "egg" = 3) - result_amount = 15 - -/datum/chemical_reaction/drinks/nuclearwaste_radium - name = "Nuclear Waste" - id = "nuclearwasterad" - result = "nuclearwaste" - required_reagents = list("oilslick" = 1, "radium" = 1, "limejuice" = 1) - result_amount = 2 - -/datum/chemical_reaction/drinks/nuclearwaste_uranium - name = "Nuclear Waste" - id = "nuclearwasteuran" - result = "nuclearwaste" - required_reagents = list("oilslick" = 2, "uranium" = 1) - result_amount = 3 - -/datum/chemical_reaction/drinks/sodaoil - name = "Soda Oil" - id = "sodaoil" - result = "sodaoil" - required_reagents = list("cornoil" = 4, "sodawater" = 1, "carbon" = 1, "tricordrazine" = 1) - result_amount = 6 - -/datum/chemical_reaction/drinks/fusionnaire - name = "Fusionnaire" - id = "fusionnaire" - result = "fusionnaire" - required_reagents = list("lemonjuice" = 3, "vodka" = 2, "schnapps_pep" = 1, "schnapps_lem" = 1, "rum" = 1, "ice" = 1) - result_amount = 9 - -//R-UST Port -/datum/chemical_reaction/hyrdophoron - name = "Hydrophoron" - id = "hydrophoron" - result = "hydrophoron" - required_reagents = list("hydrogen" = 1, "phoron" = 1) - inhibitors = list("nitrogen" = 1) //So it doesn't mess with lexorin - result_amount = 2 - -/datum/chemical_reaction/deuterium - name = "Deuterium" - id = "deuterium" - result = null - required_reagents = list("hydrophoron" = 5, "water" = 10) - result_amount = 15 - -/datum/chemical_reaction/deuterium/on_reaction(var/datum/reagents/holder, var/created_volume) - var/turf/T = get_turf(holder.my_atom) - if(istype(T)) new /obj/item/stack/material/deuterium(T, created_volume) - return - -//Skrellian crap. -/datum/chemical_reaction/talum_quem - name = "Talum-quem" - id = "talum_quem" - result = "talum_quem" - required_reagents = list("space_drugs" = 2, "sugar" = 1, "amatoxin" = 1) - result_amount = 4 - -/datum/chemical_reaction/qerr_quem - name = "Qerr-quem" - id = "qerr_quem" - result = "qerr_quem" - required_reagents = list("nicotine" = 1, "carbon" = 1, "sugar" = 2) - result_amount = 4 - -/datum/chemical_reaction/malish_qualem - name = "Malish-Qualem" - id = "malish-qualem" - result = "malish-qualem" - required_reagents = list("immunosuprizine" = 1, "qerr_quem" = 1, "inaprovaline" = 1) - catalysts = list("phoron" = 5) - result_amount = 2 - -// Biomass, for cloning and bioprinters -/datum/chemical_reaction/biomass - name = "Biomass" - id = "biomass" - result = "biomass" - required_reagents = list("protein" = 1, "sugar" = 1, "phoron" = 1) - result_amount = 1 // Roughly 20u per phoron sheet - -// Neutralization. - -/datum/chemical_reaction/neutralize_neurotoxic_protein - name = "Neutralize Toxic Proteins" - id = "neurotoxic_protein_neutral" - result = "protein" - required_reagents = list("anti_toxin" = 1, "neurotoxic_protein" = 2) - result_amount = 2 - -/datum/chemical_reaction/neutralize_carpotoxin - name = "Neutralize Carpotoxin" - id = "carpotoxin_neutral" - result = "protein" - required_reagents = list("radium" = 1, "carpotoxin" = 1, "sifsap" = 1) - catalysts = list("sifsap" = 10) - result_amount = 2 - -/datum/chemical_reaction/neutralize_spidertoxin - name = "Neutralize Spidertoxin" - id = "spidertoxin_neutral" - result = "protein" - required_reagents = list("radium" = 1, "spidertoxin" = 1, "sifsap" = 1) - catalysts = list("sifsap" = 10) - result_amount = 2 - -/* -==================== - Aurora Food -==================== -*/ - -/datum/chemical_reaction/coating/batter - name = "Batter" - id = "batter" - result = "batter" - required_reagents = list("egg" = 3, "flour" = 10, "water" = 5, "sodiumchloride" = 2) - result_amount = 20 - -/datum/chemical_reaction/coating/beerbatter - name = "Beer Batter" - id = "beerbatter" - result = "beerbatter" - required_reagents = list("egg" = 3, "flour" = 10, "beer" = 5, "sodiumchloride" = 2) - result_amount = 20 - -/datum/chemical_reaction/browniemix - name = "Brownie Mix" - id = "browniemix" - result = "browniemix" - required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5) - result_amount = 15 - -/datum/chemical_reaction/butter - name = "Butter" - id = "butter" - result = null - required_reagents = list("cream" = 20, "sodiumchloride" = 1) - result_amount = 1 - -/datum/chemical_reaction/butter/on_reaction(var/datum/reagents/holder, var/created_volume) - var/location = get_turf(holder.my_atom) - for(var/i = 1, i <= created_volume, i++) - new /obj/item/weapon/reagent_containers/food/snacks/spreads/butter(location) - return - -/datum/chemical_reaction/browniemix - name = "Brownie Mix" - id = "browniemix" - result = "browniemix" - required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5) - result_amount = 15 diff --git a/code/modules/reagents/holder/distilling.dm b/code/modules/reagents/holder/distilling.dm new file mode 100644 index 0000000000..1599f395d9 --- /dev/null +++ b/code/modules/reagents/holder/distilling.dm @@ -0,0 +1,26 @@ +/datum/reagents/distilling/handle_reactions() + if(QDELETED(my_atom)) + return FALSE + if(my_atom.flags & NOREACT) + return FALSE + var/reaction_occurred + var/list/eligible_reactions = list() + var/list/effect_reactions = list() + do + reaction_occurred = FALSE + for(var/i in reagent_list) + var/datum/reagent/R = i + if(SSchemistry.distilled_reactions_by_reagent[R.id]) + eligible_reactions |= SSchemistry.distilled_reactions_by_reagent[R.id] + + for(var/i in eligible_reactions) + var/decl/chemical_reaction/C = i + if(C.can_happen(src) && C.process(src)) + effect_reactions |= C + reaction_occurred = TRUE + eligible_reactions.len = 0 + while(reaction_occurred) + for(var/i in effect_reactions) + var/decl/chemical_reaction/C = i + C.post_reaction(src) + update_total() \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/holder/holder.dm similarity index 94% rename from code/modules/reagents/Chemistry-Holder.dm rename to code/modules/reagents/holder/holder.dm index aa50a4b79f..923ffb6bc9 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/holder/holder.dm @@ -1,518 +1,519 @@ -#define PROCESS_REACTION_ITER 5 //when processing a reaction, iterate this many times - -/datum/reagents - var/list/datum/reagent/reagent_list = list() - var/total_volume = 0 - var/maximum_volume = 100 - var/atom/my_atom = null - -/datum/reagents/New(var/max = 100, atom/A = null) - ..() - maximum_volume = max - my_atom = A - - //I dislike having these here but map-objects are initialised before world/New() is called. >_> - if(!SSchemistry.chemical_reagents) - //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id - var/paths = typesof(/datum/reagent) - /datum/reagent - SSchemistry.chemical_reagents = list() - for(var/path in paths) - var/datum/reagent/D = new path() - if(!D.name) - continue - SSchemistry.chemical_reagents[D.id] = D - -/datum/reagents/Destroy() - STOP_PROCESSING(SSchemistry, src) - for(var/datum/reagent/R in reagent_list) - qdel(R) - reagent_list = null - if(my_atom && my_atom.reagents == src) - my_atom.reagents = null - return ..() - -/* Internal procs */ - -/datum/reagents/proc/get_free_space() // Returns free space. - return maximum_volume - total_volume - -/datum/reagents/proc/get_master_reagent() // Returns reference to the reagent with the biggest volume. - var/the_reagent = null - var/the_volume = 0 - - for(var/datum/reagent/A in reagent_list) - if(A.volume > the_volume) - the_volume = A.volume - the_reagent = A - - return the_reagent - -/datum/reagents/proc/get_master_reagent_name() // Returns the name of the reagent with the biggest volume. - var/the_name = null - var/the_volume = 0 - for(var/datum/reagent/A in reagent_list) - if(A.volume > the_volume) - the_volume = A.volume - the_name = A.name - - return the_name - -/datum/reagents/proc/get_master_reagent_id() // Returns the id of the reagent with the biggest volume. - var/the_id = null - var/the_volume = 0 - for(var/datum/reagent/A in reagent_list) - if(A.volume > the_volume) - the_volume = A.volume - the_id = A.id - - return the_id - -/datum/reagents/proc/update_total() // Updates volume. - total_volume = 0 - for(var/datum/reagent/R in reagent_list) - if(R.volume < MINIMUM_CHEMICAL_VOLUME) - del_reagent(R.id) - else - total_volume += R.volume - return - -/datum/reagents/proc/handle_reactions() - if(QDELETED(my_atom)) - return FALSE - if(my_atom.flags & NOREACT) - return FALSE - var/reaction_occurred - var/list/eligible_reactions = list() - var/list/effect_reactions = list() - do - reaction_occurred = FALSE - for(var/i in reagent_list) - var/datum/reagent/R = i - if(SSchemistry.chemical_reactions_by_reagent[R.id]) - eligible_reactions |= SSchemistry.chemical_reactions_by_reagent[R.id] - - for(var/i in eligible_reactions) - var/datum/chemical_reaction/C = i - if(C.can_happen(src) && C.process(src)) - effect_reactions |= C - reaction_occurred = TRUE - eligible_reactions.len = 0 - while(reaction_occurred) - for(var/i in effect_reactions) - var/datum/chemical_reaction/C = i - C.post_reaction(src) - update_total() - -/* Holder-to-chemical */ - -/datum/reagents/proc/add_reagent(var/id, var/amount, var/data = null, var/safety = 0) - if(!isnum(amount) || amount <= 0) - return 0 - - update_total() - amount = min(amount, get_free_space()) - - if(istype(my_atom,/obj/item/weapon/reagent_containers/food)) //The following code is targeted specifically at getting allergen reagents into food items, since for the most part they're not applied by default. - var/list/add_reagents = list() - var/totalnum = 0 - - for(var/item in data) //Try to find the ID - var/add_reagent_id = null - if(item in SSchemistry.chemical_reagents) - add_reagent_id = item - else if("[item]juice" in SSchemistry.chemical_reagents) - add_reagent_id = "[item]juice" - if(add_reagent_id) //If we did find it, add it to our list of reagents to add, and add the number to our total. - add_reagents[add_reagent_id] += data[item] - totalnum += data[item] - - if(totalnum) - var/multconst = amount/totalnum //We're going to add these extra reagents so that they share the ratio described, but only add up to 1x the existing amount at the most - for(var/item in add_reagents) - add_reagent(item,add_reagents[item]*multconst) - - - - - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - if(current.id == "blood") - if(LAZYLEN(data) && !isnull(data["species"]) && !isnull(current.data["species"]) && data["species"] != current.data["species"]) // Species bloodtypes are already incompatible, this just stops it from mixing into the one already in a container. - continue - - current.volume += amount - if(!isnull(data)) // For all we know, it could be zero or empty string and meaningful - current.mix_data(data, amount) - update_total() - if(!safety) - handle_reactions() - if(my_atom) - my_atom.on_reagent_change() - return 1 - var/datum/reagent/D = SSchemistry.chemical_reagents[id] - if(D) - var/datum/reagent/R = new D.type() - reagent_list += R - R.holder = src - R.volume = amount - R.initialize_data(data) - update_total() - if(!safety) - handle_reactions() - if(my_atom) - my_atom.on_reagent_change() - return 1 - else - crash_with("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])") - return 0 - -/datum/reagents/proc/isolate_reagent(reagent) - for(var/A in reagent_list) - var/datum/reagent/R = A - if(R.id != reagent) - del_reagent(R.id) - update_total() - -/datum/reagents/proc/remove_reagent(var/id, var/amount, var/safety = 0) - if(!isnum(amount)) - return 0 - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - current.volume -= amount // It can go negative, but it doesn't matter - update_total() // Because this proc will delete it then - if(!safety) - handle_reactions() - if(my_atom) - my_atom.on_reagent_change() - return 1 - return 0 - -/datum/reagents/proc/del_reagent(var/id) - for(var/datum/reagent/current in reagent_list) - if (current.id == id) - reagent_list -= current - qdel(current) - update_total() - if(my_atom) - my_atom.on_reagent_change() - return 0 - -/datum/reagents/proc/has_reagent(var/id, var/amount = 0) - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - if(current.volume >= amount) - return 1 - else - return 0 - return 0 - -/datum/reagents/proc/has_any_reagent(var/list/check_reagents) - for(var/datum/reagent/current in reagent_list) - if(current.id in check_reagents) - if(current.volume >= check_reagents[current.id]) - return 1 - else - return 0 - return 0 - -/datum/reagents/proc/has_all_reagents(var/list/check_reagents) - //this only works if check_reagents has no duplicate entries... hopefully okay since it expects an associative list - var/missing = check_reagents.len - for(var/datum/reagent/current in reagent_list) - if(current.id in check_reagents) - if(current.volume >= check_reagents[current.id]) - missing-- - return !missing - -/datum/reagents/proc/clear_reagents() - for(var/datum/reagent/current in reagent_list) - del_reagent(current.id) - return - -/datum/reagents/proc/get_reagent_amount(var/id) - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - return current.volume - return 0 - -/datum/reagents/proc/get_data(var/id) - for(var/datum/reagent/current in reagent_list) - if(current.id == id) - return current.get_data() - return 0 - -/datum/reagents/proc/get_reagents() - . = list() - for(var/datum/reagent/current in reagent_list) - . += "[current.id] ([current.volume])" - return english_list(., "EMPTY", "", ", ", ", ") - -/* Holder-to-holder and similar procs */ - -/datum/reagents/proc/remove_any(var/amount = 1) // Removes up to [amount] of reagents from [src]. Returns actual amount removed. - amount = min(amount, total_volume) - - if(!amount) - return - - var/part = amount / total_volume - - for(var/datum/reagent/current in reagent_list) - var/amount_to_remove = current.volume * part - remove_reagent(current.id, amount_to_remove, 1) - - update_total() - handle_reactions() - return amount - -/datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). - if(!target || !istype(target)) - return - - amount = max(0, min(amount, total_volume, target.get_free_space() / multiplier)) - - if(!amount) - return - - var/part = amount / total_volume - - for(var/datum/reagent/current in reagent_list) - var/amount_to_transfer = current.volume * part - target.add_reagent(current.id, amount_to_transfer * multiplier, current.get_data(), safety = 1) // We don't react until everything is in place - if(!copy) - remove_reagent(current.id, amount_to_transfer, 1) - - if(!copy) - handle_reactions() - target.handle_reactions() - return amount - -/* Holder-to-atom and similar procs */ - -//The general proc for applying reagents to things. This proc assumes the reagents are being applied externally, -//not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob(). -//If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person), -//call the appropriate trans_to_*() proc. -/datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - touch(target) //First, handle mere touch effects - - if(ismob(target)) - return splash_mob(target, amount, copy) - if(isturf(target)) - return trans_to_turf(target, amount, multiplier, copy) - if(isobj(target) && target.is_open_container()) - return trans_to_obj(target, amount, multiplier, copy) - return 0 - -//Splashing reagents is messier than trans_to, the target's loc gets some of the reagents as well. -/datum/reagents/proc/splash(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0, var/min_spill=0, var/max_spill=60) - var/spill = 0 - if(!isturf(target) && target.loc) - spill = amount*(rand(min_spill, max_spill)/100) - amount -= spill - if(spill) - splash(target.loc, spill, multiplier, copy, min_spill, max_spill) - - if(!trans_to(target, amount, multiplier, copy)) - touch(target, amount) - -/datum/reagents/proc/trans_type_to(var/target, var/rtype, var/amount = 1) - if (!target) - return - - var/datum/reagent/transfering_reagent = get_reagent(rtype) - - if (istype(target, /atom)) - var/atom/A = target - if (!A.reagents || !A.simulated) - return - - amount = min(amount, transfering_reagent.volume) - - if(!amount) - return - - - var/datum/reagents/F = new /datum/reagents(amount) - var/tmpdata = get_data(rtype) - F.add_reagent(rtype, amount, tmpdata) - remove_reagent(rtype, amount) - - - if (istype(target, /atom)) - return F.trans_to(target, amount) // Let this proc check the atom's type - else if (istype(target, /datum/reagents)) - return F.trans_to_holder(target, amount) - -/datum/reagents/proc/trans_id_to(var/atom/target, var/id, var/amount = 1) - if (!target || !target.reagents) - return - - amount = min(amount, get_reagent_amount(id)) - - if(!amount) - return - - var/datum/reagents/F = new /datum/reagents(amount) - var/tmpdata = get_data(id) - F.add_reagent(id, amount, tmpdata) - remove_reagent(id, amount) - - return F.trans_to(target, amount) // Let this proc check the atom's type - -// When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. -// This does not handle transferring reagents to things. -// For example, splashing someone with water will get them wet and extinguish them if they are on fire, -// even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. -/datum/reagents/proc/touch(var/atom/target, var/amount) - if(ismob(target)) - touch_mob(target, amount) - if(isturf(target)) - touch_turf(target, amount) - if(isobj(target)) - touch_obj(target, amount) - return - -/datum/reagents/proc/touch_mob(var/mob/target) - if(!target || !istype(target)) - return - - for(var/datum/reagent/current in reagent_list) - current.touch_mob(target, current.volume) - - update_total() - -/datum/reagents/proc/touch_turf(var/turf/target, var/amount) - if(!target || !istype(target)) - return - - for(var/datum/reagent/current in reagent_list) - current.touch_turf(target, amount) - - update_total() - -/datum/reagents/proc/touch_obj(var/obj/target, var/amount) - if(!target || !istype(target)) - return - - for(var/datum/reagent/current in reagent_list) - current.touch_obj(target, amount) - - update_total() - -// Attempts to place a reagent on the mob's skin. -// Reagents are not guaranteed to transfer to the target. -// Do not call this directly, call trans_to() instead. -/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/copy = 0) - var/perm = 1 - if(isliving(target)) //will we ever even need to tranfer reagents to non-living mobs? - var/mob/living/L = target - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(H.check_shields(0, null, null, null, "the spray") == 1) //If they block the spray, it does nothing. - amount = 0 - perm = L.reagent_permeability() - return trans_to_mob(target, amount, CHEM_TOUCH, perm, copy) - -/datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder... - if(!target || !istype(target)) - return - if(iscarbon(target)) - var/mob/living/carbon/C = target - if(type == CHEM_BLOOD) - var/datum/reagents/R = C.reagents - return trans_to_holder(R, amount, multiplier, copy) - if(type == CHEM_INGEST) - var/datum/reagents/R = C.ingested - return C.ingest(src, R, amount, multiplier, copy) - if(type == CHEM_TOUCH) - var/datum/reagents/R = C.touching - return trans_to_holder(R, amount, multiplier, copy) - else - var/datum/reagents/R = new /datum/reagents(amount) - . = trans_to_holder(R, amount, multiplier, copy) - R.touch_mob(target) - -/datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Turfs don't have any reagents (at least, for now). Just touch it. - if(!target) - return - - var/datum/reagents/R = new /datum/reagents(amount * multiplier) - . = trans_to_holder(R, amount, multiplier, copy) - R.touch_turf(target, amount) - return - -/datum/reagents/proc/trans_to_obj(var/obj/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch. - if(!target) - return - - if(!target.reagents) - var/datum/reagents/R = new /datum/reagents(amount * multiplier) - . = trans_to_holder(R, amount, multiplier, copy) - R.touch_obj(target, amount) - return - - return trans_to_holder(target.reagents, amount, multiplier, copy) - -/* Atom reagent creation - use it all the time */ - -/atom/proc/create_reagents(var/max_vol) - reagents = new/datum/reagents(max_vol, src) - -// Aurora Cooking Port -/datum/reagents/proc/get_reagent(var/id) // Returns reference to reagent matching passed ID - for(var/datum/reagent/A in reagent_list) - if (A.id == id) - return A - - return null - -//Spreads the contents of this reagent holder all over the vicinity of the target turf. -/datum/reagents/proc/splash_area(var/turf/epicentre, var/range = 3, var/portion = 1.0, var/multiplier = 1, var/copy = 0) - var/list/things = dview(range, epicentre, INVISIBILITY_LIGHTING) - var/list/turfs = list() - for (var/turf/T in things) - turfs += T - if (!turfs.len) - return//Nowhere to splash to, somehow - //Create a temporary holder to hold all the amount that will be spread - var/datum/reagents/R = new /datum/reagents(total_volume * portion * multiplier) - trans_to_holder(R, total_volume * portion, multiplier, copy) - //The exact amount that will be given to each turf - var/turfportion = R.total_volume / turfs.len - for (var/turf/T in turfs) - var/datum/reagents/TR = new /datum/reagents(turfportion) - R.trans_to_holder(TR, turfportion, 1, 0) - TR.splash_turf(T) - qdel(R) - - -//Spreads the contents of this reagent holder all over the target turf, dividing among things in it. -//50% is divided between mobs, 20% between objects, and whatever is left on the turf itself -/datum/reagents/proc/splash_turf(var/turf/T, var/amount = null, var/multiplier = 1, var/copy = 0) - if (isnull(amount)) - amount = total_volume - else - amount = min(amount, total_volume) - if (amount <= 0) - return - var/list/mobs = list() - for (var/mob/M in T) - mobs += M - var/list/objs = list() - for (var/obj/O in T) - objs += O - if (objs.len) - var/objportion = (amount * 0.2) / objs.len - for (var/o in objs) - var/obj/O = o - trans_to(O, objportion, multiplier, copy) - amount = min(amount, total_volume) - if (mobs.len) - var/mobportion = (amount * 0.5) / mobs.len - for (var/m in mobs) - var/mob/M = m - trans_to(M, mobportion, multiplier, copy) - trans_to(T, total_volume, multiplier, copy) - if (total_volume <= 0) +#define PROCESS_REACTION_ITER 5 //when processing a reaction, iterate this many times + +/datum/reagents + var/list/datum/reagent/reagent_list = list() + var/total_volume = 0 + var/maximum_volume = 100 + var/atom/my_atom = null + +/datum/reagents/New(var/max = 100, atom/A = null) + ..() + maximum_volume = max + my_atom = A + + //I dislike having these here but map-objects are initialised before world/New() is called. >_> + if(!SSchemistry.chemical_reagents) + //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id + var/paths = subtypesof(/datum/reagent) + SSchemistry.chemical_reagents = list() + for(var/path in paths) + var/datum/reagent/D = new path() + if(!D.name) + continue + SSchemistry.chemical_reagents[D.id] = D + +/datum/reagents/Destroy() + for(var/datum/reagent/R in reagent_list) + qdel(R) + reagent_list = null + if(my_atom && my_atom.reagents == src) + my_atom.reagents = null + return ..() + +/* Internal procs */ + +/datum/reagents/proc/get_free_space() // Returns free space. + return maximum_volume - total_volume + +/datum/reagents/proc/get_master_reagent() // Returns reference to the reagent with the biggest volume. + var/the_reagent = null + var/the_volume = 0 + + for(var/datum/reagent/A in reagent_list) + if(A.volume > the_volume) + the_volume = A.volume + the_reagent = A + + return the_reagent + +/datum/reagents/proc/get_master_reagent_name() // Returns the name of the reagent with the biggest volume. + var/the_name = null + var/the_volume = 0 + for(var/datum/reagent/A in reagent_list) + if(A.volume > the_volume) + the_volume = A.volume + the_name = A.name + + return the_name + +/datum/reagents/proc/get_master_reagent_id() // Returns the id of the reagent with the biggest volume. + var/the_id = null + var/the_volume = 0 + for(var/datum/reagent/A in reagent_list) + if(A.volume > the_volume) + the_volume = A.volume + the_id = A.id + + return the_id + +/datum/reagents/proc/update_total() // Updates volume. + total_volume = 0 + for(var/datum/reagent/R in reagent_list) + if(R.volume < MINIMUM_CHEMICAL_VOLUME) + del_reagent(R.id) + else + total_volume += R.volume + return + +/datum/reagents/proc/handle_reactions() + if(QDELETED(my_atom)) + return FALSE + if(my_atom.flags & NOREACT) + return FALSE + var/reaction_occurred + var/list/eligible_reactions = list() + var/list/effect_reactions = list() + do + reaction_occurred = FALSE + for(var/i in reagent_list) + var/datum/reagent/R = i + if(SSchemistry.instant_reactions_by_reagent[R.id]) + eligible_reactions |= SSchemistry.instant_reactions_by_reagent[R.id] + + for(var/i in eligible_reactions) + var/decl/chemical_reaction/C = i + if(C.can_happen(src) && C.process(src)) + effect_reactions |= C + reaction_occurred = TRUE + eligible_reactions.len = 0 + while(reaction_occurred) + for(var/i in effect_reactions) + var/decl/chemical_reaction/C = i + C.post_reaction(src) + update_total() + +/* Holder-to-chemical */ + +/datum/reagents/proc/add_reagent(var/id, var/amount, var/data = null, var/safety = 0) + if(!isnum(amount) || amount <= 0) + return 0 + + update_total() + amount = min(amount, get_free_space()) + + if(istype(my_atom,/obj/item/weapon/reagent_containers/food)) //The following code is targeted specifically at getting allergen reagents into food items, since for the most part they're not applied by default. + var/list/add_reagents = list() + var/totalnum = 0 + + for(var/item in data) //Try to find the ID + var/add_reagent_id = null + if(item in SSchemistry.chemical_reagents) + add_reagent_id = item + else if("[item]juice" in SSchemistry.chemical_reagents) + add_reagent_id = "[item]juice" + if(add_reagent_id) //If we did find it, add it to our list of reagents to add, and add the number to our total. + add_reagents[add_reagent_id] += data[item] + totalnum += data[item] + + if(totalnum) + var/multconst = amount/totalnum //We're going to add these extra reagents so that they share the ratio described, but only add up to 1x the existing amount at the most + for(var/item in add_reagents) + add_reagent(item,add_reagents[item]*multconst) + + + + + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + if(current.id == "blood") + if(LAZYLEN(data) && !isnull(data["species"]) && !isnull(current.data["species"]) && data["species"] != current.data["species"]) // Species bloodtypes are already incompatible, this just stops it from mixing into the one already in a container. + continue + + current.volume += amount + if(!isnull(data)) // For all we know, it could be zero or empty string and meaningful + current.mix_data(data, amount) + update_total() + if(!safety) + handle_reactions() + if(my_atom) + my_atom.on_reagent_change() + return 1 + var/datum/reagent/D = SSchemistry.chemical_reagents[id] + if(D) + var/datum/reagent/R = new D.type() + reagent_list += R + R.holder = src + R.volume = amount + R.initialize_data(data) + update_total() + if(!safety) + handle_reactions() + if(my_atom) + my_atom.on_reagent_change() + return 1 + else + crash_with("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])") + return 0 + +/datum/reagents/proc/isolate_reagent(reagent) + for(var/A in reagent_list) + var/datum/reagent/R = A + if(R.id != reagent) + del_reagent(R.id) + update_total() + +/datum/reagents/proc/remove_reagent(var/id, var/amount, var/safety = 0) + if(!isnum(amount)) + return 0 + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + current.volume -= amount // It can go negative, but it doesn't matter + update_total() // Because this proc will delete it then + if(!safety) + handle_reactions() + if(my_atom) + my_atom.on_reagent_change() + return 1 + return 0 + +/datum/reagents/proc/del_reagent(var/id) + for(var/datum/reagent/current in reagent_list) + if (current.id == id) + reagent_list -= current + qdel(current) + update_total() + if(my_atom) + my_atom.on_reagent_change() + return 0 + +/datum/reagents/proc/has_reagent(var/id, var/amount = 0) + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + if(current.volume >= amount) + return 1 + else + return 0 + return 0 + +/datum/reagents/proc/has_any_reagent(var/list/check_reagents) + for(var/datum/reagent/current in reagent_list) + if(current.id in check_reagents) + if(current.volume >= check_reagents[current.id]) + return 1 + else + return 0 + return 0 + +/datum/reagents/proc/has_all_reagents(var/list/check_reagents) + //this only works if check_reagents has no duplicate entries... hopefully okay since it expects an associative list + var/missing = check_reagents.len + for(var/datum/reagent/current in reagent_list) + if(current.id in check_reagents) + if(current.volume >= check_reagents[current.id]) + missing-- + return !missing + +/datum/reagents/proc/clear_reagents() + for(var/datum/reagent/current in reagent_list) + del_reagent(current.id) + return + +/datum/reagents/proc/get_reagent_amount(var/id) + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + return current.volume + return 0 + +/datum/reagents/proc/get_data(var/id) + for(var/datum/reagent/current in reagent_list) + if(current.id == id) + return current.get_data() + return 0 + +/datum/reagents/proc/get_reagents() + . = list() + for(var/datum/reagent/current in reagent_list) + . += "[current.id] ([current.volume])" + return english_list(., "EMPTY", "", ", ", ", ") + +/* Holder-to-holder and similar procs */ + +/datum/reagents/proc/remove_any(var/amount = 1) // Removes up to [amount] of reagents from [src]. Returns actual amount removed. + amount = min(amount, total_volume) + + if(!amount) + return + + var/part = amount / total_volume + + for(var/datum/reagent/current in reagent_list) + var/amount_to_remove = current.volume * part + remove_reagent(current.id, amount_to_remove, 1) + + update_total() + handle_reactions() + return amount + +/datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). + if(!target || !istype(target)) + return + + amount = max(0, min(amount, total_volume, target.get_free_space() / multiplier)) + + if(!amount) + return + + var/part = amount / total_volume + + for(var/datum/reagent/current in reagent_list) + var/amount_to_transfer = current.volume * part + target.add_reagent(current.id, amount_to_transfer * multiplier, current.get_data(), safety = 1) // We don't react until everything is in place + if(!copy) + remove_reagent(current.id, amount_to_transfer, 1) + + if(!copy) + handle_reactions() + target.handle_reactions() + return amount + +/* Holder-to-atom and similar procs */ + +//The general proc for applying reagents to things. This proc assumes the reagents are being applied externally, +//not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob(). +//If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person), +//call the appropriate trans_to_*() proc. +/datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + touch(target) //First, handle mere touch effects + + if(ismob(target)) + return splash_mob(target, amount, copy) + if(isturf(target)) + return trans_to_turf(target, amount, multiplier, copy) + if(isobj(target) && target.is_open_container()) + return trans_to_obj(target, amount, multiplier, copy) + return 0 + +//Splashing reagents is messier than trans_to, the target's loc gets some of the reagents as well. +/datum/reagents/proc/splash(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0, var/min_spill=0, var/max_spill=60) + var/spill = 0 + if(!isturf(target) && target.loc) + spill = amount*(rand(min_spill, max_spill)/100) + amount -= spill + if(spill) + splash(target.loc, spill, multiplier, copy, min_spill, max_spill) + + if(!trans_to(target, amount, multiplier, copy)) + touch(target, amount) + +/datum/reagents/proc/trans_type_to(var/target, var/rtype, var/amount = 1) + if (!target) + return + + var/datum/reagent/transfering_reagent = get_reagent(rtype) + + if (istype(target, /atom)) + var/atom/A = target + if (!A.reagents || !A.simulated) + return + + amount = min(amount, transfering_reagent.volume) + + if(!amount) + return + + + var/datum/reagents/F = new /datum/reagents(amount) + var/tmpdata = get_data(rtype) + F.add_reagent(rtype, amount, tmpdata) + remove_reagent(rtype, amount) + + + if (istype(target, /atom)) + return F.trans_to(target, amount) // Let this proc check the atom's type + else if (istype(target, /datum/reagents)) + return F.trans_to_holder(target, amount) + +/datum/reagents/proc/trans_id_to(var/atom/target, var/id, var/amount = 1) + if (!target || !target.reagents) + return + + amount = min(amount, get_reagent_amount(id)) + + if(!amount) + return + + var/datum/reagents/F = new /datum/reagents(amount) + var/tmpdata = get_data(id) + F.add_reagent(id, amount, tmpdata) + remove_reagent(id, amount) + + return F.trans_to(target, amount) // Let this proc check the atom's type + +// When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. +// This does not handle transferring reagents to things. +// For example, splashing someone with water will get them wet and extinguish them if they are on fire, +// even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. +/datum/reagents/proc/touch(var/atom/target, var/amount) + if(ismob(target)) + touch_mob(target, amount) + if(isturf(target)) + touch_turf(target, amount) + if(isobj(target)) + touch_obj(target, amount) + return + +/datum/reagents/proc/touch_mob(var/mob/target) + if(!target || !istype(target)) + return + + for(var/datum/reagent/current in reagent_list) + current.touch_mob(target, current.volume) + + update_total() + +/datum/reagents/proc/touch_turf(var/turf/target, var/amount) + if(!target || !istype(target)) + return + + for(var/datum/reagent/current in reagent_list) + current.touch_turf(target, amount) + + update_total() + +/datum/reagents/proc/touch_obj(var/obj/target, var/amount) + if(!target || !istype(target)) + return + + for(var/datum/reagent/current in reagent_list) + current.touch_obj(target, amount) + + update_total() + +// Attempts to place a reagent on the mob's skin. +// Reagents are not guaranteed to transfer to the target. +// Do not call this directly, call trans_to() instead. +/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/copy = 0) + var/perm = 1 + if(isliving(target)) //will we ever even need to tranfer reagents to non-living mobs? + var/mob/living/L = target + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(H.check_shields(0, null, null, null, "the spray") == 1) //If they block the spray, it does nothing. + amount = 0 + perm = L.reagent_permeability() + return trans_to_mob(target, amount, CHEM_TOUCH, perm, copy) + +/datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder... + if(!target || !istype(target)) + return + if(iscarbon(target)) + var/mob/living/carbon/C = target + if(type == CHEM_BLOOD) + var/datum/reagents/R = C.reagents + return trans_to_holder(R, amount, multiplier, copy) + if(type == CHEM_INGEST) + var/datum/reagents/R = C.ingested + return C.ingest(src, R, amount, multiplier, copy) + if(type == CHEM_TOUCH) + var/datum/reagents/R = C.touching + return trans_to_holder(R, amount, multiplier, copy) + else + var/datum/reagents/R = new /datum/reagents(amount) + . = trans_to_holder(R, amount, multiplier, copy) + R.touch_mob(target) + +/datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Turfs don't have any reagents (at least, for now). Just touch it. + if(!target) + return + + var/datum/reagents/R = new /datum/reagents(amount * multiplier) + . = trans_to_holder(R, amount, multiplier, copy) + R.touch_turf(target, amount) + return + +/datum/reagents/proc/trans_to_obj(var/obj/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch. + if(!target) + return + + if(!target.reagents) + var/datum/reagents/R = new /datum/reagents(amount * multiplier) + . = trans_to_holder(R, amount, multiplier, copy) + R.touch_obj(target, amount) + return + + return trans_to_holder(target.reagents, amount, multiplier, copy) + +/* Atom reagent creation - use it all the time */ + +/atom/proc/create_reagents(var/max_vol, var/reagents_type = /datum/reagents) + if(!ispath(reagents_type)) + reagents_type = /datum/reagents + reagents = new reagents_type(max_vol, src) + +// Aurora Cooking Port +/datum/reagents/proc/get_reagent(var/id) // Returns reference to reagent matching passed ID + for(var/datum/reagent/A in reagent_list) + if (A.id == id) + return A + + return null + +//Spreads the contents of this reagent holder all over the vicinity of the target turf. +/datum/reagents/proc/splash_area(var/turf/epicentre, var/range = 3, var/portion = 1.0, var/multiplier = 1, var/copy = 0) + var/list/things = dview(range, epicentre, INVISIBILITY_LIGHTING) + var/list/turfs = list() + for (var/turf/T in things) + turfs += T + if (!turfs.len) + return//Nowhere to splash to, somehow + //Create a temporary holder to hold all the amount that will be spread + var/datum/reagents/R = new /datum/reagents(total_volume * portion * multiplier) + trans_to_holder(R, total_volume * portion, multiplier, copy) + //The exact amount that will be given to each turf + var/turfportion = R.total_volume / turfs.len + for (var/turf/T in turfs) + var/datum/reagents/TR = new /datum/reagents(turfportion) + R.trans_to_holder(TR, turfportion, 1, 0) + TR.splash_turf(T) + qdel(R) + + +//Spreads the contents of this reagent holder all over the target turf, dividing among things in it. +//50% is divided between mobs, 20% between objects, and whatever is left on the turf itself +/datum/reagents/proc/splash_turf(var/turf/T, var/amount = null, var/multiplier = 1, var/copy = 0) + if (isnull(amount)) + amount = total_volume + else + amount = min(amount, total_volume) + if (amount <= 0) + return + var/list/mobs = list() + for (var/mob/M in T) + mobs += M + var/list/objs = list() + for (var/obj/O in T) + objs += O + if (objs.len) + var/objportion = (amount * 0.2) / objs.len + for (var/o in objs) + var/obj/O = o + trans_to(O, objportion, multiplier, copy) + amount = min(amount, total_volume) + if (mobs.len) + var/mobportion = (amount * 0.5) / mobs.len + for (var/m in mobs) + var/mob/M = m + trans_to(M, mobportion, multiplier, copy) + trans_to(T, total_volume, multiplier, copy) + if (total_volume <= 0) qdel(src) \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/machinery/chem_master.dm similarity index 58% rename from code/modules/reagents/Chemistry-Machinery.dm rename to code/modules/reagents/machinery/chem_master.dm index 39ddc4ae04..be9288160f 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/machinery/chem_master.dm @@ -1,856 +1,498 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 - -#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites -#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites -#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once -#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill -#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch -#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume) -#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever - - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/obj/machinery/chem_master - name = "ChemMaster 3000" - desc = "Used to seperate and package chemicals in to patches, pills, or bottles. Warranty void if used to create Space Drugs." - density = 1 - anchored = 1 - icon = 'icons/obj/chemical.dmi' - icon_state = "mixer0" - circuit = /obj/item/weapon/circuitboard/chem_master - use_power = USE_POWER_IDLE - idle_power_usage = 20 - var/obj/item/weapon/reagent_containers/beaker = null - var/obj/item/weapon/storage/pill_bottle/loaded_pill_bottle = null - var/mode = 0 - var/condi = 0 - var/useramount = 15 // Last used amount - var/pillamount = 10 - var/list/bottle_styles - var/bottlesprite = 1 - var/pillsprite = 1 - var/max_pill_count = 20 - var/printing = FALSE - flags = OPENCONTAINER - clicksound = "button" - -/obj/machinery/chem_master/New() - ..() - var/datum/reagents/R = new/datum/reagents(900) //Just a huge random number so the buffer should (probably) never dump your reagents. - reagents = R //There should be a nano ui thingy to warn of this. - R.my_atom = src - -/obj/machinery/chem_master/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - return - if(2.0) - if (prob(50)) - qdel(src) - return - -/obj/machinery/chem_master/update_icon() - icon_state = "mixer[beaker ? "1" : "0"]" - -/obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) - - if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food)) - - if(src.beaker) - to_chat(user, "\A [beaker] is already loaded into the machine.") - return - src.beaker = B - user.drop_item() - B.loc = src - to_chat(user, "You add \the [B] to the machine.") - update_icon() - - else if(istype(B, /obj/item/weapon/storage/pill_bottle)) - - if(src.loaded_pill_bottle) - to_chat(user, "A \the [loaded_pill_bottle] s already loaded into the machine.") - return - - src.loaded_pill_bottle = B - user.drop_item() - B.loc = src - to_chat(user, "You add \the [loaded_pill_bottle] into the dispenser slot.") - - else if(default_unfasten_wrench(user, B, 20)) - return - if(default_deconstruction_screwdriver(user, B)) - return - if(default_deconstruction_crowbar(user, B)) - return - - return - -/obj/machinery/chem_master/attack_hand(mob/user as mob) - if(stat & BROKEN) - return - user.set_machine(src) - tgui_interact(user) - -/obj/machinery/chem_master/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/chem_master), - ) - -/obj/machinery/chem_master/tgui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "ChemMaster", name) - ui.open() - -/** - * Display the NanoUI window for the chem master. - * - * See NanoUI documentation for details. - */ -/obj/machinery/chem_master/tgui_data(mob/user) - var/list/data = list() - - data["condi"] = condi - - data["loaded_pill_bottle"] = !!loaded_pill_bottle - if(loaded_pill_bottle) - data["loaded_pill_bottle_name"] = loaded_pill_bottle.name - data["loaded_pill_bottle_contents_len"] = loaded_pill_bottle.contents.len - data["loaded_pill_bottle_storage_slots"] = loaded_pill_bottle.max_storage_space - - data["beaker"] = !!beaker - if(beaker) - var/list/beaker_reagents_list = list() - data["beaker_reagents"] = beaker_reagents_list - for(var/datum/reagent/R in beaker.reagents.reagent_list) - beaker_reagents_list[++beaker_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "description" = R.description, "id" = R.id) - - var/list/buffer_reagents_list = list() - data["buffer_reagents"] = buffer_reagents_list - for(var/datum/reagent/R in reagents.reagent_list) - buffer_reagents_list[++buffer_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "id" = R.id, "description" = R.description) - - data["pillsprite"] = pillsprite - data["bottlesprite"] = bottlesprite - data["mode"] = mode - data["printing"] = printing - - // Transfer modal information if there is one - data["modal"] = tgui_modal_data(src) - - return data - -/** - * Called in tgui_act() to process modal actions - * - * Arguments: - * * action - The action passed by tgui - * * params - The params passed by tgui - */ -/obj/machinery/chem_master/proc/tgui_act_modal(action, params, datum/tgui/ui, datum/tgui_state/state) - . = TRUE - var/id = params["id"] // The modal's ID - var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] - switch(tgui_modal_act(src, action, params)) - if(TGUI_MODAL_OPEN) - switch(id) - if("analyze") - var/idx = text2num(arguments["idx"]) || 0 - var/from_beaker = text2num(arguments["beaker"]) || FALSE - var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list - if(idx < 1 || idx > length(reagent_list)) - return - - var/datum/reagent/R = reagent_list[idx] - var/list/result = list("idx" = idx, "name" = R.name, "desc" = R.description) - if(!condi && istype(R, /datum/reagent/blood)) - var/datum/reagent/blood/B = R - result["blood_type"] = B.data["blood_type"] - result["blood_dna"] = B.data["blood_DNA"] - - arguments["analysis"] = result - tgui_modal_message(src, id, "", null, arguments) - // if("change_pill_bottle_style") - // if(!loaded_pill_bottle) - // return - // if(!pill_bottle_wrappers) - // pill_bottle_wrappers = list( - // "CLEAR" = "Default", - // COLOR_RED = "Red", - // COLOR_GREEN = "Green", - // COLOR_PALE_BTL_GREEN = "Pale green", - // COLOR_BLUE = "Blue", - // COLOR_CYAN_BLUE = "Light blue", - // COLOR_TEAL = "Teal", - // COLOR_YELLOW = "Yellow", - // COLOR_ORANGE = "Orange", - // COLOR_PINK = "Pink", - // COLOR_MAROON = "Brown" - // ) - // var/current = pill_bottle_wrappers[loaded_pill_bottle.wrapper_color] || "Default" - // tgui_modal_choice(src, id, "Please select a pill bottle wrapper:", null, arguments, current, pill_bottle_wrappers) - if("addcustom") - if(!beaker || !beaker.reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount to transfer to buffer:", null, arguments, useramount) - if("removecustom") - if(!reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount to transfer to [mode ? "beaker" : "disposal"]:", null, arguments, useramount) - if("create_condi_pack") - if(!condi || !reagents.total_volume) - return - tgui_modal_input(src, id, "Please name your new condiment pack:", null, arguments, reagents.get_master_reagent_name(), MAX_CUSTOM_NAME_LEN) - if("create_pill") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_pill = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PILL) - var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_pill]u)" - var/pills_text = num == 1 ? "new pill" : "[num] new pills" - tgui_modal_input(src, id, "Please name your [pills_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_pill_multiple") - if(condi || !reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount of pills to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) - if("change_pill_style") - var/list/choices = list() - for(var/i = 1 to MAX_PILL_SPRITE) - choices += "pill[i].png" - tgui_modal_bento(src, id, "Please select the new style for pills:", null, arguments, pillsprite, choices) - if("create_patch") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_patch = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PATCH) - var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_patch]u)" - var/patches_text = num == 1 ? "new patch" : "[num] new patches" - tgui_modal_input(src, id, "Please name your [patches_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_patch_multiple") - if(condi || !reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount of patches to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) - if("create_bottle") - if(condi || !reagents.total_volume) - return - var/num = round(text2num(arguments["num"] || 1)) - if(!num) - return - arguments["num"] = num - var/amount_per_bottle = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_BOTTLE) - var/default_name = "[reagents.get_master_reagent_name()]" - var/bottles_text = num == 1 ? "new bottle" : "[num] new bottles" - tgui_modal_input(src, id, "Please name your [bottles_text] ([amount_per_bottle]u in bottle):", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) - if("create_bottle_multiple") - if(condi || !reagents.total_volume) - return - tgui_modal_input(src, id, "Please enter the amount of bottles to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) - if("change_bottle_style") - var/list/choices = list() - for(var/i = 1 to MAX_BOTTLE_SPRITE) - choices += "bottle-[i].png" - tgui_modal_bento(src, id, "Please select the new style for bottles:", null, arguments, bottlesprite, choices) - else - return FALSE - if(TGUI_MODAL_ANSWER) - var/answer = params["answer"] - switch(id) - // if("change_pill_bottle_style") - // if(!pill_bottle_wrappers || !loaded_pill_bottle) // wat? - // return - // var/color = "CLEAR" - // for(var/col in pill_bottle_wrappers) - // var/col_name = pill_bottle_wrappers[col] - // if(col_name == answer) - // color = col - // break - // if(length(color) && color != "CLEAR") - // loaded_pill_bottle.wrapper_color = color - // loaded_pill_bottle.apply_wrap() - // else - // loaded_pill_bottle.wrapper_color = null - // loaded_pill_bottle.cut_overlays() - if("addcustom") - var/amount = isgoodnumber(text2num(answer)) - if(!amount || !arguments["id"]) - return - tgui_act("add", list("id" = arguments["id"], "amount" = amount), ui, state) - if("removecustom") - var/amount = isgoodnumber(text2num(answer)) - if(!amount || !arguments["id"]) - return - tgui_act("remove", list("id" = arguments["id"], "amount" = amount), ui, state) - if("create_condi_pack") - if(!condi || !reagents.total_volume) - return - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/obj/item/weapon/reagent_containers/pill/P = new(loc) - P.name = "[answer] pack" - P.desc = "A small condiment pack. The label says it contains [answer]." - P.icon_state = "bouilloncube"//Reskinned monkey cube - reagents.trans_to_obj(P, 10) - if("create_pill") - if(condi || !reagents.total_volume) - return - var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_pill = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PILL) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these pills!") - return - - var/obj/item/weapon/reagent_containers/pill/P = new(loc) - P.name = "[answer] pill" - P.pixel_x = rand(-7, 7) // Random position - P.pixel_y = rand(-7, 7) - P.icon_state = "pill[pillsprite]" - if(P.icon_state in list("pill1", "pill2", "pill3", "pill4")) // if using greyscale, take colour from reagent - P.color = reagents.get_color() - reagents.trans_to_obj(P, amount_per_pill) - // Load the pills in the bottle if there's one loaded - if(istype(loaded_pill_bottle) && length(loaded_pill_bottle.contents) < loaded_pill_bottle.max_storage_space) - P.forceMove(loaded_pill_bottle) - if("create_pill_multiple") - if(condi || !reagents.total_volume) - return - tgui_act("modal_open", list("id" = "create_pill", "arguments" = list("num" = answer)), ui, state) - if("change_pill_style") - var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_PILL_SPRITE) - if(!new_style) - return - pillsprite = new_style - if("create_patch") - if(condi || !reagents.total_volume) - return - var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_patch = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PATCH) - // var/is_medical_patch = chemical_safety_check(reagents) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these patches!") - return - - var/obj/item/weapon/reagent_containers/pill/patch/P = new(loc) - P.name = "[answer] patch" - P.pixel_x = rand(-7, 7) // random position - P.pixel_y = rand(-7, 7) - reagents.trans_to_obj(P, amount_per_patch) - // if(is_medical_patch) - // P.instant_application = TRUE - // P.icon_state = "bandaid_med" - if("create_patch_multiple") - if(condi || !reagents.total_volume) - return - tgui_act("modal_open", list("id" = "create_patch", "arguments" = list("num" = answer)), ui, state) - if("create_bottle") - if(condi || !reagents.total_volume) - return - var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) - if(!count) - return - - if(!length(answer)) - answer = reagents.get_master_reagent_name() - var/amount_per_bottle = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_BOTTLE) - while(count--) - if(reagents.total_volume <= 0) - to_chat(usr, "Not enough reagents to create these bottles!") - return - var/obj/item/weapon/reagent_containers/glass/bottle/P = new(loc) - P.name = "[answer] bottle" - P.pixel_x = rand(-7, 7) // random position - P.pixel_y = rand(-7, 7) - P.icon_state = "bottle-[bottlesprite]" || "bottle-1" - reagents.trans_to_obj(P, amount_per_bottle) - P.update_icon() - if("create_bottle_multiple") - if(condi || !reagents.total_volume) - return - tgui_act("modal_open", list("id" = "create_bottle", "arguments" = list("num" = answer)), ui, state) - if("change_bottle_style") - var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_BOTTLE_SPRITE) - if(!new_style) - return - bottlesprite = new_style - else - return FALSE - else - return FALSE - -/obj/machinery/chem_master/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state) - if(..()) - return TRUE - - if(tgui_act_modal(action, params, ui, state)) - return TRUE - - add_fingerprint(usr) - usr.set_machine(src) - - . = TRUE - switch(action) - if("toggle") - mode = !mode - if("ejectp") - if(loaded_pill_bottle) - loaded_pill_bottle.forceMove(get_turf(src)) - if(Adjacent(usr) && !issilicon(usr)) - usr.put_in_hands(loaded_pill_bottle) - loaded_pill_bottle = null - if("print") - if(printing || condi) - return - - var/idx = text2num(params["idx"]) || 0 - var/from_beaker = text2num(params["beaker"]) || FALSE - var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list - if(idx < 1 || idx > length(reagent_list)) - return - - var/datum/reagent/R = reagent_list[idx] - - printing = TRUE - visible_message("[src] rattles and prints out a sheet of paper.") - // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) - - var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) - P.info = "
Chemical Analysis

" - P.info += "Time of analysis: [worldtime2stationtime(world.time)]

" - P.info += "Chemical name: [R.name]
" - if(istype(R, /datum/reagent/blood)) - var/datum/reagent/blood/B = R - P.info += "Description: N/A
Blood Type: [B.data["blood_type"]]
DNA: [B.data["blood_DNA"]]" - else - P.info += "Description: [R.description]" - P.info += "

Notes:
" - P.name = "Chemical Analysis - [R.name]" - spawn(50) - printing = FALSE - else - . = FALSE - - if(. || !beaker) - return - - . = TRUE - var/datum/reagents/R = beaker.reagents - switch(action) - if("add") - var/id = params["id"] - var/amount = text2num(params["amount"]) - if(!id || !amount) - return - R.trans_id_to(src, id, amount) - if("remove") - var/id = params["id"] - var/amount = text2num(params["amount"]) - if(!id || !amount) - return - if(mode) - reagents.trans_id_to(beaker, id, amount) - else - reagents.remove_reagent(id, amount) - if("eject") - if(!beaker) - return - beaker.forceMove(get_turf(src)) - if(Adjacent(usr) && !issilicon(usr)) - usr.put_in_hands(beaker) - beaker = null - reagents.clear_reagents() - update_icon() - if("create_condi_bottle") - if(!condi || !reagents.total_volume) - return - var/obj/item/weapon/reagent_containers/food/condiment/P = new(loc) - reagents.trans_to_obj(P, 50) - else - return FALSE - -/obj/machinery/chem_master/attack_ai(mob/user) - return attack_hand(user) - -/obj/machinery/chem_master/proc/isgoodnumber(num) - if(isnum(num)) - if(num > 200) - num = 200 - else if(num < 0) - num = 1 - return num - else - return FALSE - -// /obj/machinery/chem_master/proc/chemical_safety_check(datum/reagents/R) -// var/all_safe = TRUE -// for(var/datum/reagent/A in R.reagent_list) -// if(!GLOB.safe_chem_list.Find(A.id)) -// all_safe = FALSE -// return all_safe - -/obj/machinery/chem_master/condimaster - name = "CondiMaster 3000" - condi = 1 - -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -/obj/machinery/reagentgrinder - - name = "All-In-One Grinder" - desc = "Grinds stuff into itty bitty bits." - icon = 'icons/obj/kitchen.dmi' - icon_state = "juicer1" - density = 0 - anchored = 0 - use_power = USE_POWER_IDLE - idle_power_usage = 5 - active_power_usage = 100 - circuit = /obj/item/weapon/circuitboard/grinder - var/inuse = 0 - var/obj/item/weapon/reagent_containers/beaker = null - var/limit = 10 - var/list/holdingitems = list() - var/list/sheet_reagents = list( //have a number of reageents divisible by REAGENTS_PER_SHEET (default 20) unless you like decimals, - /obj/item/stack/material/iron = list("iron"), - /obj/item/stack/material/uranium = list("uranium"), - /obj/item/stack/material/phoron = list("phoron"), - /obj/item/stack/material/gold = list("gold"), - /obj/item/stack/material/silver = list("silver"), - /obj/item/stack/material/platinum = list("platinum"), - /obj/item/stack/material/mhydrogen = list("hydrogen"), - /obj/item/stack/material/steel = list("iron", "carbon"), - /obj/item/stack/material/plasteel = list("iron", "iron", "carbon", "carbon", "platinum"), //8 iron, 8 carbon, 4 platinum, - /obj/item/stack/material/snow = list("water"), - /obj/item/stack/material/sandstone = list("silicon", "oxygen"), - /obj/item/stack/material/glass = list("silicon"), - /obj/item/stack/material/glass/phoronglass = list("platinum", "silicon", "silicon", "silicon"), //5 platinum, 15 silicon, - ) - - var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine") - var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject") - var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind") - // var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice") - // var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix") - -/obj/machinery/reagentgrinder/Initialize() - . = ..() - beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) - default_apply_parts() - -/obj/machinery/reagentgrinder/examine(mob/user) - . = ..() - if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) - . += "You're too far away to examine [src]'s contents and display!" - return - - if(inuse) - . += "\The [src] is operating." - return - - if(beaker || length(holdingitems)) - . += "\The [src] contains:" - if(beaker) - . += "- \A [beaker]." - for(var/i in holdingitems) - var/obj/item/O = i - . += "- \A [O.name]." - - if(!(stat & (NOPOWER|BROKEN))) - . += "The status display reads:\n" - if(beaker) - for(var/datum/reagent/R in beaker.reagents.reagent_list) - . += "- [R.volume] units of [R.name]." - -/obj/machinery/reagentgrinder/update_icon() - icon_state = "juicer"+num2text(!isnull(beaker)) - return - -/obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(beaker) - if(default_deconstruction_screwdriver(user, O)) - return - if(default_deconstruction_crowbar(user, O)) - return - - if (istype(O,/obj/item/weapon/reagent_containers/glass) || \ - istype(O,/obj/item/weapon/reagent_containers/food/drinks/glass2) || \ - istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) - - if (beaker) - return 1 - else - src.beaker = O - user.drop_item() - O.loc = src - update_icon() - src.updateUsrDialog() - return 0 - - if(holdingitems && holdingitems.len >= limit) - to_chat(user, "The machine cannot hold anymore items.") - return 1 - - if(!istype(O)) - return - - if(istype(O,/obj/item/weapon/storage/bag/plants)) - var/obj/item/weapon/storage/bag/plants/bag = O - var/failed = 1 - for(var/obj/item/G in O.contents) - if(!G.reagents || !G.reagents.total_volume) - continue - failed = 0 - bag.remove_from_storage(G, src) - holdingitems += G - if(holdingitems && holdingitems.len >= limit) - break - - if(failed) - to_chat(user, "Nothing in the plant bag is usable.") - return 1 - - if(!O.contents.len) - to_chat(user, "You empty \the [O] into \the [src].") - else - to_chat(user, "You fill \the [src] from \the [O].") - - src.updateUsrDialog() - return 0 - - if(istype(O,/obj/item/weapon/gripper)) - var/obj/item/weapon/gripper/B = O //B, for Borg. - if(!B.wrapped) - to_chat(user, "\The [B] is not holding anything.") - return 0 - else - var/B_held = B.wrapped - to_chat(user, "You use \the [B] to load \the [src] with \the [B_held].") - - return 0 - - if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume)) - to_chat(user, "\The [O] is not suitable for blending.") - return 1 - - user.remove_from_mob(O) - O.loc = src - holdingitems += O - return 0 - -/obj/machinery/reagentgrinder/AltClick(mob/user) - . = ..() - if(user.incapacitated() || !Adjacent(user)) - return - replace_beaker(user) - -/obj/machinery/reagentgrinder/attack_hand(mob/user as mob) - interact(user) - -/obj/machinery/reagentgrinder/interact(mob/user as mob) // The microwave Menu //I am reasonably certain that this is not a microwave - if(inuse || user.incapacitated()) - return - - var/list/options = list() - - if(beaker || length(holdingitems)) - options["eject"] = radial_eject - - if(isAI(user)) - if(stat & NOPOWER) - return - options["examine"] = radial_examine - - // if there is no power or it's broken, the procs will fail but the buttons will still show - if(length(holdingitems)) - options["grind"] = radial_grind - - var/choice - if(length(options) < 1) - return - if(length(options) == 1) - for(var/key in options) - choice = key - else - choice = show_radial_menu(user, src, options, require_near = !issilicon(user)) - - // post choice verification - if(inuse || (isAI(user) && stat & NOPOWER) || user.incapacitated()) - return - - switch(choice) - if("eject") - eject(user) - if("grind") - grind(user) - if("examine") - examine(user) - -/obj/machinery/reagentgrinder/proc/eject(mob/user) - if(user.incapacitated()) - return - for(var/obj/item/O in holdingitems) - O.loc = src.loc - holdingitems -= O - holdingitems.Cut() - if(beaker) - replace_beaker(user) - -/obj/machinery/reagentgrinder/proc/grind() - - power_change() - if(stat & (NOPOWER|BROKEN)) - return - - // Sanity check. - if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) - return - - playsound(src, 'sound/machines/blender.ogg', 50, 1) - inuse = 1 - - // Reset the machine. - spawn(60) - inuse = 0 - - // Process. - for (var/obj/item/O in holdingitems) - - var/remaining_volume = beaker.reagents.maximum_volume - beaker.reagents.total_volume - if(remaining_volume <= 0) - break - - if(sheet_reagents[O.type]) - var/obj/item/stack/stack = O - if(istype(stack)) - var/list/sheet_components = sheet_reagents[stack.type] - var/amount_to_take = max(0,min(stack.amount,round(remaining_volume/REAGENTS_PER_SHEET))) - if(amount_to_take) - stack.use(amount_to_take) - if(QDELETED(stack)) - holdingitems -= stack - if(islist(sheet_components)) - amount_to_take = (amount_to_take/(sheet_components.len)) - for(var/i in sheet_components) - beaker.reagents.add_reagent(i, (amount_to_take*REAGENTS_PER_SHEET)) - else - beaker.reagents.add_reagent(sheet_components, (amount_to_take*REAGENTS_PER_SHEET)) - continue - - if(O.reagents) - O.reagents.trans_to_obj(beaker, min(O.reagents.total_volume, remaining_volume)) - if(O.reagents.total_volume == 0) - holdingitems -= O - qdel(O) - if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - -/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/weapon/reagent_containers/new_beaker) - if(!user) - return FALSE - if(beaker) - if(!user.incapacitated() && Adjacent(user)) - user.put_in_hands(beaker) - else - beaker.forceMove(drop_location()) - beaker = null - if(new_beaker) - beaker = new_beaker - update_icon() - return TRUE - -/////////////// -/////////////// -// Detects reagents inside most containers, and acts as an infinite identification system for reagent-based unidentified objects. - -/obj/machinery/chemical_analyzer - name = "chem analyzer" - desc = "Used to precisely scan chemicals and other liquids inside various containers. \ - It may also identify the liquid contents of unknown objects." - description_info = "This machine will try to tell you what reagents are inside of something capable of holding reagents. \ - It is also used to 'identify' specific reagent-based objects with their properties obscured from inspection by normal means." - icon = 'icons/obj/chemical.dmi' - icon_state = "chem_analyzer" - density = TRUE - anchored = TRUE - use_power = TRUE - idle_power_usage = 20 - clicksound = "button" - var/analyzing = FALSE - -/obj/machinery/chemical_analyzer/update_icon() - icon_state = "chem_analyzer[analyzing ? "-working":""]" - -/obj/machinery/chemical_analyzer/attackby(obj/item/I, mob/living/user) - if(!istype(I)) - return ..() - - if(default_deconstruction_screwdriver(user, I)) - return - if(default_deconstruction_crowbar(user, I)) - return - - if(istype(I,/obj/item/weapon/reagent_containers)) - analyzing = TRUE - update_icon() - to_chat(user, span("notice", "Analyzing \the [I], please stand by...")) - - if(!do_after(user, 2 SECONDS, src)) - to_chat(user, span("warning", "Sample moved outside of scan range, please try again and remain still.")) - analyzing = FALSE - update_icon() - return - - // First, identify it if it isn't already. - if(!I.is_identified(IDENTITY_FULL)) - var/datum/identification/ID = I.identity - if(ID.identification_type == IDENTITY_TYPE_CHEMICAL) // This only solves chemical-based mysteries. - I.identify(IDENTITY_FULL, user) - - // Now tell us everything that is inside. - if(I.reagents && I.reagents.reagent_list.len) - to_chat(user, "
") // To add padding between regular chat and the output. - for(var/datum/reagent/R in I.reagents.reagent_list) - if(!R.name) - continue - to_chat(user, span("notice", "Contains [R.volume]u of [R.name].
[R.description]
")) - - // Last, unseal it if it's an autoinjector. - if(istype(I,/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector) && !(I.flags & OPENCONTAINER)) - I.flags |= OPENCONTAINER - to_chat(user, span("notice", "Sample container unsealed.
")) - - to_chat(user, span("notice", "Scanning of \the [I] complete.")) - analyzing = FALSE - update_icon() - return - -#undef MAX_PILL_SPRITE -#undef MAX_BOTTLE_SPRITE -#undef MAX_MULTI_AMOUNT -#undef MAX_UNITS_PER_PILL -#undef MAX_UNITS_PER_PATCH -#undef MAX_UNITS_PER_BOTTLE -#undef MAX_CUSTOM_NAME_LEN +/obj/machinery/chem_master + name = "ChemMaster 3000" + desc = "Used to seperate and package chemicals in to patches, pills, or bottles. Warranty void if used to create Space Drugs." + density = 1 + anchored = 1 + icon = 'icons/obj/chemical.dmi' + icon_state = "mixer0" + circuit = /obj/item/weapon/circuitboard/chem_master + use_power = USE_POWER_IDLE + idle_power_usage = 20 + var/obj/item/weapon/reagent_containers/beaker = null + var/obj/item/weapon/storage/pill_bottle/loaded_pill_bottle = null + var/mode = 0 + var/condi = 0 + var/useramount = 15 // Last used amount + var/pillamount = 10 + var/list/bottle_styles + var/bottlesprite = 1 + var/pillsprite = 1 + var/max_pill_count = 20 + var/printing = FALSE + flags = OPENCONTAINER + clicksound = "button" + +/obj/machinery/chem_master/New() + ..() + var/datum/reagents/R = new/datum/reagents(900) //Just a huge random number so the buffer should (probably) never dump your reagents. + reagents = R //There should be a nano ui thingy to warn of this. + R.my_atom = src + +/obj/machinery/chem_master/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + return + if(2.0) + if (prob(50)) + qdel(src) + return + +/obj/machinery/chem_master/update_icon() + icon_state = "mixer[beaker ? "1" : "0"]" + +/obj/machinery/chem_master/attackby(var/obj/item/weapon/B as obj, var/mob/user as mob) + + if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food)) + + if(src.beaker) + to_chat(user, "\A [beaker] is already loaded into the machine.") + return + src.beaker = B + user.drop_item() + B.loc = src + to_chat(user, "You add \the [B] to the machine.") + update_icon() + + else if(istype(B, /obj/item/weapon/storage/pill_bottle)) + + if(src.loaded_pill_bottle) + to_chat(user, "A \the [loaded_pill_bottle] s already loaded into the machine.") + return + + src.loaded_pill_bottle = B + user.drop_item() + B.loc = src + to_chat(user, "You add \the [loaded_pill_bottle] into the dispenser slot.") + + else if(default_unfasten_wrench(user, B, 20)) + return + if(default_deconstruction_screwdriver(user, B)) + return + if(default_deconstruction_crowbar(user, B)) + return + + return + +/obj/machinery/chem_master/attack_hand(mob/user as mob) + if(stat & BROKEN) + return + user.set_machine(src) + tgui_interact(user) + +/obj/machinery/chem_master/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/chem_master), + ) + +/obj/machinery/chem_master/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ChemMaster", name) + ui.open() + +/** + * Display the NanoUI window for the chem master. + * + * See NanoUI documentation for details. + */ +/obj/machinery/chem_master/tgui_data(mob/user) + var/list/data = list() + + data["condi"] = condi + + data["loaded_pill_bottle"] = !!loaded_pill_bottle + if(loaded_pill_bottle) + data["loaded_pill_bottle_name"] = loaded_pill_bottle.name + data["loaded_pill_bottle_contents_len"] = loaded_pill_bottle.contents.len + data["loaded_pill_bottle_storage_slots"] = loaded_pill_bottle.max_storage_space + + data["beaker"] = !!beaker + if(beaker) + var/list/beaker_reagents_list = list() + data["beaker_reagents"] = beaker_reagents_list + for(var/datum/reagent/R in beaker.reagents.reagent_list) + beaker_reagents_list[++beaker_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "description" = R.description, "id" = R.id) + + var/list/buffer_reagents_list = list() + data["buffer_reagents"] = buffer_reagents_list + for(var/datum/reagent/R in reagents.reagent_list) + buffer_reagents_list[++buffer_reagents_list.len] = list("name" = R.name, "volume" = R.volume, "id" = R.id, "description" = R.description) + + data["pillsprite"] = pillsprite + data["bottlesprite"] = bottlesprite + data["mode"] = mode + data["printing"] = printing + + // Transfer modal information if there is one + data["modal"] = tgui_modal_data(src) + + return data + +/** + * Called in tgui_act() to process modal actions + * + * Arguments: + * * action - The action passed by tgui + * * params - The params passed by tgui + */ +/obj/machinery/chem_master/proc/tgui_act_modal(action, params, datum/tgui/ui, datum/tgui_state/state) + . = TRUE + var/id = params["id"] // The modal's ID + var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] + switch(tgui_modal_act(src, action, params)) + if(TGUI_MODAL_OPEN) + switch(id) + if("analyze") + var/idx = text2num(arguments["idx"]) || 0 + var/from_beaker = text2num(arguments["beaker"]) || FALSE + var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list + if(idx < 1 || idx > length(reagent_list)) + return + + var/datum/reagent/R = reagent_list[idx] + var/list/result = list("idx" = idx, "name" = R.name, "desc" = R.description) + if(!condi && istype(R, /datum/reagent/blood)) + var/datum/reagent/blood/B = R + result["blood_type"] = B.data["blood_type"] + result["blood_dna"] = B.data["blood_DNA"] + + arguments["analysis"] = result + tgui_modal_message(src, id, "", null, arguments) + // if("change_pill_bottle_style") + // if(!loaded_pill_bottle) + // return + // if(!pill_bottle_wrappers) + // pill_bottle_wrappers = list( + // "CLEAR" = "Default", + // COLOR_RED = "Red", + // COLOR_GREEN = "Green", + // COLOR_PALE_BTL_GREEN = "Pale green", + // COLOR_BLUE = "Blue", + // COLOR_CYAN_BLUE = "Light blue", + // COLOR_TEAL = "Teal", + // COLOR_YELLOW = "Yellow", + // COLOR_ORANGE = "Orange", + // COLOR_PINK = "Pink", + // COLOR_MAROON = "Brown" + // ) + // var/current = pill_bottle_wrappers[loaded_pill_bottle.wrapper_color] || "Default" + // tgui_modal_choice(src, id, "Please select a pill bottle wrapper:", null, arguments, current, pill_bottle_wrappers) + if("addcustom") + if(!beaker || !beaker.reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount to transfer to buffer:", null, arguments, useramount) + if("removecustom") + if(!reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount to transfer to [mode ? "beaker" : "disposal"]:", null, arguments, useramount) + if("create_condi_pack") + if(!condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please name your new condiment pack:", null, arguments, reagents.get_master_reagent_name(), MAX_CUSTOM_NAME_LEN) + if("create_pill") + if(condi || !reagents.total_volume) + return + var/num = round(text2num(arguments["num"] || 1)) + if(!num) + return + arguments["num"] = num + var/amount_per_pill = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PILL) + var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_pill]u)" + var/pills_text = num == 1 ? "new pill" : "[num] new pills" + tgui_modal_input(src, id, "Please name your [pills_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) + if("create_pill_multiple") + if(condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount of pills to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) + if("change_pill_style") + var/list/choices = list() + for(var/i = 1 to MAX_PILL_SPRITE) + choices += "pill[i].png" + tgui_modal_bento(src, id, "Please select the new style for pills:", null, arguments, pillsprite, choices) + if("create_patch") + if(condi || !reagents.total_volume) + return + var/num = round(text2num(arguments["num"] || 1)) + if(!num) + return + arguments["num"] = num + var/amount_per_patch = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_PATCH) + var/default_name = "[reagents.get_master_reagent_name()] ([amount_per_patch]u)" + var/patches_text = num == 1 ? "new patch" : "[num] new patches" + tgui_modal_input(src, id, "Please name your [patches_text]:", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) + if("create_patch_multiple") + if(condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount of patches to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) + if("create_bottle") + if(condi || !reagents.total_volume) + return + var/num = round(text2num(arguments["num"] || 1)) + if(!num) + return + arguments["num"] = num + var/amount_per_bottle = CLAMP(reagents.total_volume / num, 0, MAX_UNITS_PER_BOTTLE) + var/default_name = "[reagents.get_master_reagent_name()]" + var/bottles_text = num == 1 ? "new bottle" : "[num] new bottles" + tgui_modal_input(src, id, "Please name your [bottles_text] ([amount_per_bottle]u in bottle):", null, arguments, default_name, MAX_CUSTOM_NAME_LEN) + if("create_bottle_multiple") + if(condi || !reagents.total_volume) + return + tgui_modal_input(src, id, "Please enter the amount of bottles to make (max [MAX_MULTI_AMOUNT] at a time):", null, arguments, pillamount, 5) + if("change_bottle_style") + var/list/choices = list() + for(var/i = 1 to MAX_BOTTLE_SPRITE) + choices += "bottle-[i].png" + tgui_modal_bento(src, id, "Please select the new style for bottles:", null, arguments, bottlesprite, choices) + else + return FALSE + if(TGUI_MODAL_ANSWER) + var/answer = params["answer"] + switch(id) + // if("change_pill_bottle_style") + // if(!pill_bottle_wrappers || !loaded_pill_bottle) // wat? + // return + // var/color = "CLEAR" + // for(var/col in pill_bottle_wrappers) + // var/col_name = pill_bottle_wrappers[col] + // if(col_name == answer) + // color = col + // break + // if(length(color) && color != "CLEAR") + // loaded_pill_bottle.wrapper_color = color + // loaded_pill_bottle.apply_wrap() + // else + // loaded_pill_bottle.wrapper_color = null + // loaded_pill_bottle.cut_overlays() + if("addcustom") + var/amount = isgoodnumber(text2num(answer)) + if(!amount || !arguments["id"]) + return + tgui_act("add", list("id" = arguments["id"], "amount" = amount), ui, state) + if("removecustom") + var/amount = isgoodnumber(text2num(answer)) + if(!amount || !arguments["id"]) + return + tgui_act("remove", list("id" = arguments["id"], "amount" = amount), ui, state) + if("create_condi_pack") + if(!condi || !reagents.total_volume) + return + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/obj/item/weapon/reagent_containers/pill/P = new(loc) + P.name = "[answer] pack" + P.desc = "A small condiment pack. The label says it contains [answer]." + P.icon_state = "bouilloncube"//Reskinned monkey cube + reagents.trans_to_obj(P, 10) + if("create_pill") + if(condi || !reagents.total_volume) + return + var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) + if(!count) + return + + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/amount_per_pill = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PILL) + while(count--) + if(reagents.total_volume <= 0) + to_chat(usr, "Not enough reagents to create these pills!") + return + + var/obj/item/weapon/reagent_containers/pill/P = new(loc) + P.name = "[answer] pill" + P.pixel_x = rand(-7, 7) // Random position + P.pixel_y = rand(-7, 7) + P.icon_state = "pill[pillsprite]" + if(P.icon_state in list("pill1", "pill2", "pill3", "pill4")) // if using greyscale, take colour from reagent + P.color = reagents.get_color() + reagents.trans_to_obj(P, amount_per_pill) + // Load the pills in the bottle if there's one loaded + if(istype(loaded_pill_bottle) && length(loaded_pill_bottle.contents) < loaded_pill_bottle.max_storage_space) + P.forceMove(loaded_pill_bottle) + if("create_pill_multiple") + if(condi || !reagents.total_volume) + return + tgui_act("modal_open", list("id" = "create_pill", "arguments" = list("num" = answer)), ui, state) + if("change_pill_style") + var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_PILL_SPRITE) + if(!new_style) + return + pillsprite = new_style + if("create_patch") + if(condi || !reagents.total_volume) + return + var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) + if(!count) + return + + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/amount_per_patch = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_PATCH) + // var/is_medical_patch = chemical_safety_check(reagents) + while(count--) + if(reagents.total_volume <= 0) + to_chat(usr, "Not enough reagents to create these patches!") + return + + var/obj/item/weapon/reagent_containers/pill/patch/P = new(loc) + P.name = "[answer] patch" + P.pixel_x = rand(-7, 7) // random position + P.pixel_y = rand(-7, 7) + reagents.trans_to_obj(P, amount_per_patch) + // if(is_medical_patch) + // P.instant_application = TRUE + // P.icon_state = "bandaid_med" + if("create_patch_multiple") + if(condi || !reagents.total_volume) + return + tgui_act("modal_open", list("id" = "create_patch", "arguments" = list("num" = answer)), ui, state) + if("create_bottle") + if(condi || !reagents.total_volume) + return + var/count = CLAMP(round(text2num(arguments["num"]) || 0), 0, MAX_MULTI_AMOUNT) + if(!count) + return + + if(!length(answer)) + answer = reagents.get_master_reagent_name() + var/amount_per_bottle = CLAMP(reagents.total_volume / count, 0, MAX_UNITS_PER_BOTTLE) + while(count--) + if(reagents.total_volume <= 0) + to_chat(usr, "Not enough reagents to create these bottles!") + return + var/obj/item/weapon/reagent_containers/glass/bottle/P = new(loc) + P.name = "[answer] bottle" + P.pixel_x = rand(-7, 7) // random position + P.pixel_y = rand(-7, 7) + P.icon_state = "bottle-[bottlesprite]" || "bottle-1" + reagents.trans_to_obj(P, amount_per_bottle) + P.update_icon() + if("create_bottle_multiple") + if(condi || !reagents.total_volume) + return + tgui_act("modal_open", list("id" = "create_bottle", "arguments" = list("num" = answer)), ui, state) + if("change_bottle_style") + var/new_style = CLAMP(text2num(answer) || 0, 0, MAX_BOTTLE_SPRITE) + if(!new_style) + return + bottlesprite = new_style + else + return FALSE + else + return FALSE + +/obj/machinery/chem_master/tgui_act(action, params, datum/tgui/ui, datum/tgui_state/state) + if(..()) + return TRUE + + if(tgui_act_modal(action, params, ui, state)) + return TRUE + + add_fingerprint(usr) + usr.set_machine(src) + + . = TRUE + switch(action) + if("toggle") + mode = !mode + if("ejectp") + if(loaded_pill_bottle) + loaded_pill_bottle.forceMove(get_turf(src)) + if(Adjacent(usr) && !issilicon(usr)) + usr.put_in_hands(loaded_pill_bottle) + loaded_pill_bottle = null + if("print") + if(printing || condi) + return + + var/idx = text2num(params["idx"]) || 0 + var/from_beaker = text2num(params["beaker"]) || FALSE + var/reagent_list = from_beaker ? beaker.reagents.reagent_list : reagents.reagent_list + if(idx < 1 || idx > length(reagent_list)) + return + + var/datum/reagent/R = reagent_list[idx] + + printing = TRUE + visible_message("[src] rattles and prints out a sheet of paper.") + // playsound(loc, 'sound/goonstation/machines/printer_dotmatrix.ogg', 50, 1) + + var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc) + P.info = "
Chemical Analysis

" + P.info += "Time of analysis: [worldtime2stationtime(world.time)]

" + P.info += "Chemical name: [R.name]
" + if(istype(R, /datum/reagent/blood)) + var/datum/reagent/blood/B = R + P.info += "Description: N/A
Blood Type: [B.data["blood_type"]]
DNA: [B.data["blood_DNA"]]" + else + P.info += "Description: [R.description]" + P.info += "

Notes:
" + P.name = "Chemical Analysis - [R.name]" + spawn(50) + printing = FALSE + else + . = FALSE + + if(. || !beaker) + return + + . = TRUE + var/datum/reagents/R = beaker.reagents + switch(action) + if("add") + var/id = params["id"] + var/amount = text2num(params["amount"]) + if(!id || !amount) + return + R.trans_id_to(src, id, amount) + if("remove") + var/id = params["id"] + var/amount = text2num(params["amount"]) + if(!id || !amount) + return + if(mode) + reagents.trans_id_to(beaker, id, amount) + else + reagents.remove_reagent(id, amount) + if("eject") + if(!beaker) + return + beaker.forceMove(get_turf(src)) + if(Adjacent(usr) && !issilicon(usr)) + usr.put_in_hands(beaker) + beaker = null + reagents.clear_reagents() + update_icon() + if("create_condi_bottle") + if(!condi || !reagents.total_volume) + return + var/obj/item/weapon/reagent_containers/food/condiment/P = new(loc) + reagents.trans_to_obj(P, 50) + else + return FALSE + +/obj/machinery/chem_master/attack_ai(mob/user) + return attack_hand(user) + +/obj/machinery/chem_master/proc/isgoodnumber(num) + if(isnum(num)) + if(num > 200) + num = 200 + else if(num < 0) + num = 1 + return num + else + return FALSE + +// /obj/machinery/chem_master/proc/chemical_safety_check(datum/reagents/R) +// var/all_safe = TRUE +// for(var/datum/reagent/A in R.reagent_list) +// if(!GLOB.safe_chem_list.Find(A.id)) +// all_safe = FALSE +// return all_safe + +/obj/machinery/chem_master/condimaster + name = "CondiMaster 3000" + condi = 1 \ No newline at end of file diff --git a/code/modules/reagents/machinery/chemalyzer.dm b/code/modules/reagents/machinery/chemalyzer.dm new file mode 100644 index 0000000000..ce8b1d6f12 --- /dev/null +++ b/code/modules/reagents/machinery/chemalyzer.dm @@ -0,0 +1,63 @@ +// Detects reagents inside most containers, and acts as an infinite identification system for reagent-based unidentified objects. + +/obj/machinery/chemical_analyzer + name = "chem analyzer" + desc = "Used to precisely scan chemicals and other liquids inside various containers. \ + It may also identify the liquid contents of unknown objects." + description_info = "This machine will try to tell you what reagents are inside of something capable of holding reagents. \ + It is also used to 'identify' specific reagent-based objects with their properties obscured from inspection by normal means." + icon = 'icons/obj/chemical.dmi' + icon_state = "chem_analyzer" + density = TRUE + anchored = TRUE + use_power = TRUE + idle_power_usage = 20 + clicksound = "button" + var/analyzing = FALSE + +/obj/machinery/chemical_analyzer/update_icon() + icon_state = "chem_analyzer[analyzing ? "-working":""]" + +/obj/machinery/chemical_analyzer/attackby(obj/item/I, mob/living/user) + if(!istype(I)) + return ..() + + if(default_deconstruction_screwdriver(user, I)) + return + if(default_deconstruction_crowbar(user, I)) + return + + if(istype(I,/obj/item/weapon/reagent_containers)) + analyzing = TRUE + update_icon() + to_chat(user, span("notice", "Analyzing \the [I], please stand by...")) + + if(!do_after(user, 2 SECONDS, src)) + to_chat(user, span("warning", "Sample moved outside of scan range, please try again and remain still.")) + analyzing = FALSE + update_icon() + return + + // First, identify it if it isn't already. + if(!I.is_identified(IDENTITY_FULL)) + var/datum/identification/ID = I.identity + if(ID.identification_type == IDENTITY_TYPE_CHEMICAL) // This only solves chemical-based mysteries. + I.identify(IDENTITY_FULL, user) + + // Now tell us everything that is inside. + if(I.reagents && I.reagents.reagent_list.len) + to_chat(user, "
") // To add padding between regular chat and the output. + for(var/datum/reagent/R in I.reagents.reagent_list) + if(!R.name) + continue + to_chat(user, span("notice", "Contains [R.volume]u of [R.name].
[R.description]
")) + + // Last, unseal it if it's an autoinjector. + if(istype(I,/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector) && !(I.flags & OPENCONTAINER)) + I.flags |= OPENCONTAINER + to_chat(user, span("notice", "Sample container unsealed.
")) + + to_chat(user, span("notice", "Scanning of \the [I] complete.")) + analyzing = FALSE + update_icon() + return \ No newline at end of file diff --git a/code/modules/reagents/dispenser/_defines.dm b/code/modules/reagents/machinery/dispenser/_defines.dm similarity index 96% rename from code/modules/reagents/dispenser/_defines.dm rename to code/modules/reagents/machinery/dispenser/_defines.dm index 60c12cdba6..8d52cf5cd0 100644 --- a/code/modules/reagents/dispenser/_defines.dm +++ b/code/modules/reagents/machinery/dispenser/_defines.dm @@ -1,8 +1,8 @@ -#define CARTRIDGE_VOLUME_LARGE 500 -#define CARTRIDGE_VOLUME_MEDIUM 250 -#define CARTRIDGE_VOLUME_SMALL 100 - -// Chemistry dispenser starts with 21 -// ERT dispenser starts with 28 -#define DISPENSER_MAX_CARTRIDGES 30 - +#define CARTRIDGE_VOLUME_LARGE 500 +#define CARTRIDGE_VOLUME_MEDIUM 250 +#define CARTRIDGE_VOLUME_SMALL 100 + +// Chemistry dispenser starts with 21 +// ERT dispenser starts with 28 +#define DISPENSER_MAX_CARTRIDGES 30 + diff --git a/code/modules/reagents/dispenser/cartridge.dm b/code/modules/reagents/machinery/dispenser/cartridge.dm similarity index 97% rename from code/modules/reagents/dispenser/cartridge.dm rename to code/modules/reagents/machinery/dispenser/cartridge.dm index 444577aaa5..0e2b09eb57 100644 --- a/code/modules/reagents/dispenser/cartridge.dm +++ b/code/modules/reagents/machinery/dispenser/cartridge.dm @@ -1,95 +1,95 @@ -/obj/item/weapon/reagent_containers/chem_disp_cartridge - name = "chemical dispenser cartridge" - desc = "This goes in a chemical dispenser." - icon_state = "cartridge" - - w_class = ITEMSIZE_NORMAL - - volume = CARTRIDGE_VOLUME_LARGE - amount_per_transfer_from_this = 50 - // Large, but inaccurate. Use a chem dispenser or beaker for accuracy. - possible_transfer_amounts = list(50, 100, 250, 500) - unacidable = 1 - - var/spawn_reagent = null - var/label = "" - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/Initialize() - . = ..() - if(spawn_reagent) - reagents.add_reagent(spawn_reagent, volume) - var/datum/reagent/R = SSchemistry.chemical_reagents[spawn_reagent] - setLabel(R.name) - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/examine(mob/user) - . = ..() - . += "It has a capacity of [volume] units." - if(reagents.total_volume <= 0) - . += "It is empty." - else - . += "It contains [reagents.total_volume] units of liquid." - if(!is_open_container()) - . += "The cap is sealed." - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/verb/verb_set_label(L as text) - set name = "Set Cartridge Label" - set category = "Object" - set src in view(usr, 1) - - setLabel(L, usr) - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/proc/setLabel(L, mob/user = null) - if(L) - if(user) - to_chat(user, "You set the label on \the [src] to '[L]'.") - - label = L - name = "[initial(name)] - '[L]'" - else - if(user) - to_chat(user, "You clear the label on \the [src].") - label = "" - name = initial(name) - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/attack_self() - ..() - if (is_open_container()) - to_chat(usr, "You put the cap on \the [src].") - flags ^= OPENCONTAINER - else - to_chat(usr, "You take the cap off \the [src].") - flags |= OPENCONTAINER - -/obj/item/weapon/reagent_containers/chem_disp_cartridge/afterattack(obj/target, mob/user , flag) - if (!is_open_container() || !flag) - return - - else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. - target.add_fingerprint(user) - - if(!target.reagents.total_volume && target.reagents) - to_chat(user, "\The [target] is empty.") - return - - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "\The [src] is full.") - return - - var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) - to_chat(user, "You fill \the [src] with [trans] units of the contents of \the [target].") - - else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. - - if(!reagents.total_volume) - to_chat(user, "\The [src] is empty.") - return - - if(target.reagents.total_volume >= target.reagents.maximum_volume) - to_chat(user, "\The [target] is full.") - return - - var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) - to_chat(user, "You transfer [trans] units of the solution to \the [target].") - - else - return ..() +/obj/item/weapon/reagent_containers/chem_disp_cartridge + name = "chemical dispenser cartridge" + desc = "This goes in a chemical dispenser." + icon_state = "cartridge" + + w_class = ITEMSIZE_NORMAL + + volume = CARTRIDGE_VOLUME_LARGE + amount_per_transfer_from_this = 50 + // Large, but inaccurate. Use a chem dispenser or beaker for accuracy. + possible_transfer_amounts = list(50, 100, 250, 500) + unacidable = 1 + + var/spawn_reagent = null + var/label = "" + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/Initialize() + . = ..() + if(spawn_reagent) + reagents.add_reagent(spawn_reagent, volume) + var/datum/reagent/R = SSchemistry.chemical_reagents[spawn_reagent] + setLabel(R.name) + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/examine(mob/user) + . = ..() + . += "It has a capacity of [volume] units." + if(reagents.total_volume <= 0) + . += "It is empty." + else + . += "It contains [reagents.total_volume] units of liquid." + if(!is_open_container()) + . += "The cap is sealed." + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/verb/verb_set_label(L as text) + set name = "Set Cartridge Label" + set category = "Object" + set src in view(usr, 1) + + setLabel(L, usr) + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/proc/setLabel(L, mob/user = null) + if(L) + if(user) + to_chat(user, "You set the label on \the [src] to '[L]'.") + + label = L + name = "[initial(name)] - '[L]'" + else + if(user) + to_chat(user, "You clear the label on \the [src].") + label = "" + name = initial(name) + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/attack_self() + ..() + if (is_open_container()) + to_chat(usr, "You put the cap on \the [src].") + flags ^= OPENCONTAINER + else + to_chat(usr, "You take the cap off \the [src].") + flags |= OPENCONTAINER + +/obj/item/weapon/reagent_containers/chem_disp_cartridge/afterattack(obj/target, mob/user , flag) + if (!is_open_container() || !flag) + return + + else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us. + target.add_fingerprint(user) + + if(!target.reagents.total_volume && target.reagents) + to_chat(user, "\The [target] is empty.") + return + + if(reagents.total_volume >= reagents.maximum_volume) + to_chat(user, "\The [src] is full.") + return + + var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this) + to_chat(user, "You fill \the [src] with [trans] units of the contents of \the [target].") + + else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it. + + if(!reagents.total_volume) + to_chat(user, "\The [src] is empty.") + return + + if(target.reagents.total_volume >= target.reagents.maximum_volume) + to_chat(user, "\The [target] is full.") + return + + var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this) + to_chat(user, "You transfer [trans] units of the solution to \the [target].") + + else + return ..() diff --git a/code/modules/reagents/dispenser/cartridge_presets.dm b/code/modules/reagents/machinery/dispenser/cartridge_presets.dm similarity index 97% rename from code/modules/reagents/dispenser/cartridge_presets.dm rename to code/modules/reagents/machinery/dispenser/cartridge_presets.dm index eea22fff7e..21b321ad34 100644 --- a/code/modules/reagents/dispenser/cartridge_presets.dm +++ b/code/modules/reagents/machinery/dispenser/cartridge_presets.dm @@ -1,108 +1,108 @@ -/obj/item/weapon/reagent_containers/chem_disp_cartridge - small - volume = CARTRIDGE_VOLUME_SMALL - - medium - volume = CARTRIDGE_VOLUME_MEDIUM - - // Multiple - water spawn_reagent = "water" - sugar spawn_reagent = "sugar" - - // Chemistry - hydrogen spawn_reagent = "hydrogen" - lithium spawn_reagent = "lithium" - carbon spawn_reagent = "carbon" - nitrogen spawn_reagent = "nitrogen" - oxygen spawn_reagent = "oxygen" - fluorine spawn_reagent = "fluorine" - sodium spawn_reagent = "sodium" - aluminum spawn_reagent = "aluminum" - silicon spawn_reagent = "silicon" - phosphorus spawn_reagent = "phosphorus" - sulfur spawn_reagent = "sulfur" - chlorine spawn_reagent = "chlorine" - potassium spawn_reagent = "potassium" - iron spawn_reagent = "iron" - copper spawn_reagent = "copper" - mercury spawn_reagent = "mercury" - radium spawn_reagent = "radium" - ethanol spawn_reagent = "ethanol" - sacid spawn_reagent = "sacid" - tungsten spawn_reagent = "tungsten" - calcium spawn_reagent = "calcium" - - // Bar, alcoholic - beer spawn_reagent = "beer" - kahlua spawn_reagent = "kahlua" - whiskey spawn_reagent = "whiskey" - wine spawn_reagent = "wine" - vodka spawn_reagent = "vodka" - gin spawn_reagent = "gin" - rum spawn_reagent = "rum" - tequila spawn_reagent = "tequilla" - vermouth spawn_reagent = "vermouth" - cognac spawn_reagent = "cognac" - ale spawn_reagent = "ale" - mead spawn_reagent = "mead" - bitters spawn_reagent = "bitters" - cider spawn_reagent = "cider" - - // Bar, soft - ice spawn_reagent = "ice" - tea spawn_reagent = "tea" - icetea spawn_reagent = "icetea" - cola spawn_reagent = "cola" - smw spawn_reagent = "spacemountainwind" - dr_gibb spawn_reagent = "dr_gibb" - spaceup spawn_reagent = "space_up" - tonic spawn_reagent = "tonic" - sodawater spawn_reagent = "sodawater" - lemon_lime spawn_reagent = "lemon_lime" - orange spawn_reagent = "orangejuice" - lime spawn_reagent = "limejuice" - watermelon spawn_reagent = "watermelonjuice" - lemon spawn_reagent = "lemonjuice" - - // Bar, coffee - coffee spawn_reagent = "coffee" - cafe_latte spawn_reagent = "cafe_latte" - soy_latte spawn_reagent = "soy_latte" - hot_coco spawn_reagent = "hot_coco" - milk spawn_reagent = "milk" - cream spawn_reagent = "cream" - mint spawn_reagent = "mint" - berry spawn_reagent = "berryjuice" - greentea spawn_reagent = "greentea" - decaf spawn_reagent = "decaf" - - // ERT - inaprov spawn_reagent = "inaprovaline" - ryetalyn spawn_reagent = "ryetalyn" - paracetamol spawn_reagent = "paracetamol" - tramadol spawn_reagent = "tramadol" - oxycodone spawn_reagent = "oxycodone" - sterilizine spawn_reagent = "sterilizine" - leporazine spawn_reagent = "leporazine" - kelotane spawn_reagent = "kelotane" - dermaline spawn_reagent = "dermaline" - dexalin spawn_reagent = "dexalin" - dexalin/small volume = CARTRIDGE_VOLUME_SMALL // For the medicine cartridge crate, so it's not too easy to get large amounts of dexalin - dexalin_p spawn_reagent = "dexalinp" - tricord spawn_reagent = "tricordrazine" - dylovene spawn_reagent = "anti_toxin" - synaptizine spawn_reagent = "synaptizine" - hyronalin spawn_reagent = "hyronalin" - arithrazine spawn_reagent = "arithrazine" - alkysine spawn_reagent = "alkysine" - imidazoline spawn_reagent = "imidazoline" - peridaxon spawn_reagent = "peridaxon" - bicaridine spawn_reagent = "bicaridine" - hyperzine spawn_reagent = "hyperzine" - rezadone spawn_reagent = "rezadone" - spaceacillin spawn_reagent = "spaceacillin" - ethylredox spawn_reagent = "ethylredoxrazine" - sleeptox spawn_reagent = "stoxin" - chloral spawn_reagent = "chloralhydrate" - cryoxadone spawn_reagent = "cryoxadone" - clonexadone spawn_reagent = "clonexadone" +/obj/item/weapon/reagent_containers/chem_disp_cartridge + small + volume = CARTRIDGE_VOLUME_SMALL + + medium + volume = CARTRIDGE_VOLUME_MEDIUM + + // Multiple + water spawn_reagent = "water" + sugar spawn_reagent = "sugar" + + // Chemistry + hydrogen spawn_reagent = "hydrogen" + lithium spawn_reagent = "lithium" + carbon spawn_reagent = "carbon" + nitrogen spawn_reagent = "nitrogen" + oxygen spawn_reagent = "oxygen" + fluorine spawn_reagent = "fluorine" + sodium spawn_reagent = "sodium" + aluminum spawn_reagent = "aluminum" + silicon spawn_reagent = "silicon" + phosphorus spawn_reagent = "phosphorus" + sulfur spawn_reagent = "sulfur" + chlorine spawn_reagent = "chlorine" + potassium spawn_reagent = "potassium" + iron spawn_reagent = "iron" + copper spawn_reagent = "copper" + mercury spawn_reagent = "mercury" + radium spawn_reagent = "radium" + ethanol spawn_reagent = "ethanol" + sacid spawn_reagent = "sacid" + tungsten spawn_reagent = "tungsten" + calcium spawn_reagent = "calcium" + + // Bar, alcoholic + beer spawn_reagent = "beer" + kahlua spawn_reagent = "kahlua" + whiskey spawn_reagent = "whiskey" + wine spawn_reagent = "wine" + vodka spawn_reagent = "vodka" + gin spawn_reagent = "gin" + rum spawn_reagent = "rum" + tequila spawn_reagent = "tequilla" + vermouth spawn_reagent = "vermouth" + cognac spawn_reagent = "cognac" + ale spawn_reagent = "ale" + mead spawn_reagent = "mead" + bitters spawn_reagent = "bitters" + cider spawn_reagent = "cider" + + // Bar, soft + ice spawn_reagent = "ice" + tea spawn_reagent = "tea" + icetea spawn_reagent = "icetea" + cola spawn_reagent = "cola" + smw spawn_reagent = "spacemountainwind" + dr_gibb spawn_reagent = "dr_gibb" + spaceup spawn_reagent = "space_up" + tonic spawn_reagent = "tonic" + sodawater spawn_reagent = "sodawater" + lemon_lime spawn_reagent = "lemon_lime" + orange spawn_reagent = "orangejuice" + lime spawn_reagent = "limejuice" + watermelon spawn_reagent = "watermelonjuice" + lemon spawn_reagent = "lemonjuice" + + // Bar, coffee + coffee spawn_reagent = "coffee" + cafe_latte spawn_reagent = "cafe_latte" + soy_latte spawn_reagent = "soy_latte" + hot_coco spawn_reagent = "hot_coco" + milk spawn_reagent = "milk" + cream spawn_reagent = "cream" + mint spawn_reagent = "mint" + berry spawn_reagent = "berryjuice" + greentea spawn_reagent = "greentea" + decaf spawn_reagent = "decaf" + + // ERT + inaprov spawn_reagent = "inaprovaline" + ryetalyn spawn_reagent = "ryetalyn" + paracetamol spawn_reagent = "paracetamol" + tramadol spawn_reagent = "tramadol" + oxycodone spawn_reagent = "oxycodone" + sterilizine spawn_reagent = "sterilizine" + leporazine spawn_reagent = "leporazine" + kelotane spawn_reagent = "kelotane" + dermaline spawn_reagent = "dermaline" + dexalin spawn_reagent = "dexalin" + dexalin/small volume = CARTRIDGE_VOLUME_SMALL // For the medicine cartridge crate, so it's not too easy to get large amounts of dexalin + dexalin_p spawn_reagent = "dexalinp" + tricord spawn_reagent = "tricordrazine" + dylovene spawn_reagent = "anti_toxin" + synaptizine spawn_reagent = "synaptizine" + hyronalin spawn_reagent = "hyronalin" + arithrazine spawn_reagent = "arithrazine" + alkysine spawn_reagent = "alkysine" + imidazoline spawn_reagent = "imidazoline" + peridaxon spawn_reagent = "peridaxon" + bicaridine spawn_reagent = "bicaridine" + hyperzine spawn_reagent = "hyperzine" + rezadone spawn_reagent = "rezadone" + spaceacillin spawn_reagent = "spaceacillin" + ethylredox spawn_reagent = "ethylredoxrazine" + sleeptox spawn_reagent = "stoxin" + chloral spawn_reagent = "chloralhydrate" + cryoxadone spawn_reagent = "cryoxadone" + clonexadone spawn_reagent = "clonexadone" diff --git a/code/modules/reagents/dispenser/cartridge_spawn.dm b/code/modules/reagents/machinery/dispenser/cartridge_spawn.dm similarity index 100% rename from code/modules/reagents/dispenser/cartridge_spawn.dm rename to code/modules/reagents/machinery/dispenser/cartridge_spawn.dm diff --git a/code/modules/reagents/dispenser/dispenser2.dm b/code/modules/reagents/machinery/dispenser/dispenser2.dm similarity index 97% rename from code/modules/reagents/dispenser/dispenser2.dm rename to code/modules/reagents/machinery/dispenser/dispenser2.dm index 7f2fb13f40..d53dac4ba5 100644 --- a/code/modules/reagents/dispenser/dispenser2.dm +++ b/code/modules/reagents/machinery/dispenser/dispenser2.dm @@ -1,205 +1,205 @@ -/obj/machinery/chemical_dispenser - name = "chemical dispenser" - desc = "Automagically fabricates chemicals from electricity." - icon = 'icons/obj/chemical.dmi' - icon_state = "dispenser" - clicksound = "switch" - - var/list/spawn_cartridges = null // Set to a list of types to spawn one of each on New() - - var/list/cartridges = list() // Associative, label -> cartridge - var/obj/item/weapon/reagent_containers/container = null - - var/ui_title = "Chemical Dispenser" - - var/accept_drinking = 0 - var/amount = 30 - - use_power = USE_POWER_IDLE - idle_power_usage = 100 - anchored = 1 - -/obj/machinery/chemical_dispenser/Initialize() - . = ..() - if(spawn_cartridges) - for(var/type in spawn_cartridges) - add_cartridge(new type(src)) - -/obj/machinery/chemical_dispenser/examine(mob/user) - . = ..() - . += "It has [cartridges.len] cartridges installed, and has space for [DISPENSER_MAX_CARTRIDGES - cartridges.len] more." - -/obj/machinery/chemical_dispenser/verb/rotate_clockwise() - set name = "Rotate Dispenser Clockwise" - set category = "Object" - set src in oview(1) - - if (src.anchored || usr:stat) - to_chat(usr, "It is fastened down!") - return 0 - src.set_dir(turn(src.dir, 270)) - return 1 - -/obj/machinery/chemical_dispenser/proc/add_cartridge(obj/item/weapon/reagent_containers/chem_disp_cartridge/C, mob/user) - if(!istype(C)) - if(user) - to_chat(user, "\The [C] will not fit in \the [src]!") - return - - if(cartridges.len >= DISPENSER_MAX_CARTRIDGES) - if(user) - to_chat(user, "\The [src] does not have any slots open for \the [C] to fit into!") - return - - if(!C.label) - if(user) - to_chat(user, "\The [C] does not have a label!") - return - - if(cartridges[C.label]) - if(user) - to_chat(user, "\The [src] already contains a cartridge with that label!") - return - - if(user) - user.drop_from_inventory(C) - to_chat(user, "You add \the [C] to \the [src].") - - C.loc = src - cartridges[C.label] = C - cartridges = sortAssoc(cartridges) - SStgui.update_uis(src) - -/obj/machinery/chemical_dispenser/proc/remove_cartridge(label) - . = cartridges[label] - cartridges -= label - SStgui.update_uis(src) - -/obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user) - if(W.is_wrench()) - playsound(src, W.usesound, 50, 1) - to_chat(user, "You begin to [anchored ? "un" : ""]fasten \the [src].") - if (do_after(user, 20 * W.toolspeed)) - user.visible_message( - "\The [user] [anchored ? "un" : ""]fastens \the [src].", - "You have [anchored ? "un" : ""]fastened \the [src].", - "You hear a ratchet.") - anchored = !anchored - else - to_chat(user, "You decide not to [anchored ? "un" : ""]fasten \the [src].") - - else if(istype(W, /obj/item/weapon/reagent_containers/chem_disp_cartridge)) - add_cartridge(W, user) - - else if(W.is_screwdriver()) - var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges - if(!label) return - var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = remove_cartridge(label) - if(C) - to_chat(user, "You remove \the [C] from \the [src].") - C.loc = loc - playsound(src, W.usesound, 50, 1) - - else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food)) - if(container) - to_chat(user, "There is already \a [container] on \the [src]!") - return - - var/obj/item/weapon/reagent_containers/RC = W - - if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food)) - to_chat(user, "This machine only accepts beakers!") - return - - if(!RC.is_open_container()) - to_chat(user, "You don't see how \the [src] could dispense reagents into \the [RC].") - return - - container = RC - user.drop_from_inventory(RC) - RC.loc = src - to_chat(user, "You set \the [RC] on \the [src].") - else - return ..() - -/obj/machinery/chemical_dispenser/tgui_interact(mob/user, datum/tgui/ui = null) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "ChemDispenser", ui_title) // 390, 655 - ui.open() - -/obj/machinery/chemical_dispenser/tgui_data(mob/user) - var/data[0] - data["amount"] = amount - data["isBeakerLoaded"] = container ? 1 : 0 - data["glass"] = accept_drinking - - var/beakerContents[0] - if(container && container.reagents && container.reagents.reagent_list.len) - for(var/datum/reagent/R in container.reagents.reagent_list) - beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list... - data["beakerContents"] = beakerContents - - if(container) - data["beakerCurrentVolume"] = container.reagents.total_volume - data["beakerMaxVolume"] = container.reagents.maximum_volume - else - data["beakerCurrentVolume"] = null - data["beakerMaxVolume"] = null - - var/chemicals[0] - for(var/label in cartridges) - var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] - chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list... - data["chemicals"] = chemicals - return data - -/obj/machinery/chemical_dispenser/tgui_act(action, params) - if(..()) - return TRUE - - . = TRUE - switch(action) - if("amount") - amount = clamp(round(text2num(params["amount"]), 1), 0, 120) // round to nearest 1 and clamp 0 - 120 - if("dispense") - var/label = params["reagent"] - if(cartridges[label] && container && container.is_open_container()) - var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] - playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1) - C.reagents.trans_to(container, amount) - if("remove") - var/amount = text2num(params["amount"]) - if(!container || !amount) - return - var/datum/reagents/R = container.reagents - var/id = params["reagent"] - if(amount > 0) - R.remove_reagent(id, amount) - else if(amount == -1) // Isolate - R.isolate_reagent(id) - if("ejectBeaker") - if(container) - container.forceMove(get_turf(src)) - - if(Adjacent(usr)) // So the AI doesn't get a beaker somehow. - usr.put_in_hands(container) - - container = null - else - return FALSE - - add_fingerprint(usr) - -/obj/machinery/chemical_dispenser/attack_ghost(mob/user) - if(stat & BROKEN) - return - tgui_interact(user) - -/obj/machinery/chemical_dispenser/attack_ai(mob/user) - attack_hand(user) - -/obj/machinery/chemical_dispenser/attack_hand(mob/user) - if(stat & BROKEN) - return - tgui_interact(user) +/obj/machinery/chemical_dispenser + name = "chemical dispenser" + desc = "Automagically fabricates chemicals from electricity." + icon = 'icons/obj/chemical.dmi' + icon_state = "dispenser" + clicksound = "switch" + + var/list/spawn_cartridges = null // Set to a list of types to spawn one of each on New() + + var/list/cartridges = list() // Associative, label -> cartridge + var/obj/item/weapon/reagent_containers/container = null + + var/ui_title = "Chemical Dispenser" + + var/accept_drinking = 0 + var/amount = 30 + + use_power = USE_POWER_IDLE + idle_power_usage = 100 + anchored = 1 + +/obj/machinery/chemical_dispenser/Initialize() + . = ..() + if(spawn_cartridges) + for(var/type in spawn_cartridges) + add_cartridge(new type(src)) + +/obj/machinery/chemical_dispenser/examine(mob/user) + . = ..() + . += "It has [cartridges.len] cartridges installed, and has space for [DISPENSER_MAX_CARTRIDGES - cartridges.len] more." + +/obj/machinery/chemical_dispenser/verb/rotate_clockwise() + set name = "Rotate Dispenser Clockwise" + set category = "Object" + set src in oview(1) + + if (src.anchored || usr:stat) + to_chat(usr, "It is fastened down!") + return 0 + src.set_dir(turn(src.dir, 270)) + return 1 + +/obj/machinery/chemical_dispenser/proc/add_cartridge(obj/item/weapon/reagent_containers/chem_disp_cartridge/C, mob/user) + if(!istype(C)) + if(user) + to_chat(user, "\The [C] will not fit in \the [src]!") + return + + if(cartridges.len >= DISPENSER_MAX_CARTRIDGES) + if(user) + to_chat(user, "\The [src] does not have any slots open for \the [C] to fit into!") + return + + if(!C.label) + if(user) + to_chat(user, "\The [C] does not have a label!") + return + + if(cartridges[C.label]) + if(user) + to_chat(user, "\The [src] already contains a cartridge with that label!") + return + + if(user) + user.drop_from_inventory(C) + to_chat(user, "You add \the [C] to \the [src].") + + C.loc = src + cartridges[C.label] = C + cartridges = sortAssoc(cartridges) + SStgui.update_uis(src) + +/obj/machinery/chemical_dispenser/proc/remove_cartridge(label) + . = cartridges[label] + cartridges -= label + SStgui.update_uis(src) + +/obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user) + if(W.is_wrench()) + playsound(src, W.usesound, 50, 1) + to_chat(user, "You begin to [anchored ? "un" : ""]fasten \the [src].") + if (do_after(user, 20 * W.toolspeed)) + user.visible_message( + "\The [user] [anchored ? "un" : ""]fastens \the [src].", + "You have [anchored ? "un" : ""]fastened \the [src].", + "You hear a ratchet.") + anchored = !anchored + else + to_chat(user, "You decide not to [anchored ? "un" : ""]fasten \the [src].") + + else if(istype(W, /obj/item/weapon/reagent_containers/chem_disp_cartridge)) + add_cartridge(W, user) + + else if(W.is_screwdriver()) + var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges + if(!label) return + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = remove_cartridge(label) + if(C) + to_chat(user, "You remove \the [C] from \the [src].") + C.loc = loc + playsound(src, W.usesound, 50, 1) + + else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food)) + if(container) + to_chat(user, "There is already \a [container] on \the [src]!") + return + + var/obj/item/weapon/reagent_containers/RC = W + + if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food)) + to_chat(user, "This machine only accepts beakers!") + return + + if(!RC.is_open_container()) + to_chat(user, "You don't see how \the [src] could dispense reagents into \the [RC].") + return + + container = RC + user.drop_from_inventory(RC) + RC.loc = src + to_chat(user, "You set \the [RC] on \the [src].") + else + return ..() + +/obj/machinery/chemical_dispenser/tgui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ChemDispenser", ui_title) // 390, 655 + ui.open() + +/obj/machinery/chemical_dispenser/tgui_data(mob/user) + var/data[0] + data["amount"] = amount + data["isBeakerLoaded"] = container ? 1 : 0 + data["glass"] = accept_drinking + + var/beakerContents[0] + if(container && container.reagents && container.reagents.reagent_list.len) + for(var/datum/reagent/R in container.reagents.reagent_list) + beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list... + data["beakerContents"] = beakerContents + + if(container) + data["beakerCurrentVolume"] = container.reagents.total_volume + data["beakerMaxVolume"] = container.reagents.maximum_volume + else + data["beakerCurrentVolume"] = null + data["beakerMaxVolume"] = null + + var/chemicals[0] + for(var/label in cartridges) + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] + chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list... + data["chemicals"] = chemicals + return data + +/obj/machinery/chemical_dispenser/tgui_act(action, params) + if(..()) + return TRUE + + . = TRUE + switch(action) + if("amount") + amount = clamp(round(text2num(params["amount"]), 1), 0, 120) // round to nearest 1 and clamp 0 - 120 + if("dispense") + var/label = params["reagent"] + if(cartridges[label] && container && container.is_open_container()) + var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label] + playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1) + C.reagents.trans_to(container, amount) + if("remove") + var/amount = text2num(params["amount"]) + if(!container || !amount) + return + var/datum/reagents/R = container.reagents + var/id = params["reagent"] + if(amount > 0) + R.remove_reagent(id, amount) + else if(amount == -1) // Isolate + R.isolate_reagent(id) + if("ejectBeaker") + if(container) + container.forceMove(get_turf(src)) + + if(Adjacent(usr)) // So the AI doesn't get a beaker somehow. + usr.put_in_hands(container) + + container = null + else + return FALSE + + add_fingerprint(usr) + +/obj/machinery/chemical_dispenser/attack_ghost(mob/user) + if(stat & BROKEN) + return + tgui_interact(user) + +/obj/machinery/chemical_dispenser/attack_ai(mob/user) + attack_hand(user) + +/obj/machinery/chemical_dispenser/attack_hand(mob/user) + if(stat & BROKEN) + return + tgui_interact(user) diff --git a/code/modules/reagents/dispenser/dispenser2_energy.dm b/code/modules/reagents/machinery/dispenser/dispenser2_energy.dm similarity index 100% rename from code/modules/reagents/dispenser/dispenser2_energy.dm rename to code/modules/reagents/machinery/dispenser/dispenser2_energy.dm diff --git a/code/modules/reagents/dispenser/dispenser_presets.dm b/code/modules/reagents/machinery/dispenser/dispenser_presets.dm similarity index 98% rename from code/modules/reagents/dispenser/dispenser_presets.dm rename to code/modules/reagents/machinery/dispenser/dispenser_presets.dm index 6916903048..6b90357a2c 100644 --- a/code/modules/reagents/dispenser/dispenser_presets.dm +++ b/code/modules/reagents/machinery/dispenser/dispenser_presets.dm @@ -1,144 +1,144 @@ -/obj/machinery/chemical_dispenser/full - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium - ) - -/obj/machinery/chemical_dispenser/ert - name = "medicine dispenser" - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/inaprov, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ryetalyn, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/paracetamol, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tramadol, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxycodone, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sterilizine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/leporazine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/kelotane, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dermaline, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin_p, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tricord, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dylovene, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/synaptizine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyronalin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/arithrazine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/alkysine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/imidazoline, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/peridaxon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/bicaridine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyperzine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/rezadone, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceacillin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethylredox, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sleeptox, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/chloral, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cryoxadone, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/clonexadone - ) - -/obj/machinery/chemical_dispenser/bar_soft - name = "soft drink dispenser" - desc = "A soda machine." - icon_state = "soda_dispenser" - ui_title = "Soda Dispenser" - accept_drinking = 1 - -/obj/machinery/chemical_dispenser/bar_soft/full - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon - ) - -/obj/machinery/chemical_dispenser/bar_alc - name = "booze dispenser" - desc = "A beer machine. Like a soda machine, but more fun!" - icon_state = "booze_dispenser" - ui_title = "Booze Dispenser" - accept_drinking = 1 - -/obj/machinery/chemical_dispenser/bar_alc/full - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cider, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead - ) - -/obj/machinery/chemical_dispenser/bar_coffee - name = "coffee dispenser" - desc = "Driving crack dealers out of employment since 2280." - icon_state = "coffee_dispenser" - ui_title = "Coffee Dispenser" - accept_drinking = 1 - -/obj/machinery/chemical_dispenser/bar_coffee/full - spawn_cartridges = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mint, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/berry, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/greentea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/decaf - ) +/obj/machinery/chemical_dispenser/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium + ) + +/obj/machinery/chemical_dispenser/ert + name = "medicine dispenser" + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/inaprov, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ryetalyn, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/paracetamol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tramadol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxycodone, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sterilizine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/leporazine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kelotane, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dermaline, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin_p, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tricord, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dylovene, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/synaptizine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyronalin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/arithrazine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/alkysine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/imidazoline, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/peridaxon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/bicaridine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hyperzine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rezadone, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceacillin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethylredox, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sleeptox, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/chloral, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cryoxadone, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/clonexadone + ) + +/obj/machinery/chemical_dispenser/bar_soft + name = "soft drink dispenser" + desc = "A soda machine." + icon_state = "soda_dispenser" + ui_title = "Soda Dispenser" + accept_drinking = 1 + +/obj/machinery/chemical_dispenser/bar_soft/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon + ) + +/obj/machinery/chemical_dispenser/bar_alc + name = "booze dispenser" + desc = "A beer machine. Like a soda machine, but more fun!" + icon_state = "booze_dispenser" + ui_title = "Booze Dispenser" + accept_drinking = 1 + +/obj/machinery/chemical_dispenser/bar_alc/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cider, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead + ) + +/obj/machinery/chemical_dispenser/bar_coffee + name = "coffee dispenser" + desc = "Driving crack dealers out of employment since 2280." + icon_state = "coffee_dispenser" + ui_title = "Coffee Dispenser" + accept_drinking = 1 + +/obj/machinery/chemical_dispenser/bar_coffee/full + spawn_cartridges = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mint, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/berry, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/greentea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/decaf + ) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/machinery/dispenser/reagent_tank.dm similarity index 97% rename from code/modules/reagents/reagent_dispenser.dm rename to code/modules/reagents/machinery/dispenser/reagent_tank.dm index ae6ecf8505..91f7a24a6b 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/machinery/dispenser/reagent_tank.dm @@ -1,431 +1,442 @@ - - -/obj/structure/reagent_dispensers - name = "Dispenser" - desc = "..." - icon = 'icons/obj/objects.dmi' - icon_state = "watertank" - layer = TABLE_LAYER - density = 1 - anchored = 0 - pressure_resistance = 2*ONE_ATMOSPHERE - - var/obj/item/hose_connector/input/active/InputSocket - var/obj/item/hose_connector/output/active/OutputSocket - - var/amount_per_transfer_from_this = 10 - var/possible_transfer_amounts = list(10,25,50,100) - -/obj/structure/reagent_dispensers/attackby(obj/item/weapon/W as obj, mob/user as mob) - return - -/obj/structure/reagent_dispensers/Destroy() - QDEL_NULL(InputSocket) - QDEL_NULL(OutputSocket) - - ..() - -/obj/structure/reagent_dispensers/Initialize() - var/datum/reagents/R = new/datum/reagents(5000) - reagents = R - R.my_atom = src - if (!possible_transfer_amounts) - src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT - - InputSocket = new(src) - InputSocket.carrier = src - OutputSocket = new(src) - OutputSocket.carrier = src - - . = ..() - -/obj/structure/reagent_dispensers/examine(mob/user) - . = ..() - if(get_dist(user, src) <= 2) - . += "It contains:" - if(reagents && reagents.reagent_list.len) - for(var/datum/reagent/R in reagents.reagent_list) - . += "[R.volume] units of [R.name]" - else - . += "Nothing." - -/obj/structure/reagent_dispensers/verb/set_APTFT() //set amount_per_transfer_from_this - set name = "Set transfer amount" - set category = "Object" - set src in view(1) - var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts - if (N) - amount_per_transfer_from_this = N - -/obj/structure/reagent_dispensers/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - return - if(2.0) - if (prob(50)) - new /obj/effect/effect/water(src.loc) - qdel(src) - return - if(3.0) - if (prob(5)) - new /obj/effect/effect/water(src.loc) - qdel(src) - return - else - return - -/obj/structure/reagent_dispensers/blob_act() - qdel(src) - - - -//Dispensers -/obj/structure/reagent_dispensers/watertank - name = "watertank" - desc = "A watertank." - icon = 'icons/obj/objects.dmi' - icon_state = "watertank" - amount_per_transfer_from_this = 10 - -/obj/structure/reagent_dispensers/watertank/Initialize() - . = ..() - reagents.add_reagent("water", 1000) - -/obj/structure/reagent_dispensers/watertank/high - name = "high-capacity water tank" - desc = "A highly-pressurized water tank made to hold vast amounts of water.." - icon_state = "watertank_high" - -/obj/structure/reagent_dispensers/watertank/high/Initialize() - . = ..() - reagents.add_reagent("water", 4000) - -/obj/structure/reagent_dispensers/fueltank - name = "fueltank" - desc = "A fueltank." - icon = 'icons/obj/objects.dmi' - icon_state = "weldtank" - amount_per_transfer_from_this = 10 - var/modded = 0 - var/obj/item/device/assembly_holder/rig = null - -/obj/structure/reagent_dispensers/fueltank/Initialize() - . = ..() - reagents.add_reagent("fuel",1000) - -/obj/structure/reagent_dispensers/fueltank/examine(mob/user) - . = ..() - if(get_dist(user, src) <= 2) - if(modded) - . += "Fuel faucet is wrenched open, leaking the fuel!" - if(rig) - . += "There is some kind of device rigged to the tank." - -/obj/structure/reagent_dispensers/fueltank/attack_hand() - if (rig) - usr.visible_message("[usr] begins to detach [rig] from \the [src].", "You begin to detach [rig] from \the [src]") - if(do_after(usr, 20)) - usr.visible_message("[usr] detaches [rig] from \the [src].", "You detach [rig] from \the [src]") - rig.loc = get_turf(usr) - rig = null - overlays = new/list() - -/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob) - src.add_fingerprint(user) - if (W.is_wrench()) - user.visible_message("[user] wrenches [src]'s faucet [modded ? "closed" : "open"].", \ - "You wrench [src]'s faucet [modded ? "closed" : "open"]") - modded = modded ? 0 : 1 - playsound(src, W.usesound, 75, 1) - if (modded) - message_admins("[key_name_admin(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel. (JMP)") - log_game("[key_name(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel.") - leak_fuel(amount_per_transfer_from_this) - if (istype(W,/obj/item/device/assembly_holder)) - if (rig) - to_chat(user, "There is another device in the way.") - return ..() - user.visible_message("[user] begins rigging [W] to \the [src].", "You begin rigging [W] to \the [src]") - if(do_after(user, 20)) - user.visible_message("[user] rigs [W] to \the [src].", "You rig [W] to \the [src]") - - var/obj/item/device/assembly_holder/H = W - if (istype(H.a_left,/obj/item/device/assembly/igniter) || istype(H.a_right,/obj/item/device/assembly/igniter)) - message_admins("[key_name_admin(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion. (JMP)") - log_game("[key_name(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion.") - - rig = W - user.drop_item() - W.loc = src - - var/icon/test = getFlatIcon(W) - test.Shift(NORTH,1) - test.Shift(EAST,6) - overlays += test - - return ..() - - -/obj/structure/reagent_dispensers/fueltank/bullet_act(var/obj/item/projectile/Proj) - if(Proj.get_structure_damage()) - if(istype(Proj.firer)) - message_admins("[key_name_admin(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) (JMP).") - log_game("[key_name(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).") - - if(!istype(Proj ,/obj/item/projectile/beam/lasertag) && !istype(Proj ,/obj/item/projectile/beam/practice) ) - explode() - -/obj/structure/reagent_dispensers/fueltank/ex_act() - explode() - -/obj/structure/reagent_dispensers/fueltank/blob_act() - explode() - -/obj/structure/reagent_dispensers/fueltank/proc/explode() - if (reagents.total_volume > 500) - explosion(src.loc,1,2,4) - else if (reagents.total_volume > 100) - explosion(src.loc,0,1,3) - else if (reagents.total_volume > 50) - explosion(src.loc,-1,1,2) - if(src) - qdel(src) - -/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume) - if (modded) - explode() - else if (temperature > T0C+500) - explode() - return ..() - -/obj/structure/reagent_dispensers/fueltank/Move() - if (..() && modded) - leak_fuel(amount_per_transfer_from_this/10.0) - -/obj/structure/reagent_dispensers/fueltank/proc/leak_fuel(amount) - if (reagents.total_volume == 0) - return - - amount = min(amount, reagents.total_volume) - reagents.remove_reagent("fuel",amount) - new /obj/effect/decal/cleanable/liquid_fuel(src.loc, amount,1) - -/obj/structure/reagent_dispensers/peppertank - name = "Pepper Spray Refiller" - desc = "Refills pepper spray canisters." - icon = 'icons/obj/objects.dmi' - icon_state = "peppertank" - anchored = 1 - density = 0 - amount_per_transfer_from_this = 45 - -/obj/structure/reagent_dispensers/peppertank/Initialize() - . = ..() - reagents.add_reagent("condensedcapsaicin",1000) - - -/obj/structure/reagent_dispensers/water_cooler - name = "Water-Cooler" - desc = "A machine that dispenses water to drink." - amount_per_transfer_from_this = 5 - icon = 'icons/obj/vending.dmi' - icon_state = "water_cooler" - possible_transfer_amounts = null - anchored = 1 - var/bottle = 0 - var/cups = 0 - var/cupholder = 0 - -/obj/structure/reagent_dispensers/water_cooler/full - bottle = 1 - cupholder = 1 - cups = 10 - -/obj/structure/reagent_dispensers/water_cooler/Initialize() - . = ..() - if(bottle) - reagents.add_reagent("water",120) - update_icon() - -/obj/structure/reagent_dispensers/water_cooler/examine(mob/user) - . = ..() - if(cupholder) - . += "There are [cups] cups in the cup dispenser." - -/obj/structure/reagent_dispensers/water_cooler/verb/rotate_clockwise() - set name = "Rotate Cooler Clockwise" - set category = "Object" - set src in oview(1) - - if (src.anchored || usr:stat) - to_chat(usr, "It is fastened to the floor!") - return 0 - src.set_dir(turn(src.dir, 270)) - return 1 - -/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/I as obj, mob/user as mob) - if(I.is_wrench()) - src.add_fingerprint(user) - if(bottle) - playsound(src, I.usesound, 50, 1) - if(do_after(user, 20) && bottle) - to_chat(user, "You unfasten the jug.") - var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = new /obj/item/weapon/reagent_containers/glass/cooler_bottle( src.loc ) - for(var/datum/reagent/R in reagents.reagent_list) - var/total_reagent = reagents.get_reagent_amount(R.id) - G.reagents.add_reagent(R.id, total_reagent) - reagents.clear_reagents() - bottle = 0 - update_icon() - else - if(anchored) - user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.") - else - user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.") - if(do_after(user, 20 * I.toolspeed, src)) - if(!src) return - to_chat(user, "You [anchored? "un" : ""]secured \the [src]!") - anchored = !anchored - playsound(src, I.usesound, 50, 1) - return - - if(I.is_screwdriver()) - if(cupholder) - playsound(src, I.usesound, 50, 1) - to_chat(user, "You take the cup dispenser off.") - new /obj/item/stack/material/plastic( src.loc ) - if(cups) - for(var/i = 0 to cups) - new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc) - cups = 0 - cupholder = 0 - update_icon() - return - if(!bottle && !cupholder) - playsound(src, I.usesound, 50, 1) - to_chat(user, "You start taking the water-cooler apart.") - if(do_after(user, 20 * I.toolspeed) && !bottle && !cupholder) - to_chat(user, "You take the water-cooler apart.") - new /obj/item/stack/material/plastic( src.loc, 4 ) - qdel(src) - return - - if(istype(I, /obj/item/weapon/reagent_containers/glass/cooler_bottle)) - src.add_fingerprint(user) - if(!bottle) - if(anchored) - var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = I - to_chat(user, "You start to screw the bottle onto the water-cooler.") - if(do_after(user, 20) && !bottle && anchored) - bottle = 1 - update_icon() - to_chat(user, "You screw the bottle onto the water-cooler!") - for(var/datum/reagent/R in G.reagents.reagent_list) - var/total_reagent = G.reagents.get_reagent_amount(R.id) - reagents.add_reagent(R.id, total_reagent) - qdel(G) - else - to_chat(user, "You need to wrench down the cooler first.") - else - to_chat(user, "There is already a bottle there!") - return 1 - - if(istype(I, /obj/item/stack/material/plastic)) - if(!cupholder) - if(anchored) - var/obj/item/stack/material/plastic/P = I - src.add_fingerprint(user) - to_chat(user, "You start to attach a cup dispenser onto the water-cooler.") - playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) - if(do_after(user, 20) && !cupholder && anchored) - if (P.use(1)) - to_chat(user, "You attach a cup dispenser onto the water-cooler.") - cupholder = 1 - update_icon() - else - to_chat(user, "You need to wrench down the cooler first.") - else - to_chat(user, "There is already a cup dispenser there!") - return - -/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/user) - if(cups) - new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc) - cups-- - flick("[icon_state]-vend", src) - return - -/obj/structure/reagent_dispensers/water_cooler/update_icon() - icon_state = "water_cooler" - overlays.Cut() - var/image/I - if(bottle) - I = image(icon, "water_cooler_bottle") - overlays += I - return - -/obj/structure/reagent_dispensers/beerkeg - name = "beer keg" - desc = "A beer keg." - icon = 'icons/obj/objects.dmi' - icon_state = "beertankTEMP" - amount_per_transfer_from_this = 10 - -/obj/structure/reagent_dispensers/beerkeg/Initialize() - . = ..() - reagents.add_reagent("beer",1000) - -/obj/structure/reagent_dispensers/beerkeg/fakenuke - name = "nuclear beer keg" - desc = "A beer keg in the form of a nuclear bomb! An absolute blast at parties!" - icon = 'icons/obj/stationobjs.dmi' - icon_state = "nuclearbomb0" - -/obj/structure/reagent_dispensers/virusfood - name = "Virus Food Dispenser" - desc = "A dispenser of virus food. Yum." - icon = 'icons/obj/objects.dmi' - icon_state = "virusfoodtank" - amount_per_transfer_from_this = 10 - anchored = 1 - -/obj/structure/reagent_dispensers/virusfood/Initialize() - . = ..() - reagents.add_reagent("virusfood", 1000) - -/obj/structure/reagent_dispensers/acid - name = "Sulphuric Acid Dispenser" - desc = "A dispenser of acid for industrial processes." - icon = 'icons/obj/objects.dmi' - icon_state = "acidtank" - amount_per_transfer_from_this = 10 - anchored = 1 - -/obj/structure/reagent_dispensers/acid/Initialize() - . = ..() - reagents.add_reagent("sacid", 1000) - -//Cooking oil refill tank -/obj/structure/reagent_dispensers/cookingoil - name = "cooking oil tank" - desc = "A fifty-litre tank of commercial-grade corn oil, intended for use in large scale deep fryers. Store in a cool, dark place" - icon = 'icons/obj/objects.dmi' - icon_state = "oiltank" - amount_per_transfer_from_this = 120 - -/obj/structure/reagent_dispensers/cookingoil/New() - ..() - reagents.add_reagent("cornoil",5000) - -/obj/structure/reagent_dispensers/cookingoil/bullet_act(var/obj/item/projectile/Proj) - if(Proj.get_structure_damage()) - explode() - -/obj/structure/reagent_dispensers/cookingoil/ex_act() - explode() - -/obj/structure/reagent_dispensers/cookingoil/proc/explode() - reagents.splash_area(get_turf(src), 3) - visible_message(span("danger", "The [src] bursts open, spreading oil all over the area.")) - qdel(src) + + +/obj/structure/reagent_dispensers + name = "Dispenser" + desc = "..." + icon = 'icons/obj/objects.dmi' + icon_state = "watertank" + layer = TABLE_LAYER + density = 1 + anchored = 0 + pressure_resistance = 2*ONE_ATMOSPHERE + + var/obj/item/hose_connector/input/active/InputSocket + var/obj/item/hose_connector/output/active/OutputSocket + + var/amount_per_transfer_from_this = 10 + var/possible_transfer_amounts = list(10,25,50,100) + +/obj/structure/reagent_dispensers/attackby(obj/item/weapon/W as obj, mob/user as mob) + return + +/obj/structure/reagent_dispensers/Destroy() + QDEL_NULL(InputSocket) + QDEL_NULL(OutputSocket) + + ..() + +/obj/structure/reagent_dispensers/Initialize() + var/datum/reagents/R = new/datum/reagents(5000) + reagents = R + R.my_atom = src + if (!possible_transfer_amounts) + src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT + + InputSocket = new(src) + InputSocket.carrier = src + OutputSocket = new(src) + OutputSocket.carrier = src + + . = ..() + +/obj/structure/reagent_dispensers/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 2) + . += "It contains:" + if(reagents && reagents.reagent_list.len) + for(var/datum/reagent/R in reagents.reagent_list) + . += "[R.volume] units of [R.name]" + else + . += "Nothing." + +/obj/structure/reagent_dispensers/verb/set_APTFT() //set amount_per_transfer_from_this + set name = "Set transfer amount" + set category = "Object" + set src in view(1) + var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts + if (N) + amount_per_transfer_from_this = N + +/obj/structure/reagent_dispensers/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + return + if(2.0) + if (prob(50)) + new /obj/effect/effect/water(src.loc) + qdel(src) + return + if(3.0) + if (prob(5)) + new /obj/effect/effect/water(src.loc) + qdel(src) + return + else + return + +/obj/structure/reagent_dispensers/blob_act() + qdel(src) + + + +//Dispensers +/obj/structure/reagent_dispensers/watertank + name = "watertank" + desc = "A watertank." + icon = 'icons/obj/objects.dmi' + icon_state = "watertank" + amount_per_transfer_from_this = 10 + +/obj/structure/reagent_dispensers/watertank/Initialize() + . = ..() + reagents.add_reagent("water", 1000) + +/obj/structure/reagent_dispensers/watertank/high + name = "high-capacity water tank" + desc = "A highly-pressurized water tank made to hold vast amounts of water.." + icon_state = "watertank_high" + +/obj/structure/reagent_dispensers/watertank/high/Initialize() + . = ..() + reagents.add_reagent("water", 4000) + +/obj/structure/reagent_dispensers/fueltank + name = "fueltank" + desc = "A fueltank." + icon = 'icons/obj/objects.dmi' + icon_state = "weldtank" + amount_per_transfer_from_this = 10 + var/modded = 0 + var/obj/item/device/assembly_holder/rig = null + +/obj/structure/reagent_dispensers/fueltank/Initialize() + . = ..() + reagents.add_reagent("fuel",1000) + +/obj/structure/reagent_dispensers/fueltank/examine(mob/user) + . = ..() + if(get_dist(user, src) <= 2) + if(modded) + . += "Fuel faucet is wrenched open, leaking the fuel!" + if(rig) + . += "There is some kind of device rigged to the tank." + +/obj/structure/reagent_dispensers/fueltank/attack_hand() + if (rig) + usr.visible_message("[usr] begins to detach [rig] from \the [src].", "You begin to detach [rig] from \the [src]") + if(do_after(usr, 20)) + usr.visible_message("[usr] detaches [rig] from \the [src].", "You detach [rig] from \the [src]") + rig.loc = get_turf(usr) + rig = null + overlays = new/list() + +/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob) + src.add_fingerprint(user) + if (W.is_wrench()) + user.visible_message("[user] wrenches [src]'s faucet [modded ? "closed" : "open"].", \ + "You wrench [src]'s faucet [modded ? "closed" : "open"]") + modded = modded ? 0 : 1 + playsound(src, W.usesound, 75, 1) + if (modded) + message_admins("[key_name_admin(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel. (JMP)") + log_game("[key_name(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel.") + leak_fuel(amount_per_transfer_from_this) + if (istype(W,/obj/item/device/assembly_holder)) + if (rig) + to_chat(user, "There is another device in the way.") + return ..() + user.visible_message("[user] begins rigging [W] to \the [src].", "You begin rigging [W] to \the [src]") + if(do_after(user, 20)) + user.visible_message("[user] rigs [W] to \the [src].", "You rig [W] to \the [src]") + + var/obj/item/device/assembly_holder/H = W + if (istype(H.a_left,/obj/item/device/assembly/igniter) || istype(H.a_right,/obj/item/device/assembly/igniter)) + message_admins("[key_name_admin(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion. (JMP)") + log_game("[key_name(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion.") + + rig = W + user.drop_item() + W.loc = src + + var/icon/test = getFlatIcon(W) + test.Shift(NORTH,1) + test.Shift(EAST,6) + overlays += test + + return ..() + + +/obj/structure/reagent_dispensers/fueltank/bullet_act(var/obj/item/projectile/Proj) + if(Proj.get_structure_damage()) + if(istype(Proj.firer)) + message_admins("[key_name_admin(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) (JMP).") + log_game("[key_name(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).") + + if(!istype(Proj ,/obj/item/projectile/beam/lasertag) && !istype(Proj ,/obj/item/projectile/beam/practice) ) + explode() + +/obj/structure/reagent_dispensers/fueltank/ex_act() + explode() + +/obj/structure/reagent_dispensers/fueltank/blob_act() + explode() + +/obj/structure/reagent_dispensers/fueltank/proc/explode() + if (reagents.total_volume > 500) + explosion(src.loc,1,2,4) + else if (reagents.total_volume > 100) + explosion(src.loc,0,1,3) + else if (reagents.total_volume > 50) + explosion(src.loc,-1,1,2) + if(src) + qdel(src) + +/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume) + if (modded) + explode() + else if (temperature > T0C+500) + explode() + return ..() + +/obj/structure/reagent_dispensers/fueltank/Move() + if (..() && modded) + leak_fuel(amount_per_transfer_from_this/10.0) + +/obj/structure/reagent_dispensers/fueltank/proc/leak_fuel(amount) + if (reagents.total_volume == 0) + return + + amount = min(amount, reagents.total_volume) + reagents.remove_reagent("fuel",amount) + new /obj/effect/decal/cleanable/liquid_fuel(src.loc, amount,1) + +/obj/structure/reagent_dispensers/peppertank + name = "Pepper Spray Refiller" + desc = "Refills pepper spray canisters." + icon = 'icons/obj/objects.dmi' + icon_state = "peppertank" + anchored = 1 + density = 0 + amount_per_transfer_from_this = 45 + +/obj/structure/reagent_dispensers/peppertank/Initialize() + . = ..() + reagents.add_reagent("condensedcapsaicin",1000) + + +/obj/structure/reagent_dispensers/water_cooler + name = "Water-Cooler" + desc = "A machine that dispenses water to drink." + amount_per_transfer_from_this = 5 + icon = 'icons/obj/vending.dmi' + icon_state = "water_cooler" + possible_transfer_amounts = null + anchored = 1 + var/bottle = 0 + var/cups = 0 + var/cupholder = 0 + +/obj/structure/reagent_dispensers/water_cooler/full + bottle = 1 + cupholder = 1 + cups = 10 + +/obj/structure/reagent_dispensers/water_cooler/Initialize() + . = ..() + if(bottle) + reagents.add_reagent("water",120) + update_icon() + +/obj/structure/reagent_dispensers/water_cooler/examine(mob/user) + . = ..() + if(cupholder) + . += "There are [cups] cups in the cup dispenser." + +/obj/structure/reagent_dispensers/water_cooler/verb/rotate_clockwise() + set name = "Rotate Cooler Clockwise" + set category = "Object" + set src in oview(1) + + if (src.anchored || usr:stat) + to_chat(usr, "It is fastened to the floor!") + return 0 + src.set_dir(turn(src.dir, 270)) + return 1 + +/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/I as obj, mob/user as mob) + if(I.is_wrench()) + src.add_fingerprint(user) + if(bottle) + playsound(src, I.usesound, 50, 1) + if(do_after(user, 20) && bottle) + to_chat(user, "You unfasten the jug.") + var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = new /obj/item/weapon/reagent_containers/glass/cooler_bottle( src.loc ) + for(var/datum/reagent/R in reagents.reagent_list) + var/total_reagent = reagents.get_reagent_amount(R.id) + G.reagents.add_reagent(R.id, total_reagent) + reagents.clear_reagents() + bottle = 0 + update_icon() + else + if(anchored) + user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.") + else + user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.") + if(do_after(user, 20 * I.toolspeed, src)) + if(!src) return + to_chat(user, "You [anchored? "un" : ""]secured \the [src]!") + anchored = !anchored + playsound(src, I.usesound, 50, 1) + return + + if(I.is_screwdriver()) + if(cupholder) + playsound(src, I.usesound, 50, 1) + to_chat(user, "You take the cup dispenser off.") + new /obj/item/stack/material/plastic( src.loc ) + if(cups) + for(var/i = 0 to cups) + new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc) + cups = 0 + cupholder = 0 + update_icon() + return + if(!bottle && !cupholder) + playsound(src, I.usesound, 50, 1) + to_chat(user, "You start taking the water-cooler apart.") + if(do_after(user, 20 * I.toolspeed) && !bottle && !cupholder) + to_chat(user, "You take the water-cooler apart.") + new /obj/item/stack/material/plastic( src.loc, 4 ) + qdel(src) + return + + if(istype(I, /obj/item/weapon/reagent_containers/glass/cooler_bottle)) + src.add_fingerprint(user) + if(!bottle) + if(anchored) + var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = I + to_chat(user, "You start to screw the bottle onto the water-cooler.") + if(do_after(user, 20) && !bottle && anchored) + bottle = 1 + update_icon() + to_chat(user, "You screw the bottle onto the water-cooler!") + for(var/datum/reagent/R in G.reagents.reagent_list) + var/total_reagent = G.reagents.get_reagent_amount(R.id) + reagents.add_reagent(R.id, total_reagent) + qdel(G) + else + to_chat(user, "You need to wrench down the cooler first.") + else + to_chat(user, "There is already a bottle there!") + return 1 + + if(istype(I, /obj/item/stack/material/plastic)) + if(!cupholder) + if(anchored) + var/obj/item/stack/material/plastic/P = I + src.add_fingerprint(user) + to_chat(user, "You start to attach a cup dispenser onto the water-cooler.") + playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) + if(do_after(user, 20) && !cupholder && anchored) + if (P.use(1)) + to_chat(user, "You attach a cup dispenser onto the water-cooler.") + cupholder = 1 + update_icon() + else + to_chat(user, "You need to wrench down the cooler first.") + else + to_chat(user, "There is already a cup dispenser there!") + return + +/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/user) + if(cups) + new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc) + cups-- + flick("[icon_state]-vend", src) + return + +/obj/structure/reagent_dispensers/water_cooler/update_icon() + icon_state = "water_cooler" + overlays.Cut() + var/image/I + if(bottle) + I = image(icon, "water_cooler_bottle") + overlays += I + return + +/obj/structure/reagent_dispensers/beerkeg + name = "beer keg" + desc = "A beer keg." + icon = 'icons/obj/objects.dmi' + icon_state = "beertankTEMP" + amount_per_transfer_from_this = 10 + +/obj/structure/reagent_dispensers/beerkeg/Initialize() + . = ..() + reagents.add_reagent("beer",1000) + +/obj/structure/reagent_dispensers/beerkeg/fakenuke + name = "nuclear beer keg" + desc = "A beer keg in the form of a nuclear bomb! An absolute blast at parties!" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "nuclearbomb0" + +/obj/structure/reagent_dispensers/virusfood + name = "Virus Food Dispenser" + desc = "A dispenser of virus food. Yum." + icon = 'icons/obj/objects.dmi' + icon_state = "virusfoodtank" + amount_per_transfer_from_this = 10 + anchored = 1 + +/obj/structure/reagent_dispensers/virusfood/Initialize() + . = ..() + reagents.add_reagent("virusfood", 1000) + +/obj/structure/reagent_dispensers/acid + name = "Sulphuric Acid Dispenser" + desc = "A dispenser of acid for industrial processes." + icon = 'icons/obj/objects.dmi' + icon_state = "acidtank" + amount_per_transfer_from_this = 10 + anchored = 1 + +/obj/structure/reagent_dispensers/acid/Initialize() + . = ..() + reagents.add_reagent("sacid", 1000) + +//Cooking oil refill tank +/obj/structure/reagent_dispensers/cookingoil + name = "cooking oil tank" + desc = "A fifty-litre tank of commercial-grade corn oil, intended for use in large scale deep fryers. Store in a cool, dark place" + icon = 'icons/obj/objects.dmi' + icon_state = "oiltank" + amount_per_transfer_from_this = 120 + +/obj/structure/reagent_dispensers/cookingoil/New() + ..() + reagents.add_reagent("cornoil",5000) + +/obj/structure/reagent_dispensers/cookingoil/bullet_act(var/obj/item/projectile/Proj) + if(Proj.get_structure_damage()) + explode() + +/obj/structure/reagent_dispensers/cookingoil/ex_act() + explode() + +/obj/structure/reagent_dispensers/cookingoil/proc/explode() + reagents.splash_area(get_turf(src), 3) + visible_message(span("danger", "The [src] bursts open, spreading oil all over the area.")) + qdel(src) + +/obj/structure/reagent_dispensers/he3 + name = "fueltank" + desc = "A fueltank." + icon = 'icons/obj/objects.dmi' + icon_state = "weldtank" + amount_per_transfer_from_this = 10 + +/obj/structure/reagent_dispenser/he3/Initialize() + ..() + reagents.add_reagent("helium3",1000) \ No newline at end of file diff --git a/code/modules/reagents/dispenser/supply.dm b/code/modules/reagents/machinery/dispenser/supply.dm similarity index 98% rename from code/modules/reagents/dispenser/supply.dm rename to code/modules/reagents/machinery/dispenser/supply.dm index 228c5dfeef..30b1c3c0f6 100644 --- a/code/modules/reagents/dispenser/supply.dm +++ b/code/modules/reagents/machinery/dispenser/supply.dm @@ -1,238 +1,238 @@ -/datum/supply_pack/chemistry_dispenser - name = "Reagent dispenser" - contains = list( - /obj/machinery/chemical_dispenser{anchored = 0} - ) - cost = 25 - containertype = /obj/structure/largecrate - containername = "reagent dispenser crate" - group = "Reagents" - -/datum/supply_pack/beer_dispenser - name = "Booze dispenser" - contains = list( - /obj/machinery/chemical_dispenser/bar_alc{anchored = 0} - ) - cost = 25 - containertype = /obj/structure/largecrate - containername = "booze dispenser crate" - group = "Reagents" - -/datum/supply_pack/soda_dispenser - name = "Soda dispenser" - contains = list( - /obj/machinery/chemical_dispenser/bar_soft{anchored = 0} - ) - cost = 25 - containertype = /obj/structure/largecrate - containername = "soda dispenser crate" - group = "Reagents" - -/datum/supply_pack/reagents - name = "Chemistry dispenser refill" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten - ) - cost = 150 - containertype = /obj/structure/closet/crate/secure - containername = "chemical crate" - access = list(access_chemistry) - group = "Reagents" - -/datum/supply_pack/alcohol_reagents - name = "Bar alcoholic dispenser refill" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/bitters - ) - cost = 50 - containertype = /obj/structure/closet/crate/secure - containername = "alcoholic drinks crate" - access = list(access_bar) - group = "Reagents" - -/datum/supply_pack/softdrink_reagents - name = "Bar soft drink dispenser refill" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon - ) - cost = 50 - containertype = /obj/structure/closet/crate - containername = "soft drinks crate" - group = "Reagents" - -/datum/supply_pack/coffee_reagents - name = "Coffee machine dispenser refill" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, - /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice - ) - cost = 50 - containertype = /obj/structure/closet/crate - containername = "coffee drinks crate" - group = "Reagents" - -/datum/supply_pack/dispenser_cartridges - name = "Empty dispenser cartridges" - contains = list( - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge, - /obj/item/weapon/reagent_containers/chem_disp_cartridge - ) - cost = 15 - containertype = /obj/structure/closet/crate - containername = "dispenser cartridge crate" - group = "Reagents" - -#define SEC_PACK(_tname, _type, _name, _cname, _cost, _access)\ - datum/supply_pack/dispenser_cartridges{\ - _tname {\ - name = _name ;\ - containername = _cname ;\ - containertype = /obj/structure/closet/crate/secure;\ - access = list( _access );\ - cost = _cost ;\ - contains = list( _type , _type );\ - group = "Reagent Cartridges"\ - }\ - } -#define PACK(_tname, _type, _name, _cname, _cost)\ - datum/supply_pack/dispenser_cartridges{\ - _tname {\ - name = _name ;\ - containername = _cname ;\ - containertype = /obj/structure/closet/crate;\ - cost = _cost ;\ - contains = list( _type , _type );\ - group = "Reagent Cartridges"\ - }\ - } - -// Chemistry-restricted (raw reagents excluding sugar/water) -// Datum path Contents type Supply pack name Container name Cost Container access -SEC_PACK(hydrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, "Reagent refill - Hydrogen", "hydrogen reagent cartridge crate", 15, access_chemistry) -SEC_PACK(lithium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, "Reagent refill - Lithium", "lithium reagent cartridge crate", 15, access_chemistry) -SEC_PACK(carbon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, "Reagent refill - Carbon", "carbon reagent cartridge crate", 15, access_chemistry) -SEC_PACK(nitrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, "Reagent refill - Nitrogen", "nitrogen reagent cartridge crate", 15, access_chemistry) -SEC_PACK(oxygen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, "Reagent refill - Oxygen", "oxygen reagent cartridge crate", 15, access_chemistry) -SEC_PACK(fluorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, "Reagent refill - Fluorine", "fluorine reagent cartridge crate", 15, access_chemistry) -SEC_PACK(sodium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, "Reagent refill - Sodium", "sodium reagent cartridge crate", 15, access_chemistry) -SEC_PACK(aluminium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, "Reagent refill - Aluminum", "aluminum reagent cartridge crate", 15, access_chemistry) -SEC_PACK(silicon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, "Reagent refill - Silicon", "silicon reagent cartridge crate", 15, access_chemistry) -SEC_PACK(phosphorus,/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, "Reagent refill - Phosphorus", "phosphorus reagent cartridge crate", 15, access_chemistry) -SEC_PACK(sulfur, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, "Reagent refill - Sulfur", "sulfur reagent cartridge crate", 15, access_chemistry) -SEC_PACK(chlorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, "Reagent refill - Chlorine", "chlorine reagent cartridge crate", 15, access_chemistry) -SEC_PACK(potassium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, "Reagent refill - Potassium", "potassium reagent cartridge crate", 15, access_chemistry) -SEC_PACK(iron, /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, "Reagent refill - Iron", "iron reagent cartridge crate", 15, access_chemistry) -SEC_PACK(copper, /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, "Reagent refill - Copper", "copper reagent cartridge crate", 15, access_chemistry) -SEC_PACK(mercury, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, "Reagent refill - Mercury", "mercury reagent cartridge crate", 15, access_chemistry) -SEC_PACK(radium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, "Reagent refill - Radium", "radium reagent cartridge crate", 15, access_chemistry) -SEC_PACK(ethanol, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, "Reagent refill - Ethanol", "ethanol reagent cartridge crate", 15, access_chemistry) -SEC_PACK(sacid, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, "Reagent refill - Sulfuric Acid", "sulfuric acid reagent cartridge crate", 15, access_chemistry) -SEC_PACK(tungsten, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, "Reagent refill - Tungsten", "tungsten reagent cartridge crate", 15, access_chemistry) -SEC_PACK(calcium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium, "Reagent refill - Calcium", "calcium reagent cartridge crate", 15, access_chemistry) - -// Bar-restricted (alcoholic drinks) -// Datum path Contents type Supply pack name Container name Cost Container access -SEC_PACK(beer, /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, "Reagent refill - Beer", "beer reagent cartridge crate", 15, access_bar) -SEC_PACK(kahlua, /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, "Reagent refill - Kahlua", "kahlua reagent cartridge crate", 15, access_bar) -SEC_PACK(whiskey, /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, "Reagent refill - Whiskey", "whiskey reagent cartridge crate", 15, access_bar) -SEC_PACK(wine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, "Reagent refill - Wine", "wine reagent cartridge crate", 15, access_bar) -SEC_PACK(vodka, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, "Reagent refill - Vodka", "vodka reagent cartridge crate", 15, access_bar) -SEC_PACK(gin, /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, "Reagent refill - Gin", "gin reagent cartridge crate", 15, access_bar) -SEC_PACK(rum, /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, "Reagent refill - Rum", "rum reagent cartridge crate", 15, access_bar) -SEC_PACK(tequila, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, "Reagent refill - Tequila", "tequila reagent cartridge crate", 15, access_bar) -SEC_PACK(vermouth, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, "Reagent refill - Vermouth", "vermouth reagent cartridge crate", 15, access_bar) -SEC_PACK(cognac, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, "Reagent refill - Cognac", "cognac reagent cartridge crate", 15, access_bar) -SEC_PACK(ale, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, "Reagent refill - Ale", "ale reagent cartridge crate", 15, access_bar) -SEC_PACK(mead, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, "Reagent refill - Mead", "mead reagent cartridge crate", 15, access_bar) - -// Unrestricted (water, sugar, non-alcoholic drinks) -// Datum path Contents type Supply pack name Container name Cost -PACK(water, /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, "Reagent refill - Water", "water reagent cartridge crate", 15) -PACK(sugar, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, "Reagent refill - Sugar", "sugar reagent cartridge crate", 15) -PACK(ice, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, "Reagent refill - Ice", "ice reagent cartridge crate", 15) -PACK(tea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, "Reagent refill - Tea", "tea reagent cartridge crate", 15) -PACK(icetea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, "Reagent refill - Iced Tea", "iced tea reagent cartridge crate", 15) -PACK(cola, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, "Reagent refill - Space Cola", "\improper Space Cola reagent cartridge crate", 15) -PACK(smw, /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, "Reagent refill - Space Mountain Wind", "\improper Space Mountain Wind reagent cartridge crate", 15) -PACK(dr_gibb, /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, "Reagent refill - Dr. Gibb", "\improper Dr. Gibb reagent cartridge crate", 15) -PACK(spaceup, /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, "Reagent refill - Space-Up", "\improper Space-Up reagent cartridge crate", 15) -PACK(tonic, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, "Reagent refill - Tonic Water", "tonic water reagent cartridge crate", 15) -PACK(sodawater, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, "Reagent refill - Soda Water", "soda water reagent cartridge crate", 15) -PACK(lemon_lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, "Reagent refill - Lemon-Lime Juice", "lemon-lime juice reagent cartridge crate", 15) -PACK(orange, /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, "Reagent refill - Orange Juice", "orange juice reagent cartridge crate", 15) -PACK(lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, "Reagent refill - Lime Juice", "lime juice reagent cartridge crate", 15) -PACK(lemon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, "Reagent refill - Lemon Juice", "lemon juice reagent cartridge crate", 15) -PACK(watermelon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, "Reagent refill - Watermelon Juice", "watermelon juice reagent cartridge crate", 15) -PACK(coffee, /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, "Reagent refill - Coffee", "coffee reagent cartridge crate", 15) -PACK(cafe_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, "Reagent refill - Cafe Latte", "cafe latte reagent cartridge crate", 15) -PACK(soy_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, "Reagent refill - Soy Latte", "soy latte reagent cartridge crate", 15) -PACK(hot_coco, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, "Reagent refill - Hot Coco", "hot coco reagent cartridge crate", 15) -PACK(milk, /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, "Reagent refill - Milk", "milk reagent cartridge crate", 15) -PACK(cream, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, "Reagent refill - Cream", "cream reagent cartridge crate", 15) - -#undef SEC_PACK -#undef PACK +/datum/supply_pack/chemistry_dispenser + name = "Reagent dispenser" + contains = list( + /obj/machinery/chemical_dispenser{anchored = 0} + ) + cost = 25 + containertype = /obj/structure/largecrate + containername = "reagent dispenser crate" + group = "Reagents" + +/datum/supply_pack/beer_dispenser + name = "Booze dispenser" + contains = list( + /obj/machinery/chemical_dispenser/bar_alc{anchored = 0} + ) + cost = 25 + containertype = /obj/structure/largecrate + containername = "booze dispenser crate" + group = "Reagents" + +/datum/supply_pack/soda_dispenser + name = "Soda dispenser" + contains = list( + /obj/machinery/chemical_dispenser/bar_soft{anchored = 0} + ) + cost = 25 + containertype = /obj/structure/largecrate + containername = "soda dispenser crate" + group = "Reagents" + +/datum/supply_pack/reagents + name = "Chemistry dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten + ) + cost = 150 + containertype = /obj/structure/closet/crate/secure + containername = "chemical crate" + access = list(access_chemistry) + group = "Reagents" + +/datum/supply_pack/alcohol_reagents + name = "Bar alcoholic dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/bitters + ) + cost = 50 + containertype = /obj/structure/closet/crate/secure + containername = "alcoholic drinks crate" + access = list(access_bar) + group = "Reagents" + +/datum/supply_pack/softdrink_reagents + name = "Bar soft drink dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon + ) + cost = 50 + containertype = /obj/structure/closet/crate + containername = "soft drinks crate" + group = "Reagents" + +/datum/supply_pack/coffee_reagents + name = "Coffee machine dispenser refill" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, + /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice + ) + cost = 50 + containertype = /obj/structure/closet/crate + containername = "coffee drinks crate" + group = "Reagents" + +/datum/supply_pack/dispenser_cartridges + name = "Empty dispenser cartridges" + contains = list( + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge, + /obj/item/weapon/reagent_containers/chem_disp_cartridge + ) + cost = 15 + containertype = /obj/structure/closet/crate + containername = "dispenser cartridge crate" + group = "Reagents" + +#define SEC_PACK(_tname, _type, _name, _cname, _cost, _access)\ + datum/supply_pack/dispenser_cartridges{\ + _tname {\ + name = _name ;\ + containername = _cname ;\ + containertype = /obj/structure/closet/crate/secure;\ + access = list( _access );\ + cost = _cost ;\ + contains = list( _type , _type );\ + group = "Reagent Cartridges"\ + }\ + } +#define PACK(_tname, _type, _name, _cname, _cost)\ + datum/supply_pack/dispenser_cartridges{\ + _tname {\ + name = _name ;\ + containername = _cname ;\ + containertype = /obj/structure/closet/crate;\ + cost = _cost ;\ + contains = list( _type , _type );\ + group = "Reagent Cartridges"\ + }\ + } + +// Chemistry-restricted (raw reagents excluding sugar/water) +// Datum path Contents type Supply pack name Container name Cost Container access +SEC_PACK(hydrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, "Reagent refill - Hydrogen", "hydrogen reagent cartridge crate", 15, access_chemistry) +SEC_PACK(lithium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, "Reagent refill - Lithium", "lithium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(carbon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, "Reagent refill - Carbon", "carbon reagent cartridge crate", 15, access_chemistry) +SEC_PACK(nitrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, "Reagent refill - Nitrogen", "nitrogen reagent cartridge crate", 15, access_chemistry) +SEC_PACK(oxygen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, "Reagent refill - Oxygen", "oxygen reagent cartridge crate", 15, access_chemistry) +SEC_PACK(fluorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, "Reagent refill - Fluorine", "fluorine reagent cartridge crate", 15, access_chemistry) +SEC_PACK(sodium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, "Reagent refill - Sodium", "sodium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(aluminium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, "Reagent refill - Aluminum", "aluminum reagent cartridge crate", 15, access_chemistry) +SEC_PACK(silicon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, "Reagent refill - Silicon", "silicon reagent cartridge crate", 15, access_chemistry) +SEC_PACK(phosphorus,/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, "Reagent refill - Phosphorus", "phosphorus reagent cartridge crate", 15, access_chemistry) +SEC_PACK(sulfur, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, "Reagent refill - Sulfur", "sulfur reagent cartridge crate", 15, access_chemistry) +SEC_PACK(chlorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, "Reagent refill - Chlorine", "chlorine reagent cartridge crate", 15, access_chemistry) +SEC_PACK(potassium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, "Reagent refill - Potassium", "potassium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(iron, /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, "Reagent refill - Iron", "iron reagent cartridge crate", 15, access_chemistry) +SEC_PACK(copper, /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, "Reagent refill - Copper", "copper reagent cartridge crate", 15, access_chemistry) +SEC_PACK(mercury, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, "Reagent refill - Mercury", "mercury reagent cartridge crate", 15, access_chemistry) +SEC_PACK(radium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, "Reagent refill - Radium", "radium reagent cartridge crate", 15, access_chemistry) +SEC_PACK(ethanol, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, "Reagent refill - Ethanol", "ethanol reagent cartridge crate", 15, access_chemistry) +SEC_PACK(sacid, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, "Reagent refill - Sulfuric Acid", "sulfuric acid reagent cartridge crate", 15, access_chemistry) +SEC_PACK(tungsten, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, "Reagent refill - Tungsten", "tungsten reagent cartridge crate", 15, access_chemistry) +SEC_PACK(calcium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium, "Reagent refill - Calcium", "calcium reagent cartridge crate", 15, access_chemistry) + +// Bar-restricted (alcoholic drinks) +// Datum path Contents type Supply pack name Container name Cost Container access +SEC_PACK(beer, /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, "Reagent refill - Beer", "beer reagent cartridge crate", 15, access_bar) +SEC_PACK(kahlua, /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, "Reagent refill - Kahlua", "kahlua reagent cartridge crate", 15, access_bar) +SEC_PACK(whiskey, /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, "Reagent refill - Whiskey", "whiskey reagent cartridge crate", 15, access_bar) +SEC_PACK(wine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, "Reagent refill - Wine", "wine reagent cartridge crate", 15, access_bar) +SEC_PACK(vodka, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, "Reagent refill - Vodka", "vodka reagent cartridge crate", 15, access_bar) +SEC_PACK(gin, /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, "Reagent refill - Gin", "gin reagent cartridge crate", 15, access_bar) +SEC_PACK(rum, /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, "Reagent refill - Rum", "rum reagent cartridge crate", 15, access_bar) +SEC_PACK(tequila, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, "Reagent refill - Tequila", "tequila reagent cartridge crate", 15, access_bar) +SEC_PACK(vermouth, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, "Reagent refill - Vermouth", "vermouth reagent cartridge crate", 15, access_bar) +SEC_PACK(cognac, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, "Reagent refill - Cognac", "cognac reagent cartridge crate", 15, access_bar) +SEC_PACK(ale, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, "Reagent refill - Ale", "ale reagent cartridge crate", 15, access_bar) +SEC_PACK(mead, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, "Reagent refill - Mead", "mead reagent cartridge crate", 15, access_bar) + +// Unrestricted (water, sugar, non-alcoholic drinks) +// Datum path Contents type Supply pack name Container name Cost +PACK(water, /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, "Reagent refill - Water", "water reagent cartridge crate", 15) +PACK(sugar, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, "Reagent refill - Sugar", "sugar reagent cartridge crate", 15) +PACK(ice, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, "Reagent refill - Ice", "ice reagent cartridge crate", 15) +PACK(tea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, "Reagent refill - Tea", "tea reagent cartridge crate", 15) +PACK(icetea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, "Reagent refill - Iced Tea", "iced tea reagent cartridge crate", 15) +PACK(cola, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, "Reagent refill - Space Cola", "\improper Space Cola reagent cartridge crate", 15) +PACK(smw, /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, "Reagent refill - Space Mountain Wind", "\improper Space Mountain Wind reagent cartridge crate", 15) +PACK(dr_gibb, /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, "Reagent refill - Dr. Gibb", "\improper Dr. Gibb reagent cartridge crate", 15) +PACK(spaceup, /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, "Reagent refill - Space-Up", "\improper Space-Up reagent cartridge crate", 15) +PACK(tonic, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, "Reagent refill - Tonic Water", "tonic water reagent cartridge crate", 15) +PACK(sodawater, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, "Reagent refill - Soda Water", "soda water reagent cartridge crate", 15) +PACK(lemon_lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, "Reagent refill - Lemon-Lime Juice", "lemon-lime juice reagent cartridge crate", 15) +PACK(orange, /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, "Reagent refill - Orange Juice", "orange juice reagent cartridge crate", 15) +PACK(lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, "Reagent refill - Lime Juice", "lime juice reagent cartridge crate", 15) +PACK(lemon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, "Reagent refill - Lemon Juice", "lemon juice reagent cartridge crate", 15) +PACK(watermelon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, "Reagent refill - Watermelon Juice", "watermelon juice reagent cartridge crate", 15) +PACK(coffee, /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, "Reagent refill - Coffee", "coffee reagent cartridge crate", 15) +PACK(cafe_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, "Reagent refill - Cafe Latte", "cafe latte reagent cartridge crate", 15) +PACK(soy_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, "Reagent refill - Soy Latte", "soy latte reagent cartridge crate", 15) +PACK(hot_coco, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, "Reagent refill - Hot Coco", "hot coco reagent cartridge crate", 15) +PACK(milk, /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, "Reagent refill - Milk", "milk reagent cartridge crate", 15) +PACK(cream, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, "Reagent refill - Cream", "cream reagent cartridge crate", 15) + +#undef SEC_PACK +#undef PACK diff --git a/code/modules/reagents/distilling/distilling.dm b/code/modules/reagents/machinery/distillery.dm similarity index 92% rename from code/modules/reagents/distilling/distilling.dm rename to code/modules/reagents/machinery/distillery.dm index 4bd8bd163e..d64d8b3211 100644 --- a/code/modules/reagents/distilling/distilling.dm +++ b/code/modules/reagents/machinery/distillery.dm @@ -53,31 +53,16 @@ var/image/overlay_dumping var/image/overlay_connected -// Our unique beaker, used in its unique recipes to ensure things can only react inside this machine and minimize oddities from trying to transfer to a machine and back. - var/obj/item/weapon/reagent_containers/glass/distilling/Reservoir - var/obj/item/weapon/reagent_containers/glass/InputBeaker var/obj/item/weapon/reagent_containers/glass/OutputBeaker // A multiplier for the production amount. This should really only ever be lower than one, otherwise you end up with duping. var/efficiency = 1 -/obj/item/weapon/reagent_containers/glass/distilling - name = "distilling chamber" - desc = "You should not be seeing this." - volume = 600 - - var/obj/machinery/portable_atmospherics/powered/reagent_distillery/Master - -/obj/item/weapon/reagent_containers/glass/distilling/Destroy() - Master = null - ..() - /obj/machinery/portable_atmospherics/powered/reagent_distillery/Initialize() . = ..() - Reservoir = new (src) - Reservoir.Master = src + create_reagents(600, /datum/reagents/distilling) if(!base_state) base_state = icon_state @@ -107,8 +92,6 @@ overlay_connected = image(icon = src.icon, icon_state = "[base_state]-connector") /obj/machinery/portable_atmospherics/powered/reagent_distillery/Destroy() - qdel(Reservoir) - Reservoir = null if(InputBeaker) qdel(InputBeaker) InputBeaker = null @@ -134,8 +117,8 @@ else . += "\The [src]'s input beaker is empty!" - if(Reservoir.reagents.reagent_list.len) - . += "\The [src]'s internal buffer holds [Reservoir.reagents.total_volume] units of liquid." + if(reagents.reagent_list.len) + . += "\The [src]'s internal buffer holds [reagents.total_volume] units of liquid." else . += "\The [src]'s internal buffer is empty!" @@ -164,7 +147,7 @@ to_chat(user, "You press \the [src]'s chamber agitator button.") if(on) visible_message("\The [src] rattles to life.") - Reservoir.reagents.handle_reactions() + reagents.handle_reactions() else spawn(1 SECOND) to_chat(user, "Nothing happens..") @@ -341,12 +324,12 @@ visible_message("\The [src]'s motors wind down.") on = FALSE - if(InputBeaker && Reservoir.reagents.total_volume < Reservoir.reagents.maximum_volume) - InputBeaker.reagents.trans_to_holder(Reservoir.reagents, amount = rand(10,20)) + if(InputBeaker && reagents.total_volume < reagents.maximum_volume) + InputBeaker.reagents.trans_to_holder(reagents, amount = rand(10,20)) if(OutputBeaker && OutputBeaker.reagents.total_volume < OutputBeaker.reagents.maximum_volume) use_power(power_rating * CELLRATE * 0.5) - Reservoir.reagents.trans_to_holder(OutputBeaker.reagents, amount = rand(1, 5)) + reagents.trans_to_holder(OutputBeaker.reagents, amount = rand(1, 5)) update_icon() diff --git a/code/modules/reagents/machinery/grinder.dm b/code/modules/reagents/machinery/grinder.dm new file mode 100644 index 0000000000..6be08f67e7 --- /dev/null +++ b/code/modules/reagents/machinery/grinder.dm @@ -0,0 +1,263 @@ +/obj/machinery/reagentgrinder + + name = "All-In-One Grinder" + desc = "Grinds stuff into itty bitty bits." + icon = 'icons/obj/kitchen.dmi' + icon_state = "juicer1" + density = 0 + anchored = 0 + use_power = USE_POWER_IDLE + idle_power_usage = 5 + active_power_usage = 100 + circuit = /obj/item/weapon/circuitboard/grinder + var/inuse = 0 + var/obj/item/weapon/reagent_containers/beaker = null + var/limit = 10 + var/list/holdingitems = list() + var/list/sheet_reagents = list( //have a number of reageents divisible by REAGENTS_PER_SHEET (default 20) unless you like decimals, + /obj/item/stack/material/iron = list("iron"), + /obj/item/stack/material/uranium = list("uranium"), + /obj/item/stack/material/phoron = list("phoron"), + /obj/item/stack/material/gold = list("gold"), + /obj/item/stack/material/silver = list("silver"), + /obj/item/stack/material/platinum = list("platinum"), + /obj/item/stack/material/mhydrogen = list("hydrogen"), + /obj/item/stack/material/steel = list("iron", "carbon"), + /obj/item/stack/material/plasteel = list("iron", "iron", "carbon", "carbon", "platinum"), //8 iron, 8 carbon, 4 platinum, + /obj/item/stack/material/snow = list("water"), + /obj/item/stack/material/sandstone = list("silicon", "oxygen"), + /obj/item/stack/material/glass = list("silicon"), + /obj/item/stack/material/glass/phoronglass = list("platinum", "silicon", "silicon", "silicon"), //5 platinum, 15 silicon, + ) + + var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine") + var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject") + var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind") + // var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice") + // var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix") + +/obj/machinery/reagentgrinder/Initialize() + . = ..() + beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) + default_apply_parts() + +/obj/machinery/reagentgrinder/examine(mob/user) + . = ..() + if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) + . += "You're too far away to examine [src]'s contents and display!" + return + + if(inuse) + . += "\The [src] is operating." + return + + if(beaker || length(holdingitems)) + . += "\The [src] contains:" + if(beaker) + . += "- \A [beaker]." + for(var/i in holdingitems) + var/obj/item/O = i + . += "- \A [O.name]." + + if(!(stat & (NOPOWER|BROKEN))) + . += "The status display reads:\n" + if(beaker) + for(var/datum/reagent/R in beaker.reagents.reagent_list) + . += "- [R.volume] units of [R.name]." + +/obj/machinery/reagentgrinder/update_icon() + icon_state = "juicer"+num2text(!isnull(beaker)) + return + +/obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(beaker) + if(default_deconstruction_screwdriver(user, O)) + return + if(default_deconstruction_crowbar(user, O)) + return + + if (istype(O,/obj/item/weapon/reagent_containers/glass) || \ + istype(O,/obj/item/weapon/reagent_containers/food/drinks/glass2) || \ + istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) + + if (beaker) + return 1 + else + src.beaker = O + user.drop_item() + O.loc = src + update_icon() + src.updateUsrDialog() + return 0 + + if(holdingitems && holdingitems.len >= limit) + to_chat(user, "The machine cannot hold anymore items.") + return 1 + + if(!istype(O)) + return + + if(istype(O,/obj/item/weapon/storage/bag/plants)) + var/obj/item/weapon/storage/bag/plants/bag = O + var/failed = 1 + for(var/obj/item/G in O.contents) + if(!G.reagents || !G.reagents.total_volume) + continue + failed = 0 + bag.remove_from_storage(G, src) + holdingitems += G + if(holdingitems && holdingitems.len >= limit) + break + + if(failed) + to_chat(user, "Nothing in the plant bag is usable.") + return 1 + + if(!O.contents.len) + to_chat(user, "You empty \the [O] into \the [src].") + else + to_chat(user, "You fill \the [src] from \the [O].") + + src.updateUsrDialog() + return 0 + + if(istype(O,/obj/item/weapon/gripper)) + var/obj/item/weapon/gripper/B = O //B, for Borg. + if(!B.wrapped) + to_chat(user, "\The [B] is not holding anything.") + return 0 + else + var/B_held = B.wrapped + to_chat(user, "You use \the [B] to load \the [src] with \the [B_held].") + + return 0 + + if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume)) + to_chat(user, "\The [O] is not suitable for blending.") + return 1 + + user.remove_from_mob(O) + O.loc = src + holdingitems += O + return 0 + +/obj/machinery/reagentgrinder/AltClick(mob/user) + . = ..() + if(user.incapacitated() || !Adjacent(user)) + return + replace_beaker(user) + +/obj/machinery/reagentgrinder/attack_hand(mob/user as mob) + interact(user) + +/obj/machinery/reagentgrinder/interact(mob/user as mob) // The microwave Menu //I am reasonably certain that this is not a microwave + if(inuse || user.incapacitated()) + return + + var/list/options = list() + + if(beaker || length(holdingitems)) + options["eject"] = radial_eject + + if(isAI(user)) + if(stat & NOPOWER) + return + options["examine"] = radial_examine + + // if there is no power or it's broken, the procs will fail but the buttons will still show + if(length(holdingitems)) + options["grind"] = radial_grind + + var/choice + if(length(options) < 1) + return + if(length(options) == 1) + for(var/key in options) + choice = key + else + choice = show_radial_menu(user, src, options, require_near = !issilicon(user)) + + // post choice verification + if(inuse || (isAI(user) && stat & NOPOWER) || user.incapacitated()) + return + + switch(choice) + if("eject") + eject(user) + if("grind") + grind(user) + if("examine") + examine(user) + +/obj/machinery/reagentgrinder/proc/eject(mob/user) + if(user.incapacitated()) + return + for(var/obj/item/O in holdingitems) + O.loc = src.loc + holdingitems -= O + holdingitems.Cut() + if(beaker) + replace_beaker(user) + +/obj/machinery/reagentgrinder/proc/grind() + + power_change() + if(stat & (NOPOWER|BROKEN)) + return + + // Sanity check. + if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) + return + + playsound(src, 'sound/machines/blender.ogg', 50, 1) + inuse = 1 + + // Reset the machine. + spawn(60) + inuse = 0 + + // Process. + for (var/obj/item/O in holdingitems) + + var/remaining_volume = beaker.reagents.maximum_volume - beaker.reagents.total_volume + if(remaining_volume <= 0) + break + + if(sheet_reagents[O.type]) + var/obj/item/stack/stack = O + if(istype(stack)) + var/list/sheet_components = sheet_reagents[stack.type] + var/amount_to_take = max(0,min(stack.amount,round(remaining_volume/REAGENTS_PER_SHEET))) + if(amount_to_take) + stack.use(amount_to_take) + if(QDELETED(stack)) + holdingitems -= stack + if(islist(sheet_components)) + amount_to_take = (amount_to_take/(sheet_components.len)) + for(var/i in sheet_components) + beaker.reagents.add_reagent(i, (amount_to_take*REAGENTS_PER_SHEET)) + else + beaker.reagents.add_reagent(sheet_components, (amount_to_take*REAGENTS_PER_SHEET)) + continue + + if(O.reagents) + O.reagents.trans_to_obj(beaker, min(O.reagents.total_volume, remaining_volume)) + if(O.reagents.total_volume == 0) + holdingitems -= O + qdel(O) + if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + +/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/weapon/reagent_containers/new_beaker) + if(!user) + return FALSE + if(beaker) + if(!user.incapacitated() && Adjacent(user)) + user.put_in_hands(beaker) + else + beaker.forceMove(drop_location()) + beaker = null + if(new_beaker) + beaker = new_beaker + update_icon() + return TRUE \ No newline at end of file diff --git a/code/modules/reagents/reactions/_reactions.dm b/code/modules/reagents/reactions/_reactions.dm new file mode 100644 index 0000000000..d63967d900 --- /dev/null +++ b/code/modules/reagents/reactions/_reactions.dm @@ -0,0 +1,128 @@ +//helper that ensures the reaction rate holds after iterating +//Ex. REACTION_RATE(0.3) means that 30% of the reagents will react each chemistry tick (~2 seconds by default). +#define REACTION_RATE(rate) (1.0 - (1.0-rate)**(1.0/PROCESS_REACTION_ITER)) + +//helper to define reaction rate in terms of half-life +//Ex. +//HALF_LIFE(0) -> Reaction completes immediately (default chems) +//HALF_LIFE(1) -> Half of the reagents react immediately, the rest over the following ticks. +//HALF_LIFE(2) -> Half of the reagents are consumed after 2 chemistry ticks. +//HALF_LIFE(3) -> Half of the reagents are consumed after 3 chemistry ticks. +#define HALF_LIFE(ticks) (ticks? 1.0 - (0.5)**(1.0/(ticks*PROCESS_REACTION_ITER)) : 1.0) + +/decl/chemical_reaction + var/name = null + var/id = null + var/result = null + var/list/required_reagents = list() + var/list/catalysts = list() + var/list/inhibitors = list() + var/result_amount = 0 + + //how far the reaction proceeds each time it is processed. Used with either REACTION_RATE or HALF_LIFE macros. + var/reaction_rate = HALF_LIFE(0) + + //if less than 1, the reaction will be inhibited if the ratio of products/reagents is too high. + //0.5 = 50% yield -> reaction will only proceed halfway until products are removed. + var/yield = 1.0 + + //If limits on reaction rate would leave less than this amount of any reagent (adjusted by the reaction ratios), + //the reaction goes to completion. This is to prevent reactions from going on forever with tiny reagent amounts. + var/min_reaction = 2 + + var/mix_message = "The solution begins to bubble." + var/reaction_sound = 'sound/effects/bubbles.ogg' + + var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file. + +/decl/chemical_reaction/proc/can_happen(var/datum/reagents/holder) + //check that all the required reagents are present + if(!holder.has_all_reagents(required_reagents)) + return FALSE + + //check that all the required catalysts are present in the required amount + if(!holder.has_all_reagents(catalysts)) + return FALSE + + //check that none of the inhibitors are present in the required amount + if(holder.has_any_reagent(inhibitors)) + return FALSE + + return TRUE + +/decl/chemical_reaction/proc/calc_reaction_progress(var/datum/reagents/holder, var/reaction_limit) + var/progress = reaction_limit * reaction_rate //simple exponential progression + + //calculate yield + if(1-yield > 0.001) //if yield ratio is big enough just assume it goes to completion + /* + Determine the max amount of product by applying the yield condition: + (max_product/result_amount) / reaction_limit == yield/(1-yield) + + We make use of the fact that: + reaction_limit = (holder.get_reagent_amount(reactant) / required_reagents[reactant]) of the limiting reagent. + */ + var/yield_ratio = yield/(1-yield) + var/max_product = yield_ratio * reaction_limit * result_amount //rearrange to obtain max_product + var/yield_limit = max(0, max_product - holder.get_reagent_amount(result))/result_amount + + progress = min(progress, yield_limit) //apply yield limit + + //apply min reaction progress - wasn't sure if this should go before or after applying yield + //I guess people can just have their miniscule reactions go to completion regardless of yield. + for(var/reactant in required_reagents) + var/remainder = holder.get_reagent_amount(reactant) - progress*required_reagents[reactant] + if(remainder <= min_reaction*required_reagents[reactant]) + progress = reaction_limit + break + + return progress + +/decl/chemical_reaction/process(var/datum/reagents/holder) + //determine how far the reaction can proceed + var/list/reaction_limits = list() + for(var/reactant in required_reagents) + reaction_limits += holder.get_reagent_amount(reactant) / required_reagents[reactant] + + //determine how far the reaction proceeds + var/reaction_limit = min(reaction_limits) + var/progress_limit = calc_reaction_progress(holder, reaction_limit) + + var/reaction_progress = min(reaction_limit, progress_limit) //no matter what, the reaction progress cannot exceed the stoichiometric limit. + + //need to obtain the new reagent's data before anything is altered + var/data = send_data(holder, reaction_progress) + + //remove the reactants + for(var/reactant in required_reagents) + var/amt_used = required_reagents[reactant] * reaction_progress + holder.remove_reagent(reactant, amt_used, safety = 1) + + //add the product + var/amt_produced = result_amount * reaction_progress + if(result) + holder.add_reagent(result, amt_produced, data, safety = 1) + + on_reaction(holder, amt_produced) + + return reaction_progress + +//called when a reaction processes +/decl/chemical_reaction/proc/on_reaction(var/datum/reagents/holder, var/created_volume) + return + +//called after processing reactions, if they occurred +/decl/chemical_reaction/proc/post_reaction(var/datum/reagents/holder) + var/atom/container = holder.my_atom + if(mix_message && container && !ismob(container)) + var/turf/T = get_turf(container) + var/list/seen = viewers(4, T) + for(var/mob/M in seen) + if(M.client) + M.show_message("[bicon(container)] [mix_message]", 1) + playsound(T, reaction_sound, 80, 1) + +//obtains any special data that will be provided to the reaction products +//this is called just before reactants are removed. +/decl/chemical_reaction/proc/send_data(var/datum/reagents/holder, var/reaction_limit) + return null \ No newline at end of file diff --git a/code/modules/reagents/distilling/Distilling-Recipes.dm b/code/modules/reagents/reactions/distilling/distilling.dm similarity index 74% rename from code/modules/reagents/distilling/Distilling-Recipes.dm rename to code/modules/reagents/reactions/distilling/distilling.dm index 0736ac7e61..5944a75846 100644 --- a/code/modules/reagents/distilling/Distilling-Recipes.dm +++ b/code/modules/reagents/reactions/distilling/distilling.dm @@ -1,4 +1,4 @@ -/datum/chemical_reaction/distilling +/decl/chemical_reaction/distilling // name = null // id = null // result = null @@ -26,32 +26,19 @@ var/list/temp_range = list(T0C, T20C) var/temp_shift = 0 // How much the temperature changes when the reaction occurs. -/datum/chemical_reaction/distilling/can_happen(var/datum/reagents/holder) - //check that all the required reagents are present - if(!holder.has_all_reagents(required_reagents)) - return 0 +/decl/chemical_reaction/distilling/can_happen(var/datum/reagents/holder) + if(!istype(holder, /datum/reagents/distilling) || !istype(holder.my_atom, /obj/machinery/portable_atmospherics/powered/reagent_distillery)) + return FALSE - //check that all the required catalysts are present in the required amount - if(!holder.has_all_reagents(catalysts)) - return 0 + // Super special temperature check. + var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = holder.my_atom + if(RD.current_temp < temp_range[1] || RD.current_temp > temp_range[2]) + return FALSE - //check that none of the inhibitors are present in the required amount - if(holder.has_any_reagent(inhibitors)) - return 0 - - if(!istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling)) - return 0 - - else // Super special temperature check. - var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom - var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master - if(RD.current_temp < temp_range[1] || RD.current_temp > temp_range[2]) - return 0 - - return 1 + return ..() /* -/datum/chemical_reaction/distilling/on_reaction(var/datum/reagents/holder, var/created_volume) +/decl/chemical_reaction/distilling/on_reaction(var/datum/reagents/holder, var/created_volume) if(istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling)) var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master @@ -62,7 +49,7 @@ // Subtypes // // Biomass -/datum/chemical_reaction/distilling/biomass +/decl/chemical_reaction/distilling/biomass name = "Distilling Biomass" id = "distill_biomass" result = "biomass" @@ -73,7 +60,7 @@ temp_shift = -2 // Medicinal -/datum/chemical_reaction/distilling/inaprovalaze +/decl/chemical_reaction/distilling/inaprovalaze name = "Distilling Inaprovalaze" id = "distill_inaprovalaze" result = "inaprovalaze" @@ -84,7 +71,7 @@ temp_range = list(T0C + 100, T0C + 120) -/datum/chemical_reaction/distilling/bicaridaze +/decl/chemical_reaction/distilling/bicaridaze name = "Distilling Bicaridaze" id = "distill_bicaridaze" result = "bicaridaze" @@ -95,7 +82,7 @@ temp_range = list(T0C + 110, T0C + 130) -/datum/chemical_reaction/distilling/dermalaze +/decl/chemical_reaction/distilling/dermalaze name = "Distilling Dermalaze" id = "distill_dermalaze" result = "dermalaze" @@ -106,7 +93,7 @@ temp_range = list(T0C + 115, T0C + 130) -/datum/chemical_reaction/distilling/spacomycaze +/decl/chemical_reaction/distilling/spacomycaze name = "Distilling Spacomycaze" id = "distill_spacomycaze" result = "spacomycaze" @@ -117,7 +104,7 @@ temp_range = list(T0C + 100, T0C + 120) -/datum/chemical_reaction/distilling/tricorlidaze +/decl/chemical_reaction/distilling/tricorlidaze name = "Distilling Tricorlidaze" id = "distill_tricorlidaze" result = "tricorlidaze" @@ -128,7 +115,7 @@ temp_range = list(T0C + 100, T0C + 120) -/datum/chemical_reaction/distilling/synthplas +/decl/chemical_reaction/distilling/synthplas name = "Distilling Synthplas" id = "distill_synthplas" result = "synthblood_dilute" @@ -140,7 +127,7 @@ temp_range = list(T0C + 110, T0C + 130) // Alcohol -/datum/chemical_reaction/distilling/beer +/decl/chemical_reaction/distilling/beer name = "Distilling Beer" id = "distill_beer" result = "beer" @@ -151,7 +138,7 @@ temp_range = list(T20C, T20C + 2) -/datum/chemical_reaction/distilling/ale +/decl/chemical_reaction/distilling/ale name = "Distilling Ale" id = "distill_ale" result = "ale" @@ -165,7 +152,7 @@ temp_range = list(T0C + 7, T0C + 13) // Unique -/datum/chemical_reaction/distilling/berserkjuice +/decl/chemical_reaction/distilling/berserkjuice name = "Distilling Brute Juice" id = "distill_brutejuice" result = "berserkmed" @@ -175,7 +162,7 @@ temp_range = list(T0C + 600, T0C + 700) temp_shift = 4 -/datum/chemical_reaction/distilling/berserkjuice/on_reaction(var/datum/reagents/holder, var/created_volume) +/decl/chemical_reaction/distilling/berserkjuice/on_reaction(var/datum/reagents/holder, var/created_volume) ..() if(prob(1)) @@ -183,7 +170,7 @@ explosion(T, -1, rand(-1, 1), rand(1,2), rand(3,5)) return -/datum/chemical_reaction/distilling/cryogel +/decl/chemical_reaction/distilling/cryogel name = "Distilling Cryogellatin" id = "distill_cryoslurry" result = "cryoslurry" @@ -194,7 +181,7 @@ temp_range = list(0, 15) temp_shift = 20 -/datum/chemical_reaction/distilling/cryogel/on_reaction(var/datum/reagents/holder, var/created_volume) +/decl/chemical_reaction/distilling/cryogel/on_reaction(var/datum/reagents/holder, var/created_volume) ..() if(prob(1)) @@ -204,7 +191,7 @@ F.start() return -/datum/chemical_reaction/distilling/lichpowder +/decl/chemical_reaction/distilling/lichpowder name = "Distilling Lichpowder" id = "distill_lichpowder" result = "lichpowder" @@ -215,7 +202,7 @@ temp_range = list(T0C + 100, T0C + 150) -/datum/chemical_reaction/distilling/necroxadone +/decl/chemical_reaction/distilling/necroxadone name = "Distilling Necroxadone" id = "distill_necroxadone" result = "necroxadone" diff --git a/code/modules/reagents/reactions/fusion/fusion.dm b/code/modules/reagents/reactions/fusion/fusion.dm new file mode 100644 index 0000000000..7b0acfec96 --- /dev/null +++ b/code/modules/reagents/reactions/fusion/fusion.dm @@ -0,0 +1,6 @@ +// TDOD: Port R-UST fusion reactions to the chemistry system. +//They'll operate in a similar manner to distillery reactions, +// but will have distinct behaviours (mostly relating to the fusion field) that warrants a separate type +/* +/decl/chemical_reaction/fusion + name = "Fusion"*/ \ No newline at end of file diff --git a/code/modules/reagents/reactions/instant/drinks.dm b/code/modules/reagents/reactions/instant/drinks.dm new file mode 100644 index 0000000000..75de64b284 --- /dev/null +++ b/code/modules/reagents/reactions/instant/drinks.dm @@ -0,0 +1,1223 @@ +/decl/chemical_reaction/instant/drinks/coffee + name = "Coffee" + id = "coffee" + result = "coffee" + required_reagents = list("water" = 5, "coffeepowder" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/tea + name = "Black tea" + id = "tea" + result = "tea" + required_reagents = list("water" = 5, "teapowder" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/hot_coco + name = "Hot Coco" + id = "hot_coco" + result = "hot_coco" + required_reagents = list("water" = 5, "coco" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/grapejuice + name = "Grape Juice" + id = "grapejuice" + result = "grapejuice" + required_reagents = list("water" = 3, "instantgrape" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/orangejuice + name = "Orange Juice" + id = "orangejuice" + result = "orangejuice" + required_reagents = list("water" = 3, "instantorange" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/watermelonjuice + name = "Watermelon Juice" + id = "watermelonjuice" + result = "watermelonjuice" + required_reagents = list("water" = 3, "instantwatermelon" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/applejuice + name = "Apple Juice" + id = "applejuice" + result = "applejuice" + required_reagents = list("water" = 3, "instantapple" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/goldschlager + name = "Goldschlager" + id = "goldschlager" + result = "goldschlager" + required_reagents = list("vodka" = 10, "gold" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/patron + name = "Patron" + id = "patron" + result = "patron" + required_reagents = list("tequilla" = 10, "silver" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/bilk + name = "Bilk" + id = "bilk" + result = "bilk" + required_reagents = list("milk" = 1, "beer" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/icetea + name = "Iced Tea" + id = "icetea" + result = "icetea" + required_reagents = list("ice" = 1, "tea" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/icecoffee + name = "Iced Coffee" + id = "icecoffee" + result = "icecoffee" + required_reagents = list("ice" = 1, "coffee" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/nuka_cola + name = "Nuclear Cola" + id = "nuka_cola" + result = "nuka_cola" + required_reagents = list("uranium" = 1, "cola" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/moonshine + name = "Moonshine" + id = "moonshine" + result = "moonshine" + required_reagents = list("nutriment" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/grenadine + name = "Grenadine Syrup" + id = "grenadine" + result = "grenadine" + required_reagents = list("berryjuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/wine + name = "Wine" + id = "wine" + result = "wine" + required_reagents = list("grapejuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/pwine + name = "Poison Wine" + id = "pwine" + result = "pwine" + required_reagents = list("poisonberryjuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/melonliquor + name = "Melon Liquor" + id = "melonliquor" + result = "melonliquor" + required_reagents = list("watermelonjuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/bluecuracao + name = "Blue Curacao" + id = "bluecuracao" + result = "bluecuracao" + required_reagents = list("orangejuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/spacebeer + name = "Space Beer" + id = "spacebeer" + result = "beer" + required_reagents = list("cornoil" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/vodka + name = "Vodka" + id = "vodka" + result = "vodka" + required_reagents = list("potatojuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/cider + name = "Cider" + id = "cider" + result = "cider" + required_reagents = list("applejuice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + + +/decl/chemical_reaction/instant/drinks/sake + name = "Sake" + id = "sake" + result = "sake" + required_reagents = list("rice" = 10) + catalysts = list("enzyme" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/kahlua + name = "Kahlua" + id = "kahlua" + result = "kahlua" + required_reagents = list("coffee" = 5, "sugar" = 5) + catalysts = list("enzyme" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/gin_tonic + name = "Gin and Tonic" + id = "gintonic" + result = "gintonic" + required_reagents = list("gin" = 2, "tonic" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/cuba_libre + name = "Cuba Libre" + id = "cubalibre" + result = "cubalibre" + required_reagents = list("rum" = 2, "cola" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/martini + name = "Classic Martini" + id = "martini" + result = "martini" + required_reagents = list("gin" = 2, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/vodkamartini + name = "Vodka Martini" + id = "vodkamartini" + result = "vodkamartini" + required_reagents = list("vodka" = 2, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/white_russian + name = "White Russian" + id = "whiterussian" + result = "whiterussian" + required_reagents = list("blackrussian" = 2, "cream" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/whiskey_cola + name = "Whiskey Cola" + id = "whiskeycola" + result = "whiskeycola" + required_reagents = list("whiskey" = 2, "cola" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/screwdriver + name = "Screwdriver" + id = "screwdrivercocktail" + result = "screwdrivercocktail" + required_reagents = list("vodka" = 2, "orangejuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/bloody_mary + name = "Bloody Mary" + id = "bloodymary" + result = "bloodymary" + required_reagents = list("vodka" = 2, "tomatojuice" = 3, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/gargle_blaster + name = "Pan-Galactic Gargle Blaster" + id = "gargleblaster" + result = "gargleblaster" + required_reagents = list("vodka" = 2, "gin" = 1, "whiskey" = 1, "cognac" = 1, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/brave_bull + name = "Brave Bull" + id = "bravebull" + result = "bravebull" + required_reagents = list("tequilla" = 2, "kahlua" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/tequilla_sunrise + name = "Tequilla Sunrise" + id = "tequillasunrise" + result = "tequillasunrise" + required_reagents = list("tequilla" = 2, "orangejuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/phoron_special + name = "Toxins Special" + id = "phoronspecial" + result = "phoronspecial" + required_reagents = list("rum" = 2, "vermouth" = 2, "phoron" = 2) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/beepsky_smash + name = "Beepksy Smash" + id = "beepksysmash" + result = "beepskysmash" + required_reagents = list("limejuice" = 1, "whiskey" = 1, "iron" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/doctor_delight + name = "The Doctor's Delight" + id = "doctordelight" + result = "doctorsdelight" + required_reagents = list("limejuice" = 1, "tomatojuice" = 1, "orangejuice" = 1, "cream" = 2, "tricordrazine" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/irish_cream + name = "Irish Cream" + id = "irishcream" + result = "irishcream" + required_reagents = list("whiskey" = 2, "cream" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/manly_dorf + name = "The Manly Dorf" + id = "manlydorf" + result = "manlydorf" + required_reagents = list ("beer" = 1, "ale" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/hooch + name = "Hooch" + id = "hooch" + result = "hooch" + required_reagents = list ("sugar" = 1, "ethanol" = 2, "fuel" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/irish_coffee + name = "Irish Coffee" + id = "irishcoffee" + result = "irishcoffee" + required_reagents = list("irishcream" = 1, "coffee" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/b52 + name = "B-52" + id = "b52" + result = "b52" + required_reagents = list("irishcream" = 1, "kahlua" = 1, "cognac" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/atomicbomb + name = "Atomic Bomb" + id = "atomicbomb" + result = "atomicbomb" + required_reagents = list("b52" = 10, "uranium" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/margarita + name = "Margarita" + id = "margarita" + result = "margarita" + required_reagents = list("tequilla" = 2, "limejuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/longislandicedtea + name = "Long Island Iced Tea" + id = "longislandicedtea" + result = "longislandicedtea" + required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 3) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/icedtea + name = "Long Island Iced Tea" + id = "longislandicedtea" + result = "longislandicedtea" + required_reagents = list("vodka" = 1, "gin" = 1, "tequilla" = 1, "cubalibre" = 3) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/threemileisland + name = "Three Mile Island Iced Tea" + id = "threemileisland" + result = "threemileisland" + required_reagents = list("longislandicedtea" = 10, "uranium" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/whiskeysoda + name = "Whiskey Soda" + id = "whiskeysoda" + result = "whiskeysoda" + required_reagents = list("whiskey" = 2, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/black_russian + name = "Black Russian" + id = "blackrussian" + result = "blackrussian" + required_reagents = list("vodka" = 2, "kahlua" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/manhattan + name = "Manhattan" + id = "manhattan" + result = "manhattan" + required_reagents = list("whiskey" = 2, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/manhattan_proj + name = "Manhattan Project" + id = "manhattan_proj" + result = "manhattan_proj" + required_reagents = list("manhattan" = 10, "uranium" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/vodka_tonic + name = "Vodka and Tonic" + id = "vodkatonic" + result = "vodkatonic" + required_reagents = list("vodka" = 2, "tonic" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/gin_fizz + name = "Gin Fizz" + id = "ginfizz" + result = "ginfizz" + required_reagents = list("gin" = 1, "sodawater" = 1, "limejuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/bahama_mama + name = "Bahama mama" + id = "bahama_mama" + result = "bahama_mama" + required_reagents = list("rum" = 2, "orangejuice" = 2, "limejuice" = 1, "ice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/singulo + name = "Singulo" + id = "singulo" + result = "singulo" + required_reagents = list("vodka" = 5, "radium" = 1, "wine" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/alliescocktail + name = "Allies Cocktail" + id = "alliescocktail" + result = "alliescocktail" + required_reagents = list("martini" = 1, "vodka" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/demonsblood + name = "Demons Blood" + id = "demonsblood" + result = "demonsblood" + required_reagents = list("rum" = 3, "spacemountainwind" = 1, "blood" = 1, "dr_gibb" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/booger + name = "Booger" + id = "booger" + result = "booger" + required_reagents = list("cream" = 2, "banana" = 1, "rum" = 1, "watermelonjuice" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/antifreeze + name = "Anti-freeze" + id = "antifreeze" + result = "antifreeze" + required_reagents = list("vodka" = 1, "cream" = 1, "ice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/barefoot + name = "Barefoot" + id = "barefoot" + result = "barefoot" + required_reagents = list("berryjuice" = 1, "cream" = 1, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/grapesoda + name = "Grape Soda" + id = "grapesoda" + result = "grapesoda" + required_reagents = list("grapejuice" = 2, "cola" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/sbiten + name = "Sbiten" + id = "sbiten" + result = "sbiten" + required_reagents = list("vodka" = 10, "capsaicin" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/red_mead + name = "Red Mead" + id = "red_mead" + result = "red_mead" + required_reagents = list("blood" = 1, "mead" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/mead + name = "Mead" + id = "mead" + result = "mead" + required_reagents = list("sugar" = 1, "water" = 1) + catalysts = list("enzyme" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/iced_beer + name = "Iced Beer" + id = "iced_beer" + result = "iced_beer" + required_reagents = list("beer" = 10, "frostoil" = 1) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/iced_beer2 + name = "Iced Beer" + id = "iced_beer" + result = "iced_beer" + required_reagents = list("beer" = 5, "ice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/grog + name = "Grog" + id = "grog" + result = "grog" + required_reagents = list("rum" = 1, "water" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/soy_latte + name = "Soy Latte" + id = "soy_latte" + result = "soy_latte" + required_reagents = list("coffee" = 1, "soymilk" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/cafe_latte + name = "Cafe Latte" + id = "cafe_latte" + result = "cafe_latte" + required_reagents = list("coffee" = 1, "milk" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/acidspit + name = "Acid Spit" + id = "acidspit" + result = "acidspit" + required_reagents = list("sacid" = 1, "wine" = 5) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/amasec + name = "Amasec" + id = "amasec" + result = "amasec" + required_reagents = list("iron" = 1, "wine" = 5, "vodka" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/changelingsting + name = "Changeling Sting" + id = "changelingsting" + result = "changelingsting" + required_reagents = list("screwdrivercocktail" = 1, "limejuice" = 1, "lemonjuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/aloe + name = "Aloe" + id = "aloe" + result = "aloe" + required_reagents = list("cream" = 1, "whiskey" = 1, "watermelonjuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/andalusia + name = "Andalusia" + id = "andalusia" + result = "andalusia" + required_reagents = list("rum" = 1, "whiskey" = 1, "lemonjuice" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/snowwhite + name = "Snow White" + id = "snowwhite" + result = "snowwhite" + required_reagents = list("beer" = 1, "lemon_lime" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/irishcarbomb + name = "Irish Car Bomb" + id = "irishcarbomb" + result = "irishcarbomb" + required_reagents = list("ale" = 1, "irishcream" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/syndicatebomb + name = "Syndicate Bomb" + id = "syndicatebomb" + result = "syndicatebomb" + required_reagents = list("beer" = 1, "whiskeycola" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/erikasurprise + name = "Erika Surprise" + id = "erikasurprise" + result = "erikasurprise" + required_reagents = list("ale" = 2, "limejuice" = 1, "whiskey" = 1, "banana" = 1, "ice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/devilskiss + name = "Devils Kiss" + id = "devilskiss" + result = "devilskiss" + required_reagents = list("blood" = 1, "kahlua" = 1, "rum" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/hippiesdelight + name = "Hippies Delight" + id = "hippiesdelight" + result = "hippiesdelight" + required_reagents = list("psilocybin" = 1, "gargleblaster" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/bananahonk + name = "Banana Honk" + id = "bananahonk" + result = "bananahonk" + required_reagents = list("banana" = 1, "cream" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/silencer + name = "Silencer" + id = "silencer" + result = "silencer" + required_reagents = list("nothing" = 1, "cream" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/driestmartini + name = "Driest Martini" + id = "driestmartini" + result = "driestmartini" + required_reagents = list("nothing" = 1, "gin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/lemonade + name = "Lemonade" + id = "lemonade" + result = "lemonade" + required_reagents = list("lemonjuice" = 1, "sugar" = 1, "water" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/melonade + name = "Melonade" + id = "melonade" + result = "melonade" + required_reagents = list("watermelonjuice" = 1, "sugar" = 1, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/appleade + name = "Appleade" + id = "appleade" + result = "appleade" + required_reagents = list("applejuice" = 1, "sugar" = 1, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/pineappleade + name = "Pineappleade" + id = "pineappleade" + result = "pineappleade" + required_reagents = list("pineapplejuice" = 2, "limejuice" = 1, "sodawater" = 2, "honey" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/driverspunch + name = "Driver`s Punch" + id = "driverspunch" + result = "driverspunch" + required_reagents = list("appleade" = 2, "orangejuice" = 1, "mint" = 1, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/mintapplesparkle + name = "Mint Apple Sparkle" + id = "mintapplesparkle" + result = "mintapplesparkle" + required_reagents = list("appleade" = 2, "mint" = 1) + inhibitors = list("sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/berrycordial + name = "Berry Cordial" + id = "berrycordial" + result = "berrycordial" + required_reagents = list("berryjuice" = 4, "sugar" = 1, "lemonjuice" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/tropicalfizz + name = "Tropical Fizz" + id = "tropicalfizz" + result = "tropicalfizz" + required_reagents = list("sodawater" = 6, "berryjuice" = 1, "mint" = 1, "limejuice" = 1, "lemonjuice" = 1, "pineapplejuice" = 1) + inhibitors = list("sugar" = 1) + result_amount = 8 + +/decl/chemical_reaction/instant/drinks/melonspritzer + name = "Melon Spritzer" + id = "melonspritzer" + result = "melonspritzer" + required_reagents = list("watermelonjuice" = 2, "wine" = 2, "applejuice" = 1, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/fauxfizz + name = "Faux Fizz" + id = "fauxfizz" + result = "fauxfizz" + required_reagents = list("sodawater" = 2, "berryjuice" = 1, "applejuice" = 1, "limejuice" = 1, "honey" = 1) + inhibitors = list("sugar" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/firepunch + name = "Fire Punch" + id = "firepunch" + result = "firepunch" + required_reagents = list("sugar" = 1, "rum" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/kiraspecial + name = "Kira Special" + id = "kiraspecial" + result = "kiraspecial" + required_reagents = list("orangejuice" = 1, "limejuice" = 1, "sodawater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/brownstar + name = "Brown Star" + id = "brownstar" + result = "brownstar" + required_reagents = list("orangejuice" = 2, "cola" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/milkshake + name = "Milkshake" + id = "milkshake" + result = "milkshake" + required_reagents = list("cream" = 1, "ice" = 2, "milk" = 2) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/peanutmilkshake + name = "Peanutbutter Milkshake" + id = "peanutmilkshake" + result = "peanutmilkshake" + required_reagents = list("cream" = 1, "ice" = 1, "peanutbutter" = 2, "milk" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/rewriter + name = "Rewriter" + id = "rewriter" + result = "rewriter" + required_reagents = list("spacemountainwind" = 1, "coffee" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/suidream + name = "Sui Dream" + id = "suidream" + result = "suidream" + required_reagents = list("space_up" = 1, "bluecuracao" = 1, "melonliquor" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/shirleytemple + name = "Shirley Temple" + id = "shirley_temple" + result = "shirley_temple" + required_reagents = list("gingerale" = 4, "grenadine" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/royrogers + name = "Roy Rogers" + id = "roy_rogers" + result = "roy_rogers" + required_reagents = list("shirley_temple" = 5, "lemon_lime" = 2) + result_amount = 7 + +/decl/chemical_reaction/instant/drinks/collinsmix + name = "Collins Mix" + id = "collins_mix" + result = "collins_mix" + required_reagents = list("lemon_lime" = 3, "sodawater" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/arnoldpalmer + name = "Arnold Palmer" + id = "arnold_palmer" + result = "arnold_palmer" + required_reagents = list("icetea" = 1, "lemonade" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/minttea + name = "Mint Tea" + id = "minttea" + result = "minttea" + required_reagents = list("tea" = 5, "mint" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/lemontea + name = "Lemon Tea" + id = "lemontea" + result = "lemontea" + required_reagents = list("tea" = 5, "lemonjuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/limetea + name = "Lime Tea" + id = "limetea" + result = "limetea" + required_reagents = list("tea" = 5, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/orangetea + name = "Orange Tea" + id = "orangetea" + result = "orangetea" + required_reagents = list("tea" = 5, "orangejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/berrytea + name = "Berry Tea" + id = "berrytea" + result = "berrytea" + required_reagents = list("tea" = 5, "berryjuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/sakebomb + name = "Sake Bomb" + id = "sakebomb" + result = "sakebomb" + required_reagents = list("beer" = 2, "sake" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/tamagozake + name = "Tamagozake" + id = "tamagozake" + result = "tamagozake" + required_reagents = list("sake" = 10, "sugar" = 5, "egg" = 3) + result_amount = 15 + +/decl/chemical_reaction/instant/drinks/ginzamary + name = "Ginza Mary" + id = "ginzamary" + result = "ginzamary" + required_reagents = list("sake" = 2, "vodka" = 2, "tomatojuice" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/tokyorose + name = "Tokyo Rose" + id = "tokyorose" + result = "tokyorose" + required_reagents = list("sake" = 1, "berryjuice" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/saketini + name = "Saketini" + id = "saketini" + result = "saketini" + required_reagents = list("sake" = 1, "gin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/elysiumfacepunch + name = "Elysium Facepunch" + id = "elysiumfacepunch" + result = "elysiumfacepunch" + required_reagents = list("kahlua" = 1, "lemonjuice" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/erebusmoonrise + name = "Erebus Moonrise" + id = "erebusmoonrise" + result = "erebusmoonrise" + required_reagents = list("whiskey" = 1, "vodka" = 1, "tequilla" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/balloon + name = "Balloon" + id = "balloon" + result = "balloon" + required_reagents = list("cream" = 1, "bluecuracao" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/natunabrandy + name = "Natuna Brandy" + id = "natunabrandy" + result = "natunabrandy" + required_reagents = list("beer" = 1, "sodawater" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/euphoria + name = "Euphoria" + id = "euphoria" + result = "euphoria" + required_reagents = list("specialwhiskey" = 1, "cognac" = 2) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/xanaducannon + name = "Xanadu Cannon" + id = "xanaducannon" + result = "xanaducannon" + required_reagents = list("ale" = 1, "dr_gibb" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/debugger + name = "Debugger" + id = "debugger" + result = "debugger" + required_reagents = list("fuel" = 1, "sugar" = 2, "cornoil" = 2) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/spacersbrew + name = "Spacer's Brew" + id = "spacersbrew" + result = "spacersbrew" + required_reagents = list("brownstar" = 4, "ethanol" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/binmanbliss + name = "Binman Bliss" + id = "binmanbliss" + result = "binmanbliss" + required_reagents = list("sake" = 1, "tequilla" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/chrysanthemum + name = "Chrysanthemum" + id = "chrysanthemum" + result = "chrysanthemum" + required_reagents = list("sake" = 1, "melonliquor" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/deathbell + name = "Deathbell" + id = "deathbell" + result = "deathbell" + required_reagents = list("antifreeze" = 1, "gargleblaster" = 1, "syndicatebomb" =1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/bitters + name = "Bitters" + id = "bitters" + result = "bitters" + required_reagents = list("mint" = 5) + catalysts = list("enzyme" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/soemmerfire + name = "Soemmer Fire" + id = "soemmerfire" + result = "soemmerfire" + required_reagents = list("manhattan" = 2, "condensedcapsaicin" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/winebrandy + name = "Wine brandy" + id = "winebrandy" + result = "winebrandy" + required_reagents = list("wine" = 10) + catalysts = list("enzyme" = 10) //10u enzyme so it requires more than is usually added. Stops overlap with wine recipe + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/lovepotion + name = "Love Potion" + id = "lovepotion" + result = "lovepotion" + required_reagents = list("cream" = 1, "berryjuice" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/morningafter + name = "Morning After" + id = "morningafter" + result = "morningafter" + required_reagents = list("sbiten" = 1, "coffee" = 5) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/vesper + name = "Vesper" + id = "vesper" + result = "vesper" + required_reagents = list("gin" = 3, "vodka" = 1, "wine" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/rotgut + name = "Rotgut Fever Dream" + id = "rotgut" + result = "rotgut" + required_reagents = list("vodka" = 3, "rum" = 1, "whiskey" = 1, "cola" = 3) + result_amount = 8 + +/decl/chemical_reaction/instant/drinks/entdraught + name = "Ent's Draught" + id = "entdraught" + result = "entdraught" + required_reagents = list("tonic" = 1, "holywater" = 1, "honey" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/voxdelight + name = "Vox's Delight" + id = "voxdelight" + result = "voxdelight" + required_reagents = list("phoron" = 3, "fuel" = 1, "water" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/screamingviking + name = "Screaming Viking" + id = "screamingviking" + result = "screamingviking" + required_reagents = list("martini" = 2, "vodkatonic" = 2, "limejuice" = 1, "rum" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/vilelemon + name = "Vile Lemon" + id = "vilelemon" + result = "vilelemon" + required_reagents = list("lemonade" = 5, "spacemountainwind" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/dreamcream + name = "Dream Cream" + id = "dreamcream" + result = "dreamcream" + required_reagents = list("milk" = 2, "cream" = 1, "honey" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/robustin + name = "Robustin" + id = "robustin" + result = "robustin" + required_reagents = list("antifreeze" = 1, "phoron" = 1, "fuel" = 1, "vodka" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/virginsip + name = "Virgin Sip" + id = "virginsip" + result = "virginsip" + required_reagents = list("driestmartini" = 1, "water" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/chocoshake + name = "Chocolate Milkshake" + id = "chocoshake" + result = "chocoshake" + required_reagents = list("milkshake" = 1, "coco" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/berryshake + name = "Berry Milkshake" + id = "berryshake" + result = "berryshake" + required_reagents = list("milkshake" = 1, "berryjuice" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/coffeeshake + name = "Coffee Milkshake" + id = "coffeeshake" + result = "coffeeshake" + required_reagents = list("milkshake" = 1, "coffee" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/jellyshot + name = "Jelly Shot" + id = "jellyshot" + result = "jellyshot" + required_reagents = list("cherryjelly" = 4, "vodka" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/slimeshot + name = "Named Bullet" + id = "slimeshot" + result = "slimeshot" + required_reagents = list("slimejelly" = 4, "vodka" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/negroni + name = "Negroni" + id = "negroni" + result = "negroni" + required_reagents = list("gin" = 1, "bitters" = 1, "vermouth" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/cloverclub + name = "Clover Club" + id = "cloverclub" + result = "cloverclub" + required_reagents = list("berryjuice" = 1, "lemonjuice" = 1, "gin" = 3) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/oldfashioned + name = "Old Fashioned" + id = "oldfashioned" + result = "oldfashioned" + required_reagents = list("whiskey" = 3, "bitters" = 1, "sugar" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/whiskeysour + name = "Whiskey Sour" + id = "whiskeysour" + result = "whiskeysour" + required_reagents = list("whiskey" = 2, "lemonjuice" = 1, "sugar" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/daiquiri + name = "Daiquiri" + id = "daiquiri" + result = "daiquiri" + required_reagents = list("rum" = 3, "limejuice" = 2, "sugar" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/mintjulep + name = "Mint Julep" + id = "mintjulep" + result = "mintjulep" + required_reagents = list("whiskey" = 2, "water" = 1, "mint" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/drinks/paloma + name = "Paloma" + id = "paloma" + result = "paloma" + required_reagents = list("orangejuice" = 1, "sodawater" = 1, "tequilla" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/mojito + name = "Mojito" + id = "mojito" + result = "mojito" + required_reagents = list("rum" = 3, "limejuice" = 1, "mint" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/virginmojito + name = "Mojito" + id = "virginmojito" + result = "virginmojito" + required_reagents = list("sodawater" = 3, "limejuice" = 1, "mint" = 1, "sugar" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/piscosour + name = "Pisco Sour" + id = "piscosour" + result = "piscosour" + required_reagents = list("winebrandy" = 1, "lemonjuice" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/coldfront + name = "Cold Front" + id = "coldfront" + result = "coldfront" + required_reagents = list("icecoffee" = 1, "whiskey" = 1, "mint" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/godsake + name = "Gods Sake" + id = "godsake" + result = "godsake" + required_reagents = list("sake" = 2, "holywater" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/godka //Why you would put this in your body, I don't know. + name = "Godka" + id = "godka" + result = "godka" + required_reagents = list("vodka" = 1, "holywater" = 1, "ethanol" = 1, "carthatoline" = 1) + catalysts = list("enzyme" = 5, "holywater" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/drinks/holywine + name = "Angel Ichor" + id = "holywine" + result = "holywine" + required_reagents = list("grapejuice" = 5, "gold" = 5) + catalysts = list("holywater" = 5) + result_amount = 10 + +/decl/chemical_reaction/instant/drinks/holy_mary + name = "Holy Mary" + id = "holymary" + result = "holymary" + required_reagents = list("vodka" = 2, "holywine" = 3, "limejuice" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/angelskiss + name = "Angels Kiss" + id = "angelskiss" + result = "angelskiss" + required_reagents = list("holywine" = 1, "kahlua" = 1, "rum" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/angelswrath + name = "Angels Wrath" + id = "angelswrath" + result = "angelswrath" + required_reagents = list("rum" = 3, "spacemountainwind" = 1, "holywine" = 1, "dr_gibb" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/ichor_mead + name = "Ichor Mead" + id = "ichor_mead" + result = "ichor_mead" + required_reagents = list("holywine" = 1, "mead" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/oilslick + name = "Oil Slick" + id = "oilslick" + result = "oilslick" + required_reagents = list("cornoil" = 2, "honey" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/slimeslam + name = "Slick Slime Slammer" + id = "slimeslammer" + result = "slimeslammer" + required_reagents = list("cornoil" = 2, "peanutbutter" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/virginsexonthebeach + name = "Virgin Sex On The Beach" + id = "virginsexonthebeach" + result = "virginsexonthebeach" + required_reagents = list("orangejuice" = 3, "grenadine" = 2) + result_amount = 5 + +/decl/chemical_reaction/instant/drinks/sexonthebeach + name = "Sex On The Beach" + id = "sexonthebeach" + result = "sexonthebeach" + required_reagents = list("virginsexonthebeach" = 5, "vodka" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/eggnog + name = "Eggnog" + id = "eggnog" + result = "eggnog" + required_reagents = list("milk" = 5, "cream" = 5, "sugar" = 5, "egg" = 3) + result_amount = 15 + +/decl/chemical_reaction/instant/drinks/nuclearwaste_radium + name = "Nuclear Waste" + id = "nuclearwasterad" + result = "nuclearwaste" + required_reagents = list("oilslick" = 1, "radium" = 1, "limejuice" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/drinks/nuclearwaste_uranium + name = "Nuclear Waste" + id = "nuclearwasteuran" + result = "nuclearwaste" + required_reagents = list("oilslick" = 2, "uranium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/drinks/sodaoil + name = "Soda Oil" + id = "sodaoil" + result = "sodaoil" + required_reagents = list("cornoil" = 4, "sodawater" = 1, "carbon" = 1, "tricordrazine" = 1) + result_amount = 6 + +/decl/chemical_reaction/instant/drinks/fusionnaire + name = "Fusionnaire" + id = "fusionnaire" + result = "fusionnaire" + required_reagents = list("lemonjuice" = 3, "vodka" = 2, "schnapps_pep" = 1, "schnapps_lem" = 1, "rum" = 1, "ice" = 1) + result_amount = 9 diff --git a/code/modules/reagents/reactions/instant/food.dm b/code/modules/reagents/reactions/instant/food.dm new file mode 100644 index 0000000000..952af8014b --- /dev/null +++ b/code/modules/reagents/reactions/instant/food.dm @@ -0,0 +1,183 @@ +/decl/chemical_reaction/instant/food/hot_ramen + name = "Hot Ramen" + id = "hot_ramen" + result = "hot_ramen" + required_reagents = list("water" = 1, "dry_ramen" = 3) + result_amount = 3 + +/decl/chemical_reaction/instant/food/hell_ramen + name = "Hell Ramen" + id = "hell_ramen" + result = "hell_ramen" + required_reagents = list("capsaicin" = 1, "hot_ramen" = 6) + result_amount = 6 + +/decl/chemical_reaction/instant/food/tofu + name = "Tofu" + id = "tofu" + result = null + required_reagents = list("soymilk" = 10) + catalysts = list("enzyme" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/food/tofu/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/tofu(location) + return + +/decl/chemical_reaction/instant/food/chocolate_bar + name = "Chocolate Bar" + id = "chocolate_bar" + result = null + required_reagents = list("soymilk" = 2, "coco" = 2, "sugar" = 2) + result_amount = 1 + +/decl/chemical_reaction/instant/food/chocolate_bar/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) + return + +/decl/chemical_reaction/instant/food/chocolate_bar2 + name = "Chocolate Bar" + id = "chocolate_bar" + result = null + required_reagents = list("milk" = 2, "coco" = 2, "sugar" = 2) + result_amount = 1 + +/decl/chemical_reaction/instant/food/chocolate_bar2/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location) + return + +/decl/chemical_reaction/instant/food/soysauce + name = "Soy Sauce" + id = "soysauce" + result = "soysauce" + required_reagents = list("soymilk" = 4, "sacid" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/food/ketchup + name = "Ketchup" + id = "ketchup" + result = "ketchup" + required_reagents = list("tomatojuice" = 2, "water" = 1, "sugar" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/food/barbecue + name = "Barbeque Sauce" + id = "barbecue" + result = "barbecue" + required_reagents = list("tomatojuice" = 2, "applejuice" = 1, "sugar" = 1, "spacespice" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/food/peanutbutter + name = "Peanut Butter" + id = "peanutbutter" + result = "peanutbutter" + required_reagents = list("peanutoil" = 2, "sugar" = 1, "sodiumchloride" = 1) + catalysts = list("enzyme" = 5) + result_amount = 3 + +/decl/chemical_reaction/instant/food/mayonnaise + name = "mayonnaise" + id = "mayo" + result = "mayo" + required_reagents = list("egg" = 9, "cornoil" = 5, "lemonjuice" = 5, "sodiumchloride" = 1) + result_amount = 15 + +/decl/chemical_reaction/instant/food/cheesewheel + name = "Cheesewheel" + id = "cheesewheel" + result = null + required_reagents = list("milk" = 40) + catalysts = list("enzyme" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/food/cheesewheel/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel(location) + return + +/decl/chemical_reaction/instant/food/meatball + name = "Meatball" + id = "meatball" + result = null + required_reagents = list("protein" = 3, "flour" = 5) + result_amount = 3 + +/decl/chemical_reaction/instant/food/meatball/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/meatball(location) + return + +/decl/chemical_reaction/instant/food/dough + name = "Dough" + id = "dough" + result = null + required_reagents = list("egg" = 3, "flour" = 10) + inhibitors = list("water" = 1, "beer" = 1) //To prevent it messing with batter recipes + result_amount = 1 + +/decl/chemical_reaction/instant/food/dough/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/dough(location) + return + +/decl/chemical_reaction/instant/food/syntiflesh + name = "Syntiflesh" + id = "syntiflesh" + result = null + required_reagents = list("blood" = 5, "clonexadone" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/food/syntiflesh/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh(location) + return + +/* +==================== + Aurora Food +==================== +*/ + +/decl/chemical_reaction/instant/food/coating/batter + name = "Batter" + id = "batter" + result = "batter" + required_reagents = list("egg" = 3, "flour" = 10, "water" = 5, "sodiumchloride" = 2) + result_amount = 20 + +/decl/chemical_reaction/instant/food/coating/beerbatter + name = "Beer Batter" + id = "beerbatter" + result = "beerbatter" + required_reagents = list("egg" = 3, "flour" = 10, "beer" = 5, "sodiumchloride" = 2) + result_amount = 20 + +/decl/chemical_reaction/instant/food/browniemix + name = "Brownie Mix" + id = "browniemix" + result = "browniemix" + required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5) + result_amount = 15 + +/decl/chemical_reaction/instant/food/butter + name = "Butter" + id = "butter" + result = null + required_reagents = list("cream" = 20, "sodiumchloride" = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/food/butter/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + for(var/i = 1, i <= created_volume, i++) + new /obj/item/weapon/reagent_containers/food/snacks/spreads/butter(location) + return \ No newline at end of file diff --git a/code/modules/reagents/reactions/instant/instant.dm b/code/modules/reagents/reactions/instant/instant.dm new file mode 100644 index 0000000000..4a6c25898d --- /dev/null +++ b/code/modules/reagents/reactions/instant/instant.dm @@ -0,0 +1,1118 @@ +// These reactions happen instantaneously, when added to a container that has all other necessary reagents +// They are a subtype of chemical_reaction so that such containers can iterate over only these reactions, and not have to skip other reaction types + +/* Common reactions */ + +/decl/chemical_reaction/instant/inaprovaline + name = "Inaprovaline" + id = "inaprovaline" + result = "inaprovaline" + required_reagents = list("oxygen" = 1, "carbon" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/dylovene + name = "Dylovene" + id = "anti_toxin" + result = "anti_toxin" + required_reagents = list("silicon" = 1, "potassium" = 1, "nitrogen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/carthatoline + name = "Carthatoline" + id = "carthatoline" + result = "carthatoline" + required_reagents = list("anti_toxin" = 1, "carbon" = 2, "phoron" = 0.1) + catalysts = list("phoron" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/paracetamol + name = "Paracetamol" + id = "paracetamol" + result = "paracetamol" + required_reagents = list("inaprovaline" = 1, "nitrogen" = 1, "water" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/tramadol + name = "Tramadol" + id = "tramadol" + result = "tramadol" + required_reagents = list("paracetamol" = 1, "ethanol" = 1, "oxygen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/oxycodone + name = "Oxycodone" + id = "oxycodone" + result = "oxycodone" + required_reagents = list("ethanol" = 1, "tramadol" = 1) + catalysts = list("phoron" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/sterilizine + name = "Sterilizine" + id = "sterilizine" + result = "sterilizine" + required_reagents = list("ethanol" = 1, "anti_toxin" = 1, "chlorine" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/silicate + name = "Silicate" + id = "silicate" + result = "silicate" + required_reagents = list("aluminum" = 1, "silicon" = 1, "oxygen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/mutagen + name = "Unstable mutagen" + id = "mutagen" + result = "mutagen" + required_reagents = list("radium" = 1, "phosphorus" = 1, "chlorine" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/water + name = "Water" + id = "water" + result = "water" + required_reagents = list("oxygen" = 1, "hydrogen" = 2) + result_amount = 1 + +/decl/chemical_reaction/instant/thermite + name = "Thermite" + id = "thermite" + result = "thermite" + required_reagents = list("aluminum" = 1, "iron" = 1, "oxygen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/space_drugs + name = "Space Drugs" + id = "space_drugs" + result = "space_drugs" + required_reagents = list("mercury" = 1, "sugar" = 1, "lithium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/lube + name = "Space Lube" + id = "lube" + result = "lube" + required_reagents = list("water" = 1, "silicon" = 1, "oxygen" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/pacid + name = "Polytrinic acid" + id = "pacid" + result = "pacid" + required_reagents = list("sacid" = 1, "chlorine" = 1, "potassium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/synaptizine + name = "Synaptizine" + id = "synaptizine" + result = "synaptizine" + required_reagents = list("sugar" = 1, "lithium" = 1, "water" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/hyronalin + name = "Hyronalin" + id = "hyronalin" + result = "hyronalin" + required_reagents = list("radium" = 1, "anti_toxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/arithrazine + name = "Arithrazine" + id = "arithrazine" + result = "arithrazine" + required_reagents = list("hyronalin" = 1, "hydrogen" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/impedrezene + name = "Impedrezene" + id = "impedrezene" + result = "impedrezene" + required_reagents = list("mercury" = 1, "oxygen" = 1, "sugar" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/kelotane + name = "Kelotane" + id = "kelotane" + result = "kelotane" + required_reagents = list("silicon" = 1, "carbon" = 1) + result_amount = 2 + log_is_important = 1 + +/decl/chemical_reaction/instant/peridaxon + name = "Peridaxon" + id = "peridaxon" + result = "peridaxon" + required_reagents = list("bicaridine" = 2, "clonexadone" = 2) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/osteodaxon + name = "Osteodaxon" + id = "osteodaxon" + result = "osteodaxon" + required_reagents = list("bicaridine" = 2, "phoron" = 0.1, "carpotoxin" = 1) + catalysts = list("phoron" = 5) + inhibitors = list("clonexadone" = 1) // Messes with cryox + result_amount = 2 + +/decl/chemical_reaction/instant/respirodaxon + name = "Respirodaxon" + id = "respirodaxon" + result = "respirodaxon" + required_reagents = list("dexalinp" = 2, "biomass" = 2, "phoron" = 1) + catalysts = list("phoron" = 5) + inhibitors = list("dexalin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/gastirodaxon + name = "Gastirodaxon" + id = "gastirodaxon" + result = "gastirodaxon" + required_reagents = list("carthatoline" = 1, "biomass" = 2, "tungsten" = 2) + catalysts = list("phoron" = 5) + inhibitors = list("lithium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/hepanephrodaxon + name = "Hepanephrodaxon" + id = "hepanephrodaxon" + result = "hepanephrodaxon" + required_reagents = list("carthatoline" = 2, "biomass" = 2, "lithium" = 1) + catalysts = list("phoron" = 5) + inhibitors = list("tungsten" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/cordradaxon + name = "Cordradaxon" + id = "cordradaxon" + result = "cordradaxon" + required_reagents = list("potassium_chlorophoride" = 1, "biomass" = 2, "bicaridine" = 2) + catalysts = list("phoron" = 5) + inhibitors = list("clonexadone" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/virus_food + name = "Virus Food" + id = "virusfood" + result = "virusfood" + required_reagents = list("water" = 1, "milk" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/leporazine + name = "Leporazine" + id = "leporazine" + result = "leporazine" + required_reagents = list("silicon" = 1, "copper" = 1) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/cryptobiolin + name = "Cryptobiolin" + id = "cryptobiolin" + result = "cryptobiolin" + required_reagents = list("potassium" = 1, "oxygen" = 1, "sugar" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/tricordrazine + name = "Tricordrazine" + id = "tricordrazine" + result = "tricordrazine" + required_reagents = list("inaprovaline" = 1, "anti_toxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/alkysine + name = "Alkysine" + id = "alkysine" + result = "alkysine" + required_reagents = list("chlorine" = 1, "nitrogen" = 1, "anti_toxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/dexalin + name = "Dexalin" + id = "dexalin" + result = "dexalin" + required_reagents = list("oxygen" = 2, "phoron" = 0.1) + catalysts = list("phoron" = 1) + inhibitors = list("water" = 1) // Messes with cryox + result_amount = 1 + +/decl/chemical_reaction/instant/dermaline + name = "Dermaline" + id = "dermaline" + result = "dermaline" + required_reagents = list("oxygen" = 1, "phosphorus" = 1, "kelotane" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/dexalinp + name = "Dexalin Plus" + id = "dexalinp" + result = "dexalinp" + required_reagents = list("dexalin" = 1, "carbon" = 1, "iron" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/bicaridine + name = "Bicaridine" + id = "bicaridine" + result = "bicaridine" + required_reagents = list("inaprovaline" = 1, "carbon" = 1) + inhibitors = list("sugar" = 1) // Messes up with inaprovaline + result_amount = 2 + +/decl/chemical_reaction/instant/myelamine + name = "Myelamine" + id = "myelamine" + result = "myelamine" + required_reagents = list("bicaridine" = 1, "iron" = 2, "spidertoxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/hyperzine + name = "Hyperzine" + id = "hyperzine" + result = "hyperzine" + required_reagents = list("sugar" = 1, "phosphorus" = 1, "sulfur" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/stimm + name = "Stimm" + id = "stimm" + result = "stimm" + required_reagents = list("left4zed" = 1, "fuel" = 1) + catalysts = list("fuel" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/ryetalyn + name = "Ryetalyn" + id = "ryetalyn" + result = "ryetalyn" + required_reagents = list("arithrazine" = 1, "carbon" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/cryoxadone + name = "Cryoxadone" + id = "cryoxadone" + result = "cryoxadone" + required_reagents = list("dexalin" = 1, "water" = 1, "oxygen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/clonexadone + name = "Clonexadone" + id = "clonexadone" + result = "clonexadone" + required_reagents = list("cryoxadone" = 1, "sodium" = 1, "phoron" = 0.1) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/mortiferin + name = "Mortiferin" + id = "mortiferin" + result = "mortiferin" + required_reagents = list("cryptobiolin" = 1, "clonexadone" = 1, "corophizine" = 1) + result_amount = 2 + catalysts = list("phoron" = 5) + +/decl/chemical_reaction/instant/spaceacillin + name = "Spaceacillin" + id = "spaceacillin" + result = "spaceacillin" + required_reagents = list("cryptobiolin" = 1, "inaprovaline" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/corophizine + name = "Corophizine" + id = "corophizine" + result = "corophizine" + required_reagents = list("spaceacillin" = 1, "carbon" = 1, "phoron" = 0.1) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/immunosuprizine + name = "Immunosuprizine" + id = "immunosuprizine" + result = "immunosuprizine" + required_reagents = list("corophizine" = 1, "tungsten" = 1, "sacid" = 1) + catalysts = list("phoron" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/imidazoline + name = "imidazoline" + id = "imidazoline" + result = "imidazoline" + required_reagents = list("carbon" = 1, "hydrogen" = 1, "anti_toxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/ethylredoxrazine + name = "Ethylredoxrazine" + id = "ethylredoxrazine" + result = "ethylredoxrazine" + required_reagents = list("oxygen" = 1, "anti_toxin" = 1, "carbon" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/calciumcarbonate + name = "Calcium Carbonate" + id = "calciumcarbonate" + result = "calciumcarbonate" + required_reagents = list("oxygen" = 3, "calcium" = 1, "carbon" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/soporific + name = "Soporific" + id = "stoxin" + result = "stoxin" + required_reagents = list("chloralhydrate" = 1, "sugar" = 4) + inhibitors = list("phosphorus") // Messes with the smoke + result_amount = 5 + +/decl/chemical_reaction/instant/chloralhydrate + name = "Chloral Hydrate" + id = "chloralhydrate" + result = "chloralhydrate" + required_reagents = list("ethanol" = 1, "chlorine" = 3, "water" = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/potassium_chloride + name = "Potassium Chloride" + id = "potassium_chloride" + result = "potassium_chloride" + required_reagents = list("sodiumchloride" = 1, "potassium" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/potassium_chlorophoride + name = "Potassium Chlorophoride" + id = "potassium_chlorophoride" + result = "potassium_chlorophoride" + required_reagents = list("potassium_chloride" = 1, "phoron" = 1, "chloralhydrate" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/zombiepowder + name = "Zombie Powder" + id = "zombiepowder" + result = "zombiepowder" + required_reagents = list("carpotoxin" = 5, "stoxin" = 5, "copper" = 5) + result_amount = 2 + +/decl/chemical_reaction/instant/carpotoxin + name = "Carpotoxin" + id = "carpotoxin" + result = "carpotoxin" + required_reagents = list("spidertoxin" = 2, "biomass" = 1, "sifsap" = 2) + catalysts = list("sifsap" = 10) + inhibitors = list("radium" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/mindbreaker + name = "Mindbreaker Toxin" + id = "mindbreaker" + result = "mindbreaker" + required_reagents = list("silicon" = 1, "hydrogen" = 1, "anti_toxin" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/lipozine + name = "Lipozine" + id = "Lipozine" + result = "lipozine" + required_reagents = list("sodiumchloride" = 1, "ethanol" = 1, "radium" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/surfactant + name = "Foam surfactant" + id = "foam surfactant" + result = "fluorosurfactant" + required_reagents = list("fluorine" = 2, "carbon" = 2, "sacid" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/ammonia + name = "Ammonia" + id = "ammonia" + result = "ammonia" + required_reagents = list("hydrogen" = 3, "nitrogen" = 1) + inhibitors = list("phoron" = 1) // Messes with lexorin + result_amount = 3 + +/decl/chemical_reaction/instant/diethylamine + name = "Diethylamine" + id = "diethylamine" + result = "diethylamine" + required_reagents = list ("ammonia" = 1, "ethanol" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/left4zed + name = "Left4Zed" + id = "left4zed" + result = "left4zed" + required_reagents = list ("diethylamine" = 2, "mutagen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/robustharvest + name = "RobustHarvest" + id = "robustharvest" + result = "robustharvest" + required_reagents = list ("ammonia" = 1, "calcium" = 1, "neurotoxic_protein" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/space_cleaner + name = "Space cleaner" + id = "cleaner" + result = "cleaner" + required_reagents = list("ammonia" = 1, "water" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/plantbgone + name = "Plant-B-Gone" + id = "plantbgone" + result = "plantbgone" + required_reagents = list("toxin" = 1, "water" = 4) + result_amount = 5 + +/decl/chemical_reaction/instant/foaming_agent + name = "Foaming Agent" + id = "foaming_agent" + result = "foaming_agent" + required_reagents = list("lithium" = 1, "hydrogen" = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/glycerol + name = "Glycerol" + id = "glycerol" + result = "glycerol" + required_reagents = list("cornoil" = 3, "sacid" = 1) + result_amount = 1 + +/decl/chemical_reaction/instant/sodiumchloride + name = "Sodium Chloride" + id = "sodiumchloride" + result = "sodiumchloride" + required_reagents = list("sodium" = 1, "chlorine" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/condensedcapsaicin + name = "Condensed Capsaicin" + id = "condensedcapsaicin" + result = "condensedcapsaicin" + required_reagents = list("capsaicin" = 2) + catalysts = list("phoron" = 5) + result_amount = 1 + +/decl/chemical_reaction/instant/coolant + name = "Coolant" + id = "coolant" + result = "coolant" + required_reagents = list("tungsten" = 1, "oxygen" = 1, "water" = 1) + result_amount = 3 + log_is_important = 1 + +/decl/chemical_reaction/instant/rezadone + name = "Rezadone" + id = "rezadone" + result = "rezadone" + required_reagents = list("carpotoxin" = 1, "cryptobiolin" = 1, "copper" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/lexorin + name = "Lexorin" + id = "lexorin" + result = "lexorin" + required_reagents = list("phoron" = 1, "hydrogen" = 1, "nitrogen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/methylphenidate + name = "Methylphenidate" + id = "methylphenidate" + result = "methylphenidate" + required_reagents = list("mindbreaker" = 1, "hydrogen" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/citalopram + name = "Citalopram" + id = "citalopram" + result = "citalopram" + required_reagents = list("mindbreaker" = 1, "carbon" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/paroxetine + name = "Paroxetine" + id = "paroxetine" + result = "paroxetine" + required_reagents = list("mindbreaker" = 1, "oxygen" = 1, "inaprovaline" = 1) + result_amount = 3 + +/decl/chemical_reaction/instant/neurotoxin + name = "Neurotoxin" + id = "neurotoxin" + result = "neurotoxin" + required_reagents = list("gargleblaster" = 1, "stoxin" = 1) + result_amount = 2 + +/decl/chemical_reaction/instant/luminol + name = "Luminol" + id = "luminol" + result = "luminol" + required_reagents = list("hydrogen" = 2, "carbon" = 2, "ammonia" = 2) + result_amount = 6 + +/* Solidification */ + +/decl/chemical_reaction/instant/solidification + name = "Solid Iron" + id = "solidiron" + result = null + required_reagents = list("frostoil" = 5, "iron" = REAGENTS_PER_SHEET) + result_amount = 1 + var/sheet_to_give = /obj/item/stack/material/iron + +/decl/chemical_reaction/instant/solidification/on_reaction(var/datum/reagents/holder, var/created_volume) + new sheet_to_give(get_turf(holder.my_atom), created_volume) + return + + +/decl/chemical_reaction/instant/solidification/phoron + name = "Solid Phoron" + id = "solidphoron" + required_reagents = list("frostoil" = 5, "phoron" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/phoron + + +/decl/chemical_reaction/instant/solidification/silver + name = "Solid Silver" + id = "solidsilver" + required_reagents = list("frostoil" = 5, "silver" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/silver + + +/decl/chemical_reaction/instant/solidification/gold + name = "Solid Gold" + id = "solidgold" + required_reagents = list("frostoil" = 5, "gold" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/gold + + +/decl/chemical_reaction/instant/solidification/platinum + name = "Solid Platinum" + id = "solidplatinum" + required_reagents = list("frostoil" = 5, "platinum" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/platinum + + +/decl/chemical_reaction/instant/solidification/uranium + name = "Solid Uranium" + id = "soliduranium" + required_reagents = list("frostoil" = 5, "uranium" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/uranium + + +/decl/chemical_reaction/instant/solidification/hydrogen + name = "Solid Hydrogen" + id = "solidhydrogen" + required_reagents = list("frostoil" = 100, "hydrogen" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/mhydrogen + + +// These are from Xenobio. +/decl/chemical_reaction/instant/solidification/steel + name = "Solid Steel" + id = "solidsteel" + required_reagents = list("frostoil" = 5, "steel" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/steel + + +/decl/chemical_reaction/instant/solidification/plasteel + name = "Solid Plasteel" + id = "solidplasteel" + required_reagents = list("frostoil" = 10, "plasteel" = REAGENTS_PER_SHEET) + sheet_to_give = /obj/item/stack/material/plasteel + + +/decl/chemical_reaction/instant/plastication + name = "Plastic" + id = "solidplastic" + result = null + required_reagents = list("pacid" = 1, "plasticide" = 2) + result_amount = 1 + +/decl/chemical_reaction/instant/plastication/on_reaction(var/datum/reagents/holder, var/created_volume) + new /obj/item/stack/material/plastic(get_turf(holder.my_atom), created_volume) + return + +/* Grenade reactions */ + +/decl/chemical_reaction/instant/explosion_potassium + name = "Explosion" + id = "explosion_potassium" + result = null + required_reagents = list("water" = 1, "potassium" = 1) + result_amount = 2 + mix_message = null + +/decl/chemical_reaction/instant/explosion_potassium/on_reaction(var/datum/reagents/holder, var/created_volume) + var/datum/effect/effect/system/reagents_explosion/e = new() + e.set_up(round (created_volume/10, 1), holder.my_atom, 0, 0) + if(isliving(holder.my_atom)) + e.amount *= 0.5 + var/mob/living/L = holder.my_atom + if(L.stat != DEAD) + e.amount *= 0.5 + e.start() + holder.clear_reagents() + return + +/decl/chemical_reaction/instant/flash_powder + name = "Flash powder" + id = "flash_powder" + result = null + required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1 ) + result_amount = null + +/decl/chemical_reaction/instant/flash_powder/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(2, 1, location) + s.start() + for(var/mob/living/carbon/M in viewers(world.view, location)) + switch(get_dist(M, location)) + if(0 to 3) + if(hasvar(M, "glasses")) + if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) + continue + + M.flash_eyes() + M.Weaken(15) + + if(4 to 5) + if(hasvar(M, "glasses")) + if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses)) + continue + + M.flash_eyes() + M.Stun(5) + +/decl/chemical_reaction/instant/emp_pulse + name = "EMP Pulse" + id = "emp_pulse" + result = null + required_reagents = list("uranium" = 1, "iron" = 1) // Yes, laugh, it's the best recipe I could think of that makes a little bit of sense + result_amount = 2 + +/decl/chemical_reaction/instant/emp_pulse/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + // 100 created volume = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes. + // 200 created volume = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades. + empulse(location, round(created_volume / 24), round(created_volume / 20), round(created_volume / 18), round(created_volume / 14), 1) + holder.clear_reagents() + return + +/decl/chemical_reaction/instant/nitroglycerin + name = "Nitroglycerin" + id = "nitroglycerin" + result = "nitroglycerin" + required_reagents = list("glycerol" = 1, "pacid" = 1, "sacid" = 1) + result_amount = 2 + log_is_important = 1 + +/decl/chemical_reaction/instant/nitroglycerin/on_reaction(var/datum/reagents/holder, var/created_volume) + var/datum/effect/effect/system/reagents_explosion/e = new() + e.set_up(round (created_volume/2, 1), holder.my_atom, 0, 0) + if(isliving(holder.my_atom)) + e.amount *= 0.5 + var/mob/living/L = holder.my_atom + if(L.stat!=DEAD) + e.amount *= 0.5 + e.start() + + holder.clear_reagents() + return + +/decl/chemical_reaction/instant/napalm + name = "Napalm" + id = "napalm" + result = null + required_reagents = list("aluminum" = 1, "phoron" = 1, "sacid" = 1 ) + result_amount = 1 + +/decl/chemical_reaction/instant/napalm/on_reaction(var/datum/reagents/holder, var/created_volume) + var/turf/location = get_turf(holder.my_atom.loc) + for(var/turf/simulated/floor/target_tile in range(0,location)) + target_tile.assume_gas("volatile_fuel", created_volume, 400+T0C) + spawn (0) target_tile.hotspot_expose(700, 400) + holder.del_reagent("napalm") + return + +/decl/chemical_reaction/instant/chemsmoke + name = "Chemsmoke" + id = "chemsmoke" + result = null + required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1) + result_amount = 0.4 + +/decl/chemical_reaction/instant/chemsmoke/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem + S.attach(location) + S.set_up(holder, created_volume, 0, location) + playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3) + spawn(0) + S.start() + holder.clear_reagents() + return + +/decl/chemical_reaction/instant/foam + name = "Foam" + id = "foam" + result = null + required_reagents = list("fluorosurfactant" = 1, "water" = 1) + result_amount = 2 + mix_message = "The solution violently bubbles!" + +/decl/chemical_reaction/instant/foam/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + + for(var/mob/M in viewers(5, location)) + to_chat(M, "The solution spews out foam!") + + var/datum/effect/effect/system/foam_spread/s = new() + s.set_up(created_volume, location, holder, 0) + s.start() + holder.clear_reagents() + return + +/decl/chemical_reaction/instant/metalfoam + name = "Metal Foam" + id = "metalfoam" + result = null + required_reagents = list("aluminum" = 3, "foaming_agent" = 1, "pacid" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/metalfoam/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + + for(var/mob/M in viewers(5, location)) + to_chat(M, "The solution spews out a metalic foam!") + + var/datum/effect/effect/system/foam_spread/s = new() + s.set_up(created_volume, location, holder, 1) + s.start() + return + +/decl/chemical_reaction/instant/ironfoam + name = "Iron Foam" + id = "ironlfoam" + result = null + required_reagents = list("iron" = 3, "foaming_agent" = 1, "pacid" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/ironfoam/on_reaction(var/datum/reagents/holder, var/created_volume) + var/location = get_turf(holder.my_atom) + + for(var/mob/M in viewers(5, location)) + to_chat(M, "The solution spews out a metalic foam!") + + var/datum/effect/effect/system/foam_spread/s = new() + s.set_up(created_volume, location, holder, 2) + s.start() + return + +/* Paint */ + +/decl/chemical_reaction/instant/red_paint + name = "Red paint" + id = "red_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_red" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/red_paint/send_data() + return "#FE191A" + +/decl/chemical_reaction/instant/orange_paint + name = "Orange paint" + id = "orange_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_orange" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/orange_paint/send_data() + return "#FFBE4F" + +/decl/chemical_reaction/instant/yellow_paint + name = "Yellow paint" + id = "yellow_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_yellow" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/yellow_paint/send_data() + return "#FDFE7D" + +/decl/chemical_reaction/instant/green_paint + name = "Green paint" + id = "green_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_green" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/green_paint/send_data() + return "#18A31A" + +/decl/chemical_reaction/instant/blue_paint + name = "Blue paint" + id = "blue_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_blue" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/blue_paint/send_data() + return "#247CFF" + +/decl/chemical_reaction/instant/purple_paint + name = "Purple paint" + id = "purple_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_purple" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/purple_paint/send_data() + return "#CC0099" + +/decl/chemical_reaction/instant/grey_paint //mime + name = "Grey paint" + id = "grey_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_grey" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/grey_paint/send_data() + return "#808080" + +/decl/chemical_reaction/instant/brown_paint + name = "Brown paint" + id = "brown_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "marker_ink_brown" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/brown_paint/send_data() + return "#846F35" + +/decl/chemical_reaction/instant/blood_paint + name = "Blood paint" + id = "blood_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "blood" = 2) + result_amount = 5 + +/decl/chemical_reaction/instant/blood_paint/send_data(var/datum/reagents/T) + var/t = T.get_data("blood") + if(t && t["blood_colour"]) + return t["blood_colour"] + return "#FE191A" // Probably red + +/decl/chemical_reaction/instant/milk_paint + name = "Milk paint" + id = "milk_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "milk" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/milk_paint/send_data() + return "#F0F8FF" + +/decl/chemical_reaction/instant/orange_juice_paint + name = "Orange juice paint" + id = "orange_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "orangejuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/orange_juice_paint/send_data() + return "#E78108" + +/decl/chemical_reaction/instant/tomato_juice_paint + name = "Tomato juice paint" + id = "tomato_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "tomatojuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/tomato_juice_paint/send_data() + return "#731008" + +/decl/chemical_reaction/instant/lime_juice_paint + name = "Lime juice paint" + id = "lime_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "limejuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/lime_juice_paint/send_data() + return "#365E30" + +/decl/chemical_reaction/instant/carrot_juice_paint + name = "Carrot juice paint" + id = "carrot_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "carrotjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/carrot_juice_paint/send_data() + return "#973800" + +/decl/chemical_reaction/instant/berry_juice_paint + name = "Berry juice paint" + id = "berry_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "berryjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/berry_juice_paint/send_data() + return "#990066" + +/decl/chemical_reaction/instant/grape_juice_paint + name = "Grape juice paint" + id = "grape_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "grapejuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/grape_juice_paint/send_data() + return "#863333" + +/decl/chemical_reaction/instant/poisonberry_juice_paint + name = "Poison berry juice paint" + id = "poisonberry_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "poisonberryjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/poisonberry_juice_paint/send_data() + return "#863353" + +/decl/chemical_reaction/instant/watermelon_juice_paint + name = "Watermelon juice paint" + id = "watermelon_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "watermelonjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/watermelon_juice_paint/send_data() + return "#B83333" + +/decl/chemical_reaction/instant/lemon_juice_paint + name = "Lemon juice paint" + id = "lemon_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "lemonjuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/lemon_juice_paint/send_data() + return "#AFAF00" + +/decl/chemical_reaction/instant/banana_juice_paint + name = "Banana juice paint" + id = "banana_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "banana" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/banana_juice_paint/send_data() + return "#C3AF00" + +/decl/chemical_reaction/instant/potato_juice_paint + name = "Potato juice paint" + id = "potato_juice_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "potatojuice" = 5) + result_amount = 5 + +/decl/chemical_reaction/instant/potato_juice_paint/send_data() + return "#302000" + +/decl/chemical_reaction/instant/carbon_paint + name = "Carbon paint" + id = "carbon_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "carbon" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/carbon_paint/send_data() + return "#333333" + +/decl/chemical_reaction/instant/aluminum_paint + name = "Aluminum paint" + id = "aluminum_paint" + result = "paint" + required_reagents = list("plasticide" = 1, "water" = 3, "aluminum" = 1) + result_amount = 5 + +/decl/chemical_reaction/instant/aluminum_paint/send_data() + return "#F0F8FF" + +//R-UST Port +/decl/chemical_reaction/instant/hydrophoron + name = "Hydrophoron" + id = "hydrophoron" + result = "hydrophoron" + required_reagents = list("hydrogen" = 1, "phoron" = 1) + inhibitors = list("nitrogen" = 1) //So it doesn't mess with lexorin + result_amount = 2 + +/decl/chemical_reaction/instant/deuterium + name = "Deuterium" + id = "deuterium" + result = "deuterium" + required_reagents = list("hydrophoron" = 1, "water" = 2) + result_amount = 3 + +//Skrellian crap. +/decl/chemical_reaction/instant/talum_quem + name = "Talum-quem" + id = "talum_quem" + result = "talum_quem" + required_reagents = list("space_drugs" = 2, "sugar" = 1, "amatoxin" = 1) + result_amount = 4 + +/decl/chemical_reaction/instant/qerr_quem + name = "Qerr-quem" + id = "qerr_quem" + result = "qerr_quem" + required_reagents = list("nicotine" = 1, "carbon" = 1, "sugar" = 2) + result_amount = 4 + +/decl/chemical_reaction/instant/malish_qualem + name = "Malish-Qualem" + id = "malish-qualem" + result = "malish-qualem" + required_reagents = list("immunosuprizine" = 1, "qerr_quem" = 1, "inaprovaline" = 1) + catalysts = list("phoron" = 5) + result_amount = 2 + +// Biomass, for cloning and bioprinters +/decl/chemical_reaction/instant/biomass + name = "Biomass" + id = "biomass" + result = "biomass" + required_reagents = list("protein" = 1, "sugar" = 1, "phoron" = 1) + result_amount = 1 // Roughly 20u per phoron sheet + +// Neutralization. + +/decl/chemical_reaction/instant/neutralize_neurotoxic_protein + name = "Neutralize Toxic Proteins" + id = "neurotoxic_protein_neutral" + result = "protein" + required_reagents = list("anti_toxin" = 1, "neurotoxic_protein" = 2) + result_amount = 2 + +/decl/chemical_reaction/instant/neutralize_carpotoxin + name = "Neutralize Carpotoxin" + id = "carpotoxin_neutral" + result = "protein" + required_reagents = list("radium" = 1, "carpotoxin" = 1, "sifsap" = 1) + catalysts = list("sifsap" = 10) + result_amount = 2 + +/decl/chemical_reaction/instant/neutralize_spidertoxin + name = "Neutralize Spidertoxin" + id = "spidertoxin_neutral" + result = "protein" + required_reagents = list("radium" = 1, "spidertoxin" = 1, "sifsap" = 1) + catalysts = list("sifsap" = 10) + result_amount = 2 \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Readme.dm b/code/modules/reagents/readme.md similarity index 97% rename from code/modules/reagents/Chemistry-Readme.dm rename to code/modules/reagents/readme.md index 2b7e3a832a..f9dac66b08 100644 --- a/code/modules/reagents/Chemistry-Readme.dm +++ b/code/modules/reagents/readme.md @@ -1,305 +1,305 @@ -/* -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 - - Vars: - list/datum/reagent/reagent_list - List of reagent datums. - - total_volume - Total volume of all reagents. - - maximum_volume - Maximum volume. - - atom/my_atom - Reference to the object that contains this. - - Procs: - - get_free_space() - Returns the remaining free volume in the holder. - - get_master_reagent() - Returns the reference to the reagent with the largest volume - - get_master_reagent_name() - Ditto, but returns the name. - - get_master_reagent_id() - Ditto, but returns ID. - - update_total() - Updates total volume, called automatically. - - handle_reactions() - Checks reagents and triggers any reactions that happen. Usually called automatically. - - add_reagent(var/id, var/amount, var/data = null, var/safety = 0) - Adds [amount] units of [id] reagent. [data] will be passed to reagent's mix_data() or initialize_data(). If [safety] is 0, handle_reactions() will be called. Returns 1 if successful, 0 otherwise. - - remove_reagent(var/id, var/amount, var/safety = 0) - Ditto, but removes reagent. Returns 1 if successful, 0 otherwise. - - del_reagent(var/id) - Removes all of the reagent. - - has_reagent(var/id, var/amount = 0) - Checks if holder has at least [amount] of [id] reagent. Returns 1 if the reagent is found and volume is above [amount]. Returns 0 otherwise. - - clear_reagents() - Removes all reagents. - - get_reagent_amount(var/id) - Returns reagent volume. Returns 0 if reagent is not found. - - get_data(var/id) - Returns get_data() of the reagent. - - get_reagents() - Returns a string containing all reagent ids and volumes, e.g. "carbon(4),nittrogen(5)". - - remove_any(var/amount = 1) - Removes up to [amount] of reagents from [src]. Returns actual amount removed. - - trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). If [copy] is 1, copies reagents instead. - - touch(var/atom/target) - When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. - This does not handle transferring reagents to things. - For example, splashing someone with water will get them wet and extinguish them if they are on fire, - even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. - Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type. - Not recommended to use this directly, since trans_to() calls it before attempting to transfer. - - touch_mob(var/mob/target) - Calls each reagent's touch_mob(target). - - touch_turf(var/turf/target) - Calls each reagent's touch_turf(target). - - touch_obj(var/obj/target) - Calls each reagent's touch_obj(target). - - trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - The general proc for applying reagents to things externally (as opposed to directly injected into the contents). - It first calls touch, then the appropriate trans_to_*() or splash_mob(). - If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc. - - Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy). - - trans_id_to(var/atom/target, var/id, var/amount = 1) - Transfers [amount] of [id] to [target]. Returns amount transferred. - - splash_mob(var/mob/target, var/amount = 1, var/clothes = 1) - Checks mob's clothing if [clothes] is 1 and transfers [amount] reagents to mob's skin. - Don't call this directly. Call apply_to() instead. - - trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) - Transfers [amount] reagents to the mob's appropriate holder, depending on [type]. Ignores protection. - - trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - Turfs don't currently have any reagents. Puts [amount] reagents into a temporary holder, calls touch_turf(target) from it, and deletes it. - - trans_to_obj(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) - If target has reagents, transfers [amount] to it. Otherwise, same as trans_to_turf(). - - atom/proc/create_reagents(var/max_vol) - Creates a new reagent datum. - -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. - - Vars: - - name - Name that shows up in-game. - - id - ID that is used for internal tracking. MUST BE UNIQUE. - - description - Description that shows up in-game. - - datum/reagents/holder - Reference to holder. - - reagent_state - Could be GAS, LIQUID, or SOLID. Affects nothing. Reserved for future use. - - list/data - Use varies by reagent. Custom variable. For example, blood stores blood group and viruses. - - volume - Current volume. - - metabolism - How quickly reagent is processed in mob's bloodstream; by default aslo affects ingest and touch metabolism. - - ingest_met - How quickly reagent is processed when ingested; [metabolism] is used if zero. - - touch_met - Ditto when touching. - - dose - How much of the reagent has been processed, limited by [max_dose]. Used for reagents with varying effects (e.g. ethanol or rezadone) and overdosing. - - max_dose - Maximum amount of reagent that has ever been in a mob. Exists so dose won't grow infinitely when small amounts of reagent are added over time. - - overdose - If [dose] is bigger than [overdose], overdose() proc is called every tick. - - scannable - If set to 1, will show up on health analyzers by name. - - affects_dead - If set to 1, will affect dead players. Used by Adminordrazine. - - glass_icon_state - Used by drinks. icon_state of the glass when this reagent is the master reagent. - - glass_name - Ditto for glass name. - - glass_desc - Ditto for glass desciption. - - glass_center_of_mass - Used for glass placement on tables. - - color - "#RRGGBB" or "#RRGGBBAA" where A is alpha channel. - - color_weight - How much reagent affects color of holder. Used by paint. - - Procs: - - remove_self(var/amount) - Removes [amount] of itself. - - touch_mob(var/mob/M) - Called when reagent is in another holder and not splashing the mob. Can be used with noncarbons. - - touch_obj(var/obj/O) - How reagent reacts with objects. - - touch_turf(var/turf/T) - How reagent reacts with turfs. - - on_mob_life(var/mob/living/carbon/M, var/alien, var/location) - Makes necessary checks and calls one of affect procs. - - affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - How reagent affects mob when injected. [removed] is the amount of reagent that has been removed this tick. [alien] is the mob's reagent flag. - - affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - Ditto, ingested. Defaults to affect_blood with halved dose. - - affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - Ditto, touching. - - overdose(var/mob/living/carbon/M, var/alien) - Called when dose is above overdose. Defaults to M.adjustToxLoss(REM). - - initialize_data(var/newdata) - Called when reagent is created. Defaults to setting [data] to [newdata]. - - mix_data(var/newdata, var/newamount) - Called when [newamount] of reagent with [newdata] data is added to the current reagent. Used by paint. - - get_data() - Returns data. Can be overriden. - -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. - - Vars: - - name - Name of the reaction, currently unused. - - id - ID of the reaction, must be unique. - - result - ID of the resulting reagent. Can be null. - - list/required_reagents - Reagents that are required for the reaction and are used up during it. - - list/catalysts - Ditto, but not used up. - - list/inhibitors - Opposite, prevent the reaction from happening. - - result_amount - Amount of resulting reagent. - - mix_message - Message that is shown to mobs when reaction happens. - - Procs: - - can_happen(var/datum/reagents/holder) - Customizable. If it returns 0, reaction will not happen. Defaults to always returning 1. Used by slime core reactions. - - on_reaction(var/datum/reagents/holder, var/created_volume) - Called when reaction happens. Used by explosives. - - send_data(var/datum/reagents/T) - Sets resulting reagent's data. Used by blood paint. - -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: - - atom/proc/create_reagents(var/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. - - atom/proc/is_open_container() - Checks atom/var/flags & OPENCONTAINER. - If this returns 1 , you can use syringes, beakers etc - to manipulate the contents of this object. - If it's 0, you'll need to write your own custom reagent - transfer code since you will not be able to use the standard - tools to manipulate it. - +/* +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 + + Vars: + list/datum/reagent/reagent_list + List of reagent datums. + + total_volume + Total volume of all reagents. + + maximum_volume + Maximum volume. + + atom/my_atom + Reference to the object that contains this. + + Procs: + + get_free_space() + Returns the remaining free volume in the holder. + + get_master_reagent() + Returns the reference to the reagent with the largest volume + + get_master_reagent_name() + Ditto, but returns the name. + + get_master_reagent_id() + Ditto, but returns ID. + + update_total() + Updates total volume, called automatically. + + handle_reactions() + Checks reagents and triggers any reactions that happen. Usually called automatically. + + add_reagent(var/id, var/amount, var/data = null, var/safety = 0) + Adds [amount] units of [id] reagent. [data] will be passed to reagent's mix_data() or initialize_data(). If [safety] is 0, handle_reactions() will be called. Returns 1 if successful, 0 otherwise. + + remove_reagent(var/id, var/amount, var/safety = 0) + Ditto, but removes reagent. Returns 1 if successful, 0 otherwise. + + del_reagent(var/id) + Removes all of the reagent. + + has_reagent(var/id, var/amount = 0) + Checks if holder has at least [amount] of [id] reagent. Returns 1 if the reagent is found and volume is above [amount]. Returns 0 otherwise. + + clear_reagents() + Removes all reagents. + + get_reagent_amount(var/id) + Returns reagent volume. Returns 0 if reagent is not found. + + get_data(var/id) + Returns get_data() of the reagent. + + get_reagents() + Returns a string containing all reagent ids and volumes, e.g. "carbon(4),nittrogen(5)". + + remove_any(var/amount = 1) + Removes up to [amount] of reagents from [src]. Returns actual amount removed. + + trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]). If [copy] is 1, copies reagents instead. + + touch(var/atom/target) + When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent. + This does not handle transferring reagents to things. + For example, splashing someone with water will get them wet and extinguish them if they are on fire, + even if they are wearing an impermeable suit that prevents the reagents from contacting the skin. + Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type. + Not recommended to use this directly, since trans_to() calls it before attempting to transfer. + + touch_mob(var/mob/target) + Calls each reagent's touch_mob(target). + + touch_turf(var/turf/target) + Calls each reagent's touch_turf(target). + + touch_obj(var/obj/target) + Calls each reagent's touch_obj(target). + + trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + The general proc for applying reagents to things externally (as opposed to directly injected into the contents). + It first calls touch, then the appropriate trans_to_*() or splash_mob(). + If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc. + + Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy). + + trans_id_to(var/atom/target, var/id, var/amount = 1) + Transfers [amount] of [id] to [target]. Returns amount transferred. + + splash_mob(var/mob/target, var/amount = 1, var/clothes = 1) + Checks mob's clothing if [clothes] is 1 and transfers [amount] reagents to mob's skin. + Don't call this directly. Call apply_to() instead. + + trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) + Transfers [amount] reagents to the mob's appropriate holder, depending on [type]. Ignores protection. + + trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + Turfs don't currently have any reagents. Puts [amount] reagents into a temporary holder, calls touch_turf(target) from it, and deletes it. + + trans_to_obj(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) + If target has reagents, transfers [amount] to it. Otherwise, same as trans_to_turf(). + + atom/proc/create_reagents(var/max_vol) + Creates a new reagent datum. + +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. + + Vars: + + name + Name that shows up in-game. + + id + ID that is used for internal tracking. MUST BE UNIQUE. + + description + Description that shows up in-game. + + datum/reagents/holder + Reference to holder. + + reagent_state + Could be GAS, LIQUID, or SOLID. Affects nothing. Reserved for future use. + + list/data + Use varies by reagent. Custom variable. For example, blood stores blood group and viruses. + + volume + Current volume. + + metabolism + How quickly reagent is processed in mob's bloodstream; by default aslo affects ingest and touch metabolism. + + ingest_met + How quickly reagent is processed when ingested; [metabolism] is used if zero. + + touch_met + Ditto when touching. + + dose + How much of the reagent has been processed, limited by [max_dose]. Used for reagents with varying effects (e.g. ethanol or rezadone) and overdosing. + + max_dose + Maximum amount of reagent that has ever been in a mob. Exists so dose won't grow infinitely when small amounts of reagent are added over time. + + overdose + If [dose] is bigger than [overdose], overdose() proc is called every tick. + + scannable + If set to 1, will show up on health analyzers by name. + + affects_dead + If set to 1, will affect dead players. Used by Adminordrazine. + + glass_icon_state + Used by drinks. icon_state of the glass when this reagent is the master reagent. + + glass_name + Ditto for glass name. + + glass_desc + Ditto for glass desciption. + + glass_center_of_mass + Used for glass placement on tables. + + color + "#RRGGBB" or "#RRGGBBAA" where A is alpha channel. + + color_weight + How much reagent affects color of holder. Used by paint. + + Procs: + + remove_self(var/amount) + Removes [amount] of itself. + + touch_mob(var/mob/M) + Called when reagent is in another holder and not splashing the mob. Can be used with noncarbons. + + touch_obj(var/obj/O) + How reagent reacts with objects. + + touch_turf(var/turf/T) + How reagent reacts with turfs. + + on_mob_life(var/mob/living/carbon/M, var/alien, var/location) + Makes necessary checks and calls one of affect procs. + + affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + How reagent affects mob when injected. [removed] is the amount of reagent that has been removed this tick. [alien] is the mob's reagent flag. + + affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + Ditto, ingested. Defaults to affect_blood with halved dose. + + affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + Ditto, touching. + + overdose(var/mob/living/carbon/M, var/alien) + Called when dose is above overdose. Defaults to M.adjustToxLoss(REM). + + initialize_data(var/newdata) + Called when reagent is created. Defaults to setting [data] to [newdata]. + + mix_data(var/newdata, var/newamount) + Called when [newamount] of reagent with [newdata] data is added to the current reagent. Used by paint. + + get_data() + Returns data. Can be overriden. + +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. + + Vars: + + name + Name of the reaction, currently unused. + + id + ID of the reaction, must be unique. + + result + ID of the resulting reagent. Can be null. + + list/required_reagents + Reagents that are required for the reaction and are used up during it. + + list/catalysts + Ditto, but not used up. + + list/inhibitors + Opposite, prevent the reaction from happening. + + result_amount + Amount of resulting reagent. + + mix_message + Message that is shown to mobs when reaction happens. + + Procs: + + can_happen(var/datum/reagents/holder) + Customizable. If it returns 0, reaction will not happen. Defaults to always returning 1. Used by slime core reactions. + + on_reaction(var/datum/reagents/holder, var/created_volume) + Called when reaction happens. Used by explosives. + + send_data(var/datum/reagents/T) + Sets resulting reagent's data. Used by blood paint. + +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: + + atom/proc/create_reagents(var/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. + + atom/proc/is_open_container() + Checks atom/var/flags & OPENCONTAINER. + If this returns 1 , you can use syringes, beakers etc + to manipulate the contents of this object. + If it's 0, you'll need to write your own custom reagent + transfer code since you will not be able to use the standard + tools to manipulate it. + */ \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers/_reagent_containers.dm similarity index 97% rename from code/modules/reagents/reagent_containers.dm rename to code/modules/reagents/reagent_containers/_reagent_containers.dm index 7a6927f49d..64dd2622d2 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers/_reagent_containers.dm @@ -1,145 +1,145 @@ -/obj/item/weapon/reagent_containers - name = "Container" - desc = "..." - icon = 'icons/obj/chemical.dmi' - icon_state = null - w_class = ITEMSIZE_SMALL - var/amount_per_transfer_from_this = 5 - var/possible_transfer_amounts = list(5,10,15,25,30) - var/volume = 30 - -/obj/item/weapon/reagent_containers/verb/set_APTFT() //set amount_per_transfer_from_this - set name = "Set transfer amount" - set category = "Object" - set src in range(0) - var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts - if(N) - amount_per_transfer_from_this = N - -/obj/item/weapon/reagent_containers/Initialize() - . = ..() - if(!possible_transfer_amounts) - src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT - create_reagents(volume) - -/obj/item/weapon/reagent_containers/attack_self(mob/user as mob) - return - -/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user, flag) - return - -/obj/item/weapon/reagent_containers/proc/reagentlist() // For attack logs - if(reagents) - return reagents.get_reagents() - return "No reagent holder" - -/obj/item/weapon/reagent_containers/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) // This goes into afterattack - if(!istype(target)) - return 0 - - if(!target.reagents || !target.reagents.total_volume) - to_chat(user, "[target] is empty.") - return 1 - - if(reagents && !reagents.get_free_space()) - to_chat(user, "[src] is full.") - return 1 - - var/trans = target.reagents.trans_to_obj(src, target:amount_per_transfer_from_this) - to_chat(user, "You fill [src] with [trans] units of the contents of [target].") - return 1 - -/obj/item/weapon/reagent_containers/proc/standard_splash_mob(var/mob/user, var/mob/target) // This goes into afterattack - if(!istype(target)) - return - - if(!reagents || !reagents.total_volume) - to_chat(user, "[src] is empty.") - return 1 - - if(target.reagents && !target.reagents.get_free_space()) - to_chat(user, "[target] is full.") - return 1 - - var/contained = reagentlist() - add_attack_logs(user,target,"Splashed with [src.name] containing [contained]") - user.visible_message("[target] has been splashed with something by [user]!", "You splash the solution onto [target].") - reagents.splash(target, reagents.total_volume) - return 1 - -/obj/item/weapon/reagent_containers/proc/self_feed_message(var/mob/user) - to_chat(user, "You eat \the [src]") - -/obj/item/weapon/reagent_containers/proc/other_feed_message_start(var/mob/user, var/mob/target) - user.visible_message("[user] is trying to feed [target] \the [src]!") - -/obj/item/weapon/reagent_containers/proc/other_feed_message_finish(var/mob/user, var/mob/target) - user.visible_message("[user] has fed [target] \the [src]!") - -/obj/item/weapon/reagent_containers/proc/feed_sound(var/mob/user) - return - -/obj/item/weapon/reagent_containers/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack - if(!istype(target)) - return 0 - - if(!reagents || !reagents.total_volume) - to_chat(user, "\The [src] is empty.") - return 1 - - if(target == user) - if(istype(user, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = user - if(!H.check_has_mouth()) - to_chat(user, "Where do you intend to put \the [src]? You don't have a mouth!") - return - var/obj/item/blocked = H.check_mouth_coverage() - if(blocked) - to_chat(user, "\The [blocked] is in the way!") - return - - user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things - self_feed_message(user) - reagents.trans_to_mob(user, issmall(user) ? CEILING(amount_per_transfer_from_this/2, 1) : amount_per_transfer_from_this, CHEM_INGEST) - feed_sound(user) - return 1 - else - if(istype(target, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = target - if(!H.check_has_mouth()) - to_chat(user, "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!") - return - var/obj/item/blocked = H.check_mouth_coverage() - if(blocked) - to_chat(user, "\The [blocked] is in the way!") - return - - other_feed_message_start(user, target) - - user.setClickCooldown(user.get_attack_speed(src)) - if(!do_mob(user, target)) - return - - other_feed_message_finish(user, target) - - var/contained = reagentlist() - add_attack_logs(user,target,"Fed from [src.name] containing [contained]") - reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INGEST) - feed_sound(user) - return 1 - -/obj/item/weapon/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level - if(!target.is_open_container() || !target.reagents) - return 0 - - if(!reagents || !reagents.total_volume) - to_chat(user, "[src] is empty.") - return 1 - - if(!target.reagents.get_free_space()) - to_chat(user, "[target] is full.") - return 1 - - var/trans = reagents.trans_to(target, amount_per_transfer_from_this) - to_chat(user, "You transfer [trans] units of the solution to [target].") - return 1 +/obj/item/weapon/reagent_containers + name = "Container" + desc = "..." + icon = 'icons/obj/chemical.dmi' + icon_state = null + w_class = ITEMSIZE_SMALL + var/amount_per_transfer_from_this = 5 + var/possible_transfer_amounts = list(5,10,15,25,30) + var/volume = 30 + +/obj/item/weapon/reagent_containers/verb/set_APTFT() //set amount_per_transfer_from_this + set name = "Set transfer amount" + set category = "Object" + set src in range(0) + var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts + if(N) + amount_per_transfer_from_this = N + +/obj/item/weapon/reagent_containers/Initialize() + . = ..() + if(!possible_transfer_amounts) + src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT + create_reagents(volume) + +/obj/item/weapon/reagent_containers/attack_self(mob/user as mob) + return + +/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user, flag) + return + +/obj/item/weapon/reagent_containers/proc/reagentlist() // For attack logs + if(reagents) + return reagents.get_reagents() + return "No reagent holder" + +/obj/item/weapon/reagent_containers/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) // This goes into afterattack + if(!istype(target)) + return 0 + + if(!target.reagents || !target.reagents.total_volume) + to_chat(user, "[target] is empty.") + return 1 + + if(reagents && !reagents.get_free_space()) + to_chat(user, "[src] is full.") + return 1 + + var/trans = target.reagents.trans_to_obj(src, target:amount_per_transfer_from_this) + to_chat(user, "You fill [src] with [trans] units of the contents of [target].") + return 1 + +/obj/item/weapon/reagent_containers/proc/standard_splash_mob(var/mob/user, var/mob/target) // This goes into afterattack + if(!istype(target)) + return + + if(!reagents || !reagents.total_volume) + to_chat(user, "[src] is empty.") + return 1 + + if(target.reagents && !target.reagents.get_free_space()) + to_chat(user, "[target] is full.") + return 1 + + var/contained = reagentlist() + add_attack_logs(user,target,"Splashed with [src.name] containing [contained]") + user.visible_message("[target] has been splashed with something by [user]!", "You splash the solution onto [target].") + reagents.splash(target, reagents.total_volume) + return 1 + +/obj/item/weapon/reagent_containers/proc/self_feed_message(var/mob/user) + to_chat(user, "You eat \the [src]") + +/obj/item/weapon/reagent_containers/proc/other_feed_message_start(var/mob/user, var/mob/target) + user.visible_message("[user] is trying to feed [target] \the [src]!") + +/obj/item/weapon/reagent_containers/proc/other_feed_message_finish(var/mob/user, var/mob/target) + user.visible_message("[user] has fed [target] \the [src]!") + +/obj/item/weapon/reagent_containers/proc/feed_sound(var/mob/user) + return + +/obj/item/weapon/reagent_containers/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack + if(!istype(target)) + return 0 + + if(!reagents || !reagents.total_volume) + to_chat(user, "\The [src] is empty.") + return 1 + + if(target == user) + if(istype(user, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = user + if(!H.check_has_mouth()) + to_chat(user, "Where do you intend to put \the [src]? You don't have a mouth!") + return + var/obj/item/blocked = H.check_mouth_coverage() + if(blocked) + to_chat(user, "\The [blocked] is in the way!") + return + + user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things + self_feed_message(user) + reagents.trans_to_mob(user, issmall(user) ? CEILING(amount_per_transfer_from_this/2, 1) : amount_per_transfer_from_this, CHEM_INGEST) + feed_sound(user) + return 1 + else + if(istype(target, /mob/living/carbon/human)) + var/mob/living/carbon/human/H = target + if(!H.check_has_mouth()) + to_chat(user, "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!") + return + var/obj/item/blocked = H.check_mouth_coverage() + if(blocked) + to_chat(user, "\The [blocked] is in the way!") + return + + other_feed_message_start(user, target) + + user.setClickCooldown(user.get_attack_speed(src)) + if(!do_mob(user, target)) + return + + other_feed_message_finish(user, target) + + var/contained = reagentlist() + add_attack_logs(user,target,"Fed from [src.name] containing [contained]") + reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INGEST) + feed_sound(user) + return 1 + +/obj/item/weapon/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level + if(!target.is_open_container() || !target.reagents) + return 0 + + if(!reagents || !reagents.total_volume) + to_chat(user, "[src] is empty.") + return 1 + + if(!target.reagents.get_free_space()) + to_chat(user, "[target] is full.") + return 1 + + var/trans = reagents.trans_to(target, amount_per_transfer_from_this) + to_chat(user, "You transfer [trans] units of the solution to [target].") + return 1 diff --git a/code/modules/reagents/Chemistry-Reagents-Helpers.dm b/code/modules/reagents/reagents/_helpers.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents-Helpers.dm rename to code/modules/reagents/reagents/_helpers.dm diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/reagents/_reagents.dm similarity index 97% rename from code/modules/reagents/Chemistry-Reagents.dm rename to code/modules/reagents/reagents/_reagents.dm index 3d32c00663..00bb509b7f 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/reagents/_reagents.dm @@ -1,237 +1,237 @@ - - - -/datum/reagent - var/name = "Reagent" - var/id = "reagent" - var/description = "A non-descript chemical." - var/taste_description = "bitterness" - var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable - var/datum/reagents/holder = null - var/reagent_state = SOLID - var/list/data = null - var/volume = 0 - var/metabolism = REM // This would be 0.2 normally - var/list/filtered_organs = list() // Organs that will slow the processing of this chemical. - var/mrate_static = FALSE //If the reagent should always process at the same speed, regardless of species, make this TRUE - var/ingest_met = 0 - var/touch_met = 0 - var/dose = 0 - var/max_dose = 0 - var/overdose = 0 //Amount at which overdose starts - var/overdose_mod = 1 //Modifier to overdose damage - var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch? - var/scannable = 0 // Shows up on health analyzers. - - var/affects_dead = 0 // Does this chem process inside a corpse? - var/affects_robots = 0 // Does this chem process inside a Synth? - - var/allergen_type = GENERIC // What potential allergens does this contain? - var/allergen_factor = 1 // If the potential allergens are mixed and low-volume, they're a bit less dangerous. Needed for drinks because they're a single reagent compared to food which contains multiple seperate reagents. - - var/cup_icon_state = null - var/cup_name = null - var/cup_desc = null - var/cup_center_of_mass = null - - var/color = "#000000" - var/color_weight = 1 - - var/glass_icon = DRINK_ICON_DEFAULT - var/glass_name = "something" - var/glass_desc = "It's a glass of... what, exactly?" - var/list/glass_special = null // null equivalent to list() - -/datum/reagent/proc/remove_self(var/amount) // Shortcut - if(holder) - holder.remove_reagent(id, amount) - -// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing. -/datum/reagent/proc/touch_mob(var/mob/M, var/amount) - return - -/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc - return - -/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here - return - -/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob. - if(!istype(M)) - return - if(!affects_dead && M.stat == DEAD) - return - if(!affects_robots && M.isSynthetic()) - return - if(!istype(location)) - return - - var/datum/reagents/metabolism/active_metab = location - var/removed = metabolism - - var/ingest_rem_mult = 1 - var/ingest_abs_mult = 1 - - if(!mrate_static == TRUE) - // Modifiers - for(var/datum/modifier/mod in M.modifiers) - if(!isnull(mod.metabolism_percent)) - removed *= mod.metabolism_percent - ingest_rem_mult *= mod.metabolism_percent - // Species - removed *= M.species.metabolic_rate - ingest_rem_mult *= M.species.metabolic_rate - // Metabolism - removed *= active_metab.metabolism_speed - ingest_rem_mult *= active_metab.metabolism_speed - - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!H.isSynthetic()) - if(H.species.has_organ[O_HEART] && (active_metab.metabolism_class == CHEM_BLOOD)) - var/obj/item/organ/internal/heart/Pump = H.internal_organs_by_name[O_HEART] - if(!Pump) - removed *= 0.1 - else if(Pump.standard_pulse_level == PULSE_NONE) // No pulse normally means chemicals process a little bit slower than normal. - removed *= 0.8 - else // Otherwise, chemicals process as per percentage of your current pulse, or, if you have no pulse but are alive, by a miniscule amount. - removed *= max(0.1, H.pulse / Pump.standard_pulse_level) - - if(H.species.has_organ[O_STOMACH] && (active_metab.metabolism_class == CHEM_INGEST)) - var/obj/item/organ/internal/stomach/Chamber = H.internal_organs_by_name[O_STOMACH] - if(Chamber) - ingest_rem_mult *= max(0.1, 1 - (Chamber.damage / Chamber.max_damage)) - else - ingest_rem_mult = 0.1 - - if(H.species.has_organ[O_INTESTINE] && (active_metab.metabolism_class == CHEM_INGEST)) - var/obj/item/organ/internal/intestine/Tube = H.internal_organs_by_name[O_INTESTINE] - if(Tube) - ingest_abs_mult *= max(0.1, 1 - (Tube.damage / Tube.max_damage)) - else - ingest_abs_mult = 0.1 - - else - var/obj/item/organ/internal/heart/machine/Pump = H.internal_organs_by_name[O_PUMP] - var/obj/item/organ/internal/stomach/machine/Cycler = H.internal_organs_by_name[O_CYCLER] - - if(active_metab.metabolism_class == CHEM_BLOOD) - if(Pump) - removed *= 1.1 - Pump.damage / Pump.max_damage - else - removed *= 0.1 - - else if(active_metab.metabolism_class == CHEM_INGEST) // If the pump is damaged, we waste chems from the tank. - if(Pump) - ingest_abs_mult *= max(0.25, 1 - Pump.damage / Pump.max_damage) - - else - ingest_abs_mult *= 0.2 - - if(Cycler) // If we're damaged, we empty our tank slower. - ingest_rem_mult = max(0.1, 1 - (Cycler.damage / Cycler.max_damage)) - - else - ingest_rem_mult = 0.1 - - else if(active_metab.metabolism_class == CHEM_TOUCH) // Machines don't exactly absorb chemicals. - removed *= 0.5 - - if(filtered_organs && filtered_organs.len) - for(var/organ_tag in filtered_organs) - var/obj/item/organ/internal/O = H.internal_organs_by_name[organ_tag] - if(O && !O.is_broken() && prob(max(0, O.max_damage - O.damage))) - removed *= 0.8 - if(active_metab.metabolism_class == CHEM_INGEST) - ingest_rem_mult *= 0.8 - - if(ingest_met && (active_metab.metabolism_class == CHEM_INGEST)) - removed = ingest_met * ingest_rem_mult - if(touch_met && (active_metab.metabolism_class == CHEM_TOUCH)) - removed = touch_met - removed = min(removed, volume) - max_dose = max(volume, max_dose) - dose = min(dose + removed, max_dose) - if(removed >= (metabolism * 0.1) || removed >= 0.1) // If there's too little chemical, don't affect the mob, just remove it - switch(active_metab.metabolism_class) - if(CHEM_BLOOD) - affect_blood(M, alien, removed) - if(CHEM_INGEST) - affect_ingest(M, alien, removed * ingest_abs_mult) - if(CHEM_TOUCH) - affect_touch(M, alien, removed) - if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH && !can_overdose_touch)) - overdose(M, alien, removed) - if(M.species.allergens & allergen_type) //uhoh, we can't handle this! - var/damage_severity = M.species.allergen_damage_severity*allergen_factor - var/disable_severity = M.species.allergen_disable_severity*allergen_factor - if(M.species.allergen_reaction & AG_TOX_DMG) - M.adjustToxLoss(damage_severity) - if(M.species.allergen_reaction & AG_OXY_DMG) - M.adjustOxyLoss(damage_severity) - if(prob(2.5*disable_severity)) - M.emote(pick("cough","gasp","choke")) - if(M.species.allergen_reaction & AG_EMOTE) - if(prob(2.5*disable_severity)) //this has a higher base chance, but not *too* high - M.emote(pick("pale","shiver","twitch")) - if(M.species.allergen_reaction & AG_PAIN) - M.adjustHalLoss(disable_severity) - if(M.species.allergen_reaction & AG_WEAKEN) - M.Weaken(disable_severity) - if(M.species.allergen_reaction & AG_BLURRY) - M.eye_blurry = max(M.eye_blurry, disable_severity) - if(M.species.allergen_reaction & AG_SLEEPY) - M.drowsyness = max(M.drowsyness, disable_severity) - remove_self(removed) - return - -/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) - return - -/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - M.bloodstr.add_reagent(id, removed) - return - -/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) - return - -/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect. - if(alien == IS_DIONA) - return - if(ishuman(M)) - var/mob/living/carbon/human/H = M - overdose_mod *= H.species.chemOD_mod - // 6 damage per unit at minimum, scales with excessive reagents. Rounding should help keep damage consistent between ingest / inject, but isn't perfect. - // Hardcapped at 3.6 damage per tick, or 18 damage per unit at 0.2 metabolic rate so that you can't instakill people with overdoses by feeding them infinite periadaxon. - // Overall, max damage is slightly less effective than hydrophoron, and 1/5 as effective as cyanide. - M.adjustToxLoss(min(removed * overdose_mod * round(3 + 3 * volume / overdose), 3.6)) - -/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created. - if(!isnull(newdata)) - data = newdata - return - -/datum/reagent/proc/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that? - return - -/datum/reagent/proc/get_data() // Just in case you have a reagent that handles data differently. - if(data && istype(data, /list)) - return data.Copy() - else if(data) - return data - return null - -/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references - holder = null - . = ..() - -/* DEPRECATED - TODO: REMOVE EVERYWHERE */ - -/datum/reagent/proc/reaction_turf(var/turf/target) - touch_turf(target) - -/datum/reagent/proc/reaction_obj(var/obj/target) - touch_obj(target) - -/datum/reagent/proc/reaction_mob(var/mob/target) - touch_mob(target) + + + +/datum/reagent + var/name = "Reagent" + var/id = "reagent" + var/description = "A non-descript chemical." + var/taste_description = "bitterness" + var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable + var/datum/reagents/holder = null + var/reagent_state = SOLID + var/list/data = null + var/volume = 0 + var/metabolism = REM // This would be 0.2 normally + var/list/filtered_organs = list() // Organs that will slow the processing of this chemical. + var/mrate_static = FALSE //If the reagent should always process at the same speed, regardless of species, make this TRUE + var/ingest_met = 0 + var/touch_met = 0 + var/dose = 0 + var/max_dose = 0 + var/overdose = 0 //Amount at which overdose starts + var/overdose_mod = 1 //Modifier to overdose damage + var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch? + var/scannable = 0 // Shows up on health analyzers. + + var/affects_dead = 0 // Does this chem process inside a corpse? + var/affects_robots = 0 // Does this chem process inside a Synth? + + var/allergen_type = GENERIC // What potential allergens does this contain? + var/allergen_factor = 1 // If the potential allergens are mixed and low-volume, they're a bit less dangerous. Needed for drinks because they're a single reagent compared to food which contains multiple seperate reagents. + + var/cup_icon_state = null + var/cup_name = null + var/cup_desc = null + var/cup_center_of_mass = null + + var/color = "#000000" + var/color_weight = 1 + + var/glass_icon = DRINK_ICON_DEFAULT + var/glass_name = "something" + var/glass_desc = "It's a glass of... what, exactly?" + var/list/glass_special = null // null equivalent to list() + +/datum/reagent/proc/remove_self(var/amount) // Shortcut + if(holder) + holder.remove_reagent(id, amount) + +// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing. +/datum/reagent/proc/touch_mob(var/mob/M, var/amount) + return + +/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc + return + +/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here + return + +/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob. + if(!istype(M)) + return + if(!affects_dead && M.stat == DEAD) + return + if(!affects_robots && M.isSynthetic()) + return + if(!istype(location)) + return + + var/datum/reagents/metabolism/active_metab = location + var/removed = metabolism + + var/ingest_rem_mult = 1 + var/ingest_abs_mult = 1 + + if(!mrate_static == TRUE) + // Modifiers + for(var/datum/modifier/mod in M.modifiers) + if(!isnull(mod.metabolism_percent)) + removed *= mod.metabolism_percent + ingest_rem_mult *= mod.metabolism_percent + // Species + removed *= M.species.metabolic_rate + ingest_rem_mult *= M.species.metabolic_rate + // Metabolism + removed *= active_metab.metabolism_speed + ingest_rem_mult *= active_metab.metabolism_speed + + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!H.isSynthetic()) + if(H.species.has_organ[O_HEART] && (active_metab.metabolism_class == CHEM_BLOOD)) + var/obj/item/organ/internal/heart/Pump = H.internal_organs_by_name[O_HEART] + if(!Pump) + removed *= 0.1 + else if(Pump.standard_pulse_level == PULSE_NONE) // No pulse normally means chemicals process a little bit slower than normal. + removed *= 0.8 + else // Otherwise, chemicals process as per percentage of your current pulse, or, if you have no pulse but are alive, by a miniscule amount. + removed *= max(0.1, H.pulse / Pump.standard_pulse_level) + + if(H.species.has_organ[O_STOMACH] && (active_metab.metabolism_class == CHEM_INGEST)) + var/obj/item/organ/internal/stomach/Chamber = H.internal_organs_by_name[O_STOMACH] + if(Chamber) + ingest_rem_mult *= max(0.1, 1 - (Chamber.damage / Chamber.max_damage)) + else + ingest_rem_mult = 0.1 + + if(H.species.has_organ[O_INTESTINE] && (active_metab.metabolism_class == CHEM_INGEST)) + var/obj/item/organ/internal/intestine/Tube = H.internal_organs_by_name[O_INTESTINE] + if(Tube) + ingest_abs_mult *= max(0.1, 1 - (Tube.damage / Tube.max_damage)) + else + ingest_abs_mult = 0.1 + + else + var/obj/item/organ/internal/heart/machine/Pump = H.internal_organs_by_name[O_PUMP] + var/obj/item/organ/internal/stomach/machine/Cycler = H.internal_organs_by_name[O_CYCLER] + + if(active_metab.metabolism_class == CHEM_BLOOD) + if(Pump) + removed *= 1.1 - Pump.damage / Pump.max_damage + else + removed *= 0.1 + + else if(active_metab.metabolism_class == CHEM_INGEST) // If the pump is damaged, we waste chems from the tank. + if(Pump) + ingest_abs_mult *= max(0.25, 1 - Pump.damage / Pump.max_damage) + + else + ingest_abs_mult *= 0.2 + + if(Cycler) // If we're damaged, we empty our tank slower. + ingest_rem_mult = max(0.1, 1 - (Cycler.damage / Cycler.max_damage)) + + else + ingest_rem_mult = 0.1 + + else if(active_metab.metabolism_class == CHEM_TOUCH) // Machines don't exactly absorb chemicals. + removed *= 0.5 + + if(filtered_organs && filtered_organs.len) + for(var/organ_tag in filtered_organs) + var/obj/item/organ/internal/O = H.internal_organs_by_name[organ_tag] + if(O && !O.is_broken() && prob(max(0, O.max_damage - O.damage))) + removed *= 0.8 + if(active_metab.metabolism_class == CHEM_INGEST) + ingest_rem_mult *= 0.8 + + if(ingest_met && (active_metab.metabolism_class == CHEM_INGEST)) + removed = ingest_met * ingest_rem_mult + if(touch_met && (active_metab.metabolism_class == CHEM_TOUCH)) + removed = touch_met + removed = min(removed, volume) + max_dose = max(volume, max_dose) + dose = min(dose + removed, max_dose) + if(removed >= (metabolism * 0.1) || removed >= 0.1) // If there's too little chemical, don't affect the mob, just remove it + switch(active_metab.metabolism_class) + if(CHEM_BLOOD) + affect_blood(M, alien, removed) + if(CHEM_INGEST) + affect_ingest(M, alien, removed * ingest_abs_mult) + if(CHEM_TOUCH) + affect_touch(M, alien, removed) + if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH && !can_overdose_touch)) + overdose(M, alien, removed) + if(M.species.allergens & allergen_type) //uhoh, we can't handle this! + var/damage_severity = M.species.allergen_damage_severity*allergen_factor + var/disable_severity = M.species.allergen_disable_severity*allergen_factor + if(M.species.allergen_reaction & AG_TOX_DMG) + M.adjustToxLoss(damage_severity) + if(M.species.allergen_reaction & AG_OXY_DMG) + M.adjustOxyLoss(damage_severity) + if(prob(2.5*disable_severity)) + M.emote(pick("cough","gasp","choke")) + if(M.species.allergen_reaction & AG_EMOTE) + if(prob(2.5*disable_severity)) //this has a higher base chance, but not *too* high + M.emote(pick("pale","shiver","twitch")) + if(M.species.allergen_reaction & AG_PAIN) + M.adjustHalLoss(disable_severity) + if(M.species.allergen_reaction & AG_WEAKEN) + M.Weaken(disable_severity) + if(M.species.allergen_reaction & AG_BLURRY) + M.eye_blurry = max(M.eye_blurry, disable_severity) + if(M.species.allergen_reaction & AG_SLEEPY) + M.drowsyness = max(M.drowsyness, disable_severity) + remove_self(removed) + return + +/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + return + +/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + M.bloodstr.add_reagent(id, removed) + return + +/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) + return + +/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect. + if(alien == IS_DIONA) + return + if(ishuman(M)) + var/mob/living/carbon/human/H = M + overdose_mod *= H.species.chemOD_mod + // 6 damage per unit at minimum, scales with excessive reagents. Rounding should help keep damage consistent between ingest / inject, but isn't perfect. + // Hardcapped at 3.6 damage per tick, or 18 damage per unit at 0.2 metabolic rate so that you can't instakill people with overdoses by feeding them infinite periadaxon. + // Overall, max damage is slightly less effective than hydrophoron, and 1/5 as effective as cyanide. + M.adjustToxLoss(min(removed * overdose_mod * round(3 + 3 * volume / overdose), 3.6)) + +/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created. + if(!isnull(newdata)) + data = newdata + return + +/datum/reagent/proc/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that? + return + +/datum/reagent/proc/get_data() // Just in case you have a reagent that handles data differently. + if(data && istype(data, /list)) + return data.Copy() + else if(data) + return data + return null + +/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references + holder = null + . = ..() + +/* DEPRECATED - TODO: REMOVE EVERYWHERE */ + +/datum/reagent/proc/reaction_turf(var/turf/target) + touch_turf(target) + +/datum/reagent/proc/reaction_obj(var/obj/target) + touch_obj(target) + +/datum/reagent/proc/reaction_mob(var/mob/target) + touch_mob(target) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/reagents/core.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm rename to code/modules/reagents/reagents/core.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/reagents/dispenser.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm rename to code/modules/reagents/reagents/dispenser.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/reagents/food_drinks.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm rename to code/modules/reagents/reagents/food_drinks.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/reagents/medicine.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm rename to code/modules/reagents/reagents/medicine.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm b/code/modules/reagents/reagents/modifiers.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Modifiers.dm rename to code/modules/reagents/reagents/modifiers.dm diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm b/code/modules/reagents/reagents/other.dm similarity index 90% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm rename to code/modules/reagents/reagents/other.dm index 5c1c9cf427..9e83c720bc 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Other.dm +++ b/code/modules/reagents/reagents/other.dm @@ -238,14 +238,6 @@ reagent_state = SOLID color = "#D0D0D0" -/datum/reagent/uranium - name ="Uranium" - id = "uranium" - description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." - taste_description = "metal" - reagent_state = SOLID - color = "#B8B8C0" - /datum/reagent/platinum name = "Platinum" id = "platinum" @@ -254,6 +246,14 @@ reagent_state = SOLID color = "#777777" +/datum/reagent/uranium + name ="Uranium" + id = "uranium" + description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." + taste_description = "metal" + reagent_state = SOLID + color = "#B8B8C0" + /datum/reagent/uranium/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) affect_ingest(M, alien, removed) @@ -268,6 +268,55 @@ new /obj/effect/decal/cleanable/greenglow(T) return +/datum/reagent/hydrogen/deuterium + name = "Deuterium" + id = "deuterium" + description = "A isotope of hydrogen. It has one extra neutron, and shares all chemical characteristics with hydrogen." + +/datum/reagent/hydrogen/tritium + name = "Tritium" + id = "tritium" + description = "A radioactive isotope of hydrogen. It has two extra neutrons, and shares all other chemical characteristics with hydrogen." + +/datum/reagent/lithium/lithium6 + name = "Lithium-6" + id = "lithium6" + description = "An isotope of lithium. It has 3 neutrons, but shares all chemical characteristics with regular lithium." + +/datum/reagent/helium/helium3 + name = "Helium-3" + id = "helium3" + description = "An isotope of helium. It only has one neutron, but shares all chemical characteristics with regular helium." + taste_mult = 0 + reagent_state = GAS + color = "#808080" + +/datum/reagent/boron/boron11 + name = "Boron-11" + id = "boron11" + description = "An isotope of boron. It has 6 neutrons." + taste_description = "metallic" // Apparently noone on the internet knows what boron tastes like. Or at least they won't share + +/datum/reagent/supermatter + name = "Supermatter" + id = "supermatter" + description = "The immense power of a supermatter crystal, in liquid form. You're not entirely sure how that's possible, but it's probably best handled with care." + taste_description = "taffy" // 0. The supermatter is tasty, tasty taffy. + +// Same as if you boop it wrong. It touches you, you die +/datum/reagent/supermatter/affect_touch(mob/living/carbon/M, alien, removed) + . = ..() + M.ash() + +/datum/reagent/supermatter/affect_ingest(mob/living/carbon/M, alien, removed) + . = ..() + M.ash() + +/datum/reagent/supermatter/affect_blood(mob/living/carbon/M, alien, removed) + . = ..() + M.ash() + + /datum/reagent/adrenaline name = "Adrenaline" id = "adrenaline" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/reagents/toxins.dm similarity index 100% rename from code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm rename to code/modules/reagents/reagents/toxins.dm diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index d6b9c373d5..4b3a9c09ad 100755 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -72,14 +72,9 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/proc/CallReagentName(var/ID) var/return_name = ID - var/datum/reagent/temp_reagent - for(var/R in (typesof(/datum/reagent) - /datum/reagent)) - temp_reagent = null - temp_reagent = new R() - if(temp_reagent.id == ID) - return_name = temp_reagent.name - qdel(temp_reagent) - temp_reagent = null + for(var/datum/reagent/R in SSchemistry.chemical_reagents) + if(R.id == ID) + return_name = R.name break return return_name diff --git a/code/modules/xenobio/items/extracts.dm b/code/modules/xenobio/items/extracts.dm index 159bb0f151..f810b9f68b 100644 --- a/code/modules/xenobio/items/extracts.dm +++ b/code/modules/xenobio/items/extracts.dm @@ -39,17 +39,17 @@ else . += "This extract is inert." -/datum/chemical_reaction/slime +/decl/chemical_reaction/instant/slime var/required = null -/datum/chemical_reaction/slime/can_happen(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/can_happen(var/datum/reagents/holder) if(holder.my_atom && istype(holder.my_atom, required)) var/obj/item/slime_extract/T = holder.my_atom if(T.uses > 0) return ..() return FALSE -/datum/chemical_reaction/slime/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/on_reaction(var/datum/reagents/holder) var/obj/item/slime_extract/T = holder.my_atom T.uses-- if(T.uses <= 0) @@ -67,7 +67,7 @@ icon_state = "grey slime extract" description_info = "This extract will create a new grey baby slime if injected with phoron, or some new monkey cubes if injected with blood." -/datum/chemical_reaction/slime/grey_new_slime +/decl/chemical_reaction/instant/slime/grey_new_slime name = "Slime Spawn" id = "m_spawn" result = null @@ -75,12 +75,12 @@ result_amount = 1 required = /obj/item/slime_extract/grey -/datum/chemical_reaction/slime/grey_new_slime/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/grey_new_slime/on_reaction(var/datum/reagents/holder) holder.my_atom.visible_message("Infused with phoron, the core begins to quiver and grow, and soon a new baby slime emerges from it!") new /mob/living/simple_mob/slime/xenobio(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/grey_monkey +/decl/chemical_reaction/instant/slime/grey_monkey name = "Slime Monkey" id = "m_monkey" result = null @@ -88,12 +88,12 @@ result_amount = 1 required = /obj/item/slime_extract/grey -/datum/chemical_reaction/slime/grey_monkey/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/grey_monkey/on_reaction(var/datum/reagents/holder) for(var/i = 1 to 4) new /obj/item/weapon/reagent_containers/food/snacks/monkeycube(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/grey_slimejelly +/decl/chemical_reaction/instant/slime/grey_slimejelly name = "Slime Jelly" id = "m_jelly" result = "slimejelly" @@ -123,7 +123,7 @@ color = "#666666" strength = 20 -/datum/chemical_reaction/slime/metal_metamorphic +/decl/chemical_reaction/instant/slime/metal_metamorphic name = "Slime Metal" id = "m_metal" required_reagents = list("phoron" = 5) @@ -132,7 +132,7 @@ required = /obj/item/slime_extract/metal -/datum/chemical_reaction/metamorphic +/decl/chemical_reaction/instant/metamorphic result_amount = REAGENTS_PER_SHEET * 2 @@ -145,42 +145,42 @@ // This is kind of a waste since iron is in the chem dispenser but it would be inconsistent if this wasn't here. -/datum/chemical_reaction/metamorphic/iron +/decl/chemical_reaction/instant/metamorphic/iron name = "Morph into Iron" id = "morph_iron" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "iron" = REAGENTS_PER_SHEET) result = "iron" -/datum/chemical_reaction/metamorphic/silver +/decl/chemical_reaction/instant/metamorphic/silver name = "Morph into Silver" id = "morph_silver" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "silver" = REAGENTS_PER_SHEET) result = "silver" -/datum/chemical_reaction/metamorphic/gold +/decl/chemical_reaction/instant/metamorphic/gold name = "Morph into Gold" id = "morph_gold" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "gold" = REAGENTS_PER_SHEET) result = "gold" -/datum/chemical_reaction/metamorphic/platinum +/decl/chemical_reaction/instant/metamorphic/platinum name = "Morph into Platinum" id = "morph_platinum" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "platinum" = REAGENTS_PER_SHEET) result = "platinum" -/datum/chemical_reaction/metamorphic/uranium +/decl/chemical_reaction/instant/metamorphic/uranium name = "Morph into Uranium" id = "morph_uranium" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "uranium" = REAGENTS_PER_SHEET) result = "uranium" -/datum/chemical_reaction/metamorphic/phoron +/decl/chemical_reaction/instant/metamorphic/phoron name = "Morph into Phoron" id = "morph_phoron" required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "phoron" = REAGENTS_PER_SHEET) @@ -188,7 +188,7 @@ // Creates 'alloys' which can be finalized with frost oil. -/datum/chemical_reaction/slime/metal_binding +/decl/chemical_reaction/instant/slime/metal_binding name = "Slime Binding" id = "m_binding" required_reagents = list("water" = 5) @@ -215,7 +215,7 @@ prefill = list("binding" = 60) -/datum/chemical_reaction/binding +/decl/chemical_reaction/instant/binding name = "Bind into Steel" id = "bind_steel" result = "steel" @@ -231,7 +231,7 @@ color = "#888888" -/datum/chemical_reaction/binding/plasteel // Two parts 'steel', one part platnium matches the smelter alloy recipe. +/decl/chemical_reaction/instant/binding/plasteel // Two parts 'steel', one part platnium matches the smelter alloy recipe. name = "Bind into Plasteel" id = "bind_plasteel" required_reagents = list("binding" = REAGENTS_PER_SHEET, "steel" = REAGENTS_PER_SHEET * 2, "platinum" = REAGENTS_PER_SHEET) @@ -258,7 +258,7 @@ The extract can also create a slime stability agent when injected with blood, which reduces the odds of newly created slimes mutating into \ a different color when a slime reproduces." -/datum/chemical_reaction/slime/blue_frostoil +/decl/chemical_reaction/instant/slime/blue_frostoil name = "Slime Frost Oil" id = "m_frostoil" result = "frostoil" @@ -267,14 +267,14 @@ required = /obj/item/slime_extract/blue -/datum/chemical_reaction/slime/blue_stability +/decl/chemical_reaction/instant/slime/blue_stability name = "Slime Stability" id = "m_stability" required_reagents = list("blood" = 5) result_amount = 1 required = /obj/item/slime_extract/blue -/datum/chemical_reaction/slime/blue_stability/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/blue_stability/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/stabilizer(get_turf(holder.my_atom)) ..() @@ -291,14 +291,14 @@ can extract from a slime specimen." -/datum/chemical_reaction/slime/purple_steroid +/decl/chemical_reaction/instant/slime/purple_steroid name = "Slime Steroid" id = "m_steroid" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/purple -/datum/chemical_reaction/slime/purple_steroid/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/purple_steroid/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/steroid(get_turf(holder.my_atom)) ..() @@ -313,14 +313,14 @@ icon_state = "orange slime extract" description_info = "This extract creates a fire when injected with phoron, after a five second delay." -/datum/chemical_reaction/slime/orange_fire +/decl/chemical_reaction/instant/slime/orange_fire name = "Slime Fire" id = "m_fire" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/orange -/datum/chemical_reaction/slime/orange_fire/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/orange_fire/on_reaction(var/datum/reagents/holder) log_and_message_admins("Orange extract reaction (fire) has been activated in [get_area(holder.my_atom)]. Last fingerprints: [holder.my_atom.fingerprintslast]") holder.my_atom.visible_message("\The [src] begins to vibrate violently!") playsound(holder.my_atom, 'sound/effects/phasein.ogg', 75, 1) @@ -350,14 +350,14 @@ description_info = "This extract will create a special 10k capacity power cell that self recharges slowly over time, when injected with phoron. \ When injected with blood, it will create a glob of slime which glows brightly. If injected with water, it will emit a strong EMP, after a five second delay." -/datum/chemical_reaction/slime/yellow_emp +/decl/chemical_reaction/instant/slime/yellow_emp name = "Slime EMP" id = "m_emp" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/yellow -/datum/chemical_reaction/slime/yellow_emp/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/yellow_emp/on_reaction(var/datum/reagents/holder) log_and_message_admins("Yellow extract reaction (emp) has been activated in [get_area(holder.my_atom)]. Last fingerprints: [holder.my_atom.fingerprintslast]") holder.my_atom.visible_message("\The [src] begins to vibrate violently!") playsound(holder.my_atom, 'sound/effects/phasein.ogg', 75, 1) @@ -368,26 +368,26 @@ ..() -/datum/chemical_reaction/slime/yellow_battery +/decl/chemical_reaction/instant/slime/yellow_battery name = "Slime Cell" id = "m_cell" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/yellow -/datum/chemical_reaction/slime/yellow_battery/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/yellow_battery/on_reaction(var/datum/reagents/holder) new /obj/item/weapon/cell/slime(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/yellow_flashlight +/decl/chemical_reaction/instant/slime/yellow_flashlight name = "Slime Flashlight" id = "m_flashlight" required_reagents = list("blood" = 5) result_amount = 1 required = /obj/item/slime_extract/yellow -/datum/chemical_reaction/slime/yellow_flashlight/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/yellow_flashlight/on_reaction(var/datum/reagents/holder) new /obj/item/device/flashlight/slime(get_turf(holder.my_atom)) ..() @@ -401,7 +401,7 @@ description_info = "This extract will create 5u liquid gold when injected with phoron." -/datum/chemical_reaction/slime/gold_gold +/decl/chemical_reaction/instant/slime/gold_gold name = "Slime Gold" id = "m_gold" result = "gold" @@ -420,7 +420,7 @@ description_info = "This extract will create 5u liquid silver when injected with phoron." -/datum/chemical_reaction/slime/silver_silver +/decl/chemical_reaction/instant/slime/silver_silver name = "Slime Silver" id = "m_silver" result = "silver" @@ -440,7 +440,7 @@ description_info = "This extract will create 40u liquid phoron when injected with water." -/datum/chemical_reaction/slime/dark_purple_phoron +/decl/chemical_reaction/instant/slime/dark_purple_phoron name = "Slime Phoron" id = "m_phoron_harvest" result = "phoron" @@ -462,7 +462,7 @@ cold-resistant armor like winter coats can protect from this. Note that the user is not immune to the extract's effects." -/datum/chemical_reaction/slime/dark_blue_cold_snap +/decl/chemical_reaction/instant/slime/dark_blue_cold_snap name = "Slime Cold Snap" id = "m_cold_snap" required_reagents = list("phoron" = 5) @@ -470,7 +470,7 @@ required = /obj/item/slime_extract/dark_blue // This iterates over a ZAS zone's contents, so that things seperated in other zones aren't subjected to the temperature drop. -/datum/chemical_reaction/slime/dark_blue_cold_snap/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/dark_blue_cold_snap/on_reaction(var/datum/reagents/holder) var/turf/simulated/T = get_turf(holder.my_atom) if(!T) // Nullspace lacks zones. return @@ -544,14 +544,14 @@ out of control." -/datum/chemical_reaction/slime/red_enrage +/decl/chemical_reaction/instant/slime/red_enrage name = "Slime Enrage" id = "m_enrage" required_reagents = list("blood" = 5) result_amount = 1 required = /obj/item/slime_extract/red -/datum/chemical_reaction/slime/red_enrage/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/red_enrage/on_reaction(var/datum/reagents/holder) for(var/mob/living/simple_mob/slime/S in view(get_turf(holder.my_atom))) if(S.stat) continue @@ -580,14 +580,14 @@ -/datum/chemical_reaction/slime/red_mutation +/decl/chemical_reaction/instant/slime/red_mutation name = "Slime Mutation" id = "m_mutation" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/red -/datum/chemical_reaction/slime/red_mutation/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/red_mutation/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/mutator(get_turf(holder.my_atom)) ..() @@ -600,7 +600,7 @@ icon_state = "green slime extract" description_info = "This extract will create 5u of liquid uranium when injected with phoron." -/datum/chemical_reaction/slime/green_uranium +/decl/chemical_reaction/instant/slime/green_uranium name = "Slime Uranium" id = "m_uranium" result = "uranium" @@ -620,7 +620,7 @@ with phoron. When injected with water, it will create an organ-mending agent. The slime medications have a very low threshold for overdosage, however." -/datum/chemical_reaction/slime/pink_clotting +/decl/chemical_reaction/instant/slime/pink_clotting name = "Slime Clotting Med" id = "m_clotting" result = "slime_bleed_fixer" @@ -629,7 +629,7 @@ required = /obj/item/slime_extract/pink -/datum/chemical_reaction/slime/pink_bone_fix +/decl/chemical_reaction/instant/slime/pink_bone_fix name = "Slime Bone Med" id = "m_bone_fixer" result = "slime_bone_fixer" @@ -638,7 +638,7 @@ required = /obj/item/slime_extract/pink -/datum/chemical_reaction/slime/pink_organ_fix +/decl/chemical_reaction/instant/slime/pink_organ_fix name = "Slime Organ Med" id = "m_organ_fixer" result = "slime_organ_fixer" @@ -680,7 +680,7 @@ increase the power of the explosion instead of allowing for multiple explosions." -/datum/chemical_reaction/slime/oil_griff +/decl/chemical_reaction/instant/slime/oil_griff name = "Slime Explosion" id = "m_boom" required_reagents = list("blood" = 5) @@ -688,7 +688,7 @@ required = /obj/item/slime_extract/oil -/datum/chemical_reaction/slime/oil_griff/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/oil_griff/on_reaction(var/datum/reagents/holder) ..() var/obj/item/slime_extract/E = holder.my_atom var/power = 1 @@ -718,26 +718,26 @@ short ranged, random teleporting. When injected with phoron, it creates one 'greater' slime crystal, which allows for a one time precise teleport to \ a specific area." -/datum/chemical_reaction/slime/bluespace_lesser +/decl/chemical_reaction/instant/slime/bluespace_lesser name = "Slime Lesser Tele" id = "m_tele_lesser" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/bluespace -/datum/chemical_reaction/slime/bluespace_lesser/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/bluespace_lesser/on_reaction(var/datum/reagents/holder) for(var/i = 1 to 5) new /obj/item/slime_crystal(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/bluespace_greater +/decl/chemical_reaction/instant/slime/bluespace_greater name = "Slime Greater Tele" id = "m_tele_lesser" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/bluespace -/datum/chemical_reaction/slime/bluespace_greater/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/bluespace_greater/on_reaction(var/datum/reagents/holder) new /obj/item/weapon/disposable_teleporter/slime(get_turf(holder.my_atom)) ..() @@ -752,14 +752,14 @@ 'charges' before it goes inert." -/datum/chemical_reaction/slime/cerulean_enhancer +/decl/chemical_reaction/instant/slime/cerulean_enhancer name = "Slime Enhancer" id = "m_enhancer" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/cerulean -/datum/chemical_reaction/slime/cerulean_enhancer/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/cerulean_enhancer/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/enhancer(get_turf(holder.my_atom)) ..() @@ -774,26 +774,26 @@ injected with water, it will create a very delicious and filling product." -/datum/chemical_reaction/slime/amber_slimefood +/decl/chemical_reaction/instant/slime/amber_slimefood name = "Slime Feeding" id = "m_slime_food" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/amber -/datum/chemical_reaction/slime/amber_slimefood/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/amber_slimefood/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/feeding(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/amber_peoplefood +/decl/chemical_reaction/instant/slime/amber_peoplefood name = "Slime Food" id = "m_people_food" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/amber -/datum/chemical_reaction/slime/amber_peoplefood/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/amber_peoplefood/on_reaction(var/datum/reagents/holder) new /obj/item/weapon/reagent_containers/food/snacks/slime(get_turf(holder.my_atom)) ..() @@ -809,14 +809,14 @@ description_info = "This extract will create one 'slime cube' when injected with phoron. The slime cube is needed to create a Promethean." -/datum/chemical_reaction/slime/sapphire_promethean +/decl/chemical_reaction/instant/slime/sapphire_promethean name = "Slime Promethean" id = "m_promethean" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/sapphire -/datum/chemical_reaction/slime/sapphire_promethean/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/sapphire_promethean/on_reaction(var/datum/reagents/holder) new /obj/item/slime_cube(get_turf(holder.my_atom)) ..() @@ -830,14 +830,14 @@ description_info = "This extract will cause all entities close to the extract to become stronger for ten minutes, when injected with phoron. \ When injected with blood, makes a slime loyalty agent which will make the slime fight other dangerous entities but not station crew." -/datum/chemical_reaction/slime/ruby_swole +/decl/chemical_reaction/instant/slime/ruby_swole name = "Slime Strength" id = "m_strength" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/ruby -/datum/chemical_reaction/slime/ruby_swole/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/ruby_swole/on_reaction(var/datum/reagents/holder) for(var/mob/living/L in range(1, holder.my_atom)) L.add_modifier(/datum/modifier/slime_strength, 10 MINUTES, src) ..() @@ -858,14 +858,14 @@ incoming_damage_percent = 0.75 -/datum/chemical_reaction/slime/ruby_loyalty +/decl/chemical_reaction/instant/slime/ruby_loyalty name = "Slime Loyalty" id = "m_strength" required_reagents = list("blood" = 5) result_amount = 1 required = /obj/item/slime_extract/ruby -/datum/chemical_reaction/slime/ruby_loyalty/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/ruby_loyalty/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/loyalty(get_turf(holder.my_atom)) ..() @@ -879,14 +879,14 @@ icon_state = "emerald slime extract" description_info = "This extract will cause all entities close to the extract to become more agile for ten minutes, when injected with phoron." -/datum/chemical_reaction/slime/emerald_fast +/decl/chemical_reaction/instant/slime/emerald_fast name = "Slime Agility" id = "m_agility" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/emerald -/datum/chemical_reaction/slime/emerald_fast/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/emerald_fast/on_reaction(var/datum/reagents/holder) for(var/mob/living/L in range(1, holder.my_atom)) L.add_modifier(/datum/modifier/slime_agility, 10 MINUTES, src) ..() @@ -916,26 +916,26 @@ When injected with phoron, it instead creates a slime friendship agent, which makes the slime consider the user their ally. The agent \ might be useful on other specimens as well." -/datum/chemical_reaction/slime/light_pink_docility +/decl/chemical_reaction/instant/slime/light_pink_docility name = "Slime Docility" id = "m_docile" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/light_pink -/datum/chemical_reaction/slime/light_pink_docility/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/light_pink_docility/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/docility(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/light_pink_friendship +/decl/chemical_reaction/instant/slime/light_pink_friendship name = "Slime Friendship" id = "m_friendship" required_reagents = list("phoron" = 5) result_amount = 1 required = /obj/item/slime_extract/light_pink -/datum/chemical_reaction/slime/light_pink_friendship/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/light_pink_friendship/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/friendship(get_turf(holder.my_atom)) ..() @@ -952,7 +952,7 @@ which makes slimes stop attacking other slime colors." -/datum/chemical_reaction/slime/rainbow_random_slime +/decl/chemical_reaction/instant/slime/rainbow_random_slime name = "Slime Random Slime" id = "m_rng_slime" required_reagents = list("phoron" = 5) @@ -960,7 +960,7 @@ required = /obj/item/slime_extract/rainbow -/datum/chemical_reaction/slime/rainbow_random_slime/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/rainbow_random_slime/on_reaction(var/datum/reagents/holder) var/mob/living/simple_mob/slime/xenobio/S var/list/slime_types = typesof(/mob/living/simple_mob/slime/xenobio) @@ -976,14 +976,14 @@ new S(get_turf(holder.my_atom)) ..() -/datum/chemical_reaction/slime/rainbow_unity +/decl/chemical_reaction/instant/slime/rainbow_unity name = "Slime Unity" id = "m_unity" required_reagents = list("water" = 5) result_amount = 1 required = /obj/item/slime_extract/rainbow -/datum/chemical_reaction/slime/rainbow_unity/on_reaction(var/datum/reagents/holder) +/decl/chemical_reaction/instant/slime/rainbow_unity/on_reaction(var/datum/reagents/holder) new /obj/item/slimepotion/unity(get_turf(holder.my_atom)) ..() diff --git a/polaris.dme b/polaris.dme index 5a15acac7a..f02eb408fd 100644 --- a/polaris.dme +++ b/polaris.dme @@ -214,6 +214,7 @@ #include "code\controllers\subsystems\atoms.dm" #include "code\controllers\subsystems\character_setup.dm" #include "code\controllers\subsystems\chat.dm" +#include "code\controllers\subsystems\chemistry.dm" #include "code\controllers\subsystems\circuits.dm" #include "code\controllers\subsystems\dcs.dm" #include "code\controllers\subsystems\events.dm" @@ -246,7 +247,6 @@ #include "code\controllers\subsystems\timer.dm" #include "code\controllers\subsystems\vote.dm" #include "code\controllers\subsystems\xenoarch.dm" -#include "code\controllers\subsystems\processing\chemistry.dm" #include "code\controllers\subsystems\processing\fastprocess.dm" #include "code\controllers\subsystems\processing\obj.dm" #include "code\controllers\subsystems\processing\processing.dm" @@ -2710,7 +2710,6 @@ #include "code\modules\power\fusion\fusion_circuits.dm" #include "code\modules\power\fusion\fusion_particle_catcher.dm" #include "code\modules\power\fusion\fusion_reactions.dm" -#include "code\modules\power\fusion\fusion_reagents.dm" #include "code\modules\power\fusion\magpower.dm" #include "code\modules\power\fusion\core\_core.dm" #include "code\modules\power\fusion\core\core_control.dm" @@ -2832,36 +2831,33 @@ #include "code\modules\random_map\noise\ore.dm" #include "code\modules\random_map\noise\tundra.dm" #include "code\modules\reagents\Chemistry-Colours.dm" -#include "code\modules\reagents\Chemistry-Holder.dm" #include "code\modules\reagents\Chemistry-Logging.dm" -#include "code\modules\reagents\Chemistry-Machinery.dm" #include "code\modules\reagents\Chemistry-Metabolism.dm" -#include "code\modules\reagents\Chemistry-Readme.dm" -#include "code\modules\reagents\Chemistry-Reagents-Helpers.dm" -#include "code\modules\reagents\Chemistry-Reagents.dm" -#include "code\modules\reagents\Chemistry-Recipes.dm" -#include "code\modules\reagents\reagent_containers.dm" -#include "code\modules\reagents\reagent_dispenser.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Core.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Dispenser.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Food-Drinks.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Medicine.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Modifiers.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Other.dm" -#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Toxins.dm" -#include "code\modules\reagents\dispenser\_defines.dm" -#include "code\modules\reagents\dispenser\cartridge.dm" -#include "code\modules\reagents\dispenser\cartridge_presets.dm" -#include "code\modules\reagents\dispenser\cartridge_spawn.dm" -#include "code\modules\reagents\dispenser\dispenser2.dm" -#include "code\modules\reagents\dispenser\dispenser2_energy.dm" -#include "code\modules\reagents\dispenser\dispenser_presets.dm" -#include "code\modules\reagents\dispenser\supply.dm" -#include "code\modules\reagents\distilling\Distilling-Recipes.dm" -#include "code\modules\reagents\distilling\distilling.dm" +#include "code\modules\reagents\holder\holder.dm" +#include "code\modules\reagents\holder\distilling.dm" #include "code\modules\reagents\hoses\connector.dm" #include "code\modules\reagents\hoses\hose.dm" #include "code\modules\reagents\hoses\hose_connector.dm" +#include "code\modules\reagents\machinery\chem_master.dm" +#include "code\modules\reagents\machinery\chemalyzer.dm" +#include "code\modules\reagents\machinery\distillery.dm" +#include "code\modules\reagents\machinery\grinder.dm" +#include "code\modules\reagents\machinery\dispenser\_defines.dm" +#include "code\modules\reagents\machinery\dispenser\cartridge.dm" +#include "code\modules\reagents\machinery\dispenser\cartridge_presets.dm" +#include "code\modules\reagents\machinery\dispenser\cartridge_spawn.dm" +#include "code\modules\reagents\machinery\dispenser\dispenser2.dm" +#include "code\modules\reagents\machinery\dispenser\dispenser2_energy.dm" +#include "code\modules\reagents\machinery\dispenser\dispenser_presets.dm" +#include "code\modules\reagents\machinery\dispenser\reagent_tank.dm" +#include "code\modules\reagents\machinery\dispenser\supply.dm" +#include "code\modules\reagents\reactions\_reactions.dm" +#include "code\modules\reagents\reactions\distilling\distilling.dm" +#include "code\modules\reagents\reactions\fusion\fusion.dm" +#include "code\modules\reagents\reactions\instant\drinks.dm" +#include "code\modules\reagents\reactions\instant\food.dm" +#include "code\modules\reagents\reactions\instant\instant.dm" +#include "code\modules\reagents\reagent_containers\_reagent_containers.dm" #include "code\modules\reagents\reagent_containers\blood_pack.dm" #include "code\modules\reagents\reagent_containers\borghypo.dm" #include "code\modules\reagents\reagent_containers\dropper.dm" @@ -2872,6 +2868,15 @@ #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm" #include "code\modules\reagents\reagent_containers\unidentified_hypospray.dm" +#include "code\modules\reagents\reagents\_helpers.dm" +#include "code\modules\reagents\reagents\_reagents.dm" +#include "code\modules\reagents\reagents\core.dm" +#include "code\modules\reagents\reagents\dispenser.dm" +#include "code\modules\reagents\reagents\food_drinks.dm" +#include "code\modules\reagents\reagents\medicine.dm" +#include "code\modules\reagents\reagents\modifiers.dm" +#include "code\modules\reagents\reagents\other.dm" +#include "code\modules\reagents\reagents\toxins.dm" #include "code\modules\recycling\conveyor2.dm" #include "code\modules\recycling\disposal-construction.dm" #include "code\modules\recycling\disposal.dm"