diff --git a/code/modules/reagents/Chemistry-Colours.dm b/code/modules/reagents/chemistry/colors.dm similarity index 96% rename from code/modules/reagents/Chemistry-Colours.dm rename to code/modules/reagents/chemistry/colors.dm index 176ec99c4d4..e0c6d5efd84 100644 --- a/code/modules/reagents/Chemistry-Colours.dm +++ b/code/modules/reagents/chemistry/colors.dm @@ -1,31 +1,31 @@ -/* - * Returns: - * #RRGGBB(AA) on success, null on failure - */ -/proc/mix_color_from_reagents(const/list/reagent_list) - if(!istype(reagent_list)) - return - - var/color - var/reagent_color - var/vol_counter = 0 - var/vol_temp - // see libs/IconProcs/IconProcs.dm - for(var/datum/reagent/reagent in reagent_list) - if(reagent.id == "blood" && reagent.data && reagent.data["blood_colour"]) - reagent_color = reagent.data["blood_colour"] - else - reagent_color = reagent.color - - vol_temp = reagent.volume - vol_counter += vol_temp - - if(isnull(color)) - color = reagent.color - else if(length(color) >= length(reagent_color)) - color = BlendRGB(color, reagent_color, vol_temp/vol_counter) - else - color = BlendRGB(reagent_color, color, vol_temp/vol_counter) - return color - - +/* + * Returns: + * #RRGGBB(AA) on success, null on failure + */ +/proc/mix_color_from_reagents(const/list/reagent_list) + if(!istype(reagent_list)) + return + + var/color + var/reagent_color + var/vol_counter = 0 + var/vol_temp + // see libs/IconProcs/IconProcs.dm + for(var/datum/reagent/reagent in reagent_list) + if(reagent.id == "blood" && reagent.data && reagent.data["blood_colour"]) + reagent_color = reagent.data["blood_colour"] + else + reagent_color = reagent.color + + vol_temp = reagent.volume + vol_counter += vol_temp + + if(isnull(color)) + color = reagent.color + else if(length(color) >= length(reagent_color)) + color = BlendRGB(color, reagent_color, vol_temp/vol_counter) + else + color = BlendRGB(reagent_color, color, vol_temp/vol_counter) + return color + + diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/chemistry/holder.dm similarity index 81% rename from code/modules/reagents/Chemistry-Holder.dm rename to code/modules/reagents/chemistry/holder.dm index ecc9c9ddc18..12e8a73d35c 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -1,601 +1,720 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -var/const/TOUCH = 1 -var/const/INGEST = 2 - -/////////////////////////////////////////////////////////////////////////////////// - -/datum/reagents - var/list/datum/reagent/reagent_list = new/list() - var/total_volume = 0 - var/maximum_volume = 100 - var/atom/my_atom = null - var/chem_temp = 300 - var/list/datum/reagent/addiction_list = new/list() - -/datum/reagents/New(maximum=100) - maximum_volume = maximum - - //I dislike having these here but map-objects are initialised before world/New() is called. >_> - if(!chemical_reagents_list) - //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id - var/paths = subtypesof(/datum/reagent) - chemical_reagents_list = list() - for(var/path in paths) - var/datum/reagent/D = new path() - chemical_reagents_list[D.id] = D - if(!D.can_grow_in_plants) - plant_blocked_chems.Add(D.id) - if(!chemical_reactions_list) - //Chemical Reactions - Initialises all /datum/chemical_reaction into a list - // It is filtered into multiple lists within a list. - // For example: - // chemical_reaction_list["plasma"] is a list of all reactions relating to plasma - - var/paths = subtypesof(/datum/chemical_reaction) - chemical_reactions_list = list() - - for(var/path in paths) - - var/datum/chemical_reaction/D = new path() - var/list/reaction_ids = list() - - if(D && D.required_reagents && D.required_reagents.len) - for(var/reaction in D.required_reagents) - reaction_ids += reaction - - // Create filters based on each reagent id in the required reagents list - for(var/id in reaction_ids) - if(!chemical_reactions_list[id]) - chemical_reactions_list[id] = list() - chemical_reactions_list[id] += D - break // Don't bother adding ourselves to other reagent ids, it is redundant. - -/datum/reagents/proc/remove_any(amount=1) - var/total_transfered = 0 - var/current_list_element = 1 - - current_list_element = rand(1,reagent_list.len) - - while(total_transfered != amount) - if(total_transfered >= amount) - break - if(total_volume <= 0 || !reagent_list.len) - break - - if(current_list_element > reagent_list.len) current_list_element = 1 - var/datum/reagent/current_reagent = reagent_list[current_list_element] - - remove_reagent(current_reagent.id, min(1, amount - total_transfered)) - - current_list_element++ - total_transfered++ - update_total() - - handle_reactions() - return total_transfered - -/datum/reagents/proc/get_master_reagent_name() - 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() - 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/trans_to(target, amount=1, multiplier=1, preserve_data=1)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred. - if(!target) - return - if(total_volume <= 0) - return - var/datum/reagents/R - if(istype(target, /obj)) - var/obj/O = target - if(!O.reagents ) - return - R = O.reagents - else if(isliving(target)) - var/mob/living/M = target - if(!M.reagents) - return - R = M.reagents - else if(istype(target, /datum/reagents)) - R = target - else - return - - amount = min(min(amount, total_volume), R.maximum_volume-R.total_volume) - var/part = amount / total_volume - var/trans_data = null - for(var/datum/reagent/current_reagent in reagent_list) - if(!current_reagent) - continue - if(current_reagent.id == "blood" && ishuman(target)) - var/mob/living/carbon/human/H = target - H.inject_blood(my_atom, amount) - continue - var/current_reagent_transfer = current_reagent.volume * part - if(preserve_data) - trans_data = copy_data(current_reagent) - - R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, chem_temp) - remove_reagent(current_reagent.id, current_reagent_transfer) - - update_total() - R.update_total() - R.handle_reactions() - handle_reactions() - return amount - -/datum/reagents/proc/copy_to(obj/target, amount=1, multiplier=1, preserve_data=1, safety = 0) - if(!target) - return - if(!target.reagents || total_volume<=0) - return - var/datum/reagents/R = target.reagents - amount = min(min(amount, total_volume), R.maximum_volume-R.total_volume) - var/part = amount / total_volume - var/trans_data = null - for(var/datum/reagent/current_reagent in reagent_list) - var/current_reagent_transfer = current_reagent.volume * part - if(preserve_data) - trans_data = copy_data(current_reagent) - R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data) - - update_total() - R.update_total() - R.handle_reactions() - handle_reactions() - return amount - -/datum/reagents/proc/trans_id_to(obj/target, reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N - if(!target) - return - if(!target.reagents || total_volume<=0 || !get_reagent_amount(reagent)) - return - - var/datum/reagents/R = target.reagents - if(get_reagent_amount(reagent) R.maximum_volume) return 0 - - current_list_element = rand(1,reagent_list.len) //Eh, bandaid fix. - - while(total_transfered != amount) - if(total_transfered >= amount) break //Better safe than sorry. - if(total_volume <= 0 || !reagent_list.len) break - if(R.total_volume >= R.maximum_volume) break - - if(current_list_element > reagent_list.len) current_list_element = 1 - var/datum/reagent/current_reagent = reagent_list[current_list_element] - if(preserve_data) - trans_data = current_reagent.data - R.add_reagent(current_reagent.id, (1 * multiplier), trans_data) - remove_reagent(current_reagent.id, 1) - - current_list_element++ - total_transfered++ - update_total() - R.update_total() - R.handle_reactions() - handle_reactions() - - return total_transfered -*/ - - -/datum/reagents/proc/conditional_update_move(atom/A, Running = 0) - for(var/datum/reagent/R in reagent_list) - R.on_move (A, Running) - update_total() - -/datum/reagents/proc/conditional_update(atom/A, ) - for(var/datum/reagent/R in reagent_list) - R.on_update (A) - update_total() - -/datum/reagents/proc/handle_reactions() - if(my_atom.flags & NOREACT) - return //Yup, no reactions here. No siree. - - var/reaction_occured = 0 - do - reaction_occured = 0 - for(var/datum/reagent/R in reagent_list) // Usually a small list - for(var/reaction in chemical_reactions_list[R.id]) // Was a big list but now it should be smaller since we filtered it with our reagent id - if(!reaction) - continue - - var/datum/chemical_reaction/C = reaction - var/total_required_reagents = C.required_reagents.len - var/total_matching_reagents = 0 - var/total_required_catalysts = C.required_catalysts.len - var/total_matching_catalysts= 0 - var/matching_container = 0 - var/matching_other = 0 - var/list/multipliers = new/list() - var/min_temp = C.min_temp //Minimum temperature required for the reaction to occur (heat to/above this) - var/max_temp = C.max_temp //Maximum temperature allowed for the reaction to occur (cool to/below this) - for(var/B in C.required_reagents) - if(!has_reagent(B, C.required_reagents[B])) - break - total_matching_reagents++ - multipliers += round(get_reagent_amount(B) / C.required_reagents[B]) - for(var/B in C.required_catalysts) - if(!has_reagent(B, C.required_catalysts[B])) - break - total_matching_catalysts++ - - if(!C.required_container) - matching_container = 1 - - else - if(my_atom.type == C.required_container) - matching_container = 1 - - if(!C.required_other) - matching_other = 1 - - else if(istype(my_atom, /obj/item/slime_extract)) - var/obj/item/slime_extract/M = my_atom - - if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this - matching_other = 1 - - if(min_temp == 0) - min_temp = chem_temp - - if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts && matching_container && matching_other && chem_temp <= max_temp && chem_temp >= min_temp) - var/multiplier = min(multipliers) - var/preserved_data = null - for(var/B in C.required_reagents) - if(!preserved_data) - preserved_data = get_data(B) - remove_reagent(B, (multiplier * C.required_reagents[B]), safety = 1) - - var/created_volume = C.result_amount*multiplier - if(C.result) - feedback_add_details("chemical_reaction","[C.result]|[C.result_amount*multiplier]") - multiplier = max(multiplier, 1) //this shouldnt happen ... - add_reagent(C.result, C.result_amount*multiplier) - set_data(C.result, preserved_data) - - //add secondary products - for(var/S in C.secondary_results) - add_reagent(S, C.result_amount * C.secondary_results[S] * multiplier) - - var/list/seen = viewers(4, get_turf(my_atom)) - for(var/mob/M in seen) - if(!C.no_message) - to_chat(M, "[bicon(my_atom)] [C.mix_message]") - - if(istype(my_atom, /obj/item/slime_extract)) - var/obj/item/slime_extract/ME2 = my_atom - ME2.Uses-- - if(ME2.Uses <= 0) // give the notification that the slime core is dead - for(var/mob/M in seen) - to_chat(M, "[bicon(my_atom)] The [my_atom]'s power is consumed in the reaction.") - ME2.name = "used slime extract" - ME2.desc = "This extract has been used up." - - playsound(get_turf(my_atom), C.mix_sound, 80, 1) - - C.on_reaction(src, created_volume) - reaction_occured = 1 - break - - while(reaction_occured) - update_total() - 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/del_reagent(reagent) - for(var/A in reagent_list) - var/datum/reagent/R = A - if(R.id == reagent) - if(isliving(my_atom)) - var/mob/living/M = my_atom - R.reagent_deleted(M) - reagent_list -= A - qdel(A) - update_total() - my_atom.on_reagent_change() - return 0 - - - return 1 - -/datum/reagents/proc/update_total() - total_volume = 0 - for(var/datum/reagent/R in reagent_list) - if(R.volume < 0.1) - del_reagent(R.id) - else - total_volume += R.volume - - return 0 - -/datum/reagents/proc/clear_reagents() - for(var/datum/reagent/R in reagent_list) - del_reagent(R.id) - return 0 - -/datum/reagents/proc/reaction_check(mob/living/M, datum/reagent/R) - var/can_process = 0 - if(ishuman(M)) - var/mob/living/carbon/human/H = M - //Check if this mob's species is set and can process this type of reagent - if(H.species && H.species.reagent_tag) - if((R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN - can_process = 1 - if((R.process_flags & ORGANIC) && (H.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG - can_process = 1 - //Species with PROCESS_DUO are only affected by reagents that affect both organics and synthetics, like acid and hellwater - if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_DUO)) - can_process = 1 - if(H.species && H.species.exotic_blood) - if(R.id == H.species.exotic_blood) - can_process = 0 - //We'll assume that non-human mobs lack the ability to process synthetic-oriented reagents (adjust this if we need to change that assumption) - else - if(R.process_flags != SYNTHETIC) - can_process = 1 - return can_process - -/datum/reagents/proc/reaction(atom/A, method=TOUCH, volume_modifier = 1) - switch(method) - if(TOUCH) - for(var/datum/reagent/R in reagent_list) - if(isliving(A)) - var/check = reaction_check(A, R) - if(!check) - continue - else - R.reaction_mob(A, TOUCH, R.volume*volume_modifier) - if(isturf(A)) - R.reaction_turf(A, R.volume*volume_modifier) - if(isobj(A)) - R.reaction_obj(A, R.volume*volume_modifier) - if(INGEST) - for(var/datum/reagent/R in reagent_list) - if(isliving(A)) - var/check = reaction_check(A, R) - if(!check) - continue - else - R.reaction_mob(A, INGEST, R.volume*volume_modifier) - if(isturf(A)) - R.reaction_turf(A, R.volume*volume_modifier) - if(isobj(A)) - R.reaction_obj(A, R.volume*volume_modifier) - -/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data=null) // Like add_reagent but you can enter a list. Format it like this: list("toxin" = 10, "beer" = 15) - for(var/r_id in list_reagents) - var/amt = list_reagents[r_id] - add_reagent(r_id, amt, data) - -/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300) - if(!isnum(amount)) - return 1 - update_total() - if(total_volume + amount > maximum_volume) amount = (maximum_volume - total_volume) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen. - if(amount <= 0) - return 0 - chem_temp = round(((amount * reagtemp) + (total_volume * chem_temp)) / (total_volume + amount)) //equalize with new chems - - for(var/A in reagent_list) - - var/datum/reagent/R = A - if(R.id == reagent) - R.volume += amount - update_total() - my_atom.on_reagent_change() - R.on_merge(data) - handle_reactions() - return 0 - - var/datum/reagent/D = chemical_reagents_list[reagent] - if(D) - - var/datum/reagent/R = new D.type() - reagent_list += R - R.holder = src - R.volume = amount - if(data) - R.data = data - R.on_new(data) - - update_total() - my_atom.on_reagent_change() - handle_reactions() - return 0 - else - warning("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])") - - handle_reactions() - - return 1 - -/datum/reagents/proc/remove_reagent(reagent, amount, safety)//Added a safety check for the trans_id_to - - if(!isnum(amount)) - return 1 - - for(var/A in reagent_list) - var/datum/reagent/R = A - if(R.id == reagent) - R.volume -= amount - update_total() - if(!safety)//So it does not handle reactions when it need not to - handle_reactions() - my_atom.on_reagent_change() - return 0 - - return 1 - -/datum/reagents/proc/has_reagent(reagent, amount = -1) - - for(var/A in reagent_list) - var/datum/reagent/R = A - if(R.id == reagent) - if(!amount) - return R - else - if(R.volume >= amount) - return R - else - return 0 - - return 0 - -/datum/reagents/proc/get_reagent_amount(reagent) - for(var/A in reagent_list) - var/datum/reagent/R = A - if(R.id == reagent) - return R.volume - - return 0 - -/datum/reagents/proc/get_reagents() - var/res = "" - for(var/datum/reagent/A in reagent_list) - if(res != "") res += "," - res += A.name - - return res - -/datum/reagents/proc/get_reagent(type) - . = locate(type) in reagent_list - -/datum/reagents/proc/remove_all_type(reagent_type, amount, strict = 0, safety = 1) // Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included. - if(!isnum(amount)) - return 1 - - var/has_removed_reagent = 0 - - for(var/datum/reagent/R in reagent_list) - var/matches = 0 - // Switch between how we check the reagent type - if(strict) - if(R.type == reagent_type) - matches = 1 - else - if(istype(R, reagent_type)) - matches = 1 - // We found a match, proceed to remove the reagent. Keep looping, we might find other reagents of the same type. - if(matches) - // Have our other proc handle removement - has_removed_reagent = remove_reagent(R.id, amount, safety) - - return has_removed_reagent - -// Admin logging. -/datum/reagents/proc/get_reagent_ids(and_amount=0) - var/list/stuff = list() - for(var/datum/reagent/A in reagent_list) - if(and_amount) - stuff += "[get_reagent_amount(A.id)]U of [A.id]" - else - stuff += A.id - return english_list(stuff) - -//two helper functions to preserve data across reactions (needed for xenoarch) -/datum/reagents/proc/get_data(reagent_id) - for(var/datum/reagent/D in reagent_list) - if(D.id == reagent_id) -// to_chat(world, "proffering a data-carrying reagent ([reagent_id])") - return D.data - -/datum/reagents/proc/set_data(reagent_id, new_data) - for(var/datum/reagent/D in reagent_list) - if(D.id == reagent_id) -// to_chat(world, "reagent data set ([reagent_id])") - D.data = new_data - -/datum/reagents/proc/copy_data(datum/reagent/current_reagent) - if(!current_reagent || !current_reagent.data) - return null - if(!istype(current_reagent.data, /list)) - return current_reagent.data - - var/list/trans_data = current_reagent.data.Copy() - - // We do this so that introducing a virus to a blood sample - // doesn't automagically infect all other blood samples from - // the same donor. - // - // Technically we should probably copy all data lists, but - // that could possibly eat up a lot of memory needlessly - // if most data lists are read-only. - if(trans_data["viruses"]) - var/list/v = trans_data["viruses"] - trans_data["viruses"] = v.Copy() - - return trans_data - -/////////////////////////////////////////////////////////////////////////////////// - - -// Convenience proc to create a reagents holder for an atom -// Max vol is maximum volume of holder -atom/proc/create_reagents(max_vol) - reagents = new/datum/reagents(max_vol) - reagents.my_atom = src - -/datum/reagents/proc/get_reagent_from_id(id) - var/datum/reagent/result = null - for(var/datum/reagent/R in reagent_list) - if(R.id == id) - result = R - break - return result - -/datum/reagents/Destroy() - . = ..() - processing_objects.Remove(src) - for(var/datum/reagent/R in reagent_list) - qdel(R) - reagent_list.Cut() - reagent_list = null - if(my_atom && my_atom.reagents == src) - my_atom.reagents = null +//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 + +var/const/TOUCH = 1 +var/const/INGEST = 2 +#define ADDICTION_TIME 4800 //8 minutes + +/////////////////////////////////////////////////////////////////////////////////// + +/datum/reagents + var/list/datum/reagent/reagent_list = new/list() + var/total_volume = 0 + var/maximum_volume = 100 + var/atom/my_atom = null + var/chem_temp = 300 + var/list/datum/reagent/addiction_list = new/list() + +/datum/reagents/New(maximum=100) + maximum_volume = maximum + + //I dislike having these here but map-objects are initialised before world/New() is called. >_> + if(!chemical_reagents_list) + //Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id + var/paths = subtypesof(/datum/reagent) + chemical_reagents_list = list() + for(var/path in paths) + var/datum/reagent/D = new path() + chemical_reagents_list[D.id] = D + if(!D.can_grow_in_plants) + plant_blocked_chems.Add(D.id) + if(!chemical_reactions_list) + //Chemical Reactions - Initialises all /datum/chemical_reaction into a list + // It is filtered into multiple lists within a list. + // For example: + // chemical_reaction_list["plasma"] is a list of all reactions relating to plasma + + var/paths = subtypesof(/datum/chemical_reaction) + chemical_reactions_list = list() + + for(var/path in paths) + + var/datum/chemical_reaction/D = new path() + var/list/reaction_ids = list() + + if(D && D.required_reagents && D.required_reagents.len) + for(var/reaction in D.required_reagents) + reaction_ids += reaction + + // Create filters based on each reagent id in the required reagents list + for(var/id in reaction_ids) + if(!chemical_reactions_list[id]) + chemical_reactions_list[id] = list() + chemical_reactions_list[id] += D + break // Don't bother adding ourselves to other reagent ids, it is redundant. + +/datum/reagents/proc/remove_any(amount=1) + var/total_transfered = 0 + var/current_list_element = 1 + + current_list_element = rand(1,reagent_list.len) + + while(total_transfered != amount) + if(total_transfered >= amount) + break + if(total_volume <= 0 || !reagent_list.len) + break + + if(current_list_element > reagent_list.len) current_list_element = 1 + var/datum/reagent/current_reagent = reagent_list[current_list_element] + + remove_reagent(current_reagent.id, min(1, amount - total_transfered)) + + current_list_element++ + total_transfered++ + update_total() + + handle_reactions() + return total_transfered + +/datum/reagents/proc/get_master_reagent_name() + 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() + 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/trans_to(target, amount=1, multiplier=1, preserve_data=1)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred. + if(!target) + return + if(total_volume <= 0) + return + var/datum/reagents/R + if(istype(target, /obj)) + var/obj/O = target + if(!O.reagents ) + return + R = O.reagents + else if(isliving(target)) + var/mob/living/M = target + if(!M.reagents) + return + R = M.reagents + else if(istype(target, /datum/reagents)) + R = target + else + return + + amount = min(min(amount, total_volume), R.maximum_volume-R.total_volume) + var/part = amount / total_volume + var/trans_data = null + for(var/datum/reagent/current_reagent in reagent_list) + if(!current_reagent) + continue + if(current_reagent.id == "blood" && ishuman(target)) + var/mob/living/carbon/human/H = target + H.inject_blood(my_atom, amount) + continue + var/current_reagent_transfer = current_reagent.volume * part + if(preserve_data) + trans_data = copy_data(current_reagent) + + R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data, chem_temp) + remove_reagent(current_reagent.id, current_reagent_transfer) + + update_total() + R.update_total() + R.handle_reactions() + handle_reactions() + return amount + +/datum/reagents/proc/copy_to(obj/target, amount=1, multiplier=1, preserve_data=1, safety = 0) + if(!target) + return + if(!target.reagents || total_volume<=0) + return + var/datum/reagents/R = target.reagents + amount = min(min(amount, total_volume), R.maximum_volume-R.total_volume) + var/part = amount / total_volume + var/trans_data = null + for(var/datum/reagent/current_reagent in reagent_list) + var/current_reagent_transfer = current_reagent.volume * part + if(preserve_data) + trans_data = copy_data(current_reagent) + R.add_reagent(current_reagent.id, (current_reagent_transfer * multiplier), trans_data) + + update_total() + R.update_total() + R.handle_reactions() + handle_reactions() + return amount + +/datum/reagents/proc/trans_id_to(obj/target, reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N + if(!target) + return + if(!target.reagents || total_volume<=0 || !get_reagent_amount(reagent)) + return + + var/datum/reagents/R = target.reagents + if(get_reagent_amount(reagent)= R.overdose_threshold && !R.overdosed && R.overdose_threshold > 0) + R.overdosed = 1 + R.overdose_start(M) + if(R.volume < R.overdose_threshold && R.overdosed) + R.overdosed = 0 + if(R.overdosed) + R.overdose_process(M, R.volume >= R.overdose_threshold*2 ? 2 : 1) + + for(var/A in addiction_list) + var/datum/reagent/R = A + if(M && R) + if(R.addiction_stage < 5) + if(prob(5)) + R.addiction_stage++ + switch(R.addiction_stage) + if(1) + R.addiction_act_stage1(M) + if(2) + R.addiction_act_stage2(M) + if(3) + R.addiction_act_stage3(M) + if(4) + R.addiction_act_stage4(M) + if(5) + R.addiction_act_stage5(M) + if(prob(20) && (world.timeofday > (R.last_addiction_dose + ADDICTION_TIME))) //Each addiction lasts 8 minutes before it can end + to_chat(M, "You no longer feel reliant on [R.name]!") + addiction_list.Remove(R) + update_total() + +/datum/reagents/proc/death_metabolize(mob/living/M) + if(!M) + return + if(M.stat != DEAD) //what part of DEATH_metabolize don't you get? + return + for(var/A in reagent_list) + var/datum/reagent/R = A + if(!istype(R)) + continue + if(M && R) + R.on_mob_death(M) + +/datum/reagents/proc/overdose_list() + var/od_chems[0] + for(var/datum/reagent/R in reagent_list) + if(R.overdosed) + od_chems.Add(R.id) + return od_chems + + +/datum/reagents/proc/reagent_on_tick() + for(var/datum/reagent/R in reagent_list) + R.on_tick() + return +/* + if(!target) return + var/total_transfered = 0 + var/current_list_element = 1 + var/datum/reagents/R = target.reagents + var/trans_data = null + //if(R.total_volume + amount > R.maximum_volume) return 0 + + current_list_element = rand(1,reagent_list.len) //Eh, bandaid fix. + + while(total_transfered != amount) + if(total_transfered >= amount) break //Better safe than sorry. + if(total_volume <= 0 || !reagent_list.len) break + if(R.total_volume >= R.maximum_volume) break + + if(current_list_element > reagent_list.len) current_list_element = 1 + var/datum/reagent/current_reagent = reagent_list[current_list_element] + if(preserve_data) + trans_data = current_reagent.data + R.add_reagent(current_reagent.id, (1 * multiplier), trans_data) + remove_reagent(current_reagent.id, 1) + + current_list_element++ + total_transfered++ + update_total() + R.update_total() + R.handle_reactions() + handle_reactions() + + return total_transfered +*/ + + +/datum/reagents/proc/conditional_update_move(atom/A, Running = 0) + for(var/datum/reagent/R in reagent_list) + R.on_move (A, Running) + update_total() + +/datum/reagents/proc/conditional_update(atom/A, ) + for(var/datum/reagent/R in reagent_list) + R.on_update (A) + update_total() + +/datum/reagents/proc/handle_reactions() + if(my_atom.flags & NOREACT) + return //Yup, no reactions here. No siree. + + var/reaction_occured = 0 + do + reaction_occured = 0 + for(var/datum/reagent/R in reagent_list) // Usually a small list + for(var/reaction in chemical_reactions_list[R.id]) // Was a big list but now it should be smaller since we filtered it with our reagent id + if(!reaction) + continue + + var/datum/chemical_reaction/C = reaction + var/total_required_reagents = C.required_reagents.len + var/total_matching_reagents = 0 + var/total_required_catalysts = C.required_catalysts.len + var/total_matching_catalysts= 0 + var/matching_container = 0 + var/matching_other = 0 + var/list/multipliers = new/list() + var/min_temp = C.min_temp //Minimum temperature required for the reaction to occur (heat to/above this) + var/max_temp = C.max_temp //Maximum temperature allowed for the reaction to occur (cool to/below this) + for(var/B in C.required_reagents) + if(!has_reagent(B, C.required_reagents[B])) + break + total_matching_reagents++ + multipliers += round(get_reagent_amount(B) / C.required_reagents[B]) + for(var/B in C.required_catalysts) + if(!has_reagent(B, C.required_catalysts[B])) + break + total_matching_catalysts++ + + if(!C.required_container) + matching_container = 1 + + else + if(my_atom.type == C.required_container) + matching_container = 1 + + if(!C.required_other) + matching_other = 1 + + else if(istype(my_atom, /obj/item/slime_extract)) + var/obj/item/slime_extract/M = my_atom + + if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this + matching_other = 1 + + if(min_temp == 0) + min_temp = chem_temp + + if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts && matching_container && matching_other && chem_temp <= max_temp && chem_temp >= min_temp) + var/multiplier = min(multipliers) + var/preserved_data = null + for(var/B in C.required_reagents) + if(!preserved_data) + preserved_data = get_data(B) + remove_reagent(B, (multiplier * C.required_reagents[B]), safety = 1) + + var/created_volume = C.result_amount*multiplier + if(C.result) + feedback_add_details("chemical_reaction","[C.result]|[C.result_amount*multiplier]") + multiplier = max(multiplier, 1) //this shouldnt happen ... + add_reagent(C.result, C.result_amount*multiplier) + set_data(C.result, preserved_data) + + //add secondary products + for(var/S in C.secondary_results) + add_reagent(S, C.result_amount * C.secondary_results[S] * multiplier) + + var/list/seen = viewers(4, get_turf(my_atom)) + for(var/mob/M in seen) + if(!C.no_message) + to_chat(M, "[bicon(my_atom)] [C.mix_message]") + + if(istype(my_atom, /obj/item/slime_extract)) + var/obj/item/slime_extract/ME2 = my_atom + ME2.Uses-- + if(ME2.Uses <= 0) // give the notification that the slime core is dead + for(var/mob/M in seen) + to_chat(M, "[bicon(my_atom)] The [my_atom]'s power is consumed in the reaction.") + ME2.name = "used slime extract" + ME2.desc = "This extract has been used up." + + playsound(get_turf(my_atom), C.mix_sound, 80, 1) + + C.on_reaction(src, created_volume) + reaction_occured = 1 + break + + while(reaction_occured) + update_total() + 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/del_reagent(reagent) + for(var/A in reagent_list) + var/datum/reagent/R = A + if(R.id == reagent) + if(isliving(my_atom)) + var/mob/living/M = my_atom + R.on_mob_delete(M) + reagent_list -= A + qdel(A) + update_total() + my_atom.on_reagent_change() + return 0 + + + return 1 + +/datum/reagents/proc/update_total() + total_volume = 0 + for(var/datum/reagent/R in reagent_list) + if(R.volume < 0.1) + del_reagent(R.id) + else + total_volume += R.volume + + return 0 + +/datum/reagents/proc/clear_reagents() + for(var/datum/reagent/R in reagent_list) + del_reagent(R.id) + return 0 + +/datum/reagents/proc/reaction_check(mob/living/M, datum/reagent/R) + var/can_process = 0 + if(ishuman(M)) + var/mob/living/carbon/human/H = M + //Check if this mob's species is set and can process this type of reagent + if(H.species && H.species.reagent_tag) + if((R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN + can_process = 1 + if((R.process_flags & ORGANIC) && (H.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG + can_process = 1 + //Species with PROCESS_DUO are only affected by reagents that affect both organics and synthetics, like acid and hellwater + if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_DUO)) + can_process = 1 + if(H.species && H.species.exotic_blood) + if(R.id == H.species.exotic_blood) + can_process = 0 + //We'll assume that non-human mobs lack the ability to process synthetic-oriented reagents (adjust this if we need to change that assumption) + else + if(R.process_flags != SYNTHETIC) + can_process = 1 + return can_process + +/datum/reagents/proc/reaction(atom/A, method=TOUCH, volume_modifier = 1) + switch(method) + if(TOUCH) + for(var/datum/reagent/R in reagent_list) + if(isliving(A)) + var/check = reaction_check(A, R) + if(!check) + continue + else + R.reaction_mob(A, TOUCH, R.volume*volume_modifier) + if(isturf(A)) + R.reaction_turf(A, R.volume*volume_modifier) + if(isobj(A)) + R.reaction_obj(A, R.volume*volume_modifier) + if(INGEST) + for(var/datum/reagent/R in reagent_list) + if(isliving(A)) + var/check = reaction_check(A, R) + if(!check) + continue + else + R.reaction_mob(A, INGEST, R.volume*volume_modifier) + if(isturf(A)) + R.reaction_turf(A, R.volume*volume_modifier) + if(isobj(A)) + R.reaction_obj(A, R.volume*volume_modifier) + +/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data=null) // Like add_reagent but you can enter a list. Format it like this: list("toxin" = 10, "beer" = 15) + for(var/r_id in list_reagents) + var/amt = list_reagents[r_id] + add_reagent(r_id, amt, data) + +/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300) + if(!isnum(amount)) + return 1 + update_total() + if(total_volume + amount > maximum_volume) amount = (maximum_volume - total_volume) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen. + if(amount <= 0) + return 0 + chem_temp = round(((amount * reagtemp) + (total_volume * chem_temp)) / (total_volume + amount)) //equalize with new chems + + for(var/A in reagent_list) + + var/datum/reagent/R = A + if(R.id == reagent) + R.volume += amount + update_total() + my_atom.on_reagent_change() + R.on_merge(data) + handle_reactions() + return 0 + + var/datum/reagent/D = chemical_reagents_list[reagent] + if(D) + + var/datum/reagent/R = new D.type() + reagent_list += R + R.holder = src + R.volume = amount + if(data) + R.data = data + R.on_new(data) + + update_total() + my_atom.on_reagent_change() + handle_reactions() + return 0 + else + warning("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])") + + handle_reactions() + + return 1 + +/datum/reagents/proc/remove_reagent(reagent, amount, safety)//Added a safety check for the trans_id_to + + if(!isnum(amount)) + return 1 + + for(var/A in reagent_list) + var/datum/reagent/R = A + if(R.id == reagent) + R.volume -= amount + update_total() + if(!safety)//So it does not handle reactions when it need not to + handle_reactions() + my_atom.on_reagent_change() + return 0 + + return 1 + +/datum/reagents/proc/has_reagent(reagent, amount = -1) + + for(var/A in reagent_list) + var/datum/reagent/R = A + if(R.id == reagent) + if(!amount) + return R + else + if(R.volume >= amount) + return R + else + return 0 + + return 0 + +/datum/reagents/proc/get_reagent_amount(reagent) + for(var/A in reagent_list) + var/datum/reagent/R = A + if(R.id == reagent) + return R.volume + + return 0 + +/datum/reagents/proc/get_reagents() + var/res = "" + for(var/datum/reagent/A in reagent_list) + if(res != "") res += "," + res += A.name + + return res + +/datum/reagents/proc/get_reagent(type) + . = locate(type) in reagent_list + +/datum/reagents/proc/remove_all_type(reagent_type, amount, strict = 0, safety = 1) // Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included. + if(!isnum(amount)) + return 1 + + var/has_removed_reagent = 0 + + for(var/datum/reagent/R in reagent_list) + var/matches = 0 + // Switch between how we check the reagent type + if(strict) + if(R.type == reagent_type) + matches = 1 + else + if(istype(R, reagent_type)) + matches = 1 + // We found a match, proceed to remove the reagent. Keep looping, we might find other reagents of the same type. + if(matches) + // Have our other proc handle removement + has_removed_reagent = remove_reagent(R.id, amount, safety) + + return has_removed_reagent + +// Admin logging. +/datum/reagents/proc/get_reagent_ids(and_amount=0) + var/list/stuff = list() + for(var/datum/reagent/A in reagent_list) + if(and_amount) + stuff += "[get_reagent_amount(A.id)]U of [A.id]" + else + stuff += A.id + return english_list(stuff) + +//two helper functions to preserve data across reactions (needed for xenoarch) +/datum/reagents/proc/get_data(reagent_id) + for(var/datum/reagent/D in reagent_list) + if(D.id == reagent_id) +// to_chat(world, "proffering a data-carrying reagent ([reagent_id])") + return D.data + +/datum/reagents/proc/set_data(reagent_id, new_data) + for(var/datum/reagent/D in reagent_list) + if(D.id == reagent_id) +// to_chat(world, "reagent data set ([reagent_id])") + D.data = new_data + +/datum/reagents/proc/copy_data(datum/reagent/current_reagent) + if(!current_reagent || !current_reagent.data) + return null + if(!istype(current_reagent.data, /list)) + return current_reagent.data + + var/list/trans_data = current_reagent.data.Copy() + + // We do this so that introducing a virus to a blood sample + // doesn't automagically infect all other blood samples from + // the same donor. + // + // Technically we should probably copy all data lists, but + // that could possibly eat up a lot of memory needlessly + // if most data lists are read-only. + if(trans_data["viruses"]) + var/list/v = trans_data["viruses"] + trans_data["viruses"] = v.Copy() + + return trans_data + +// For random item spawning. Takes a list of paths, and returns the same list without anything that contains admin only reagents +/proc/adminReagentCheck(list/incoming) + var/list/outgoing[0] + for(var/tocheck in incoming) + if(ispath(tocheck)) + var/check = new tocheck + if(istype(check, /atom)) + var/atom/reagentCheck = check + var/datum/reagents/reagents = reagentCheck.reagents + var/admin = 0 + for(var/reag in reagents.reagent_list) + var/datum/reagent/reagent = reag + if(reagent.admin_only) + admin = 1 + break + if(!(admin)) + outgoing += tocheck + else + outgoing += tocheck + return outgoing + +/////////////////////////////////////////////////////////////////////////////////// + + +// Convenience proc to create a reagents holder for an atom +// Max vol is maximum volume of holder +atom/proc/create_reagents(max_vol) + reagents = new/datum/reagents(max_vol) + reagents.my_atom = src + +/datum/reagents/proc/get_reagent_from_id(id) + var/datum/reagent/result = null + for(var/datum/reagent/R in reagent_list) + if(R.id == id) + result = R + break + return result + +/datum/reagents/Destroy() + . = ..() + processing_objects.Remove(src) + for(var/datum/reagent/R in reagent_list) + qdel(R) + reagent_list.Cut() + reagent_list = null + if(my_atom && my_atom.reagents == src) + my_atom.reagents = null diff --git a/code/modules/reagents/newchem/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm similarity index 100% rename from code/modules/reagents/newchem/chem_heater.dm rename to code/modules/reagents/chemistry/machinery/chem_heater.dm diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/chemistry/machinery/chemistry_machinery.dm similarity index 97% rename from code/modules/reagents/Chemistry-Machinery.dm rename to code/modules/reagents/chemistry/machinery/chemistry_machinery.dm index ddd53d98fdf..913f6e593eb 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/chemistry/machinery/chemistry_machinery.dm @@ -1,1215 +1,1215 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 - -/obj/machinery/chem_dispenser - name = "chem dispenser" - density = 1 - anchored = 1 - icon = 'icons/obj/chemical.dmi' - icon_state = "dispenser" - use_power = 0 - idle_power_usage = 40 - var/ui_title = "Chem Dispenser 5000" - var/energy = 100 - var/max_energy = 100 - var/amount = 30 - var/obj/item/weapon/reagent_containers/beaker = null - var/recharged = 0 - var/hackedcheck = 0 - var/list/dispensable_reagents = list("hydrogen", "lithium", "carbon", "nitrogen", "oxygen", "fluorine", - "sodium", "aluminum", "silicon", "phosphorus", "sulfur", "chlorine", "potassium", "iron", - "copper", "mercury", "plasma", "radium", "water", "ethanol", "sugar", "iodine", "bromine", "silver") - var/list/hacked_reagents = list("toxin") - var/hack_message = "You disable the safety safeguards, enabling the \"Mad Scientist\" mode." - var/unhack_message = "You re-enable the safety safeguards, enabling the \"NT Standard\" mode." - var/list/broken_requirements = list() - var/broken_on_spawn = 0 - var/recharge_delay = 5 - var/image/icon_beaker = null //cached overlay - - -/obj/machinery/chem_dispenser/proc/recharge() - if(stat & (BROKEN|NOPOWER)) return - var/addenergy = 1 - var/oldenergy = energy - energy = min(energy + addenergy, max_energy) - if(energy != oldenergy) - use_power(1500) // This thing uses up alot of power (this is still low as shit for creating reagents from thin air) - nanomanager.update_uis(src) // update all UIs attached to src - -/obj/machinery/chem_dispenser/power_change() - if(powered()) - stat &= ~NOPOWER - else - spawn(rand(0, 15)) - stat |= NOPOWER - nanomanager.update_uis(src) // update all UIs attached to src - -/obj/machinery/chem_dispenser/process() - - if(recharged < 0) - recharge() - recharged = recharge_delay - else - recharged -= 1 - -/obj/machinery/chem_dispenser/New() - ..() - recharge() - dispensable_reagents = sortList(dispensable_reagents) - - if(broken_on_spawn) - overlays.Cut() - var/amount = pick(3,3,4) - var/list/options = list() - options[/obj/item/weapon/stock_parts/capacitor/adv] = "Add an advanced capacitor to fix it." - options[/obj/item/weapon/stock_parts/console_screen] = "Replace the console screen to fix it." - options[/obj/item/weapon/stock_parts/manipulator/pico] = "Upgrade to a pico manipulator to fix it." - options[/obj/item/weapon/stock_parts/matter_bin/super] = "Give it a super matter bin to fix it." - options[/obj/item/weapon/stock_parts/cell/super] = "Replace the reagent synthesizer with a super capacity cell to fix it." - options[/obj/item/device/mass_spectrometer/adv] = "Replace the reagent scanner with an advanced mass spectrometer to fix it" - options[/obj/item/weapon/stock_parts/micro_laser/high] = "Repair the reagent synthesizer with an high-power micro-laser to fix it" - options[/obj/item/device/reagent_scanner/adv] = "Replace the reagent scanner with an advanced reagent scanner to fix it" - options[/obj/item/stack/nanopaste] = "Apply some nanopaste to the broken nozzles to fix it." - options[/obj/item/stack/sheet/plasteel] = "Surround the outside with a plasteel cover to fix it." - options[/obj/item/stack/sheet/rglass] = "Insert a pane of reinforced glass to fix it." - - while(amount > 0) - amount -= 1 - - var/index = pick(options) - broken_requirements[index] = options[index] - options -= index - - -/obj/machinery/chem_dispenser/ex_act(severity) - switch(severity) - if(1.0) - qdel(src) - return - if(2.0) - if(prob(50)) - qdel(src) - return - -/obj/machinery/chem_dispenser/blob_act() - if(prob(50)) - qdel(src) - - /** - * The ui_interact proc is used to open and update Nano UIs - * If ui_interact is not used then the UI will not update correctly - * ui_interact is currently defined for /atom/movable - * - * @param user /mob The mob who is interacting with this ui - * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") - * - * @return nothing - */ - -/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) - if(broken_requirements.len) - to_chat(user, "[src] is broken. [broken_requirements[broken_requirements[1]]]") - return - - - // this is the data which will be sent to the ui - var/data[0] - data["amount"] = amount - data["energy"] = round(energy) - data["maxEnergy"] = round(max_energy) - data["isBeakerLoaded"] = beaker ? 1 : 0 - - var beakerContents[0] - var beakerCurrentVolume = 0 - if(beaker && beaker.reagents && beaker.reagents.reagent_list.len) - for(var/datum/reagent/R in beaker.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... - beakerCurrentVolume += R.volume - data["beakerContents"] = beakerContents - - if(beaker) - data["beakerCurrentVolume"] = beakerCurrentVolume - data["beakerMaxVolume"] = beaker.volume - else - data["beakerCurrentVolume"] = null - data["beakerMaxVolume"] = null - - var chemicals[0] - for(var/re in dispensable_reagents) - var/datum/reagent/temp = chemical_reagents_list[re] - if(temp) - chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("dispense" = temp.id)))) // list in a list because Byond merges the first list... - data["chemicals"] = chemicals - - // update the ui if it exists, returns null if no ui is passed/found - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - // the ui does not exist, so we'll create a new() one - // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm - ui = new(user, src, ui_key, "chem_dispenser.tmpl", ui_title, 390, 655) - // when the ui is first opened this is the data it will use - ui.set_initial_data(data) - // open the new ui window - ui.open() - -/obj/machinery/chem_dispenser/Topic(href, href_list) - if(..()) - return 1 - - if(href_list["amount"]) - amount = round(text2num(href_list["amount"]), 5) // round to nearest 5 - if(amount < 0) // Since the user can actually type the commands himself, some sanity checking - amount = 0 - if(amount > 100) - amount = 100 - - if(href_list["dispense"]) - if(dispensable_reagents.Find(href_list["dispense"]) && beaker != null) - var/obj/item/weapon/reagent_containers/glass/B = beaker - var/datum/reagents/R = B.reagents - var/space = R.maximum_volume - R.total_volume - - R.add_reagent(href_list["dispense"], min(amount, energy * 10, space)) - energy = max(energy - min(amount, energy * 10, space) / 10, 0) - overlays.Cut() - icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. - icon_beaker.pixel_x = rand(-10,5) - overlays += icon_beaker - - if(href_list["remove"]) - if(beaker) - if(href_list["removeamount"]) - var/amount = text2num(href_list["removeamount"]) - if(isnum(amount) && (amount > 0)) - var/obj/item/weapon/reagent_containers/glass/B = beaker - var/datum/reagents/R = B.reagents - var/id = href_list["remove"] - R.remove_reagent(id, amount) - - if(href_list["ejectBeaker"]) - if(beaker) - var/obj/item/weapon/reagent_containers/glass/B = beaker - B.forceMove(loc) - beaker = null - overlays.Cut() - add_fingerprint(usr) - return 1 // update UIs attached to this object - -/obj/machinery/chem_dispenser/attackby(obj/item/weapon/reagent_containers/B, mob/user, params) - if(isrobot(user)) - return - - if(broken_requirements.len && B.type == broken_requirements[1]) - if(istype(B,/obj/item/stack)) - var/obj/item/stack/S = B - S.use(1) - else - if(!user.drop_item()) - to_chat(user, "[B] is stuck to you!") - return - qdel(B) - broken_requirements -= broken_requirements[1] - to_chat(user, "You fix [src].") - return - - if(beaker) - to_chat(user, "Something is already loaded into the machine.") - return - - if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food/drinks)) - beaker = B - if(!user.drop_item()) - to_chat(user, "[B] is stuck to you!") - return - B.forceMove(src) - to_chat(user, "You set [B] on the machine.") - nanomanager.update_uis(src) // update all UIs attached to src - if(!icon_beaker) - icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. - icon_beaker.pixel_x = rand(-10,5) - overlays += icon_beaker - return - -/obj/machinery/chem_dispenser/attackby(obj/item/weapon/B, mob/user, params) - ..() - if(istype(B, /obj/item/device/multitool)) - if(hackedcheck == 0) - to_chat(user, hack_message) - dispensable_reagents += hacked_reagents - hackedcheck = 1 - return - - else - to_chat(user, unhack_message) - dispensable_reagents -= hacked_reagents - hackedcheck = 0 - return - -/obj/machinery/chem_dispenser/attack_ai(mob/user) - return attack_hand(user) - -/obj/machinery/chem_dispenser/attack_ghost(mob/user) - return attack_hand(user) - -/obj/machinery/chem_dispenser/attack_hand(mob/user) - if(stat & BROKEN) - return - - ui_interact(user) - -/obj/machinery/chem_dispenser/soda - icon_state = "soda_dispenser" - name = "soda fountain" - desc = "A drink fabricating machine, capable of producing many sugary drinks with just one touch." - ui_title = "Soda Dispens-o-matic" - energy = 100 - max_energy = 100 - dispensable_reagents = list("water", "ice", "milk", "soymilk", "coffee", "tea", "hot_coco", "cola", "spacemountainwind", "dr_gibb", "space_up", - "tonic", "sodawater", "lemon_lime", "grapejuice", "sugar", "orangejuice", "lemonjuice", "limejuice", "tomatojuice", "banana", - "watermelonjuice", "carrotjuice", "potato", "berryjuice") - hack_message = "You change the mode from 'McNano' to 'Pizza King'." - unhack_message = "You change the mode from 'Pizza King' to 'McNano'." - hacked_reagents = list("thirteenloko") - -/obj/machinery/chem_dispenser/beer - icon_state = "booze_dispenser" - name = "booze dispenser" - ui_title = "Booze Portal 9001" - energy = 100 - max_energy = 100 - desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." - dispensable_reagents = list("ice", "cream", "cider", "beer", "kahlua", "whiskey", "wine", "vodka", "gin", "rum", "tequila", "vermouth", "cognac", "ale", "mead", "synthanol") - hack_message = "You disable the 'nanotrasen-are-cheap-bastards' lock, enabling hidden and very expensive boozes." - unhack_message = "You re-enable the 'nanotrasen-are-cheap-bastards' lock, disabling hidden and very expensive boozes." - hacked_reagents = list("goldschlager", "patron", "absinthe", "ethanol", "nothing") - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/obj/machinery/chem_dispenser/constructable - name = "portable chem dispenser" - icon = 'icons/obj/chemical.dmi' - icon_state = "minidispenser" - energy = 5 - max_energy = 5 - amount = 5 - recharge_delay = 10 - dispensable_reagents = list() - var/list/special_reagents = list(list("hydrogen", "oxygen", "silicon", "phosphorus", "sulfur", "carbon", "nitrogen", "water"), - list("lithium", "sugar", "copper", "mercury", "sodium","iodine","bromine"), - list("ethanol", "chlorine", "potassium", "aluminum","plasma", "radium", "fluorine", "iron", "silver"), - list("oil", "ash", "acetone", "saltpetre", "ammonia", "diethylamine", "fuel")) - -/obj/machinery/chem_dispenser/constructable/New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/chem_dispenser(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) - component_parts += new /obj/item/weapon/stock_parts/manipulator(null) - component_parts += new /obj/item/weapon/stock_parts/capacitor(null) - component_parts += new /obj/item/weapon/stock_parts/console_screen(null) - component_parts += new /obj/item/weapon/stock_parts/cell/super(null) - RefreshParts() - -/obj/machinery/chem_dispenser/constructable/upgraded/New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/chem_dispenser(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/weapon/stock_parts/manipulator/pico(null) - component_parts += new /obj/item/weapon/stock_parts/capacitor/super(null) - component_parts += new /obj/item/weapon/stock_parts/console_screen(null) - component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null) - RefreshParts() - -/obj/machinery/chem_dispenser/constructable/RefreshParts() - var/time = 0 - var/temp_energy = 0 - var/i - for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) - temp_energy += M.rating - temp_energy-- - max_energy = temp_energy * 5 //max energy = (bin1.rating + bin2.rating - 1) * 5, 5 on lowest 25 on highest - for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts) - time += C.rating - for(var/obj/item/weapon/stock_parts/cell/P in component_parts) - time += round(P.maxcharge, 10000) / 10000 - recharge_delay = 10 / (time/2) //delay between recharges, double the usual time on lowest 33% less than usual on highest - for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) - for(i=1, i<=M.rating, i++) - dispensable_reagents = sortList(dispensable_reagents | special_reagents[i]) - -/obj/machinery/chem_dispenser/constructable/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/weapon/reagent_containers/glass)) - if(panel_open) - to_chat(user, "Close the maintenance panel first.") - return - ..() - else - ..() - - if(default_deconstruction_screwdriver(user, "minidispenser-o", "minidispenser", I)) - return - - if(exchange_parts(user, I)) - return - - if(istype(I, /obj/item/weapon/wrench)) - playsound(src, 'sound/items/Ratchet.ogg', 50, 1) - if(anchored) - anchored = 0 - to_chat(user, "[src] can now be moved.") - else if(!anchored) - anchored = 1 - to_chat(user, "[src] is now secured.") - - if(panel_open) - if(istype(I, /obj/item/weapon/crowbar)) - if(beaker) - var/obj/item/weapon/reagent_containers/glass/B = beaker - B.forceMove(loc) - beaker = null - default_deconstruction_crowbar(I) - return 1 - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/obj/machinery/chem_master - name = "\improper ChemMaster 3000" - density = 1 - anchored = 1 - icon = 'icons/obj/chemical.dmi' - icon_state = "mixer0" - use_power = 1 - 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 = 30 // Last used amount - var/pillamount = 10 - var/patchamount = 10 - var/bottlesprite = "bottle" - var/pillsprite = "1" - var/client/has_sprites = list() - var/printing = null - -/obj/machinery/chem_master/New() - var/datum/reagents/R = new/datum/reagents(100) - reagents = R - R.my_atom = src - overlays += "waitlight" - -/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/blob_act() - if(prob(50)) - qdel(src) - -/obj/machinery/chem_master/power_change() - if(powered()) - stat &= ~NOPOWER - else - spawn(rand(0, 15)) - stat |= NOPOWER - -/obj/machinery/chem_master/attackby(obj/item/weapon/B, mob/user, params) - - if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass)) - - if(beaker) - to_chat(user, "A beaker is already loaded into the machine.") - return - if(!user.drop_item()) - to_chat(user, "[B] is stuck to you!") - return - beaker = B - B.forceMove(src) - to_chat(user, "You add the beaker to the machine!") - nanomanager.update_uis(src) - icon_state = "mixer1" - - else if(istype(B, /obj/item/weapon/storage/pill_bottle)) - - if(loaded_pill_bottle) - to_chat(user, "A pill bottle is already loaded into the machine.") - return - - if(!user.drop_item()) - to_chat(user, "[B] is stuck to you!") - return - loaded_pill_bottle = B - B.forceMove(src) - to_chat(user, "You add the pill bottle into the dispenser slot!") - nanomanager.update_uis(src) - return - -/obj/machinery/chem_master/Topic(href, href_list) - if(..()) - return 1 - - add_fingerprint(usr) - usr.set_machine(src) - - - if(href_list["ejectp"]) - if(loaded_pill_bottle) - loaded_pill_bottle.forceMove(loc) - loaded_pill_bottle = null - else if(href_list["close"]) - usr << browse(null, "window=chem_master") - onclose(usr, "chem_master") - usr.unset_machine() - return - - if(href_list["print_p"]) - if(!(printing)) - printing = 1 - 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: [worldtime2text(world.time)]

" - P.info += "Chemical name: [href_list["name"]]
" - if(href_list["name"] == "Blood") - var/datum/reagents/R = beaker.reagents - var/datum/reagent/blood/G - for(var/datum/reagent/F in R.reagent_list) - if(F.name == href_list["name"]) - G = F - break - var/B = G.data["blood_type"] - var/C = G.data["blood_DNA"] - P.info += "Description:
Blood Type: [B]
DNA: [C]" - else - P.info += "Description: [href_list["desc"]]" - P.info += "

Notes:
" - P.name = "Chemical Analysis - [href_list["name"]]" - printing = null - - if(beaker) - var/datum/reagents/R = beaker.reagents - if(href_list["analyze"]) - var/dat = "" - if(!condi) - if(href_list["name"] == "Blood") - var/datum/reagent/blood/G - for(var/datum/reagent/F in R.reagent_list) - if(F.name == href_list["name"]) - G = F - break - var/A = G.name - var/B = G.data["blood_type"] - var/C = G.data["blood_DNA"] - dat += "Chemmaster 3000Chemical infos:

Name:
[A]

Description:
Blood Type: [B]
DNA: [C]" - else - dat += "Chemmaster 3000Chemical infos:

Name:
[href_list["name"]]

Description:
[href_list["desc"]]" - dat += "

(Print Analysis)
" - dat += "(Back)" - else - dat += "Condimaster 3000Condiment infos:

Name:
[href_list["name"]]

Description:
[href_list["desc"]]


(Back)" - usr << browse(dat, "window=chem_master;size=575x400") - return - - else if(href_list["add"]) - - if(href_list["amount"]) - var/id = href_list["add"] - var/amount = text2num(href_list["amount"]) - R.trans_id_to(src, id, amount) - - else if(href_list["addcustom"]) - - var/id = href_list["addcustom"] - useramount = input("Select the amount to transfer.", 30, useramount) as num - useramount = isgoodnumber(useramount) - Topic(null, list("amount" = "[useramount]", "add" = "[id]")) - - else if(href_list["remove"]) - - if(href_list["amount"]) - var/id = href_list["remove"] - var/amount = text2num(href_list["amount"]) - if(mode) - reagents.trans_id_to(beaker, id, amount) - else - reagents.remove_reagent(id, amount) - - - else if(href_list["removecustom"]) - - var/id = href_list["removecustom"] - useramount = input("Select the amount to transfer.", 30, useramount) as num - useramount = isgoodnumber(useramount) - Topic(null, list("amount" = "[useramount]", "remove" = "[id]")) - - else if(href_list["toggle"]) - mode = !mode - - else if(href_list["main"]) - attack_hand(usr) - return - else if(href_list["eject"]) - if(beaker) - beaker.forceMove(get_turf(src)) - beaker = null - reagents.clear_reagents() - icon_state = "mixer0" - else if(href_list["createpill"] || href_list["createpill_multiple"]) - if(!condi) - var/count = 1 - if(href_list["createpill_multiple"]) - count = input("Select the number of pills to make.", 10, pillamount) as num|null - if(count == null) - return - count = isgoodnumber(count) - if(count > 20) count = 20 //Pevent people from creating huge stacks of pills easily. Maybe move the number to defines? - if(count <= 0) return - var/amount_per_pill = reagents.total_volume/count - if(amount_per_pill > 50) amount_per_pill = 50 - var/name = input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill]u)") as text|null - if(!name) - return - name = reject_bad_text(name) - while(count--) - var/obj/item/weapon/reagent_containers/food/pill/P = new/obj/item/weapon/reagent_containers/food/pill(loc) - if(!name) name = reagents.get_master_reagent_name() - P.name = "[name] pill" - P.pixel_x = rand(-7, 7) //random position - P.pixel_y = rand(-7, 7) - P.icon_state = "pill"+pillsprite - reagents.trans_to(P,amount_per_pill) - if(loaded_pill_bottle) - if(loaded_pill_bottle.contents.len < loaded_pill_bottle.storage_slots) - P.forceMove(loaded_pill_bottle) - updateUsrDialog() - else - var/name = input(usr,"Name:","Name your bag!",reagents.get_master_reagent_name()) as text|null - if(!name) - return - name = reject_bad_text(name) - var/obj/item/weapon/reagent_containers/food/condiment/pack/P = new/obj/item/weapon/reagent_containers/food/condiment/pack(loc) - if(!name) name = reagents.get_master_reagent_name() - P.originalname = name - P.name = "[name] pack" - P.desc = "A small condiment pack. The label says it contains [name]." - reagents.trans_to(P,10) - else if(href_list["createpatch"] || href_list["createpatch_multiple"]) - if(!condi) - var/count = 1 - if(href_list["createpatch_multiple"]) - count = input("Select the number of patches to make.", 10, patchamount) as num|null - if(count == null) - return - count = isgoodnumber(count) - if(!count || count <= 0) - return - if(count > 20) count = 20 //Pevent people from creating huge stacks of patches easily. Maybe move the number to defines? - var/amount_per_patch = reagents.total_volume/count - if(amount_per_patch > 40) amount_per_patch = 40 - var/name = input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([amount_per_patch]u)") as text|null - if(!name) - return - name = reject_bad_text(name) - var/is_medical_patch = chemical_safety_check(reagents) - while(count--) - var/obj/item/weapon/reagent_containers/food/pill/patch/P = new/obj/item/weapon/reagent_containers/food/pill/patch(loc) - if(!name) name = reagents.get_master_reagent_name() - P.name = "[name] patch" - P.pixel_x = rand(-7, 7) //random position - P.pixel_y = rand(-7, 7) - reagents.trans_to(P,amount_per_patch) - if(is_medical_patch) - P.instant_application = 1 - P.icon_state = "bandaid_med" - else if(href_list["createbottle"]) - if(!condi) - var/name = input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()) as text|null - if(!name) - return - name = reject_bad_text(name) - var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(loc) - if(!name) name = reagents.get_master_reagent_name() - P.name = "[name] bottle" - P.pixel_x = rand(-7, 7) //random position - P.pixel_y = rand(-7, 7) - P.icon_state = bottlesprite - reagents.trans_to(P,30) - else - var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(loc) - reagents.trans_to(P,50) - else if(href_list["change_pill"]) - #define MAX_PILL_SPRITE 20 //max icon state of the pill sprites - var/dat = "" - var/j = 0 - for(var/i = 1 to MAX_PILL_SPRITE) - j++ - if(j == 1) - dat += "" - dat += "" - if(j == 5) - dat += "" - j = 0 - dat += "
" - usr << browse(dat, "window=chem_master_iconsel;size=225x193") - return - else if(href_list["change_bottle"]) - var/dat = "" - var/j = 0 - for(var/i in list("bottle", "small_bottle", "wide_bottle", "round_bottle")) - j++ - if(j == 1) - dat += "" - dat += "" - if(j == 5) - dat += "" - j = 0 - dat += "
" - usr << browse(dat, "window=chem_master_iconsel;size=225x193") - return - else if(href_list["pill_sprite"]) - pillsprite = href_list["pill_sprite"] - usr << browse(null, "window=chem_master_iconsel") - else if(href_list["bottle_sprite"]) - bottlesprite = href_list["bottle_sprite"] - usr << browse(null, "window=chem_master_iconsel") - - nanomanager.update_uis(src) - return - -/obj/machinery/chem_master/attack_ai(mob/user) - return attack_hand(user) - -/obj/machinery/chem_master/attack_ghost(mob/user) - return attack_hand(user) - -/obj/machinery/chem_master/attack_hand(mob/user) - if(..()) - return 1 - ui_interact(user) - return - -/obj/machinery/chem_master/ui_interact(mob/user, ui_key="main", datum/nanoui/ui = null, force_open = 1) - - var/datum/asset/chem_master/assets = get_asset_datum(/datum/asset/chem_master) - assets.send(user) - - var/data = list() - - data["condi"] = condi - data["loaded_pill_bottle"] = (loaded_pill_bottle ? 1 : 0) - if(loaded_pill_bottle) - data["loaded_pill_bottle_contents_len"] = loaded_pill_bottle.contents.len - data["loaded_pill_bottle_storage_slots"] = loaded_pill_bottle.storage_slots - - data["beaker"] = (beaker ? 1 : 0) - 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, "id" = R.id, "description" = R.description) - 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 - - ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) - if(!ui) - ui = new(user, src, ui_key, "chem_master.tmpl", name, 575, 400) - ui.set_initial_data(data) - ui.open() - -/obj/machinery/chem_master/proc/isgoodnumber(num) - if(isnum(num)) - if(num > 200) - num = 200 - else if(num < 0) - num = 1 - else - num = round(num) - return num - else - return 0 - -/obj/machinery/chem_master/proc/chemical_safety_check(datum/reagents/R) - var/all_safe = 1 - for(var/datum/reagent/A in R.reagent_list) - if(!safe_chem_list.Find(A.id)) - all_safe = 0 - return all_safe - -/obj/machinery/chem_master/condimaster - name = "\improper CondiMaster 3000" - condi = 1 - -/obj/machinery/chem_master/constructable - name = "ChemMaster 2999" - desc = "Used to seperate chemicals and distribute them in a variety of forms." - -/obj/machinery/chem_master/constructable/New() - ..() - component_parts = list() - component_parts += new /obj/item/weapon/circuitboard/chem_master(null) - component_parts += new /obj/item/weapon/stock_parts/manipulator(null) - component_parts += new /obj/item/weapon/stock_parts/console_screen(null) - component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(null) - component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(null) - -/obj/machinery/chem_master/constructable/attackby(obj/item/B, mob/user, params) - - if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", B)) - if(beaker) - beaker.forceMove(get_turf(src)) - beaker = null - reagents.clear_reagents() - if(loaded_pill_bottle) - loaded_pill_bottle.forceMove(get_turf(src)) - loaded_pill_bottle = null - return - - if(exchange_parts(user, B)) - return - - if(panel_open) - if(istype(B, /obj/item/weapon/crowbar)) - default_deconstruction_crowbar(B) - return 1 - else - to_chat(user, "You can't use the [name] while it's panel is opened!") - return 1 - else - ..() - -/obj/machinery/reagentgrinder - - name = "\improper All-In-One Grinder" - icon = 'icons/obj/kitchen.dmi' - icon_state = "juicer1" - layer = 2.9 - density = 1 - anchored = 1 - use_power = 1 - idle_power_usage = 5 - active_power_usage = 100 - var/inuse = 0 - var/obj/item/weapon/reagent_containers/beaker = null - var/limit = 10 - - //IMPORTANT NOTE! A negative number is a multiplier, a positive number is a flat amount to add. 0 means equal to the amount of the original reagent - var/list/blend_items = list ( - - //Sheets - /obj/item/stack/sheet/mineral/plasma = list("plasma_dust" = 20), - /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), - /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), - /obj/item/stack/sheet/mineral/tranquillite = list("nothing" = 20), - /obj/item/stack/sheet/mineral/silver = list("silver" = 20), - /obj/item/stack/sheet/mineral/gold = list("gold" = 20), - /obj/item/weapon/grown/novaflower = list("capsaicin" = 0), - - //archaeology! - ///obj/item/weapon/rocksliver = list("ground_rock" = 50), - - - //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! - /obj/item/weapon/reagent_containers/food = list(), - /obj/item/weapon/reagent_containers/honeycomb = list() - ) - - var/list/blend_tags = list ( - "nettle" = list("sacid" = 0), - "deathnettle" = list("facid" = 0), - "soybeans" = list("soymilk" = 0), - "tomato" = list("ketchup" = 0), - "wheat" = list("flour" = -5), - "rice" = list("rice" = -5), - "cherries" = list("cherryjelly" = 0), - ) - - var/list/juice_items = list ( - /obj/item/weapon/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), - ) - - var/list/juice_tags = list ( - "tomato" = list("tomatojuice" = 0), - "carrot" = list("carrotjuice" = 0), - "berries" = list("berryjuice" = 0), - "banana" = list("banana" = 0), - "potato" = list("potato" = 0), - "lemon" = list("lemonjuice" = 0), - "orange" = list("orangejuice" = 0), - "lime" = list("limejuice" = 0), - "poisonberries" = list("poisonberryjuice" = 0), - "grapes" = list("grapejuice" = 0), - "corn" = list("cornoil" = 0), - ) - - var/list/holdingitems = list() - -/obj/machinery/reagentgrinder/New() - ..() - beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) - return - -/obj/machinery/reagentgrinder/update_icon() - icon_state = "juicer"+num2text(!isnull(beaker)) - return - -/obj/machinery/reagentgrinder/attackby(obj/item/O, mob/user, params) - - if(istype(O,/obj/item/weapon/reagent_containers/glass) || \ - istype(O,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass) || \ - istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) - - if(beaker) - return 1 - else - if(!user.drop_item()) - to_chat(user, "[O] is stuck to you!") - return - beaker = O - O.forceMove(src) - update_icon() - updateUsrDialog() - return 0 - - if(holdingitems && holdingitems.len >= limit) - to_chat(usr, "The machine cannot hold anymore items.") - return 1 - - //Fill machine with a plantbag! - if(istype(O, /obj/item/weapon/storage/bag/plants)) - var/obj/item/weapon/storage/bag/plants/PB = O - for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in PB.contents) - PB.remove_from_storage(G, src) - holdingitems += G - if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill - to_chat(user, "You empty [PB] into the All-In-One grinder.") - - updateUsrDialog() - return 0 - - - if(!is_type_in_list(O, blend_items) && !is_type_in_list(O, juice_items)) - to_chat(user, "Cannot refine into a reagent.") - return 1 - - user.unEquip(O) - O.forceMove(src) - holdingitems += O - updateUsrDialog() - return 0 - -/obj/machinery/reagentgrinder/attack_ai(mob/user) - return 0 - -/obj/machinery/reagentgrinder/attack_hand(mob/user) - user.set_machine(src) - interact(user) - -/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu - var/is_chamber_empty = 0 - var/is_beaker_ready = 0 - var/processing_chamber = "" - var/beaker_contents = "" - var/dat = "" - - if(!inuse) - for(var/obj/item/O in holdingitems) - processing_chamber += "\A [O.name]
" - - if(!processing_chamber) - is_chamber_empty = 1 - processing_chamber = "Nothing." - if(!beaker) - beaker_contents = "No beaker attached.
" - else - is_beaker_ready = 1 - beaker_contents = "The beaker contains:
" - var/anything = 0 - for(var/datum/reagent/R in beaker.reagents.reagent_list) - anything = 1 - beaker_contents += "[R.volume] - [R.name]
" - if(!anything) - beaker_contents += "Nothing
" - - - dat = {" - Processing chamber contains:
- [processing_chamber]
- [beaker_contents]
- "} - if(is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Grind the reagents
" - dat += "Juice the reagents

" - if(holdingitems && holdingitems.len > 0) - dat += "Eject the reagents
" - if(beaker) - dat += "Detach the beaker
" - else - dat += "Please wait..." - user << browse("All-In-One Grinder[dat]", "window=reagentgrinder") - onclose(user, "reagentgrinder") - return - -/obj/machinery/reagentgrinder/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - switch(href_list["action"]) - if("grind") - grind() - if("juice") - juice() - if("eject") - eject() - if("detach") - detach() - updateUsrDialog() - return - -/obj/machinery/reagentgrinder/proc/detach() - - if(usr.stat != 0) - return - if(!beaker) - return - beaker.forceMove(loc) - beaker = null - update_icon() - -/obj/machinery/reagentgrinder/proc/eject() - - if(usr.stat != 0) - return - if(holdingitems && holdingitems.len == 0) - return - - for(var/obj/item/O in holdingitems) - O.forceMove(loc) - holdingitems -= O - holdingitems = list() - -/obj/machinery/reagentgrinder/proc/is_allowed(obj/item/weapon/reagent_containers/O) - for(var/i in blend_items) - if(istype(O, i)) - return 1 - return 0 - -/obj/machinery/reagentgrinder/proc/get_allowed_by_id(obj/item/weapon/grown/O) - for(var/i in blend_items) - if(istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_snack_by_id(obj/item/weapon/reagent_containers/food/snacks/O) - for(var/i in blend_items) - if(istype(O, i)) - return blend_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_id(obj/item/weapon/reagent_containers/food/snacks/O) - for(var/i in juice_items) - if(istype(O, i)) - return juice_items[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_snack_by_tag(obj/item/weapon/reagent_containers/food/snacks/grown/O) - for(var/i in blend_tags) - if(O.seed.kitchen_tag == i) - return blend_tags[i] - -/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_tag(obj/item/weapon/reagent_containers/food/snacks/grown/O) - for(var/i in juice_tags) - if(O.seed.kitchen_tag == i) - return juice_tags[i] - -/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/weapon/grown/O) - if(!istype(O)) - return 5 - else if(O.potency == -1) - return 5 - else - return round(O.potency) - -/obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/weapon/reagent_containers/food/snacks/grown/O) - if(!istype(O)) - return 5 - else if(O.potency == -1) - return 5 - else - return round(5*sqrt(O.potency)) - -/obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) - holdingitems -= O - qdel(O) - -/obj/machinery/reagentgrinder/proc/juice() - power_change() - if(stat & (NOPOWER|BROKEN)) - return - if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) - return - playsound(loc, 'sound/machines/juicer.ogg', 20, 1) - var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking - inuse = 1 - spawn(50) - pixel_x = initial(pixel_x) //return to its spot after shaking - inuse = 0 - interact(usr) - //Snacks - for(var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - var/allowed = null - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) - allowed = get_allowed_juice_by_tag(O) - else - allowed = get_allowed_juice_by_id(O) - if(isnull(allowed)) - break - - for(var/r_id in allowed) - - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = get_juice_amount(O) - - beaker.reagents.add_reagent(r_id, min(amount, space)) - - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - remove_object(O) - -/obj/machinery/reagentgrinder/proc/grind() - - power_change() - if(stat & (NOPOWER|BROKEN)) - return - if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) - return - playsound(loc, 'sound/machines/blender.ogg', 50, 1) - var/offset = prob(50) ? -2 : 2 - animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking - inuse = 1 - spawn(60) - pixel_x = initial(pixel_x) //return to its spot after shaking - inuse = 0 - interact(usr) - //Snacks and Plants - for(var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - var/allowed = null - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) - allowed = get_allowed_snack_by_tag(O) - else - allowed = get_allowed_snack_by_id(O) - if(isnull(allowed)) - break - - for(var/r_id in allowed) - - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount <= 0) //Negative amounts are multipliers for the reagent amount (Example: "amount = -5" means "reagent_amount * 5") - if(amount == 0) - if(O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - if(O.reagents != null && O.reagents.has_reagent("plantmatter")) - beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("plantmatter"), space)) - O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) - else - if(O.reagents != null && O.reagents.has_reagent("nutriment")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) - O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) - if(O.reagents != null && O.reagents.has_reagent("plantmatter")) - beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("plantmatter")*abs(amount)), space)) - O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) - - else - O.reagents.trans_id_to(beaker, r_id, min(amount, space)) - - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - - if(O.reagents.reagent_list.len == 0) - remove_object(O) - - //Sheets - for(var/obj/item/stack/sheet/O in holdingitems) - var/allowed = get_allowed_by_id(O) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - for(var/i = 1; i <= round(O.amount, 1); i++) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space)) - if(space < amount) - break - if(i == round(O.amount, 1)) - remove_object(O) - break - //Plants - for(var/obj/item/weapon/grown/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/allowed = get_allowed_by_id(O) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - if(amount == 0) - if(O.reagents != null && O.reagents.has_reagent(r_id)) - beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) - else - beaker.reagents.add_reagent(r_id,min(amount, space)) - - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O) - - //xenoarch - /*for(var/obj/item/weapon/rocksliver/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/allowed = get_allowed_by_id(O) - for(var/r_id in allowed) - var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume - var/amount = allowed[r_id] - beaker.reagents.add_reagent(r_id,min(amount, space), O.geological_data) - - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - remove_object(O)*/ - - //Everything else - Transfers reagents from it into beaker - for(var/obj/item/weapon/reagent_containers/O in holdingitems) - if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) - break - var/amount = O.reagents.total_volume - O.reagents.trans_to(beaker, amount) - if(!O.reagents.total_volume) +#define SOLID 1 +#define LIQUID 2 +#define GAS 3 + +/obj/machinery/chem_dispenser + name = "chem dispenser" + density = 1 + anchored = 1 + icon = 'icons/obj/chemical.dmi' + icon_state = "dispenser" + use_power = 0 + idle_power_usage = 40 + var/ui_title = "Chem Dispenser 5000" + var/energy = 100 + var/max_energy = 100 + var/amount = 30 + var/obj/item/weapon/reagent_containers/beaker = null + var/recharged = 0 + var/hackedcheck = 0 + var/list/dispensable_reagents = list("hydrogen", "lithium", "carbon", "nitrogen", "oxygen", "fluorine", + "sodium", "aluminum", "silicon", "phosphorus", "sulfur", "chlorine", "potassium", "iron", + "copper", "mercury", "plasma", "radium", "water", "ethanol", "sugar", "iodine", "bromine", "silver") + var/list/hacked_reagents = list("toxin") + var/hack_message = "You disable the safety safeguards, enabling the \"Mad Scientist\" mode." + var/unhack_message = "You re-enable the safety safeguards, enabling the \"NT Standard\" mode." + var/list/broken_requirements = list() + var/broken_on_spawn = 0 + var/recharge_delay = 5 + var/image/icon_beaker = null //cached overlay + + +/obj/machinery/chem_dispenser/proc/recharge() + if(stat & (BROKEN|NOPOWER)) return + var/addenergy = 1 + var/oldenergy = energy + energy = min(energy + addenergy, max_energy) + if(energy != oldenergy) + use_power(1500) // This thing uses up alot of power (this is still low as shit for creating reagents from thin air) + nanomanager.update_uis(src) // update all UIs attached to src + +/obj/machinery/chem_dispenser/power_change() + if(powered()) + stat &= ~NOPOWER + else + spawn(rand(0, 15)) + stat |= NOPOWER + nanomanager.update_uis(src) // update all UIs attached to src + +/obj/machinery/chem_dispenser/process() + + if(recharged < 0) + recharge() + recharged = recharge_delay + else + recharged -= 1 + +/obj/machinery/chem_dispenser/New() + ..() + recharge() + dispensable_reagents = sortList(dispensable_reagents) + + if(broken_on_spawn) + overlays.Cut() + var/amount = pick(3,3,4) + var/list/options = list() + options[/obj/item/weapon/stock_parts/capacitor/adv] = "Add an advanced capacitor to fix it." + options[/obj/item/weapon/stock_parts/console_screen] = "Replace the console screen to fix it." + options[/obj/item/weapon/stock_parts/manipulator/pico] = "Upgrade to a pico manipulator to fix it." + options[/obj/item/weapon/stock_parts/matter_bin/super] = "Give it a super matter bin to fix it." + options[/obj/item/weapon/stock_parts/cell/super] = "Replace the reagent synthesizer with a super capacity cell to fix it." + options[/obj/item/device/mass_spectrometer/adv] = "Replace the reagent scanner with an advanced mass spectrometer to fix it" + options[/obj/item/weapon/stock_parts/micro_laser/high] = "Repair the reagent synthesizer with an high-power micro-laser to fix it" + options[/obj/item/device/reagent_scanner/adv] = "Replace the reagent scanner with an advanced reagent scanner to fix it" + options[/obj/item/stack/nanopaste] = "Apply some nanopaste to the broken nozzles to fix it." + options[/obj/item/stack/sheet/plasteel] = "Surround the outside with a plasteel cover to fix it." + options[/obj/item/stack/sheet/rglass] = "Insert a pane of reinforced glass to fix it." + + while(amount > 0) + amount -= 1 + + var/index = pick(options) + broken_requirements[index] = options[index] + options -= index + + +/obj/machinery/chem_dispenser/ex_act(severity) + switch(severity) + if(1.0) + qdel(src) + return + if(2.0) + if(prob(50)) + qdel(src) + return + +/obj/machinery/chem_dispenser/blob_act() + if(prob(50)) + qdel(src) + + /** + * The ui_interact proc is used to open and update Nano UIs + * If ui_interact is not used then the UI will not update correctly + * ui_interact is currently defined for /atom/movable + * + * @param user /mob The mob who is interacting with this ui + * @param ui_key string A string key to use for this ui. Allows for multiple unique uis on one obj/mob (defaut value "main") + * + * @return nothing + */ + +/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) + if(broken_requirements.len) + to_chat(user, "[src] is broken. [broken_requirements[broken_requirements[1]]]") + return + + + // this is the data which will be sent to the ui + var/data[0] + data["amount"] = amount + data["energy"] = round(energy) + data["maxEnergy"] = round(max_energy) + data["isBeakerLoaded"] = beaker ? 1 : 0 + + var beakerContents[0] + var beakerCurrentVolume = 0 + if(beaker && beaker.reagents && beaker.reagents.reagent_list.len) + for(var/datum/reagent/R in beaker.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... + beakerCurrentVolume += R.volume + data["beakerContents"] = beakerContents + + if(beaker) + data["beakerCurrentVolume"] = beakerCurrentVolume + data["beakerMaxVolume"] = beaker.volume + else + data["beakerCurrentVolume"] = null + data["beakerMaxVolume"] = null + + var chemicals[0] + for(var/re in dispensable_reagents) + var/datum/reagent/temp = chemical_reagents_list[re] + if(temp) + chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("dispense" = temp.id)))) // list in a list because Byond merges the first list... + data["chemicals"] = chemicals + + // update the ui if it exists, returns null if no ui is passed/found + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + // the ui does not exist, so we'll create a new() one + // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm + ui = new(user, src, ui_key, "chem_dispenser.tmpl", ui_title, 390, 655) + // when the ui is first opened this is the data it will use + ui.set_initial_data(data) + // open the new ui window + ui.open() + +/obj/machinery/chem_dispenser/Topic(href, href_list) + if(..()) + return 1 + + if(href_list["amount"]) + amount = round(text2num(href_list["amount"]), 5) // round to nearest 5 + if(amount < 0) // Since the user can actually type the commands himself, some sanity checking + amount = 0 + if(amount > 100) + amount = 100 + + if(href_list["dispense"]) + if(dispensable_reagents.Find(href_list["dispense"]) && beaker != null) + var/obj/item/weapon/reagent_containers/glass/B = beaker + var/datum/reagents/R = B.reagents + var/space = R.maximum_volume - R.total_volume + + R.add_reagent(href_list["dispense"], min(amount, energy * 10, space)) + energy = max(energy - min(amount, energy * 10, space) / 10, 0) + overlays.Cut() + icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. + icon_beaker.pixel_x = rand(-10,5) + overlays += icon_beaker + + if(href_list["remove"]) + if(beaker) + if(href_list["removeamount"]) + var/amount = text2num(href_list["removeamount"]) + if(isnum(amount) && (amount > 0)) + var/obj/item/weapon/reagent_containers/glass/B = beaker + var/datum/reagents/R = B.reagents + var/id = href_list["remove"] + R.remove_reagent(id, amount) + + if(href_list["ejectBeaker"]) + if(beaker) + var/obj/item/weapon/reagent_containers/glass/B = beaker + B.forceMove(loc) + beaker = null + overlays.Cut() + add_fingerprint(usr) + return 1 // update UIs attached to this object + +/obj/machinery/chem_dispenser/attackby(obj/item/weapon/reagent_containers/B, mob/user, params) + if(isrobot(user)) + return + + if(broken_requirements.len && B.type == broken_requirements[1]) + if(istype(B,/obj/item/stack)) + var/obj/item/stack/S = B + S.use(1) + else + if(!user.drop_item()) + to_chat(user, "[B] is stuck to you!") + return + qdel(B) + broken_requirements -= broken_requirements[1] + to_chat(user, "You fix [src].") + return + + if(beaker) + to_chat(user, "Something is already loaded into the machine.") + return + + if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food/drinks)) + beaker = B + if(!user.drop_item()) + to_chat(user, "[B] is stuck to you!") + return + B.forceMove(src) + to_chat(user, "You set [B] on the machine.") + nanomanager.update_uis(src) // update all UIs attached to src + if(!icon_beaker) + icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position. + icon_beaker.pixel_x = rand(-10,5) + overlays += icon_beaker + return + +/obj/machinery/chem_dispenser/attackby(obj/item/weapon/B, mob/user, params) + ..() + if(istype(B, /obj/item/device/multitool)) + if(hackedcheck == 0) + to_chat(user, hack_message) + dispensable_reagents += hacked_reagents + hackedcheck = 1 + return + + else + to_chat(user, unhack_message) + dispensable_reagents -= hacked_reagents + hackedcheck = 0 + return + +/obj/machinery/chem_dispenser/attack_ai(mob/user) + return attack_hand(user) + +/obj/machinery/chem_dispenser/attack_ghost(mob/user) + return attack_hand(user) + +/obj/machinery/chem_dispenser/attack_hand(mob/user) + if(stat & BROKEN) + return + + ui_interact(user) + +/obj/machinery/chem_dispenser/soda + icon_state = "soda_dispenser" + name = "soda fountain" + desc = "A drink fabricating machine, capable of producing many sugary drinks with just one touch." + ui_title = "Soda Dispens-o-matic" + energy = 100 + max_energy = 100 + dispensable_reagents = list("water", "ice", "milk", "soymilk", "coffee", "tea", "hot_coco", "cola", "spacemountainwind", "dr_gibb", "space_up", + "tonic", "sodawater", "lemon_lime", "grapejuice", "sugar", "orangejuice", "lemonjuice", "limejuice", "tomatojuice", "banana", + "watermelonjuice", "carrotjuice", "potato", "berryjuice") + hack_message = "You change the mode from 'McNano' to 'Pizza King'." + unhack_message = "You change the mode from 'Pizza King' to 'McNano'." + hacked_reagents = list("thirteenloko") + +/obj/machinery/chem_dispenser/beer + icon_state = "booze_dispenser" + name = "booze dispenser" + ui_title = "Booze Portal 9001" + energy = 100 + max_energy = 100 + desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one." + dispensable_reagents = list("ice", "cream", "cider", "beer", "kahlua", "whiskey", "wine", "vodka", "gin", "rum", "tequila", "vermouth", "cognac", "ale", "mead", "synthanol") + hack_message = "You disable the 'nanotrasen-are-cheap-bastards' lock, enabling hidden and very expensive boozes." + unhack_message = "You re-enable the 'nanotrasen-are-cheap-bastards' lock, disabling hidden and very expensive boozes." + hacked_reagents = list("goldschlager", "patron", "absinthe", "ethanol", "nothing") + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/obj/machinery/chem_dispenser/constructable + name = "portable chem dispenser" + icon = 'icons/obj/chemical.dmi' + icon_state = "minidispenser" + energy = 5 + max_energy = 5 + amount = 5 + recharge_delay = 10 + dispensable_reagents = list() + var/list/special_reagents = list(list("hydrogen", "oxygen", "silicon", "phosphorus", "sulfur", "carbon", "nitrogen", "water"), + list("lithium", "sugar", "copper", "mercury", "sodium","iodine","bromine"), + list("ethanol", "chlorine", "potassium", "aluminum","plasma", "radium", "fluorine", "iron", "silver"), + list("oil", "ash", "acetone", "saltpetre", "ammonia", "diethylamine", "fuel")) + +/obj/machinery/chem_dispenser/constructable/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/chem_dispenser(null) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) + component_parts += new /obj/item/weapon/stock_parts/matter_bin(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/weapon/stock_parts/capacitor(null) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + component_parts += new /obj/item/weapon/stock_parts/cell/super(null) + RefreshParts() + +/obj/machinery/chem_dispenser/constructable/upgraded/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/chem_dispenser(null) + component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null) + component_parts += new /obj/item/weapon/stock_parts/matter_bin/super(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator/pico(null) + component_parts += new /obj/item/weapon/stock_parts/capacitor/super(null) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + component_parts += new /obj/item/weapon/stock_parts/cell/hyper(null) + RefreshParts() + +/obj/machinery/chem_dispenser/constructable/RefreshParts() + var/time = 0 + var/temp_energy = 0 + var/i + for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts) + temp_energy += M.rating + temp_energy-- + max_energy = temp_energy * 5 //max energy = (bin1.rating + bin2.rating - 1) * 5, 5 on lowest 25 on highest + for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts) + time += C.rating + for(var/obj/item/weapon/stock_parts/cell/P in component_parts) + time += round(P.maxcharge, 10000) / 10000 + recharge_delay = 10 / (time/2) //delay between recharges, double the usual time on lowest 33% less than usual on highest + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + for(i=1, i<=M.rating, i++) + dispensable_reagents = sortList(dispensable_reagents | special_reagents[i]) + +/obj/machinery/chem_dispenser/constructable/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/reagent_containers/glass)) + if(panel_open) + to_chat(user, "Close the maintenance panel first.") + return + ..() + else + ..() + + if(default_deconstruction_screwdriver(user, "minidispenser-o", "minidispenser", I)) + return + + if(exchange_parts(user, I)) + return + + if(istype(I, /obj/item/weapon/wrench)) + playsound(src, 'sound/items/Ratchet.ogg', 50, 1) + if(anchored) + anchored = 0 + to_chat(user, "[src] can now be moved.") + else if(!anchored) + anchored = 1 + to_chat(user, "[src] is now secured.") + + if(panel_open) + if(istype(I, /obj/item/weapon/crowbar)) + if(beaker) + var/obj/item/weapon/reagent_containers/glass/B = beaker + B.forceMove(loc) + beaker = null + default_deconstruction_crowbar(I) + return 1 + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/obj/machinery/chem_master + name = "\improper ChemMaster 3000" + density = 1 + anchored = 1 + icon = 'icons/obj/chemical.dmi' + icon_state = "mixer0" + use_power = 1 + 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 = 30 // Last used amount + var/pillamount = 10 + var/patchamount = 10 + var/bottlesprite = "bottle" + var/pillsprite = "1" + var/client/has_sprites = list() + var/printing = null + +/obj/machinery/chem_master/New() + var/datum/reagents/R = new/datum/reagents(100) + reagents = R + R.my_atom = src + overlays += "waitlight" + +/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/blob_act() + if(prob(50)) + qdel(src) + +/obj/machinery/chem_master/power_change() + if(powered()) + stat &= ~NOPOWER + else + spawn(rand(0, 15)) + stat |= NOPOWER + +/obj/machinery/chem_master/attackby(obj/item/weapon/B, mob/user, params) + + if(istype(B, /obj/item/weapon/reagent_containers/glass) || istype(B, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass)) + + if(beaker) + to_chat(user, "A beaker is already loaded into the machine.") + return + if(!user.drop_item()) + to_chat(user, "[B] is stuck to you!") + return + beaker = B + B.forceMove(src) + to_chat(user, "You add the beaker to the machine!") + nanomanager.update_uis(src) + icon_state = "mixer1" + + else if(istype(B, /obj/item/weapon/storage/pill_bottle)) + + if(loaded_pill_bottle) + to_chat(user, "A pill bottle is already loaded into the machine.") + return + + if(!user.drop_item()) + to_chat(user, "[B] is stuck to you!") + return + loaded_pill_bottle = B + B.forceMove(src) + to_chat(user, "You add the pill bottle into the dispenser slot!") + nanomanager.update_uis(src) + return + +/obj/machinery/chem_master/Topic(href, href_list) + if(..()) + return 1 + + add_fingerprint(usr) + usr.set_machine(src) + + + if(href_list["ejectp"]) + if(loaded_pill_bottle) + loaded_pill_bottle.forceMove(loc) + loaded_pill_bottle = null + else if(href_list["close"]) + usr << browse(null, "window=chem_master") + onclose(usr, "chem_master") + usr.unset_machine() + return + + if(href_list["print_p"]) + if(!(printing)) + printing = 1 + 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: [worldtime2text(world.time)]

" + P.info += "Chemical name: [href_list["name"]]
" + if(href_list["name"] == "Blood") + var/datum/reagents/R = beaker.reagents + var/datum/reagent/blood/G + for(var/datum/reagent/F in R.reagent_list) + if(F.name == href_list["name"]) + G = F + break + var/B = G.data["blood_type"] + var/C = G.data["blood_DNA"] + P.info += "Description:
Blood Type: [B]
DNA: [C]" + else + P.info += "Description: [href_list["desc"]]" + P.info += "

Notes:
" + P.name = "Chemical Analysis - [href_list["name"]]" + printing = null + + if(beaker) + var/datum/reagents/R = beaker.reagents + if(href_list["analyze"]) + var/dat = "" + if(!condi) + if(href_list["name"] == "Blood") + var/datum/reagent/blood/G + for(var/datum/reagent/F in R.reagent_list) + if(F.name == href_list["name"]) + G = F + break + var/A = G.name + var/B = G.data["blood_type"] + var/C = G.data["blood_DNA"] + dat += "Chemmaster 3000Chemical infos:

Name:
[A]

Description:
Blood Type: [B]
DNA: [C]" + else + dat += "Chemmaster 3000Chemical infos:

Name:
[href_list["name"]]

Description:
[href_list["desc"]]" + dat += "

(Print Analysis)
" + dat += "(Back)" + else + dat += "Condimaster 3000Condiment infos:

Name:
[href_list["name"]]

Description:
[href_list["desc"]]


(Back)" + usr << browse(dat, "window=chem_master;size=575x400") + return + + else if(href_list["add"]) + + if(href_list["amount"]) + var/id = href_list["add"] + var/amount = text2num(href_list["amount"]) + R.trans_id_to(src, id, amount) + + else if(href_list["addcustom"]) + + var/id = href_list["addcustom"] + useramount = input("Select the amount to transfer.", 30, useramount) as num + useramount = isgoodnumber(useramount) + Topic(null, list("amount" = "[useramount]", "add" = "[id]")) + + else if(href_list["remove"]) + + if(href_list["amount"]) + var/id = href_list["remove"] + var/amount = text2num(href_list["amount"]) + if(mode) + reagents.trans_id_to(beaker, id, amount) + else + reagents.remove_reagent(id, amount) + + + else if(href_list["removecustom"]) + + var/id = href_list["removecustom"] + useramount = input("Select the amount to transfer.", 30, useramount) as num + useramount = isgoodnumber(useramount) + Topic(null, list("amount" = "[useramount]", "remove" = "[id]")) + + else if(href_list["toggle"]) + mode = !mode + + else if(href_list["main"]) + attack_hand(usr) + return + else if(href_list["eject"]) + if(beaker) + beaker.forceMove(get_turf(src)) + beaker = null + reagents.clear_reagents() + icon_state = "mixer0" + else if(href_list["createpill"] || href_list["createpill_multiple"]) + if(!condi) + var/count = 1 + if(href_list["createpill_multiple"]) + count = input("Select the number of pills to make.", 10, pillamount) as num|null + if(count == null) + return + count = isgoodnumber(count) + if(count > 20) count = 20 //Pevent people from creating huge stacks of pills easily. Maybe move the number to defines? + if(count <= 0) return + var/amount_per_pill = reagents.total_volume/count + if(amount_per_pill > 50) amount_per_pill = 50 + var/name = input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill]u)") as text|null + if(!name) + return + name = reject_bad_text(name) + while(count--) + var/obj/item/weapon/reagent_containers/food/pill/P = new/obj/item/weapon/reagent_containers/food/pill(loc) + if(!name) name = reagents.get_master_reagent_name() + P.name = "[name] pill" + P.pixel_x = rand(-7, 7) //random position + P.pixel_y = rand(-7, 7) + P.icon_state = "pill"+pillsprite + reagents.trans_to(P,amount_per_pill) + if(loaded_pill_bottle) + if(loaded_pill_bottle.contents.len < loaded_pill_bottle.storage_slots) + P.forceMove(loaded_pill_bottle) + updateUsrDialog() + else + var/name = input(usr,"Name:","Name your bag!",reagents.get_master_reagent_name()) as text|null + if(!name) + return + name = reject_bad_text(name) + var/obj/item/weapon/reagent_containers/food/condiment/pack/P = new/obj/item/weapon/reagent_containers/food/condiment/pack(loc) + if(!name) name = reagents.get_master_reagent_name() + P.originalname = name + P.name = "[name] pack" + P.desc = "A small condiment pack. The label says it contains [name]." + reagents.trans_to(P,10) + else if(href_list["createpatch"] || href_list["createpatch_multiple"]) + if(!condi) + var/count = 1 + if(href_list["createpatch_multiple"]) + count = input("Select the number of patches to make.", 10, patchamount) as num|null + if(count == null) + return + count = isgoodnumber(count) + if(!count || count <= 0) + return + if(count > 20) count = 20 //Pevent people from creating huge stacks of patches easily. Maybe move the number to defines? + var/amount_per_patch = reagents.total_volume/count + if(amount_per_patch > 40) amount_per_patch = 40 + var/name = input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([amount_per_patch]u)") as text|null + if(!name) + return + name = reject_bad_text(name) + var/is_medical_patch = chemical_safety_check(reagents) + while(count--) + var/obj/item/weapon/reagent_containers/food/pill/patch/P = new/obj/item/weapon/reagent_containers/food/pill/patch(loc) + if(!name) name = reagents.get_master_reagent_name() + P.name = "[name] patch" + P.pixel_x = rand(-7, 7) //random position + P.pixel_y = rand(-7, 7) + reagents.trans_to(P,amount_per_patch) + if(is_medical_patch) + P.instant_application = 1 + P.icon_state = "bandaid_med" + else if(href_list["createbottle"]) + if(!condi) + var/name = input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()) as text|null + if(!name) + return + name = reject_bad_text(name) + var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(loc) + if(!name) name = reagents.get_master_reagent_name() + P.name = "[name] bottle" + P.pixel_x = rand(-7, 7) //random position + P.pixel_y = rand(-7, 7) + P.icon_state = bottlesprite + reagents.trans_to(P,30) + else + var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(loc) + reagents.trans_to(P,50) + else if(href_list["change_pill"]) + #define MAX_PILL_SPRITE 20 //max icon state of the pill sprites + var/dat = "" + var/j = 0 + for(var/i = 1 to MAX_PILL_SPRITE) + j++ + if(j == 1) + dat += "" + dat += "" + if(j == 5) + dat += "" + j = 0 + dat += "
" + usr << browse(dat, "window=chem_master_iconsel;size=225x193") + return + else if(href_list["change_bottle"]) + var/dat = "" + var/j = 0 + for(var/i in list("bottle", "small_bottle", "wide_bottle", "round_bottle")) + j++ + if(j == 1) + dat += "" + dat += "" + if(j == 5) + dat += "" + j = 0 + dat += "
" + usr << browse(dat, "window=chem_master_iconsel;size=225x193") + return + else if(href_list["pill_sprite"]) + pillsprite = href_list["pill_sprite"] + usr << browse(null, "window=chem_master_iconsel") + else if(href_list["bottle_sprite"]) + bottlesprite = href_list["bottle_sprite"] + usr << browse(null, "window=chem_master_iconsel") + + nanomanager.update_uis(src) + return + +/obj/machinery/chem_master/attack_ai(mob/user) + return attack_hand(user) + +/obj/machinery/chem_master/attack_ghost(mob/user) + return attack_hand(user) + +/obj/machinery/chem_master/attack_hand(mob/user) + if(..()) + return 1 + ui_interact(user) + return + +/obj/machinery/chem_master/ui_interact(mob/user, ui_key="main", datum/nanoui/ui = null, force_open = 1) + + var/datum/asset/chem_master/assets = get_asset_datum(/datum/asset/chem_master) + assets.send(user) + + var/data = list() + + data["condi"] = condi + data["loaded_pill_bottle"] = (loaded_pill_bottle ? 1 : 0) + if(loaded_pill_bottle) + data["loaded_pill_bottle_contents_len"] = loaded_pill_bottle.contents.len + data["loaded_pill_bottle_storage_slots"] = loaded_pill_bottle.storage_slots + + data["beaker"] = (beaker ? 1 : 0) + 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, "id" = R.id, "description" = R.description) + 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 + + ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open) + if(!ui) + ui = new(user, src, ui_key, "chem_master.tmpl", name, 575, 400) + ui.set_initial_data(data) + ui.open() + +/obj/machinery/chem_master/proc/isgoodnumber(num) + if(isnum(num)) + if(num > 200) + num = 200 + else if(num < 0) + num = 1 + else + num = round(num) + return num + else + return 0 + +/obj/machinery/chem_master/proc/chemical_safety_check(datum/reagents/R) + var/all_safe = 1 + for(var/datum/reagent/A in R.reagent_list) + if(!safe_chem_list.Find(A.id)) + all_safe = 0 + return all_safe + +/obj/machinery/chem_master/condimaster + name = "\improper CondiMaster 3000" + condi = 1 + +/obj/machinery/chem_master/constructable + name = "ChemMaster 2999" + desc = "Used to seperate chemicals and distribute them in a variety of forms." + +/obj/machinery/chem_master/constructable/New() + ..() + component_parts = list() + component_parts += new /obj/item/weapon/circuitboard/chem_master(null) + component_parts += new /obj/item/weapon/stock_parts/manipulator(null) + component_parts += new /obj/item/weapon/stock_parts/console_screen(null) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(null) + component_parts += new /obj/item/weapon/reagent_containers/glass/beaker(null) + +/obj/machinery/chem_master/constructable/attackby(obj/item/B, mob/user, params) + + if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", B)) + if(beaker) + beaker.forceMove(get_turf(src)) + beaker = null + reagents.clear_reagents() + if(loaded_pill_bottle) + loaded_pill_bottle.forceMove(get_turf(src)) + loaded_pill_bottle = null + return + + if(exchange_parts(user, B)) + return + + if(panel_open) + if(istype(B, /obj/item/weapon/crowbar)) + default_deconstruction_crowbar(B) + return 1 + else + to_chat(user, "You can't use the [name] while it's panel is opened!") + return 1 + else + ..() + +/obj/machinery/reagentgrinder + + name = "\improper All-In-One Grinder" + icon = 'icons/obj/kitchen.dmi' + icon_state = "juicer1" + layer = 2.9 + density = 1 + anchored = 1 + use_power = 1 + idle_power_usage = 5 + active_power_usage = 100 + var/inuse = 0 + var/obj/item/weapon/reagent_containers/beaker = null + var/limit = 10 + + //IMPORTANT NOTE! A negative number is a multiplier, a positive number is a flat amount to add. 0 means equal to the amount of the original reagent + var/list/blend_items = list ( + + //Sheets + /obj/item/stack/sheet/mineral/plasma = list("plasma_dust" = 20), + /obj/item/stack/sheet/mineral/uranium = list("uranium" = 20), + /obj/item/stack/sheet/mineral/bananium = list("banana" = 20), + /obj/item/stack/sheet/mineral/tranquillite = list("nothing" = 20), + /obj/item/stack/sheet/mineral/silver = list("silver" = 20), + /obj/item/stack/sheet/mineral/gold = list("gold" = 20), + /obj/item/weapon/grown/novaflower = list("capsaicin" = 0), + + //archaeology! + ///obj/item/weapon/rocksliver = list("ground_rock" = 50), + + + //All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.! + /obj/item/weapon/reagent_containers/food = list(), + /obj/item/weapon/reagent_containers/honeycomb = list() + ) + + var/list/blend_tags = list ( + "nettle" = list("sacid" = 0), + "deathnettle" = list("facid" = 0), + "soybeans" = list("soymilk" = 0), + "tomato" = list("ketchup" = 0), + "wheat" = list("flour" = -5), + "rice" = list("rice" = -5), + "cherries" = list("cherryjelly" = 0), + ) + + var/list/juice_items = list ( + /obj/item/weapon/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0), + ) + + var/list/juice_tags = list ( + "tomato" = list("tomatojuice" = 0), + "carrot" = list("carrotjuice" = 0), + "berries" = list("berryjuice" = 0), + "banana" = list("banana" = 0), + "potato" = list("potato" = 0), + "lemon" = list("lemonjuice" = 0), + "orange" = list("orangejuice" = 0), + "lime" = list("limejuice" = 0), + "poisonberries" = list("poisonberryjuice" = 0), + "grapes" = list("grapejuice" = 0), + "corn" = list("cornoil" = 0), + ) + + var/list/holdingitems = list() + +/obj/machinery/reagentgrinder/New() + ..() + beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src) + return + +/obj/machinery/reagentgrinder/update_icon() + icon_state = "juicer"+num2text(!isnull(beaker)) + return + +/obj/machinery/reagentgrinder/attackby(obj/item/O, mob/user, params) + + if(istype(O,/obj/item/weapon/reagent_containers/glass) || \ + istype(O,/obj/item/weapon/reagent_containers/food/drinks/drinkingglass) || \ + istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker)) + + if(beaker) + return 1 + else + if(!user.drop_item()) + to_chat(user, "[O] is stuck to you!") + return + beaker = O + O.forceMove(src) + update_icon() + updateUsrDialog() + return 0 + + if(holdingitems && holdingitems.len >= limit) + to_chat(usr, "The machine cannot hold anymore items.") + return 1 + + //Fill machine with a plantbag! + if(istype(O, /obj/item/weapon/storage/bag/plants)) + var/obj/item/weapon/storage/bag/plants/PB = O + for(var/obj/item/weapon/reagent_containers/food/snacks/grown/G in PB.contents) + PB.remove_from_storage(G, src) + holdingitems += G + if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill + to_chat(user, "You empty [PB] into the All-In-One grinder.") + + updateUsrDialog() + return 0 + + + if(!is_type_in_list(O, blend_items) && !is_type_in_list(O, juice_items)) + to_chat(user, "Cannot refine into a reagent.") + return 1 + + user.unEquip(O) + O.forceMove(src) + holdingitems += O + updateUsrDialog() + return 0 + +/obj/machinery/reagentgrinder/attack_ai(mob/user) + return 0 + +/obj/machinery/reagentgrinder/attack_hand(mob/user) + user.set_machine(src) + interact(user) + +/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu + var/is_chamber_empty = 0 + var/is_beaker_ready = 0 + var/processing_chamber = "" + var/beaker_contents = "" + var/dat = "" + + if(!inuse) + for(var/obj/item/O in holdingitems) + processing_chamber += "\A [O.name]
" + + if(!processing_chamber) + is_chamber_empty = 1 + processing_chamber = "Nothing." + if(!beaker) + beaker_contents = "No beaker attached.
" + else + is_beaker_ready = 1 + beaker_contents = "The beaker contains:
" + var/anything = 0 + for(var/datum/reagent/R in beaker.reagents.reagent_list) + anything = 1 + beaker_contents += "[R.volume] - [R.name]
" + if(!anything) + beaker_contents += "Nothing
" + + + dat = {" + Processing chamber contains:
+ [processing_chamber]
+ [beaker_contents]
+ "} + if(is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) + dat += "Grind the reagents
" + dat += "Juice the reagents

" + if(holdingitems && holdingitems.len > 0) + dat += "Eject the reagents
" + if(beaker) + dat += "Detach the beaker
" + else + dat += "Please wait..." + user << browse("All-In-One Grinder[dat]", "window=reagentgrinder") + onclose(user, "reagentgrinder") + return + +/obj/machinery/reagentgrinder/Topic(href, href_list) + if(..()) + return + usr.set_machine(src) + switch(href_list["action"]) + if("grind") + grind() + if("juice") + juice() + if("eject") + eject() + if("detach") + detach() + updateUsrDialog() + return + +/obj/machinery/reagentgrinder/proc/detach() + + if(usr.stat != 0) + return + if(!beaker) + return + beaker.forceMove(loc) + beaker = null + update_icon() + +/obj/machinery/reagentgrinder/proc/eject() + + if(usr.stat != 0) + return + if(holdingitems && holdingitems.len == 0) + return + + for(var/obj/item/O in holdingitems) + O.forceMove(loc) + holdingitems -= O + holdingitems = list() + +/obj/machinery/reagentgrinder/proc/is_allowed(obj/item/weapon/reagent_containers/O) + for(var/i in blend_items) + if(istype(O, i)) + return 1 + return 0 + +/obj/machinery/reagentgrinder/proc/get_allowed_by_id(obj/item/weapon/grown/O) + for(var/i in blend_items) + if(istype(O, i)) + return blend_items[i] + +/obj/machinery/reagentgrinder/proc/get_allowed_snack_by_id(obj/item/weapon/reagent_containers/food/snacks/O) + for(var/i in blend_items) + if(istype(O, i)) + return blend_items[i] + +/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_id(obj/item/weapon/reagent_containers/food/snacks/O) + for(var/i in juice_items) + if(istype(O, i)) + return juice_items[i] + +/obj/machinery/reagentgrinder/proc/get_allowed_snack_by_tag(obj/item/weapon/reagent_containers/food/snacks/grown/O) + for(var/i in blend_tags) + if(O.seed.kitchen_tag == i) + return blend_tags[i] + +/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_tag(obj/item/weapon/reagent_containers/food/snacks/grown/O) + for(var/i in juice_tags) + if(O.seed.kitchen_tag == i) + return juice_tags[i] + +/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/weapon/grown/O) + if(!istype(O)) + return 5 + else if(O.potency == -1) + return 5 + else + return round(O.potency) + +/obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/weapon/reagent_containers/food/snacks/grown/O) + if(!istype(O)) + return 5 + else if(O.potency == -1) + return 5 + else + return round(5*sqrt(O.potency)) + +/obj/machinery/reagentgrinder/proc/remove_object(obj/item/O) + holdingitems -= O + qdel(O) + +/obj/machinery/reagentgrinder/proc/juice() + power_change() + if(stat & (NOPOWER|BROKEN)) + return + if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) + return + playsound(loc, 'sound/machines/juicer.ogg', 20, 1) + var/offset = prob(50) ? -2 : 2 + animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking + inuse = 1 + spawn(50) + pixel_x = initial(pixel_x) //return to its spot after shaking + inuse = 0 + interact(usr) + //Snacks + for(var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + + var/allowed = null + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) + allowed = get_allowed_juice_by_tag(O) + else + allowed = get_allowed_juice_by_id(O) + if(isnull(allowed)) + break + + for(var/r_id in allowed) + + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = get_juice_amount(O) + + beaker.reagents.add_reagent(r_id, min(amount, space)) + + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + + remove_object(O) + +/obj/machinery/reagentgrinder/proc/grind() + + power_change() + if(stat & (NOPOWER|BROKEN)) + return + if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume)) + return + playsound(loc, 'sound/machines/blender.ogg', 50, 1) + var/offset = prob(50) ? -2 : 2 + animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking + inuse = 1 + spawn(60) + pixel_x = initial(pixel_x) //return to its spot after shaking + inuse = 0 + interact(usr) + //Snacks and Plants + for(var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + + var/allowed = null + if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown)) + allowed = get_allowed_snack_by_tag(O) + else + allowed = get_allowed_snack_by_id(O) + if(isnull(allowed)) + break + + for(var/r_id in allowed) + + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = allowed[r_id] + if(amount <= 0) //Negative amounts are multipliers for the reagent amount (Example: "amount = -5" means "reagent_amount * 5") + if(amount == 0) + if(O.reagents != null && O.reagents.has_reagent("nutriment")) + beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space)) + O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) + if(O.reagents != null && O.reagents.has_reagent("plantmatter")) + beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("plantmatter"), space)) + O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) + else + if(O.reagents != null && O.reagents.has_reagent("nutriment")) + beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space)) + O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space)) + if(O.reagents != null && O.reagents.has_reagent("plantmatter")) + beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("plantmatter")*abs(amount)), space)) + O.reagents.remove_reagent("plantmatter", min(O.reagents.get_reagent_amount("plantmatter"), space)) + + else + O.reagents.trans_id_to(beaker, r_id, min(amount, space)) + + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + + if(O.reagents.reagent_list.len == 0) + remove_object(O) + + //Sheets + for(var/obj/item/stack/sheet/O in holdingitems) + var/allowed = get_allowed_by_id(O) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + for(var/i = 1; i <= round(O.amount, 1); i++) + for(var/r_id in allowed) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = allowed[r_id] + beaker.reagents.add_reagent(r_id,min(amount, space)) + if(space < amount) + break + if(i == round(O.amount, 1)) + remove_object(O) + break + //Plants + for(var/obj/item/weapon/grown/O in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/allowed = get_allowed_by_id(O) + for(var/r_id in allowed) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = allowed[r_id] + if(amount == 0) + if(O.reagents != null && O.reagents.has_reagent(r_id)) + beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space)) + else + beaker.reagents.add_reagent(r_id,min(amount, space)) + + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + remove_object(O) + + //xenoarch + /*for(var/obj/item/weapon/rocksliver/O in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/allowed = get_allowed_by_id(O) + for(var/r_id in allowed) + var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume + var/amount = allowed[r_id] + beaker.reagents.add_reagent(r_id,min(amount, space), O.geological_data) + + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + remove_object(O)*/ + + //Everything else - Transfers reagents from it into beaker + for(var/obj/item/weapon/reagent_containers/O in holdingitems) + if(beaker.reagents.total_volume >= beaker.reagents.maximum_volume) + break + var/amount = O.reagents.total_volume + O.reagents.trans_to(beaker, amount) + if(!O.reagents.total_volume) remove_object(O) \ No newline at end of file diff --git a/code/modules/reagents/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm similarity index 100% rename from code/modules/reagents/pandemic.dm rename to code/modules/reagents/chemistry/machinery/pandemic.dm diff --git a/code/modules/reagents/Chemistry-Readme.dm b/code/modules/reagents/chemistry/readme.dm similarity index 97% rename from code/modules/reagents/Chemistry-Readme.dm rename to code/modules/reagents/chemistry/readme.dm index cae0c31162c..1fe946a10d1 100644 --- a/code/modules/reagents/Chemistry-Readme.dm +++ b/code/modules/reagents/chemistry/readme.dm @@ -1,249 +1,249 @@ -/* -NOTE: IF YOU UPDATE THE REAGENT-SYSTEM, ALSO UPDATE THIS README. - -Structure: /////////////////// ////////////////////////// - // Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents. - /////////////////// ////////////////////////// - | | - The object that holds everything. V - reagent_list var (list) A List of datums, each datum is a reagent. - - | | | - V V V - - reagents (datums) Reagents. I.e. Water , antitoxins or mercury. - - -Random important notes: - - An objects on_reagent_change will be called every time the objects reagents change. - Useful if you want to update the objects icon etc. - -About the Holder: - - The holder (reagents datum) is the datum that holds a list of all reagents - currently in the object.It also has all the procs needed to manipulate reagents - - remove_any(amount) - This proc removes reagents from the holder until the passed amount - is matched. It'll try to remove some of ALL reagents contained. - - trans_to(obj/target, amount) - This proc equally transfers the contents of the holder to another - objects holder. You need to pass it the object (not the holder) you want - to transfer to and the amount you want to transfer. Its return value is the - actual amount transfered (if one of the objects is full/empty) - - trans_id_to(obj/target, reagent, amount) - Same as above but only for a specific reagent in the reagent list. - If the specified amount is greater than what is available, it will use - the amount of the reagent that is available. If no reagent exists, returns null. - - metabolize(mob/living/M) - This proc is called by the mobs life proc. It simply calls on_mob_life for - all contained reagents. You shouldnt have to use this one directly. - - handle_reactions() - This proc check all recipes and, on a match, uses them. - It will also call the recipe's on_reaction proc (for explosions or w/e). - Currently, this proc is automatically called by trans_to. - - Modified from the original to preserve reagent data across reactions (originally for xenoarchaeology) - - isolate_reagent(reagent) - Pass it a reagent id and it will remove all reagents but that one. - It's that simple. - - del_reagent(reagent) - Completely remove the reagent with the matching id. - - update_total() - This one simply updates the total volume of the holder. - (the volume of all reagents added together) - - clear_reagents() - This proc removes ALL reagents from the holder. - - reaction(atom/A, method=TOUCH, volume_modifier=0) - This proc calls the appropriate reaction procs of the reagents. - I.e. if A is an object, it will call the reagents reaction_obj - proc. The method var is used for reaction on mobs. It simply tells - us if the mob TOUCHed the reagent or if it INGESTed the reagent. - Since the volume can be checked in a reagents proc, you might want to - use the volume_modifier var to modifiy the passed value without actually - changing the volume of the reagents. - If you're not sure if you need to use this the answer is very most likely 'No'. - You'll want to use this proc whenever an atom first comes in - contact with the reagents of a holder. (in the 'splash' part of a beaker i.e.) - More on the reaction in the reagent part of this readme. - - add_reagent(reagent, amount, data) - Attempts to add X of the matching reagent to the holder. - You wont use this much. Mostly in new procs for pre-filled - objects. - - remove_reagent(reagent, amount) - The exact opposite of the add_reagent proc. - - Modified from original to return the reagent's data, in order to preserve reagent data across reactions (originally for xenoarchaeology) - - has_reagent(reagent, amount) - Returns 1 if the holder contains this reagent. - Or 0 if not. - If you pass it an amount it will additionally check - if the amount is matched. This is optional. - - get_reagent_amount(reagent) - Returns the amount of the matching reagent inside the - holder. Returns 0 if the reagent is missing. - - overdose_list() - Returns a list of all the chemical IDs in the reagent holder that are overdosing - - Important variables: - - total_volume - This variable contains the total volume of all reagents in this holder. - - reagent_list - This is a list of all contained reagents. More specifically, references - to the reagent datums. - - maximum_volume - This is the maximum volume of the holder. - - my_atom - This is the atom the holder is 'in'. Useful if you need to find the location. - (i.e. for explosions) - - -About Reagents: - - Reagents are all the things you can mix and fille in bottles etc. This can be anything from - rejuvs over water to ... iron. Each reagent also has a few procs - i'll explain those below. - - reaction_mob(mob/living/M, method=TOUCH) - This is called by the holder's reation proc. - This version is only called when the reagent - reacts with a mob. The method var can be either - TOUCH or INGEST. You'll want to put stuff like - acid-facemelting in here. Should only ever be - called, directly, on living mobs. - - reaction_obj(obj/O) - This is called by the holder's reation proc. - This version is called when the reagents reacts - with an object. You'll want to put stuff like - object melting in here ... or something. i dunno. - - reaction_turf(turf/T) - This is called by the holder's reation proc. - This version is called when the reagents reacts - with a turf. You'll want to put stuff like extra - slippery floors for lube or something in here. - - on_mob_life(mob/living/M) - This proc is called everytime the mobs life proc executes. - This is the place where you put damage for toxins , - drowsyness for sleep toxins etc etc. - You'll want to call the parents proc by using ..() . - If you dont, the chemical will stay in the mob forever - - unless you write your own piece of code to slowly remove it. - (Should be pretty easy, 1 line of code) - - Important variables: - - holder - This variable contains a reference to the holder the chemical is 'in' - - volume - This is the volume of the reagent. - - id - The id of the reagent - - name - The name of the reagent. - - data - This var can be used for whatever the fuck you want.You could use this - for DNA in a blood reagent or ... well whatever you want. - - color - This is a hexadecimal color that represents the reagent outside of containers, - you define it as "#RRGGBB", or, red green blue. You can also define it using the - rgb() proc, which returns a hexadecimal value too. The color is black by default. - - A good website for color calculations: http://www.psyclops.com/tools/rgb/ - - - - -About Recipes: - - Recipes are simple datums that contain a list of required reagents and a result. - They also have a proc that is called when the recipe is matched. - - on_reaction(datum/reagents/holder, created_volume) - This proc is called when the recipe is matched. - You'll want to add explosions etc here. - To find the location you'll have to do something - like get_turf(holder.my_atom) - - name & id - Should be pretty obvious. - - result - This var contains the id of the resulting reagent. - - required_reagents - This is a list of ids of the required reagents. - Each id also needs an associated value that gives us the minimum required amount - of that reagent. The handle_reaction proc can detect mutiples of the same recipes - so for most cases you want to set the required amount to 1. - - required_catalysts (Added May 2011) - This is a list of the ids of the required catalysts. - Functionally similar to required_reagents, it is a list of reagents that are required - for the reaction. However, unlike required_reagents, catalysts are NOT consumed. - They mearly have to be present in the container. - - result_amount - This is the amount of the resulting reagent this recipe will produce. - I recommend you set this to the total volume of all required reagent. - - required_container - The container the recipe has to take place in in order to happen. Leave this blank/null - if you want the reaction to happen anywhere. - - required_other - Basically like a reagent's data variable. You can set extra requirements for a - reaction with this. - - -About the Tools: - - By default, all atom have a reagents var - but its empty. if you want to use an object for the chem. - system you'll need to add something like this in its new proc: - - var/datum/reagents/R = new/datum/reagents(100), <<< create a new datum, 100 is the maximum_volume of the new holder datum. - reagents = R, <<< assign the new datum to the objects reagents var - R.my_atom = src, <<< set the holders my_atom to src so that we know where we are. - - This can also be done by calling a convenience proc: - atom/proc/create_reagents(max_volume) - - Other important stuff: - - amount_per_transfer_from_this var - This var is mostly used by beakers and bottles. - It simply tells us how much to transfer when - 'pouring' our reagents into something else. - - 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 + + remove_any(amount) + This proc removes reagents from the holder until the passed amount + is matched. It'll try to remove some of ALL reagents contained. + + trans_to(obj/target, amount) + This proc equally transfers the contents of the holder to another + objects holder. You need to pass it the object (not the holder) you want + to transfer to and the amount you want to transfer. Its return value is the + actual amount transfered (if one of the objects is full/empty) + + trans_id_to(obj/target, reagent, amount) + Same as above but only for a specific reagent in the reagent list. + If the specified amount is greater than what is available, it will use + the amount of the reagent that is available. If no reagent exists, returns null. + + metabolize(mob/living/M) + This proc is called by the mobs life proc. It simply calls on_mob_life for + all contained reagents. You shouldnt have to use this one directly. + + handle_reactions() + This proc check all recipes and, on a match, uses them. + It will also call the recipe's on_reaction proc (for explosions or w/e). + Currently, this proc is automatically called by trans_to. + - Modified from the original to preserve reagent data across reactions (originally for xenoarchaeology) + + isolate_reagent(reagent) + Pass it a reagent id and it will remove all reagents but that one. + It's that simple. + + del_reagent(reagent) + Completely remove the reagent with the matching id. + + update_total() + This one simply updates the total volume of the holder. + (the volume of all reagents added together) + + clear_reagents() + This proc removes ALL reagents from the holder. + + reaction(atom/A, method=TOUCH, volume_modifier=0) + This proc calls the appropriate reaction procs of the reagents. + I.e. if A is an object, it will call the reagents reaction_obj + proc. The method var is used for reaction on mobs. It simply tells + us if the mob TOUCHed the reagent or if it INGESTed the reagent. + Since the volume can be checked in a reagents proc, you might want to + use the volume_modifier var to modifiy the passed value without actually + changing the volume of the reagents. + If you're not sure if you need to use this the answer is very most likely 'No'. + You'll want to use this proc whenever an atom first comes in + contact with the reagents of a holder. (in the 'splash' part of a beaker i.e.) + More on the reaction in the reagent part of this readme. + + add_reagent(reagent, amount, data) + Attempts to add X of the matching reagent to the holder. + You wont use this much. Mostly in new procs for pre-filled + objects. + + remove_reagent(reagent, amount) + The exact opposite of the add_reagent proc. + - Modified from original to return the reagent's data, in order to preserve reagent data across reactions (originally for xenoarchaeology) + + has_reagent(reagent, amount) + Returns 1 if the holder contains this reagent. + Or 0 if not. + If you pass it an amount it will additionally check + if the amount is matched. This is optional. + + get_reagent_amount(reagent) + Returns the amount of the matching reagent inside the + holder. Returns 0 if the reagent is missing. + + overdose_list() + Returns a list of all the chemical IDs in the reagent holder that are overdosing + + Important variables: + + total_volume + This variable contains the total volume of all reagents in this holder. + + reagent_list + This is a list of all contained reagents. More specifically, references + to the reagent datums. + + maximum_volume + This is the maximum volume of the holder. + + my_atom + This is the atom the holder is 'in'. Useful if you need to find the location. + (i.e. for explosions) + + +About Reagents: + + Reagents are all the things you can mix and fille in bottles etc. This can be anything from + rejuvs over water to ... iron. Each reagent also has a few procs - i'll explain those below. + + reaction_mob(mob/living/M, method=TOUCH) + This is called by the holder's reation proc. + This version is only called when the reagent + reacts with a mob. The method var can be either + TOUCH or INGEST. You'll want to put stuff like + acid-facemelting in here. Should only ever be + called, directly, on living mobs. + + reaction_obj(obj/O) + This is called by the holder's reation proc. + This version is called when the reagents reacts + with an object. You'll want to put stuff like + object melting in here ... or something. i dunno. + + reaction_turf(turf/T) + This is called by the holder's reation proc. + This version is called when the reagents reacts + with a turf. You'll want to put stuff like extra + slippery floors for lube or something in here. + + on_mob_life(mob/living/M) + This proc is called everytime the mobs life proc executes. + This is the place where you put damage for toxins , + drowsyness for sleep toxins etc etc. + You'll want to call the parents proc by using ..() . + If you dont, the chemical will stay in the mob forever - + unless you write your own piece of code to slowly remove it. + (Should be pretty easy, 1 line of code) + + Important variables: + + holder + This variable contains a reference to the holder the chemical is 'in' + + volume + This is the volume of the reagent. + + id + The id of the reagent + + name + The name of the reagent. + + data + This var can be used for whatever the fuck you want.You could use this + for DNA in a blood reagent or ... well whatever you want. + + color + This is a hexadecimal color that represents the reagent outside of containers, + you define it as "#RRGGBB", or, red green blue. You can also define it using the + rgb() proc, which returns a hexadecimal value too. The color is black by default. + + A good website for color calculations: http://www.psyclops.com/tools/rgb/ + + + + +About Recipes: + + Recipes are simple datums that contain a list of required reagents and a result. + They also have a proc that is called when the recipe is matched. + + on_reaction(datum/reagents/holder, created_volume) + This proc is called when the recipe is matched. + You'll want to add explosions etc here. + To find the location you'll have to do something + like get_turf(holder.my_atom) + + name & id + Should be pretty obvious. + + result + This var contains the id of the resulting reagent. + + required_reagents + This is a list of ids of the required reagents. + Each id also needs an associated value that gives us the minimum required amount + of that reagent. The handle_reaction proc can detect mutiples of the same recipes + so for most cases you want to set the required amount to 1. + + required_catalysts (Added May 2011) + This is a list of the ids of the required catalysts. + Functionally similar to required_reagents, it is a list of reagents that are required + for the reaction. However, unlike required_reagents, catalysts are NOT consumed. + They mearly have to be present in the container. + + result_amount + This is the amount of the resulting reagent this recipe will produce. + I recommend you set this to the total volume of all required reagent. + + required_container + The container the recipe has to take place in in order to happen. Leave this blank/null + if you want the reaction to happen anywhere. + + required_other + Basically like a reagent's data variable. You can set extra requirements for a + reaction with this. + + +About the Tools: + + By default, all atom have a reagents var - but its empty. if you want to use an object for the chem. + system you'll need to add something like this in its new proc: + + var/datum/reagents/R = new/datum/reagents(100), <<< create a new datum, 100 is the maximum_volume of the new holder datum. + reagents = R, <<< assign the new datum to the objects reagents var + R.my_atom = src, <<< set the holders my_atom to src so that we know where we are. + + This can also be done by calling a convenience proc: + atom/proc/create_reagents(max_volume) + + Other important stuff: + + amount_per_transfer_from_this var + This var is mostly used by beakers and bottles. + It simply tells us how much to transfer when + 'pouring' our reagents into something else. + + 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/oldchem/reagents/_reagent_base.dm b/code/modules/reagents/chemistry/reagents.dm similarity index 55% rename from code/modules/reagents/oldchem/reagents/_reagent_base.dm rename to code/modules/reagents/chemistry/reagents.dm index fbf1398decb..f9e0a664e1a 100644 --- a/code/modules/reagents/oldchem/reagents/_reagent_base.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -1,3 +1,9 @@ +#define SOLID 1 +#define LIQUID 2 +#define GAS 3 +#define FOOD_METABOLISM 0.4 +#define REM REAGENTS_EFFECT_MULTIPLIER + /datum/reagent var/name = "Reagent" var/id = "reagent" @@ -20,6 +26,16 @@ //By default, all reagents will ONLY affect organics, not synthetics. Re-define in the reagent's definition if the reagent is meant to affect synths var/process_flags = ORGANIC var/admin_only = 0 + var/overdose_threshold = 0 + var/addiction_chance = 0 + var/addiction_stage = 1 + var/last_addiction_dose = 0 + var/overdosed = 0 // You fucked up and this is now triggering it's overdose effects, purge that shit quick. + var/current_cycle = 1 + +/datum/reagent/Destroy() + . = ..() + holder = null /datum/reagent/proc/reaction_mob(mob/living/M, method=TOUCH, volume) //Some reagents transfer on touch, others don't; dependent on if they penetrate the skin or not. if(holder) //for catching rare runtimes @@ -61,20 +77,78 @@ /datum/reagent/proc/on_mob_death(mob/living/M) //use this to have chems have a "death-triggered" effect return -// Called when two reagents of the same are mixing. -/datum/reagent/proc/on_merge(data) +// Called when this reagent is removed while inside a mob +/datum/reagent/proc/on_mob_delete(mob/living/M) return /datum/reagent/proc/on_move(mob/M) return -/datum/reagent/proc/on_update(atom/A) - return - // Called after add_reagents creates a new reagent. /datum/reagent/proc/on_new(data) return -/datum/reagent/Destroy() - . = ..() - holder = null \ No newline at end of file +// Called when two reagents of the same are mixing. +/datum/reagent/proc/on_merge(data) + return + +/datum/reagent/proc/on_update(atom/A) + return + +// Called every time reagent containers process. +/datum/reagent/proc/on_tick(data) + return + +// Called when the reagent container is hit by an explosion +/datum/reagent/proc/on_ex_act(severity) + return + +// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects +/datum/reagent/proc/overdose_process(mob/living/M, severity) + var/effect = rand(1, 100) - severity + if(effect <= 8) + M.adjustToxLoss(severity) + return effect + +/datum/reagent/proc/overdose_start(mob/living/M) + return + +/datum/reagent/proc/addiction_act_stage1(mob/living/M) + return + +/datum/reagent/proc/addiction_act_stage2(mob/living/M) + if(prob(8)) + M.emote("shiver") + if(prob(8)) + M.emote("sneeze") + if(prob(4)) + to_chat(M, "You feel a dull headache.") + +/datum/reagent/proc/addiction_act_stage3(mob/living/M) + if(prob(8)) + M.emote("twitch_s") + if(prob(8)) + M.emote("shiver") + if(prob(4)) + to_chat(M, "You begin craving [name]!") + +/datum/reagent/proc/addiction_act_stage4(mob/living/M) + if(prob(8)) + M.emote("twitch") + if(prob(4)) + to_chat(M, "You have the strong urge for some [name]!") + if(prob(4)) + to_chat(M, "You REALLY crave some [name]!") + +/datum/reagent/proc/addiction_act_stage5(mob/living/M) + if(prob(8)) + M.emote("twitch") + if(prob(6)) + to_chat(M, "Your stomach lurches painfully!") + M.visible_message("[M] gags and retches!") + M.Stun(rand(2,4)) + M.Weaken(rand(2,4)) + if(prob(5)) + to_chat(M, "You feel like you can't live without [name]!") + if(prob(5)) + to_chat(M, "You would DIE for some [name] right now!") \ No newline at end of file diff --git a/code/modules/reagents/oldchem/reagents/reagents_admin.dm b/code/modules/reagents/chemistry/reagents/admin.dm similarity index 69% rename from code/modules/reagents/oldchem/reagents/reagents_admin.dm rename to code/modules/reagents/chemistry/reagents/admin.dm index 09636bd111f..024b78c3cb0 100644 --- a/code/modules/reagents/oldchem/reagents/reagents_admin.dm +++ b/code/modules/reagents/chemistry/reagents/admin.dm @@ -57,27 +57,4 @@ /datum/reagent/adminordrazine/nanites name = "Nanites" id = "nanites" - description = "Nanomachines that aid in rapid cellular regeneration." - - -// For random item spawning. Takes a list of paths, and returns the same list without anything that contains admin only reagents - -/proc/adminReagentCheck(var/list/incoming) - var/list/outgoing[0] - for(var/tocheck in incoming) - if(ispath(tocheck)) - var/check = new tocheck - if(istype(check, /atom)) - var/atom/reagentCheck = check - var/datum/reagents/reagents = reagentCheck.reagents - var/admin = 0 - for(var/reag in reagents.reagent_list) - var/datum/reagent/reagent = reag - if(reagent.admin_only) - admin = 1 - break - if(!(admin)) - outgoing += tocheck - else - outgoing += tocheck - return outgoing + description = "Nanomachines that aid in rapid cellular regeneration." \ No newline at end of file diff --git a/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm b/code/modules/reagents/chemistry/reagents/alcohol.dm similarity index 100% rename from code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm rename to code/modules/reagents/chemistry/reagents/alcohol.dm diff --git a/code/modules/reagents/newchem/Blob-Reagents.dm b/code/modules/reagents/chemistry/reagents/blob.dm similarity index 100% rename from code/modules/reagents/newchem/Blob-Reagents.dm rename to code/modules/reagents/chemistry/reagents/blob.dm diff --git a/code/modules/reagents/newchem/disease.dm b/code/modules/reagents/chemistry/reagents/disease.dm similarity index 57% rename from code/modules/reagents/newchem/disease.dm rename to code/modules/reagents/chemistry/reagents/disease.dm index cdc2d0b8d43..b4c76ac1338 100644 --- a/code/modules/reagents/newchem/disease.dm +++ b/code/modules/reagents/chemistry/reagents/disease.dm @@ -180,141 +180,4 @@ /datum/reagent/plasma_dust/plasmavirusfood/weak name = "weakened virus plasma" id = "weakplasmavirusfood" - color = "#CEC3C6" // rgb: 206,195,198 - -//reactions -/datum/chemical_reaction/virus_food - name = "Virus Food" - id = "virusfood" - result = "virusfood" - required_reagents = list("water" = 1, "milk" = 1, "oxygen" = 1) - result_amount = 3 - -/datum/chemical_reaction/virus_food_mutagen - name = "mutagenic agar" - id = "mutagenvirusfood" - result = "mutagenvirusfood" - required_reagents = list("mutagen" = 1, "virusfood" = 1) - result_amount = 1 - -/datum/chemical_reaction/virus_food_diphenhydramine - name = "virus rations" - id = "diphenhydraminevirusfood" - result = "diphenhydraminevirusfood" - required_reagents = list("diphenhydramine" = 1, "virusfood" = 1) - result_amount = 1 - -/datum/chemical_reaction/virus_food_plasma - name = "virus plasma" - id = "plasmavirusfood" - result = "plasmavirusfood" - required_reagents = list("plasma_dust" = 1, "virusfood" = 1) - result_amount = 1 - -/datum/chemical_reaction/virus_food_plasma_diphenhydramine - name = "weakened virus plasma" - id = "weakplasmavirusfood" - result = "weakplasmavirusfood" - required_reagents = list("diphenhydramine" = 1, "plasmavirusfood" = 1) - result_amount = 2 - -/datum/chemical_reaction/virus_food_mutagen_sugar - name = "sucrose agar" - id = "sugarvirusfood" - result = "sugarvirusfood" - required_reagents = list("sugar" = 1, "mutagenvirusfood" = 1) - result_amount = 2 - -/datum/chemical_reaction/virus_food_mutagen_salineglucose - name = "sucrose agar" - id = "salineglucosevirusfood" - result = "sugarvirusfood" - required_reagents = list("salglu_solution" = 1, "mutagenvirusfood" = 1) - result_amount = 2 - - -//mix virus -/datum/chemical_reaction/mix_virus - name = "Mix Virus" - id = "mixvirus" - required_reagents = list("virusfood" = 1) - required_catalysts = list("blood" = 1) - var/level_min = 0 - var/level_max = 2 - -/datum/chemical_reaction/mix_virus/on_reaction(datum/reagents/holder, created_volume) - var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list - if(B && B.data) - var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"] - if(D) - D.Evolve(level_min, level_max) - - -/datum/chemical_reaction/mix_virus/mix_virus_2 - name = "Mix Virus 2" - id = "mixvirus2" - required_reagents = list("mutagen" = 1) - level_min = 2 - level_max = 4 - -/datum/chemical_reaction/mix_virus/mix_virus_3 - name = "Mix Virus 3" - id = "mixvirus3" - required_reagents = list("plasma_dust" = 1) - level_min = 4 - level_max = 6 - -/datum/chemical_reaction/mix_virus/mix_virus_4 - name = "Mix Virus 4" - id = "mixvirus4" - required_reagents = list("uranium" = 1) - level_min = 5 - level_max = 6 - -/datum/chemical_reaction/mix_virus/mix_virus_5 - name = "Mix Virus 5" - id = "mixvirus5" - required_reagents = list("mutagenvirusfood" = 1) - level_min = 3 - level_max = 3 - -/datum/chemical_reaction/mix_virus/mix_virus_6 - name = "Mix Virus 6" - id = "mixvirus6" - required_reagents = list("sugarvirusfood" = 1) - level_min = 4 - level_max = 4 - -/datum/chemical_reaction/mix_virus/mix_virus_7 - name = "Mix Virus 7" - id = "mixvirus7" - required_reagents = list("weakplasmavirusfood" = 1) - level_min = 5 - level_max = 5 - -/datum/chemical_reaction/mix_virus/mix_virus_8 - name = "Mix Virus 8" - id = "mixvirus8" - required_reagents = list("plasmavirusfood" = 1) - level_min = 6 - level_max = 6 - -/datum/chemical_reaction/mix_virus/mix_virus_9 - name = "Mix Virus 9" - id = "mixvirus9" - required_reagents = list("diphenhydraminevirusfood" = 1) - level_min = 1 - level_max = 1 - -/datum/chemical_reaction/mix_virus/rem_virus - name = "Devolve Virus" - id = "remvirus" - required_reagents = list("diphenhydramine" = 1) - required_catalysts = list("blood" = 1) - -/datum/chemical_reaction/mix_virus/rem_virus/on_reaction(datum/reagents/holder, created_volume) - var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list - if(B && B.data) - var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"] - if(D) - D.Devolve() + color = "#CEC3C6" // rgb: 206,195,198 \ No newline at end of file diff --git a/code/modules/reagents/oldchem/reagents/drink/reagents_drink_base.dm b/code/modules/reagents/chemistry/reagents/drink_base.dm similarity index 100% rename from code/modules/reagents/oldchem/reagents/drink/reagents_drink_base.dm rename to code/modules/reagents/chemistry/reagents/drink_base.dm diff --git a/code/modules/reagents/oldchem/reagents/drink/reagents_drink_cold.dm b/code/modules/reagents/chemistry/reagents/drink_cold.dm similarity index 97% rename from code/modules/reagents/oldchem/reagents/drink/reagents_drink_cold.dm rename to code/modules/reagents/chemistry/reagents/drink_cold.dm index 26164571769..3e3c2670608 100644 --- a/code/modules/reagents/oldchem/reagents/drink/reagents_drink_cold.dm +++ b/code/modules/reagents/chemistry/reagents/drink_cold.dm @@ -54,7 +54,7 @@ M.status_flags |= GOTTAGOFAST ..() -/datum/reagent/drink/cold/nuka_cola/reagent_deleted(mob/living/M) +/datum/reagent/drink/cold/nuka_cola/on_mob_delete(mob/living/M) M.status_flags &= ~GOTTAGOFAST ..() diff --git a/code/modules/reagents/oldchem/reagents/drink/reagents_drink.dm b/code/modules/reagents/chemistry/reagents/drinks.dm similarity index 63% rename from code/modules/reagents/oldchem/reagents/drink/reagents_drink.dm rename to code/modules/reagents/chemistry/reagents/drinks.dm index 869e9295bf5..b415d0f8d08 100644 --- a/code/modules/reagents/oldchem/reagents/drink/reagents_drink.dm +++ b/code/modules/reagents/chemistry/reagents/drinks.dm @@ -283,3 +283,150 @@ M.adjustBruteLoss(-1) M.adjustFireLoss(-1) ..() + +/datum/reagent/ginsonic/on_mob_life(mob/living/M) + M.AdjustDrowsy(-5) + if(prob(25)) + M.AdjustParalysis(-1) + M.AdjustStunned(-1) + M.AdjustWeakened(-1) + if(prob(8)) + M.reagents.add_reagent("methamphetamine",1.2) + var/sonic_message = pick("Gotta go fast!", "Time to speed, keed!", "I feel a need for speed!", "Let's juice.", "Juice time.", "Way Past Cool!") + if(prob(50)) + M.say("[sonic_message]") + else + to_chat(M, "[sonic_message ]") + ..() + +/datum/reagent/ethanol/applejack + name = "Applejack" + id = "applejack" + description = "A highly concentrated alcoholic beverage made by repeatedly freezing cider and removing the ice." + color = "#997A00" + alcohol_perc = 0.4 + +/datum/reagent/ethanol/jackrose + name = "Jack Rose" + id = "jackrose" + description = "A classic cocktail that had fallen out of fashion, but never out of taste," + color = "#664300" + alcohol_perc = 0.4 + +/datum/reagent/ethanol/dragons_breath //inaccessible to players, but here for admin shennanigans + name = "Dragon's Breath" + id = "dragonsbreath" + description = "Possessing this stuff probably breaks the Geneva convention." + reagent_state = LIQUID + color = "#DC0000" + alcohol_perc = 1 + +/datum/reagent/ethanol/dragons_breath/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method == INGEST && prob(20)) + if(M.on_fire) + M.adjust_fire_stacks(3) + +/datum/reagent/ethanol/dragons_breath/on_mob_life(mob/living/M) + if(M.reagents.has_reagent("milk")) + to_chat(M, "The milk stops the burning. Ahhh.") + M.reagents.del_reagent("milk") + M.reagents.del_reagent("dragonsbreath") + return + if(prob(8)) + to_chat(M, "Oh god! Oh GODD!!") + if(prob(50)) + to_chat(M, "Your throat burns terribly!") + M.emote(pick("scream","cry","choke","gasp")) + M.Stun(1) + if(prob(8)) + to_chat(M, "Why!? WHY!?") + if(prob(8)) + to_chat(M, "ARGHHHH!") + if(prob(2 * volume)) + to_chat(M, "OH GOD OH GOD PLEASE NO!!") + if(M.on_fire) + M.adjust_fire_stacks(5) + if(prob(50)) + to_chat(M, "IT BURNS!!!!") + M.visible_message("[M] is consumed in flames!") + M.dust() + return + ..() + +// ROBOT ALCOHOL PAST THIS POINT +// WOOO! + + +/datum/reagent/ethanol/synthanol + name = "Synthanol" + id = "synthanol" + description = "A runny liquid with conductive capacities. Its effects on synthetics are similar to those of alcohol on organics." + reagent_state = LIQUID + color = "#1BB1FF" + process_flags = ORGANIC | SYNTHETIC + metabolization_rate = 0.4 + alcohol_perc = 0.5 + +/datum/reagent/ethanol/synthanol/on_mob_life(mob/living/M) + if(!M.isSynthetic()) + holder.remove_reagent(id, 3.6) //gets removed from organics very fast + if(prob(25)) + holder.remove_reagent(id, 15) + M.fakevomit() + ..() + +/datum/reagent/ethanol/synthanol/reaction_mob(mob/living/M, method=TOUCH, volume) + if(M.isSynthetic()) + return + if(method == INGEST) + to_chat(M, pick("That was awful!", "Yuck!")) + +/datum/reagent/ethanol/synthanol/robottears + name = "Robot Tears" + id = "robottears" + description = "An oily substance that an IPC could technically consider a 'drink'." + reagent_state = LIQUID + color = "#363636" + alcohol_perc = 0.25 + +/datum/reagent/ethanol/synthanol/trinary + name = "Trinary" + id = "trinary" + description = "A fruit drink meant only for synthetics, however that works." + reagent_state = LIQUID + color = "#adb21f" + alcohol_perc = 0.2 + +/datum/reagent/ethanol/synthanol/servo + name = "Servo" + id = "servo" + description = "A drink containing some organic ingredients, but meant only for synthetics." + reagent_state = LIQUID + color = "#5b3210" + alcohol_perc = 0.25 + +/datum/reagent/ethanol/synthanol/uplink + name = "Uplink" + id = "uplink" + description = "A potent mix of alcohol and synthanol. Will only work on synthetics." + reagent_state = LIQUID + color = "#e7ae04" + alcohol_perc = 0.15 + +/datum/reagent/ethanol/synthanol/synthnsoda + name = "Synth 'n Soda" + id = "synthnsoda" + description = "The classic drink adjusted for a robot's tastes." + reagent_state = LIQUID + color = "#7204e7" + alcohol_perc = 0.25 + +/datum/reagent/ethanol/synthanol/synthignon + name = "Synthignon" + id = "synthignon" + description = "Someone mixed wine and alcohol for robots. Hope you're proud of yourself." + reagent_state = LIQUID + color = "#d004e7" + alcohol_perc = 0.25 + +// ROBOT ALCOHOL ENDS \ No newline at end of file diff --git a/code/modules/reagents/newchem/drugs.dm b/code/modules/reagents/chemistry/reagents/drugs.dm similarity index 81% rename from code/modules/reagents/newchem/drugs.dm rename to code/modules/reagents/chemistry/reagents/drugs.dm index bc5b10be569..f70360baf28 100644 --- a/code/modules/reagents/newchem/drugs.dm +++ b/code/modules/reagents/chemistry/reagents/drugs.dm @@ -1,8 +1,118 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 +/datum/reagent/serotrotium + name = "Serotrotium" + id = "serotrotium" + description = "A chemical compound that promotes concentrated production of the serotonin neurotransmitter in humans." + reagent_state = LIQUID + color = "#202040" // rgb: 20, 20, 40 + metabolization_rate = 0.25 * REAGENTS_METABOLISM -#define REM REAGENTS_EFFECT_MULTIPLIER +/datum/reagent/serotrotium/on_mob_life(mob/living/M) + if(ishuman(M)) + if(prob(7)) + M.emote(pick("twitch","drool","moan","gasp")) + ..() + + +/datum/reagent/lithium + name = "Lithium" + id = "lithium" + description = "A chemical element." + reagent_state = SOLID + color = "#808080" // rgb: 128, 128, 128 + +/datum/reagent/lithium/on_mob_life(mob/living/M) + if(isturf(M.loc) && !istype(M.loc, /turf/space)) + if(M.canmove && !M.restrained()) + step(M, pick(cardinal)) + if(prob(5)) M.emote(pick("twitch","drool","moan")) + ..() + + +/datum/reagent/hippies_delight + name = "Hippie's Delight" + id = "hippiesdelight" + description = "You just don't get it maaaan." + reagent_state = LIQUID + color = "#664300" // rgb: 102, 67, 0 + metabolization_rate = 0.2 * REAGENTS_METABOLISM + +/datum/reagent/hippies_delight/on_mob_life(mob/living/M) + M.Druggy(50) + switch(current_cycle) + if(1 to 5) + if(!M.stuttering) M.stuttering = 1 + M.Dizzy(10) + if(prob(10)) M.emote(pick("twitch","giggle")) + if(5 to 10) + if(!M.stuttering) M.stuttering = 1 + M.Jitter(20) + M.Dizzy(20) + M.Druggy(45) + if(prob(20)) M.emote(pick("twitch","giggle")) + if(10 to INFINITY) + if(!M.stuttering) M.stuttering = 1 + M.Jitter(40) + M.Dizzy(40) + M.Druggy(60) + if(prob(30)) M.emote(pick("twitch","giggle")) + ..() + +/datum/reagent/lsd + name = "Lysergic acid diethylamide" + id = "lsd" + description = "A highly potent hallucinogenic substance. Far out, maaaan." + reagent_state = LIQUID + color = "#0000D8" + +/datum/reagent/lsd/on_mob_life(mob/living/M) + M.Druggy(15) + M.AdjustHallucinate(10) + ..() + +/datum/reagent/space_drugs + name = "Space drugs" + id = "space_drugs" + description = "An illegal chemical compound used as drug." + reagent_state = LIQUID + color = "#9087A2" + metabolization_rate = 0.2 + addiction_chance = 65 + heart_rate_decrease = 1 + +/datum/reagent/space_drugs/on_mob_life(mob/living/M) + M.Druggy(15) + if(isturf(M.loc) && !istype(M.loc, /turf/space)) + if(M.canmove && !M.restrained()) + step(M, pick(cardinal)) + if(prob(7)) M.emote(pick("twitch","drool","moan","giggle")) + ..() + +/datum/reagent/psilocybin + name = "Psilocybin" + id = "psilocybin" + description = "A strong psycotropic derived from certain species of mushroom." + color = "#E700E7" // rgb: 231, 0, 231 + +/datum/reagent/psilocybin/on_mob_life(mob/living/M) + M.Druggy(30) + switch(current_cycle) + if(1 to 5) + M.Stuttering(1) + M.Dizzy(5) + if(prob(10)) M.emote(pick("twitch","giggle")) + if(5 to 10) + M.Stuttering(1) + M.Jitter(10) + M.Dizzy(10) + M.Druggy(35) + if(prob(20)) M.emote(pick("twitch","giggle")) + if(10 to INFINITY) + M.Stuttering(1) + M.Jitter(20) + M.Dizzy(20) + M.Druggy(40) + if(prob(30)) M.emote(pick("twitch","giggle")) + ..() /datum/reagent/nicotine name = "Nicotine" @@ -133,22 +243,6 @@ M.adjustBruteLoss(5) M.emote("twitch_s") -/datum/chemical_reaction/crank - name = "Crank" - id = "crank" - result = "crank" - required_reagents = list("diphenhydramine" = 1, "ammonia" = 1, "lithium" = 1, "sacid" = 1, "fuel" = 1) - result_amount = 5 - mix_message = "The mixture violently reacts, leaving behind a few crystalline shards." - mix_sound = 'sound/goonstation/effects/crystalshatter.ogg' - min_temp = 390 - -/datum/chemical_reaction/crank/on_reaction(datum/reagents/holder, created_volume) - var/turf/T = get_turf(holder.my_atom) - for(var/turf/turf in range(1,T)) - new /obj/effect/hotspot(turf) - explosion(T,0,0,2) - /datum/reagent/krokodil name = "Krokodil" id = "krokodil" @@ -216,16 +310,6 @@ M.emote("shiver") M.bodytemperature -= 70 -/datum/chemical_reaction/krokodil - name = "Krokodil" - id = "krokodil" - result = "krokodil" - required_reagents = list("diphenhydramine" = 1, "morphine" = 1, "cleaner" = 1, "potassium" = 1, "phosphorus" = 1, "fuel" = 1) - result_amount = 6 - mix_message = "The mixture dries into a pale blue powder." - min_temp = 380 - mix_sound = 'sound/goonstation/misc/fuse.ogg' - /datum/reagent/methamphetamine name = "Methamphetamine" id = "methamphetamine" @@ -253,7 +337,7 @@ M.adjustBrainLoss(1.0) ..() -/datum/reagent/methamphetamine/reagent_deleted(mob/living/M) +/datum/reagent/methamphetamine/on_mob_delete(mob/living/M) M.status_flags &= ~GOTTAGOREALLYFAST ..() @@ -282,32 +366,6 @@ else if(effect <= 7) M.emote("laugh") -/datum/chemical_reaction/methamphetamine - name = "methamphetamine" - id = "methamphetamine" - result = "methamphetamine" - required_reagents = list("ephedrine" = 1, "iodine" = 1, "phosphorus" = 1, "hydrogen" = 1) - result_amount = 4 - min_temp = 374 - -/datum/chemical_reaction/methamphetamine/on_reaction(datum/reagents/holder) - var/turf/T = get_turf(holder.my_atom) - T.visible_message("The solution generates a strong vapor!") - for(var/mob/living/carbon/C in range(T, 1)) - if(C.can_breathe_gas()) - C.emote("gasp") - C.AdjustLoseBreath(1) - C.reagents.add_reagent("toxin", 10) - C.reagents.add_reagent("neurotoxin2", 20) - -/datum/chemical_reaction/saltpetre - name = "saltpetre" - id = "saltpetre" - result = "saltpetre" - required_reagents = list("potassium" = 1, "nitrogen" = 1, "oxygen" = 3) - result_amount = 3 - mix_sound = 'sound/goonstation/misc/fuse.ogg' - /datum/reagent/saltpetre name = "Saltpetre" id = "saltpetre" @@ -411,32 +469,6 @@ M.reagents.add_reagent("jagged_crystals", 5) M.emote("twitch") -/datum/chemical_reaction/bath_salts - name = "bath_salts" - id = "bath_salts" - result = "bath_salts" - required_reagents = list("????" = 1, "saltpetre" = 1, "msg" = 1, "cleaner" = 1, "enzyme" = 1, "mugwort" = 1, "mercury" = 1) - result_amount = 6 - min_temp = 374 - mix_message = "Tiny cubic crystals precipitate out of the mixture. Huh." - mix_sound = 'sound/goonstation/misc/fuse.ogg' - -/datum/chemical_reaction/jenkem - name = "Jenkem" - id = "jenkem" - result = "jenkem" - required_reagents = list("toiletwater" = 1, "ammonia" = 1, "water" = 1) - result_amount = 3 - mix_message = "The mixture ferments into a filthy morass." - mix_sound = 'sound/effects/blobattack.ogg' - -/datum/chemical_reaction/jenkem/on_reaction(datum/reagents/holder) - var/turf/T = get_turf(holder.my_atom) - T.visible_message("The solution generates a strong vapor!") - for(var/mob/living/carbon/C in range(T, 1)) - if(C.can_breathe_gas()) - C.reagents.add_reagent("jenkem", 25) - /datum/reagent/jenkem name = "Jenkem" id = "jenkem" @@ -452,13 +484,6 @@ M.adjustToxLoss(1) ..() -/datum/chemical_reaction/aranesp - name = "Aranesp" - id = "aranesp" - result = "aranesp" - required_reagents = list("epinephrine" = 1, "atropine" = 1, "insulin" = 1) - result_amount = 3 - /datum/reagent/aranesp name = "Aranesp" id = "aranesp" @@ -514,14 +539,6 @@ process_flags = ORGANIC | SYNTHETIC //Flipping for everyone! addiction_chance = 10 -/datum/chemical_reaction/fliptonium - name = "fliptonium" - id = "fliptonium" - result = "fliptonium" - required_reagents = list("ephedrine" = 1, "liquid_dark_matter" = 1, "chocolate" = 1, "ginsonic" = 1) - result_amount = 4 - mix_message = "The mixture swirls around excitedly!" - /datum/reagent/fliptonium/reaction_mob(mob/living/M, method=TOUCH, volume) if(method == INGEST || method == TOUCH) M.SpinAnimation(speed = 12, loops = -1) @@ -553,7 +570,7 @@ M.SetSleeping(0) ..() -/datum/reagent/fliptonium/reagent_deleted(mob/living/M) +/datum/reagent/fliptonium/on_mob_delete(mob/living/M) M.SpinAnimation(speed = 12, loops = -1) /datum/reagent/fliptonium/overdose_process(mob/living/M, severity) @@ -592,20 +609,11 @@ description = "Ultra-Lube is an enhanced lubricant which induces effect similar to Methamphetamine in synthetic users by drastically reducing internal friction and increasing cooling capabilities." reagent_state = LIQUID color = "#1BB1FF" - process_flags = SYNTHETIC overdose_threshold = 20 addiction_chance = 60 metabolization_rate = 0.6 -/datum/chemical_reaction/lube/ultra - name = "Ultra-Lube" - id = "ultralube" - result = "ultralube" - required_reagents = list("lube" = 2, "formaldehyde" = 1, "cryostylane" = 1) - result_amount = 2 - mix_message = "The mixture darkens and appears to partially vaporize into a chilling aerosol." - /datum/reagent/lube/ultra/on_mob_life(mob/living/M) var/high_message = pick("You feel your servos whir!", "You feel like you need to go faster.", "You feel like you were just overclocked!") if(prob(1)) @@ -624,7 +632,7 @@ M.emote(pick("twitch", "shiver")) ..() -/datum/reagent/lube/ultra/reagent_deleted(mob/living/M) +/datum/reagent/lube/ultra/on_mob_delete(mob/living/M) M.status_flags &= ~GOTTAGOREALLYFAST ..() @@ -681,12 +689,4 @@ B.pixel_y = rand(-20, 0) B.icon = I M.adjustFireLoss(rand(1,5)*REM) - M.adjustBruteLoss(rand(1,5)*REM) - -/datum/chemical_reaction/surge - name = "Surge" - id = "surge" - result = "surge" - required_reagents = list("thermite" = 3, "uranium" = 1, "fluorosurfactant" = 1, "sacid" = 1) - result_amount = 6 - mix_message = "The mixture congeals into a metallic green gel that crackles with electrical activity." + M.adjustBruteLoss(rand(1,5)*REM) \ No newline at end of file diff --git a/code/modules/reagents/newchem/food.dm b/code/modules/reagents/chemistry/reagents/food.dm similarity index 54% rename from code/modules/reagents/newchem/food.dm rename to code/modules/reagents/chemistry/reagents/food.dm index 7f529b6b815..83e0cbb031e 100644 --- a/code/modules/reagents/newchem/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -1,3 +1,397 @@ +/////////////////////////Food Reagents//////////////////////////// +// Part of the food code. Nutriment is used instead of the old "heal_amt" code. Also is where all the food +// condiments, additives, and such go. +/datum/reagent/nutriment // Pure nutriment, universally digestable and thus slightly less effective + name = "Nutriment" + id = "nutriment" + description = "A questionable mixture of various pure nutrients commonly found in processed foods." + reagent_state = SOLID + nutriment_factor = 12 * REAGENTS_METABOLISM + color = "#664330" // rgb: 102, 67, 48 + var/diet_flags = DIET_OMNI | DIET_HERB | DIET_CARN + +/datum/reagent/nutriment/on_mob_life(mob/living/M) + if(!(M.mind in ticker.mode.vampires)) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.can_eat(diet_flags)) //Make sure the species has it's dietflag set, otherwise it can't digest any nutrients + H.nutrition += nutriment_factor // For hunger and fatness + if(prob(50)) + M.adjustBruteLoss(-1) + if(H.species.exotic_blood) + H.vessel.add_reagent(H.species.exotic_blood, 0.4) + else + if(!(H.species.flags & NO_BLOOD)) + H.vessel.add_reagent("blood", 0.4) + ..() + +/datum/reagent/nutriment/protein // Meat-based protein, digestable by carnivores and omnivores, worthless to herbivores + name = "Protein" + id = "protein" + description = "Various essential proteins and fats commonly found in animal flesh and blood." + nutriment_factor = 15 * REAGENTS_METABOLISM + diet_flags = DIET_CARN | DIET_OMNI + +/datum/reagent/nutriment/plantmatter // Plant-based biomatter, digestable by herbivores and omnivores, worthless to carnivores + name = "Plant-matter" + id = "plantmatter" + description = "Vitamin-rich fibers and natural sugars commonly found in fresh produce." + nutriment_factor = 15 * REAGENTS_METABOLISM + diet_flags = DIET_HERB | DIET_OMNI + + +/datum/reagent/vitamin + name = "Vitamin" + id = "vitamin" + description = "All the best vitamins, minerals, and carbohydrates the body needs in pure form." + reagent_state = SOLID + nutriment_factor = 1 * REAGENTS_METABOLISM + color = "#664330" // rgb: 102, 67, 48 + +/datum/reagent/vitamin/on_mob_life(mob/living/M) //everyone needs vitamins, so this works on everyone, regardless of diet or if they're a vampire. + M.nutrition += nutriment_factor + if(prob(50)) + M.adjustBruteLoss(-1) + M.adjustFireLoss(-1) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.species.exotic_blood) + H.vessel.add_reagent(H.species.exotic_blood, 0.5) + else + if(!(H.species.flags & NO_BLOOD)) + H.vessel.add_reagent("blood", 0.5) + ..() + +/datum/reagent/soysauce + name = "Soysauce" + id = "soysauce" + description = "A salty sauce made from the soy plant." + reagent_state = LIQUID + nutriment_factor = 2 * REAGENTS_METABOLISM + color = "#792300" // rgb: 121, 35, 0 + +/datum/reagent/ketchup + name = "Ketchup" + id = "ketchup" + description = "Ketchup, catsup, whatever. It's tomato paste." + reagent_state = LIQUID + nutriment_factor = 5 * REAGENTS_METABOLISM + color = "#731008" // rgb: 115, 16, 8 + + +/datum/reagent/capsaicin + name = "Capsaicin Oil" + id = "capsaicin" + description = "This is what makes chilis hot." + reagent_state = LIQUID + color = "#B31008" // rgb: 179, 16, 8 + +/datum/reagent/capsaicin/on_mob_life(mob/living/M) + switch(current_cycle) + if(1 to 15) + M.bodytemperature += 5 * TEMPERATURE_DAMAGE_COEFFICIENT + if(holder.has_reagent("frostoil")) + holder.remove_reagent("frostoil", 5) + if(isslime(M)) + M.bodytemperature += rand(5,20) + if(15 to 25) + M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT + if(isslime(M)) + M.bodytemperature += rand(10,20) + if(25 to 35) + M.bodytemperature += 15 * TEMPERATURE_DAMAGE_COEFFICIENT + if(isslime(M)) + M.bodytemperature += rand(15,20) + if(35 to INFINITY) + M.bodytemperature += 20 * TEMPERATURE_DAMAGE_COEFFICIENT + if(isslime(M)) + M.bodytemperature += rand(20,25) + ..() + +/datum/reagent/frostoil + name = "Frost Oil" + id = "frostoil" + description = "A special oil that noticably chills the body. Extraced from Icepeppers." + reagent_state = LIQUID + color = "#8BA6E9" // rgb: 139, 166, 233 + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/frostoil/on_mob_life(mob/living/M) + switch(current_cycle) + if(1 to 15) + M.bodytemperature -= 10 * TEMPERATURE_DAMAGE_COEFFICIENT + if(holder.has_reagent("capsaicin")) + holder.remove_reagent("capsaicin", 5) + if(isslime(M)) + M.bodytemperature -= rand(5,20) + if(15 to 25) + M.bodytemperature -= 15 * TEMPERATURE_DAMAGE_COEFFICIENT + if(isslime(M)) + M.bodytemperature -= rand(10,20) + if(25 to 35) + M.bodytemperature -= 20 * TEMPERATURE_DAMAGE_COEFFICIENT + if(prob(1)) + M.emote("shiver") + if(isslime(M)) + M.bodytemperature -= rand(15,20) + if(35 to INFINITY) + M.bodytemperature -= 20 * TEMPERATURE_DAMAGE_COEFFICIENT + if(prob(1)) + M.emote("shiver") + if(isslime(M)) + M.bodytemperature -= rand(20,25) + ..() + +/datum/reagent/frostoil/reaction_turf(turf/T, volume) + if(volume >= 5) + for(var/mob/living/carbon/slime/M in T) + M.adjustToxLoss(rand(15,30)) + + +/datum/reagent/sodiumchloride + name = "Salt" + id = "sodiumchloride" + description = "Sodium chloride, common table salt." + reagent_state = SOLID + color = "#B1B0B0" + overdose_threshold = 100 + +/datum/reagent/sodiumchloride/overdose_process(mob/living/M, severity) + if(prob(70)) + M.adjustBrainLoss(1) + ..() + +/datum/reagent/blackpepper + name = "Black Pepper" + id = "blackpepper" + description = "A powder ground from peppercorns. *AAAACHOOO*" + reagent_state = SOLID + +/datum/reagent/cocoa + name = "Cocoa Powder" + id = "cocoa" + description = "A fatty, bitter paste made from cocoa beans." + reagent_state = SOLID + nutriment_factor = 5 * REAGENTS_METABOLISM + color = "#302000" // rgb: 48, 32, 0 + +/datum/reagent/cocoa/on_mob_life(mob/living/M) + M.nutrition += nutriment_factor + ..() + +/datum/reagent/hot_coco + name = "Hot Chocolate" + id = "hot_coco" + description = "Made with love! And cocoa beans." + reagent_state = LIQUID + nutriment_factor = 2 * REAGENTS_METABOLISM + color = "#403010" // rgb: 64, 48, 16 + +/datum/reagent/hot_coco/on_mob_life(mob/living/M) + if(M.bodytemperature < 310)//310 is the normal bodytemp. 310.055 + M.bodytemperature = min(310, M.bodytemperature + (5 * TEMPERATURE_DAMAGE_COEFFICIENT)) + M.nutrition += nutriment_factor + ..() + +/datum/reagent/sprinkles + name = "Sprinkles" + id = "sprinkles" + description = "Multi-colored little bits of sugar, commonly found on donuts. Loved by cops." + nutriment_factor = 1 * REAGENTS_METABOLISM + color = "#FF00FF" // rgb: 255, 0, 255 + +/datum/reagent/sprinkles/on_mob_life(mob/living/M) + M.nutrition += nutriment_factor + if(ishuman(M) && M.job in list("Security Officer", "Security Pod Pilot", "Detective", "Warden", "Head of Security", "Brig Physician", "Internal Affairs Agent", "Magistrate")) + M.adjustBruteLoss(-1) + M.adjustFireLoss(-1) + ..() + + +/datum/reagent/cornoil + name = "Corn Oil" + id = "cornoil" + description = "An oil derived from various types of corn." + reagent_state = LIQUID + nutriment_factor = 20 * REAGENTS_METABOLISM + color = "#302000" // rgb: 48, 32, 0 + +/datum/reagent/cornoil/on_mob_life(mob/living/M) + M.nutrition += nutriment_factor + ..() + +/datum/reagent/cornoil/reaction_turf(turf/simulated/T, volume) + if(!istype(T)) + return + if(volume >= 3) + T.MakeSlippery() + var/hotspot = (locate(/obj/effect/hotspot) in T) + if(hotspot) + var/datum/gas_mixture/lowertemp = T.remove_air( T.air.total_moles()) + lowertemp.temperature = max(min(lowertemp.temperature-2000, lowertemp.temperature / 2), 0) + lowertemp.react() + T.assume_air(lowertemp) + qdel(hotspot) + + +/datum/reagent/enzyme + name = "Denatured Enzyme" + id = "enzyme" + description = "Heated beyond usefulness, this enzyme is now worthless." + reagent_state = LIQUID + color = "#282314" // rgb: 54, 94, 48 + + +/datum/reagent/dry_ramen + name = "Dry Ramen" + id = "dry_ramen" + description = "Space age food, since August 25, 1958. Contains dried noodles, vegetables, and chemicals that boil in contact with water." + reagent_state = SOLID + nutriment_factor = 1 * REAGENTS_METABOLISM + color = "#302000" // rgb: 48, 32, 0 + +/datum/reagent/dry_ramen/on_mob_life(mob/living/M) + M.nutrition += nutriment_factor + ..() + + +/datum/reagent/hot_ramen + name = "Hot Ramen" + id = "hot_ramen" + description = "The noodles are boiled, the flavors are artificial, just like being back in school." + reagent_state = LIQUID + nutriment_factor = 5 * REAGENTS_METABOLISM + color = "#302000" // rgb: 48, 32, 0 + +/datum/reagent/hot_ramen/on_mob_life(mob/living/M) + M.nutrition += nutriment_factor + if(M.bodytemperature < 310)//310 is the normal bodytemp. 310.055 + M.bodytemperature = min(310, M.bodytemperature + (10 * TEMPERATURE_DAMAGE_COEFFICIENT)) + ..() + + +/datum/reagent/hell_ramen + name = "Hell Ramen" + id = "hell_ramen" + description = "The noodles are boiled, the flavors are artificial, just like being back in school." + reagent_state = LIQUID + nutriment_factor = 5 * REAGENTS_METABOLISM + color = "#302000" // rgb: 48, 32, 0 + +/datum/reagent/hell_ramen/on_mob_life(mob/living/M) + M.nutrition += nutriment_factor + M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT + ..() + + +/datum/reagent/flour + name = "flour" + id = "flour" + description = "This is what you rub all over yourself to pretend to be a ghost." + reagent_state = SOLID + nutriment_factor = 1 * REAGENTS_METABOLISM + color = "#FFFFFF" // rgb: 0, 0, 0 + +/datum/reagent/flour/on_mob_life(mob/living/M) + M.nutrition += nutriment_factor + ..() + +/datum/reagent/flour/reaction_turf(turf/T, volume) + if(!istype(T, /turf/space)) + new /obj/effect/decal/cleanable/flour(T) + + +/datum/reagent/rice + name = "Rice" + id = "rice" + description = "Enjoy the great taste of nothing." + reagent_state = SOLID + nutriment_factor = 1 * REAGENTS_METABOLISM + color = "#FFFFFF" // rgb: 0, 0, 0 + +/datum/reagent/rice/on_mob_life(mob/living/M) + M.nutrition += nutriment_factor + ..() + + +/datum/reagent/cherryjelly + name = "Cherry Jelly" + id = "cherryjelly" + description = "Totally the best. Only to be spread on foods with excellent lateral symmetry." + reagent_state = LIQUID + nutriment_factor = 1 * REAGENTS_METABOLISM + color = "#801E28" // rgb: 128, 30, 40 + +/datum/reagent/cherryjelly/on_mob_life(mob/living/M) + M.nutrition += nutriment_factor + ..() + +/datum/reagent/toxin/coffeepowder + name = "Coffee Grounds" + id = "coffeepowder" + description = "Finely ground Coffee beans, used to make coffee." + reagent_state = SOLID + color = "#5B2E0D" // rgb: 91, 46, 13 + +/datum/reagent/toxin/teapowder + name = "Ground Tea Leaves" + id = "teapowder" + description = "Finely shredded Tea leaves, used for making tea." + reagent_state = SOLID + color = "#7F8400" // rgb: 127, 132, 0 + +//Reagents used for plant fertilizers. +/datum/reagent/toxin/fertilizer + name = "fertilizer" + id = "fertilizer" + description = "A chemical mix good for growing plants with." + reagent_state = LIQUID + color = "#664330" // rgb: 102, 67, 48 + +/datum/reagent/toxin/fertilizer/eznutrient + name = "EZ Nutrient" + id = "eznutrient" + +/datum/reagent/toxin/fertilizer/left4zed + name = "Left-4-Zed" + id = "left4zed" + +/datum/reagent/toxin/fertilizer/robustharvest + name = "Robust Harvest" + id = "robustharvest" + + +/datum/reagent/sugar + name = "Sugar" + id = "sugar" + description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste." + reagent_state = SOLID + color = "#FFFFFF" // rgb: 255, 255, 255 + overdose_threshold = 200 // Hyperglycaemic shock + +/datum/reagent/sugar/on_mob_life(mob/living/M) + M.AdjustDrowsy(-5) + if(current_cycle >= 90) + M.AdjustJitter(2) + if(prob(50)) + M.AdjustParalysis(-1) + M.AdjustStunned(-1) + M.AdjustWeakened(-1) + if(prob(4)) + M.reagents.add_reagent("epinephrine", 1.2) + ..() + +/datum/reagent/sugar/overdose_start(mob/living/M) + to_chat(M, "You pass out from hyperglycemic shock!") + M.emote("collapse") + ..() + +/datum/reagent/sugar/overdose_process(mob/living/M, severity) + M.Paralyse(3 * severity) + M.Weaken(4 * severity) + if(prob(8)) + M.adjustToxLoss(severity) + /datum/reagent/questionmark // food poisoning name = "????" id = "????" @@ -34,15 +428,6 @@ reagent_state = LIQUID color = "#23A046" -/datum/chemical_reaction/triple_citrus - name = "triple_citrus" - id = "triple_citrus" - result = "triple_citrus" - required_reagents = list("lemonjuice" = 1, "limejuice" = 1, "orangejuice" = 1) - result_amount = 3 - mix_message = "The citrus juices begin to blend together." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/triple_citrus/reaction_mob(mob/living/M, method=TOUCH, volume) if(method == INGEST) M.adjustToxLoss(-rand(1,2)) @@ -54,15 +439,6 @@ reagent_state = LIQUID color = "#C8A5DC" -/datum/chemical_reaction/corn_syrup - name = "corn_syrup" - id = "corn_syrup" - result = "corn_syrup" - required_reagents = list("corn_starch" = 1, "sacid" = 1) - result_amount = 2 - min_temp = 374 - mix_message = "The mixture forms a viscous, clear fluid!" - /datum/reagent/corn_syrup name = "Corn Syrup" id = "corn_syrup" @@ -74,15 +450,6 @@ M.reagents.add_reagent("sugar", 1.2) ..() -/datum/chemical_reaction/vhfcs - name = "vhfcs" - id = "vhfcs" - result = "vhfcs" - required_reagents = list("corn_syrup" = 1) - required_catalysts = list("enzyme" = 1) - result_amount = 1 - mix_message = "The mixture emits a sickly-sweet smell." - /datum/reagent/vhfcs name = "Very-high-fructose corn syrup" id = "vhfcs" @@ -94,15 +461,6 @@ M.reagents.add_reagent("sugar", 2.4) ..() -/datum/chemical_reaction/cola - name = "cola" - id = "cola" - result = "cola" - required_reagents = list("carbon" = 1, "oxygen" = 1, "water" = 1, "sugar" = 1) - result_amount = 4 - mix_message = "The mixture begins to fizz." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/honey name = "Honey" id = "honey" @@ -236,18 +594,6 @@ if(volume >= 5 && !istype(T, /turf/space)) new /obj/item/weapon/reagent_containers/food/snacks/cheesewedge(T) -/datum/chemical_reaction/cheese - name = "cheese" - id = "cheese" - result = "cheese" - required_reagents = list("vomit" = 1, "milk" = 1) - result_amount = 1 - mix_message = "The mixture curdles up." - -/datum/chemical_reaction/cheese/on_reaction(datum/reagents/holder) - var/turf/T = get_turf(holder.my_atom) - T.visible_message("A faint cheesy smell drifts through the air...") - /datum/reagent/fake_cheese name = "Cheese substitute" id = "fake_cheese" @@ -279,19 +625,6 @@ if(volume >= 5 && !istype(T, /turf/space)) new /obj/item/weapon/reagent_containers/food/snacks/weirdcheesewedge(T) -/datum/chemical_reaction/weird_cheese - name = "Weird cheese" - id = "weird_cheese" - result = "weird_cheese" - required_reagents = list("green_vomit" = 1, "milk" = 1) - result_amount = 1 - mix_message = "The disgusting mixture sloughs together horribly, emitting a foul stench." - mix_sound = 'sound/goonstation/misc/gurggle.ogg' - -/datum/chemical_reaction/weird_cheese/on_reaction(datum/reagents/holder) - var/turf/T = get_turf(holder.my_atom) - T.visible_message("A horrible smell assaults your nose! What in space is it?") - /datum/reagent/beans name = "Refried beans" id = "beans" @@ -409,15 +742,6 @@ M.Stun(5) M.Paralyse(10) -/datum/chemical_reaction/hydrogenated_soybeanoil - name = "Partially hydrogenated space-soybean oil" - id = "hydrogenated_soybeanoil" - result = "hydrogenated_soybeanoil" - required_reagents = list("soybeanoil" = 1, "hydrogen" = 1) - result_amount = 2 - min_temp = 520 - mix_message = "The mixture emits a burnt, oily smell." - /datum/reagent/meatslurry name = "Meat Slurry" id = "meatslurry" @@ -435,15 +759,6 @@ new /obj/effect/decal/cleanable/blood/gibs/cleangibs(T) playsound(T, 'sound/effects/splat.ogg', 50, 1, -3) -/datum/chemical_reaction/meatslurry - name = "Meat Slurry" - id = "meatslurry" - result = "meatslurry" - required_reagents = list("corn_starch" = 1, "blood" = 1) - result_amount = 2 - mix_message = "The mixture congeals into a bloody mass." - mix_sound = 'sound/effects/blobattack.ogg' - /datum/reagent/mashedpotatoes name = "Mashed potatoes" id = "mashedpotatoes" @@ -458,15 +773,6 @@ reagent_state = LIQUID color = "#B4641B" -/datum/chemical_reaction/gravy - name = "Gravy" - id = "gravy" - result = "gravy" - required_reagents = list("porktonium" = 1, "corn_starch" = 1, "milk" = 1) - result_amount = 3 - min_temp = 374 - mix_message = "The substance thickens and takes on a meaty odor." - /datum/reagent/beff name = "Beff" id = "beff" @@ -484,15 +790,6 @@ M.emote(pick("groan","moan")) ..() -/datum/chemical_reaction/beff - name = "Beff" - id = "beff" - result = "beff" - required_reagents = list("hydrogenated_soybeanoil" = 2, "meatslurry" = 1, "plasma" = 1) - result_amount = 4 - mix_message = "The mixture solidifies, taking a crystalline appearance." - mix_sound = 'sound/effects/blobattack.ogg' - /datum/reagent/pepperoni name = "Pepperoni" id = "pepperoni" @@ -521,16 +818,6 @@ M.emote("burp") to_chat(M, "My goodness, that was tasty!") - -/datum/chemical_reaction/pepperoni - name = "Pepperoni" - id = "pepperoni" - result = "pepperoni" - required_reagents = list("beff" = 1, "saltpetre" = 1, "synthflesh" = 1) - result_amount = 2 - mix_message = "The beff and the synthflesh combine to form a smoky red log." - mix_sound = 'sound/effects/blobattack.ogg' - /datum/reagent/cholesterol name = "cholesterol" id = "cholesterol" diff --git a/code/modules/reagents/newchem/medicine.dm b/code/modules/reagents/chemistry/reagents/medicine.dm similarity index 75% rename from code/modules/reagents/newchem/medicine.dm rename to code/modules/reagents/chemistry/reagents/medicine.dm index a84ac83f385..2cbf4bdbd00 100644 --- a/code/modules/reagents/newchem/medicine.dm +++ b/code/modules/reagents/chemistry/reagents/medicine.dm @@ -1,8 +1,146 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 +/datum/reagent/hydrocodone + name = "Hydrocodone" + id = "hydrocodone" + description = "An extremely effective painkiller; may have long term abuse consequences." + reagent_state = LIQUID + color = "#C805DC" + metabolization_rate = 0.3 // Lasts 1.5 minutes for 15 units + shock_reduction = 200 + +/datum/reagent/hydrocodone/on_mob_life(mob/living/M) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H.traumatic_shock < 100) + H.shock_stage = 0 + ..() + +/datum/reagent/sterilizine + name = "Sterilizine" + id = "sterilizine" + description = "Sterilizes wounds in preparation for surgery." + reagent_state = LIQUID + color = "#C8A5DC" // rgb: 200, 165, 220 + + //makes you squeaky clean +/datum/reagent/sterilizine/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method == TOUCH) + M.germ_level -= min(volume*20, M.germ_level) + +/datum/reagent/sterilizine/reaction_obj(obj/O, volume) + O.germ_level -= min(volume*20, O.germ_level) + +/datum/reagent/sterilizine/reaction_turf(turf/T, volume) + T.germ_level -= min(volume*20, T.germ_level) + +/datum/reagent/synaptizine + name = "Synaptizine" + id = "synaptizine" + description = "Synaptizine is used to treat neuroleptic shock. Can be used to help remove disabling symptoms such as paralysis." + reagent_state = LIQUID + color = "#FA46FA" + overdose_threshold = 40 + +/datum/reagent/synaptizine/on_mob_life(mob/living/M) + M.AdjustDrowsy(-5) + M.AdjustParalysis(-1) + M.AdjustStunned(-1) + M.AdjustWeakened(-1) + M.SetSleeping(0) + if(prob(50)) + M.adjustBrainLoss(-1.0) + ..() + +/datum/reagent/synaptizine/overdose_process(mob/living/M, severity) + var/effect = ..() + if(severity == 1) + if(effect <= 1) + M.visible_message("[M] suddenly and violently vomits!") + M.fakevomit(no_text = 1) + else if(effect <= 3) + M.emote(pick("groan","moan")) + if(effect <= 8) + M.adjustToxLoss(1) + else if(severity == 2) + if(effect <= 2) + M.visible_message("[M] suddenly and violently vomits!") + M.fakevomit(no_text = 1) + else if(effect <= 5) + M.visible_message("[M] staggers and drools, their eyes bloodshot!") + M.Dizzy(8) + M.Weaken(4) + if(effect <= 15) + M.adjustToxLoss(1) + +/datum/reagent/mitocholide + name = "Mitocholide" + id = "mitocholide" + description = "A specialized drug that stimulates the mitochondria of cells to encourage healing of internal organs." + reagent_state = LIQUID + color = "#C8A5DC" // rgb: 200, 165, 220 + +/datum/reagent/mitocholide/on_mob_life(mob/living/M) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + + //Mitocholide is hard enough to get, it's probably fair to make this all internal organs + for(var/name in H.internal_organs) + var/obj/item/organ/internal/I = H.get_int_organ(name) + if(I.damage > 0) + I.damage = max(I.damage-0.4, 0) + ..() + +/datum/reagent/mitocholide/reaction_obj(obj/O, volume) + if(istype(O, /obj/item/organ)) + var/obj/item/organ/Org = O + Org.rejuvenate() + +/datum/reagent/cryoxadone + name = "Cryoxadone" + id = "cryoxadone" + description = "A plasma mixture with almost magical healing powers. Its main limitation is that the targets body temperature must be under 265K for it to metabolise correctly." + reagent_state = LIQUID + color = "#0000C8" // rgb: 200, 165, 220 + heart_rate_decrease = 1 + +/datum/reagent/cryoxadone/on_mob_life(mob/living/M) + if(M.bodytemperature < 265) + M.adjustCloneLoss(-4) + M.adjustOxyLoss(-10) + M.adjustToxLoss(-3) + M.adjustBruteLoss(-12) + M.adjustFireLoss(-12) + M.status_flags &= ~DISFIGURED + ..() + +/datum/reagent/rezadone + name = "Rezadone" + id = "rezadone" + description = "A powder derived from fish toxin, Rezadone can effectively treat genetic damage as well as restoring minor wounds. Overdose will cause intense nausea and minor toxin damage." + reagent_state = SOLID + color = "#669900" // rgb: 102, 153, 0 + overdose_threshold = 30 + +/datum/reagent/rezadone/on_mob_life(mob/living/M) + M.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that. + M.adjustCloneLoss(-1) //What? We just set cloneloss to 0. Why? Simple; this is so external organs properly unmutate. + M.adjustBruteLoss(-1) + M.adjustFireLoss(-1) + M.status_flags &= ~DISFIGURED + ..() + +/datum/reagent/rezadone/overdose_process(mob/living/M, severity) + M.adjustToxLoss(1) + M.Dizzy(5) + M.Jitter(5) + +/datum/reagent/spaceacillin + name = "Spaceacillin" + id = "spaceacillin" + description = "An all-purpose antibiotic agent extracted from space fungus." + reagent_state = LIQUID + color = "#0AB478" + metabolization_rate = 0.2 -#define REM REAGENTS_EFFECT_MULTIPLIER /datum/reagent/silver_sulfadiazine name = "Silver Sulfadiazine" @@ -108,49 +246,6 @@ M.reagents.remove_reagent(R.id,1) ..() -/datum/chemical_reaction/charcoal - name = "Charcoal" - id = "charcoal" - result = "charcoal" - required_reagents = list("ash" = 1, "sodiumchloride" = 1) - result_amount = 2 - mix_message = "The mixture yields a fine black powder." - min_temp = 380 - mix_sound = 'sound/goonstation/misc/fuse.ogg' - -/datum/chemical_reaction/silver_sulfadiazine - name = "Silver Sulfadiazine" - id = "silver_sulfadiazine" - result = "silver_sulfadiazine" - required_reagents = list("ammonia" = 1, "silver" = 1, "sulfur" = 1, "oxygen" = 1, "chlorine" = 1) - result_amount = 5 - mix_message = "A strong and cloying odor begins to bubble from the mixture." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - -/datum/chemical_reaction/salglu_solution - name = "Saline-Glucose Solution" - id = "salglu_solution" - result = "salglu_solution" - required_reagents = list("sodiumchloride" = 1, "water" = 1, "sugar" = 1) - result_amount = 3 - -/datum/chemical_reaction/synthflesh - name = "Synthflesh" - id = "synthflesh" - result = "synthflesh" - required_reagents = list("blood" = 1, "carbon" = 1, "styptic_powder" = 1) - result_amount = 3 - mix_message = "The mixture knits together into a fibrous, bloody mass." - mix_sound = 'sound/effects/blobattack.ogg' - -/datum/chemical_reaction/styptic_powder - name = "Styptic Powder" - id = "styptic_powder" - result = "styptic_powder" - required_reagents = list("aluminum" = 1, "hydrogen" = 1, "oxygen" = 1, "sacid" = 1) - result_amount = 4 - mix_message = "The solution yields an astringent powder." - /datum/reagent/omnizine name = "Omnizine" id = "omnizine" @@ -222,15 +317,6 @@ M.fakevomit() ..() -/datum/chemical_reaction/calomel - name = "Calomel" - id = "calomel" - result = "calomel" - required_reagents = list("mercury" = 1, "chlorine" = 1) - result_amount = 2 - min_temp = 374 - mix_message = "Stinging vapors rise from the solution." - /datum/reagent/potass_iodide name = "Potassium Iodide" id = "potass_iodide" @@ -243,14 +329,6 @@ M.radiation = max(0, M.radiation-1) ..() -/datum/chemical_reaction/potass_iodide - name = "Potassium Iodide" - id = "potass_iodide" - result = "potass_iodide" - required_reagents = list("potassium" = 1, "iodine" = 1) - result_amount = 2 - mix_message = "The solution settles calmly and emits gentle fumes." - /datum/reagent/pen_acid name = "Pentetic Acid" id = "pen_acid" @@ -269,15 +347,6 @@ M.adjustBruteLoss(1*REM) M.adjustFireLoss(1*REM) ..() - return - -/datum/chemical_reaction/pen_acid - name = "Pentetic Acid" - id = "pen_acid" - result = "pen_acid" - required_reagents = list("fuel" = 1, "chlorine" = 1, "ammonia" = 1, "formaldehyde" = 1, "sodium" = 1, "cyanide" = 1) - result_amount = 6 - mix_message = "The substance becomes very still, emitting a curious haze." /datum/reagent/sal_acid name = "Salicylic Acid" @@ -298,15 +367,6 @@ H.shock_stage = 0 ..() -/datum/chemical_reaction/sal_acid - name = "Salicyclic Acid" - id = "sal_acid" - result = "sal_acid" - required_reagents = list("sodium" = 1, "phenol" = 1, "carbon" = 1, "oxygen" = 1, "sacid" = 1) - result_amount = 5 - mix_message = "The mixture crystallizes." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/salbutamol name = "Salbutamol" id = "salbutamol" @@ -320,15 +380,6 @@ M.AdjustLoseBreath(-4) ..() -/datum/chemical_reaction/salbutamol - name = "Salbutamol" - id = "salbutamol" - result = "salbutamol" - required_reagents = list("sal_acid" = 1, "lithium" = 1, "aluminum" = 1, "bromine" = 1, "ammonia" = 1) - result_amount = 5 - mix_message = "The solution bubbles freely, creating a head of bluish foam." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/perfluorodecalin name = "Perfluorodecalin" id = "perfluorodecalin" @@ -348,16 +399,6 @@ M.adjustFireLoss(-1*REM) ..() -/datum/chemical_reaction/perfluorodecalin - name = "Perfluorodecalin" - id = "perfluorodecalin" - result = "perfluorodecalin" - required_reagents = list("hydrogen" = 1, "fluorine" = 1, "oil" = 1) - result_amount = 3 - min_temp = 370 - mix_message = "The mixture rapidly turns into a dense pink liquid." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/ephedrine name = "Ephedrine" id = "ephedrine" @@ -404,14 +445,6 @@ if(effect <= 15) M.emote("collapse") -/datum/chemical_reaction/ephedrine - name = "Ephedrine" - id = "ephedrine" - result = "ephedrine" - required_reagents = list("sugar" = 1, "oil" = 1, "hydrogen" = 1, "diethylamine" = 1) - result_amount = 4 - mix_message = "The solution fizzes and gives off toxic fumes." - /datum/reagent/diphenhydramine name = "Diphenhydramine" id = "diphenhydramine" @@ -432,15 +465,6 @@ M.visible_message("[M] looks a bit dazed.") ..() -/datum/chemical_reaction/diphenhydramine - name = "Diphenhydramine" - id = "diphenhydramine" - result = "diphenhydramine" - required_reagents = list("oil" = 1, "carbon" = 1, "bromine" = 1, "diethylamine" = 1, "ethanol" = 1) - result_amount = 4 - mix_message = "The mixture fizzes gently." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/morphine name = "Morphine" id = "morphine" @@ -487,14 +511,6 @@ M.SetEarDeaf(0) ..() -/datum/chemical_reaction/oculine - name = "Oculine" - id = "oculine" - result = "oculine" - required_reagents = list("atropine" = 1, "spaceacillin" = 1, "salglu_solution" = 1) - result_amount = 3 - mix_message = "The mixture settles, becoming a milky white." - /datum/reagent/oculine name = "Oculine" id = "oculine" @@ -530,14 +546,6 @@ M.reagents.remove_reagent("sarin", 20) ..() -/datum/chemical_reaction/atropine - name = "Atropine" - id = "atropine" - result = "atropine" - required_reagents = list("ethanol" = 1, "acetone" = 1, "diethylamine" = 1, "phenol" = 1, "sacid" = 1) - result_amount = 5 - mix_message = "A horrid smell like something died drifts from the mixture." - /datum/reagent/epinephrine name = "Epinephrine" id = "epinephrine" @@ -590,15 +598,6 @@ if(effect <= 15) M.emote("collapse") -/datum/chemical_reaction/epinephrine - name = "Epinephrine" - id = "epinephrine" - result = "epinephrine" - required_reagents = list("phenol" = 1, "acetone" = 1, "diethylamine" = 1, "oxygen" = 1, "chlorine" = 1, "hydrogen" = 1) - result_amount = 6 - mix_message = "Tiny white crystals precipitate out of the solution." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/strange_reagent name = "Strange Reagent" id = "strange_reagent" @@ -645,14 +644,6 @@ M.adjustToxLoss(2*REM) ..() -/datum/chemical_reaction/strange_reagent - name = "Strange Reagent" - id = "strange_reagent" - result = "strange_reagent" - required_reagents = list("omnizine" = 1, "holywater" = 1, "mutagen" = 1) - result_amount = 3 - mix_message = "The substance begins moving on its own somehow." - /datum/reagent/life name = "Life" id = "life" @@ -661,29 +652,10 @@ color = "#C8A5DC" metabolization_rate = 0.2 -/datum/chemical_reaction/life - name = "Life" - id = "life" - result = null - required_reagents = list("strange_reagent" = 1, "synthflesh" = 1, "blood" = 1) - result_amount = 3 - min_temp = 374 - -/datum/chemical_reaction/life/on_reaction(datum/reagents/holder, created_volume) - chemical_mob_spawn(holder, 1, "Life") - /datum/reagent/mannitol/on_mob_life(mob/living/M) M.adjustBrainLoss(-3) ..() -/datum/chemical_reaction/mannitol - name = "Mannitol" - id = "mannitol" - result = "mannitol" - required_reagents = list("sugar" = 1, "hydrogen" = 1, "water" = 1) - result_amount = 3 - mix_message = "The mixture bubbles slowly, making a slightly sweet odor." - /datum/reagent/mannitol name = "Mannitol" id = "mannitol" @@ -708,15 +680,6 @@ H.update_mutations() ..() -/datum/chemical_reaction/mutadone - name = "Mutadone" - id = "mutadone" - result = "mutadone" - required_reagents = list("mutagen" = 1, "acetone" = 1, "bromine" = 1) - result_amount = 3 - mix_message = "A foul astringent liquid emerges from the reaction." - - /datum/reagent/mutadone name = "Mutadone" id = "mutadone" @@ -737,15 +700,6 @@ M.adjustToxLoss(-2.0) ..() -/datum/chemical_reaction/antihol - name = "antihol" - id = "antihol" - result = "antihol" - required_reagents = list("ethanol" = 1, "charcoal" = 1) - result_amount = 2 - mix_message = "A minty and refreshing smell drifts from the effervescent mixture." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/stimulants name = "Stimulants" id = "stimulants" @@ -775,7 +729,7 @@ M.Stun(3) ..() -/datum/reagent/stimulants/reagent_deleted(mob/living/M) +/datum/reagent/stimulants/on_mob_delete(mob/living/M) M.status_flags |= CANSTUN | CANWEAKEN | CANPARALYSE ..() @@ -800,7 +754,7 @@ M.adjustStaminaLoss(-5*REM) ..() -/datum/reagent/medicine/stimulative_agent/reagent_deleted(mob/living/M) +/datum/reagent/medicine/stimulative_agent/on_mob_delete(mob/living/M) M.status_flags &= ~GOTTAGOFAST ..() @@ -828,14 +782,6 @@ description = "This strange liquid seems to have no bubbles on the surface." color = "#14AA46" -/datum/chemical_reaction/Simethicone - name = "Simethicone" - id = "simethicone" - result = "simethicone" - required_reagents = list("hydrogen" = 1, "chlorine" = 1, "silicon" = 1, "oxygen" = 1) - result_amount = 4 - - /datum/reagent/teporone name = "Teporone" id = "teporone" @@ -852,15 +798,6 @@ M.bodytemperature = min(310, M.bodytemperature + (40 * TEMPERATURE_DAMAGE_COEFFICIENT)) ..() -/datum/chemical_reaction/teporone - name = "Teporone" - id = "teporone" - result = "teporone" - required_reagents = list("acetone" = 1, "silicon" = 1, "plasma" = 1) - result_amount = 2 - mix_message = "The mixture turns an odd lavender color." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/haloperidol name = "Haloperidol" id = "haloperidol" @@ -890,15 +827,6 @@ M.adjustBrainLoss(1) ..() -/datum/chemical_reaction/haloperidol - name = "Haloperidol" - id = "haloperidol" - result = "haloperidol" - required_reagents = list("chlorine" = 1, "fluorine" = 1, "aluminum" = 1, "potass_iodide" = 1, "oil" = 1) - result_amount = 4 - mix_message = "The chemicals mix into an odd pink slush." - - /datum/reagent/ether name = "Ether" id = "ether" @@ -919,14 +847,6 @@ M.Drowsy(20) ..() -/datum/chemical_reaction/ether - name = "Ether" - id = "ether" - result = "ether" - required_reagents = list("sacid" = 1, "ethanol" = 1, "oxygen" = 1) - result_amount = 1 - mix_message = "The mixture yields a pungent odor, which makes you tired." - ////////////////////////////// // Synth-Meds // ////////////////////////////// @@ -940,13 +860,6 @@ color = "#CC7A00" process_flags = SYNTHETIC -/datum/chemical_reaction/degreaser - name = "Degreaser" - id = "degreaser" - result = "degreaser" - required_reagents = list("oil" = 1, "sterilizine" = 1) - result_amount = 2 - /datum/reagent/degreaser/reaction_turf(turf/simulated/T, volume) if(volume >= 1 && istype(T)) if(T.wet) @@ -980,16 +893,6 @@ M.adjustBrainLoss(-3) ..() -/datum/chemical_reaction/liquid_solder - name = "Liquid Solder" - id = "liquid_solder" - result = "liquid_solder" - required_reagents = list("ethanol" = 1, "copper" = 1, "silver" = 1) - result_amount = 3 - min_temp = 370 - mix_message = "The solution gently swirls with a metallic sheen." - - /datum/reagent/medicine/syndicate_nanites //Used exclusively by Syndicate medical cyborgs name = "Restorative Nanites" id = "syndicate_nanites" @@ -1055,4 +958,4 @@ else if(effect <= 8) M.visible_message("[M] stumbles and staggers.") M.Dizzy(5) - M.Weaken(3) + M.Weaken(3) \ No newline at end of file diff --git a/code/modules/reagents/newchem/other.dm b/code/modules/reagents/chemistry/reagents/misc.dm similarity index 61% rename from code/modules/reagents/newchem/other.dm rename to code/modules/reagents/chemistry/reagents/misc.dm index 2ff4a18c3d0..2b0b51ad89e 100644 --- a/code/modules/reagents/newchem/other.dm +++ b/code/modules/reagents/chemistry/reagents/misc.dm @@ -1,7 +1,192 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 -#define REM REAGENTS_EFFECT_MULTIPLIER +/*/datum/reagent/silicate + name = "Silicate" + id = "silicate" + description = "A compound that can be used to reinforce glass." + reagent_state = LIQUID + color = "#C7FFFF" // rgb: 199, 255, 255 + +/datum/reagent/silicate/reaction_obj(obj/O, volume) + if(istype(O, /obj/structure/window)) + if(O:silicate <= 200) + + O:silicate += volume + O:health += volume * 3 + + if(!O:silicateIcon) + var/icon/I = icon(O.icon,O.icon_state,O.dir) + + var/r = (volume / 100) + 1 + var/g = (volume / 70) + 1 + var/b = (volume / 50) + 1 + I.SetIntensity(r,g,b) + O.icon = I + O:silicateIcon = I + else + var/icon/I = O:silicateIcon + + var/r = (volume / 100) + 1 + var/g = (volume / 70) + 1 + var/b = (volume / 50) + 1 + I.SetIntensity(r,g,b) + O.icon = I + O:silicateIcon = I */ + + +/datum/reagent/oxygen + name = "Oxygen" + id = "oxygen" + description = "A colorless, odorless gas." + reagent_state = GAS + color = "#808080" // rgb: 128, 128, 128 + + +/datum/reagent/nitrogen + name = "Nitrogen" + id = "nitrogen" + description = "A colorless, odorless, tasteless gas." + reagent_state = GAS + color = "#808080" // rgb: 128, 128, 128 + + +/datum/reagent/hydrogen + name = "Hydrogen" + id = "hydrogen" + description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas." + reagent_state = GAS + color = "#808080" // rgb: 128, 128, 128 + + +/datum/reagent/potassium + name = "Potassium" + id = "potassium" + description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water." + reagent_state = SOLID + color = "#A0A0A0" // rgb: 160, 160, 160 + + +/datum/reagent/sulfur + name = "Sulfur" + id = "sulfur" + description = "A chemical element." + reagent_state = SOLID + color = "#BF8C00" // rgb: 191, 140, 0 + + +/datum/reagent/sodium + name = "Sodium" + id = "sodium" + description = "A chemical element." + reagent_state = SOLID + color = "#808080" // rgb: 128, 128, 128 + + +/datum/reagent/phosphorus + name = "Phosphorus" + id = "phosphorus" + description = "A chemical element." + reagent_state = SOLID + color = "#832828" // rgb: 131, 40, 40 + + +/datum/reagent/carbon + name = "Carbon" + id = "carbon" + description = "A chemical element." + reagent_state = SOLID + color = "#1C1300" // rgb: 30, 20, 0 + +/datum/reagent/carbon/reaction_turf(turf/T, volume) + if(!istype(T, /turf/space) && !(locate(/obj/effect/decal/cleanable/dirt) in T)) // Only add one dirt per turf. Was causing people to crash. + new /obj/effect/decal/cleanable/dirt(T) + +/datum/reagent/gold + name = "Gold" + id = "gold" + description = "Gold is a dense, soft, shiny metal and the most malleable and ductile metal known." + reagent_state = SOLID + color = "#F7C430" // rgb: 247, 196, 48 + + +/datum/reagent/silver + name = "Silver" + id = "silver" + description = "A lustrous metallic element regarded as one of the precious metals." + reagent_state = SOLID + color = "#D0D0D0" // rgb: 208, 208, 208 + + +/datum/reagent/aluminum + name = "Aluminum" + id = "aluminum" + description = "A silvery white and ductile member of the boron group of chemical elements." + reagent_state = SOLID + color = "#A8A8A8" // rgb: 168, 168, 168 + + +/datum/reagent/silicon + name = "Silicon" + id = "silicon" + description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon." + reagent_state = SOLID + color = "#A8A8A8" // rgb: 168, 168, 168 + + +/datum/reagent/copper + name = "Copper" + id = "copper" + description = "A highly ductile metal." + color = "#6E3B08" // rgb: 110, 59, 8 + + +/datum/reagent/iron + name = "Iron" + id = "iron" + description = "Pure iron is a metal." + reagent_state = SOLID + color = "#C8A5DC" // rgb: 200, 165, 220 + +/datum/reagent/iron/on_mob_life(mob/living/M) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(!H.species.exotic_blood && !(H.species.flags & NO_BLOOD)) + H.vessel.add_reagent("blood", 0.8) + ..() + + +//foam +/datum/reagent/fluorosurfactant + name = "Fluorosurfactant" + id = "fluorosurfactant" + description = "A perfluoronated sulfonic acid that forms a foam when mixed with water." + reagent_state = LIQUID + color = "#9E6B38" // rgb: 158, 107, 56 + +// metal foaming agent +// this is lithium hydride. Add other recipies (e.g. LiH + H2O -> LiOH + H2) eventually +/datum/reagent/ammonia + name = "Ammonia" + id = "ammonia" + description = "A caustic substance commonly used in fertilizer or household cleaners." + reagent_state = GAS + color = "#404030" // rgb: 64, 64, 48 + +/datum/reagent/diethylamine + name = "Diethylamine" + id = "diethylamine" + description = "A secondary amine, useful as a plant nutrient and as building block for other compounds." + reagent_state = LIQUID + color = "#322D00" + + +// Ported from Bay as part of the Botany Update +// Allows you to make planks from any plant that has this reagent in it. +// Also vines with this reagent are considered dense. +/datum/reagent/woodpulp + name = "Wood Pulp" + id = "woodpulp" + description = "A mass of wood fibers." + reagent_state = LIQUID + color = "#B97A57" var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700") @@ -64,50 +249,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 M.adjustToxLoss(1.5) ..() -/datum/chemical_reaction/acetone - name = "acetone" - id = "acetone" - result = "acetone" - required_reagents = list("oil" = 1, "fuel" = 1, "oxygen" = 1) - result_amount = 3 - mix_message = "The smell of paint thinner assaults you as the solution bubbles." - -/datum/chemical_reaction/carpet - name = "carpet" - id = "carpet" - result = "carpet" - required_reagents = list("fungus" = 1, "blood" = 1) - result_amount = 2 - mix_message = "The substance turns thick and stiff, yet soft." - - -/datum/chemical_reaction/oil - name = "Oil" - id = "oil" - result = "oil" - required_reagents = list("fuel" = 1, "carbon" = 1, "hydrogen" = 1) - result_amount = 3 - mix_message = "An iridescent black chemical forms in the container." - -/datum/chemical_reaction/phenol - name = "phenol" - id = "phenol" - result = "phenol" - required_reagents = list("water" = 1, "chlorine" = 1, "oil" = 1) - result_amount = 3 - mix_message = "The mixture bubbles and gives off an unpleasant medicinal odor." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - -/datum/chemical_reaction/ash - name = "Ash" - id = "ash" - result = "ash" - required_reagents = list("oil" = 1) - result_amount = 0.5 - min_temp = 480 - mix_sound = null - no_message = 1 - /datum/reagent/colorful_reagent name = "Colorful Reagent" id = "colorful_reagent" @@ -115,14 +256,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 reagent_state = LIQUID color = "#FFFFFF" -/datum/chemical_reaction/colorful_reagent - name = "colorful_reagent" - id = "colorful_reagent" - result = "colorful_reagent" - required_reagents = list("plasma" = 1, "radium" = 1, "space_drugs" = 1, "cryoxadone" = 1, "triple_citrus" = 1, "stabilizing_agent" = 1) - result_amount = 6 - mix_message = "The substance flashes multiple colors and emits the smell of a pocket protector." - /datum/reagent/colorful_reagent/reaction_mob(mob/living/simple_animal/M, method=TOUCH, volume) if(isanimal(M)) M.color = pick(random_color_list) @@ -138,14 +271,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 T.color = pick(random_color_list) ..() -/datum/chemical_reaction/corgium - name = "corgium" - id = "corgium" - result = null - required_reagents = list("nutriment" = 1, "colorful_reagent" = 1, "strange_reagent" = 1, "blood" = 1) - result_amount = 3 - min_temp = 374 - /datum/reagent/corgium name = "Corgium" id = "corgium" @@ -153,25 +278,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 reagent_state = LIQUID color = "#F9A635" -/datum/chemical_reaction/corgium/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - new /mob/living/simple_animal/pet/corgi(location) - ..() - -/datum/chemical_reaction/flaptonium - name = "Flaptonium" - id = "flaptonium" - result = null - required_reagents = list("egg" = 1, "colorful_reagent" = 1, "chicken_soup" = 1, "strange_reagent" = 1, "blood" = 1) - result_amount = 5 - min_temp = 374 - mix_message = "The substance turns an airy sky-blue and foams up into a new shape." - -/datum/chemical_reaction/flaptonium/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - new /mob/living/simple_animal/parrot(location) - ..() - /datum/reagent/hair_dye name = "Quantum Hair Dye" id = "hair_dye" @@ -179,13 +285,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 reagent_state = LIQUID color = "#960096" -/datum/chemical_reaction/hair_dye - name = "hair_dye" - id = "hair_dye" - result = "hair_dye" - required_reagents = list("colorful_reagent" = 1, "hairgrownium" = 1) - result_amount = 2 - /datum/reagent/hair_dye/reaction_mob(mob/living/M, volume) if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -208,14 +307,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 color = "#5DDA5D" penetrates_skin = 1 -/datum/chemical_reaction/hairgrownium - name = "hairgrownium" - id = "hairgrownium" - result = "hairgrownium" - required_reagents = list("carpet" = 1, "synthflesh" = 1, "ephedrine" = 1) - result_amount = 3 - mix_message = "The liquid becomes slightly hairy." - /datum/reagent/hairgrownium/reaction_mob(mob/living/M, volume) if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -234,15 +325,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 color = "#5DD95D" penetrates_skin = 1 - -/datum/chemical_reaction/super_hairgrownium - name = "Super Hairgrownium" - id = "super_hairgrownium" - result = "super_hairgrownium" - required_reagents = list("iron" = 1, "methamphetamine" = 1, "hairgrownium" = 1) - result_amount = 3 - mix_message = "The liquid becomes amazingly furry and smells peculiar." - /datum/reagent/super_hairgrownium/reaction_mob(mob/living/M, volume) if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -275,14 +357,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 reagent_state = GAS color = "#D06E27" -/datum/chemical_reaction/fartonium - name = "Fartonium" - id = "fartonium" - result = "fartonium" - required_reagents = list("fake_cheese" = 1, "beans" = 1, "????" = 1, "egg" = 1) - result_amount = 2 - mix_message = "The substance makes a little 'toot' noise and starts to smell pretty bad." - /datum/reagent/fartonium/on_mob_life(mob/living/M) if(prob(66)) M.emote("fart") @@ -299,49 +373,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 M.adjustBruteLoss(4) ..() -/datum/chemical_reaction/soapification - name = "Soapification" - id = "soapification" - result = null - required_reagents = list("liquidgibs" = 10, "lye" = 10) // requires two scooped gib tiles - min_temp = 374 - result_amount = 1 - - -/datum/chemical_reaction/soapification/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - new /obj/item/weapon/soap/homemade(location) - -/datum/chemical_reaction/candlefication - name = "Candlefication" - id = "candlefication" - result = null - required_reagents = list("liquidgibs" = 5, "oxygen" = 5) // - min_temp = 374 - result_amount = 1 - -/datum/chemical_reaction/candlefication/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - new /obj/item/candle(location) - -/datum/chemical_reaction/meatification - name = "Meatification" - id = "meatification" - result = null - required_reagents = list("liquidgibs" = 10, "nutriment" = 10, "carbon" = 10) - result_amount = 1 - -/datum/chemical_reaction/meatification/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/meatproduct(location) - -/datum/chemical_reaction/lye - name = "lye" - id = "lye" - result = "lye" - required_reagents = list("sodium" = 1, "hydrogen" = 1, "oxygen" = 1) - result_amount = 3 - /datum/reagent/hugs name = "Pure hugs" id = "hugs" @@ -378,14 +409,6 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 break ..() -/datum/chemical_reaction/love - name = "pure love" - id = "love" - result = "love" - required_reagents = list("hugs" = 1, "chocolate" = 1) - result_amount = 2 - mix_message = "The substance gives off a lovely scent!" - ///Alchemical Reagents /datum/reagent/eyenewt @@ -432,11 +455,4 @@ var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d111 /datum/reagent/royal_bee_jelly/on_mob_life(mob/living/M) if(prob(2)) M.say(pick("Bzzz...","BZZ BZZ","Bzzzzzzzzzzz...")) - ..() - -/datum/chemical_reaction/royal_bee_jelly - name = "royal bee jelly" - id = "royal_bee_jelly" - result = "royal_bee_jelly" - required_reagents = list("mutagen" = 10, "honey" = 40) - result_amount = 5 \ No newline at end of file + ..() \ No newline at end of file diff --git a/code/modules/reagents/oldchem/reagents/reagents_paint.dm b/code/modules/reagents/chemistry/reagents/paint.dm similarity index 100% rename from code/modules/reagents/oldchem/reagents/reagents_paint.dm rename to code/modules/reagents/chemistry/reagents/paint.dm diff --git a/code/modules/reagents/newchem/paradise_pop.dm b/code/modules/reagents/chemistry/reagents/paradise_pop.dm similarity index 100% rename from code/modules/reagents/newchem/paradise_pop.dm rename to code/modules/reagents/chemistry/reagents/paradise_pop.dm diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm new file mode 100644 index 00000000000..73b20340962 --- /dev/null +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic.dm @@ -0,0 +1,325 @@ +/datum/reagent/fuel + name = "Welding fuel" + id = "fuel" + description = "A highly flammable blend of basic hydrocarbons, mostly Acetylene. Useful for both welding and organic chemistry, and can be fortified into a heavier oil." + reagent_state = LIQUID + color = "#060606" + +/datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with welding fuel to make them easy to ignite! + if(method == TOUCH) + M.adjust_fire_stacks(volume / 10) + return + ..() + +/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke + name = "Unholy Water" + id = "unholywater" + description = "Something that shouldn't exist on this plane of existance." + process_flags = ORGANIC | SYNTHETIC //ethereal means everything processes it. + metabolization_rate = 1 + +/datum/reagent/fuel/unholywater/on_mob_life(mob/living/M) + M.adjustBrainLoss(3) + if(iscultist(M)) + M.status_flags |= GOTTAGOFAST + M.AdjustDrowsy(-5) + M.AdjustParalysis(-2) + M.AdjustStunned(-2) + M.AdjustWeakened(-2) + else + M.adjustToxLoss(2) + M.adjustFireLoss(2) + M.adjustOxyLoss(2) + M.adjustBruteLoss(2) + ..() + +/datum/reagent/fuel/unholywater/on_mob_delete(mob/living/M) + M.status_flags &= ~GOTTAGOFAST + ..() + +/datum/reagent/plasma + name = "Plasma" + id = "plasma" + description = "The liquid phase of an unusual extraterrestrial compound." + reagent_state = LIQUID + color = "#7A2B94" + +/datum/reagent/plasma/on_mob_life(mob/living/M) + M.adjustToxLoss(1*REM) + if(holder.has_reagent("epinephrine")) + holder.remove_reagent("epinephrine", 2) + if(iscarbon(M)) + var/mob/living/carbon/C = M + C.adjustPlasma(10) + ..() + +/datum/reagent/plasma/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with plasma is stronger than fuel! + if(method == TOUCH) + M.adjust_fire_stacks(volume / 5) + ..() + + +/datum/reagent/thermite + name = "Thermite" + id = "thermite" + description = "Thermite produces an aluminothermic reaction known as a thermite reaction. Can be used to melt walls." + reagent_state = SOLID + color = "#673910" // rgb: 103, 57, 16 + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/thermite/reaction_turf(turf/simulated/wall/W, volume) + if(volume >= 5 && istype(W)) + W.thermite = 1 + W.overlays.Cut() + W.overlays = image('icons/effects/effects.dmi',icon_state = "thermite") + +/datum/reagent/glycerol + name = "Glycerol" + id = "glycerol" + description = "Glycerol is a simple polyol compound. Glycerol is sweet-tasting and of low toxicity." + reagent_state = LIQUID + color = "#808080" // rgb: 128, 128, 128 + +/datum/reagent/stabilizing_agent + name = "Stabilizing Agent" + id = "stabilizing_agent" + description = "A chemical that stabilises normally volatile compounds, preventing them from reacting immediately." + reagent_state = LIQUID + color = "#FFFF00" + +/datum/reagent/clf3 + name = "Chlorine Trifluoride" + id = "clf3" + description = "An extremely volatile substance, handle with the utmost care." + reagent_state = LIQUID + color = "#FF0000" + metabolization_rate = 4 + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/clf3/on_mob_life(mob/living/M) + M.adjust_fire_stacks(2) + var/burndmg = max(0.3*M.fire_stacks, 0.3) + M.adjustFireLoss(burndmg) + ..() + +/datum/reagent/clf3/reaction_turf(turf/simulated/T, volume) + if(istype(T, /turf/simulated/floor/plating)) + var/turf/simulated/floor/plating/F = T + if(prob(1)) + F.ChangeTurf(/turf/space) + if(istype(T, /turf/simulated/floor/)) + var/turf/simulated/floor/F = T + if(prob(volume/10)) + F.make_plating() + if(istype(F, /turf/simulated/floor/)) + new /obj/effect/hotspot(F) + if(istype(T, /turf/simulated/wall/)) + var/turf/simulated/wall/W = T + if(prob(volume/10)) + W.ChangeTurf(/turf/simulated/floor) + if(istype(T, /turf/simulated/shuttle/)) + new /obj/effect/hotspot(T) + +/datum/reagent/clf3/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method == TOUCH) + M.adjust_fire_stacks(min(volume/5, 10)) + M.IgniteMob() + M.bodytemperature += 30 + +/datum/reagent/sorium + name = "Sorium" + id = "sorium" + description = "Sends everything flying from the detonation point." + reagent_state = LIQUID + color = "#FFA500" + +/datum/reagent/liquid_dark_matter + name = "Liquid Dark Matter" + id = "liquid_dark_matter" + description = "Sucks everything into the detonation point." + reagent_state = LIQUID + color = "#800080" + +/datum/reagent/blackpowder + name = "Black Powder" + id = "blackpowder" + description = "Explodes. Violently." + reagent_state = LIQUID + color = "#000000" + metabolization_rate = 0.05 + penetrates_skin = 1 + +/datum/reagent/blackpowder/reaction_turf(turf/T, volume) //oh shit + if(volume >= 5 && !istype(T, /turf/space)) + if(!locate(/obj/effect/decal/cleanable/dirt/blackpowder) in T) //let's not have hundreds of decals of black powder on the same turf + new /obj/effect/decal/cleanable/dirt/blackpowder(T) + +/* +/datum/reagent/blackpowder/on_ex_act() + var/location = get_turf(holder.my_atom) + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(2, 1, location) + s.start() + sleep(rand(10,15)) + blackpowder_detonate(holder, volume) + holder.remove_reagent("blackpowder", volume) + return */ + +/datum/reagent/flash_powder + name = "Flash Powder" + id = "flash_powder" + description = "Makes a very bright flash." + reagent_state = LIQUID + color = "#FFFF00" + +/datum/reagent/smoke_powder + name = "Smoke Powder" + id = "smoke_powder" + description = "Makes a large cloud of smoke that can carry reagents." + reagent_state = LIQUID + color = "#808080" + +/datum/reagent/sonic_powder + name = "Sonic Powder" + id = "sonic_powder" + description = "Makes a deafening noise." + reagent_state = LIQUID + color = "#0000FF" + +/datum/reagent/phlogiston + name = "Phlogiston" + id = "phlogiston" + description = "Catches you on fire and makes you ignite." + reagent_state = LIQUID + color = "#FF9999" + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, volume) + M.IgniteMob() + ..() + +/datum/reagent/phlogiston/on_mob_life(mob/living/M) + M.adjust_fire_stacks(1) + var/burndmg = max(0.3*M.fire_stacks, 0.3) + M.adjustFireLoss(burndmg) + ..() + +/datum/reagent/napalm + name = "Napalm" + id = "napalm" + description = "Very flammable." + reagent_state = LIQUID + color = "#FF9999" + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/napalm/on_mob_life(mob/living/M) + M.adjust_fire_stacks(1) + ..() + +/datum/reagent/napalm/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method == TOUCH) + M.adjust_fire_stacks(min(volume/4, 20)) + +/datum/reagent/cryostylane + name = "Cryostylane" + id = "cryostylane" + description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Cryostylane slowly cools all other reagents in the mob down to 0K." + color = "#B2B2FF" // rgb: 139, 166, 233 + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/cryostylane/on_mob_life(mob/living/M) //TODO: code freezing into an ice cube + if(M.reagents.has_reagent("oxygen")) + M.reagents.remove_reagent("oxygen", 1) + M.bodytemperature -= 30 + ..() + +/datum/reagent/cryostylane/on_tick() + if(holder.has_reagent("oxygen")) + holder.remove_reagent("oxygen", 1) + holder.chem_temp -= 10 + holder.handle_reactions() + ..() + +/datum/reagent/cryostylane/reaction_turf(turf/T, volume) + if(volume >= 5) + for(var/mob/living/carbon/slime/M in T) + M.adjustToxLoss(rand(15,30)) + +/datum/reagent/pyrosium + name = "Pyrosium" + id = "pyrosium" + description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly cools all other reagents in the mob down to 0K." + color = "#B20000" // rgb: 139, 166, 233 + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/pyrosium/on_mob_life(mob/living/M) + if(M.reagents.has_reagent("oxygen")) + M.reagents.remove_reagent("oxygen", 1) + M.bodytemperature += 30 + ..() + +/datum/reagent/pyrosium/on_tick() + if(holder.has_reagent("oxygen")) + holder.remove_reagent("oxygen", 1) + holder.chem_temp += 10 + holder.handle_reactions() + ..() + +/datum/reagent/firefighting_foam + name = "Firefighting foam" + id = "firefighting_foam" + description = "Carbon Tetrachloride is a foam used for fire suppression." + reagent_state = LIQUID + color = "#A0A090" + var/cooling_temperature = 3 // more effective than water + +/datum/reagent/firefighting_foam/reaction_mob(mob/living/M, method=TOUCH, volume) +// Put out fire + if(method == TOUCH) + M.adjust_fire_stacks(-(volume / 5)) // more effective than water + M.ExtinguishMob() + +/datum/reagent/firefighting_foam/reaction_obj(obj/O, volume) + if(istype(O)) + O.extinguish() + +/datum/reagent/firefighting_foam/reaction_turf(turf/simulated/T, volume) + if(!istype(T)) + return + var/CT = cooling_temperature + new /obj/effect/decal/cleanable/flour/foam(T) //foam mess; clears up quickly. + var/hotspot = (locate(/obj/effect/hotspot) in T) + if(hotspot) + var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles()) + lowertemp.temperature = max(min(lowertemp.temperature-(CT*1000), lowertemp.temperature / CT), 0) + lowertemp.react() + T.assume_air(lowertemp) + qdel(hotspot) + +/datum/reagent/plasma_dust + name = "Plasma Dust" + id = "plasma_dust" + description = "A fine dust of plasma. This chemical has unusual mutagenic properties for viruses and slimes alike." + color = "#500064" // rgb: 80, 0, 100 + +/datum/reagent/plasma_dust/on_mob_life(mob/living/M) + M.adjustToxLoss(3) + if(iscarbon(M)) + var/mob/living/carbon/C = M + C.adjustPlasma(20) + ..() + +/datum/reagent/plasma_dust/reaction_obj(obj/O, volume) + if((!O) || (!volume)) + return 0 + O.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, volume) + +/datum/reagent/plasma_dust/reaction_turf(turf/simulated/T, volume) + if(istype(T)) + T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, volume) + +/datum/reagent/plasma_dust/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with plasma dust is stronger than fuel! + if(method == TOUCH) + M.adjust_fire_stacks(volume / 5) + return + ..() diff --git a/code/modules/reagents/newchem/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm similarity index 63% rename from code/modules/reagents/newchem/toxins.dm rename to code/modules/reagents/chemistry/reagents/toxins.dm index d8e8205b1f7..4585e8df667 100644 --- a/code/modules/reagents/newchem/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -1,8 +1,417 @@ -#define SOLID 1 -#define LIQUID 2 -#define GAS 3 +/datum/reagent/toxin + name = "Toxin" + id = "toxin" + description = "A Toxic chemical." + reagent_state = LIQUID + color = "#CF3600" // rgb: 207, 54, 0 -#define REM REAGENTS_EFFECT_MULTIPLIER +/datum/reagent/toxin/on_mob_life(mob/living/M) + M.adjustToxLoss(2) + ..() + +/datum/reagent/spider_venom + name = "Spider venom" + id = "spidertoxin" + description = "A toxic venom injected by spacefaring arachnids." + reagent_state = LIQUID + color = "#CF3600" // rgb: 207, 54, 0 + +/datum/reagent/spider_venom/on_mob_life(mob/living/M) + M.adjustToxLoss(1.5) + ..() + +/datum/reagent/plasticide + name = "Plasticide" + id = "plasticide" + description = "Liquid plastic, do not eat." + reagent_state = LIQUID + color = "#CF3600" // rgb: 207, 54, 0 + +/datum/reagent/plasticide/on_mob_life(mob/living/M) + M.adjustToxLoss(1.5) + ..() + + +/datum/reagent/minttoxin + name = "Mint Toxin" + id = "minttoxin" + description = "Useful for dealing with undesirable customers." + reagent_state = LIQUID + color = "#CF3600" // rgb: 207, 54, 0 + +/datum/reagent/minttoxin/on_mob_life(mob/living/M) + if(FAT in M.mutations) + M.gib() + ..() + +/datum/reagent/slimejelly + name = "Slime Jelly" + id = "slimejelly" + description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL." + reagent_state = LIQUID + color = "#801E28" // rgb: 128, 30, 40 + +/datum/reagent/slimejelly/on_mob_life(mob/living/M) + if(prob(10)) + to_chat(M, "Your insides are burning!") + M.adjustToxLoss(rand(20,60)*REM) + else if(prob(40)) + M.adjustBruteLoss(-5*REM) + ..() + +/datum/reagent/slimetoxin + name = "Mutation Toxin" + id = "mutationtoxin" + description = "A corruptive toxin produced by slimes." + reagent_state = LIQUID + color = "#13BC5E" // rgb: 19, 188, 94 + +/datum/reagent/slimetoxin/on_mob_life(mob/living/M) + if(ishuman(M)) + var/mob/living/carbon/human/human = M + if(human.species.name != "Shadow") + to_chat(M, "Your flesh rapidly mutates!") + to_chat(M, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") + to_chat(M, "Your body reacts violently to light. \green However, it naturally heals in darkness.") + to_chat(M, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") + human.set_species("Shadow") + ..() + +/datum/reagent/aslimetoxin + name = "Advanced Mutation Toxin" + id = "amutationtoxin" + description = "An advanced corruptive toxin produced by slimes." + reagent_state = LIQUID + color = "#13BC5E" // rgb: 19, 188, 94 + +/datum/reagent/aslimetoxin/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method != TOUCH) + M.ForceContractDisease(new /datum/disease/transformation/slime(0)) + + +/datum/reagent/mercury + name = "Mercury" + id = "mercury" + description = "A chemical element." + reagent_state = LIQUID + color = "#484848" // rgb: 72, 72, 72 + metabolization_rate = 0.2 + penetrates_skin = 1 + +/datum/reagent/mercury/on_mob_life(mob/living/M) + if(prob(70)) + M.adjustBrainLoss(1) + ..() + +/datum/reagent/chlorine + name = "Chlorine" + id = "chlorine" + description = "A chemical element." + reagent_state = GAS + color = "#808080" // rgb: 128, 128, 128 + penetrates_skin = 1 + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/chlorine/on_mob_life(mob/living/M) + M.adjustFireLoss(1) + ..() + +/datum/reagent/fluorine + name = "Fluorine" + id = "fluorine" + description = "A highly-reactive chemical element." + reagent_state = GAS + color = "#6A6054" + penetrates_skin = 1 + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/fluorine/on_mob_life(mob/living/M) + M.adjustFireLoss(1) + M.adjustToxLoss(1*REM) + ..() + +/datum/reagent/radium + name = "Radium" + id = "radium" + description = "Radium is an alkaline earth metal. It is extremely radioactive." + reagent_state = SOLID + color = "#C7C7C7" // rgb: 199,199,199 + metabolization_rate = 0.4 + penetrates_skin = 1 + +/datum/reagent/radium/on_mob_life(mob/living/M) + if(M.radiation < 80) + M.apply_effect(4, IRRADIATE, negate_armor = 1) + ..() + +/datum/reagent/radium/reaction_turf(turf/T, volume) + if(volume >= 3 && !istype(T, /turf/space)) + new /obj/effect/decal/cleanable/greenglow(T) + +/datum/reagent/mutagen + name = "Unstable mutagen" + id = "mutagen" + description = "Might cause unpredictable mutations. Keep away from children." + reagent_state = LIQUID + color = "#04DF27" + metabolization_rate = 0.3 + +/datum/reagent/mutagen/reaction_mob(mob/living/M, method=TOUCH, volume) + if(!..()) + return + if(!M.dna) + return //No robots, AIs, aliens, Ians or other mobs should be affected by this. + if((method==TOUCH && prob(33)) || method==INGEST) + randmutb(M) + domutcheck(M, null) + M.UpdateAppearance() + +/datum/reagent/mutagen/on_mob_life(mob/living/M) + if(!M.dna) + return //No robots, AIs, aliens, Ians or other mobs should be affected by this. + M.apply_effect(2*REM, IRRADIATE, negate_armor = 1) + if(prob(4)) + randmutb(M) + ..() + + +/datum/reagent/uranium + name ="Uranium" + id = "uranium" + description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." + reagent_state = SOLID + color = "#B8B8C0" // rgb: 184, 184, 192 + +/datum/reagent/uranium/on_mob_life(mob/living/M) + M.apply_effect(2, IRRADIATE, negate_armor = 1) + ..() + +/datum/reagent/uranium/reaction_turf(turf/T, volume) + if(volume >= 3 && !istype(T, /turf/space)) + new /obj/effect/decal/cleanable/greenglow(T) + + +/datum/reagent/lexorin + name = "Lexorin" + id = "lexorin" + description = "Lexorin temporarily stops respiration. Causes tissue damage." + reagent_state = LIQUID + color = "#52685D" + metabolization_rate = 0.2 + +/datum/reagent/lexorin/on_mob_life(mob/living/M) + M.adjustToxLoss(1) + ..() + + +/datum/reagent/sacid + name = "Sulphuric acid" + id = "sacid" + description = "A strong mineral acid with the molecular formula H2SO4." + reagent_state = LIQUID + color = "#00D72B" + process_flags = ORGANIC | SYNTHETIC + +/datum/reagent/sacid/on_mob_life(mob/living/M) + M.adjustFireLoss(1) + ..() + +/datum/reagent/sacid/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method == TOUCH) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + + if(volume > 25) + + if(H.wear_mask) + to_chat(H, "Your mask protects you from the acid!") + return + + if(H.head) + to_chat(H, "Your helmet protects you from the acid!") + return + + if(!M.unacidable) + if(prob(75)) + var/obj/item/organ/external/affecting = H.get_organ("head") + if(affecting) + affecting.take_damage(5, 10) + H.UpdateDamageIcon() + H.emote("scream") + else + M.take_organ_damage(5,10) + else + M.take_organ_damage(5,10) + + if(method == INGEST) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + + if(volume < 10) + to_chat(M, "The greenish acidic substance stings you, but isn't concentrated enough to harm you!") + + if(volume >=10 && volume <=25) + if(!H.unacidable) + M.take_organ_damage(0,min(max(volume-10,2)*2,20)) + M.emote("scream") + + + if(volume > 25) + if(!M.unacidable) + if(prob(75)) + var/obj/item/organ/external/affecting = H.get_organ("head") + if(affecting) + affecting.take_damage(0, 20) + H.UpdateDamageIcon() + H.emote("scream") + else + M.take_organ_damage(0,20) + +/datum/reagent/sacid/reaction_obj(obj/O, volume) + if((istype(O,/obj/item) || istype(O,/obj/effect/glowshroom)) && prob(40)) + if(!O.unacidable) + var/obj/effect/decal/cleanable/molten_item/I = new/obj/effect/decal/cleanable/molten_item(O.loc) + I.desc = "Looks like this was \an [O] some time ago." + O.visible_message("[O] melts.") + qdel(O) + + +/datum/reagent/hellwater + name = "Hell Water" + id = "hell_water" + description = "YOUR FLESH! IT BURNS!" + process_flags = ORGANIC | SYNTHETIC //Admin-bus has no brakes! KILL THEM ALL. + metabolization_rate = 1 + +/datum/reagent/hellwater/on_mob_life(mob/living/M) + M.fire_stacks = min(5, M.fire_stacks + 3) + M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire + M.adjustToxLoss(1) + M.adjustFireLoss(1) //Hence the other damages... ain't I a bastard? + M.adjustBrainLoss(5) + ..() + + +/datum/reagent/carpotoxin + name = "Carpotoxin" + id = "carpotoxin" + description = "A deadly neurotoxin produced by the dreaded spess carp." + reagent_state = LIQUID + color = "#003333" // rgb: 0, 51, 51 + +/datum/reagent/carpotoxin/on_mob_life(mob/living/M) + M.adjustToxLoss(2*REM) + ..() + +/datum/reagent/staminatoxin + name = "Tirizene" + id = "tirizene" + description = "A toxin that affects the stamina of a person when injected into the bloodstream." + reagent_state = LIQUID + color = "#6E2828" + data = 13 + +/datum/reagent/staminatoxin/on_mob_life(mob/living/M) + M.adjustStaminaLoss(REM * data) + data = max(data - 1, 3) + ..() + + +/datum/reagent/spore + name = "Spore Toxin" + id = "spore" + description = "A natural toxin produced by blob spores that inhibits vision when ingested." + color = "#9ACD32" + +/datum/reagent/spores/on_mob_life(mob/living/M) + M.adjustToxLoss(1) + M.damageoverlaytemp = 60 + M.EyeBlurry(3) + ..() + +/datum/reagent/beer2 //disguised as normal beer for use by emagged brobots + name = "Beer" + id = "beer2" + description = "An alcoholic beverage made from malted grains, hops, yeast, and water." + color = "#664300" // rgb: 102, 67, 0 + metabolization_rate = 1.5 * REAGENTS_METABOLISM + +/datum/reagent/beer2/on_mob_life(mob/living/M) + switch(current_cycle) + if(1 to 50) + M.AdjustSleeping(1) + if(51 to INFINITY) + M.AdjustSleeping(1) + M.adjustToxLoss((current_cycle - 50)*REM) + ..() + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/datum/reagent/condensedcapsaicin + name = "Condensed Capsaicin" + id = "condensedcapsaicin" + description = "This shit goes in pepperspray." + reagent_state = LIQUID + color = "#B31008" // rgb: 179, 16, 8 + +/datum/reagent/condensedcapsaicin/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method == TOUCH) + if(ishuman(M)) + var/mob/living/carbon/human/victim = M + var/mouth_covered = 0 + var/eyes_covered = 0 + var/obj/item/safe_thing = null + if( victim.wear_mask ) + if( victim.wear_mask.flags & MASKCOVERSEYES ) + eyes_covered = 1 + safe_thing = victim.wear_mask + if( victim.wear_mask.flags & MASKCOVERSMOUTH ) + mouth_covered = 1 + safe_thing = victim.wear_mask + if( victim.head ) + if( victim.head.flags & MASKCOVERSEYES ) + eyes_covered = 1 + safe_thing = victim.head + if( victim.head.flags & MASKCOVERSMOUTH ) + mouth_covered = 1 + safe_thing = victim.head + if(victim.glasses) + eyes_covered = 1 + if( !safe_thing ) + safe_thing = victim.glasses + if( eyes_covered && mouth_covered ) + to_chat(victim, "Your [safe_thing] protects you from the pepperspray!") + return + else if( mouth_covered ) // Reduced effects if partially protected + to_chat(victim, "Your [safe_thing] protect you from most of the pepperspray!") + if(prob(5)) + victim.emote("scream") + victim.EyeBlurry(3) + victim.EyeBlind(1) + victim.Confused(3) + victim.damageoverlaytemp = 60 + victim.Weaken(3) + victim.drop_item() + return + else if( eyes_covered ) // Eye cover is better than mouth cover + to_chat(victim, "Your [safe_thing] protects your eyes from the pepperspray!") + victim.EyeBlurry(3) + victim.damageoverlaytemp = 30 + return + else // Oh dear :D + if(prob(5)) + victim.emote("scream") + to_chat(victim, "You're sprayed directly in the eyes with pepperspray!") + victim.EyeBlurry(5) + victim.EyeBlind(2) + victim.Confused(6) + victim.damageoverlaytemp = 75 + victim.Weaken(5) + victim.drop_item() + +/datum/reagent/condensedcapsaicin/on_mob_life(mob/living/M) + if(prob(5)) + M.visible_message("[M] [pick("dry heaves!","coughs!","splutters!")]") + ..() /datum/reagent/polonium name = "Polonium" @@ -105,15 +514,6 @@ M.reagents.add_reagent("histamine",rand(5,15)) ..() -/datum/chemical_reaction/formaldehyde - name = "formaldehyde" - id = "formaldehyde" - result = "formaldehyde" - required_reagents = list("ethanol" = 1, "oxygen" = 1, "silver" = 1) - result_amount = 3 - min_temp = 420 - mix_message = "Ugh, it smells like the morgue in here." - /datum/reagent/venom name = "Venom" id = "venom" @@ -182,16 +582,6 @@ M.adjustToxLoss(1) ..() -/datum/chemical_reaction/neurotoxin2 - name = "neurotoxin2" - id = "neurotoxin2" - result = "neurotoxin2" - required_reagents = list("space_drugs" = 1) - result_amount = 1 - min_temp = 674 - mix_sound = null - no_message = 1 - /datum/reagent/cyanide name = "Cyanide" id = "cyanide" @@ -215,23 +605,6 @@ M.adjustToxLoss(2) ..() -/datum/chemical_reaction/cyanide - name = "Cyanide" - id = "cyanide" - result = "cyanide" - required_reagents = list("oil" = 1, "ammonia" = 1, "oxygen" = 1) - result_amount = 3 - min_temp = 380 - mix_message = "The mixture gives off a faint scent of almonds." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - -/datum/chemical_reaction/cyanide/on_reaction(datum/reagents/holder) - var/turf/T = get_turf(holder.my_atom) - T.visible_message("The solution generates a strong vapor!") - for(var/mob/living/carbon/C in range(T, 1)) - if(C.can_breathe_gas()) - C.reagents.add_reagent("cyanide", 7) - /datum/reagent/itching_powder name = "Itching Powder" id = "itching_powder" @@ -266,15 +639,6 @@ M.emote("scream") ..() -/datum/chemical_reaction/itching_powder - name = "Itching Powder" - id = "itching_powder" - result = "itching_powder" - required_reagents = list("fuel" = 1, "ammonia" = 1, "fungus" = 1) - result_amount = 3 - mix_message = "The mixture congeals and dries up, leaving behind an abrasive powder." - mix_sound = 'sound/effects/blobattack.ogg' - /datum/reagent/facid/on_mob_life(mob/living/M) M.adjustToxLoss(1*REM) M.adjustFireLoss(1) @@ -338,15 +702,6 @@ O.visible_message("[O] melts.") qdel(O) -/datum/chemical_reaction/facid - name = "Fluorosulfuric Acid" - id = "facid" - result = "facid" - required_reagents = list("sacid" = 1, "fluorine" = 1, "hydrogen" = 1, "potassium" = 1) - result_amount = 4 - min_temp = 380 - mix_message = "The mixture deepens to a dark blue, and slowly begins to corrode its container." - /datum/reagent/initropidril name = "Initropidril" id = "initropidril" @@ -377,15 +732,6 @@ H.heart_attack = 1 // rip in pepperoni ..() -/datum/chemical_reaction/initropidril - name = "Initropidril" - id = "initropidril" - result = "initropidril" - required_reagents = list("crank" = 1, "histamine" = 1, "krokodil" = 1, "bath_salts" = 1, "atropine" = 1, "nicotine" = 1, "morphine" = 1) - result_amount = 4 - mix_message = "A sweet and sugary scent drifts from the unpleasant milky substance." - - /datum/reagent/concentrated_initro name = "Concentrated Initropidril" id = "concentrated_initro" @@ -492,15 +838,6 @@ color = "#6BA688" metabolization_rate = 0.1 -/datum/chemical_reaction/sulfonal - name = "sulfonal" - id = "sulfonal" - result = "sulfonal" - required_reagents = list("acetone" = 1, "diethylamine" = 1, "sulfur" = 1) - result_amount = 3 - mix_message = "The mixture gives off quite a stench." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - /datum/reagent/sulfonal/on_mob_life(mob/living/M) M.AdjustJitter(-30) switch(current_cycle) @@ -526,7 +863,7 @@ reagent_state = LIQUID color = "#D9D9D9" -/datum/reagent/amanitin/reagent_deleted(mob/living/M) +/datum/reagent/amanitin/on_mob_delete(mob/living/M) M.adjustToxLoss(current_cycle*rand(2,4)) ..() @@ -538,13 +875,6 @@ color = "#D1DED1" metabolization_rate = 0.2 -/datum/chemical_reaction/lipolicide - name = "lipolicide" - id = "lipolicide" - result = "lipolicide" - required_reagents = list("mercury" = 1, "diethylamine" = 1, "ephedrine" = 1) - result_amount = 3 - /datum/reagent/lipolicide/on_mob_life(mob/living/M) if(!M.nutrition) switch(rand(1,3)) @@ -616,23 +946,6 @@ penetrates_skin = 1 overdose_threshold = 25 -/datum/chemical_reaction/sarin - name = "sarin" - id = "sarin" - result = "sarin" - required_reagents = list("chlorine" = 1, "fuel" = 1, "oxygen" = 1, "phosphorus" = 1, "fluorine" = 1, "hydrogen" = 1, "acetone" = 1, "atrazine" = 1) - result_amount = 3 - mix_message = "The mixture yields a colorless, odorless liquid." - min_temp = 374 - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - -/datum/chemical_reaction/sarin/on_reaction(datum/reagents/holder) - var/turf/T = get_turf(holder.my_atom) - T.visible_message("The solution generates a strong vapor!") - for(var/mob/living/carbon/C in range(T, 2)) - if(C.can_breathe_gas()) - C.reagents.add_reagent("sarin", 4) - /datum/reagent/sarin/on_mob_life(mob/living/M) switch(current_cycle) if(1 to 15) @@ -727,14 +1040,6 @@ D.adjustHealth(100) ..() -/datum/chemical_reaction/atrazine - name = "atrazine" - id = "atrazine" - result = "atrazine" - required_reagents = list("chlorine" = 1, "hydrogen" = 1, "nitrogen" = 1) - result_amount = 3 - mix_message = "The mixture gives off a harsh odor" - /datum/reagent/capulettium name = "Capulettium" id = "capulettium" @@ -743,14 +1048,6 @@ color = "#60A584" heart_rate_stop = 1 -/datum/chemical_reaction/capulettium - name = "capulettium" - id = "capulettium" - result = "capulettium" - required_reagents = list("neurotoxin2" = 1, "chlorine" = 1, "hydrogen" = 1) - result_amount = 1 - mix_message = "The smell of death wafts up from the solution." - /datum/reagent/capulettium/on_mob_life(mob/living/M) switch(current_cycle) if(1 to 5) @@ -774,14 +1071,6 @@ color = "#60A584" heart_rate_stop = 1 -/datum/chemical_reaction/capulettium_plus - name = "capulettium_plus" - id = "capulettium_plus" - result = "capulettium_plus" - required_reagents = list("capulettium" = 1, "ephedrine" = 1, "methamphetamine" = 1) - result_amount = 3 - mix_message = "The solution begins to slosh about violently by itself." - /datum/reagent/capulettium_plus/on_mob_life(mob/living/M) M.Silence(2) ..() @@ -868,20 +1157,4 @@ shock_timer = 0 M.electrocute_act(rand(5,20), "Teslium in their body", 1, 1) //Override because it's caused from INSIDE of you playsound(M, "sparks", 50, 1) - ..() - -/datum/chemical_reaction/teslium - name = "Teslium" - id = "teslium" - result = "teslium" - required_reagents = list("plasma" = 1, "silver" = 1, "blackpowder" = 1) - result_amount = 3 - mix_message = "A jet of sparks flies from the mixture as it merges into a flickering slurry." - min_temp = 400 - mix_sound = null - -/datum/chemical_reaction/teslium/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(6, 1, location) - s.start() + ..() \ No newline at end of file diff --git a/code/modules/reagents/oldchem/reagents/reagents_water.dm b/code/modules/reagents/chemistry/reagents/water.dm similarity index 100% rename from code/modules/reagents/oldchem/reagents/reagents_water.dm rename to code/modules/reagents/chemistry/reagents/water.dm diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm new file mode 100644 index 00000000000..28994d10fb2 --- /dev/null +++ b/code/modules/reagents/chemistry/recipes.dm @@ -0,0 +1,81 @@ +/////////////////////////////////////////////////////////////////////////////////// +/datum/chemical_reaction + var/name = null + var/id = null + var/result = null + var/list/required_reagents = list() + var/list/required_catalysts = list() + + // Both of these variables are mostly going to be used with slime cores - but if you want to, you can use them for other things + var/atom/required_container = null // the container required for the reaction to happen + var/required_other = 0 // an integer required for the reaction to happen + + var/result_amount = 0 + var/secondary = 0 // set to nonzero if secondary reaction + var/list/secondary_results = list() //additional reagents produced by the reaction + var/min_temp = 0 //Minimum temperature required for the reaction to occur (heat to/above this). min_temp = 0 means no requirement + var/max_temp = 9999 //Maximum temperature allowed for the reaction to occur (cool to/below this). + var/mix_message = "The solution begins to bubble." + var/mix_sound = 'sound/effects/bubbles.ogg' + var/no_message = 0 + +/datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, created_volume) + return + +var/list/chemical_mob_spawn_meancritters = list() // list of possible hostile mobs +var/list/chemical_mob_spawn_nicecritters = list() // and possible friendly mobs +/datum/chemical_reaction/proc/chemical_mob_spawn(datum/reagents/holder, amount_to_spawn, reaction_name, mob_faction = "chemicalsummon") + if(holder && holder.my_atom) + if(chemical_mob_spawn_meancritters.len <= 0 || chemical_mob_spawn_nicecritters.len <= 0) + for(var/T in typesof(/mob/living/simple_animal)) + var/mob/living/simple_animal/SA = T + switch(initial(SA.gold_core_spawnable)) + if(CHEM_MOB_SPAWN_HOSTILE) + chemical_mob_spawn_meancritters += T + if(CHEM_MOB_SPAWN_FRIENDLY) + chemical_mob_spawn_nicecritters += T + var/atom/A = holder.my_atom + var/turf/T = get_turf(A) + var/area/my_area = get_area(T) + var/message = "A [reaction_name] reaction has occured in [my_area.name]. (JMP)" + message += " (VV)" + + var/mob/M = get(A, /mob) + if(M) + message += " - Carried By: [key_name_admin(M)](?) (FLW)" + else + message += " - Last Fingerprint: [(A.fingerprintslast ? A.fingerprintslast : "N/A")]" + + message_admins(message, 0, 1) + + playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) + + for(var/mob/living/carbon/C in viewers(get_turf(holder.my_atom), null)) + C.flash_eyes() + for(var/i = 1, i <= amount_to_spawn, i++) + var/chosen + if(reaction_name == "Friendly Gold Slime") + chosen = pick(chemical_mob_spawn_nicecritters) + else + chosen = pick(chemical_mob_spawn_meancritters) + var/mob/living/simple_animal/C = new chosen + C.faction |= mob_faction + C.forceMove(get_turf(holder.my_atom)) + if(prob(50)) + for(var/j = 1, j <= rand(1, 3), j++) + step(C, pick(NORTH,SOUTH,EAST,WEST)) + +/proc/goonchem_vortex(turf/simulated/T, setting_type, range, pull_times) + for(var/atom/movable/X in orange(range, T)) + if(istype(X, /obj/effect)) + continue //stop pulling smoke and hotspots please + if(istype(X, /atom/movable)) + if((X) && !X.anchored) + if(setting_type) + playsound(T, 'sound/effects/bang.ogg', 25, 1) + for(var/i = 0, i < pull_times, i++) + step_away(X,T) + else + playsound(T, 'sound/effects/whoosh.ogg', 25, 1) //credit to Robinhood76 of Freesound.org for this. + for(var/i = 0, i < pull_times, i++) + step_towards(X,T) \ No newline at end of file diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm b/code/modules/reagents/chemistry/recipes/drinks.dm similarity index 86% rename from code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm rename to code/modules/reagents/chemistry/recipes/drinks.dm index 1b69b88e071..fb10986cd0b 100644 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_drink.dm +++ b/code/modules/reagents/chemistry/recipes/drinks.dm @@ -676,3 +676,103 @@ required_reagents = list("spacemountainwind" = 1, "coffee" = 1) result_amount = 2 mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/reagent/ginsonic + name = "Gin and sonic" + id = "ginsonic" + description = "GOTTA GET CRUNK FAST BUT LIQUOR TOO SLOW" + reagent_state = LIQUID + color = "#1111CF" + +/datum/chemical_reaction/ginsonic + name = "ginsonic" + id = "ginsonic" + result = "ginsonic" + required_reagents = list("gintonic" = 1, "methamphetamine" = 1) + result_amount = 2 + mix_message = "The drink turns electric blue and starts quivering violently." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/applejack + name = "applejack" + id = "applejack" + result = "applejack" + required_reagents = list("cider" = 2) + max_temp = 270 + result_amount = 1 + mix_message = "The drink darkens as the water freezes, leaving the concentrated cider behind." + mix_sound = null + +/datum/chemical_reaction/jackrose + name = "jackrose" + id = "jackrose" + result = "jackrose" + required_reagents = list("applejack" = 4, "lemonjuice" = 1) + result_amount = 5 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/synthanol + name = "Synthanol" + id = "synthanol" + result = "synthanol" + required_reagents = list("lube" = 1, "plasma" = 1, "fuel" = 1) + result_amount = 3 + mix_message = "The chemicals mix to create shiny, blue substance." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/synthanol/robottears + name = "Robot Tears" + id = "robottears" + result = "robottears" + required_reagents = list("synthanol" = 1, "oil" = 1, "sodawater" = 1) + result_amount = 3 + mix_message = "The ingredients combine into a stiff, dark goo." + +/datum/chemical_reaction/synthanol/trinary + name = "Trinary" + id = "trinary" + result = "trinary" + required_reagents = list("synthanol" = 1, "limejuice" = 1, "orangejuice" = 1) + result_amount = 3 + mix_message = "The ingredients mix into a colorful substance." + +/datum/chemical_reaction/synthanol/servo + name = "Servo" + id = "servo" + result = "servo" + required_reagents = list("synthanol" = 2, "cream" = 1, "hot_coco" = 1) + result_amount = 4 + mix_message = "The ingredients mix into a dark brown substance." + +/datum/chemical_reaction/synthanol/uplink + name = "Uplink" + id = "uplink" + result = "uplink" + required_reagents = list("rum" = 1, "vodka" = 1, "tequila" = 1, "whiskey" = 1, "synthanol" = 1) + result_amount = 5 + mix_message = "The chemicals mix to create a shiny, orange substance." + +/datum/chemical_reaction/synthanol/synthnsoda + name = "Synth 'n Soda" + id = "synthnsoda" + result = "synthnsoda" + required_reagents = list("synthanol" = 1, "cola" = 1) + result_amount = 2 + mix_message = "The chemicals mix to create a smooth, fizzy substance." + +/datum/chemical_reaction/synthanol/synthignon + name = "Synthignon" + id = "synthignon" + result = "synthignon" + required_reagents = list("synthanol" = 1, "wine" = 1) + result_amount = 2 + mix_message = "The chemicals mix to create a fine, red substance." + +/datum/chemical_reaction/triple_citrus + name = "triple_citrus" + id = "triple_citrus" + result = "triple_citrus" + required_reagents = list("lemonjuice" = 1, "limejuice" = 1, "orangejuice" = 1) + result_amount = 3 + mix_message = "The citrus juices begin to blend together." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' \ No newline at end of file diff --git a/code/modules/reagents/chemistry/recipes/drugs.dm b/code/modules/reagents/chemistry/recipes/drugs.dm new file mode 100644 index 00000000000..e44ace8f511 --- /dev/null +++ b/code/modules/reagents/chemistry/recipes/drugs.dm @@ -0,0 +1,117 @@ +/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 + mix_message = "Slightly dizzying fumes drift from the solution." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/crank + name = "Crank" + id = "crank" + result = "crank" + required_reagents = list("diphenhydramine" = 1, "ammonia" = 1, "lithium" = 1, "sacid" = 1, "fuel" = 1) + result_amount = 5 + mix_message = "The mixture violently reacts, leaving behind a few crystalline shards." + mix_sound = 'sound/goonstation/effects/crystalshatter.ogg' + min_temp = 390 + +/datum/chemical_reaction/crank/on_reaction(datum/reagents/holder, created_volume) + var/turf/T = get_turf(holder.my_atom) + for(var/turf/turf in range(1,T)) + new /obj/effect/hotspot(turf) + explosion(T,0,0,2) + +/datum/chemical_reaction/krokodil + name = "Krokodil" + id = "krokodil" + result = "krokodil" + required_reagents = list("diphenhydramine" = 1, "morphine" = 1, "cleaner" = 1, "potassium" = 1, "phosphorus" = 1, "fuel" = 1) + result_amount = 6 + mix_message = "The mixture dries into a pale blue powder." + min_temp = 380 + mix_sound = 'sound/goonstation/misc/fuse.ogg' + +/datum/chemical_reaction/methamphetamine + name = "methamphetamine" + id = "methamphetamine" + result = "methamphetamine" + required_reagents = list("ephedrine" = 1, "iodine" = 1, "phosphorus" = 1, "hydrogen" = 1) + result_amount = 4 + min_temp = 374 + +/datum/chemical_reaction/methamphetamine/on_reaction(datum/reagents/holder) + var/turf/T = get_turf(holder.my_atom) + T.visible_message("The solution generates a strong vapor!") + for(var/mob/living/carbon/C in range(T, 1)) + if(C.can_breathe_gas()) + C.emote("gasp") + C.AdjustLoseBreath(1) + C.reagents.add_reagent("toxin", 10) + C.reagents.add_reagent("neurotoxin2", 20) + +/datum/chemical_reaction/bath_salts + name = "bath_salts" + id = "bath_salts" + result = "bath_salts" + required_reagents = list("????" = 1, "saltpetre" = 1, "msg" = 1, "cleaner" = 1, "enzyme" = 1, "mugwort" = 1, "mercury" = 1) + result_amount = 6 + min_temp = 374 + mix_message = "Tiny cubic crystals precipitate out of the mixture. Huh." + mix_sound = 'sound/goonstation/misc/fuse.ogg' + +/datum/chemical_reaction/jenkem + name = "Jenkem" + id = "jenkem" + result = "jenkem" + required_reagents = list("toiletwater" = 1, "ammonia" = 1, "water" = 1) + result_amount = 3 + mix_message = "The mixture ferments into a filthy morass." + mix_sound = 'sound/effects/blobattack.ogg' + +/datum/chemical_reaction/jenkem/on_reaction(datum/reagents/holder) + var/turf/T = get_turf(holder.my_atom) + T.visible_message("The solution generates a strong vapor!") + for(var/mob/living/carbon/C in range(T, 1)) + if(C.can_breathe_gas()) + C.reagents.add_reagent("jenkem", 25) + +/datum/chemical_reaction/aranesp + name = "Aranesp" + id = "aranesp" + result = "aranesp" + required_reagents = list("epinephrine" = 1, "atropine" = 1, "insulin" = 1) + result_amount = 3 + +/datum/chemical_reaction/fliptonium + name = "fliptonium" + id = "fliptonium" + result = "fliptonium" + required_reagents = list("ephedrine" = 1, "liquid_dark_matter" = 1, "chocolate" = 1, "ginsonic" = 1) + result_amount = 4 + mix_message = "The mixture swirls around excitedly!" + +/datum/chemical_reaction/lsd + name = "Lysergic acid diethylamide" + id = "lsd" + result = "lsd" + required_reagents = list("diethylamine" = 1, "fungus" = 1) + result_amount = 3 + mix_message = "The mixture turns a rather unassuming color and settles." + +/datum/chemical_reaction/lube/ultra + name = "Ultra-Lube" + id = "ultralube" + result = "ultralube" + required_reagents = list("lube" = 2, "formaldehyde" = 1, "cryostylane" = 1) + result_amount = 2 + mix_message = "The mixture darkens and appears to partially vaporize into a chilling aerosol." + +/datum/chemical_reaction/surge + name = "Surge" + id = "surge" + result = "surge" + required_reagents = list("thermite" = 3, "uranium" = 1, "fluorosurfactant" = 1, "sacid" = 1) + result_amount = 6 + mix_message = "The mixture congeals into a metallic green gel that crackles with electrical activity." \ No newline at end of file diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm b/code/modules/reagents/chemistry/recipes/food.dm similarity index 51% rename from code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm rename to code/modules/reagents/chemistry/recipes/food.dm index b43c9b344f1..02453d44e31 100644 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm +++ b/code/modules/reagents/chemistry/recipes/food.dm @@ -89,34 +89,6 @@ required_reagents = list("flour" = 15, "water" = 5) required_catalysts = list("enzyme" = 5) -/datum/chemical_reaction/sodiumchloride - name = "Sodium Chloride" - id = "sodiumchloride" - result = "sodiumchloride" - required_reagents = list("sodium" = 1, "chlorine" = 1, "water" = 1) - result_amount = 3 - mix_message = "The solution crystallizes with a brief flare of light." - -/datum/chemical_reaction/ice - name = "Ice" - id = "ice" - result = "ice" - required_reagents = list("water" = 1) - result_amount = 1 - max_temp = 273 - mix_message = "Ice forms as the water freezes." - mix_sound = null - -/datum/chemical_reaction/water - name = "Water" - id = "water" - result = "water" - required_reagents = list("ice" = 1) - result_amount = 1 - min_temp = 301 // In Space.....ice melts at 82F...don't ask - mix_message = "Water pools as the ice melts." - mix_sound = null - /datum/chemical_reaction/dough name = "Dough" id = "dough" @@ -128,4 +100,101 @@ /datum/chemical_reaction/dough/on_reaction(datum/reagents/holder, 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) \ No newline at end of file + new /obj/item/weapon/reagent_containers/food/snacks/dough(location) + +/datum/chemical_reaction/corn_syrup + name = "corn_syrup" + id = "corn_syrup" + result = "corn_syrup" + required_reagents = list("corn_starch" = 1, "sacid" = 1) + result_amount = 2 + min_temp = 374 + mix_message = "The mixture forms a viscous, clear fluid!" + +/datum/chemical_reaction/vhfcs + name = "vhfcs" + id = "vhfcs" + result = "vhfcs" + required_reagents = list("corn_syrup" = 1) + required_catalysts = list("enzyme" = 1) + result_amount = 1 + mix_message = "The mixture emits a sickly-sweet smell." + +/datum/chemical_reaction/cola + name = "cola" + id = "cola" + result = "cola" + required_reagents = list("carbon" = 1, "oxygen" = 1, "water" = 1, "sugar" = 1) + result_amount = 4 + mix_message = "The mixture begins to fizz." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/cheese + name = "cheese" + id = "cheese" + result = "cheese" + required_reagents = list("vomit" = 1, "milk" = 1) + result_amount = 1 + mix_message = "The mixture curdles up." + +/datum/chemical_reaction/cheese/on_reaction(datum/reagents/holder) + var/turf/T = get_turf(holder.my_atom) + T.visible_message("A faint cheesy smell drifts through the air...") + +/datum/chemical_reaction/weird_cheese + name = "Weird cheese" + id = "weird_cheese" + result = "weird_cheese" + required_reagents = list("green_vomit" = 1, "milk" = 1) + result_amount = 1 + mix_message = "The disgusting mixture sloughs together horribly, emitting a foul stench." + mix_sound = 'sound/goonstation/misc/gurggle.ogg' + +/datum/chemical_reaction/weird_cheese/on_reaction(datum/reagents/holder) + var/turf/T = get_turf(holder.my_atom) + T.visible_message("A horrible smell assaults your nose! What in space is it?") + +/datum/chemical_reaction/hydrogenated_soybeanoil + name = "Partially hydrogenated space-soybean oil" + id = "hydrogenated_soybeanoil" + result = "hydrogenated_soybeanoil" + required_reagents = list("soybeanoil" = 1, "hydrogen" = 1) + result_amount = 2 + min_temp = 520 + mix_message = "The mixture emits a burnt, oily smell." + +/datum/chemical_reaction/meatslurry + name = "Meat Slurry" + id = "meatslurry" + result = "meatslurry" + required_reagents = list("corn_starch" = 1, "blood" = 1) + result_amount = 2 + mix_message = "The mixture congeals into a bloody mass." + mix_sound = 'sound/effects/blobattack.ogg' + +/datum/chemical_reaction/gravy + name = "Gravy" + id = "gravy" + result = "gravy" + required_reagents = list("porktonium" = 1, "corn_starch" = 1, "milk" = 1) + result_amount = 3 + min_temp = 374 + mix_message = "The substance thickens and takes on a meaty odor." + +/datum/chemical_reaction/beff + name = "Beff" + id = "beff" + result = "beff" + required_reagents = list("hydrogenated_soybeanoil" = 2, "meatslurry" = 1, "plasma" = 1) + result_amount = 4 + mix_message = "The mixture solidifies, taking a crystalline appearance." + mix_sound = 'sound/effects/blobattack.ogg' + +/datum/chemical_reaction/pepperoni + name = "Pepperoni" + id = "pepperoni" + result = "pepperoni" + required_reagents = list("beff" = 1, "saltpetre" = 1, "synthflesh" = 1) + result_amount = 2 + mix_message = "The beff and the synthflesh combine to form a smoky red log." + mix_sound = 'sound/effects/blobattack.ogg' \ No newline at end of file diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm new file mode 100644 index 00000000000..3d0a0feb8d8 --- /dev/null +++ b/code/modules/reagents/chemistry/recipes/medicine.dm @@ -0,0 +1,275 @@ +/datum/chemical_reaction/hydrocodone + name = "Hydrocodone" + id = "hydrocodone" + result = "hydrocodone" + required_reagents = list("morphine" = 1, "sacid" = 1, "water" = 1, "oil" = 1) + result_amount = 2 + +/datum/chemical_reaction/mitocholide + name = "mitocholide" + id = "mitocholide" + result = "mitocholide" + required_reagents = list("synthflesh" = 1, "cryoxadone" = 1, "plasma" = 1) + result_amount = 3 + +/datum/chemical_reaction/cryoxadone + name = "Cryoxadone" + id = "cryoxadone" + result = "cryoxadone" + required_reagents = list("cryostylane" = 1, "plasma" = 1, "acetone" = 1, "mutagen" = 1) + result_amount = 4 + mix_message = "The solution bubbles softly." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/spaceacillin + name = "Spaceacillin" + id = "spaceacillin" + result = "spaceacillin" + required_reagents = list("fungus" = 1, "ethanol" = 1) + result_amount = 2 + mix_message = "The solvent extracts an antibiotic compound from the fungus." + +/datum/chemical_reaction/rezadone + name = "Rezadone" + id = "rezadone" + result = "rezadone" + required_reagents = list("carpotoxin" = 1, "spaceacillin" = 1, "copper" = 1) + result_amount = 3 + +/datum/chemical_reaction/sterilizine + name = "Sterilizine" + id = "sterilizine" + result = "sterilizine" + required_reagents = list("antihol" = 2, "chlorine" = 1) + result_amount = 3 + +/datum/chemical_reaction/charcoal + name = "Charcoal" + id = "charcoal" + result = "charcoal" + required_reagents = list("ash" = 1, "sodiumchloride" = 1) + result_amount = 2 + mix_message = "The mixture yields a fine black powder." + min_temp = 380 + mix_sound = 'sound/goonstation/misc/fuse.ogg' + +/datum/chemical_reaction/silver_sulfadiazine + name = "Silver Sulfadiazine" + id = "silver_sulfadiazine" + result = "silver_sulfadiazine" + required_reagents = list("ammonia" = 1, "silver" = 1, "sulfur" = 1, "oxygen" = 1, "chlorine" = 1) + result_amount = 5 + mix_message = "A strong and cloying odor begins to bubble from the mixture." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/salglu_solution + name = "Saline-Glucose Solution" + id = "salglu_solution" + result = "salglu_solution" + required_reagents = list("sodiumchloride" = 1, "water" = 1, "sugar" = 1) + result_amount = 3 + +/datum/chemical_reaction/synthflesh + name = "Synthflesh" + id = "synthflesh" + result = "synthflesh" + required_reagents = list("blood" = 1, "carbon" = 1, "styptic_powder" = 1) + result_amount = 3 + mix_message = "The mixture knits together into a fibrous, bloody mass." + mix_sound = 'sound/effects/blobattack.ogg' + +/datum/chemical_reaction/styptic_powder + name = "Styptic Powder" + id = "styptic_powder" + result = "styptic_powder" + required_reagents = list("aluminum" = 1, "hydrogen" = 1, "oxygen" = 1, "sacid" = 1) + result_amount = 4 + mix_message = "The solution yields an astringent powder." + +/datum/chemical_reaction/calomel + name = "Calomel" + id = "calomel" + result = "calomel" + required_reagents = list("mercury" = 1, "chlorine" = 1) + result_amount = 2 + min_temp = 374 + mix_message = "Stinging vapors rise from the solution." + +/datum/chemical_reaction/potass_iodide + name = "Potassium Iodide" + id = "potass_iodide" + result = "potass_iodide" + required_reagents = list("potassium" = 1, "iodine" = 1) + result_amount = 2 + mix_message = "The solution settles calmly and emits gentle fumes." + +/datum/chemical_reaction/pen_acid + name = "Pentetic Acid" + id = "pen_acid" + result = "pen_acid" + required_reagents = list("fuel" = 1, "chlorine" = 1, "ammonia" = 1, "formaldehyde" = 1, "sodium" = 1, "cyanide" = 1) + result_amount = 6 + mix_message = "The substance becomes very still, emitting a curious haze." + +/datum/chemical_reaction/sal_acid + name = "Salicyclic Acid" + id = "sal_acid" + result = "sal_acid" + required_reagents = list("sodium" = 1, "phenol" = 1, "carbon" = 1, "oxygen" = 1, "sacid" = 1) + result_amount = 5 + mix_message = "The mixture crystallizes." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/salbutamol + name = "Salbutamol" + id = "salbutamol" + result = "salbutamol" + required_reagents = list("sal_acid" = 1, "lithium" = 1, "aluminum" = 1, "bromine" = 1, "ammonia" = 1) + result_amount = 5 + mix_message = "The solution bubbles freely, creating a head of bluish foam." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/perfluorodecalin + name = "Perfluorodecalin" + id = "perfluorodecalin" + result = "perfluorodecalin" + required_reagents = list("hydrogen" = 1, "fluorine" = 1, "oil" = 1) + result_amount = 3 + min_temp = 370 + mix_message = "The mixture rapidly turns into a dense pink liquid." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/ephedrine + name = "Ephedrine" + id = "ephedrine" + result = "ephedrine" + required_reagents = list("sugar" = 1, "oil" = 1, "hydrogen" = 1, "diethylamine" = 1) + result_amount = 4 + mix_message = "The solution fizzes and gives off toxic fumes." + +/datum/chemical_reaction/diphenhydramine + name = "Diphenhydramine" + id = "diphenhydramine" + result = "diphenhydramine" + required_reagents = list("oil" = 1, "carbon" = 1, "bromine" = 1, "diethylamine" = 1, "ethanol" = 1) + result_amount = 4 + mix_message = "The mixture fizzes gently." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/oculine + name = "Oculine" + id = "oculine" + result = "oculine" + required_reagents = list("atropine" = 1, "spaceacillin" = 1, "salglu_solution" = 1) + result_amount = 3 + mix_message = "The mixture settles, becoming a milky white." + +/datum/chemical_reaction/atropine + name = "Atropine" + id = "atropine" + result = "atropine" + required_reagents = list("ethanol" = 1, "acetone" = 1, "diethylamine" = 1, "phenol" = 1, "sacid" = 1) + result_amount = 5 + mix_message = "A horrid smell like something died drifts from the mixture." + +/datum/chemical_reaction/epinephrine + name = "Epinephrine" + id = "epinephrine" + result = "epinephrine" + required_reagents = list("phenol" = 1, "acetone" = 1, "diethylamine" = 1, "oxygen" = 1, "chlorine" = 1, "hydrogen" = 1) + result_amount = 6 + mix_message = "Tiny white crystals precipitate out of the solution." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/strange_reagent + name = "Strange Reagent" + id = "strange_reagent" + result = "strange_reagent" + required_reagents = list("omnizine" = 1, "holywater" = 1, "mutagen" = 1) + result_amount = 3 + mix_message = "The substance begins moving on its own somehow." + +/datum/chemical_reaction/life + name = "Life" + id = "life" + result = null + required_reagents = list("strange_reagent" = 1, "synthflesh" = 1, "blood" = 1) + result_amount = 3 + min_temp = 374 + +/datum/chemical_reaction/life/on_reaction(datum/reagents/holder, created_volume) + chemical_mob_spawn(holder, 1, "Life") + +/datum/chemical_reaction/mannitol + name = "Mannitol" + id = "mannitol" + result = "mannitol" + required_reagents = list("sugar" = 1, "hydrogen" = 1, "water" = 1) + result_amount = 3 + mix_message = "The mixture bubbles slowly, making a slightly sweet odor." + +/datum/chemical_reaction/mutadone + name = "Mutadone" + id = "mutadone" + result = "mutadone" + required_reagents = list("mutagen" = 1, "acetone" = 1, "bromine" = 1) + result_amount = 3 + mix_message = "A foul astringent liquid emerges from the reaction." + +/datum/chemical_reaction/antihol + name = "antihol" + id = "antihol" + result = "antihol" + required_reagents = list("ethanol" = 1, "charcoal" = 1) + result_amount = 2 + mix_message = "A minty and refreshing smell drifts from the effervescent mixture." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/simethicone + name = "simethicone" + id = "simethicone" + result = "simethicone" + required_reagents = list("hydrogen" = 1, "chlorine" = 1, "silicon" = 1, "oxygen" = 1) + result_amount = 4 + +/datum/chemical_reaction/teporone + name = "Teporone" + id = "teporone" + result = "teporone" + required_reagents = list("acetone" = 1, "silicon" = 1, "plasma" = 1) + result_amount = 2 + mix_message = "The mixture turns an odd lavender color." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/haloperidol + name = "Haloperidol" + id = "haloperidol" + result = "haloperidol" + required_reagents = list("chlorine" = 1, "fluorine" = 1, "aluminum" = 1, "potass_iodide" = 1, "oil" = 1) + result_amount = 4 + mix_message = "The chemicals mix into an odd pink slush." + +/datum/chemical_reaction/ether + name = "Ether" + id = "ether" + result = "ether" + required_reagents = list("sacid" = 1, "ethanol" = 1, "oxygen" = 1) + result_amount = 1 + mix_message = "The mixture yields a pungent odor, which makes you tired." + +/datum/chemical_reaction/degreaser + name = "Degreaser" + id = "degreaser" + result = "degreaser" + required_reagents = list("oil" = 1, "sterilizine" = 1) + result_amount = 2 + +/datum/chemical_reaction/liquid_solder + name = "Liquid Solder" + id = "liquid_solder" + result = "liquid_solder" + required_reagents = list("ethanol" = 1, "copper" = 1, "silver" = 1) + result_amount = 3 + min_temp = 370 + mix_message = "The solution gently swirls with a metallic sheen." + diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm new file mode 100644 index 00000000000..b97deb0ae8f --- /dev/null +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -0,0 +1,482 @@ +// foam and foam precursor + +/datum/chemical_reaction/surfactant + name = "Foam surfactant" + id = "foam surfactant" + result = "fluorosurfactant" + required_reagents = list("fluorine" = 2, "carbon" = 2, "sacid" = 1) + result_amount = 5 + mix_message = "A head of foam results from the mixture's constant fizzing." + +/datum/chemical_reaction/foam + name = "Foam" + id = "foam" + result = null + required_reagents = list("fluorosurfactant" = 1, "water" = 1) + result_amount = 2 + +/datum/chemical_reaction/foam/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + holder.my_atom.visible_message("The solution spews out foam!") + + var/datum/effect/system/foam_spread/s = new() + s.set_up(created_volume, location, holder, 0) + s.start() + holder.clear_reagents() + + +/datum/chemical_reaction/metalfoam + name = "Metal Foam" + id = "metalfoam" + result = null + required_reagents = list("aluminum" = 3, "fluorosurfactant" = 1, "sacid" = 1) + result_amount = 5 + +/datum/chemical_reaction/metalfoam/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + + holder.my_atom.visible_message("The solution spews out a metalic foam!") + + var/datum/effect/system/foam_spread/s = new() + s.set_up(created_volume, location, holder, MFOAM_ALUMINUM) + s.start() + + +/datum/chemical_reaction/ironfoam + name = "Iron Foam" + id = "ironlfoam" + result = null + required_reagents = list("iron" = 3, "fluorosurfactant" = 1, "sacid" = 1) + result_amount = 5 + +/datum/chemical_reaction/ironfoam/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + + holder.my_atom.visible_message("= 5 && !istype(T, /turf/space)) - if(!locate(/obj/effect/decal/cleanable/dirt/blackpowder) in T) //let's not have hundreds of decals of black powder on the same turf - new /obj/effect/decal/cleanable/dirt/blackpowder(T) - /datum/chemical_reaction/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume) var/location = get_turf(holder.my_atom) var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread @@ -190,17 +136,6 @@ sleep(rand(20,30)) blackpowder_detonate(holder, created_volume) -/* -/datum/reagent/blackpowder/on_ex_act() - var/location = get_turf(holder.my_atom) - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(2, 1, location) - s.start() - sleep(rand(10,15)) - blackpowder_detonate(holder, volume) - holder.remove_reagent("blackpowder", volume) - return */ - /proc/blackpowder_detonate(datum/reagents/holder, created_volume) var/turf/simulated/T = get_turf(holder.my_atom) var/ex_severe = round(created_volume / 100) @@ -213,20 +148,28 @@ spawn(0) qdel(holder.my_atom) -/datum/reagent/flash_powder - name = "Flash Powder" - id = "flash_powder" - description = "Makes a very bright flash." - reagent_state = LIQUID - color = "#FFFF00" - -/datum/chemical_reaction/flash_powder +datum/chemical_reaction/flash_powder name = "Flash powder" id = "flash_powder" result = "flash_powder" required_reagents = list("aluminum" = 1, "potassium" = 1, "sulfur" = 1, "chlorine" = 1) result_amount = 3 +/datum/chemical_reaction/flash_powder/on_reaction(datum/reagents/holder, created_volume) + if(holder.has_reagent("stabilizing_agent")) + return + var/location = get_turf(holder.my_atom) + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(2, 1, location) + s.start() + for(var/mob/living/carbon/C in viewers(5, location)) + if(C.flash_eyes()) + if(get_dist(C, location) < 4) + C.Weaken(5) + continue + C.Stun(5) + holder.remove_reagent("flash_powder", created_volume) + /datum/chemical_reaction/flash_powder_flash name = "Flash powder activation" id = "flash_powder_flash" @@ -246,29 +189,6 @@ continue C.Stun(5) - -/datum/chemical_reaction/flash_powder/on_reaction(datum/reagents/holder, created_volume) - if(holder.has_reagent("stabilizing_agent")) - return - var/location = get_turf(holder.my_atom) - var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread - s.set_up(2, 1, location) - s.start() - for(var/mob/living/carbon/C in viewers(5, location)) - if(C.flash_eyes()) - if(get_dist(C, location) < 4) - C.Weaken(5) - continue - C.Stun(5) - holder.remove_reagent("flash_powder", created_volume) - -/datum/reagent/smoke_powder - name = "Smoke Powder" - id = "smoke_powder" - description = "Makes a large cloud of smoke that can carry reagents." - reagent_state = LIQUID - color = "#808080" - /datum/chemical_reaction/smoke_powder name = "smoke_powder" id = "smoke_powder" @@ -318,13 +238,6 @@ forbidden_reagents = list("stimulants") mix_sound = null -/datum/reagent/sonic_powder - name = "Sonic Powder" - id = "sonic_powder" - description = "Makes a deafening noise." - reagent_state = LIQUID - color = "#0000FF" - /datum/chemical_reaction/sonic_powder name = "sonic_powder" id = "sonic_powder" @@ -332,6 +245,35 @@ required_reagents = list("oxygen" = 1, "cola" = 1, "phosphorus" = 1) result_amount = 3 +/datum/chemical_reaction/sonic_powder/on_reaction(datum/reagents/holder, created_volume) + if(holder.has_reagent("stabilizing_agent")) + return + var/location = get_turf(holder.my_atom) + playsound(location, 'sound/effects/bang.ogg', 25, 1) + for(var/mob/living/M in hearers(5, location)) + var/ear_safety = 0 + var/distance = max(1,get_dist(src,T)) + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(ishuman(C)) + var/mob/living/carbon/human/H = C + if((H.r_ear && (H.r_ear.flags & EARBANGPROTECT)) || (H.l_ear && (H.l_ear.flags & EARBANGPROTECT)) || (H.head && (H.head.flags & HEADBANGPROTECT))) + ear_safety++ + to_chat(C, "BANG") + if(!ear_safety) + M.Stun(max(10/distance, 3)) + M.Weaken(max(10/distance, 3)) + M.AdjustEarDamage(rand(0, 5)) + M.EarDeaf(15) + if(M.ear_damage >= 15) + to_chat(M, "Your ears start to ring badly!") + if(prob(M.ear_damage - 5)) + to_chat(M, "You can't hear anything!") + M.disabilities |= DEAF + else + if(M.ear_damage >= 5) + to_chat(M, "Your ears start to ring!") + holder.remove_reagent("sonic_powder", created_volume) /datum/chemical_reaction/sonic_powder_deafen name = "sonic_powder_deafen" @@ -367,44 +309,6 @@ if(M.ear_damage >= 5) to_chat(M, "Your ears start to ring!") -/datum/chemical_reaction/sonic_powder/on_reaction(datum/reagents/holder, created_volume) - if(holder.has_reagent("stabilizing_agent")) - return - var/location = get_turf(holder.my_atom) - playsound(location, 'sound/effects/bang.ogg', 25, 1) - for(var/mob/living/M in hearers(5, location)) - var/ear_safety = 0 - var/distance = max(1,get_dist(src,T)) - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(ishuman(C)) - var/mob/living/carbon/human/H = C - if((H.r_ear && (H.r_ear.flags & EARBANGPROTECT)) || (H.l_ear && (H.l_ear.flags & EARBANGPROTECT)) || (H.head && (H.head.flags & HEADBANGPROTECT))) - ear_safety++ - to_chat(C, "BANG") - if(!ear_safety) - M.Stun(max(10/distance, 3)) - M.Weaken(max(10/distance, 3)) - M.AdjustEarDamage(rand(0, 5)) - M.EarDeaf(15) - if(M.ear_damage >= 15) - to_chat(M, "Your ears start to ring badly!") - if(prob(M.ear_damage - 5)) - to_chat(M, "You can't hear anything!") - M.disabilities |= DEAF - else - if(M.ear_damage >= 5) - to_chat(M, "Your ears start to ring!") - holder.remove_reagent("sonic_powder", created_volume) - -/datum/reagent/phlogiston - name = "Phlogiston" - id = "phlogiston" - description = "Catches you on fire and makes you ignite." - reagent_state = LIQUID - color = "#FF9999" - process_flags = ORGANIC | SYNTHETIC - /datum/chemical_reaction/phlogiston name = "phlogiston" id = "phlogiston" @@ -419,32 +323,6 @@ for(var/turf/simulated/turf in range(min(created_volume/10,4),T)) new /obj/effect/hotspot(turf) -/datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, volume) - M.IgniteMob() - ..() - -/datum/reagent/phlogiston/on_mob_life(mob/living/M) - M.adjust_fire_stacks(1) - var/burndmg = max(0.3*M.fire_stacks, 0.3) - M.adjustFireLoss(burndmg) - ..() - -/datum/reagent/napalm - name = "Napalm" - id = "napalm" - description = "Very flammable." - reagent_state = LIQUID - color = "#FF9999" - process_flags = ORGANIC | SYNTHETIC - -/datum/reagent/napalm/on_mob_life(mob/living/M) - M.adjust_fire_stacks(1) - ..() - -/datum/reagent/napalm/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) - M.adjust_fire_stacks(min(volume/4, 20)) - /datum/chemical_reaction/napalm name = "Napalm" id = "napalm" @@ -452,13 +330,6 @@ required_reagents = list("sugar" = 1, "fuel" = 1, "ethanol" = 1 ) result_amount = 1 -/datum/reagent/cryostylane - name = "Cryostylane" - id = "cryostylane" - description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Cryostylane slowly cools all other reagents in the mob down to 0K." - color = "#B2B2FF" // rgb: 139, 166, 233 - process_flags = ORGANIC | SYNTHETIC - /datum/chemical_reaction/cryostylane name = "cryostylane" id = "cryostylane" @@ -467,31 +338,6 @@ result_amount = 3 mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' -/datum/reagent/cryostylane/on_mob_life(mob/living/M) //TODO: code freezing into an ice cube - if(M.reagents.has_reagent("oxygen")) - M.reagents.remove_reagent("oxygen", 1) - M.bodytemperature -= 30 - ..() - -/datum/reagent/cryostylane/on_tick() - if(holder.has_reagent("oxygen")) - holder.remove_reagent("oxygen", 1) - holder.chem_temp -= 10 - holder.handle_reactions() - ..() - -/datum/reagent/cryostylane/reaction_turf(turf/T, volume) - if(volume >= 5) - for(var/mob/living/carbon/slime/M in T) - M.adjustToxLoss(rand(15,30)) - -/datum/reagent/pyrosium - name = "Pyrosium" - id = "pyrosium" - description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly cools all other reagents in the mob down to 0K." - color = "#B20000" // rgb: 139, 166, 233 - process_flags = ORGANIC | SYNTHETIC - /datum/chemical_reaction/pyrosium name = "pyrosium" id = "pyrosium" @@ -499,19 +345,6 @@ required_reagents = list("plasma" = 1, "radium" = 1, "phosphorus" = 1) result_amount = 3 -/datum/reagent/pyrosium/on_mob_life(mob/living/M) - if(M.reagents.has_reagent("oxygen")) - M.reagents.remove_reagent("oxygen", 1) - M.bodytemperature += 30 - ..() - -/datum/reagent/pyrosium/on_tick() - if(holder.has_reagent("oxygen")) - holder.remove_reagent("oxygen", 1) - holder.chem_temp += 10 - holder.handle_reactions() - ..() - /datum/chemical_reaction/azide name = "azide" id = "azide" @@ -525,14 +358,6 @@ var/location = get_turf(holder.my_atom) explosion(location, 0, 1, 4) -/datum/reagent/firefighting_foam - name = "Firefighting foam" - id = "firefighting_foam" - description = "Carbon Tetrachloride is a foam used for fire suppression." - reagent_state = LIQUID - color = "#A0A090" - var/cooling_temperature = 3 // more effective than water - /datum/chemical_reaction/firefighting_foam name = "firefighting_foam" id = "firefighting_foam" @@ -542,29 +367,6 @@ mix_message = "The mixture bubbles gently." mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' -/datum/reagent/firefighting_foam/reaction_mob(mob/living/M, method=TOUCH, volume) -// Put out fire - if(method == TOUCH) - M.adjust_fire_stacks(-(volume / 5)) // more effective than water - M.ExtinguishMob() - -/datum/reagent/firefighting_foam/reaction_obj(obj/O, volume) - if(istype(O)) - O.extinguish() - -/datum/reagent/firefighting_foam/reaction_turf(turf/simulated/T, volume) - if(!istype(T)) - return - var/CT = cooling_temperature - new /obj/effect/decal/cleanable/flour/foam(T) //foam mess; clears up quickly. - var/hotspot = (locate(/obj/effect/hotspot) in T) - if(hotspot) - var/datum/gas_mixture/lowertemp = T.remove_air(T.air.total_moles()) - lowertemp.temperature = max(min(lowertemp.temperature-(CT*1000), lowertemp.temperature / CT), 0) - lowertemp.react() - T.assume_air(lowertemp) - qdel(hotspot) - /datum/chemical_reaction/clf3_firefighting name = "clf3_firefighting" id = "clf3_firefighting" @@ -595,30 +397,9 @@ holder.del_reagent("teslium") //Clear all remaining Teslium and Uranium, but leave all other reagents untouched. holder.del_reagent("uranium") -/datum/reagent/plasma_dust - name = "Plasma Dust" - id = "plasma_dust" - description = "A fine dust of plasma. This chemical has unusual mutagenic properties for viruses and slimes alike." - color = "#500064" // rgb: 80, 0, 100 - -/datum/reagent/plasma_dust/on_mob_life(mob/living/M) - M.adjustToxLoss(3) - if(iscarbon(M)) - var/mob/living/carbon/C = M - C.adjustPlasma(20) - ..() - -/datum/reagent/plasma_dust/reaction_obj(obj/O, volume) - if((!O) || (!volume)) - return 0 - O.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, volume) - -/datum/reagent/plasma_dust/reaction_turf(turf/simulated/T, volume) - if(istype(T)) - T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, volume) - -/datum/reagent/plasma_dust/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with plasma dust is stronger than fuel! - if(method == TOUCH) - M.adjust_fire_stacks(volume / 5) - return - ..() +/datum/chemical_reaction/thermite + name = "Thermite" + id = "thermite" + result = "thermite" + required_reagents = list("aluminum" = 1, "iron" = 1, "oxygen" = 1) + result_amount = 3 \ No newline at end of file diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm similarity index 100% rename from code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm rename to code/modules/reagents/chemistry/recipes/slime_extracts.dm diff --git a/code/modules/reagents/chemistry/recipes/toxins.dm b/code/modules/reagents/chemistry/recipes/toxins.dm new file mode 100644 index 00000000000..2181401b2da --- /dev/null +++ b/code/modules/reagents/chemistry/recipes/toxins.dm @@ -0,0 +1,142 @@ +/datum/chemical_reaction/formaldehyde + name = "formaldehyde" + id = "formaldehyde" + result = "formaldehyde" + required_reagents = list("ethanol" = 1, "oxygen" = 1, "silver" = 1) + result_amount = 3 + min_temp = 420 + mix_message = "Ugh, it smells like the morgue in here." + +/datum/chemical_reaction/neurotoxin2 + name = "neurotoxin2" + id = "neurotoxin2" + result = "neurotoxin2" + required_reagents = list("space_drugs" = 1) + result_amount = 1 + min_temp = 674 + mix_sound = null + no_message = 1 + +/datum/chemical_reaction/cyanide + name = "Cyanide" + id = "cyanide" + result = "cyanide" + required_reagents = list("oil" = 1, "ammonia" = 1, "oxygen" = 1) + result_amount = 3 + min_temp = 380 + mix_message = "The mixture gives off a faint scent of almonds." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/cyanide/on_reaction(datum/reagents/holder) + var/turf/T = get_turf(holder.my_atom) + T.visible_message("The solution generates a strong vapor!") + for(var/mob/living/carbon/C in range(T, 1)) + if(C.can_breathe_gas()) + C.reagents.add_reagent("cyanide", 7) + +/datum/chemical_reaction/itching_powder + name = "Itching Powder" + id = "itching_powder" + result = "itching_powder" + required_reagents = list("fuel" = 1, "ammonia" = 1, "fungus" = 1) + result_amount = 3 + mix_message = "The mixture congeals and dries up, leaving behind an abrasive powder." + mix_sound = 'sound/effects/blobattack.ogg' + +/datum/chemical_reaction/facid + name = "Fluorosulfuric Acid" + id = "facid" + result = "facid" + required_reagents = list("sacid" = 1, "fluorine" = 1, "hydrogen" = 1, "potassium" = 1) + result_amount = 4 + min_temp = 380 + mix_message = "The mixture deepens to a dark blue, and slowly begins to corrode its container." + +/datum/chemical_reaction/initropidril + name = "Initropidril" + id = "initropidril" + result = "initropidril" + required_reagents = list("crank" = 1, "histamine" = 1, "krokodil" = 1, "bath_salts" = 1, "atropine" = 1, "nicotine" = 1, "morphine" = 1) + result_amount = 4 + mix_message = "A sweet and sugary scent drifts from the unpleasant milky substance." + +/datum/chemical_reaction/sulfonal + name = "sulfonal" + id = "sulfonal" + result = "sulfonal" + required_reagents = list("acetone" = 1, "diethylamine" = 1, "sulfur" = 1) + result_amount = 3 + mix_message = "The mixture gives off quite a stench." + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/lipolicide + name = "lipolicide" + id = "lipolicide" + result = "lipolicide" + required_reagents = list("mercury" = 1, "diethylamine" = 1, "ephedrine" = 1) + result_amount = 3 + +/datum/chemical_reaction/sarin + name = "sarin" + id = "sarin" + result = "sarin" + required_reagents = list("chlorine" = 1, "fuel" = 1, "oxygen" = 1, "phosphorus" = 1, "fluorine" = 1, "hydrogen" = 1, "acetone" = 1, "atrazine" = 1) + result_amount = 3 + mix_message = "The mixture yields a colorless, odorless liquid." + min_temp = 374 + mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' + +/datum/chemical_reaction/sarin/on_reaction(datum/reagents/holder) + var/turf/T = get_turf(holder.my_atom) + T.visible_message("The solution generates a strong vapor!") + for(var/mob/living/carbon/C in range(T, 2)) + if(C.can_breathe_gas()) + C.reagents.add_reagent("sarin", 4) + +/datum/chemical_reaction/atrazine + name = "atrazine" + id = "atrazine" + result = "atrazine" + required_reagents = list("chlorine" = 1, "hydrogen" = 1, "nitrogen" = 1) + result_amount = 3 + mix_message = "The mixture gives off a harsh odor" + +/datum/chemical_reaction/capulettium + name = "capulettium" + id = "capulettium" + result = "capulettium" + required_reagents = list("neurotoxin2" = 1, "chlorine" = 1, "hydrogen" = 1) + result_amount = 1 + mix_message = "The smell of death wafts up from the solution." + +/datum/chemical_reaction/capulettium_plus + name = "capulettium_plus" + id = "capulettium_plus" + result = "capulettium_plus" + required_reagents = list("capulettium" = 1, "ephedrine" = 1, "methamphetamine" = 1) + result_amount = 3 + mix_message = "The solution begins to slosh about violently by itself." + +/datum/chemical_reaction/teslium + name = "Teslium" + id = "teslium" + result = "teslium" + required_reagents = list("plasma" = 1, "silver" = 1, "blackpowder" = 1) + result_amount = 3 + mix_message = "A jet of sparks flies from the mixture as it merges into a flickering slurry." + min_temp = 400 + mix_sound = null + +/datum/chemical_reaction/teslium/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread + s.set_up(6, 1, location) + s.start() + +/datum/chemical_reaction/mutagen + name = "Unstable mutagen" + id = "mutagen" + result = "mutagen" + required_reagents = list("radium" = 1, "plasma" = 1, "chlorine" = 1) + result_amount = 3 + mix_message = "The substance turns neon green and bubbles unnervingly." \ No newline at end of file diff --git a/code/modules/reagents/newchem/drinks.dm b/code/modules/reagents/newchem/drinks.dm deleted file mode 100644 index da07f7a995f..00000000000 --- a/code/modules/reagents/newchem/drinks.dm +++ /dev/null @@ -1,238 +0,0 @@ -/datum/reagent/ginsonic - name = "Gin and sonic" - id = "ginsonic" - description = "GOTTA GET CRUNK FAST BUT LIQUOR TOO SLOW" - reagent_state = LIQUID - color = "#1111CF" - -/datum/chemical_reaction/ginsonic - name = "ginsonic" - id = "ginsonic" - result = "ginsonic" - required_reagents = list("gintonic" = 1, "methamphetamine" = 1) - result_amount = 2 - mix_message = "The drink turns electric blue and starts quivering violently." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - -/datum/reagent/ginsonic/on_mob_life(mob/living/M) - M.AdjustDrowsy(-5) - if(prob(25)) - M.AdjustParalysis(-1) - M.AdjustStunned(-1) - M.AdjustWeakened(-1) - if(prob(8)) - M.reagents.add_reagent("methamphetamine",1.2) - var/sonic_message = pick("Gotta go fast!", "Time to speed, keed!", "I feel a need for speed!", "Let's juice.", "Juice time.", "Way Past Cool!") - if(prob(50)) - M.say("[sonic_message]") - else - to_chat(M, "[sonic_message ]") - ..() - -/datum/reagent/ethanol/applejack - name = "Applejack" - id = "applejack" - description = "A highly concentrated alcoholic beverage made by repeatedly freezing cider and removing the ice." - color = "#997A00" - alcohol_perc = 0.4 - -/datum/chemical_reaction/applejack - name = "applejack" - id = "applejack" - result = "applejack" - required_reagents = list("cider" = 2) - max_temp = 270 - result_amount = 1 - mix_message = "The drink darkens as the water freezes, leaving the concentrated cider behind." - mix_sound = null - -/datum/reagent/ethanol/jackrose - name = "Jack Rose" - id = "jackrose" - description = "A classic cocktail that had fallen out of fashion, but never out of taste," - color = "#664300" - alcohol_perc = 0.4 - -/datum/chemical_reaction/jackrose - name = "jackrose" - id = "jackrose" - result = "jackrose" - required_reagents = list("applejack" = 4, "lemonjuice" = 1) - result_amount = 5 - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - - -/datum/reagent/ethanol/dragons_breath //inaccessible to players, but here for admin shennanigans - name = "Dragon's Breath" - id = "dragonsbreath" - description = "Possessing this stuff probably breaks the Geneva convention." - reagent_state = LIQUID - color = "#DC0000" - alcohol_perc = 1 - -/datum/reagent/ethanol/dragons_breath/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == INGEST && prob(20)) - if(M.on_fire) - M.adjust_fire_stacks(3) - -/datum/reagent/ethanol/dragons_breath/on_mob_life(mob/living/M) - if(M.reagents.has_reagent("milk")) - to_chat(M, "The milk stops the burning. Ahhh.") - M.reagents.del_reagent("milk") - M.reagents.del_reagent("dragonsbreath") - return - if(prob(8)) - to_chat(M, "Oh god! Oh GODD!!") - if(prob(50)) - to_chat(M, "Your throat burns terribly!") - M.emote(pick("scream","cry","choke","gasp")) - M.Stun(1) - if(prob(8)) - to_chat(M, "Why!? WHY!?") - if(prob(8)) - to_chat(M, "ARGHHHH!") - if(prob(2 * volume)) - to_chat(M, "OH GOD OH GOD PLEASE NO!!") - if(M.on_fire) - M.adjust_fire_stacks(5) - if(prob(50)) - to_chat(M, "IT BURNS!!!!") - M.visible_message("[M] is consumed in flames!") - M.dust() - return - ..() - -// ROBOT ALCOHOL PAST THIS POINT -// WOOO! - - -/datum/reagent/ethanol/synthanol - name = "Synthanol" - id = "synthanol" - description = "A runny liquid with conductive capacities. Its effects on synthetics are similar to those of alcohol on organics." - reagent_state = LIQUID - color = "#1BB1FF" - process_flags = ORGANIC | SYNTHETIC - metabolization_rate = 0.4 - alcohol_perc = 0.5 - -/datum/chemical_reaction/synthanol - name = "Synthanol" - id = "synthanol" - result = "synthanol" - required_reagents = list("lube" = 1, "plasma" = 1, "fuel" = 1) - result_amount = 3 - mix_message = "The chemicals mix to create shiny, blue substance." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - -/datum/reagent/ethanol/synthanol/on_mob_life(mob/living/M) - if(!M.isSynthetic()) - holder.remove_reagent(id, 3.6) //gets removed from organics very fast - if(prob(25)) - holder.remove_reagent(id, 15) - M.fakevomit() - ..() - -/datum/reagent/ethanol/synthanol/reaction_mob(mob/living/M, method=TOUCH, volume) - if(M.isSynthetic()) - return - if(method == INGEST) - to_chat(M, pick("That was awful!", "Yuck!")) - -/datum/reagent/ethanol/synthanol/robottears - name = "Robot Tears" - id = "robottears" - description = "An oily substance that an IPC could technically consider a 'drink'." - reagent_state = LIQUID - color = "#363636" - alcohol_perc = 0.25 - -/datum/chemical_reaction/synthanol/robottears - name = "Robot Tears" - id = "robottears" - result = "robottears" - required_reagents = list("synthanol" = 1, "oil" = 1, "sodawater" = 1) - result_amount = 3 - mix_message = "The ingredients combine into a stiff, dark goo." - -/datum/reagent/ethanol/synthanol/trinary - name = "Trinary" - id = "trinary" - description = "A fruit drink meant only for synthetics, however that works." - reagent_state = LIQUID - color = "#adb21f" - alcohol_perc = 0.2 - -/datum/chemical_reaction/synthanol/trinary - name = "Trinary" - id = "trinary" - result = "trinary" - required_reagents = list("synthanol" = 1, "limejuice" = 1, "orangejuice" = 1) - result_amount = 3 - mix_message = "The ingredients mix into a colorful substance." - -/datum/reagent/ethanol/synthanol/servo - name = "Servo" - id = "servo" - description = "A drink containing some organic ingredients, but meant only for synthetics." - reagent_state = LIQUID - color = "#5b3210" - alcohol_perc = 0.25 - -/datum/chemical_reaction/synthanol/servo - name = "Servo" - id = "servo" - result = "servo" - required_reagents = list("synthanol" = 2, "cream" = 1, "hot_coco" = 1) - result_amount = 4 - mix_message = "The ingredients mix into a dark brown substance." - -/datum/reagent/ethanol/synthanol/uplink - name = "Uplink" - id = "uplink" - description = "A potent mix of alcohol and synthanol. Will only work on synthetics." - reagent_state = LIQUID - color = "#e7ae04" - alcohol_perc = 0.15 - -/datum/chemical_reaction/synthanol/uplink - name = "Uplink" - id = "uplink" - result = "uplink" - required_reagents = list("rum" = 1, "vodka" = 1, "tequila" = 1, "whiskey" = 1, "synthanol" = 1) - result_amount = 5 - mix_message = "The chemicals mix to create a shiny, orange substance." - -/datum/reagent/ethanol/synthanol/synthnsoda - name = "Synth 'n Soda" - id = "synthnsoda" - description = "The classic drink adjusted for a robot's tastes." - reagent_state = LIQUID - color = "#7204e7" - alcohol_perc = 0.25 - -/datum/chemical_reaction/synthanol/synthnsoda - name = "Synth 'n Soda" - id = "synthnsoda" - result = "synthnsoda" - required_reagents = list("synthanol" = 1, "cola" = 1) - result_amount = 2 - mix_message = "The chemicals mix to create a smooth, fizzy substance." - -/datum/reagent/ethanol/synthanol/synthignon - name = "Synthignon" - id = "synthignon" - description = "Someone mixed wine and alcohol for robots. Hope you're proud of yourself." - reagent_state = LIQUID - color = "#d004e7" - alcohol_perc = 0.25 - -/datum/chemical_reaction/synthanol/synthignon - name = "Synthignon" - id = "synthignon" - result = "synthignon" - required_reagents = list("synthanol" = 1, "wine" = 1) - result_amount = 2 - mix_message = "The chemicals mix to create a fine, red substance." - -// ROBOT ALCOHOL ENDS diff --git a/code/modules/reagents/newchem/newchem_procs.dm b/code/modules/reagents/newchem/newchem_procs.dm deleted file mode 100644 index 7ad083407d9..00000000000 --- a/code/modules/reagents/newchem/newchem_procs.dm +++ /dev/null @@ -1,212 +0,0 @@ -#define ADDICTION_TIME 4800 //8 minutes - -/datum/reagent - var/overdose_threshold = 0 - var/addiction_chance = 0 - var/addiction_stage = 1 - var/last_addiction_dose = 0 - var/overdosed = 0 // You fucked up and this is now triggering it's overdose effects, purge that shit quick. - var/current_cycle = 1 - -/datum/reagents/proc/metabolize(mob/living/M) - if(M) - chem_temp = M.bodytemperature - handle_reactions() - for(var/A in reagent_list) - var/datum/reagent/R = A - if(!istype(R)) // How are non-reagents ending up in the reagents_list? - continue - if(!R.holder) - continue - if(!M) - M = R.holder.my_atom - if(ishuman(M)) - var/mob/living/carbon/human/H = M - //Check if this mob's species is set and can process this type of reagent - var/can_process = 0 - //If we somehow avoided getting a species or reagent_tag set, we'll assume we aren't meant to process ANY reagents (CODERS: SET YOUR SPECIES AND TAG!) - if(H.species && H.species.reagent_tag) - if((R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_SYN)) //SYNTHETIC-oriented reagents require PROCESS_SYN - can_process = 1 - if((R.process_flags & ORGANIC) && (H.species.reagent_tag & PROCESS_ORG)) //ORGANIC-oriented reagents require PROCESS_ORG - can_process = 1 - //Species with PROCESS_DUO are only affected by reagents that affect both organics and synthetics, like acid and hellwater - if((R.process_flags & ORGANIC) && (R.process_flags & SYNTHETIC) && (H.species.reagent_tag & PROCESS_DUO)) - can_process = 1 - - //If handle_reagents returns 0, it's doing the reagent removal on its own - var/species_handled = !(H.species.handle_reagents(H, R)) - can_process = can_process && !species_handled - //If the mob can't process it, remove the reagent at it's normal rate without doing any addictions, overdoses, or on_mob_life() for the reagent - if(can_process == 0) - if(!species_handled) - R.holder.remove_reagent(R.id, R.metabolization_rate) - continue - //We'll assume that non-human mobs lack the ability to process synthetic-oriented reagents (adjust this if we need to change that assumption) - else - if(R.process_flags == SYNTHETIC) - R.holder.remove_reagent(R.id, R.metabolization_rate) - continue - //If you got this far, that means we can process whatever reagent this iteration is for. Handle things normally from here. - if(M && R) - R.on_mob_life(M) - if(R.volume >= R.overdose_threshold && !R.overdosed && R.overdose_threshold > 0) - R.overdosed = 1 - R.overdose_start(M) - if(R.volume < R.overdose_threshold && R.overdosed) - R.overdosed = 0 - if(R.overdosed) - R.overdose_process(M, R.volume >= R.overdose_threshold*2 ? 2 : 1) - - for(var/A in addiction_list) - var/datum/reagent/R = A - if(M && R) - if(R.addiction_stage < 5) - if(prob(5)) - R.addiction_stage++ - switch(R.addiction_stage) - if(1) - R.addiction_act_stage1(M) - if(2) - R.addiction_act_stage2(M) - if(3) - R.addiction_act_stage3(M) - if(4) - R.addiction_act_stage4(M) - if(5) - R.addiction_act_stage5(M) - if(prob(20) && (world.timeofday > (R.last_addiction_dose + ADDICTION_TIME))) //Each addiction lasts 8 minutes before it can end - to_chat(M, "You no longer feel reliant on [R.name]!") - addiction_list.Remove(R) - update_total() - -/datum/reagents/proc/death_metabolize(mob/living/M) - if(!M) - return - if(M.stat != DEAD) //what part of DEATH_metabolize don't you get? - return - for(var/A in reagent_list) - var/datum/reagent/R = A - if(!istype(R)) - continue - if(M && R) - R.on_mob_death(M) - -/datum/reagents/proc/overdose_list() - var/od_chems[0] - for(var/datum/reagent/R in reagent_list) - if(R.overdosed) - od_chems.Add(R.id) - return od_chems - - -/datum/reagents/proc/reagent_on_tick() - for(var/datum/reagent/R in reagent_list) - R.on_tick() - return - -// Called every time reagent containers process. -/datum/reagent/proc/on_tick(data) - return - -// Called when the reagent container is hit by an explosion -/datum/reagent/proc/on_ex_act(severity) - return - -// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects -/datum/reagent/proc/overdose_process(mob/living/M, severity) - var/effect = rand(1, 100) - severity - if(effect <= 8) - M.adjustToxLoss(severity) - return effect - -/datum/reagent/proc/overdose_start(mob/living/M) - return - -/datum/reagent/proc/addiction_act_stage1(mob/living/M) - return - -/datum/reagent/proc/addiction_act_stage2(mob/living/M) - if(prob(8)) - M.emote("shiver") - if(prob(8)) - M.emote("sneeze") - if(prob(4)) - to_chat(M, "You feel a dull headache.") - -/datum/reagent/proc/addiction_act_stage3(mob/living/M) - if(prob(8)) - M.emote("twitch_s") - if(prob(8)) - M.emote("shiver") - if(prob(4)) - to_chat(M, "You begin craving [name]!") - -/datum/reagent/proc/addiction_act_stage4(mob/living/M) - if(prob(8)) - M.emote("twitch") - if(prob(4)) - to_chat(M, "You have the strong urge for some [name]!") - if(prob(4)) - to_chat(M, "You REALLY crave some [name]!") - -/datum/reagent/proc/addiction_act_stage5(mob/living/M) - if(prob(8)) - M.emote("twitch") - if(prob(6)) - to_chat(M, "Your stomach lurches painfully!") - M.visible_message("[M] gags and retches!") - M.Stun(rand(2,4)) - M.Weaken(rand(2,4)) - if(prob(5)) - to_chat(M, "You feel like you can't live without [name]!") - if(prob(5)) - to_chat(M, "You would DIE for some [name] right now!") - -/datum/reagent/proc/reagent_deleted() - return - -var/list/chemical_mob_spawn_meancritters = list() // list of possible hostile mobs -var/list/chemical_mob_spawn_nicecritters = list() // and possible friendly mobs -/datum/chemical_reaction/proc/chemical_mob_spawn(datum/reagents/holder, amount_to_spawn, reaction_name, mob_faction = "chemicalsummon") - if(holder && holder.my_atom) - if(chemical_mob_spawn_meancritters.len <= 0 || chemical_mob_spawn_nicecritters.len <= 0) - for(var/T in typesof(/mob/living/simple_animal)) - var/mob/living/simple_animal/SA = T - switch(initial(SA.gold_core_spawnable)) - if(CHEM_MOB_SPAWN_HOSTILE) - chemical_mob_spawn_meancritters += T - if(CHEM_MOB_SPAWN_FRIENDLY) - chemical_mob_spawn_nicecritters += T - var/atom/A = holder.my_atom - var/turf/T = get_turf(A) - var/area/my_area = get_area(T) - var/message = "A [reaction_name] reaction has occured in [my_area.name]. (JMP)" - message += " (VV)" - - var/mob/M = get(A, /mob) - if(M) - message += " - Carried By: [key_name_admin(M)](?) (FLW)" - else - message += " - Last Fingerprint: [(A.fingerprintslast ? A.fingerprintslast : "N/A")]" - - message_admins(message, 0, 1) - - playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1) - - for(var/mob/living/carbon/C in viewers(get_turf(holder.my_atom), null)) - C.flash_eyes() - for(var/i = 1, i <= amount_to_spawn, i++) - var/chosen - if(reaction_name == "Friendly Gold Slime") - chosen = pick(chemical_mob_spawn_nicecritters) - else - chosen = pick(chemical_mob_spawn_meancritters) - var/mob/living/simple_animal/C = new chosen - C.faction |= mob_faction - C.forceMove(get_turf(holder.my_atom)) - if(prob(50)) - for(var/j = 1, j <= rand(1, 3), j++) - step(C, pick(NORTH,SOUTH,EAST,WEST)) - -#undef ADDICTION_TIME \ No newline at end of file diff --git a/code/modules/reagents/oldchem/chemical_reaction/_chemical_reaction_base.dm b/code/modules/reagents/oldchem/chemical_reaction/_chemical_reaction_base.dm deleted file mode 100644 index 3b4cc507415..00000000000 --- a/code/modules/reagents/oldchem/chemical_reaction/_chemical_reaction_base.dm +++ /dev/null @@ -1,23 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////////// -/datum/chemical_reaction - var/name = null - var/id = null - var/result = null - var/list/required_reagents = list() - var/list/required_catalysts = list() - - // Both of these variables are mostly going to be used with slime cores - but if you want to, you can use them for other things - var/atom/required_container = null // the container required for the reaction to happen - var/required_other = 0 // an integer required for the reaction to happen - - var/result_amount = 0 - var/secondary = 0 // set to nonzero if secondary reaction - var/list/secondary_results = list() //additional reagents produced by the reaction - var/min_temp = 0 //Minimum temperature required for the reaction to occur (heat to/above this). min_temp = 0 means no requirement - var/max_temp = 9999 //Maximum temperature allowed for the reaction to occur (cool to/below this). - var/mix_message = "The solution begins to bubble." - var/mix_sound = 'sound/effects/bubbles.ogg' - var/no_message = 0 - -/datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, created_volume) - return \ No newline at end of file diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_harm.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_harm.dm deleted file mode 100644 index afcd0d398ce..00000000000 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_harm.dm +++ /dev/null @@ -1,71 +0,0 @@ -//Anything for harm or hostile intents go here (explosions, EMPs, thermite, mutagen) -/datum/chemical_reaction/explosion_potassium - name = "Explosion" - id = "explosion_potassium" - result = null - required_reagents = list("water" = 1, "potassium" = 1) - result_amount = 2 - mix_message = "The mixture explodes!" - -/datum/chemical_reaction/explosion_potassium/on_reaction(datum/reagents/holder, created_volume) - var/datum/effect/system/reagents_explosion/e = new() - e.set_up(round (created_volume/10, 1), holder.my_atom, 0, 0) - e.start() - holder.clear_reagents() - -/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(datum/reagents/holder, 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 / 14), 1) - holder.clear_reagents() - -/datum/chemical_reaction/mutagen - name = "Unstable mutagen" - id = "mutagen" - result = "mutagen" - required_reagents = list("radium" = 1, "plasma" = 1, "chlorine" = 1) - result_amount = 3 - mix_message = "The substance turns neon green and bubbles unnervingly." - -/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/glycerol - name = "Glycerol" - id = "glycerol" - result = "glycerol" - required_reagents = list("cornoil" = 3, "sacid" = 1) - result_amount = 1 - -/datum/chemical_reaction/nitroglycerin - name = "Nitroglycerin" - id = "nitroglycerin" - result = "nitroglycerin" - required_reagents = list("glycerol" = 1, "facid" = 1, "sacid" = 1) - result_amount = 2 - -/datum/chemical_reaction/nitroglycerin/on_reaction(datum/reagents/holder, created_volume) - var/datum/effect/system/reagents_explosion/e = new() - e.set_up(round(created_volume/2, 1), holder.my_atom, 0, 0) - e.start() - holder.clear_reagents() - -/datum/chemical_reaction/condensedcapsaicin - name = "Condensed Capsaicin" - id = "condensedcapsaicin" - result = "condensedcapsaicin" - required_reagents = list("capsaicin" = 2) - required_catalysts = list("plasma" = 5) - result_amount = 1 \ No newline at end of file diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_med.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_med.dm deleted file mode 100644 index 0550813849c..00000000000 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_med.dm +++ /dev/null @@ -1,44 +0,0 @@ -/datum/chemical_reaction/hydrocodone - name = "Hydrocodone" - id = "hydrocodone" - result = "hydrocodone" - required_reagents = list("morphine" = 1, "sacid" = 1, "water" = 1, "oil" = 1) - result_amount = 2 - -/datum/chemical_reaction/mitocholide - name = "mitocholide" - id = "mitocholide" - result = "mitocholide" - required_reagents = list("synthflesh" = 1, "cryoxadone" = 1, "plasma" = 1) - result_amount = 3 - -/datum/chemical_reaction/cryoxadone - name = "Cryoxadone" - id = "cryoxadone" - result = "cryoxadone" - required_reagents = list("cryostylane" = 1, "plasma" = 1, "acetone" = 1, "mutagen" = 1) - result_amount = 4 - mix_message = "The solution bubbles softly." - mix_sound = 'sound/goonstation/misc/drinkfizz.ogg' - -/datum/chemical_reaction/spaceacillin - name = "Spaceacillin" - id = "spaceacillin" - result = "spaceacillin" - required_reagents = list("fungus" = 1, "ethanol" = 1) - result_amount = 2 - mix_message = "The solvent extracts an antibiotic compound from the fungus." - -/datum/chemical_reaction/rezadone - name = "Rezadone" - id = "rezadone" - result = "rezadone" - required_reagents = list("carpotoxin" = 1, "spaceacillin" = 1, "copper" = 1) - result_amount = 3 - -/datum/chemical_reaction/sterilizine - name = "Sterilizine" - id = "sterilizine" - result = "sterilizine" - required_reagents = list("antihol" = 2, "chlorine" = 1) - result_amount = 3 diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_misc.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_misc.dm deleted file mode 100644 index 8a5dedf218b..00000000000 --- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_misc.dm +++ /dev/null @@ -1,147 +0,0 @@ -// foam and foam precursor - -/datum/chemical_reaction/surfactant - name = "Foam surfactant" - id = "foam surfactant" - result = "fluorosurfactant" - required_reagents = list("fluorine" = 2, "carbon" = 2, "sacid" = 1) - result_amount = 5 - mix_message = "A head of foam results from the mixture's constant fizzing." - -/datum/chemical_reaction/foam - name = "Foam" - id = "foam" - result = null - required_reagents = list("fluorosurfactant" = 1, "water" = 1) - result_amount = 2 - -/datum/chemical_reaction/foam/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - holder.my_atom.visible_message("The solution spews out foam!") - - var/datum/effect/system/foam_spread/s = new() - s.set_up(created_volume, location, holder, 0) - s.start() - holder.clear_reagents() - - -/datum/chemical_reaction/metalfoam - name = "Metal Foam" - id = "metalfoam" - result = null - required_reagents = list("aluminum" = 3, "fluorosurfactant" = 1, "sacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/metalfoam/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - - holder.my_atom.visible_message("The solution spews out a metalic foam!") - - var/datum/effect/system/foam_spread/s = new() - s.set_up(created_volume, location, holder, MFOAM_ALUMINUM) - s.start() - - -/datum/chemical_reaction/ironfoam - name = "Iron Foam" - id = "ironlfoam" - result = null - required_reagents = list("iron" = 3, "fluorosurfactant" = 1, "sacid" = 1) - result_amount = 5 - -/datum/chemical_reaction/ironfoam/on_reaction(datum/reagents/holder, created_volume) - var/location = get_turf(holder.my_atom) - - holder.my_atom.visible_message("= 5 && istype(W)) - W.thermite = 1 - W.overlays.Cut() - W.overlays = image('icons/effects/effects.dmi',icon_state = "thermite") - -/datum/reagent/glycerol - name = "Glycerol" - id = "glycerol" - description = "Glycerol is a simple polyol compound. Glycerol is sweet-tasting and of low toxicity." - reagent_state = LIQUID - color = "#808080" // rgb: 128, 128, 128 diff --git a/code/modules/reagents/oldchem/reagents/reagents_food.dm b/code/modules/reagents/oldchem/reagents/reagents_food.dm deleted file mode 100644 index de52805fef2..00000000000 --- a/code/modules/reagents/oldchem/reagents/reagents_food.dm +++ /dev/null @@ -1,393 +0,0 @@ -/////////////////////////Food Reagents//////////////////////////// -// Part of the food code. Nutriment is used instead of the old "heal_amt" code. Also is where all the food -// condiments, additives, and such go. -/datum/reagent/nutriment // Pure nutriment, universally digestable and thus slightly less effective - name = "Nutriment" - id = "nutriment" - description = "A questionable mixture of various pure nutrients commonly found in processed foods." - reagent_state = SOLID - nutriment_factor = 12 * REAGENTS_METABOLISM - color = "#664330" // rgb: 102, 67, 48 - var/diet_flags = DIET_OMNI | DIET_HERB | DIET_CARN - -/datum/reagent/nutriment/on_mob_life(mob/living/M) - if(!(M.mind in ticker.mode.vampires)) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.can_eat(diet_flags)) //Make sure the species has it's dietflag set, otherwise it can't digest any nutrients - H.nutrition += nutriment_factor // For hunger and fatness - if(prob(50)) - M.adjustBruteLoss(-1) - if(H.species.exotic_blood) - H.vessel.add_reagent(H.species.exotic_blood, 0.4) - else - if(!(H.species.flags & NO_BLOOD)) - H.vessel.add_reagent("blood", 0.4) - ..() - -/datum/reagent/nutriment/protein // Meat-based protein, digestable by carnivores and omnivores, worthless to herbivores - name = "Protein" - id = "protein" - description = "Various essential proteins and fats commonly found in animal flesh and blood." - nutriment_factor = 15 * REAGENTS_METABOLISM - diet_flags = DIET_CARN | DIET_OMNI - -/datum/reagent/nutriment/plantmatter // Plant-based biomatter, digestable by herbivores and omnivores, worthless to carnivores - name = "Plant-matter" - id = "plantmatter" - description = "Vitamin-rich fibers and natural sugars commonly found in fresh produce." - nutriment_factor = 15 * REAGENTS_METABOLISM - diet_flags = DIET_HERB | DIET_OMNI - - -/datum/reagent/vitamin - name = "Vitamin" - id = "vitamin" - description = "All the best vitamins, minerals, and carbohydrates the body needs in pure form." - reagent_state = SOLID - nutriment_factor = 1 * REAGENTS_METABOLISM - color = "#664330" // rgb: 102, 67, 48 - -/datum/reagent/vitamin/on_mob_life(mob/living/M) //everyone needs vitamins, so this works on everyone, regardless of diet or if they're a vampire. - M.nutrition += nutriment_factor - if(prob(50)) - M.adjustBruteLoss(-1) - M.adjustFireLoss(-1) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.species.exotic_blood) - H.vessel.add_reagent(H.species.exotic_blood, 0.5) - else - if(!(H.species.flags & NO_BLOOD)) - H.vessel.add_reagent("blood", 0.5) - ..() - -/datum/reagent/soysauce - name = "Soysauce" - id = "soysauce" - description = "A salty sauce made from the soy plant." - reagent_state = LIQUID - nutriment_factor = 2 * REAGENTS_METABOLISM - color = "#792300" // rgb: 121, 35, 0 - -/datum/reagent/ketchup - name = "Ketchup" - id = "ketchup" - description = "Ketchup, catsup, whatever. It's tomato paste." - reagent_state = LIQUID - nutriment_factor = 5 * REAGENTS_METABOLISM - color = "#731008" // rgb: 115, 16, 8 - - -/datum/reagent/capsaicin - name = "Capsaicin Oil" - id = "capsaicin" - description = "This is what makes chilis hot." - reagent_state = LIQUID - color = "#B31008" // rgb: 179, 16, 8 - -/datum/reagent/capsaicin/on_mob_life(mob/living/M) - switch(current_cycle) - if(1 to 15) - M.bodytemperature += 5 * TEMPERATURE_DAMAGE_COEFFICIENT - if(holder.has_reagent("frostoil")) - holder.remove_reagent("frostoil", 5) - if(isslime(M)) - M.bodytemperature += rand(5,20) - if(15 to 25) - M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT - if(isslime(M)) - M.bodytemperature += rand(10,20) - if(25 to 35) - M.bodytemperature += 15 * TEMPERATURE_DAMAGE_COEFFICIENT - if(isslime(M)) - M.bodytemperature += rand(15,20) - if(35 to INFINITY) - M.bodytemperature += 20 * TEMPERATURE_DAMAGE_COEFFICIENT - if(isslime(M)) - M.bodytemperature += rand(20,25) - ..() - -/datum/reagent/frostoil - name = "Frost Oil" - id = "frostoil" - description = "A special oil that noticably chills the body. Extraced from Icepeppers." - reagent_state = LIQUID - color = "#8BA6E9" // rgb: 139, 166, 233 - process_flags = ORGANIC | SYNTHETIC - -/datum/reagent/frostoil/on_mob_life(mob/living/M) - switch(current_cycle) - if(1 to 15) - M.bodytemperature -= 10 * TEMPERATURE_DAMAGE_COEFFICIENT - if(holder.has_reagent("capsaicin")) - holder.remove_reagent("capsaicin", 5) - if(isslime(M)) - M.bodytemperature -= rand(5,20) - if(15 to 25) - M.bodytemperature -= 15 * TEMPERATURE_DAMAGE_COEFFICIENT - if(isslime(M)) - M.bodytemperature -= rand(10,20) - if(25 to 35) - M.bodytemperature -= 20 * TEMPERATURE_DAMAGE_COEFFICIENT - if(prob(1)) - M.emote("shiver") - if(isslime(M)) - M.bodytemperature -= rand(15,20) - if(35 to INFINITY) - M.bodytemperature -= 20 * TEMPERATURE_DAMAGE_COEFFICIENT - if(prob(1)) - M.emote("shiver") - if(isslime(M)) - M.bodytemperature -= rand(20,25) - ..() - -/datum/reagent/frostoil/reaction_turf(turf/T, volume) - if(volume >= 5) - for(var/mob/living/carbon/slime/M in T) - M.adjustToxLoss(rand(15,30)) - - -/datum/reagent/sodiumchloride - name = "Salt" - id = "sodiumchloride" - description = "Sodium chloride, common table salt." - reagent_state = SOLID - color = "#B1B0B0" - overdose_threshold = 100 - -/datum/reagent/sodiumchloride/overdose_process(mob/living/M, severity) - if(prob(70)) - M.adjustBrainLoss(1) - ..() - -/datum/reagent/blackpepper - name = "Black Pepper" - id = "blackpepper" - description = "A powder ground from peppercorns. *AAAACHOOO*" - reagent_state = SOLID - -/datum/reagent/cocoa - name = "Cocoa Powder" - id = "cocoa" - description = "A fatty, bitter paste made from cocoa beans." - reagent_state = SOLID - nutriment_factor = 5 * REAGENTS_METABOLISM - color = "#302000" // rgb: 48, 32, 0 - -/datum/reagent/cocoa/on_mob_life(mob/living/M) - M.nutrition += nutriment_factor - ..() - -/datum/reagent/hot_coco - name = "Hot Chocolate" - id = "hot_coco" - description = "Made with love! And cocoa beans." - reagent_state = LIQUID - nutriment_factor = 2 * REAGENTS_METABOLISM - color = "#403010" // rgb: 64, 48, 16 - -/datum/reagent/hot_coco/on_mob_life(mob/living/M) - if(M.bodytemperature < 310)//310 is the normal bodytemp. 310.055 - M.bodytemperature = min(310, M.bodytemperature + (5 * TEMPERATURE_DAMAGE_COEFFICIENT)) - M.nutrition += nutriment_factor - ..() - -/datum/reagent/sprinkles - name = "Sprinkles" - id = "sprinkles" - description = "Multi-colored little bits of sugar, commonly found on donuts. Loved by cops." - nutriment_factor = 1 * REAGENTS_METABOLISM - color = "#FF00FF" // rgb: 255, 0, 255 - -/datum/reagent/sprinkles/on_mob_life(mob/living/M) - M.nutrition += nutriment_factor - if(ishuman(M) && M.job in list("Security Officer", "Security Pod Pilot", "Detective", "Warden", "Head of Security", "Brig Physician", "Internal Affairs Agent", "Magistrate")) - M.adjustBruteLoss(-1) - M.adjustFireLoss(-1) - ..() - - -/datum/reagent/cornoil - name = "Corn Oil" - id = "cornoil" - description = "An oil derived from various types of corn." - reagent_state = LIQUID - nutriment_factor = 20 * REAGENTS_METABOLISM - color = "#302000" // rgb: 48, 32, 0 - -/datum/reagent/cornoil/on_mob_life(mob/living/M) - M.nutrition += nutriment_factor - ..() - -/datum/reagent/cornoil/reaction_turf(turf/simulated/T, volume) - if(!istype(T)) - return - if(volume >= 3) - T.MakeSlippery() - var/hotspot = (locate(/obj/effect/hotspot) in T) - if(hotspot) - var/datum/gas_mixture/lowertemp = T.remove_air( T.air.total_moles()) - lowertemp.temperature = max(min(lowertemp.temperature-2000, lowertemp.temperature / 2), 0) - lowertemp.react() - T.assume_air(lowertemp) - qdel(hotspot) - - -/datum/reagent/enzyme - name = "Denatured Enzyme" - id = "enzyme" - description = "Heated beyond usefulness, this enzyme is now worthless." - reagent_state = LIQUID - color = "#282314" // rgb: 54, 94, 48 - - -/datum/reagent/dry_ramen - name = "Dry Ramen" - id = "dry_ramen" - description = "Space age food, since August 25, 1958. Contains dried noodles, vegetables, and chemicals that boil in contact with water." - reagent_state = SOLID - nutriment_factor = 1 * REAGENTS_METABOLISM - color = "#302000" // rgb: 48, 32, 0 - -/datum/reagent/dry_ramen/on_mob_life(mob/living/M) - M.nutrition += nutriment_factor - ..() - - -/datum/reagent/hot_ramen - name = "Hot Ramen" - id = "hot_ramen" - description = "The noodles are boiled, the flavors are artificial, just like being back in school." - reagent_state = LIQUID - nutriment_factor = 5 * REAGENTS_METABOLISM - color = "#302000" // rgb: 48, 32, 0 - -/datum/reagent/hot_ramen/on_mob_life(mob/living/M) - M.nutrition += nutriment_factor - if(M.bodytemperature < 310)//310 is the normal bodytemp. 310.055 - M.bodytemperature = min(310, M.bodytemperature + (10 * TEMPERATURE_DAMAGE_COEFFICIENT)) - ..() - - -/datum/reagent/hell_ramen - name = "Hell Ramen" - id = "hell_ramen" - description = "The noodles are boiled, the flavors are artificial, just like being back in school." - reagent_state = LIQUID - nutriment_factor = 5 * REAGENTS_METABOLISM - color = "#302000" // rgb: 48, 32, 0 - -/datum/reagent/hell_ramen/on_mob_life(mob/living/M) - M.nutrition += nutriment_factor - M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT - ..() - - -/datum/reagent/flour - name = "flour" - id = "flour" - description = "This is what you rub all over yourself to pretend to be a ghost." - reagent_state = SOLID - nutriment_factor = 1 * REAGENTS_METABOLISM - color = "#FFFFFF" // rgb: 0, 0, 0 - -/datum/reagent/flour/on_mob_life(mob/living/M) - M.nutrition += nutriment_factor - ..() - -/datum/reagent/flour/reaction_turf(turf/T, volume) - if(!istype(T, /turf/space)) - new /obj/effect/decal/cleanable/flour(T) - - -/datum/reagent/rice - name = "Rice" - id = "rice" - description = "Enjoy the great taste of nothing." - reagent_state = SOLID - nutriment_factor = 1 * REAGENTS_METABOLISM - color = "#FFFFFF" // rgb: 0, 0, 0 - -/datum/reagent/rice/on_mob_life(mob/living/M) - M.nutrition += nutriment_factor - ..() - - -/datum/reagent/cherryjelly - name = "Cherry Jelly" - id = "cherryjelly" - description = "Totally the best. Only to be spread on foods with excellent lateral symmetry." - reagent_state = LIQUID - nutriment_factor = 1 * REAGENTS_METABOLISM - color = "#801E28" // rgb: 128, 30, 40 - -/datum/reagent/cherryjelly/on_mob_life(mob/living/M) - M.nutrition += nutriment_factor - ..() - -/datum/reagent/toxin/coffeepowder - name = "Coffee Grounds" - id = "coffeepowder" - description = "Finely ground Coffee beans, used to make coffee." - reagent_state = SOLID - color = "#5B2E0D" // rgb: 91, 46, 13 - -/datum/reagent/toxin/teapowder - name = "Ground Tea Leaves" - id = "teapowder" - description = "Finely shredded Tea leaves, used for making tea." - reagent_state = SOLID - color = "#7F8400" // rgb: 127, 132, 0 - -//Reagents used for plant fertilizers. -/datum/reagent/toxin/fertilizer - name = "fertilizer" - id = "fertilizer" - description = "A chemical mix good for growing plants with." - reagent_state = LIQUID - color = "#664330" // rgb: 102, 67, 48 - -/datum/reagent/toxin/fertilizer/eznutrient - name = "EZ Nutrient" - id = "eznutrient" - -/datum/reagent/toxin/fertilizer/left4zed - name = "Left-4-Zed" - id = "left4zed" - -/datum/reagent/toxin/fertilizer/robustharvest - name = "Robust Harvest" - id = "robustharvest" - - -/datum/reagent/sugar - name = "Sugar" - id = "sugar" - description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste." - reagent_state = SOLID - color = "#FFFFFF" // rgb: 255, 255, 255 - overdose_threshold = 200 // Hyperglycaemic shock - -/datum/reagent/sugar/on_mob_life(mob/living/M) - M.AdjustDrowsy(-5) - if(current_cycle >= 90) - M.AdjustJitter(2) - if(prob(50)) - M.AdjustParalysis(-1) - M.AdjustStunned(-1) - M.AdjustWeakened(-1) - if(prob(4)) - M.reagents.add_reagent("epinephrine", 1.2) - ..() - -/datum/reagent/sugar/overdose_start(mob/living/M) - to_chat(M, "You pass out from hyperglycemic shock!") - M.emote("collapse") - ..() - -/datum/reagent/sugar/overdose_process(mob/living/M, severity) - M.Paralyse(3 * severity) - M.Weaken(4 * severity) - if(prob(8)) - M.adjustToxLoss(severity) diff --git a/code/modules/reagents/oldchem/reagents/reagents_med.dm b/code/modules/reagents/oldchem/reagents/reagents_med.dm deleted file mode 100644 index b0a09afc999..00000000000 --- a/code/modules/reagents/oldchem/reagents/reagents_med.dm +++ /dev/null @@ -1,142 +0,0 @@ -/datum/reagent/hydrocodone - name = "Hydrocodone" - id = "hydrocodone" - description = "An extremely effective painkiller; may have long term abuse consequences." - reagent_state = LIQUID - color = "#C805DC" - metabolization_rate = 0.3 // Lasts 1.5 minutes for 15 units - shock_reduction = 200 - -/datum/reagent/hydrocodone/on_mob_life(mob/living/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(H.traumatic_shock < 100) - H.shock_stage = 0 - ..() - -/datum/reagent/sterilizine - name = "Sterilizine" - id = "sterilizine" - description = "Sterilizes wounds in preparation for surgery." - reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 - - //makes you squeaky clean -/datum/reagent/sterilizine/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) - M.germ_level -= min(volume*20, M.germ_level) - -/datum/reagent/sterilizine/reaction_obj(obj/O, volume) - O.germ_level -= min(volume*20, O.germ_level) - -/datum/reagent/sterilizine/reaction_turf(turf/T, volume) - T.germ_level -= min(volume*20, T.germ_level) - -/datum/reagent/synaptizine - name = "Synaptizine" - id = "synaptizine" - description = "Synaptizine is used to treat neuroleptic shock. Can be used to help remove disabling symptoms such as paralysis." - reagent_state = LIQUID - color = "#FA46FA" - overdose_threshold = 40 - -/datum/reagent/synaptizine/on_mob_life(mob/living/M) - M.AdjustDrowsy(-5) - M.AdjustParalysis(-1) - M.AdjustStunned(-1) - M.AdjustWeakened(-1) - M.SetSleeping(0) - if(prob(50)) - M.adjustBrainLoss(-1.0) - ..() - -/datum/reagent/synaptizine/overdose_process(mob/living/M, severity) - var/effect = ..() - if(severity == 1) - if(effect <= 1) - M.visible_message("[M] suddenly and violently vomits!") - M.fakevomit(no_text = 1) - else if(effect <= 3) - M.emote(pick("groan","moan")) - if(effect <= 8) - M.adjustToxLoss(1) - else if(severity == 2) - if(effect <= 2) - M.visible_message("[M] suddenly and violently vomits!") - M.fakevomit(no_text = 1) - else if(effect <= 5) - M.visible_message("[M] staggers and drools, their eyes bloodshot!") - M.Dizzy(8) - M.Weaken(4) - if(effect <= 15) - M.adjustToxLoss(1) - -/datum/reagent/mitocholide - name = "Mitocholide" - id = "mitocholide" - description = "A specialized drug that stimulates the mitochondria of cells to encourage healing of internal organs." - reagent_state = LIQUID - color = "#C8A5DC" // rgb: 200, 165, 220 - -/datum/reagent/mitocholide/on_mob_life(mob/living/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - - //Mitocholide is hard enough to get, it's probably fair to make this all internal organs - for(var/name in H.internal_organs) - var/obj/item/organ/internal/I = H.get_int_organ(name) - if(I.damage > 0) - I.damage = max(I.damage-0.4, 0) - ..() - -/datum/reagent/mitocholide/reaction_obj(obj/O, volume) - if(istype(O, /obj/item/organ)) - var/obj/item/organ/Org = O - Org.rejuvenate() - -/datum/reagent/cryoxadone - name = "Cryoxadone" - id = "cryoxadone" - description = "A plasma mixture with almost magical healing powers. Its main limitation is that the targets body temperature must be under 265K for it to metabolise correctly." - reagent_state = LIQUID - color = "#0000C8" // rgb: 200, 165, 220 - heart_rate_decrease = 1 - -/datum/reagent/cryoxadone/on_mob_life(mob/living/M) - if(M.bodytemperature < 265) - M.adjustCloneLoss(-4) - M.adjustOxyLoss(-10) - M.adjustToxLoss(-3) - M.adjustBruteLoss(-12) - M.adjustFireLoss(-12) - M.status_flags &= ~DISFIGURED - ..() - -/datum/reagent/rezadone - name = "Rezadone" - id = "rezadone" - description = "A powder derived from fish toxin, Rezadone can effectively treat genetic damage as well as restoring minor wounds. Overdose will cause intense nausea and minor toxin damage." - reagent_state = SOLID - color = "#669900" // rgb: 102, 153, 0 - overdose_threshold = 30 - -/datum/reagent/rezadone/on_mob_life(mob/living/M) - M.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that. - M.adjustCloneLoss(-1) //What? We just set cloneloss to 0. Why? Simple; this is so external organs properly unmutate. - M.adjustBruteLoss(-1) - M.adjustFireLoss(-1) - M.status_flags &= ~DISFIGURED - ..() - -/datum/reagent/rezadone/overdose_process(mob/living/M, severity) - M.adjustToxLoss(1) - M.Dizzy(5) - M.Jitter(5) - -/datum/reagent/spaceacillin - name = "Spaceacillin" - id = "spaceacillin" - description = "An all-purpose antibiotic agent extracted from space fungus." - reagent_state = LIQUID - color = "#0AB478" - metabolization_rate = 0.2 diff --git a/code/modules/reagents/oldchem/reagents/reagents_misc.dm b/code/modules/reagents/oldchem/reagents/reagents_misc.dm deleted file mode 100644 index ff729dcdf3f..00000000000 --- a/code/modules/reagents/oldchem/reagents/reagents_misc.dm +++ /dev/null @@ -1,189 +0,0 @@ -/*/datum/reagent/silicate - name = "Silicate" - id = "silicate" - description = "A compound that can be used to reinforce glass." - reagent_state = LIQUID - color = "#C7FFFF" // rgb: 199, 255, 255 - -/datum/reagent/silicate/reaction_obj(obj/O, volume) - if(istype(O, /obj/structure/window)) - if(O:silicate <= 200) - - O:silicate += volume - O:health += volume * 3 - - if(!O:silicateIcon) - var/icon/I = icon(O.icon,O.icon_state,O.dir) - - var/r = (volume / 100) + 1 - var/g = (volume / 70) + 1 - var/b = (volume / 50) + 1 - I.SetIntensity(r,g,b) - O.icon = I - O:silicateIcon = I - else - var/icon/I = O:silicateIcon - - var/r = (volume / 100) + 1 - var/g = (volume / 70) + 1 - var/b = (volume / 50) + 1 - I.SetIntensity(r,g,b) - O.icon = I - O:silicateIcon = I */ - - -/datum/reagent/oxygen - name = "Oxygen" - id = "oxygen" - description = "A colorless, odorless gas." - reagent_state = GAS - color = "#808080" // rgb: 128, 128, 128 - - -/datum/reagent/nitrogen - name = "Nitrogen" - id = "nitrogen" - description = "A colorless, odorless, tasteless gas." - reagent_state = GAS - color = "#808080" // rgb: 128, 128, 128 - - -/datum/reagent/hydrogen - name = "Hydrogen" - id = "hydrogen" - description = "A colorless, odorless, nonmetallic, tasteless, highly combustible diatomic gas." - reagent_state = GAS - color = "#808080" // rgb: 128, 128, 128 - - -/datum/reagent/potassium - name = "Potassium" - id = "potassium" - description = "A soft, low-melting solid that can easily be cut with a knife. Reacts violently with water." - reagent_state = SOLID - color = "#A0A0A0" // rgb: 160, 160, 160 - - -/datum/reagent/sulfur - name = "Sulfur" - id = "sulfur" - description = "A chemical element." - reagent_state = SOLID - color = "#BF8C00" // rgb: 191, 140, 0 - - -/datum/reagent/sodium - name = "Sodium" - id = "sodium" - description = "A chemical element." - reagent_state = SOLID - color = "#808080" // rgb: 128, 128, 128 - - -/datum/reagent/phosphorus - name = "Phosphorus" - id = "phosphorus" - description = "A chemical element." - reagent_state = SOLID - color = "#832828" // rgb: 131, 40, 40 - - -/datum/reagent/carbon - name = "Carbon" - id = "carbon" - description = "A chemical element." - reagent_state = SOLID - color = "#1C1300" // rgb: 30, 20, 0 - -/datum/reagent/carbon/reaction_turf(turf/T, volume) - if(!istype(T, /turf/space) && !(locate(/obj/effect/decal/cleanable/dirt) in T)) // Only add one dirt per turf. Was causing people to crash. - new /obj/effect/decal/cleanable/dirt(T) - -/datum/reagent/gold - name = "Gold" - id = "gold" - description = "Gold is a dense, soft, shiny metal and the most malleable and ductile metal known." - reagent_state = SOLID - color = "#F7C430" // rgb: 247, 196, 48 - - -/datum/reagent/silver - name = "Silver" - id = "silver" - description = "A lustrous metallic element regarded as one of the precious metals." - reagent_state = SOLID - color = "#D0D0D0" // rgb: 208, 208, 208 - - -/datum/reagent/aluminum - name = "Aluminum" - id = "aluminum" - description = "A silvery white and ductile member of the boron group of chemical elements." - reagent_state = SOLID - color = "#A8A8A8" // rgb: 168, 168, 168 - - -/datum/reagent/silicon - name = "Silicon" - id = "silicon" - description = "A tetravalent metalloid, silicon is less reactive than its chemical analog carbon." - reagent_state = SOLID - color = "#A8A8A8" // rgb: 168, 168, 168 - - -/datum/reagent/copper - name = "Copper" - id = "copper" - description = "A highly ductile metal." - color = "#6E3B08" // rgb: 110, 59, 8 - - -/datum/reagent/iron - name = "Iron" - id = "iron" - description = "Pure iron is a metal." - reagent_state = SOLID - color = "#C8A5DC" // rgb: 200, 165, 220 - -/datum/reagent/iron/on_mob_life(mob/living/M) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!H.species.exotic_blood && !(H.species.flags & NO_BLOOD)) - H.vessel.add_reagent("blood", 0.8) - ..() - - -//foam -/datum/reagent/fluorosurfactant - name = "Fluorosurfactant" - id = "fluorosurfactant" - description = "A perfluoronated sulfonic acid that forms a foam when mixed with water." - reagent_state = LIQUID - color = "#9E6B38" // rgb: 158, 107, 56 - -// metal foaming agent -// this is lithium hydride. Add other recipies (e.g. LiH + H2O -> LiOH + H2) eventually -/datum/reagent/ammonia - name = "Ammonia" - id = "ammonia" - description = "A caustic substance commonly used in fertilizer or household cleaners." - reagent_state = GAS - color = "#404030" // rgb: 64, 64, 48 - -/datum/reagent/diethylamine - name = "Diethylamine" - id = "diethylamine" - description = "A secondary amine, useful as a plant nutrient and as building block for other compounds." - reagent_state = LIQUID - color = "#322D00" - - -// Ported from Bay as part of the Botany Update -// Allows you to make planks from any plant that has this reagent in it. -// Also vines with this reagent are considered dense. -/datum/reagent/woodpulp - name = "Wood Pulp" - id = "woodpulp" - description = "A mass of wood fibers." - reagent_state = LIQUID - color = "#B97A57" \ No newline at end of file diff --git a/code/modules/reagents/oldchem/reagents/reagents_toxin.dm b/code/modules/reagents/oldchem/reagents/reagents_toxin.dm deleted file mode 100644 index 0aae5e3f40e..00000000000 --- a/code/modules/reagents/oldchem/reagents/reagents_toxin.dm +++ /dev/null @@ -1,414 +0,0 @@ -/datum/reagent/toxin - name = "Toxin" - id = "toxin" - description = "A Toxic chemical." - reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 - -/datum/reagent/toxin/on_mob_life(mob/living/M) - M.adjustToxLoss(2) - ..() - -/datum/reagent/spider_venom - name = "Spider venom" - id = "spidertoxin" - description = "A toxic venom injected by spacefaring arachnids." - reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 - -/datum/reagent/spider_venom/on_mob_life(mob/living/M) - M.adjustToxLoss(1.5) - ..() - -/datum/reagent/plasticide - name = "Plasticide" - id = "plasticide" - description = "Liquid plastic, do not eat." - reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 - -/datum/reagent/plasticide/on_mob_life(mob/living/M) - M.adjustToxLoss(1.5) - ..() - - -/datum/reagent/minttoxin - name = "Mint Toxin" - id = "minttoxin" - description = "Useful for dealing with undesirable customers." - reagent_state = LIQUID - color = "#CF3600" // rgb: 207, 54, 0 - -/datum/reagent/minttoxin/on_mob_life(mob/living/M) - if(FAT in M.mutations) - M.gib() - ..() - -/datum/reagent/slimejelly - name = "Slime Jelly" - id = "slimejelly" - description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL." - reagent_state = LIQUID - color = "#801E28" // rgb: 128, 30, 40 - -/datum/reagent/slimejelly/on_mob_life(mob/living/M) - if(prob(10)) - to_chat(M, "Your insides are burning!") - M.adjustToxLoss(rand(20,60)*REM) - else if(prob(40)) - M.adjustBruteLoss(-5*REM) - ..() - -/datum/reagent/slimetoxin - name = "Mutation Toxin" - id = "mutationtoxin" - description = "A corruptive toxin produced by slimes." - reagent_state = LIQUID - color = "#13BC5E" // rgb: 19, 188, 94 - -/datum/reagent/slimetoxin/on_mob_life(mob/living/M) - if(ishuman(M)) - var/mob/living/carbon/human/human = M - if(human.species.name != "Shadow") - to_chat(M, "Your flesh rapidly mutates!") - to_chat(M, "You are now a Shadow Person, a mutant race of darkness-dwelling humanoids.") - to_chat(M, "Your body reacts violently to light. \green However, it naturally heals in darkness.") - to_chat(M, "Aside from your new traits, you are mentally unchanged and retain your prior obligations.") - human.set_species("Shadow") - ..() - -/datum/reagent/aslimetoxin - name = "Advanced Mutation Toxin" - id = "amutationtoxin" - description = "An advanced corruptive toxin produced by slimes." - reagent_state = LIQUID - color = "#13BC5E" // rgb: 19, 188, 94 - -/datum/reagent/aslimetoxin/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method != TOUCH) - M.ForceContractDisease(new /datum/disease/transformation/slime(0)) - - -/datum/reagent/mercury - name = "Mercury" - id = "mercury" - description = "A chemical element." - reagent_state = LIQUID - color = "#484848" // rgb: 72, 72, 72 - metabolization_rate = 0.2 - penetrates_skin = 1 - -/datum/reagent/mercury/on_mob_life(mob/living/M) - if(prob(70)) - M.adjustBrainLoss(1) - ..() - -/datum/reagent/chlorine - name = "Chlorine" - id = "chlorine" - description = "A chemical element." - reagent_state = GAS - color = "#808080" // rgb: 128, 128, 128 - penetrates_skin = 1 - process_flags = ORGANIC | SYNTHETIC - -/datum/reagent/chlorine/on_mob_life(mob/living/M) - M.adjustFireLoss(1) - ..() - -/datum/reagent/fluorine - name = "Fluorine" - id = "fluorine" - description = "A highly-reactive chemical element." - reagent_state = GAS - color = "#6A6054" - penetrates_skin = 1 - process_flags = ORGANIC | SYNTHETIC - -/datum/reagent/fluorine/on_mob_life(mob/living/M) - M.adjustFireLoss(1) - M.adjustToxLoss(1*REM) - ..() - -/datum/reagent/radium - name = "Radium" - id = "radium" - description = "Radium is an alkaline earth metal. It is extremely radioactive." - reagent_state = SOLID - color = "#C7C7C7" // rgb: 199,199,199 - metabolization_rate = 0.4 - penetrates_skin = 1 - -/datum/reagent/radium/on_mob_life(mob/living/M) - if(M.radiation < 80) - M.apply_effect(4, IRRADIATE, negate_armor = 1) - ..() - -/datum/reagent/radium/reaction_turf(turf/T, volume) - if(volume >= 3 && !istype(T, /turf/space)) - new /obj/effect/decal/cleanable/greenglow(T) - -/datum/reagent/mutagen - name = "Unstable mutagen" - id = "mutagen" - description = "Might cause unpredictable mutations. Keep away from children." - reagent_state = LIQUID - color = "#04DF27" - metabolization_rate = 0.3 - -/datum/reagent/mutagen/reaction_mob(mob/living/M, method=TOUCH, volume) - if(!..()) - return - if(!M.dna) - return //No robots, AIs, aliens, Ians or other mobs should be affected by this. - if((method==TOUCH && prob(33)) || method==INGEST) - randmutb(M) - domutcheck(M, null) - M.UpdateAppearance() - -/datum/reagent/mutagen/on_mob_life(mob/living/M) - if(!M.dna) - return //No robots, AIs, aliens, Ians or other mobs should be affected by this. - M.apply_effect(2*REM, IRRADIATE, negate_armor = 1) - if(prob(4)) - randmutb(M) - ..() - - -/datum/reagent/uranium - name ="Uranium" - id = "uranium" - description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive." - reagent_state = SOLID - color = "#B8B8C0" // rgb: 184, 184, 192 - -/datum/reagent/uranium/on_mob_life(mob/living/M) - M.apply_effect(2, IRRADIATE, negate_armor = 1) - ..() - -/datum/reagent/uranium/reaction_turf(turf/T, volume) - if(volume >= 3 && !istype(T, /turf/space)) - new /obj/effect/decal/cleanable/greenglow(T) - - -/datum/reagent/lexorin - name = "Lexorin" - id = "lexorin" - description = "Lexorin temporarily stops respiration. Causes tissue damage." - reagent_state = LIQUID - color = "#52685D" - metabolization_rate = 0.2 - -/datum/reagent/lexorin/on_mob_life(mob/living/M) - M.adjustToxLoss(1) - ..() - - -/datum/reagent/sacid - name = "Sulphuric acid" - id = "sacid" - description = "A strong mineral acid with the molecular formula H2SO4." - reagent_state = LIQUID - color = "#00D72B" - process_flags = ORGANIC | SYNTHETIC - -/datum/reagent/sacid/on_mob_life(mob/living/M) - M.adjustFireLoss(1) - ..() - -/datum/reagent/sacid/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - - if(volume > 25) - - if(H.wear_mask) - to_chat(H, "Your mask protects you from the acid!") - return - - if(H.head) - to_chat(H, "Your helmet protects you from the acid!") - return - - if(!M.unacidable) - if(prob(75)) - var/obj/item/organ/external/affecting = H.get_organ("head") - if(affecting) - affecting.take_damage(5, 10) - H.UpdateDamageIcon() - H.emote("scream") - else - M.take_organ_damage(5,10) - else - M.take_organ_damage(5,10) - - if(method == INGEST) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - - if(volume < 10) - to_chat(M, "The greenish acidic substance stings you, but isn't concentrated enough to harm you!") - - if(volume >=10 && volume <=25) - if(!H.unacidable) - M.take_organ_damage(0,min(max(volume-10,2)*2,20)) - M.emote("scream") - - - if(volume > 25) - if(!M.unacidable) - if(prob(75)) - var/obj/item/organ/external/affecting = H.get_organ("head") - if(affecting) - affecting.take_damage(0, 20) - H.UpdateDamageIcon() - H.emote("scream") - else - M.take_organ_damage(0,20) - -/datum/reagent/sacid/reaction_obj(obj/O, volume) - if((istype(O,/obj/item) || istype(O,/obj/effect/glowshroom)) && prob(40)) - if(!O.unacidable) - var/obj/effect/decal/cleanable/molten_item/I = new/obj/effect/decal/cleanable/molten_item(O.loc) - I.desc = "Looks like this was \an [O] some time ago." - O.visible_message("[O] melts.") - qdel(O) - - -/datum/reagent/hellwater - name = "Hell Water" - id = "hell_water" - description = "YOUR FLESH! IT BURNS!" - process_flags = ORGANIC | SYNTHETIC //Admin-bus has no brakes! KILL THEM ALL. - metabolization_rate = 1 - -/datum/reagent/hellwater/on_mob_life(mob/living/M) - M.fire_stacks = min(5, M.fire_stacks + 3) - M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire - M.adjustToxLoss(1) - M.adjustFireLoss(1) //Hence the other damages... ain't I a bastard? - M.adjustBrainLoss(5) - ..() - - -/datum/reagent/carpotoxin - name = "Carpotoxin" - id = "carpotoxin" - description = "A deadly neurotoxin produced by the dreaded spess carp." - reagent_state = LIQUID - color = "#003333" // rgb: 0, 51, 51 - -/datum/reagent/carpotoxin/on_mob_life(mob/living/M) - M.adjustToxLoss(2*REM) - ..() - -/datum/reagent/staminatoxin - name = "Tirizene" - id = "tirizene" - description = "A toxin that affects the stamina of a person when injected into the bloodstream." - reagent_state = LIQUID - color = "#6E2828" - data = 13 - -/datum/reagent/staminatoxin/on_mob_life(mob/living/M) - M.adjustStaminaLoss(REM * data) - data = max(data - 1, 3) - ..() - - -/datum/reagent/spore - name = "Spore Toxin" - id = "spore" - description = "A natural toxin produced by blob spores that inhibits vision when ingested." - color = "#9ACD32" - -/datum/reagent/spores/on_mob_life(mob/living/M) - M.adjustToxLoss(1) - M.damageoverlaytemp = 60 - M.EyeBlurry(3) - ..() - -/datum/reagent/beer2 //disguised as normal beer for use by emagged brobots - name = "Beer" - id = "beer2" - description = "An alcoholic beverage made from malted grains, hops, yeast, and water." - color = "#664300" // rgb: 102, 67, 0 - metabolization_rate = 1.5 * REAGENTS_METABOLISM - -/datum/reagent/beer2/on_mob_life(mob/living/M) - switch(current_cycle) - if(1 to 50) - M.AdjustSleeping(1) - if(51 to INFINITY) - M.AdjustSleeping(1) - M.adjustToxLoss((current_cycle - 50)*REM) - ..() - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/datum/reagent/condensedcapsaicin - name = "Condensed Capsaicin" - id = "condensedcapsaicin" - description = "This shit goes in pepperspray." - reagent_state = LIQUID - color = "#B31008" // rgb: 179, 16, 8 - -/datum/reagent/condensedcapsaicin/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) - if(ishuman(M)) - var/mob/living/carbon/human/victim = M - var/mouth_covered = 0 - var/eyes_covered = 0 - var/obj/item/safe_thing = null - if( victim.wear_mask ) - if( victim.wear_mask.flags & MASKCOVERSEYES ) - eyes_covered = 1 - safe_thing = victim.wear_mask - if( victim.wear_mask.flags & MASKCOVERSMOUTH ) - mouth_covered = 1 - safe_thing = victim.wear_mask - if( victim.head ) - if( victim.head.flags & MASKCOVERSEYES ) - eyes_covered = 1 - safe_thing = victim.head - if( victim.head.flags & MASKCOVERSMOUTH ) - mouth_covered = 1 - safe_thing = victim.head - if(victim.glasses) - eyes_covered = 1 - if( !safe_thing ) - safe_thing = victim.glasses - if( eyes_covered && mouth_covered ) - to_chat(victim, "Your [safe_thing] protects you from the pepperspray!") - return - else if( mouth_covered ) // Reduced effects if partially protected - to_chat(victim, "Your [safe_thing] protect you from most of the pepperspray!") - if(prob(5)) - victim.emote("scream") - victim.EyeBlurry(3) - victim.EyeBlind(1) - victim.Confused(3) - victim.damageoverlaytemp = 60 - victim.Weaken(3) - victim.drop_item() - return - else if( eyes_covered ) // Eye cover is better than mouth cover - to_chat(victim, "Your [safe_thing] protects your eyes from the pepperspray!") - victim.EyeBlurry(3) - victim.damageoverlaytemp = 30 - return - else // Oh dear :D - if(prob(5)) - victim.emote("scream") - to_chat(victim, "You're sprayed directly in the eyes with pepperspray!") - victim.EyeBlurry(5) - victim.EyeBlind(2) - victim.Confused(6) - victim.damageoverlaytemp = 75 - victim.Weaken(5) - victim.drop_item() - -/datum/reagent/condensedcapsaicin/on_mob_life(mob/living/M) - if(prob(5)) - M.visible_message("[M] [pick("dry heaves!","coughs!","splutters!")]") - ..() diff --git a/code/modules/reagents/newchem/patch.dm b/code/modules/reagents/reagent_containers/patch.dm similarity index 100% rename from code/modules/reagents/newchem/patch.dm rename to code/modules/reagents/reagent_containers/patch.dm diff --git a/paradise.dme b/paradise.dme index ad5db876321..0d341f894de 100644 --- a/paradise.dme +++ b/paradise.dme @@ -1831,54 +1831,47 @@ #include "code\modules\projectiles\projectile\magic.dm" #include "code\modules\projectiles\projectile\reusable.dm" #include "code\modules\projectiles\projectile\special.dm" -#include "code\modules\reagents\Chemistry-Colours.dm" -#include "code\modules\reagents\Chemistry-Holder.dm" -#include "code\modules\reagents\Chemistry-Machinery.dm" -#include "code\modules\reagents\Chemistry-Readme.dm" -#include "code\modules\reagents\pandemic.dm" #include "code\modules\reagents\reagent_containers.dm" #include "code\modules\reagents\reagent_dispenser.dm" -#include "code\modules\reagents\newchem\Blob-Reagents.dm" -#include "code\modules\reagents\newchem\chem_heater.dm" -#include "code\modules\reagents\newchem\disease.dm" -#include "code\modules\reagents\newchem\drinks.dm" -#include "code\modules\reagents\newchem\drugs.dm" -#include "code\modules\reagents\newchem\food.dm" -#include "code\modules\reagents\newchem\medicine.dm" -#include "code\modules\reagents\newchem\newchem_procs.dm" -#include "code\modules\reagents\newchem\other.dm" -#include "code\modules\reagents\newchem\paradise_pop.dm" -#include "code\modules\reagents\newchem\patch.dm" -#include "code\modules\reagents\newchem\pyro.dm" -#include "code\modules\reagents\newchem\toxins.dm" -#include "code\modules\reagents\oldchem\chemical_reaction\_chemical_reaction_base.dm" -#include "code\modules\reagents\oldchem\chemical_reaction\chemical_reaction_drink.dm" -#include "code\modules\reagents\oldchem\chemical_reaction\chemical_reaction_food.dm" -#include "code\modules\reagents\oldchem\chemical_reaction\chemical_reaction_harm.dm" -#include "code\modules\reagents\oldchem\chemical_reaction\chemical_reaction_med.dm" -#include "code\modules\reagents\oldchem\chemical_reaction\chemical_reaction_misc.dm" -#include "code\modules\reagents\oldchem\chemical_reaction\chemical_reaction_slime.dm" -#include "code\modules\reagents\oldchem\reagents\__oldchem_defines.dm" -#include "code\modules\reagents\oldchem\reagents\_reagent_base.dm" -#include "code\modules\reagents\oldchem\reagents\reagents_admin.dm" -#include "code\modules\reagents\oldchem\reagents\reagents_drugs.dm" -#include "code\modules\reagents\oldchem\reagents\reagents_flammable.dm" -#include "code\modules\reagents\oldchem\reagents\reagents_food.dm" -#include "code\modules\reagents\oldchem\reagents\reagents_med.dm" -#include "code\modules\reagents\oldchem\reagents\reagents_misc.dm" -#include "code\modules\reagents\oldchem\reagents\reagents_paint.dm" -#include "code\modules\reagents\oldchem\reagents\reagents_toxin.dm" -#include "code\modules\reagents\oldchem\reagents\reagents_water.dm" -#include "code\modules\reagents\oldchem\reagents\drink\reagents_alcohol.dm" -#include "code\modules\reagents\oldchem\reagents\drink\reagents_drink.dm" -#include "code\modules\reagents\oldchem\reagents\drink\reagents_drink_base.dm" -#include "code\modules\reagents\oldchem\reagents\drink\reagents_drink_cold.dm" +#include "code\modules\reagents\chemistry\colors.dm" +#include "code\modules\reagents\chemistry\holder.dm" +#include "code\modules\reagents\chemistry\readme.dm" +#include "code\modules\reagents\chemistry\reagents.dm" +#include "code\modules\reagents\chemistry\recipes.dm" +#include "code\modules\reagents\chemistry\machinery\chem_heater.dm" +#include "code\modules\reagents\chemistry\machinery\chemistry_machinery.dm" +#include "code\modules\reagents\chemistry\machinery\pandemic.dm" +#include "code\modules\reagents\chemistry\reagents\admin.dm" +#include "code\modules\reagents\chemistry\reagents\alcohol.dm" +#include "code\modules\reagents\chemistry\reagents\blob.dm" +#include "code\modules\reagents\chemistry\reagents\disease.dm" +#include "code\modules\reagents\chemistry\reagents\drink_base.dm" +#include "code\modules\reagents\chemistry\reagents\drink_cold.dm" +#include "code\modules\reagents\chemistry\reagents\drinks.dm" +#include "code\modules\reagents\chemistry\reagents\drugs.dm" +#include "code\modules\reagents\chemistry\reagents\food.dm" +#include "code\modules\reagents\chemistry\reagents\medicine.dm" +#include "code\modules\reagents\chemistry\reagents\misc.dm" +#include "code\modules\reagents\chemistry\reagents\paint.dm" +#include "code\modules\reagents\chemistry\reagents\paradise_pop.dm" +#include "code\modules\reagents\chemistry\reagents\pyrotechnic.dm" +#include "code\modules\reagents\chemistry\reagents\toxins.dm" +#include "code\modules\reagents\chemistry\reagents\water.dm" +#include "code\modules\reagents\chemistry\recipes\drinks.dm" +#include "code\modules\reagents\chemistry\recipes\drugs.dm" +#include "code\modules\reagents\chemistry\recipes\food.dm" +#include "code\modules\reagents\chemistry\recipes\medicine.dm" +#include "code\modules\reagents\chemistry\recipes\others.dm" +#include "code\modules\reagents\chemistry\recipes\pyrotechnics.dm" +#include "code\modules\reagents\chemistry\recipes\slime_extracts.dm" +#include "code\modules\reagents\chemistry\recipes\toxins.dm" #include "code\modules\reagents\reagent_containers\blood_pack.dm" #include "code\modules\reagents\reagent_containers\borghydro.dm" #include "code\modules\reagents\reagent_containers\bottle.dm" #include "code\modules\reagents\reagent_containers\dropper.dm" #include "code\modules\reagents\reagent_containers\glass_containers.dm" #include "code\modules\reagents\reagent_containers\hypospray.dm" +#include "code\modules\reagents\reagent_containers\patch.dm" #include "code\modules\reagents\reagent_containers\pill.dm" #include "code\modules\reagents\reagent_containers\spray.dm" #include "code\modules\reagents\reagent_containers\syringes.dm"