Merge branch 'master' into cool-ipcs

This commit is contained in:
Timothy Teakettle
2020-09-16 05:09:02 +01:00
2723 changed files with 184768 additions and 215036 deletions
+8 -9
View File
@@ -463,17 +463,10 @@
if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts && matching_container && matching_other && meets_temp_requirement && can_special_react)
possible_reactions += C
sortTim(possible_reactions, /proc/cmp_chemical_reactions_default, FALSE)
if(possible_reactions.len)
var/datum/chemical_reaction/selected_reaction = possible_reactions[1]
//select the reaction with the most extreme temperature requirements
for(var/V in possible_reactions)
var/datum/chemical_reaction/competitor = V
if(selected_reaction.is_cold_recipe)
if(competitor.required_temp <= selected_reaction.required_temp)
selected_reaction = competitor
else
if(competitor.required_temp >= selected_reaction.required_temp) //will return with the hotter reacting first.
selected_reaction = competitor
var/list/cached_required_reagents = selected_reaction.required_reagents//update reagents list
var/list/cached_results = selected_reaction.results//resultant chemical list
var/special_react_result = selected_reaction.check_special_react(src)
@@ -1172,3 +1165,9 @@
random_reagents += R
var/picked_reagent = pick(random_reagents)
return picked_reagent
/proc/get_chem_id(chem_name)
for(var/X in GLOB.chemical_reagents_list)
var/datum/reagent/R = GLOB.chemical_reagents_list[X]
if(ckey(chem_name) == ckey(lowertext(R.name)))
return X
@@ -32,7 +32,6 @@
var/nopower_state = "dispenser_nopower"
var/has_panel_overlay = TRUE
var/obj/item/reagent_containers/beaker = null
//dispensable_reagents is copypasted in plumbing synthesizers. Please update accordingly. (I didn't make it global because that would limit custom chem dispensers)
var/list/dispensable_reagents = list(
/datum/reagent/hydrogen,
/datum/reagent/lithium,
@@ -178,11 +177,10 @@
beaker = null
update_icon()
/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/obj/machinery/chem_dispenser/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "chem_dispenser", name, 565, 550, master_ui, state)
ui = new(user, src, "ChemDispenser", name)
if(user.hallucinating())
ui.set_autoupdate(FALSE) //to not ruin the immersion by constantly changing the fake chemicals
ui.open()
@@ -217,7 +215,7 @@
data["beakerTransferAmounts"] = null
data["beakerCurrentpH"] = null
var/list/chemicals = list()
var/chemicals[0]
var/is_hallucinating = FALSE
if(user.hallucinating())
is_hallucinating = TRUE
@@ -276,7 +274,7 @@
. = TRUE
if("eject")
replace_beaker(usr)
. = TRUE //no afterattack
. = TRUE
if("dispense_recipe")
if(!is_operational() || QDELETED(cell))
return
@@ -327,9 +325,9 @@
for(var/reagent in recording_recipe)
var/reagent_id = GLOB.name2reagent[translate_legacy_chem_id(reagent)]
if(!dispensable_reagents.Find(reagent_id))
visible_message("<span class='warning'>[src] buzzes.</span>", "<span class='italics'>You hear a faint buzz.</span>")
visible_message("<span class='warning'>[src] buzzes.</span>", "<span class='hear'>You hear a faint buzz.</span>")
to_chat(usr, "<span class ='danger'>[src] cannot find <b>[reagent]</b>!</span>")
playsound(src, 'sound/machines/buzz-two.ogg', 50, 1)
playsound(src, 'sound/machines/buzz-two.ogg', 50, TRUE)
return
saved_recipes[name] = recording_recipe
recording_recipe = null
@@ -7,6 +7,7 @@
idle_power_usage = 40
resistance_flags = FIRE_PROOF | ACID_PROOF
circuit = /obj/item/circuitboard/machine/chem_heater
var/obj/item/reagent_containers/beaker = null
var/target_temperature = 300
var/heater_coefficient = 0.1
@@ -30,22 +31,20 @@
/obj/machinery/chem_heater/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
if(!can_interact(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return TRUE
/obj/machinery/chem_heater/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(!user)
return FALSE
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && user.can_hold_items())
user.put_in_hands(beaker)
user.put_in_hands(beaker)
beaker = null
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
update_icon()
return TRUE
/obj/machinery/chem_heater/RefreshParts()
heater_coefficient = 0.1
@@ -63,6 +62,7 @@
return
if(on)
if(beaker && beaker.reagents.total_volume)
//keep constant with the chemical acclimator please
beaker.reagents.adjust_thermal_energy((target_temperature - beaker.reagents.chem_temp) * heater_coefficient * SPECIFIC_HEAT_DEFAULT * beaker.reagents.total_volume)
beaker.reagents.handle_reactions()
@@ -83,27 +83,16 @@
updateUsrDialog()
update_icon()
return
if(beaker)
if(istype(I, /obj/item/reagent_containers/dropper))
var/obj/item/reagent_containers/dropper/D = I
D.afterattack(beaker, user, 1)
if(istype(I, /obj/item/reagent_containers/syringe))
var/obj/item/reagent_containers/syringe/S = I
S.afterattack(beaker, user, 1)
return ..()
/obj/machinery/chem_heater/on_deconstruction()
replace_beaker()
return ..()
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/obj/machinery/chem_heater/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "chem_heater", name, 275, 400, master_ui, state)
ui = new(user, src, "ChemHeater", name)
ui.open()
/obj/machinery/chem_heater/ui_data()
@@ -140,14 +129,7 @@
. = TRUE
if("temperature")
var/target = params["target"]
var/adjust = text2num(params["adjust"])
if(target == "input")
target = input("New target temperature:", name, target_temperature) as num|null
if(!isnull(target) && !..())
. = TRUE
else if(adjust)
target = target_temperature + adjust
else if(text2num(target) != null)
if(text2num(target) != null)
target = text2num(target)
. = TRUE
if(.)
@@ -155,4 +137,4 @@
if("eject")
on = FALSE
replace_beaker(usr)
. = TRUE
. = TRUE
@@ -1,5 +1,3 @@
#define PILL_STYLE_COUNT 22 //Update this if you add more pill icons or you die
#define RANDOM_PILL_STYLE 22 //Dont change this one though
/obj/machinery/chem_master
name = "ChemMaster 3000"
@@ -12,6 +10,7 @@
idle_power_usage = 20
resistance_flags = FIRE_PROOF | ACID_PROOF
circuit = /obj/item/circuitboard/machine/chem_master
var/obj/item/reagent_containers/beaker = null
var/obj/item/storage/pill_bottle/bottle = null
var/mode = 1
@@ -32,7 +31,7 @@
for (var/x in 1 to PILL_STYLE_COUNT)
var/list/SL = list()
SL["id"] = x
SL["htmltag"] = assets.icon_class_name("pill[x]")
SL["className"] = assets.icon_class_name("pill[x]")
pillStyles += list(SL)
. = ..()
@@ -154,19 +153,16 @@
bottle?.forceMove(A)
return ..()
/obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
assets.send(user)
ui = new(user, src, ui_key, "chem_master", name, 500, 550, master_ui, state)
ui.open()
/obj/machinery/chem_master/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/simple/pills),
)
//Insert our custom spritesheet css link into the html
/obj/machinery/chem_master/ui_base_html(html)
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
. = replacetext(html, "<!--customheadhtml-->", assets.css_tag())
/obj/machinery/chem_master/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ChemMaster", name)
ui.open()
/obj/machinery/chem_master/ui_data(mob/user)
var/list/data = list()
@@ -182,8 +178,8 @@
data["isPillBottleLoaded"] = bottle ? 1 : 0
if(bottle)
var/datum/component/storage/STRB = bottle.GetComponent(/datum/component/storage)
data["pillBotContent"] = bottle.contents.len
data["pillBotMaxContent"] = STRB.max_items
data["pillBottleCurrentAmount"] = bottle.contents.len
data["pillBottleMaxAmount"] = STRB.max_items
var/beakerContents[0]
if(beaker)
@@ -205,216 +201,219 @@
if(..())
return
switch(action)
if("eject")
replace_beaker(usr)
. = TRUE
if(action == "eject")
replace_beaker(usr)
return TRUE
if("ejectPillBottle")
replace_pillbottle(usr)
. = TRUE
if("transfer")
if(!beaker)
return FALSE
var/reagent = GLOB.name2reagent[params["id"]]
var/amount = text2num(params["amount"])
var/to_container = params["to"]
// Custom amount
if (amount == -1)
amount = text2num(input(
"Enter the amount you want to transfer:",
name, ""))
if (amount == null || amount <= 0)
return FALSE
if (to_container == "buffer")
end_fermi_reaction()
beaker.reagents.trans_id_to(src, reagent, amount)
return TRUE
if (to_container == "beaker" && mode)
end_fermi_reaction()
reagents.trans_id_to(beaker, reagent, amount)
return TRUE
if (to_container == "beaker" && !mode)
end_fermi_reaction()
reagents.remove_reagent(reagent, amount)
return TRUE
if(action == "ejectPillBottle")
if(!bottle)
return FALSE
bottle.forceMove(drop_location())
adjust_item_drop_location(bottle)
bottle = null
return TRUE
if("toggleMode")
mode = !mode
. = TRUE
if(action == "transfer")
if(!beaker)
return FALSE
var/reagent = GLOB.name2reagent[params["id"]]
var/amount = text2num(params["amount"])
var/to_container = params["to"]
// Custom amount
if (amount == -1)
amount = text2num(input(
"Enter the amount you want to transfer:",
name, ""))
if (amount == null || amount <= 0)
return FALSE
if (to_container == "buffer")
end_fermi_reaction()
beaker.reagents.trans_id_to(src, reagent, amount)
return TRUE
if (to_container == "beaker" && mode)
end_fermi_reaction()
reagents.trans_id_to(beaker, reagent, amount)
return TRUE
if (to_container == "beaker" && !mode)
end_fermi_reaction()
reagents.remove_reagent(reagent, amount)
return TRUE
return FALSE
if("pillStyle")
var/id = text2num(params["id"])
chosenPillStyle = id
if(action == "toggleMode")
mode = !mode
return TRUE
if(action == "pillStyle")
var/id = text2num(params["id"])
chosenPillStyle = id
return TRUE
if(action == "create")
if(reagents.total_volume == 0)
return FALSE
var/item_type = params["type"]
// Get amount of items
var/amount = text2num(params["amount"])
if(amount == null)
amount = text2num(input(usr,
"Max 10. Buffer content will be split evenly.",
"How many to make?", 1))
amount = clamp(round(amount), 0, 10)
if (amount <= 0)
return FALSE
// Get units per item
var/vol_each = text2num(params["volume"])
var/vol_each_text = params["volume"]
var/vol_each_max = reagents.total_volume / amount
if (item_type == "pill")
vol_each_max = min(50, vol_each_max)
else if (item_type == "patch")
vol_each_max = min(40, vol_each_max)
else if (item_type == "bottle")
vol_each_max = min(30, vol_each_max)
else if (item_type == "condimentPack")
vol_each_max = min(10, vol_each_max)
else if (item_type == "condimentBottle")
vol_each_max = min(50, vol_each_max)
else if (item_type == "hypoVial")
vol_each_max = min(60, vol_each_max)
else if (item_type == "smartDart")
vol_each_max = min(20, vol_each_max)
else
return FALSE
if(vol_each_text == "auto")
vol_each = vol_each_max
if(vol_each == null)
vol_each = text2num(input(usr,
"Maximum [vol_each_max] units per item.",
"How many units to fill?",
vol_each_max))
vol_each = clamp(vol_each, 0, vol_each_max)
if(vol_each <= 0)
return FALSE
// Get item name
var/name = params["name"]
var/name_has_units = item_type == "pill" || item_type == "patch"
if(!name)
var/name_default = reagents.get_master_reagent_name()
if (name_has_units)
name_default += " ([vol_each]u)"
name = stripped_input(usr,
"Name:",
"Give it a name!",
name_default,
MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return FALSE
// Start filling
if(item_type == "pill")
var/obj/item/reagent_containers/pill/P
var/target_loc = drop_location()
var/drop_threshold = INFINITY
if(bottle)
var/datum/component/storage/STRB = bottle.GetComponent(
/datum/component/storage)
if(STRB)
drop_threshold = STRB.max_items - bottle.contents.len
for(var/i = 0; i < amount; i++)
if(i < drop_threshold)
P = new/obj/item/reagent_containers/pill(target_loc)
else
P = new/obj/item/reagent_containers/pill(drop_location())
P.name = trim("[name] pill")
if(chosenPillStyle == RANDOM_PILL_STYLE)
P.icon_state ="pill[rand(1,21)]"
else
P.icon_state = "pill[chosenPillStyle]"
if(P.icon_state == "pill4")
P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality."
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)//, transfered_by = usr)
return TRUE
if(item_type == "patch")
var/obj/item/reagent_containers/pill/patch/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/pill/patch(drop_location())
P.name = trim("[name] patch")
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)//, transfered_by = usr)
return TRUE
if(item_type == "bottle")
var/obj/item/reagent_containers/glass/bottle/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/glass/bottle(drop_location())
P.name = trim("[name] bottle")
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)//, transfered_by = usr)
return TRUE
if(item_type == "condimentPack")
var/obj/item/reagent_containers/food/condiment/pack/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/food/condiment/pack(drop_location())
P.originalname = name
P.name = trim("[name] pack")
P.desc = "A small condiment pack. The label says it contains [name]."
reagents.trans_to(P, vol_each)//, transfered_by = usr)
return TRUE
if(item_type == "condimentBottle")
var/obj/item/reagent_containers/food/condiment/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/food/condiment(drop_location())
P.originalname = name
P.name = trim("[name] bottle")
reagents.trans_to(P, vol_each)//, transfered_by = usr)
return TRUE
if(item_type == "hypoVial")
var/obj/item/reagent_containers/glass/bottle/vial/small/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location())
P.name = trim("[name] hypovial")
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)//, transfered_by = usr)
return TRUE
if(item_type == "smartDart")
var/obj/item/reagent_containers/syringe/dart/P
for(var/i = 0; i < amount; i++)
P = new /obj/item/reagent_containers/syringe/dart(drop_location())
P.name = trim("[name] SmartDart")
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)//, transfered_by = usr)
P.mode=!mode
P.update_icon()
return TRUE
return FALSE
if(action == "analyze")
// var/datum/reagent/R = GLOB.name2reagent[params["id"]]
var/reagent = GLOB.name2reagent[params["id"]]
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent]
if(R)
var/state = "Unknown"
if(initial(R.reagent_state) == 1)
state = "Solid"
else if(initial(R.reagent_state) == 2)
state = "Liquid"
else if(initial(R.reagent_state) == 3)
state = "Gas"
var/const/P = 3 //The number of seconds between life ticks
var/T = initial(R.metabolization_rate) * (60 / P)
if(istype(R, /datum/reagent/fermi))
fermianalyze = TRUE
var/datum/chemical_reaction/Rcr = get_chemical_reaction(reagent)
var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = R.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
screen = "analyze"
return TRUE
if("create")
if(reagents.total_volume == 0)
return FALSE
var/item_type = params["type"]
// Get amount of items
var/amount = text2num(params["amount"])
if(amount == null)
amount = text2num(input(usr,
"Max 10. Buffer content will be split evenly.",
"How many to make?", 1))
amount = clamp(round(amount), 0, 10)
if (amount <= 0)
return FALSE
// Get units per item
var/vol_each = text2num(params["volume"])
var/vol_each_text = params["volume"]
var/vol_each_max = reagents.total_volume / amount
if (item_type == "pill")
vol_each_max = min(50, vol_each_max)
else if (item_type == "patch")
vol_each_max = min(40, vol_each_max)
else if (item_type == "bottle")
vol_each_max = min(30, vol_each_max)
else if (item_type == "condimentPack")
vol_each_max = min(10, vol_each_max)
else if (item_type == "condimentBottle")
vol_each_max = min(50, vol_each_max)
else if (item_type == "hypoVial")
vol_each_max = min(60, vol_each_max)
else if (item_type == "smartDart")
vol_each_max = min(20, vol_each_max)
else
return FALSE
if(vol_each_text == "auto")
vol_each = vol_each_max
if(vol_each == null)
vol_each = text2num(input(usr,
"Maximum [vol_each_max] units per item.",
"How many units to fill?",
vol_each_max))
vol_each = clamp(vol_each, 0, vol_each_max)
if(vol_each <= 0)
return FALSE
// Get item name
var/name = params["name"]
var/name_has_units = item_type == "pill" || item_type == "patch"
if(!name)
var/name_default = reagents.get_master_reagent_name()
if (name_has_units)
name_default += " ([vol_each]u)"
name = stripped_input(usr,
"Name:",
"Give it a name!",
name_default,
MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return FALSE
// Start filling
if(item_type == "pill")
var/obj/item/reagent_containers/pill/P
var/target_loc = drop_location()
var/drop_threshold = INFINITY
if(bottle)
var/datum/component/storage/STRB = bottle.GetComponent(
/datum/component/storage)
if(STRB)
drop_threshold = STRB.max_items - bottle.contents.len
for(var/i = 0; i < amount; i++)
if(i < drop_threshold)
P = new/obj/item/reagent_containers/pill(target_loc)
else
P = new/obj/item/reagent_containers/pill(drop_location())
P.name = trim("[name] pill")
if(chosenPillStyle == RANDOM_PILL_STYLE)
P.icon_state ="pill[rand(1,21)]"
else
P.icon_state = "pill[chosenPillStyle]"
if(P.icon_state == "pill4")
P.desc = "A tablet or capsule, but not just any, a red one, one taken by the ones not scared of knowledge, freedom, uncertainty and the brutal truths of reality."
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)
return TRUE
if(item_type == "patch")
var/obj/item/reagent_containers/pill/patch/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/pill/patch(drop_location())
P.name = trim("[name] patch")
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)
return TRUE
if(item_type == "bottle")
var/obj/item/reagent_containers/glass/bottle/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/glass/bottle(drop_location())
P.name = trim("[name] bottle")
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)
return TRUE
if(item_type == "condimentPack")
var/obj/item/reagent_containers/food/condiment/pack/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/food/condiment/pack(drop_location())
P.originalname = name
P.name = trim("[name] pack")
P.desc = "A small condiment pack. The label says it contains [name]."
reagents.trans_to(P, vol_each)
return TRUE
if(item_type == "condimentBottle")
var/obj/item/reagent_containers/food/condiment/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/food/condiment(drop_location())
P.originalname = name
P.name = trim("[name] bottle")
reagents.trans_to(P, vol_each)
return TRUE
if(item_type == "hypoVial")
var/obj/item/reagent_containers/glass/bottle/vial/small/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location())
P.name = trim("[name] hypovial")
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)
return TRUE
if(item_type == "smartDart")
var/obj/item/reagent_containers/syringe/dart/P
for(var/i = 0; i < amount; i++)
P = new /obj/item/reagent_containers/syringe/dart(drop_location())
P.name = trim("[name] SmartDart")
adjust_item_drop_location(P)
reagents.trans_to(P, vol_each)
P.mode=!mode
P.update_icon()
return TRUE
return FALSE
if(action == "goScreen")
screen = params["screen"]
return TRUE
if("analyze")
var/datum/reagent/R = GLOB.name2reagent[params["id"]]
if(R)
var/state = "Unknown"
if(initial(R.reagent_state) == 1)
state = "Solid"
else if(initial(R.reagent_state) == 2)
state = "Liquid"
else if(initial(R.reagent_state) == 3)
state = "Gas"
var/const/P = 3 //The number of seconds between life ticks
var/T = initial(R.metabolization_rate) * (60 / P)
if(istype(R, /datum/reagent/fermi))
fermianalyze = TRUE
var/datum/chemical_reaction/Rcr = get_chemical_reaction(R)
var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2
var/datum/reagent/targetReagent = reagents.has_reagent(R)
if(!targetReagent)
CRASH("Tried to find a reagent that doesn't exist in the chem_master!")
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
screen = "analyze"
return TRUE
if("goScreen")
screen = params["screen"]
. = TRUE
return FALSE
@@ -12,11 +12,10 @@
"tricord" = /datum/reagent/medicine/tricordrazine
)
/obj/machinery/chem_dispenser/chem_synthesizer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/obj/machinery/chem_dispenser/chem_synthesizer/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "chem_synthesizer", name, 390, 330, master_ui, state)
ui = new(user, src, "ChemDebugSynthesizer", name)
ui.open()
/obj/machinery/chem_dispenser/chem_synthesizer/ui_act(action, params)
@@ -31,7 +30,11 @@
beaker = null
. = TRUE
if("input")
var/input_reagent = replacetext(lowertext(input("Enter the name of any reagent", "Input") as text), " ", "") //95% of the time, the reagent types is a lowercase, no spaces / underscored version of the name
var/input_reagent = replacetext(lowertext(input("Enter the name of any reagent", "Input") as text|null), " ", "") //95% of the time, the reagent id is a lowercase/no spaces version of the name
if (isnull(input_reagent))
return
if(shortcuts[input_reagent])
input_reagent = shortcuts[input_reagent]
else
@@ -51,7 +54,7 @@
beaker = new /obj/item/reagent_containers/glass/beaker/bluespace(src)
visible_message("<span class='notice'>[src] dispenses a bluespace beaker.</span>")
if("amount")
var/input = input("Units to dispense", "Units") as num|null
var/input = text2num(params["amount"])
if(input)
amount = input
update_icon()
@@ -7,10 +7,11 @@
density = TRUE
icon = 'icons/obj/chemical.dmi'
icon_state = "mixer0"
circuit = /obj/item/circuitboard/computer/pandemic
use_power = TRUE
idle_power_usage = 20
resistance_flags = ACID_PROOF
circuit = /obj/item/circuitboard/computer/pandemic
var/wait
var/datum/symptom/selected_symptom
var/obj/item/reagent_containers/beaker
@@ -23,11 +24,27 @@
QDEL_NULL(beaker)
return ..()
/obj/machinery/computer/pandemic/handle_atom_del(atom/A)
/obj/machinery/computer/pandemic/examine(mob/user)
. = ..()
if(beaker)
var/is_close
if(Adjacent(user)) //don't reveal exactly what's inside unless they're close enough to see the UI anyway.
. += "It contains \a [beaker]."
is_close = TRUE
else
. += "It has a beaker inside it."
. += "<span class='info'>Alt-click to eject [is_close ? beaker : "the beaker"].</span>"
/obj/machinery/computer/pandemic/AltClick(mob/user)
. = ..()
if(user.canUseTopic(src, BE_CLOSE))
eject_beaker()
/obj/machinery/computer/pandemic/handle_atom_del(atom/A)
if(A == beaker)
beaker = null
update_icon()
return ..()
/obj/machinery/computer/pandemic/proc/get_by_index(thing, index)
if(!beaker || !beaker.reagents)
@@ -107,7 +124,7 @@
/obj/machinery/computer/pandemic/proc/reset_replicator_cooldown()
wait = FALSE
update_icon()
playsound(loc, 'sound/machines/ping.ogg', 30, 1)
playsound(src, 'sound/machines/ping.ogg', 30, TRUE)
/obj/machinery/computer/pandemic/update_icon_state()
if(stat & BROKEN)
@@ -117,13 +134,19 @@
/obj/machinery/computer/pandemic/update_overlays()
. = ..()
if(!(stat & BROKEN) && wait)
if(wait)
. += "waitlight"
/obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/obj/machinery/computer/pandemic/proc/eject_beaker()
if(beaker)
beaker.forceMove(drop_location())
beaker = null
update_icon()
/obj/machinery/computer/pandemic/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "pandemic", name, 520, 550, master_ui, state)
ui = new(user, src, "Pandemic", name)
ui.open()
/obj/machinery/computer/pandemic/ui_data(mob/user)
@@ -135,9 +158,9 @@
var/datum/reagent/blood/B = locate() in beaker.reagents.reagent_list
if(B)
data["has_blood"] = TRUE
data[/datum/reagent/blood] = list()
data[/datum/reagent/blood]["dna"] = B.data["blood_DNA"] || "none"
data[/datum/reagent/blood]["type"] = B.data["blood_type"] || "none"
data["blood"] = list() //wha why the fuck are we sending pathtypes to tgui frontend?
data["blood"]["dna"] = B.data["blood_DNA"] || "none"
data["blood"]["type"] = B.data["blood_type"] || "none"
data["viruses"] = get_viruses_data(B)
data["resistances"] = get_resistance_data(B)
else
@@ -153,7 +176,7 @@
return
switch(action)
if("eject_beaker")
replace_beaker(usr)
eject_beaker()
. = TRUE
if("empty_beaker")
if(beaker)
@@ -162,7 +185,7 @@
if("empty_eject_beaker")
if(beaker)
beaker.reagents.clear_reagents()
replace_beaker(usr)
eject_beaker()
. = TRUE
if("rename_disease")
var/id = get_virus_id_by_index(text2num(params["index"]))
@@ -170,75 +193,62 @@
if(!A.mutable)
return
if(A)
var/new_name = sanitize_name(html_encode(trim(params["name"], 50)))
var/new_name = sanitize_name(html_encode(trim(params["name"], 50)))//, allow_numbers = TRUE)
if(!new_name || ..())
return
A.AssignName(new_name)
. = TRUE
if("create_culture_bottle")
if (wait)
return
var/id = get_virus_id_by_index(text2num(params["index"]))
var/datum/disease/advance/A = SSdisease.archive_diseases[id]
if(!istype(A) || !A.mutable)
to_chat(usr, "<span class='warning'>ERROR: Cannot replicate virus strain.</span>")
return
wait = TRUE
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50)
A = A.Copy()
var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY", "viruses" = list(A))
var/list/data = list("viruses" = list(A))
var/obj/item/reagent_containers/glass/bottle/B = new(drop_location())
B.name = "[A.name] culture bottle"
B.desc = "A small bottle. Contains [A.agent] culture in synthblood medium."
B.reagents.add_reagent(/datum/reagent/blood/synthetics, 10, data)
wait = TRUE
update_icon()
var/turf/source_turf = get_turf(src)
log_virus("A culture bottle was printed for the virus [A.admin_details()] at [loc_name(source_turf)] by [key_name(usr)]")
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50)
. = TRUE
if("create_vaccine_bottle")
wait = TRUE
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 400)
if (wait)
return
var/id = params["index"]
var/datum/disease/D = SSdisease.archive_diseases[id]
var/obj/item/reagent_containers/glass/bottle/B = new(drop_location())
B.name = "[D.name] vaccine bottle"
B.reagents.add_reagent(/datum/reagent/vaccine, 15, list(id))
wait = TRUE
update_icon()
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 200)
. = TRUE
/obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
. = TRUE //no afterattack
if(stat & (NOPOWER|BROKEN))
return
var/obj/item/reagent_containers/B = I
if(!user.transferItemToLoc(B, src))
if(beaker)
to_chat(user, "<span class='warning'>A container is already loaded into [src]!</span>")
return
replace_beaker(user, B)
if(!user.transferItemToLoc(I, src))
return
beaker = I
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
update_icon()
else
return ..()
/obj/machinery/computer/pandemic/AltClick(mob/living/user)
. = ..()
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return TRUE
/obj/machinery/computer/pandemic/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
if(user && Adjacent(user) && user.can_hold_items())
if(!user.put_in_hands(beaker))
beaker.forceMove(drop_location())
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/computer/pandemic/on_deconstruction()
replace_beaker(usr)
eject_beaker()
. = ..()
@@ -7,6 +7,7 @@
icon_state = "smoke0"
density = TRUE
circuit = /obj/item/circuitboard/machine/smoke_machine
var/efficiency = 10
var/on = FALSE
var/cooldown = 0
@@ -31,9 +32,18 @@
/obj/machinery/smoke_machine/Initialize()
. = ..()
create_reagents(REAGENTS_BASE_VOLUME)
// AddComponent(/datum/component/plumbing/simple_demand)
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
reagents.maximum_volume += REAGENTS_BASE_VOLUME * B.rating
/obj/machinery/smoke_machine/ComponentInitialize()
. = ..()
AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS, null, CALLBACK(src, .proc/can_be_rotated))
AddComponent(/datum/component/plumbing/simple_demand) //this SURELY CANT' LEAD TO BAD THINGS HAPPENING.
/obj/machinery/smoke_machine/proc/can_be_rotated(mob/user, rotation_type)
return !anchored
/obj/machinery/smoke_machine/update_icon_state()
if((!is_operational()) || (!on) || (reagents.total_volume == 0))
if (panel_open)
@@ -81,10 +91,9 @@
add_fingerprint(user)
if(istype(I, /obj/item/reagent_containers) && I.is_open_container())
var/obj/item/reagent_containers/RC = I
var/units = RC.reagents.trans_to(src, RC.amount_per_transfer_from_this)
var/units = RC.reagents.trans_to(src, RC.amount_per_transfer_from_this) //, transfered_by = user)
if(units)
to_chat(user, "<span class='notice'>You transfer [units] units of the solution to [src].</span>")
log_combat(usr, src, "has added [english_list(RC.reagents.reagent_list)] to [src]")
return
if(default_unfasten_wrench(user, I, 40))
on = FALSE
@@ -100,11 +109,10 @@
reagents.clear_reagents()
return ..()
/obj/machinery/smoke_machine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/obj/machinery/smoke_machine/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, ui_key, "smoke_machine", name, 350, 350, master_ui, state)
ui = new(user, src, "SmokeMachine", name)
ui.open()
/obj/machinery/smoke_machine/ui_data(mob/user)
+9 -1
View File
@@ -8,6 +8,7 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
if (length(initial(R.name)))
.[ckey(initial(R.name))] = t
//Various reagents
//Toxin & acid reagents
//Hydroponics stuff
@@ -52,6 +53,14 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
var/metabolizing = FALSE
var/chemical_flags // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME
var/value = REAGENT_VALUE_NONE //How much does it sell for in cargo?
var/datum/material/material //are we made of material?
/datum/reagent/New()
. = ..()
if(material)
material = SSmaterials.GetMaterialRef(material)
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
. = ..()
@@ -220,4 +229,3 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
bloodsuckerdatum.handle_eat_human_food(disgust, blood_puke, force)
if(blood_change)
bloodsuckerdatum.AddBloodVolume(blood_change)
@@ -1962,12 +1962,12 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/bug_spray/on_mob_life(mob/living/carbon/M)
//Bugs should not drink Bug spray.
if(ismoth(M) || isflyperson(M))
if(isinsect(M) || isflyperson(M))
M.adjustToxLoss(1,0)
return ..()
/datum/reagent/consumable/ethanol/bug_spray/on_mob_add(mob/living/carbon/M)
if(ismoth(M) || isflyperson(M))
if(isinsect(M) || isflyperson(M))
M.emote("scream")
return ..()
@@ -2270,59 +2270,52 @@ All effects don't start immediately, but rather get worse over time; the rate is
////////////////////
//Race-Base-Drinks//
////////////////////
/datum/reagent/consumable/ethanol/species_drink
var/species_required
var/disgust = 25
boozepwr = 50
/datum/reagent/consumable/ethanol/coldscales
/datum/reagent/consumable/ethanol/species_drink/on_mob_life(mob/living/carbon/C)
if(C.dna.species && C.dna.species.species_type == species_required) //species have a species_type variable that refers to one of the drinks
quality = RACE_DRINK
else
C.adjust_disgust(disgust)
/datum/reagent/consumable/ethanol/species_drink/coldscales
name = "Coldscales"
color = "#5AEB52" //(90, 235, 82)
description = "A cold looking drink made for people with scales."
boozepwr = 50 //strong!
taste_description = "dead flies"
glass_icon_state = "coldscales"
glass_name = "glass of Coldscales"
glass_desc = "A soft green drink that looks inviting!"
/datum/reagent/consumable/ethanol/coldscales/on_mob_life(mob/living/carbon/M)
if(islizard(M))
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "lizard"
/datum/reagent/consumable/ethanol/oil_drum
/datum/reagent/consumable/ethanol/species_drink/oil_drum
name = "Oil Drum"
color = "#000000" //(0, 0, 0)
description = "Industeral grade oil mixed with some ethanol to make it a drink. Somehow not known to be toxic."
description = "Industrial grade oil mixed with some ethanol to make it a drink. Somehow not known to be toxic."
boozepwr = 45
taste_description = "oil spill"
glass_icon_state = "oil_drum"
glass_name = "Drum of oil"
glass_desc = "A gray can of booze and oil..."
/datum/reagent/consumable/ethanol/oil_drum/on_mob_life(mob/living/carbon/M)
if(isipcperson(M) || issynthliz(M))
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "robot"
/datum/reagent/consumable/ethanol/nord_king
/datum/reagent/consumable/ethanol/species_drink/nord_king
name = "Nord King"
color = "#EB1010" //(235, 16, 16)
description = "Strong mead mixed with more honey and ethanol. Known to beloved by most palettes."
boozepwr = 50 //strong!
description = "Strong mead mixed with more honey and ethanol. Beloved by its human patrons."
taste_description = "honey and red wine"
glass_icon_state = "nord_king"
glass_name = "Keg of Nord King"
glass_desc = "A dripping keg of red mead."
/datum/reagent/consumable/ethanol/nord_king/on_mob_life(mob/living/carbon/M)
if(ishumanbasic(M) || isdwarf(M) || isangel(M)) //Humans and angel races are rare
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "basic"
/datum/reagent/consumable/ethanol/velvet_kiss
/datum/reagent/consumable/ethanol/species_drink/velvet_kiss
name = "Velvet Kiss"
color = "#EB1010" //(235, 16, 16)
description = "A bloody drink mixed with wine."
@@ -2332,14 +2325,9 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of Velvet Kiss"
glass_desc = "Red and white drink for the upper classes or undead."
/datum/reagent/consumable/ethanol/velvet_kiss/on_mob_life(mob/living/carbon/M)
if(iszombie(M) || isvampire(M) || isdullahan(M)) //Rare races!
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "undead"
/datum/reagent/consumable/ethanol/abduction_fruit
/datum/reagent/consumable/ethanol/species_drink/abduction_fruit
name = "Abduction Fruit"
color = "#DEFACD" //(222, 250, 205)
description = "Mixing of juices to make an alien taste."
@@ -2347,33 +2335,23 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "grass and lime"
glass_icon_state = "abduction_fruit"
glass_name = "glass of Abduction Fruit"
glass_desc = "Mixed fruits that were never ment to be mixed..."
glass_desc = "Mixed fruits that were never meant to be mixed..."
/datum/reagent/consumable/ethanol/abduction_fruit/on_mob_life(mob/living/carbon/M)
if(isabductor(M) || isxenoperson(M))
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "alien"
/datum/reagent/consumable/ethanol/bug_zapper
/datum/reagent/consumable/ethanol/species_drink/bug_zapper
name = "Bug Zapper"
color = "#F5882A" //(222, 250, 205)
description = "Metals and lemon juice. Hardly even a drink."
description = "Copper and lemon juice. Hardly even a drink."
boozepwr = 5 //No booze really
taste_description = "copper and AC power"
glass_icon_state = "bug_zapper"
glass_name = "glass of Bug Zapper"
glass_desc = "An odd mix of copper, lemon juice and power meant for non-human consumption."
/datum/reagent/consumable/ethanol/bug_zapper/on_mob_life(mob/living/carbon/M)
if(isinsect(M) || isflyperson(M) || ismoth(M))
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "bug"
/datum/reagent/consumable/ethanol/mush_crush
/datum/reagent/consumable/ethanol/species_drink/mush_crush
name = "Mush Crush"
color = "#F5882A" //(222, 250, 205)
description = "Soil in a glass."
@@ -2381,16 +2359,11 @@ All effects don't start immediately, but rather get worse over time; the rate is
taste_description = "dirt and iron"
glass_icon_state = "mush_crush"
glass_name = "glass of Mush Crush"
glass_desc = "Popular among people that want to grow their own food rather then drink the soil."
glass_desc = "Popular among people that want to grow their own food rather than drink the soil."
/datum/reagent/consumable/ethanol/mush_crush/on_mob_life(mob/living/carbon/M)
if(ispodperson(M) || ismush(M))
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "plant"
/datum/reagent/consumable/ethanol/darkbrew
/datum/reagent/consumable/ethanol/species_drink/darkbrew
name = "Darkbrew"
color = "#000000" //(0, 0, 0)
description = "Contained dark matter mixed with coffee."
@@ -2400,31 +2373,21 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of Darkbrew"
glass_desc = "A pitch black drink that's commonly confused with a type of coffee."
/datum/reagent/consumable/ethanol/darkbrew/on_mob_life(mob/living/carbon/M)
if(isshadow(M))
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "shadow"
/datum/reagent/consumable/ethanol/hollow_bone
/datum/reagent/consumable/ethanol/species_drink/hollow_bone
name = "Hollow Bone"
color = "#FCF7D4" //(252, 247, 212)
description = "Shockingly none-harmful mix of toxins and milk."
description = "Shockingly non-harmful mix of toxins and milk."
boozepwr = 15
taste_description = "Milk and salt"
glass_icon_state = "hollow_bone"
glass_name = "skull of Hollow Bone"
glass_desc = "Mixing of milk and bone hurting juice for enjoyment for rather skinny people."
glass_desc = "Mixing of milk and bone hurting juice for the enjoyment of rather skinny people."
/datum/reagent/consumable/ethanol/hollow_bone/on_mob_life(mob/living/carbon/M)
if(isplasmaman(M) || isskeleton(M))
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "skeleton"
/datum/reagent/consumable/ethanol/frisky_kitty
/datum/reagent/consumable/ethanol/species_drink/frisky_kitty
name = "Frisky Kitty"
color = "#FCF7D4" //(252, 247, 212)
description = "Warm milk mixed with a catnip."
@@ -2434,14 +2397,9 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "cup of Drisky Kitty"
glass_desc = "Warm milk and some catnip."
/datum/reagent/consumable/ethanol/frisky_kitty/on_mob_life(mob/living/carbon/M)
if(ismammal(M) || iscatperson(M)) //well its not to bad for mammals
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "furry"
/datum/reagent/consumable/ethanol/jell_wyrm
/datum/reagent/consumable/ethanol/species_drink/jell_wyrm
name = "Jell Wyrm"
color = "#FF6200" //(255, 98, 0)
description = "Horrible mix of Co2, toxins and heat. Meant for slime based life."
@@ -2451,15 +2409,9 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of Jell Wyrm"
glass_desc = "A bubbly drink that is rather inviting to those that don't know who it's meant for."
/datum/reagent/consumable/ethanol/jell_wyrm/on_mob_life(mob/living/carbon/M)
if(isjellyperson(M) || isstartjelly(M) || isslimeperson(M) || isluminescent(M))
quality = RACE_DRINK
else
M.adjust_disgust(25)
M.adjustToxLoss(1, 0) //Low tox do to being carp + jell toxins.
return ..()
species_required = "jelly"
/datum/reagent/consumable/ethanol/laval_spit //Yes Laval
/datum/reagent/consumable/ethanol/species_drink/laval_spit //Yes Laval
name = "Laval Spit"
color = "#DE3009" //(222, 48, 9)
description = "Heat minerals and some mauna loa. Meant for rock based life."
@@ -2469,15 +2421,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "glass of Laval Spit"
glass_desc = "Piping hot drink for those who can stomach the heat of lava."
/datum/reagent/consumable/ethanol/laval_spit/on_mob_life(mob/living/carbon/M)
if(isgolem(M))
quality = RACE_DRINK
else
M.adjust_disgust(25)
return ..()
species_required = "golem"
///////////////
//Barrle Wine//
//Barrel Wine//
///////////////
/datum/reagent/consumable/ethanol/fruit_wine
@@ -217,6 +217,9 @@
/datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/M)
if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER))
M.heal_bodypart_damage(1.5,0, 0)
for(var/i in M.all_wounds)
var/datum/wound/iter_wound = i
iter_wound.on_xadone(2)
. = 1
else
if(M.getBruteLoss() && prob(20))
@@ -320,6 +323,83 @@
..()
. = 1
/datum/reagent/consumable/tea/red
name = "Red Tea"
description = "Tasty red tea, helps the body digest food. Drink in moderation!"
color = "#101000" // rgb: 16, 16, 0
nutriment_factor = 0
taste_description = "sweet red tea"
glass_icon_state = "teaglass"
glass_name = "glass of red tea"
glass_desc = "A piping hot tea that helps with the digestion of food."
/datum/reagent/consumable/tea/red/on_mob_life(mob/living/carbon/M)
if(M.nutrition > NUTRITION_LEVEL_HUNGRY)
M.adjust_nutrition(-3)
M.dizziness = max(0,M.dizziness-2)
M.drowsyness = max(0,M.drowsyness-1)
M.jitteriness = max(0,M.jitteriness-3)
M.adjust_bodytemperature(23 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL)
. = 1
/datum/reagent/consumable/tea/green
name = "Green Tea"
description = "Tasty green tea, known to heal livers, it's good for you!"
color = "#101000" // rgb: 16, 16, 0
nutriment_factor = 0
taste_description = "tart green tea"
glass_icon_state = "teaglass"
glass_name = "glass of tea"
glass_desc = "A calming glass of green tea to help get you through the day."
/datum/reagent/consumable/tea/green/on_mob_life(mob/living/carbon/M)
M.adjustOrganLoss(ORGAN_SLOT_LIVER, -0.5) //Detox!
M.dizziness = max(0,M.dizziness-2)
M.drowsyness = max(0,M.drowsyness-1)
M.jitteriness = max(0,M.jitteriness-3)
M.adjust_bodytemperature(15 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL)
. = 1
/datum/reagent/consumable/tea/forest
name = "Forest Tea"
description = "Tea mixed with honey, has both antitoxins and sweetness in one!"
color = "#101000" // rgb: 16, 16, 0
nutriment_factor = 0
quality = DRINK_NICE
taste_description = "sweet tea"
glass_icon_state = "teaglass"
glass_name = "glass of forest tea"
glass_desc = "A lovely glass of tea and honey."
/datum/reagent/consumable/tea/forest/on_mob_life(mob/living/carbon/M)
if(M.getToxLoss() && prob(40))//Two anti-toxins working here
M.adjustToxLoss(-1, 0, TRUE) //heals TOXINLOVERs
//Reminder that honey heals toxin lovers
M.dizziness = max(0,M.dizziness-2)
M.drowsyness = max(0,M.drowsyness-1)
M.jitteriness = max(0,M.jitteriness-3)
M.adjust_bodytemperature(15 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL)
. = 1
/datum/reagent/consumable/tea/mush
name = "Mush Tea"
description = "Tea mixed with mushroom hallucinogen, used for fun rides or self reflection."
color = "#101000" // rgb: 16, 16, 0
nutriment_factor = 0
quality = DRINK_NICE
taste_description = "fungal infections"
glass_icon_state = "teaglass"
glass_name = "glass of mush tea"
glass_desc = "A cold merky brown tea."
/datum/reagent/consumable/tea/mush/on_mob_life(mob/living/carbon/M)
M.set_drugginess(20) //Little better then space drugs
if(prob(20))
M.Dizzy(10)
if(prob(10))
M.disgust = 0
. = 1
/datum/reagent/consumable/lemonade
name = "Lemonade"
description = "Sweet, tangy lemonade. Good for the soul."
@@ -964,12 +1044,6 @@
M.emote("nya")
if(prob(20))
to_chat(M, "<span class = 'notice'>[pick("Headpats feel nice.", "Backrubs would be nice.", "Mew")]</span>")
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/list/adjusted = H.adjust_arousal(5,aphro = TRUE)
for(var/g in adjusted)
var/obj/item/organ/genital/G = g
to_chat(M, "<span class='userlove'>You feel like playing with your [G.name]!</span>")
..()
/datum/reagent/consumable/monkey_energy
@@ -999,3 +1073,37 @@
glass_name = "glass of bungo juice"
glass_desc = "Exotic! You feel like you are on vacation already."
value = REAGENT_VALUE_COMMON
/datum/reagent/consumable/aloejuice
name = "Aloe Juice"
color = "#A3C48B"
description = "A healthy and refreshing juice."
taste_description = "vegetable"
glass_icon_state = "glass_yellow"
glass_name = "glass of aloe juice"
glass_desc = "A healthy and refreshing juice."
/datum/reagent/consumable/aloejuice/on_mob_life(mob/living/M)
if(M.getToxLoss() && prob(30))
M.adjustToxLoss(-1, 0)
..()
. = TRUE
// i googled "natural coagulant" and a couple of results came up for banana peels, so after precisely 30 more seconds of research, i now dub grinding banana peels good for your blood
/datum/reagent/consumable/banana_peel
name = "Pulped Banana Peel"
description = "Okay, so you put a banana peel in a grinder... Why, exactly?"
color = "#863333" // rgb: 175, 175, 0
reagent_state = SOLID
taste_description = "stringy, bitter pulp"
glass_name = "glass of banana peel pulp"
glass_desc = "Okay, so you put a banana peel in a grinder... Why, exactly?"
/datum/reagent/consumable/baked_banana_peel
name = "Baked Banana Peel Powder"
description = "You took a banana peel... pulped it... baked it... Where are you going with this?"
color = "#863333" // rgb: 175, 175, 0
reagent_state = SOLID
taste_description = "bitter powder"
glass_name = "glass of banana peel powder"
description = "You took a banana peel... pulped it... baked it... Where are you going with this?"
@@ -467,7 +467,7 @@
/datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L)
. = ..()
L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/skooma)
L.next_move_modifier *= 2
L.action_cooldown_mod *= 2
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.physiology)
@@ -480,7 +480,7 @@
/datum/reagent/drug/skooma/on_mob_end_metabolize(mob/living/L)
. = ..()
L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/skooma)
L.next_move_modifier *= 0.5
L.action_cooldown_mod *= 0.5
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.physiology)
@@ -542,13 +542,13 @@
/datum/reagent/syndicateadrenals/on_mob_metabolize(mob/living/M)
. = ..()
if(istype(M))
M.next_move_modifier *= 0.5
M.action_cooldown_mod *= 0.5
to_chat(M, "<span class='notice'>You feel an intense surge of energy rushing through your veins.</span>")
/datum/reagent/syndicateadrenals/on_mob_end_metabolize(mob/living/M)
. = ..()
if(istype(M))
M.next_move_modifier *= 2
M.action_cooldown_mod *= 2
to_chat(M, "<span class='notice'>You feel as though the world around you is going faster.</span>")
/datum/reagent/syndicateadrenals/overdose_start(mob/living/M)
@@ -559,128 +559,3 @@
var/mob/living/carbon/C = M
if(!C.undergoing_cardiac_arrest())
C.set_heartattack(TRUE)
//aphrodisiac & anaphrodisiac
/datum/reagent/drug/aphrodisiac
name = "Crocin"
description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac."
taste_description = "strawberries"
color = "#FFADFF"//PINK, rgb(255, 173, 255)
can_synth = FALSE
/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M)
if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO))
if((prob(min(current_cycle/2,5))))
M.emote(pick("moan","blush"))
if(prob(min(current_cycle/4,10)))
var/aroused_message = pick("You feel frisky.", "You're having trouble suppressing your urges.", "You feel in the mood.")
to_chat(M, "<span class='userlove'>[aroused_message]</span>")
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/list/genits = H.adjust_arousal(current_cycle, aphro = TRUE) // redundant but should still be here
for(var/g in genits)
var/obj/item/organ/genital/G = g
to_chat(M, "<span class='userlove'>[G.arousal_verb]!</span>")
..()
/datum/reagent/drug/aphrodisiacplus
name = "Hexacrocin"
description = "Chemically condensed form of basic crocin. This aphrodisiac is extremely powerful and addictive in most animals.\
Addiction withdrawals can cause brain damage and shortness of breath. Overdosage can lead to brain damage and a \
permanent increase in libido (commonly referred to as 'bimbofication')."
taste_description = "liquid desire"
color = "#FF2BFF"//dark pink
addiction_threshold = 20
overdose_threshold = 20
can_synth = FALSE
/datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M)
if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO))
if(prob(5))
if(prob(current_cycle))
M.say(pick("Hnnnnngghh...", "Ohh...", "Mmnnn..."))
else
M.emote(pick("moan","blush"))
if(prob(5))
var/aroused_message
if(current_cycle>25)
aroused_message = pick("You need to fuck someone!", "You're bursting with sexual tension!", "You can't get sex off your mind!")
else
aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.")
to_chat(M, "<span class='userlove'>[aroused_message]</span>")
REMOVE_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/list/genits = H.adjust_arousal(100, aphro = TRUE) // redundant but should still be here
for(var/g in genits)
var/obj/item/organ/genital/G = g
to_chat(M, "<span class='userlove'>[G.arousal_verb]!</span>")
..()
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M)
if(prob(30))
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2)
..()
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage3(mob/living/M)
if(prob(30))
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3)
..()
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage4(mob/living/M)
if(prob(30))
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4)
..()
/datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M)
if(M && M.client?.prefs.arousable && !(M.client?.prefs.cit_toggles & NO_APHRO) && prob(33))
if(prob(5) && ishuman(M) && M.has_dna() && (M.client?.prefs.cit_toggles & BIMBOFICATION))
if(!HAS_TRAIT(M,TRAIT_PERMABONER))
to_chat(M, "<span class='userlove'>Your libido is going haywire!</span>")
ADD_TRAIT(M,TRAIT_PERMABONER,APHRO_TRAIT)
..()
/datum/reagent/drug/anaphrodisiac
name = "Camphor"
description = "Naturally found in some species of evergreen trees, camphor is a waxy substance. When injested by most animals, it acts as an anaphrodisiac\
, reducing libido and calming them. Non-habit forming and not addictive."
taste_description = "dull bitterness"
taste_mult = 2
color = "#D9D9D9"//rgb(217, 217, 217)
reagent_state = SOLID
can_synth = FALSE
/datum/reagent/drug/anaphrodisiac/on_mob_life(mob/living/M)
if(M && M.client?.prefs.arousable && prob(16))
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/list/genits = H.adjust_arousal(-100, aphro = TRUE)
if(genits.len)
to_chat(M, "<span class='notice'>You no longer feel aroused.")
..()
/datum/reagent/drug/anaphrodisiacplus
name = "Hexacamphor"
description = "Chemically condensed camphor. Causes an extreme reduction in libido and a permanent one if overdosed. Non-addictive."
taste_description = "tranquil celibacy"
color = "#D9D9D9"//rgb(217, 217, 217)
reagent_state = SOLID
overdose_threshold = 20
can_synth = FALSE
/datum/reagent/drug/anaphrodisiacplus/on_mob_life(mob/living/M)
if(M && M.client?.prefs.arousable)
REMOVE_TRAIT(M,TRAIT_PERMABONER,APHRO_TRAIT)
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/list/genits = H.adjust_arousal(-100, aphro = TRUE)
if(genits.len)
to_chat(M, "<span class='notice'>You no longer feel aroused.")
..()
/datum/reagent/drug/anaphrodisiacplus/overdose_process(mob/living/M)
if(M && M.client?.prefs.arousable && prob(5))
to_chat(M, "<span class='userlove'>You feel like you'll never feel aroused again...</span>")
ADD_TRAIT(M,TRAIT_NEVERBONER,APHRO_TRAIT)
..()
@@ -117,11 +117,11 @@
/datum/reagent/consumable/cooking_oil/reaction_obj(obj/O, reac_volume)
if(holder && holder.chem_temp >= fry_temperature)
if(isitem(O) && !istype(O, /obj/item/reagent_containers/food/snacks/deepfryholder) && !(O.resistance_flags & (FIRE_PROOF|INDESTRUCTIBLE)))
if(isitem(O) && !O.GetComponent(/datum/component/fried) && !(O.resistance_flags & (FIRE_PROOF|INDESTRUCTIBLE)) && (!O.reagents || isfood(O))) //don't fry stuff we shouldn't
O.loc.visible_message("<span class='warning'>[O] rapidly fries as it's splashed with hot oil! Somehow.</span>")
var/obj/item/reagent_containers/food/snacks/deepfryholder/F = new(O.drop_location(), O)
F.fry(volume)
F.reagents.add_reagent(/datum/reagent/consumable/cooking_oil, reac_volume)
O.fry(volume)
if(O.reagents)
O.reagents.add_reagent(/datum/reagent/consumable/cooking_oil, reac_volume)
/datum/reagent/consumable/cooking_oil/reaction_mob(mob/living/M, method = TOUCH, reac_volume, show_message = 1, touch_protection = 0)
if(!istype(M))
@@ -134,8 +134,8 @@
"<span class='userdanger'>You're covered in boiling oil!</span>")
M.emote("scream")
playsound(M, 'sound/machines/fryer/deep_fryer_emerge.ogg', 25, TRUE)
var/oil_damage = (holder.chem_temp / fry_temperature) * 0.33 //Damage taken per unit
M.adjustFireLoss(min(35, oil_damage * reac_volume)) //Damage caps at 35
var/oil_damage = min((holder.chem_temp / fry_temperature) * 0.33,1) //Damage taken per unit
M.adjustFireLoss(oil_damage * min(reac_volume,20)) //Damage caps at 20
else
..()
return TRUE
@@ -143,10 +143,9 @@
/datum/reagent/consumable/cooking_oil/reaction_turf(turf/open/T, reac_volume)
if(!istype(T) || isgroundlessturf(T))
return
if(reac_volume >= 5)
if(reac_volume >= 5 && holder && holder.chem_temp >= fry_temperature)
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume * 1.5 SECONDS)
T.name = "deep-fried [initial(T.name)]"
T.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY)
T.fry(reac_volume/4)
/datum/reagent/consumable/sugar
name = "Sugar"
@@ -273,7 +272,7 @@
if(isopenturf(T))
var/turf/open/OT = T
OT.MakeSlippery(wet_setting=TURF_WET_ICE, min_wet_time=100, wet_time_to_add=reac_volume SECONDS) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure.
OT.air.temperature -= MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity() // reduces environment temperature by 5K per unit.
OT.air.set_temperature(OT.air.return_temperature() - MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity()) // reduces environment temperature by 5K per unit.
/datum/reagent/consumable/condensedcapsaicin
name = "Condensed Capsaicin"
@@ -508,7 +507,7 @@
var/obj/effect/hotspot/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.set_temperature(max( min(lowertemp.return_temperature()-2000,lowertemp.return_temperature() / 2) ,0))
lowertemp.react(src)
T.assume_air(lowertemp)
qdel(hotspot)
@@ -771,7 +770,6 @@
color = "#97ee63"
taste_description = "pure electricity"
/* //We don't have ethereals here, so I'll just comment it out.
/datum/reagent/consumable/liquidelectricity/reaction_mob(mob/living/M, method=TOUCH, reac_volume) //can't be on life because of the way blood works.
if((method == INGEST || method == INJECT || method == PATCH) && iscarbon(M))
@@ -779,10 +777,9 @@
var/obj/item/organ/stomach/ethereal/stomach = C.getorganslot(ORGAN_SLOT_STOMACH)
if(istype(stomach))
stomach.adjust_charge(reac_volume * REM)
*/
/datum/reagent/consumable/liquidelectricity/on_mob_life(mob/living/carbon/M)
if(prob(25)) // && !isethereal(M))
if(prob(25) && !isethereal(M))
M.electrocute_act(rand(10,15), "Liquid Electricity in their body", 1) //lmao at the newbs who eat energy bars
playsound(M, "sparks", 50, TRUE)
return ..()
@@ -868,4 +865,4 @@
taste_mult = 2
taste_description = "fizzy sweetness"
value = REAGENT_VALUE_COMMON
@@ -144,6 +144,9 @@
M.adjustFireLoss(-power, 0)
M.adjustToxLoss(-power, 0, TRUE) //heals TOXINLOVERs
M.adjustCloneLoss(-power, 0)
for(var/i in M.all_wounds)
var/datum/wound/iter_wound = i
iter_wound.on_xadone(power)
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration
. = 1
metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5)
@@ -192,6 +195,9 @@
M.adjustFireLoss(-1.5 * power, 0)
M.adjustToxLoss(-power, 0, TRUE)
M.adjustCloneLoss(-power, 0)
for(var/i in M.all_wounds)
var/datum/wound/iter_wound = i
iter_wound.on_xadone(power)
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC)
. = 1
..()
@@ -231,7 +237,7 @@
/datum/reagent/medicine/spaceacillin
name = "Spaceacillin"
description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with."
description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with. Also reduces infection in serious burns."
color = "#f2f2f2"
metabolization_rate = 0.1 * REAGENTS_METABOLISM
pH = 8.1
@@ -359,7 +365,7 @@
/datum/reagent/medicine/salglu_solution
name = "Saline-Glucose Solution"
description = "Has a 33% chance per metabolism cycle to heal brute and burn damage. Can be used as a temporary blood substitute."
description = "Has a 33% chance per metabolism cycle to heal brute and burn damage. Can be used as a temporary blood substitute, as well as slowly speeding blood regeneration."
reagent_state = LIQUID
color = "#DCDCDC"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
@@ -367,6 +373,7 @@
taste_description = "sweetness and salt"
var/last_added = 0
var/maximum_reachable = BLOOD_VOLUME_NORMAL - 10 //So that normal blood regeneration can continue with salglu active
var/extra_regen = 0.25 // in addition to acting as temporary blood, also add this much to their actual blood per tick
pH = 5.5
/datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/carbon/M)
@@ -379,7 +386,7 @@
var/amount_to_add = min(M.blood_volume, volume*5)
var/new_blood_level = min(M.blood_volume + amount_to_add, maximum_reachable)
last_added = new_blood_level - M.blood_volume
M.blood_volume = new_blood_level
M.blood_volume = new_blood_level + extra_regen
if(prob(33))
M.adjustBruteLoss(-0.5*REM, 0)
M.adjustFireLoss(-0.5*REM, 0)
@@ -403,7 +410,7 @@
/datum/reagent/medicine/mine_salve
name = "Miner's Salve"
description = "A powerful painkiller. Restores bruising and burns in addition to making the patient believe they are fully healed."
description = "A powerful painkiller. Restores bruising and burns in addition to making the patient believe they are fully healed. Also great for treating severe burn wounds in a pinch."
reagent_state = LIQUID
color = "#6D6374"
metabolization_rate = 0.4 * REAGENTS_METABOLISM
@@ -432,7 +439,7 @@
// +10% success propability on each step, useful while operating in less-than-perfect conditions
if(show_message)
to_chat(M, "<span class='danger'>You feel your wounds fade away to nothing!</span>" )
to_chat(M, "<span class='danger'>You feel your injuries fade away to nothing!</span>" )
..()
/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M)
@@ -453,10 +460,10 @@
/datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M))
if (M.stat == DEAD)
var/mob/living/carbon/C = M
if(M.stat == DEAD)
show_message = 0
if(method in list(INGEST, VAPOR))
var/mob/living/carbon/C = M
C.losebreath++
C.emote("cough")
to_chat(M, "<span class='danger'>You feel your throat closing up!</span>")
@@ -465,6 +472,9 @@
else if(method in list(PATCH, TOUCH))
M.adjustBruteLoss(-1 * reac_volume)
M.adjustFireLoss(-1 * reac_volume)
for(var/i in C.all_wounds)
var/datum/wound/iter_wound = i
iter_wound.on_synthflesh(reac_volume)
if(show_message)
to_chat(M, "<span class='danger'>You feel your burns and bruises healing! It stings like hell!</span>")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
@@ -505,12 +515,13 @@
overdose_threshold = 30
pH = 2
value = REAGENT_VALUE_UNCOMMON
var/healing = 0.5
/datum/reagent/medicine/omnizine/on_mob_life(mob/living/carbon/M)
M.adjustToxLoss(-0.5*REM, 0)
M.adjustOxyLoss(-0.5*REM, 0)
M.adjustBruteLoss(-0.5*REM, 0)
M.adjustFireLoss(-0.5*REM, 0)
M.adjustToxLoss(-healing*REM, 0)
M.adjustOxyLoss(-healing*REM, 0)
M.adjustBruteLoss(-healing*REM, 0)
M.adjustFireLoss(-healing*REM, 0)
..()
. = 1
@@ -522,6 +533,12 @@
..()
. = 1
/datum/reagent/medicine/omnizine/protozine
name = "Protozine"
description = "A less environmentally friendly and somewhat weaker variant of omnizine."
color = "#d8c7b7"
healing = 0.2
/datum/reagent/medicine/calomel
name = "Calomel"
description = "Quickly purges the body of all chemicals. Toxin damage is dealt if the patient is in good condition."
@@ -928,10 +945,18 @@
M.adjustOxyLoss(-20, 0)
M.adjustToxLoss(-20, 0)
M.updatehealth()
var/tplus = world.time - M.timeofdeath
if(M.revive())
M.grab_ghost()
M.emote("gasp")
log_combat(M, M, "revived", src)
var/list/policies = CONFIG_GET(keyed_list/policyconfig)
var/timelimit = CONFIG_GET(number/defib_cmd_time_limit)
var/late = timelimit && (tplus > timelimit)
var/policy = late? policies[POLICYCONFIG_ON_DEFIB_LATE] : policies[POLICYCONFIG_ON_DEFIB_INTACT]
if(policy)
to_chat(M, policy)
M.log_message("revived using strange reagent, [tplus] deciseconds from time of death, considered [late? "late" : "memory-intact"] revival under configured policy limits.", LOG_GAME)
..()
@@ -1544,10 +1569,6 @@
/datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all.
M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25)
M.adjustBruteLoss(-0.35, 0)
if(prob(50))
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate = max(H.bleed_rate - 1, 0)
..()
. = 1
@@ -1580,3 +1601,56 @@
to_chat(C, "[pick(GLOB.wisdoms)]") //give them a random wisdom
..()
// helps bleeding wounds clot faster
/datum/reagent/medicine/coagulant
name = "Sanguirite"
description = "A proprietary coagulant used to help bleeding wounds clot faster."
reagent_state = LIQUID
color = "#bb2424"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
overdose_threshold = 20
/// How much base clotting we do per bleeding wound, multiplied by the below number for each bleeding wound
var/clot_rate = 0.25
/// If we have multiple bleeding wounds, we count the number of bleeding wounds, then multiply the clot rate by this^(n) before applying it to each cut, so more cuts = less clotting per cut (though still more total clotting)
var/clot_coeff_per_wound = 0.9
/datum/reagent/medicine/coagulant/on_mob_life(mob/living/carbon/M)
. = ..()
if(!M.blood_volume || !M.all_wounds)
return
var/effective_clot_rate = clot_rate
for(var/i in M.all_wounds)
var/datum/wound/iter_wound = i
if(iter_wound.blood_flow)
effective_clot_rate *= clot_coeff_per_wound
for(var/i in M.all_wounds)
var/datum/wound/iter_wound = i
iter_wound.blood_flow = max(0, iter_wound.blood_flow - effective_clot_rate)
/datum/reagent/medicine/coagulant/overdose_process(mob/living/M)
. = ..()
if(!M.blood_volume)
return
if(prob(15))
M.losebreath += rand(2,4)
M.adjustOxyLoss(rand(1,3))
if(prob(30))
to_chat(M, "<span class='danger'>You can feel your blood clotting up in your veins!</span>")
else if(prob(10))
to_chat(M, "<span class='userdanger'>You feel like your blood has stopped moving!</span>")
if(prob(50))
var/obj/item/organ/lungs/our_lungs = M.getorganslot(ORGAN_SLOT_LUNGS)
our_lungs.applyOrganDamage(1)
else
var/obj/item/organ/heart/our_heart = M.getorganslot(ORGAN_SLOT_HEART)
our_heart.applyOrganDamage(1)
// can be synthesized on station rather than bought. made by grinding a banana peel, heating it up, then mixing the banana peel powder with salglu
/datum/reagent/medicine/coagulant/weak
name = "Synthi-Sanguirite"
description = "A synthetic coagulant used to help bleeding wounds clot faster. Not quite as effective as name brand Sanguirite, especially on patients with lots of cuts."
clot_coeff_per_wound = 0.8
@@ -70,6 +70,10 @@
B = new(T)
if(data["blood_DNA"])
B.blood_DNA[data["blood_DNA"]] = data["blood_type"]
if(!B.blood_DNA["color"])
B.blood_DNA["color"] = data["bloodcolor"]
else
B.blood_DNA["color"] = BlendRGB(B.blood_DNA["color"], data["bloodcolor"])
if(B.reagents)
B.reagents.add_reagent(type, reac_volume)
B.update_icon()
@@ -77,7 +81,7 @@
/datum/reagent/blood/on_new(list/data)
if(istype(data))
SetViruses(src, data)
color = bloodtype_to_color(data["blood_type"])
color = data["bloodcolor"]
if(data["blood_type"] == "SY")
name = "Synthetic Blood"
taste_description = "oil"
@@ -240,6 +244,11 @@
glass_desc = "The father of all refreshments."
shot_glass_icon_state = "shotglassclear"
/datum/reagent/water/on_mob_life(mob/living/carbon/M)
. = ..()
if(M.blood_volume)
M.blood_volume += 0.1 // water is good for you!
/*
* Water reaction to turf
*/
@@ -259,7 +268,7 @@
if(hotspot && !isspaceturf(T))
if(T.air)
var/datum/gas_mixture/G = T.air
G.temperature = max(min(G.temperature-(CT*1000),G.temperature/CT),TCMB)
G.set_temperature(max(min(G.return_temperature()-(CT*1000),G.return_temperature()/CT),TCMB))
G.react(src)
qdel(hotspot)
var/obj/effect/acid/A = (locate(/obj/effect/acid) in T)
@@ -304,6 +313,13 @@
metabolization_rate = 45 * REAGENTS_METABOLISM
. = 1
/datum/reagent/water/hollowwater
name = "Hollow Water"
description = "An ubiquitous chemical substance that is composed of hydrogen and oxygen, but it looks kinda hollow."
color = "#88878777"
taste_description = "emptyiness"
/datum/reagent/water/holywater
name = "Holy Water"
description = "Water blessed by some deity."
@@ -330,6 +346,8 @@
return ..()
/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)
if(M.blood_volume)
M.blood_volume += 0.1 // water is good for you!
if(!data)
data = list("misc" = 1)
data["misc"]++
@@ -872,7 +890,7 @@
if(istype(O, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/M = O
reac_volume = min(reac_volume, M.amount)
new/obj/item/stack/tile/bronze(get_turf(M), reac_volume)
new/obj/item/stack/sheet/bronze(get_turf(M), reac_volume)
M.use(reac_volume)
/datum/reagent/nitrogen
@@ -939,6 +957,7 @@
color = "#1C1300" // rgb: 30, 20, 0
taste_description = "sour chalk"
pH = 5
material = /datum/material/diamond
/datum/reagent/carbon/reaction_turf(turf/T, reac_volume)
if(!isspaceturf(T))
@@ -1061,6 +1080,7 @@
pH = 6
overdose_threshold = 30
color = "#c2391d"
material = /datum/material/iron
/datum/reagent/iron/on_mob_life(mob/living/carbon/C)
if((HAS_TRAIT(C, TRAIT_NOMARROW)))
@@ -1092,6 +1112,7 @@
reagent_state = SOLID
color = "#F7C430" // rgb: 247, 196, 48
taste_description = "expensive metal"
material = /datum/material/gold
/datum/reagent/silver
name = "Silver"
@@ -1099,6 +1120,7 @@
reagent_state = SOLID
color = "#D0D0D0" // rgb: 208, 208, 208
taste_description = "expensive yet reasonable metal"
material = /datum/material/silver
/datum/reagent/silver/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(M.has_bane(BANE_SILVER))
@@ -1112,6 +1134,7 @@
color = "#B8B8C0" // rgb: 184, 184, 192
taste_description = "the inside of a reactor"
pH = 4
material = /datum/material/uranium
/datum/reagent/uranium/on_mob_life(mob/living/carbon/M)
M.apply_effect(1/M.metabolism_efficiency,EFFECT_IRRADIATE,0)
@@ -1133,6 +1156,7 @@
taste_description = "fizzling blue"
pH = 12
value = REAGENT_VALUE_RARE
material = /datum/material/bluespace
/datum/reagent/bluespace/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == TOUCH || method == VAPOR)
@@ -1150,6 +1174,13 @@
/mob/living/proc/bluespace_shuffle()
do_teleport(src, get_turf(src), 5, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
/datum/reagent/telecrystal
name = "Telecrystal Dust"
description = "A blood-red dust comprised of something that was much more useful when it was intact."
reagent_state = SOLID
color = "#660000" // rgb: 102, 0, 0.
taste_description = "contraband"
/datum/reagent/aluminium
name = "Aluminium"
description = "A silvery white and ductile member of the boron group of chemical elements."
@@ -1164,6 +1195,7 @@
color = "#A8A8A8" // rgb: 168, 168, 168
taste_mult = 0
pH = 10
material = /datum/material/glass
/datum/reagent/fuel
name = "Welding fuel"
@@ -2179,13 +2211,6 @@
M.emote("nya")
if(prob(20))
to_chat(M, "<span class = 'notice'>[pick("Headpats feel nice.", "The feeling of a hairball...", "Backrubs would be nice.", "Whats behind those doors?")]</span>")
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/list/adjusted = H.adjust_arousal(2,aphro = TRUE)
for(var/g in adjusted)
var/obj/item/organ/genital/G = g
to_chat(M, "<span class='userlove'>You feel like playing with your [G.name]!</span>")
..()
/datum/reagent/preservahyde
@@ -2195,6 +2220,66 @@
color = "#f7685e"
metabolization_rate = REAGENTS_METABOLISM * 0.25
/datum/reagent/wittel
name = "Wittel"
description = "An extremely rare metallic-white substance only found on demon-class planets."
color = "#FFFFFF" // rgb: 255, 255, 255
taste_mult = 0 // oderless and tasteless
/datum/reagent/metalgen
name = "Metalgen"
data = list("material"=null)
description = "A purple metal morphic liquid, said to impose it's metallic properties on whatever it touches."
color = "#b000aa"
taste_mult = 0 // oderless and tasteless
var/applied_material_flags = MATERIAL_ADD_PREFIX | MATERIAL_COLOR
var/minumum_material_amount = 100
/datum/reagent/metalgen/reaction_obj(obj/O, volume)
metal_morph(O)
return
/datum/reagent/metalgen/reaction_turf(turf/T, volume)
metal_morph(T)
return
///turn an object into a special material
/datum/reagent/metalgen/proc/metal_morph(atom/A)
var/metal_ref = data["material"]
if(!metal_ref)
return
var/metal_amount = 0
for(var/B in A.custom_materials) //list with what they're made of
metal_amount += A.custom_materials[B]
if(!metal_amount)
metal_amount = minumum_material_amount //some stuff doesn't have materials at all. To still give them properties, we give them a material. Basically doesnt exist
var/list/metal_dat = list()
metal_dat[metal_ref] = metal_amount //if we pass the list directly, byond turns metal_ref into "metal_ref" kjewrg8fwcyvf
A.material_flags = applied_material_flags
A.set_custom_materials(metal_dat)
/datum/reagent/gravitum
name = "Gravitum"
description = "A rare kind of null fluid, capable of temporalily removing all weight of whatever it touches." //i dont even
color = "#050096" // rgb: 5, 0, 150
taste_mult = 0 // oderless and tasteless
metabolization_rate = 0.1 * REAGENTS_METABOLISM //20 times as long, so it's actually viable to use
var/time_multiplier = 1 MINUTES //1 minute per unit of gravitum on objects. Seems overpowered, but the whole thing is very niche
/datum/reagent/gravitum/reaction_obj(obj/O, volume)
O.AddElement(/datum/element/forced_gravity, 0)
addtimer(CALLBACK(O, .proc/_RemoveElement, /datum/element/forced_gravity, 0), volume * time_multiplier)
/datum/reagent/gravitum/on_mob_add(mob/living/L)
L.AddElement(/datum/element/forced_gravity, 0) //0 is the gravity, and in this case weightless
/datum/reagent/gravitum/on_mob_end_metabolize(mob/living/L)
L.RemoveElement(/datum/element/forced_gravity, 0)
//body bluids
/datum/reagent/consumable/semen
@@ -2207,6 +2292,7 @@
color = "#FFFFFF" // rgb: 255, 255, 255
can_synth = FALSE
nutriment_factor = 0.5 * REAGENTS_METABOLISM
var/decal_path = /obj/effect/decal/cleanable/semen
/datum/reagent/consumable/semen/reaction_turf(turf/T, reac_volume)
if(!istype(T))
@@ -2216,7 +2302,7 @@
var/obj/effect/decal/cleanable/semen/S = locate() in T
if(!S)
S = new(T)
S = new decal_path(T)
if(data["blood_DNA"])
S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
@@ -2240,48 +2326,134 @@
blood_DNA |= S.blood_DNA
return ..()
/datum/reagent/consumable/femcum
/datum/reagent/consumable/semen/femcum
name = "Female Ejaculate"
description = "Vaginal lubricant found in most mammals and other animals of similar nature. Where you found this is your own business."
taste_description = "something with a tang" // wew coders who haven't eaten out a girl.
taste_mult = 2
data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null)
reagent_state = LIQUID
color = "#AAAAAA77"
can_synth = FALSE
nutriment_factor = 0.5 * REAGENTS_METABOLISM
decal_path = /obj/effect/decal/cleanable/semen/femcum
/obj/effect/decal/cleanable/femcum
/obj/effect/decal/cleanable/semen/femcum
name = "female ejaculate"
desc = null
gender = PLURAL
density = 0
layer = ABOVE_NORMAL_TURF_LAYER
icon = 'icons/obj/genitals/effects.dmi'
icon_state = "fem1"
random_icon_states = list("fem1", "fem2", "fem3", "fem4")
blood_state = null
bloodiness = null
/obj/effect/decal/cleanable/femcum/Initialize(mapload)
. = ..()
dir = GLOB.cardinals
add_blood_DNA(list("Non-human DNA" = "A+"))
/datum/reagent/determination
name = "Determination"
description = "For when you need to push on a little more. Do NOT allow near plants."
reagent_state = LIQUID
color = "#D2FFFA"
metabolization_rate = 0.75 * REAGENTS_METABOLISM // 5u (WOUND_DETERMINATION_CRITICAL) will last for ~17 ticks
/// Whether we've had at least WOUND_DETERMINATION_SEVERE (2.5u) of determination at any given time. No damage slowdown immunity or indication we're having a second wind if it's just a single moderate wound
var/significant = FALSE
self_consuming = TRUE
/obj/effect/decal/cleanable/femcum/replace_decal(obj/effect/decal/cleanable/femcum/F)
if(F.blood_DNA)
blood_DNA |= F.blood_DNA
return ..()
/datum/reagent/determination/on_mob_end_metabolize(mob/living/carbon/M)
if(significant)
var/stam_crash = 0
for(var/thing in M.all_wounds)
var/datum/wound/W = thing
stam_crash += (W.severity + 1) * 3 // spike of 3 stam damage per wound severity (moderate = 6, severe = 9, critical = 12) when the determination wears off if it was a combat rush
M.adjustStaminaLoss(stam_crash)
M.remove_status_effect(STATUS_EFFECT_DETERMINED)
..()
/datum/reagent/consumable/femcum/reaction_turf(turf/T, reac_volume)
if(!istype(T))
return
if(reac_volume < 10)
return
/datum/reagent/determination/on_mob_life(mob/living/carbon/M)
if(!significant && volume >= WOUND_DETERMINATION_SEVERE)
significant = TRUE
M.apply_status_effect(STATUS_EFFECT_DETERMINED) // in addition to the slight healing, limping cooldowns are divided by 4 during the combat high
var/obj/effect/decal/cleanable/femcum/S = locate() in T
if(!S)
S = new(T)
if(data["blood_DNA"])
S.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
volume = min(volume, WOUND_DETERMINATION_MAX)
for(var/thing in M.all_wounds)
var/datum/wound/W = thing
var/obj/item/bodypart/wounded_part = W.limb
if(wounded_part)
wounded_part.heal_damage(0.25, 0.25)
M.adjustStaminaLoss(-0.25*REM) // the more wounds, the more stamina regen
..()
datum/reagent/eldritch
name = "Eldritch Essence"
description = "Strange liquid that defies the laws of physics"
taste_description = "Ag'hsj'saje'sh"
color = "#1f8016"
/datum/reagent/eldritch/on_mob_life(mob/living/carbon/M)
if(IS_HERETIC(M))
M.drowsyness = max(M.drowsyness-5, 0)
M.AdjustAllImmobility(-40, FALSE)
M.adjustStaminaLoss(-15, FALSE)
M.adjustToxLoss(-3, FALSE)
M.adjustOxyLoss(-3, FALSE)
M.adjustBruteLoss(-3, FALSE)
M.adjustFireLoss(-3, FALSE)
if(ishuman(M) && M.blood_volume < BLOOD_VOLUME_NORMAL)
M.blood_volume += 3
else
M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 150)
M.adjustToxLoss(2, FALSE)
M.adjustFireLoss(2, FALSE)
M.adjustOxyLoss(2, FALSE)
M.adjustBruteLoss(2, FALSE)
holder.remove_reagent(type, 1)
return TRUE
/datum/reagent/cellulose
name = "Cellulose Fibers"
description = "A crystaline polydextrose polymer, plants swear by this stuff."
reagent_state = SOLID
color = "#E6E6DA"
taste_mult = 0
/datum/reagent/hairball
name = "Hairball"
description = "A bundle of keratinous bits and fibers, not easily digestible."
reagent_state = SOLID
can_synth = FALSE
metabolization_rate = 0.05 * REAGENTS_METABOLISM
taste_description = "wet hair"
var/amount = 0
var/knotted = FALSE
/datum/reagent/hairball/on_mob_life(mob/living/carbon/M)
amount = M.reagents.get_reagent_amount(/datum/reagent/hairball)
if(amount < 10)
if(prob(10))
M.losebreath += 1
M.emote("cough")
to_chat(M, "<span class='notice'>You clear your throat.</span>")
else
if(!knotted)
to_chat(M, "<span class='notice'>You feel a knot in your stomach.</span>")
knotted = TRUE
if(prob(5 + amount * 0.5)) // don't want this to cause too much damage
M.losebreath += 2
to_chat(M, "<span class='notice'>You feel a knot in your throat.</span>")
M.emote("cough")
else if(prob(amount - 4))
to_chat(M, "<span class='warning'>Your stomach feels awfully bloated.</span>")
playsound(M,'sound/voice/catpeople/distressed.ogg', 50, FALSE)
M.visible_message("<span class='warning'>[M] seems distressed!.</span>", ignored_mobs=M)
else if(prob(amount - 8))
knotted = FALSE
playsound(M,'sound/voice/catpeople/puking.ogg', 110, FALSE)
M.Immobilize(30)
sleep(30) //snowflake but it works, don't wanna proc this
if(QDELETED(M) || QDELETED(src)) //this handles race conditions about m or src not existing.
return
M.visible_message("<span class='warning'>[M] throws up a hairball! Disgusting!</span>", ignored_mobs=M)
new /obj/item/toy/plush/hairball(get_turf(M))
to_chat(M, "<span class='notice'>Aaaah that's better!</span>")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "cleared_stomach", /datum/mood_event/cleared_stomach, name)
M.reagents.del_reagent(/datum/reagent/hairball)
return
..()
@@ -281,8 +281,8 @@
if(hotspot && !isspaceturf(T))
if(T.air)
var/datum/gas_mixture/G = T.air
if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C)
if(G.return_temperature() > T20C)
G.set_temperature(max(G.return_temperature()/2,T20C))
G.react(src)
qdel(hotspot)
@@ -64,6 +64,7 @@
toxpwr = 3
pH = 4
value = REAGENT_VALUE_RARE //sheets are worth more
material = /datum/material/plasma
/datum/reagent/toxin/plasma/on_mob_life(mob/living/carbon/C)
if(holder.has_reagent(/datum/reagent/medicine/epinephrine))
@@ -154,6 +155,11 @@
pH = 12
value = REAGENT_VALUE_RARE
/datum/reagent/toxin/carpotoxin/on_mob_life(mob/living/carbon/M)
. = ..()
for(var/i in M.all_scars)
qdel(i)
/datum/reagent/toxin/zombiepowder
name = "Zombie Powder"
description = "A strong neurotoxin that puts the subject into a death-like state."
@@ -368,6 +374,14 @@
pH = 4.9
value = REAGENT_VALUE_VERY_COMMON
/datum/reagent/toxin/teapowder/red
name = "Ground Red Tea Leaves"
toxpwr = 0.4
/datum/reagent/toxin/teapowder/green
name = "Ground Green Tea Leaves"
toxpwr = 0.6
/datum/reagent/toxin/mutetoxin //the new zombie powder.
name = "Mute Toxin"
description = "A nonlethal poison that inhibits speech in its victim."
@@ -520,25 +534,6 @@
taste_description = "bad cooking"
value = REAGENT_VALUE_NONE
/datum/reagent/toxin/condensed_cooking_oil
name = "Condensed Cooking Oil"
description = "Taste the consequences of your mistakes."
reagent_state = LIQUID
color = "#d6d6d8"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
toxpwr = 0
taste_mult = -2
taste_description = "awful cooking"
value = REAGENT_VALUE_NONE
/datum/reagent/toxin/condensed_cooking_oil/on_mob_life(mob/living/carbon/M)
if(prob(5))
M.vomit()
else
if(prob(40))
M.adjustOrganLoss(ORGAN_SLOT_HEART, 0.5) //For reference, bungotoxin does 3
..()
/datum/reagent/toxin/itching_powder
name = "Itching Powder"
description = "A powder that induces itching upon contact with the skin. Causes the victim to scratch at their itches and has a very low chance to decay into Histamine."
@@ -736,22 +731,13 @@
/datum/reagent/toxin/heparin //Based on a real-life anticoagulant. I'm not a doctor, so this won't be realistic.
name = "Heparin"
description = "A powerful anticoagulant. Victims will bleed uncontrollably and suffer scaling bruising."
description = "A powerful anticoagulant. All open cut wounds on the victim will open up and bleed much faster"
reagent_state = LIQUID
color = "#C8C8C8" //RGB: 200, 200, 200
metabolization_rate = 0.2 * REAGENTS_METABOLISM
toxpwr = 0
value = REAGENT_VALUE_VERY_RARE
/datum/reagent/toxin/heparin/on_mob_life(mob/living/carbon/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate = min(H.bleed_rate + 2, 8)
H.adjustBruteLoss(1, 0) //Brute damage increases with the amount they're bleeding
. = 1
return ..() || .
/datum/reagent/toxin/rotatium //Rotatium. Fucks up your rotation and is hilarious
name = "Rotatium"
description = "A constantly swirling, oddly colourful fluid. Causes the consumer's sense of direction and hand-eye coordination to become wild."
@@ -5,6 +5,9 @@
var/list/required_reagents = new/list()
var/list/required_catalysts = new/list()
/// Higher is higher priority, determines which order reactions are checked.
var/priority = CHEMICAL_REACTION_PRIORITY_DEFAULT
// 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/required_container = null // the exact container path required for the reaction to happen
var/required_other = 0 // an integer required for the reaction to happen
@@ -62,34 +62,3 @@
results = list(/datum/reagent/moonsugar = 1, /datum/reagent/medicine/morphine = 2.5)
required_temp = 315 //a little above normal body temperature
required_reagents = list(/datum/reagent/drug/skooma = 1)
/datum/chemical_reaction/aphro
name = "crocin"
id = /datum/reagent/drug/aphrodisiac
results = list(/datum/reagent/drug/aphrodisiac = 6)
required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/water = 1)
required_temp = 400
mix_message = "The mixture boils off a pink vapor..."//The water boils off, leaving the crocin
/datum/chemical_reaction/aphroplus
name = "hexacrocin"
id = /datum/reagent/drug/aphrodisiacplus
results = list(/datum/reagent/drug/aphrodisiacplus = 1)
required_reagents = list(/datum/reagent/drug/aphrodisiac = 6, /datum/reagent/phenol = 1)
required_temp = 400
mix_message = "The mixture rapidly condenses and darkens in color..."
/datum/chemical_reaction/anaphro
name = "camphor"
id = /datum/reagent/drug/anaphrodisiac
results = list(/datum/reagent/drug/anaphrodisiac = 6)
required_reagents = list(/datum/reagent/carbon = 2, /datum/reagent/hydrogen = 2, /datum/reagent/oxygen = 2, /datum/reagent/sulfur = 1)
required_temp = 400
mix_message = "The mixture boils off a yellow, smelly vapor..."//Sulfur burns off, leaving the camphor
/datum/chemical_reaction/anaphroplus
name = "pentacamphor"
id = /datum/reagent/drug/anaphrodisiacplus
results = list(/datum/reagent/drug/anaphrodisiacplus = 1)
required_reagents = list(/datum/reagent/drug/aphrodisiac = 5, /datum/reagent/acetone = 1)
required_temp = 300
mix_message = "The mixture thickens and heats up slighty..."
@@ -50,6 +50,18 @@
results = list(/datum/reagent/medicine/salglu_solution = 3)
required_reagents = list(/datum/reagent/consumable/sodiumchloride = 1, /datum/reagent/water = 1, /datum/reagent/consumable/sugar = 1)
/datum/chemical_reaction/baked_banana_peel
results = list(/datum/reagent/consumable/baked_banana_peel = 1)
required_temp = 413.15 // if it's good enough for caramel it's good enough for this
required_reagents = list(/datum/reagent/consumable/banana_peel = 1)
mix_message = "The pulp dries up and takes on a powdery state!"
mob_react = FALSE
/datum/chemical_reaction/coagulant_weak
results = list(/datum/reagent/medicine/coagulant/weak = 3)
required_reagents = list(/datum/reagent/medicine/salglu_solution = 2, /datum/reagent/consumable/baked_banana_peel = 1)
mob_react = FALSE
/datum/chemical_reaction/mine_salve
name = "Miner's Salve"
id = /datum/reagent/medicine/mine_salve
@@ -207,6 +219,12 @@
results = list(/datum/reagent/medicine/strange_reagent = 3)
required_reagents = list(/datum/reagent/medicine/omnizine = 1, /datum/reagent/water/holywater = 1, /datum/reagent/toxin/mutagen = 1)
/datum/chemical_reaction/strange_reagent/alt
name = "Strange Reagent"
id = /datum/reagent/medicine/strange_reagent
results = list(/datum/reagent/medicine/strange_reagent = 2)
required_reagents = list(/datum/reagent/medicine/omnizine/protozine = 1, /datum/reagent/water/holywater = 1, /datum/reagent/toxin/mutagen = 1)
/datum/chemical_reaction/mannitol
name = "Mannitol"
id = /datum/reagent/medicine/mannitol
@@ -318,3 +336,35 @@
id = /datum/reagent/medicine/psicodine
results = list(/datum/reagent/medicine/psicodine = 5)
required_reagents = list( /datum/reagent/medicine/mannitol = 2, /datum/reagent/water = 2, /datum/reagent/impedrezene = 1)
/datum/chemical_reaction/medsuture
required_reagents = list(/datum/reagent/cellulose = 10, /datum/reagent/toxin/formaldehyde = 20, /datum/reagent/medicine/polypyr = 15) //This might be a bit much, reagent cost should be reviewed after implementation.
/datum/chemical_reaction/medsuture/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/stack/medical/suture/medicated(location)
/datum/chemical_reaction/medmesh
required_reagents = list(/datum/reagent/cellulose = 20, /datum/reagent/consumable/aloejuice = 20, /datum/reagent/space_cleaner/sterilizine = 10)
/datum/chemical_reaction/medmesh/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/stack/medical/mesh/advanced(location)
/datum/chemical_reaction/suture
required_reagents = list(/datum/reagent/cellulose = 2, /datum/reagent/medicine/styptic_powder = 2)
/datum/chemical_reaction/suture/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/stack/medical/suture/(location)
/datum/chemical_reaction/mesh
required_reagents = list(/datum/reagent/cellulose = 2, /datum/reagent/medicine/silver_sulfadiazine = 2)
/datum/chemical_reaction/mesh/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/stack/medical/mesh/(location)
@@ -1,3 +1,34 @@
/datum/chemical_reaction/metalgen
name = "metalgen"
id = /datum/reagent/metalgen
required_reagents = list(/datum/reagent/wittel = 1, /datum/reagent/bluespace = 1, /datum/reagent/toxin/mutagen = 1)
results = list(/datum/reagent/metalgen = 1)
/datum/chemical_reaction/metalgen_imprint
name = "metalgen imprint"
id = /datum/reagent/metalgen
required_reagents = list(/datum/reagent/metalgen = 1, /datum/reagent/liquid_dark_matter = 1)
results = list(/datum/reagent/metalgen = 1)
/datum/chemical_reaction/holywater
name = "Holy Water"
id = /datum/reagent/water/holywater
results = list(/datum/reagent/water/holywater = 1)
required_reagents = list(/datum/reagent/water/hollowwater = 1)
required_catalysts = list(/datum/reagent/water/holywater = 1)
/datum/chemical_reaction/metalgen_imprint/on_reaction(datum/reagents/holder, created_volume)
var/datum/reagent/metalgen/MM = holder.get_reagent(/datum/reagent/metalgen)
for(var/datum/reagent/R in holder.reagent_list)
if(R.material && R.volume >= 40)
MM.data["material"] = R.material
holder.remove_reagent(R.type, 40)
/datum/chemical_reaction/gravitum
name = "gravitum"
id = /datum/reagent/gravitum
required_reagents = list(/datum/reagent/wittel = 1, /datum/reagent/sorium = 10)
results = list(/datum/reagent/gravitum = 10)
/datum/chemical_reaction/sterilizine
name = "Sterilizine"
@@ -87,7 +118,7 @@
new /obj/item/stack/sheet/mineral/uranium(location)
/datum/chemical_reaction/bluespacecrystalifaction
name = "Crystal Bluespace"
name = "Crystallized Bluespace"
id = "crystalbluespace"
required_reagents = list(/datum/reagent/consumable/frostoil = 5, /datum/reagent/bluespace = 20, /datum/reagent/iron = 1)
mob_react = FALSE
@@ -684,10 +715,10 @@
required_reagents = list(/datum/reagent/toxin/mindbreaker = 1, /datum/reagent/medicine/synaptizine = 1, /datum/reagent/water = 1)
/datum/chemical_reaction/cat
name = "felined mutation toxic"
name = "felinid mutation toxic"
id = /datum/reagent/mutationtoxin/felinid
results = list(/datum/reagent/mutationtoxin/felinid = 1)
required_reagents = list(/datum/reagent/toxin/mindbreaker = 1, /datum/reagent/ammonia = 1, /datum/reagent/water = 1, /datum/reagent/drug/aphrodisiac = 10, /datum/reagent/mutationtoxin = 1) // Maybe aphro+ if it becomes a shitty meme
required_reagents = list(/datum/reagent/toxin/mindbreaker = 1, /datum/reagent/ammonia = 1, /datum/reagent/water = 1, /datum/reagent/pax/catnip = 1, /datum/reagent/mutationtoxin = 1)
required_temp = 450
/datum/chemical_reaction/moff
@@ -704,6 +735,14 @@
required_reagents = list(/datum/reagent/liquid_dark_matter = 5, /datum/reagent/medicine/synaptizine = 10, /datum/reagent/medicine/oculine = 10, /datum/reagent/mutationtoxin = 1)
required_temp = 600
/datum/chemical_reaction/slime_extractification
required_reagents = list(/datum/reagent/toxin/slimejelly = 30, /datum/reagent/consumable/frostoil = 5, /datum/reagent/toxin/plasma = 5)
mix_message = "The mixture condenses into a ball."
/datum/chemical_reaction/slime_extractification/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
new /obj/item/slime_extract/grey(location)
// Liquid Carpets
/datum/chemical_reaction/carpet
@@ -825,3 +864,8 @@
required_reagents = list(/datum/reagent/medicine/salglu_solution = 1, /datum/reagent/iron = 1, /datum/reagent/stable_plasma = 1)
mix_message = "The mixture congeals and gives off a faint copper scent."
required_temp = 350
/datum/chemical_reaction/cellulose_carbonization
results = list(/datum/reagent/carbon = 1)
required_reagents = list(/datum/reagent/cellulose = 1)
required_temp = 512
@@ -280,6 +280,7 @@
/datum/chemical_reaction/smoke_powder
name = "smoke_powder"
id = /datum/reagent/smoke_powder
priority = CHEMICAL_REACTION_PRIORITY_SMOKE
results = list(/datum/reagent/smoke_powder = 3)
required_reagents = list(/datum/reagent/potassium = 1, /datum/reagent/consumable/sugar = 1, /datum/reagent/phosphorus = 1)
@@ -165,10 +165,7 @@
var/chosen = getbork()
var/obj/B = new chosen(T)
if(prob(5))//Fry it!
var/obj/item/reagent_containers/food/snacks/deepfryholder/fried
fried = new(T, B)
fried.fry() // actually set the name and colour it
B = fried
B.fry() // actually set the name and colour it
if(prob(50))
for(var/j in 1 to rand(1, 3))
step(B, pick(NORTH,SOUTH,EAST,WEST))