Merge remote-tracking branch 'refs/remotes/origin/master' into syntheticbloods

This commit is contained in:
Poojawa
2019-07-31 19:24:39 -05:00
1257 changed files with 31159 additions and 17321 deletions
+36 -15
View File
@@ -21,7 +21,9 @@
if(GLOB.chemical_reactions_list)
return
var/paths = subtypesof(/datum/chemical_reaction)
//Randomized need to go last since they need to check against conflicts with normal recipes
var/paths = subtypesof(/datum/chemical_reaction) - typesof(/datum/chemical_reaction/randomized) + subtypesof(/datum/chemical_reaction/randomized)
GLOB.chemical_reactions_list = list()
for(var/path in paths)
@@ -29,6 +31,9 @@
var/datum/chemical_reaction/D = new path()
var/list/reaction_ids = list()
if(!D.id)
continue
if(D.required_reagents && D.required_reagents.len)
for(var/reaction in D.required_reagents)
reaction_ids += reaction
@@ -53,7 +58,7 @@
var/list/datum/reagent/addiction_list = new/list()
var/reagents_holder_flags
/datum/reagents/New(maximum=100)
/datum/reagents/New(maximum=100, new_flags)
maximum_volume = maximum
//I dislike having these here but map-objects are initialised before world/New() is called. >_>
@@ -62,6 +67,8 @@
if(!GLOB.chemical_reactions_list)
build_chemical_reactions_list()
reagents_holder_flags = new_flags
/datum/reagents/Destroy()
. = ..()
var/list/cached_reagents = reagent_list
@@ -265,6 +272,9 @@
continue
if(!C)
C = R.holder.my_atom
if(!R.metabolizing)
R.metabolizing = TRUE
R.on_mob_metabolize(C)
if(C && R)
if(C.reagent_check(R) != 1)
if(can_overdose)
@@ -311,12 +321,20 @@
C.update_stamina()
update_total()
/datum/reagents/proc/set_reacting(react = TRUE)
if(react)
reagents_holder_flags &= ~(REAGENT_NOREACT)
else
reagents_holder_flags |= REAGENT_NOREACT
//Signals that metabolization has stopped, triggering the end of trait-based effects
/datum/reagents/proc/end_metabolization(mob/living/carbon/C, keep_liverless = TRUE)
var/list/cached_reagents = reagent_list
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(QDELETED(R.holder))
continue
if(keep_liverless && R.self_consuming) //Will keep working without a liver
continue
if(!C)
C = R.holder.my_atom
if(R.metabolizing)
R.metabolizing = FALSE
R.on_mob_end_metabolize(C)
/datum/reagents/proc/conditional_update_move(atom/A, Running = 0)
var/list/cached_reagents = reagent_list
@@ -333,11 +351,11 @@
update_total()
/datum/reagents/proc/handle_reactions()
if(reagents_holder_flags & NO_REACT)
return //Yup, no reactions here. No siree.
var/list/cached_reagents = reagent_list
var/list/cached_reactions = GLOB.chemical_reactions_list
var/datum/cached_my_atom = my_atom
if(reagents_holder_flags & REAGENT_NOREACT)
return //Yup, no reactions here. No siree.
var/reaction_occurred = 0
do
@@ -471,6 +489,9 @@
if(R.id == reagent)
if(my_atom && isliving(my_atom))
var/mob/living/M = my_atom
if(R.metabolizing)
R.metabolizing = FALSE
R.on_mob_end_metabolize(M)
R.on_mob_delete(M)
qdel(R)
reagent_list -= R
@@ -555,7 +576,7 @@
if(!D)
WARNING("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])")
return FALSE
update_total()
var/cached_total = total_volume
if(cached_total + amount > maximum_volume)
@@ -599,9 +620,9 @@
if(data)
R.data = data
R.on_new(data)
if(isliving(my_atom))
R.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete
R.on_mob_add(my_atom) //Must occur befor it could posibly run on_mob_delete
update_total()
if(my_atom)
my_atom.on_reagent_change(ADD_REAGENT)
@@ -800,10 +821,10 @@
// Convenience proc to create a reagents holder for an atom
// Max vol is maximum volume of holder
/atom/proc/create_reagents(max_vol)
/atom/proc/create_reagents(max_vol, flags)
if(reagents)
qdel(reagents)
reagents = new/datum/reagents(max_vol)
reagents = new/datum/reagents(max_vol, flags)
reagents.my_atom = src
/proc/get_random_reagent_id() // Returns a random reagent ID minus blacklisted reagents
@@ -9,7 +9,6 @@
interaction_flags_machine = INTERACT_MACHINE_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE
resistance_flags = FIRE_PROOF | ACID_PROOF
circuit = /obj/item/circuitboard/machine/chem_dispenser
var/cell_type = /obj/item/stock_parts/cell/high
var/obj/item/stock_parts/cell/cell
var/powerefficiency = 0.1
var/amount = 30
@@ -52,7 +51,8 @@
//these become available once upgraded.
var/list/upgrade_reagents = list(
"oil",
"ammonia"
"ammonia",
"ash"
)
var/list/upgrade_reagents2 = list(
@@ -79,7 +79,6 @@
/obj/machinery/chem_dispenser/Initialize()
. = ..()
cell = new cell_type
dispensable_reagents = sortList(dispensable_reagents)
update_icon()
@@ -250,13 +249,8 @@
work_animation()
. = TRUE
if("eject")
if(beaker)
beaker.forceMove(drop_location())
if(Adjacent(usr) && !issilicon(usr))
usr.put_in_hands(beaker)
beaker = null
update_icon()
. = TRUE
replace_beaker(usr)
. = TRUE //no afterattack
if("dispense_recipe")
if(!is_operational() || QDELETED(cell))
return
@@ -269,7 +263,7 @@
if(beaker && dispensable_reagents.Find(r_id)) // but since we verify we have the reagent, it'll be fine
var/datum/reagents/R = beaker.reagents
var/free = R.maximum_volume - R.total_volume
var/actual = min(round(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free)
var/actual = min(max(chemicals_to_dispense[key], res), (cell.charge * powerefficiency)*10, free)
if(actual)
if(!cell.use(actual / powerefficiency))
say("Not enough energy to complete operation!")
@@ -322,14 +316,12 @@
return
if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
var/obj/item/reagent_containers/B = I
. = 1 //no afterattack
if(beaker)
to_chat(user, "<span class='warning'>A container is already loaded into [src]!</span>")
return
. = TRUE //no afterattack
if(!user.transferItemToLoc(B, src))
return
beaker = B
replace_beaker(user, B)
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
updateUsrDialog()
update_icon()
else if(user.a_intent != INTENT_HARM && !istype(I, /obj/item/card/emag))
to_chat(user, "<span class='warning'>You can't load [I] into [src]!</span>")
@@ -381,7 +373,17 @@
dispensable_reagents |= upgrade_reagents3
powerefficiency = round(newpowereff, 0.01)
/obj/machinery/chem_dispenser/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/chem_dispenser/on_deconstruction()
cell = null
@@ -417,6 +419,12 @@
final_list += list(avoid_assoc_duplicate_keys(fuck[1],key_list) = text2num(fuck[2]))
return final_list
/obj/machinery/chem_dispenser/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
/obj/machinery/chem_dispenser/drinks/Initialize()
. = ..()
AddComponent(/datum/component/simple_rotation, ROTATION_ALTCLICK | ROTATION_CLOCKWISE)
@@ -480,9 +488,16 @@
"tomatojuice",
"lemonjuice",
"menthol"
) //prevents the soda machine from obtaining chemical upgrades. .
upgrade_reagents = null
upgrade_reagents2 = null
)
upgrade_reagents = list(
"mushroomhallucinogen",
"nothing",
"cryoxadone"
)
upgrade_reagents2 = list(
"banana",
"berryjuice"
)
upgrade_reagents3 = null
emagged_reagents = list(
"thirteenloko",
@@ -534,19 +549,21 @@
"creme_de_menthe",
"creme_de_cacao",
"triple_sec",
"sake"
)//prevents the booze machine from obtaining chemical upgrades.
upgrade_reagents = null
"sake",
"applejack"
)
upgrade_reagents = list(
"ethanol",
"fernet"
)
upgrade_reagents2 = null
upgrade_reagents3 = null
emagged_reagents = list(
"ethanol",
"iron",
"alexander",
"clownstears",
"minttoxin",
"atomicbomb",
"fernet",
"aphro",
"aphro+"
)
@@ -28,13 +28,23 @@
else
icon_state = "mixer0b"
/obj/machinery/chem_heater/proc/eject_beaker(mob/user)
/obj/machinery/chem_heater/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
/obj/machinery/chem_heater/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/chem_heater/RefreshParts()
heater_coefficient = 0.1
@@ -58,21 +68,19 @@
return
if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
. = 1 //no afterattack
if(beaker)
to_chat(user, "<span class='warning'>A container is already loaded into [src]!</span>")
. = TRUE //no afterattack
var/obj/item/reagent_containers/B = I
if(!user.transferItemToLoc(B, src))
return
if(!user.transferItemToLoc(I, src))
return
beaker = I
to_chat(user, "<span class='notice'>You add [I] to [src].</span>")
replace_beaker(user, B)
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
updateUsrDialog()
update_icon()
return
return ..()
/obj/machinery/chem_heater/on_deconstruction()
eject_beaker()
replace_beaker()
return ..()
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
@@ -122,5 +130,5 @@
target_temperature = CLAMP(target, 0, 1000)
if("eject")
on = FALSE
eject_beaker(usr)
replace_beaker(usr)
. = TRUE
@@ -1,3 +1,6 @@
#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"
desc = "Used to separate chemicals and distribute them in a variety of forms."
@@ -13,12 +16,24 @@
var/obj/item/storage/pill_bottle/bottle = null
var/mode = 1
var/condi = FALSE
var/chosenPillStyle = 1
var/screen = "home"
var/analyzeVars[0]
var/useramount = 30 // Last used amount
var/list/pillStyles
/obj/machinery/chem_master/Initialize()
create_reagents(100)
//Calculate the span tags and ids fo all the available pill icons
var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills)
pillStyles = list()
for (var/x in 1 to PILL_STYLE_COUNT)
var/list/SL = list()
SL["id"] = x
SL["htmltag"] = assets.icon_tag("pill[x]")
pillStyles += list(SL)
. = ..()
/obj/machinery/chem_master/Destroy()
@@ -60,16 +75,6 @@
else
icon_state = "mixer0"
/obj/machinery/chem_master/proc/eject_beaker(mob/user)
if(beaker)
beaker.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(beaker)
else
adjust_item_drop_location(beaker)
beaker = null
update_icon()
/obj/machinery/chem_master/blob_act(obj/structure/blob/B)
if (prob(50))
qdel(src)
@@ -85,49 +90,76 @@
return
if(istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
. = 1 // no afterattack
. = TRUE // no afterattack
if(panel_open)
to_chat(user, "<span class='warning'>You can't use the [src.name] while its panel is opened!</span>")
return
if(beaker)
to_chat(user, "<span class='warning'>A container is already loaded into [src]!</span>")
var/obj/item/reagent_containers/B = I
if(!user.transferItemToLoc(B, src))
return
if(!user.transferItemToLoc(I, src))
return
beaker = I
to_chat(user, "<span class='notice'>You add [I] to [src].</span>")
src.updateUsrDialog()
replace_beaker(user, B)
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
updateUsrDialog()
update_icon()
else if(!condi && istype(I, /obj/item/storage/pill_bottle))
if(bottle)
to_chat(user, "<span class='warning'>A pill bottle is already loaded into [src]!</span>")
return
if(!user.transferItemToLoc(I, src))
return
bottle = I
replace_pillbottle(user, I)
to_chat(user, "<span class='notice'>You add [I] into the dispenser slot.</span>")
src.updateUsrDialog()
updateUsrDialog()
else
return ..()
/obj/machinery/chem_master/on_deconstruction()
eject_beaker()
/obj/machinery/chem_master/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
replace_beaker(user)
return
/obj/machinery/chem_master/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/chem_master/proc/replace_pillbottle(mob/living/user, obj/item/storage/pill_bottle/new_bottle)
if(bottle)
bottle.forceMove(drop_location())
adjust_item_drop_location(bottle)
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
else
adjust_item_drop_location(bottle)
if(new_bottle)
bottle = new_bottle
else
bottle = null
update_icon()
return TRUE
/obj/machinery/chem_master/on_deconstruction()
replace_beaker(usr)
replace_pillbottle(usr)
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()
//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_data(mob/user)
var/list/data = list()
@@ -138,7 +170,7 @@
data["condi"] = condi
data["screen"] = screen
data["analyzeVars"] = analyzeVars
data["chosenPillStyle"] = chosenPillStyle
data["isPillBottleLoaded"] = bottle ? 1 : 0
if(bottle)
GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
@@ -157,6 +189,9 @@
bufferContents.Add(list(list("name" = N.name, "id" = N.id, "volume" = N.volume))) // ^
data["bufferContents"] = bufferContents
//Calculated at init time as it never changes
data["pillStyles"] = pillStyles
return data
/obj/machinery/chem_master/ui_act(action, params)
@@ -164,15 +199,12 @@
return
switch(action)
if("eject")
eject_beaker(usr)
replace_beaker(usr)
. = TRUE
if("ejectp")
if(bottle)
bottle.forceMove(drop_location())
adjust_item_drop_location(bottle)
bottle = null
. = TRUE
replace_pillbottle(usr)
. = TRUE
if("transferToBuffer")
if(beaker)
@@ -218,19 +250,25 @@
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
var/obj/item/reagent_containers/pill/P
var/target_loc = drop_location()
var/target_loc = bottle ? bottle : drop_location()
var/drop_threshold = INFINITY
if(bottle)
GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
if(STRB)
drop_threshold = STRB.max_items - bottle.contents.len
for(var/i = 0; i < amount; i++)
for(var/i in 1 to amount)
if(i < drop_threshold)
P = new(target_loc)
else
P = new(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)
else
@@ -245,6 +283,10 @@
reagents.trans_to(P,10)
. = TRUE
if("pillStyle")
var/id = text2num(params["id"])
chosenPillStyle = id
if("createPatch")
var/many = params["many"]
if(reagents.total_volume == 0)
@@ -311,10 +353,10 @@
return
var/amount_full = 0
var/vol_part = min(reagents.total_volume, 30)
var/vol_part = min(reagents.total_volume, 60)
if(text2num(many))
amount_full = round(reagents.total_volume / 30)
vol_part = reagents.total_volume % 30
amount_full = round(reagents.total_volume / 60)
vol_part = reagents.total_volume % 60
var/name = stripped_input(usr, "Name:","Name your hypovial!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN)
if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
return
@@ -324,7 +366,7 @@
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, 30)
reagents.trans_to(P, 60)
if(vol_part)
P = new/obj/item/reagent_containers/glass/bottle/vial/small(drop_location())
@@ -393,3 +435,6 @@
name = "CondiMaster 3000"
desc = "Used to create condiments and other cooking supplies."
condi = TRUE
#undef PILL_STYLE_COUNT
#undef RANDOM_PILL_STYLE
@@ -19,6 +19,12 @@
var/speed = 1
var/list/holdingitems
var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject")
var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind")
var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice")
var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix")
/obj/machinery/reagentgrinder/Initialize()
. = ..()
holdingitems = list()
@@ -51,7 +57,6 @@
if(A == beaker)
beaker = null
update_icon()
updateUsrDialog()
if(holdingitems[A])
holdingitems -= A
@@ -67,6 +72,18 @@
else
icon_state = "juicer0"
/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
if(beaker)
beaker.forceMove(drop_location())
if(user && Adjacent(user) && !issiliconoradminghost(user))
user.put_in_hands(beaker)
if(new_beaker)
beaker = new_beaker
else
beaker = null
update_icon()
return TRUE
/obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params)
//You can only screw open empty grinder
if(!beaker && !length(holdingitems) && default_deconstruction_screwdriver(user, icon_state, icon_state, I))
@@ -82,17 +99,14 @@
return TRUE
if (istype(I, /obj/item/reagent_containers) && !(I.item_flags & ABSTRACT) && I.is_open_container())
if (!beaker)
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
return TRUE
to_chat(user, "<span class='notice'>You slide [I] into [src].</span>")
beaker = I
update_icon()
updateUsrDialog()
else
to_chat(user, "<span class='warning'>There's already a container inside [src].</span>")
return TRUE //no afterattack
var/obj/item/reagent_containers/B = I
. = TRUE
if(!user.transferItemToLoc(B, src))
return
replace_beaker(user, B)
to_chat(user, "<span class='notice'>You add [B] to [src].</span>")
update_icon()
return
if(holdingitems.len >= limit)
to_chat(user, "<span class='warning'>[src] is filled to capacity!</span>")
@@ -108,8 +122,6 @@
to_chat(user, "<span class='notice'>You empty [I] into [src].</span>")
else
to_chat(user, "<span class='notice'>You fill [src] to the brim.</span>")
updateUsrDialog()
return TRUE
if(!I.grind_results && !I.juice_results)
@@ -125,104 +137,89 @@
if(user.transferItemToLoc(I, src))
to_chat(user, "<span class='notice'>You add [I] to [src].</span>")
holdingitems[I] = TRUE
updateUsrDialog()
return FALSE
/obj/machinery/reagentgrinder/ui_interact(mob/user) // The microwave Menu //I am reasonably certain that this is not a microwave
. = ..()
var/is_chamber_empty = FALSE
var/is_beaker_ready = FALSE
var/processing_chamber = ""
var/beaker_contents = ""
var/dat = ""
if(!operating)
for (var/i in holdingitems)
var/obj/item/O = i
processing_chamber += "\A [O.name]<BR>"
if(operating || !user.canUseTopic(src, !issilicon(user)))
return
if (!processing_chamber)
is_chamber_empty = TRUE
processing_chamber = "Nothing."
if (!beaker)
beaker_contents = "<B>No beaker attached.</B><br>"
else
is_beaker_ready = TRUE
beaker_contents = "<B>The beaker contains:</B><br>"
var/anything = FALSE
for(var/datum/reagent/R in beaker.reagents.reagent_list)
anything = TRUE
beaker_contents += "[R.volume] - [R.name]<br>"
if(!anything)
beaker_contents += "Nothing<br>"
var/list/options = list()
dat = {"
<b>Processing chamber contains:</b><br>
[processing_chamber]<br>
[beaker_contents]<hr>
"}
if (is_beaker_ready)
if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN)))
dat += "<A href='?src=[REF(src)];action=grind'>Grind the reagents</a><BR>"
dat += "<A href='?src=[REF(src)];action=juice'>Juice the reagents</a><BR><BR>"
else if (beaker.reagents.total_volume)
dat += "<A href='?src=[REF(src)];action=mix'>Mix the reagents</a><BR><BR>"
if(length(holdingitems))
dat += "<A href='?src=[REF(src)];action=eject'>Eject the reagents</a><BR>"
if(beaker)
dat += "<A href='?src=[REF(src)];action=detach'>Detach the beaker</a><BR>"
if(beaker || length(holdingitems))
options["eject"] = radial_eject
if(isAI(user))
if(stat & NOPOWER)
return
options["examine"] = radial_examine
// if there is no power or it's broken, the procs will fail but the buttons will still show
if(length(holdingitems))
options["grind"] = radial_grind
options["juice"] = radial_juice
else if(beaker?.reagents.total_volume)
options["mix"] = radial_mix
var/choice
if(length(options) < 1)
return
if(length(options) == 1)
for(var/key in options)
choice = key
else
dat += "Please wait..."
choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
popup.open(1)
return
// post choice verification
if(operating || (isAI(user) && stat & NOPOWER) || !user.canUseTopic(src, !issilicon(user)))
return
/obj/machinery/reagentgrinder/Topic(href, href_list)
if(..())
return
var/mob/user = usr
if(!user.canUseTopic(src))
return
if(stat & (NOPOWER|BROKEN))
return
user.set_machine(src)
if(operating)
updateUsrDialog()
return
switch(href_list["action"])
if ("grind")
switch(choice)
if("eject")
eject(user)
if("grind")
grind(user)
if("juice")
juice(user)
if("mix")
mix(user)
if("eject")
eject(user)
if("detach")
detach(user)
updateUsrDialog()
if("examine")
examine(user)
/obj/machinery/reagentgrinder/proc/detach(mob/user)
if(!beaker)
/obj/machinery/reagentgrinder/examine(mob/user)
. = ..()
if(!in_range(user, src) && !issilicon(user) && !isobserver(user))
to_chat(user, "<span class='warning'>You're too far away to examine [src]'s contents and display!</span>")
return
beaker.forceMove(drop_location())
if(Adjacent(user) && !issilicon(user))
user.put_in_hands(beaker)
beaker = null
update_icon()
updateUsrDialog()
if(operating)
to_chat(user, "<span class='warning'>\The [src] is operating.</span>")
return
if(beaker || length(holdingitems))
to_chat(user, "<span class='notice'>\The [src] contains:</span>")
if(beaker)
to_chat(user, "<span class='notice'>- \A [beaker].</span>")
for(var/i in holdingitems)
var/obj/item/O = i
to_chat(user, "<span class='notice'>- \A [O.name].</span>")
if(!(stat & (NOPOWER|BROKEN)))
to_chat(user, "<span class='notice'>The status display reads:</span>")
to_chat(user, "<span class='notice'>- Grinding reagents at <b>[speed*100]%</b>.<span>")
if(beaker)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
to_chat(user, "<span class='notice'>- [R.volume] units of [R.name].</span>")
/obj/machinery/reagentgrinder/proc/eject(mob/user)
if(!length(holdingitems))
return
for(var/i in holdingitems)
var/obj/item/O = i
O.forceMove(drop_location())
holdingitems -= O
updateUsrDialog()
if(beaker)
replace_beaker(user)
/obj/machinery/reagentgrinder/proc/remove_object(obj/item/O)
holdingitems -= O
@@ -240,7 +237,6 @@
/obj/machinery/reagentgrinder/proc/operate_for(time, silent = FALSE, juicing = FALSE)
shake_for(time / speed)
updateUsrDialog()
operating = TRUE
if(!silent)
if(!juicing)
@@ -251,11 +247,10 @@
/obj/machinery/reagentgrinder/proc/stop_operating()
operating = FALSE
updateUsrDialog()
/obj/machinery/reagentgrinder/proc/juice()
power_change()
if(!beaker || (beaker && (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)))
if(!beaker || stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
return
operate_for(50, juicing = TRUE)
for(var/obj/item/i in holdingitems)
@@ -274,7 +269,7 @@
/obj/machinery/reagentgrinder/proc/grind()
power_change()
if(!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
if(!beaker || stat & (NOPOWER|BROKEN) || beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
return
operate_for(60)
for(var/i in holdingitems)
@@ -296,13 +291,13 @@
/obj/machinery/reagentgrinder/proc/mix(mob/user)
//For butter and other things that would change upon shaking or mixing
power_change()
if(!beaker)
if(!beaker || stat & (NOPOWER|BROKEN))
return
operate_for(50, juicing = TRUE)
addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50)
/obj/machinery/reagentgrinder/proc/mix_complete()
if(beaker && beaker.reagents.total_volume)
if(beaker?.reagents.total_volume)
//Recipe to make Butter
var/butter_amt = FLOOR(beaker.reagents.get_reagent_amount("milk") / MILK_TO_BUTTER_COEFF, 1)
beaker.reagents.remove_reagent("milk", MILK_TO_BUTTER_COEFF * butter_amt)
+1 -1
View File
@@ -230,7 +230,7 @@ By default, all atom have a reagents var - but its empty. if you want to use an
'pouring' our reagents into something else.
atom/proc/is_open_container()
Checks obj/var/container_type & OPENCONTAINER.
Checks atom/var/reagents.reagents_holder_flags & OPENCONTAINER.
If this returns 1 , you can use syringes, beakers etc
to manipulate the contents of this object.
If it's 0, you'll need to write your own custom reagent
@@ -33,6 +33,8 @@
var/addiction_stage4_end = 40
var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick.
var/self_consuming = FALSE
var/metabolizing = FALSE
var/invisible = FALSE //Set to true if it doesn't appear on handheld health analyzers.
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
. = ..()
@@ -68,6 +70,14 @@
/datum/reagent/proc/on_mob_delete(mob/living/L)
return
// Called when this reagent first starts being metabolized by a liver
/datum/reagent/proc/on_mob_metabolize(mob/living/L)
return
// Called when this reagent stops being metabolized by a liver
/datum/reagent/proc/on_mob_end_metabolize(mob/living/L)
return
/datum/reagent/proc/on_move(mob/M)
return
@@ -37,7 +37,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/on_mob_life(mob/living/carbon/C)
if(C.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER)
var/booze_power = boozepwr
if(C.has_trait(TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker
if(HAS_TRAIT(C, TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker
booze_power *= 0.7
C.drunkenness = max((C.drunkenness + (sqrt(volume) * booze_power * ALCOHOL_RATE)), 0) //Volume, power, and server alcohol rate effect how quickly one gets drunk
var/obj/item/organ/liver/L = C.getorganslot(ORGAN_SLOT_LIVER)
@@ -111,7 +111,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY)
return ..()
/datum/reagent/consumable/ethanol/beer/green/on_mob_delete(mob/living/M)
/datum/reagent/consumable/ethanol/beer/green/on_mob_end_metabolize(mob/living/M)
M.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, color)
/datum/reagent/consumable/ethanol/kahlua
@@ -129,7 +129,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
M.AdjustSleeping(-40, FALSE)
if(!M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
if(!HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE))
M.Jitter(5)
..()
. = 1
@@ -165,7 +165,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.drowsyness = max(0,M.drowsyness-7)
M.AdjustSleeping(-40)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL)
if(!M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
if(!HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE))
M.Jitter(5)
return ..()
@@ -186,7 +186,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
to_chat(M, "<span class='notice'>[pick("You have a really bad headache.", "Your eyes hurt.", "You find it hard to stay still.", "You feel your heart practically beating out of your chest.")]</span>")
if(prob(5) && iscarbon(M))
if(M.has_trait(TRAIT_BLIND))
if(HAS_TRAIT(M, TRAIT_BLIND))
var/obj/item/organ/eyes/eye = M.getorganslot(ORGAN_SLOT_EYES)
if(istype(eye))
eye.Remove(M)
@@ -333,7 +333,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
id = "grappa"
description = "A fine Italian brandy, for when regular wine just isn't alcoholic enough for you."
color = "#F8EBF1"
boozepwr = 45
boozepwr = 60
taste_description = "classy bitter sweetness"
glass_icon_state = "grappa"
glass_name = "glass of grappa"
@@ -364,7 +364,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
shot_glass_icon_state = "shotglassgreen"
/datum/reagent/consumable/ethanol/absinthe/on_mob_life(mob/living/carbon/M)
if(prob(10) && !M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
if(prob(10) && !HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE))
M.hallucination += 4 //Reference to the urban myth
..()
@@ -379,6 +379,11 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "Hooch"
glass_desc = "You've really hit rock bottom now... your liver packed its bags and left last night."
/datum/reagent/consumable/ethanol/hooch/on_mob_life(mob/living/carbon/M)
if(M.mind && M.mind.assigned_role == "Assistant")
M.heal_bodypart_damage(1,1)
. = TRUE
return ..() || .
/datum/reagent/consumable/ethanol/ale
name = "Ale"
@@ -569,13 +574,13 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "Tequila and Coffee liqueur, brought together in a mouthwatering mixture. Drink up."
var/tough_text
/datum/reagent/consumable/ethanol/brave_bull/on_mob_add(mob/living/M)
/datum/reagent/consumable/ethanol/brave_bull/on_mob_metabolize(mob/living/M)
tough_text = pick("brawny", "tenacious", "tough", "hardy", "sturdy") //Tuff stuff
to_chat(M, "<span class='notice'>You feel [tough_text]!</span>")
M.maxHealth += 10 //Brave Bull makes you sturdier, and thus capable of withstanding a tiny bit more punishment.
M.health += 10
/datum/reagent/consumable/ethanol/brave_bull/on_mob_delete(mob/living/M)
/datum/reagent/consumable/ethanol/brave_bull/on_mob_end_metabolize(mob/living/M)
to_chat(M, "<span class='notice'>You no longer feel [tough_text].</span>")
M.maxHealth -= 10
M.health = min(M.health - 10, M.maxHealth) //This can indeed crit you if you're alive solely based on alchol ingestion
@@ -593,7 +598,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "Oh great, now you feel nostalgic about sunrises back on Terra..."
var/obj/effect/light_holder
/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_add(mob/living/M)
/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_metabolize(mob/living/M)
to_chat(M, "<span class='notice'>You feel gentle warmth spread through your body!</span>")
light_holder = new(M)
light_holder.set_light(3, 0.7, "#FFCC00") //Tequila Sunrise makes you radiate dim light, like a sunrise!
@@ -605,7 +610,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
light_holder.forceMove(M)
return ..()
/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_delete(mob/living/M)
/datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_end_metabolize(mob/living/M)
to_chat(M, "<span class='notice'>The warmth in your body fades.</span>")
QDEL_NULL(light_holder)
@@ -633,25 +638,48 @@ All effects don't start immediately, but rather get worse over time; the rate is
color = "#664300" // rgb: 102, 67, 0
boozepwr = 90 //THE FIST OF THE LAW IS STRONG AND HARD
quality = DRINK_GOOD
metabolization_rate = 0.8
metabolization_rate = 0.5
taste_description = "JUSTICE"
glass_icon_state = "beepskysmashglass"
glass_name = "Beepsky Smash"
glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW."
overdose_threshold = 40
var/datum/brain_trauma/special/beepsky/B
/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_metabolize(mob/living/carbon/M)
if(HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE))
metabolization_rate = 0.8
if(!HAS_TRAIT(M, TRAIT_LAW_ENFORCEMENT_METABOLISM))
B = new()
M.gain_trauma(B, TRAUMA_RESILIENCE_ABSOLUTE)
..()
/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/carbon/M)
if(M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
M.Stun(30, 0) //this realistically does nothing to prevent chainstunning but will cause them to recover faster once it's out of their system
else
M.Stun(40, 0)
M.Jitter(2)
if(HAS_TRAIT(M, TRAIT_LAW_ENFORCEMENT_METABOLISM))
M.adjustStaminaLoss(-10, 0)
if(prob(20))
new /datum/hallucination/items_other(M)
if(prob(10))
new /datum/hallucination/stray_bullet(M)
..()
. = TRUE
/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_end_metabolize(mob/living/carbon/M)
if(B)
QDEL_NULL(B)
return ..()
/datum/reagent/consumable/ethanol/beepsky_smash/overdose_start(mob/living/carbon/M)
if(!HAS_TRAIT(M, TRAIT_LAW_ENFORCEMENT_METABOLISM))
M.gain_trauma(/datum/brain_trauma/mild/phobia/security, TRAUMA_RESILIENCE_BASIC)
/datum/reagent/consumable/ethanol/irish_cream
name = "Irish Cream"
id = "irishcream"
description = "Whiskey-imbued cream, what else would you expect from the Irish?"
color = "#664300" // rgb: 102, 67, 0
boozepwr = 70
boozepwr = 50
quality = DRINK_NICE
taste_description = "creamy alcohol"
glass_icon_state = "irishcreamglass"
@@ -671,10 +699,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "A manly concoction made from Ale and Beer. Intended for true men only."
var/dorf_mode
/datum/reagent/consumable/ethanol/manly_dorf/on_mob_add(mob/living/M)
/datum/reagent/consumable/ethanol/manly_dorf/on_mob_metabolize(mob/living/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.dna.check_mutation(DWARFISM) || H.has_trait(TRAIT_ALCOHOL_TOLERANCE))
if(H.dna.check_mutation(DWARFISM) || HAS_TRAIT(H, TRAIT_ALCOHOL_TOLERANCE))
to_chat(H, "<span class='notice'>Now THAT is MANLY!</span>")
boozepwr = 5 //We've had worse in the mines
dorf_mode = TRUE
@@ -722,7 +750,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "Kahlua, Irish Cream, and cognac. You will get bombed."
shot_glass_icon_state = "b52glass"
/datum/reagent/consumable/ethanol/b52/on_mob_add(mob/living/M)
/datum/reagent/consumable/ethanol/b52/on_mob_metabolize(mob/living/M)
playsound(M, 'sound/effects/explosion_distant.ogg', 100, FALSE)
/datum/reagent/consumable/ethanol/irishcoffee
@@ -947,7 +975,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
id = "red_mead"
description = "The true Viking drink! Even though it has a strange red color."
color = "#C73C00" // rgb: 199, 60, 0
boozepwr = 51 //Red drinks are stronger
boozepwr = 31 //Red drinks are stronger
quality = DRINK_GOOD
taste_description = "sweet and salty alcohol"
glass_icon_state = "red_meadglass"
@@ -960,7 +988,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
description = "A Viking drink, though a cheap one."
color = "#664300" // rgb: 102, 67, 0
nutriment_factor = 1 * REAGENTS_METABOLISM
boozepwr = 50
boozepwr = 30
quality = DRINK_NICE
taste_description = "sweet, sweet alcohol"
glass_icon_state = "meadglass"
@@ -1274,7 +1302,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/atomicbomb/on_mob_life(mob/living/carbon/M)
M.set_drugginess(50)
if(!M.has_trait(TRAIT_ALCOHOL_TOLERANCE))
if(!HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE))
M.confused = max(M.confused+2,0)
M.Dizzy(10)
M.slurring = max(M.slurring,50)
@@ -1319,32 +1347,49 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/neurotoxin
name = "Neurotoxin"
id = "neurotoxin"
description = "A strong neurotoxin that puts the subject into a death-like state."
color = "#2E2E61" // rgb: 46, 46, 97
boozepwr = 0 //custom drunk effect
boozepwr = 50
quality = DRINK_VERYGOOD
taste_description = "a numbing sensation"
metabolization_rate = 1 * REAGENTS_METABOLISM
glass_icon_state = "neurotoxinglass"
glass_name = "Neurotoxin"
glass_desc = "A drink that is guaranteed to knock you silly."
/datum/reagent/consumable/ethanol/neurotoxin/proc/pickt()
return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG))
/datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/M)
M.Knockdown(60, 1, 0)
M.set_drugginess(50)
M.dizziness +=2
switch(current_cycle)
if(15 to 45)
M.slurring = max(M.slurring,50)
M.slurring += 3
if(45 to 55)
if(prob(50))
M.confused = max(M.confused+3,0)
if(55 to 200)
M.set_drugginess(55)
if(200 to INFINITY)
M.adjustToxLoss(2, 0)
M.adjustBrainLoss(1*REM, 150)
if(prob(20))
M.adjustStaminaLoss(10)
M.drop_all_held_items()
to_chat(M, "<span class='notice'>You cant feel your hands!</span>")
if(current_cycle > 5)
if(prob(20))
var/t = pickt()
ADD_TRAIT(M, t, type)
M.adjustStaminaLoss(10)
if(current_cycle > 30)
M.adjustBrainLoss(2*REM)
if(current_cycle > 50 && prob(15))
if(!M.undergoing_cardiac_arrest() && M.can_heartattack())
M.set_heartattack(TRUE)
if(M.stat == CONSCIOUS)
M.visible_message("<span class='userdanger'>[M] clutches at [M.p_their()] chest as if [M.p_their()] heart stopped!</span>")
. = TRUE
..()
/datum/reagent/consumable/ethanol/neurotoxin/on_mob_end_metabolize(mob/living/carbon/M)
REMOVE_TRAIT(M, TRAIT_PARALYSIS_L_ARM, type)
REMOVE_TRAIT(M, TRAIT_PARALYSIS_R_ARM, type)
REMOVE_TRAIT(M, TRAIT_PARALYSIS_R_LEG, type)
REMOVE_TRAIT(M, TRAIT_PARALYSIS_L_LEG, type)
M.adjustStaminaLoss(10)
..()
. = 1
/datum/reagent/consumable/ethanol/hippies_delight
name = "Hippie's Delight"
@@ -1468,7 +1513,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "An intimidating and lawful beverage dares you to violate the law and make its day. Still can't drink it on duty, though."
/datum/reagent/consumable/ethanol/quadruple_sec/on_mob_life(mob/living/carbon/M)
if(M.mind && M.mind.assigned_role in list("Security Officer", "Detective", "Head of Security", "Warden", "Lawyer")) //Securidrink in line with the screwderiver for engineers or nothing for mimes.
if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) //Securidrink in line with the screwderiver for engineers or nothing for mimes.
M.heal_bodypart_damage(1, 1)
M.adjustBruteLoss(-2,0)
. = 1
@@ -1487,7 +1532,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "Now you are become law, destroyer of clowns."
/datum/reagent/consumable/ethanol/quintuple_sec/on_mob_life(mob/living/carbon/M)
if(M.mind && M.mind.assigned_role in list("Security Officer", "Detective", "Head of Security", "Warden", "Lawyer")) //Securidrink in line with the screwderiver for engineers or nothing for mimes but STRONG..
if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) //Securidrink in line with the screwderiver for engineers or nothing for mimes but STRONG..
M.heal_bodypart_damage(2,2,2)
M.adjustBruteLoss(-5,0)
M.adjustOxyLoss(-5,0)
@@ -1534,7 +1579,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "If you're feeling low, count on the buttery flavor of our own bastion bourbon."
shot_glass_icon_state = "shotglassgreen"
/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_add(mob/living/L)
/datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_metabolize(mob/living/L)
var/heal_points = 10
if(L.health <= 0)
heal_points = 20 //heal more if we're in softcrit
@@ -1618,7 +1663,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_name = "Crevice Spike"
glass_desc = "It'll either knock the drunkenness out of you or knock you out cold. Both, probably."
/datum/reagent/consumable/ethanol/crevice_spike/on_mob_add(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out
/datum/reagent/consumable/ethanol/crevice_spike/on_mob_metabolize(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out
L.adjustBruteLoss(3 * min(5,volume)) //minimum 3 brute damage on ingestion to limit non-drink means of injury - a full 5 unit gulp of the drink trucks you for the full 15
/datum/reagent/consumable/ethanol/sake
@@ -1661,7 +1706,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_desc = "A creamy, indulgent delight that is stronger than it seems."
var/obj/item/shield/mighty_shield
/datum/reagent/consumable/ethanol/alexander/on_mob_add(mob/living/L)
/datum/reagent/consumable/ethanol/alexander/on_mob_metabolize(mob/living/L)
if(ishuman(L))
var/mob/living/carbon/human/thehuman = L
for(var/obj/item/shield/theshield in thehuman.contents)
@@ -1675,7 +1720,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
if(mighty_shield && !(mighty_shield in L.contents)) //If you had a shield and lose it, you lose the reagent as well. Otherwise this is just a normal drink.
L.reagents.del_reagent("alexander")
/datum/reagent/consumable/ethanol/alexander/on_mob_delete(mob/living/L)
/datum/reagent/consumable/ethanol/alexander/on_mob_end_metabolize(mob/living/L)
if(mighty_shield)
mighty_shield.block_chance -= 10
to_chat(L,"<span class='notice'>You notice [mighty_shield] looks worn again. Weird.</span>")
@@ -1796,7 +1841,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.overeatduration = 0
return ..()
/datum/reagent/consumable/ethanol/fanciulli/on_mob_add(mob/living/M)
/datum/reagent/consumable/ethanol/fanciulli/on_mob_metabolize(mob/living/M)
if(M.health > 0)
M.adjustStaminaLoss(20)
. = TRUE
@@ -1820,12 +1865,236 @@ All effects don't start immediately, but rather get worse over time; the rate is
M.adjust_bodytemperature(-20 * TEMPERATURE_DAMAGE_COEFFICIENT, T0C)
return ..()
/datum/reagent/consumable/ethanol/branca_menta/on_mob_add(mob/living/M)
/datum/reagent/consumable/ethanol/branca_menta/on_mob_metabolize(mob/living/M)
if(M.health > 0)
M.adjustStaminaLoss(35)
. = TRUE
..()
/datum/reagent/consumable/ethanol/blank_paper
name = "Blank Paper"
id = "blank_paper"
description = "A bubbling glass of blank paper. Just looking at it makes you feel fresh."
nutriment_factor = 1 * REAGENTS_METABOLISM
color = "#DCDCDC" // rgb: 220, 220, 220
boozepwr = 20
quality = DRINK_GOOD
taste_description = "bubbling possibility"
glass_icon_state = "blank_paper"
glass_name = "glass of blank paper"
glass_desc = "A fizzy cocktail for those looking to start fresh."
/datum/reagent/consumable/ethanol/blank_paper/on_mob_life(mob/living/carbon/M)
if(ishuman(M) && M.job == "Mime")
M.heal_bodypart_damage(1,1)
. = 1
return ..()
/datum/reagent/consumable/ethanol/champagne //How the hell did we not have champagne already!?
name = "Champagne"
id = "champagne"
description = "A sparkling wine known for its ability to strike fast and hard."
color = "#ffffc1"
boozepwr = 40
taste_description = "auspicious occasions and bad decisions"
glass_icon_state = "champagne_glass"
glass_name = "Champagne"
glass_desc = "The flute clearly displays the slowly rising bubbles."
/datum/reagent/consumable/ethanol/wizz_fizz
name = "Wizz Fizz"
id = "wizz_fizz"
description = "A magical potion, fizzy and wild! However the taste, you will find, is quite mild."
color = "#4235d0" //Just pretend that the triple-sec was blue curacao.
boozepwr = 50
quality = DRINK_GOOD
taste_description = "friendship! It is magic, after all"
glass_icon_state = "wizz_fizz"
glass_name = "Wizz Fizz"
glass_desc = "The glass bubbles and froths with an almost magical intensity."
/datum/reagent/consumable/ethanol/wizz_fizz/on_mob_life(mob/living/carbon/M)
//A healing drink similar to Quadruple Sec, Ling Stings, and Screwdrivers for the Wizznerds; the check is consistent with the changeling sting
if(M?.mind?.has_antag_datum(/datum/antagonist/wizard))
M.heal_bodypart_damage(1,1,1)
M.adjustOxyLoss(-1,0)
M.adjustToxLoss(-1,0)
return ..()
/datum/reagent/consumable/ethanol/bug_spray
name = "Bug Spray"
id = "bug_spray"
description = "A harsh, acrid, bitter drink, for those who need something to brace themselves."
color = "#33ff33"
boozepwr = 50
quality = DRINK_GOOD
taste_description = "the pain of ten thousand slain mosquitos"
glass_icon_state = "bug_spray"
glass_name = "Bug Spray"
glass_desc = "Your eyes begin to water as the sting of alcohol reaches them."
/datum/reagent/consumable/ethanol/bug_spray/on_mob_life(mob/living/carbon/M)
//Bugs should not drink Bug spray.
if(ismoth(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))
M.emote("scream")
return ..()
/datum/reagent/consumable/ethanol/applejack
name = "Applejack"
id = "applejack"
description = "The perfect beverage for when you feel the need to horse around."
color = "#ff6633"
boozepwr = 20
taste_description = "an honest day's work at the orchard"
glass_icon_state = "applejack_glass"
glass_name = "Applejack"
glass_desc = "You feel like you could drink this all neight."
/datum/reagent/consumable/ethanol/jack_rose
name = "Jack Rose"
id = "jack_rose"
description = "A light cocktail perfect for sipping with a slice of pie."
color = "#ff6633"
boozepwr = 15
quality = DRINK_NICE
taste_description = "a sweet and sour slice of apple"
glass_icon_state = "jack_rose"
glass_name = "Jack Rose"
glass_desc = "Enough of these, and you really will start to suppose your toeses are roses."
/datum/reagent/consumable/ethanol/turbo
name = "Turbo"
id = "turbo"
description = "A turbulent cocktail associated with outlaw hoverbike racing. Not for the faint of heart."
color = "#e94c3a"
boozepwr = 85
quality = DRINK_VERYGOOD
taste_description = "the outlaw spirit"
glass_icon_state = "turbo"
glass_name = "Turbo"
glass_desc = "A turbulent cocktail for outlaw hoverbikers."
/datum/reagent/consumable/ethanol/turbo/on_mob_life(mob/living/carbon/M)
if(prob(4))
to_chat(M, "<span class='notice'>[pick("You feel disregard for the rule of law.", "You feel pumped!", "Your head is pounding.", "Your thoughts are racing..")]</span>")
M.adjustStaminaLoss(-M.drunkenness * 0.25)
return ..()
/datum/reagent/consumable/ethanol/old_timer
name = "Old Timer"
id = "old_timer"
description = "An archaic potation enjoyed by old coots of all ages."
color = "#996835"
boozepwr = 35
quality = DRINK_NICE
taste_description = "simpler times"
glass_icon_state = "old_timer"
glass_name = "Old Timer"
glass_desc = "WARNING! May cause premature aging!"
/datum/reagent/consumable/ethanol/old_timer/on_mob_life(mob/living/carbon/M)
if(prob(20))
if(ishuman(M))
var/mob/living/carbon/human/N = M
N.age += 1
if(N.age > 70)
N.facial_hair_color = "ccc"
N.hair_color = "ccc"
N.update_hair()
if(N.age > 100)
N.become_nearsighted(id)
if(N.gender == MALE)
N.facial_hair_style = "Beard (Very Long)"
N.update_hair()
if(N.age > 969) //Best not let people get older than this or i might incur G-ds wrath
M.visible_message("<span class='notice'>[M] becomes older than any man should be.. and crumbles into dust!</span>")
M.dust(0,1,0)
return ..()
/datum/reagent/consumable/ethanol/rubberneck
name = "Rubberneck"
id = "rubberneck"
description = "A quality rubberneck should not contain any gross natural ingredients."
color = "#ffe65b"
boozepwr = 60
quality = DRINK_GOOD
taste_description = "artifical fruityness"
glass_icon_state = "rubberneck"
glass_name = "Rubberneck"
glass_desc = "A popular drink amongst those adhering to an all synthetic diet."
/datum/reagent/consumable/ethanol/duplex
name = "Duplex"
id = "duplex"
description = "An inseparable combination of two fruity drinks."
color = "#50e5cf"
boozepwr = 25
quality = DRINK_NICE
taste_description = "green apples and blue raspberries"
glass_icon_state = "duplex"
glass_name = "Duplex"
glass_desc = "To imbibe one component separately from the other is consider a great faux pas."
/datum/reagent/consumable/ethanol/trappist
name = "Trappist Beer"
id = "trappist"
description = "A strong dark ale brewed by space-monks."
color = "#390c00"
boozepwr = 40
quality = DRINK_VERYGOOD
taste_description = "dried plums and malt"
glass_icon_state = "trappistglass"
glass_name = "Trappist Beer"
glass_desc = "boozy Catholicism in a glass."
/datum/reagent/consumable/ethanol/trappist/on_mob_life(mob/living/carbon/M)
if(M.mind.isholy)
M.adjustFireLoss(-2.5, 0)
M.jitteriness = max(0, M.jitteriness-1)
M.stuttering = max(0, M.stuttering-1)
return ..()
/datum/reagent/consumable/ethanol/blazaam
name = "Blazaam"
id = "blazaam"
description = "A strange drink that few people seem to remember existing. Doubles as a Berenstain remover."
boozepwr = 70
quality = DRINK_FANTASTIC
taste_description = "alternate realities"
glass_icon_state = "blazaamglass"
glass_name = "Blazaam"
glass_desc = "The glass seems to be sliding between realities. Doubles as a Berenstain remover."
var/stored_teleports = 0
/datum/reagent/consumable/ethanol/blazaam/on_mob_life(mob/living/carbon/M)
if(M.drunkenness > 40)
if(stored_teleports)
do_teleport(M, get_turf(M), rand(1,3))
stored_teleports--
if(prob(10))
stored_teleports += rand(2,6)
if(prob(70))
M.vomit()
return ..()
/datum/reagent/consumable/ethanol/planet_cracker
name = "Planet Cracker"
id = "planet_cracker"
description = "This jubilant drink celebrates humanity's triumph over the alien menace. May be offensive to non-human crewmembers."
boozepwr = 50
quality = DRINK_FANTASTIC
taste_description = "triumph with a hint of bitterness"
glass_icon_state = "planet_cracker"
glass_name = "Planet Cracker"
glass_desc = "Although historians believe the drink was originally created to commemorate the end of an important conflict in man's past, its origins have largely been forgotten and it is today seen more as a general symbol of human supremacy."
/datum/reagent/consumable/ethanol/fruit_wine
name = "Fruit Wine"
id = "fruit_wine"
@@ -187,7 +187,7 @@
description = "will do toxin damage and cause targets to believe they are fully healed."
analyzerdescdamage = "Does toxin damage and injects a toxin that causes the target to believe they are fully healed."
taste_description = "heaven"
color = "#C8A5DC"
color = "#5e7842"
complementary_color = "#CD7794"
message_living = ", and you feel <i>alive</i>"
@@ -204,7 +204,7 @@
C.hal_screwyhud = SCREWYHUD_HEALTHY //fully healed, honest
..()
/datum/reagent/blob/regenerative_materia/on_mob_delete(mob/living/M)
/datum/reagent/blob/regenerative_materia/on_mob_end_metabolize(mob/living/M)
if(iscarbon(M))
var/mob/living/carbon/N = M
N.hal_screwyhud = 0
@@ -213,15 +213,15 @@
glass_desc = "White and nutritious goodness!"
/datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/M)
if(M.getBruteLoss() && prob(20))
M.heal_bodypart_damage(1,0, 0)
if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER))
M.heal_bodypart_damage(1.5,0, 0)
. = 1
else
if(M.getBruteLoss() && prob(20))
M.heal_bodypart_damage(1,0, 0)
. = 1
if(holder.has_reagent("capsaicin"))
holder.remove_reagent("capsaicin", 2)
var/datum/dna/Mdna = M.has_dna()
if(Mdna && Mdna.species && (Mdna.species.id == "plasmaman" || Mdna.species.id == "skeleton"))
M.heal_bodypart_damage(1,0, 0)
. = 1
..()
/datum/reagent/consumable/soymilk
@@ -305,6 +305,16 @@
..()
. = 1
/datum/reagent/consumable/lemonade
name = "Lemonade"
id = "lemonade"
description = "Sweet, tangy lemonade. Good for the soul."
quality = DRINK_NICE
taste_description = "sunshine and summertime"
glass_icon_state = "lemonpitcher"
glass_name = "pitcher of lemonade"
glass_desc = "This drink leaves you feeling nostalgic for some reason."
/datum/reagent/consumable/tea/arnold_palmer
name = "Arnold Palmer"
id = "arnold_palmer"
@@ -390,12 +400,12 @@
glass_name = "glass of Nuka Cola"
glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland."
/datum/reagent/consumable/nuka_cola/on_mob_add(mob/living/L)
/datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_GOTTAGOFAST, id)
ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
/datum/reagent/consumable/nuka_cola/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_GOTTAGOFAST, id)
/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id)
..()
/datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/M)
@@ -498,6 +508,34 @@
/datum/reagent/consumable/shamblers/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-8 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL)
..()
/datum/reagent/consumable/grey_bull
name = "Grey Bull"
id = "grey_bull"
description = "Grey Bull, it gives you gloves!"
color = "#EEFF00" // rgb: 238, 255, 0
quality = DRINK_VERYGOOD
taste_description = "carbonated oil"
glass_icon_state = "grey_bull_glass"
glass_name = "glass of Grey Bull"
glass_desc = "Surprisingly it isnt grey."
/datum/reagent/consumable/grey_bull/on_mob_metabolize(mob/living/L)
..()
ADD_TRAIT(L, TRAIT_SHOCKIMMUNE, id)
/datum/reagent/consumable/grey_bull/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_SHOCKIMMUNE, id)
..()
/datum/reagent/consumable/grey_bull/on_mob_life(mob/living/carbon/M)
M.Jitter(20)
M.dizziness +=1
M.drowsyness = 0
M.AdjustSleeping(-40, FALSE)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL)
..()
/datum/reagent/consumable/sodawater
name = "Soda Water"
id = "sodawater"
@@ -703,7 +741,7 @@
name = "Triple Citrus"
id = "triple_citrus"
description = "A solution."
color = "#C8A5DC"
color = "#fff12b"
quality = DRINK_NICE
taste_description = "extreme bitterness"
glass_icon_state = "triplecitrus" //needs own sprite mine are trash
@@ -719,6 +757,11 @@
glass_name = "glass of grape juice"
glass_desc = "It's grape (soda)!"
/datum/reagent/consumable/grape_soda/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL)
..()
/datum/reagent/consumable/milk/chocolate_milk
name = "Chocolate Milk"
id = "chocolate_milk"
@@ -746,6 +789,65 @@
glass_name = "glass of grenadine"
glass_desc = "Delicious flavored syrup."
/datum/reagent/consumable/parsnipjuice
name = "Parsnip Juice"
id = "parsnipjuice"
description = "Why..."
color = "#FFA500"
taste_description = "parsnip"
glass_name = "glass of parsnip juice"
/datum/reagent/consumable/peachjuice //Intended to be extremely rare due to being the limiting ingredients in the blazaam drink
name = "Peach Juice"
id = "peachjuice"
description = "Just peachy."
color = "#E78108"
taste_description = "peaches"
glass_name = "glass of peach juice"
/datum/reagent/consumable/cream_soda
name = "Cream Soda"
id = "cream_soda"
description = "A classic space-American vanilla flavored soft drink."
color = "#dcb137"
quality = DRINK_VERYGOOD
taste_description = "fizzy vanilla"
glass_icon_state = "cream_soda"
glass_name = "Cream Soda"
glass_desc = "A classic space-American vanilla flavored soft drink."
/datum/reagent/consumable/cream_soda/on_mob_life(mob/living/carbon/M)
M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL)
..()
/datum/reagent/consumable/red_queen
name = "Red Queen"
id = "red_queen"
description = "DRINK ME."
color = "#e6ddc3"
quality = DRINK_GOOD
taste_description = "wonder"
glass_icon_state = "red_queen"
glass_name = "Red Queen"
glass_desc = "DRINK ME."
var/current_size = 1
/datum/reagent/consumable/red_queen/on_mob_life(mob/living/carbon/H)
if(prob(75))
return ..()
var/newsize = pick(0.5, 0.75, 1, 1.50, 2)
H.resize = newsize/current_size
current_size = newsize
H.update_transform()
if(prob(40))
H.emote("sneeze")
..()
/datum/reagent/consumable/red_queen/on_mob_end_metabolize(mob/living/M)
M.resize = 1/current_size
M.update_transform()
..()
/datum/reagent/consumable/pinkmilk
name = "Strawberry Milk"
id = "pinkmilk"
@@ -5,7 +5,7 @@
taste_description = "bitterness"
var/trippy = TRUE //Does this drug make you trip?
/datum/reagent/drug/on_mob_delete(mob/living/M)
/datum/reagent/drug/on_mob_end_metabolize(mob/living/M)
if(trippy)
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "[id]_high")
@@ -164,13 +164,16 @@
overdose_threshold = 20
addiction_threshold = 10
metabolization_rate = 0.75 * REAGENTS_METABOLISM
var/brain_damage = TRUE
var/jitter = TRUE
var/confusion = TRUE
/datum/reagent/drug/methamphetamine/on_mob_add(mob/living/L)
/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_IGNORESLOWDOWN, id)
L.ignore_slowdown(id)
/datum/reagent/drug/methamphetamine/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_IGNORESLOWDOWN, id)
/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/L)
L.unignore_slowdown(id)
..()
/datum/reagent/drug/methamphetamine/on_mob_life(mob/living/carbon/M)
@@ -181,10 +184,10 @@
M.AdjustKnockdown(-40, 0)
M.AdjustUnconscious(-40, 0)
M.adjustStaminaLoss(-7.5 * REM, 0)
M.Jitter(2)
M.adjustBrainLoss(rand(1,4))
if(prob(30))
M.confused = max(1, M.confused)
if(jitter)
M.Jitter(2)
if(brain_damage)
M.adjustBrainLoss(rand(1,4))
M.heal_overall_damage(2, 2)
if(prob(5))
M.emote(pick("twitch", "shiver"))
@@ -240,6 +243,14 @@
..()
. = 1
/datum/reagent/drug/methamphetamine/changeling
id = "changelingmeth"
name = "Changeling Adrenaline"
addiction_threshold = 35
overdose_threshold = 35
jitter = FALSE
brain_damage = FALSE
/datum/reagent/drug/bath_salts
name = "Bath Salts"
id = "bath_salts"
@@ -251,18 +262,18 @@
taste_description = "salt" // because they're bathsalts?
var/datum/brain_trauma/special/psychotic_brawling/bath_salts/rage
/datum/reagent/drug/bath_salts/on_mob_add(mob/living/L)
/datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_STUNIMMUNE, id)
L.add_trait(TRAIT_SLEEPIMMUNE, id)
ADD_TRAIT(L, TRAIT_STUNIMMUNE, id)
ADD_TRAIT(L, TRAIT_SLEEPIMMUNE, id)
if(iscarbon(L))
var/mob/living/carbon/C = L
rage = new()
C.gain_trauma(rage, TRAUMA_RESILIENCE_ABSOLUTE)
/datum/reagent/drug/bath_salts/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_STUNIMMUNE, id)
L.remove_trait(TRAIT_SLEEPIMMUNE, id)
/datum/reagent/drug/bath_salts/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id)
REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id)
if(rage)
QDEL_NULL(rage)
..()
@@ -370,9 +381,9 @@
addiction_stage3_end = 40
addiction_stage4_end = 240
/datum/reagent/drug/skooma/on_mob_add(mob/living/L)
/datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L)
. = ..()
L.add_trait(TRAIT_GOTTAGOFAST, id)
ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
L.next_move_modifier *= 2
if(ishuman(L))
var/mob/living/carbon/human/H = L
@@ -381,9 +392,9 @@
if(H.dna && H.dna.species)
H.dna.species.punchdamagehigh *= 5
/datum/reagent/drug/skooma/on_mob_delete(mob/living/L)
/datum/reagent/drug/skooma/on_mob_end_metabolize(mob/living/L)
. = ..()
L.remove_trait(TRAIT_GOTTAGOFAST, id)
REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id)
L.next_move_modifier *= 0.5
if(ishuman(L))
var/mob/living/carbon/human/H = L
@@ -22,7 +22,7 @@
/datum/reagent/consumable/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == INGEST)
if (quality && !M.has_trait(TRAIT_AGEUSIA))
if (quality && !HAS_TRAIT(M, TRAIT_AGEUSIA))
switch(quality)
if (DRINK_NICE)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_nice)
@@ -32,6 +32,8 @@
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_verygood)
if (DRINK_FANTASTIC)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_drink", /datum/mood_event/quality_fantastic)
if (FOOD_AMAZING)
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "quality_food", /datum/mood_event/amazingtaste)
return ..()
/datum/reagent/consumable/nutriment
@@ -319,7 +321,7 @@
victim.blind_eyes(2)
victim.confused = max(M.confused, 3)
victim.damageoverlaytemp = 60
victim.Knockdown(60, override_stamdmg = min(reac_volume * 3, 15))
victim.Knockdown(80, override_hardstun = 0.1, override_stamdmg = min(reac_volume * 3, 15))
return
else if ( eyes_covered ) // Eye cover is better than mouth cover
victim.blur_eyes(3)
@@ -332,7 +334,7 @@
victim.blind_eyes(3)
victim.confused = max(M.confused, 6)
victim.damageoverlaytemp = 75
victim.Knockdown(100, override_stamdmg = min(reac_volume * 5, 25))
victim.Knockdown(80, override_hardstun = 0.1, override_stamdmg = min(reac_volume * 5, 25))
victim.update_damage_hud()
/datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/M)
@@ -401,7 +403,7 @@
metabolization_rate = 0.2 * REAGENTS_METABOLISM
taste_description = "mushroom"
/datum/reagent/mushroomhallucinogen/on_mob_life(mob/living/carbon/M)
/datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/M)
M.slurring = max(M.slurring,50)
switch(current_cycle)
if(1 to 5)
@@ -431,11 +433,19 @@
taste_description = "childhood whimsy"
/datum/reagent/consumable/sprinkles/on_mob_life(mob/living/carbon/M)
if(ishuman(M) && M.job in list("Security Officer", "Head of Security", "Detective", "Warden"))
if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM))
M.heal_bodypart_damage(1,1, 0)
. = 1
..()
/datum/reagent/consumable/peanut_butter
name = "Peanut Butter"
id = "peanut_butter"
description = "A popular food paste made from ground dry-roasted peanuts."
color = "#C29261"
nutriment_factor = 15 * REAGENTS_METABOLISM
taste_description = "peanuts"
/datum/reagent/consumable/cornoil
name = "Corn Oil"
id = "cornoil"
@@ -554,14 +564,14 @@
name = "Corn Starch"
id = "corn_starch"
description = "A slippery solution."
color = "#C8A5DC"
color = "#f7f6e4"
taste_description = "slime"
/datum/reagent/consumable/corn_syrup
name = "Corn Syrup"
id = "corn_syrup"
description = "Decays into sugar."
color = "#C8A5DC"
color = "#fff882"
metabolization_rate = 3 * REAGENTS_METABOLISM
taste_description = "sweet slime"
@@ -686,7 +696,7 @@
/datum/reagent/consumable/tinlux/reaction_mob(mob/living/M)
M.set_light(2)
/datum/reagent/consumable/tinlux/on_mob_delete(mob/living/M)
/datum/reagent/consumable/tinlux/on_mob_end_metabolize(mob/living/M)
M.set_light(-2)
/datum/reagent/consumable/vitfro
@@ -711,3 +721,32 @@
nutriment_factor = 5 * REAGENTS_METABOLISM
color = "#eef442" // rgb: 238, 244, 66
taste_description = "mournful honking"
/datum/reagent/consumable/astrotame
name = "Astrotame"
id = "astrotame"
description = "A space age artifical sweetener."
nutriment_factor = 0
metabolization_rate = 2 * REAGENTS_METABOLISM
reagent_state = SOLID
color = "#FFFFFF" // rgb: 255, 255, 255
taste_mult = 8
taste_description = "sweetness"
overdose_threshold = 17
/datum/reagent/consumable/astrotame/overdose_process(mob/living/carbon/M)
if(M.disgust < 80)
M.adjust_disgust(10)
..()
. = TRUE
/datum/reagent/consumable/secretsauce
name = "secret sauce"
id = "secret_sauce"
description = "What could it be."
nutriment_factor = 2 * REAGENTS_METABOLISM
color = "#792300"
taste_description = "indescribable"
quality = FOOD_AMAZING
taste_mult = 100
can_synth = FALSE
@@ -18,7 +18,7 @@
name = "Leporazine"
id = "leporazine"
description = "Leporazine will effectively regulate a patient's body temperature, ensuring it never leaves safe levels."
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#82b8aa"
/datum/reagent/medicine/leporazine/on_mob_life(mob/living/carbon/M)
if(M.bodytemperature > BODYTEMP_NORMAL)
@@ -31,7 +31,7 @@
name = "Adminordrazine"
id = "adminordrazine"
description = "It's magic. We don't have to explain it."
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#ffffff"
can_synth = FALSE
taste_description = "badmins"
@@ -44,7 +44,7 @@
M.adjustToxLoss(-5, 0, TRUE)
M.hallucination = 0
M.setBrainLoss(0)
M.remove_all_traits()
REMOVE_TRAITS_NOT_IN(M, list(SPECIES_TRAIT, ROUNDSTART_TRAIT, ORGAN_TRAIT))
M.set_blurriness(0)
M.set_blindness(0)
M.SetKnockdown(0, 0)
@@ -136,7 +136,7 @@
M.adjustFireLoss(-power, 0)
M.adjustToxLoss(-power, 0, TRUE) //heals TOXINLOVERs
M.adjustCloneLoss(-power, 0)
M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration
. = 1
metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (M.bodytemperature ** 2) + 0.5)
..()
@@ -152,7 +152,7 @@
/datum/reagent/medicine/clonexadone/on_mob_life(mob/living/carbon/M)
if(M.bodytemperature < T0C)
M.adjustCloneLoss(0.00006 * (M.bodytemperature ** 2) - 6, 0)
M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC)
. = 1
metabolization_rate = REAGENTS_METABOLISM * (0.000015 * (M.bodytemperature ** 2) + 0.75)
..()
@@ -182,7 +182,7 @@
M.adjustFireLoss(-1.5 * power, 0)
M.adjustToxLoss(-power, 0, TRUE)
M.adjustCloneLoss(-power, 0)
M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC)
. = 1
..()
@@ -198,7 +198,7 @@
/datum/reagent/medicine/rezadone/on_mob_life(mob/living/carbon/M)
M.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that.
M.heal_bodypart_damage(1,1)
M.remove_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
REMOVE_TRAIT(M, TRAIT_DISFIGURED, TRAIT_GENERIC)
..()
. = 1
@@ -213,7 +213,7 @@
name = "Spaceacillin"
id = "spaceacillin"
description = "Spaceacillin will prevent a patient from conventionally spreading any diseases they are currently infected with."
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#f2f2f2"
metabolization_rate = 0.1 * REAGENTS_METABOLISM
//Goon Chems. Ported mainly from Goonstation. Easily mixable (or not so easily) and provide a variety of effects.
@@ -222,7 +222,7 @@
id = "silver_sulfadiazine"
description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. If ingested through other means, deals minor toxin damage."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#ffeac9"
/datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M) && M.stat != DEAD)
@@ -366,7 +366,7 @@
to_chat(M, "<span class='danger'>You feel your wounds fade away to nothing!</span>" )
..()
/datum/reagent/medicine/mine_salve/on_mob_delete(mob/living/M)
/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/M)
if(iscarbon(M))
var/mob/living/carbon/N = M
N.hal_screwyhud = SCREWYHUD_NONE
@@ -483,16 +483,24 @@
reagent_state = LIQUID
color = "#E6FFF0"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
var/healtoxinlover = FALSE
/datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/M)
M.radiation -= max(M.radiation-RAD_MOB_SAFE, 0)/50
M.adjustToxLoss(-2*REM, 0)
M.adjustToxLoss(-2*REM, 0, healtoxinlover)
for(var/datum/reagent/R in M.reagents.reagent_list)
if(R != src)
M.reagents.remove_reagent(R.id,2)
..()
. = 1
/datum/reagent/medicine/pen_acid/pen_jelly
name = "Pentetic Jelly"
id = "pen_jelly"
description = "Reduces massive amounts of radiation and toxin damage while purging other chemicals from the body. Slimepeople friendly!"
color = "#91D865"
healtoxinlover = TRUE
/datum/reagent/medicine/sal_acid
name = "Salicyclic Acid"
id = "sal_acid"
@@ -630,12 +638,12 @@
overdose_threshold = 30
addiction_threshold = 25
/datum/reagent/medicine/morphine/on_mob_add(mob/living/L)
/datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_IGNORESLOWDOWN, id)
L.ignore_slowdown(id)
/datum/reagent/medicine/morphine/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_IGNORESLOWDOWN, id)
/datum/reagent/medicine/morphine/on_mob_end_metabolize(mob/living/L)
L.unignore_slowdown(id)
..()
/datum/reagent/medicine/morphine/on_mob_life(mob/living/carbon/M)
@@ -702,14 +710,14 @@
var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
if(M.has_trait(TRAIT_BLIND, EYE_DAMAGE))
if(HAS_TRAIT_FROM(M, TRAIT_BLIND, EYE_DAMAGE))
if(prob(20))
to_chat(M, "<span class='warning'>Your vision slowly returns...</span>")
M.cure_blind(EYE_DAMAGE)
M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(35)
else if(M.has_trait(TRAIT_NEARSIGHT, EYE_DAMAGE))
else if(HAS_TRAIT_FROM(M, TRAIT_NEARSIGHT, EYE_DAMAGE))
to_chat(M, "<span class='warning'>The blackness in your peripheral vision fades.</span>")
M.cure_nearsighted(EYE_DAMAGE)
M.blur_eyes(10)
@@ -800,7 +808,7 @@
M.visible_message("<span class='warning'>[M]'s body convulses a bit, and then falls still once more.</span>")
return
M.visible_message("<span class='warning'>[M]'s body convulses a bit.</span>")
if(!M.suiciding && !(M.has_trait(TRAIT_NOCLONE)) && !M.hellbound)
if(!M.suiciding && !(HAS_TRAIT(M, TRAIT_NOCLONE)) && !M.hellbound)
if(!M)
return
if(M.notify_ghost_cloning(source = M))
@@ -875,12 +883,12 @@
metabolization_rate = 0.5 * REAGENTS_METABOLISM
overdose_threshold = 60
/datum/reagent/medicine/stimulants/on_mob_add(mob/living/L)
/datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_GOTTAGOFAST, id)
ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
/datum/reagent/medicine/stimulants/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_GOTTAGOFAST, id)
/datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id)
..()
/datum/reagent/medicine/stimulants/on_mob_life(mob/living/carbon/M)
@@ -924,7 +932,7 @@
id = "bicaridine"
description = "Restores bruising. Overdose causes it instead."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#fc2626"
overdose_threshold = 30
/datum/reagent/medicine/bicaridine/on_mob_life(mob/living/carbon/M)
@@ -942,7 +950,7 @@
id = "dexalin"
description = "Restores oxygen loss. Overdose causes it instead."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#13d2f0"
overdose_threshold = 30
/datum/reagent/medicine/dexalin/on_mob_life(mob/living/carbon/M)
@@ -960,7 +968,7 @@
id = "kelotane"
description = "Restores fire damage. Overdose causes it instead."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#ffc400"
overdose_threshold = 30
/datum/reagent/medicine/kelotane/on_mob_life(mob/living/carbon/M)
@@ -978,7 +986,7 @@
id = "antitoxin"
description = "Heals toxin damage and removes toxins in the bloodstream. Overdose causes toxin damage."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#6aff00"
overdose_threshold = 30
taste_description = "a roll of gauze"
@@ -999,7 +1007,7 @@
id = "inaprovaline"
description = "Stabilizes the breathing of patients. Good for those in critical condition."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#5dc1f0"
/datum/reagent/medicine/inaprovaline/on_mob_life(mob/living/carbon/M)
if(M.losebreath >= 5)
@@ -1011,7 +1019,7 @@
id = "tricordrazine"
description = "Has a high chance to heal all types of damage. Overdose instead causes it."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#e650c0"
overdose_threshold = 30
taste_description = "grossness"
@@ -1102,7 +1110,7 @@
M.adjustBruteLoss(-3 * REM, 0)
M.adjustFireLoss(-3 * REM, 0)
M.adjustOxyLoss(-15 * REM, 0)
M.adjustToxLoss(-3 * REM, 0)
M.adjustToxLoss(-3 * REM, 0, TRUE) //Heals TOXINLOVERS
M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
M.adjustCloneLoss(-1 * REM, 0)
M.adjustStaminaLoss(-30 * REM, 0)
@@ -1113,7 +1121,7 @@
/datum/reagent/medicine/earthsblood/overdose_process(mob/living/M)
M.hallucination = min(max(0, M.hallucination + 5), 60)
M.adjustToxLoss(5 * REM, 0)
M.adjustToxLoss(8 * REM, 0, TRUE) //Hurts TOXINLOVERS
..()
. = 1
@@ -1143,7 +1151,7 @@
name = "Lavaland Extract"
id = "lavaland_extract"
description = "An extract of lavaland atmospheric and mineral elements. Heals the user in small doses, but is extremely toxic otherwise."
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#a1a1a1"
overdose_threshold = 3 //To prevent people stacking massive amounts of a very strong healing reagent
can_synth = FALSE
@@ -1164,13 +1172,14 @@
name = "Changeling Adrenaline"
id = "changelingadrenaline"
description = "Reduces the duration of unconciousness, knockdown and stuns. Restores stamina, but deals toxin damage when overdosed."
color = "#C8A5DC"
color = "#918e53"
overdose_threshold = 30
/datum/reagent/medicine/changelingadrenaline/on_mob_life(mob/living/carbon/M as mob)
M.AdjustUnconscious(-20, 0)
M.AdjustStun(-20, 0)
M.AdjustKnockdown(-20, 0)
M.AdjustSleeping(-20, 0)
M.adjustStaminaLoss(-30, 0)
..()
return TRUE
@@ -1184,15 +1193,15 @@
name = "Changeling Haste"
id = "changelinghaste"
description = "Drastically increases movement speed, but deals toxin damage."
color = "#C8A5DC"
color = "#669153"
metabolization_rate = 1
/datum/reagent/medicine/changelinghaste/on_mob_add(mob/living/L)
/datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_GOTTAGOREALLYFAST, id)
ADD_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id)
/datum/reagent/medicine/changelinghaste/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_GOTTAGOREALLYFAST, id)
/datum/reagent/medicine/changelinghaste/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id)
..()
/datum/reagent/medicine/changelinghaste/on_mob_life(mob/living/carbon/M)
@@ -1209,12 +1218,12 @@
color = "#F5F5F5"
self_consuming = TRUE
/datum/reagent/medicine/corazone/on_mob_add(mob/living/M)
/datum/reagent/medicine/corazone/on_mob_metabolize(mob/living/M)
..()
M.add_trait(TRAIT_STABLEHEART, id)
ADD_TRAIT(M, TRAIT_STABLEHEART, id)
/datum/reagent/medicine/corazone/on_mob_delete(mob/living/M)
M.remove_trait(TRAIT_STABLEHEART, id)
/datum/reagent/medicine/corazone/on_mob_end_metabolize(mob/living/M)
REMOVE_TRAIT(M, TRAIT_STABLEHEART, id)
..()
/datum/reagent/medicine/muscle_stimulant
@@ -1222,13 +1231,13 @@
id = "muscle_stimulant"
description = "A potent chemical that allows someone under its influence to be at full physical ability even when under massive amounts of pain."
/datum/reagent/medicine/muscle_stimulant/on_mob_add(mob/living/M)
/datum/reagent/medicine/muscle_stimulant/on_mob_metabolize(mob/living/M)
. = ..()
M.add_trait(TRAIT_IGNORESLOWDOWN, id)
M.ignore_slowdown(id)
/datum/reagent/medicine/muscle_stimulant/on_mob_delete(mob/living/M)
/datum/reagent/medicine/muscle_stimulant/on_mob_end_metabolize(mob/living/M)
. = ..()
M.remove_trait(TRAIT_IGNORESLOWDOWN, id)
M.unignore_slowdown(id)
/datum/reagent/medicine/modafinil
name = "Modafinil"
@@ -1241,12 +1250,12 @@
taste_description = "salt" // it actually does taste salty
var/overdose_progress = 0 // to track overdose progress
/datum/reagent/medicine/modafinil/on_mob_add(mob/living/M)
M.add_trait(TRAIT_SLEEPIMMUNE, id)
/datum/reagent/medicine/modafinil/on_mob_metabolize(mob/living/M)
ADD_TRAIT(M, TRAIT_SLEEPIMMUNE, id)
..()
/datum/reagent/medicine/modafinil/on_mob_delete(mob/living/M)
M.remove_trait(TRAIT_SLEEPIMMUNE, id)
/datum/reagent/medicine/modafinil/on_mob_end_metabolize(mob/living/M)
REMOVE_TRAIT(M, TRAIT_SLEEPIMMUNE, id)
..()
/datum/reagent/medicine/modafinil/on_mob_life(mob/living/carbon/M)
@@ -315,17 +315,22 @@
glass_name = "glass of holy water"
glass_desc = "A glass of holy water."
/datum/reagent/water/holywater/on_mob_add(mob/living/L)
/datum/reagent/water/holywater/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_HOLY, id)
ADD_TRAIT(L, TRAIT_HOLY, id)
/datum/reagent/water/holywater/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_HOLY, id)
/datum/reagent/water/holywater/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_HOLY, id)
..()
/datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(is_servant_of_ratvar(M))
to_chat(M, "<span class='userdanger'>A darkness begins to spread its unholy tendrils through your mind, purging the Justiciar's influence!</span>")
to_chat(M, "<span class='userdanger'>A fog spreads through your mind, purging the Justiciar's influence!</span>")
..()
/datum/reagent/water/holywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(iscultist(M))
to_chat(M, "<span class='userdanger'>A fog spreads through your mind, weakening your connection to the veil and purging Nar-sie's influence</span>")
..()
/datum/reagent/water/holywater/on_mob_life(mob/living/carbon/M)
@@ -380,7 +385,7 @@
qdel(R)
T.Bless()
/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke
/datum/reagent/fuel/unholywater //if you somehow managed to extract this from someone, dont splash it on yourself and have a smoke
name = "Unholy Water"
id = "unholywater"
description = "Something that shouldn't exist on this plane of existence."
@@ -399,7 +404,7 @@
M.AdjustStun(-40, 0)
M.AdjustKnockdown(-40, 0)
M.adjustStaminaLoss(-10, 0)
M.adjustToxLoss(-2, 0)
M.adjustToxLoss(-2, 0, TRUE)
M.adjustOxyLoss(-2, 0)
M.adjustBruteLoss(-2, 0)
M.adjustFireLoss(-2, 0)
@@ -428,6 +433,45 @@
M.adjustBrainLoss(5, 150)
holder.remove_reagent(id, 1)
/datum/reagent/fuel/holyoil //Its oil
name = "Zelus Oil"
id = "holyoil"
description = "Oil blessed by a greater being."
taste_description = "metallic oil"
/datum/reagent/fuel/holyoil/on_mob_life(mob/living/carbon/M)
if(is_servant_of_ratvar(M))
M.drowsyness = max(M.drowsyness-5, 0)
M.AdjustUnconscious(-60, 0)
M.AdjustStun(-30, 0)
M.AdjustKnockdown(-70, 0)
M.adjustStaminaLoss(-15, 0)
M.adjustToxLoss(-5, 0, TRUE)
M.adjustOxyLoss(-3, 0)
M.adjustBruteLoss(-3, 0)
M.adjustFireLoss(-5, 0)
if(iscultist(M))
M.AdjustUnconscious(1, 0)
M.AdjustStun(10, 0)
M.AdjustKnockdown(20, 0)
M.adjustStaminaLoss(15, 0)
else
M.adjustToxLoss(3, 0)
M.adjustOxyLoss(2, 0)
M.adjustStaminaLoss(10, 0)
holder.remove_reagent(id, 1)
return TRUE
//We only get 30u to start with...
/datum/reagent/fuel/holyoil/reaction_obj(obj/O, reac_volume)
. = ..()
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/brass(get_turf(M), reac_volume)
M.use(reac_volume)
/datum/reagent/medicine/omnizine/godblood
name = "Godblood"
id = "godblood"
@@ -982,7 +1026,7 @@
name = "Sterilizine"
id = "sterilizine"
description = "Sterilizes wounds in preparation for surgery."
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#e6f1f5" // rgb: 200, 165, 220
taste_description = "bitterness"
/datum/reagent/space_cleaner/sterilizine/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume)
@@ -1000,7 +1044,7 @@
reagent_state = SOLID
taste_description = "iron"
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#c2391d"
/datum/reagent/iron/on_mob_life(mob/living/carbon/C)
if(C.blood_volume < BLOOD_VOLUME_NORMAL)
@@ -1195,7 +1239,7 @@
name = "Cryptobiolin"
id = "cryptobiolin"
description = "Cryptobiolin causes confusion and dizziness."
color = "#C8A5DC" // rgb: 200, 165, 220
color = "#7529b3" // rgb: 200, 165, 220
metabolization_rate = 1.5 * REAGENTS_METABOLISM
taste_description = "sourness"
@@ -1210,7 +1254,7 @@
name = "Impedrezene"
id = "impedrezene"
description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions."
color = "#C8A5DC" // rgb: 200, 165, 220A
color = "#587a31" // rgb: 200, 165, 220A
taste_description = "numbness"
/datum/reagent/impedrezene/on_mob_life(mob/living/carbon/M)
@@ -1360,14 +1404,14 @@
color = "E1A116"
taste_description = "sourness"
/datum/reagent/stimulum/on_mob_add(mob/living/L)
/datum/reagent/stimulum/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_STUNIMMUNE, id)
L.add_trait(TRAIT_SLEEPIMMUNE, id)
ADD_TRAIT(L, TRAIT_STUNIMMUNE, id)
ADD_TRAIT(L, TRAIT_SLEEPIMMUNE, id)
/datum/reagent/stimulum/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_STUNIMMUNE, id)
L.remove_trait(TRAIT_SLEEPIMMUNE, id)
/datum/reagent/stimulum/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_STUNIMMUNE, id)
REMOVE_TRAIT(L, TRAIT_SLEEPIMMUNE, id)
..()
/datum/reagent/stimulum/on_mob_life(mob/living/carbon/M)
@@ -1385,12 +1429,12 @@
color = "90560B"
taste_description = "burning"
/datum/reagent/nitryl/on_mob_add(mob/living/L)
/datum/reagent/nitryl/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_GOTTAGOFAST, id)
ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
/datum/reagent/nitryl/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_GOTTAGOFAST, id)
/datum/reagent/nitryl/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id)
..()
/////////////////////////Coloured Crayon Powder////////////////////////////
@@ -1529,7 +1573,7 @@
id = "oil"
description = "Burns in a small smoky fire, mostly used to get Ash."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#292929"
taste_description = "oil"
/datum/reagent/stable_plasma
@@ -1537,7 +1581,7 @@
id = "stable_plasma"
description = "Non-flammable plasma locked into a liquid form that cannot ignite or become gaseous/solid."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#6b008f"
taste_description = "bitterness"
taste_mult = 1.5
@@ -1550,7 +1594,7 @@
id = "iodine"
description = "Commonly added to table salt as a nutrient. On its own it tastes far less pleasing."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#694600"
taste_description = "metal"
/datum/reagent/carpet
@@ -1558,7 +1602,7 @@
id = "carpet"
description = "For those that need a more creative way to roll out a red carpet."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#b51d05"
taste_description = "carpet" // Your tounge feels furry.
/datum/reagent/carpet/reaction_turf(turf/T, reac_volume)
@@ -1572,7 +1616,7 @@
id = "bromine"
description = "A brownish liquid that's highly reactive. Useful for stopping free radicals, but not intended for human consumption."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#b37740"
taste_description = "chemicals"
/datum/reagent/phenol
@@ -1580,7 +1624,7 @@
id = "phenol"
description = "An aromatic ring of carbon with a hydroxyl group. A useful precursor to some medicines, but has no healing properties on its own."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#e6e8ff"
taste_description = "acid"
/datum/reagent/ash
@@ -1588,7 +1632,7 @@
id = "ash"
description = "Supposedly phoenixes rise from these, but you've never seen it."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#665c56"
taste_description = "ash"
/datum/reagent/acetone
@@ -1596,7 +1640,7 @@
id = "acetone"
description = "A slick, slightly carcinogenic liquid. Has a multitude of mundane uses in everyday life."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#e6e6e6"
taste_description = "acid"
/datum/reagent/colorful_reagent
@@ -1604,7 +1648,7 @@
id = "colorful_reagent"
description = "Thoroughly sample the rainbow."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#FFFF00"
var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700")
taste_description = "rainbows"
var/no_mob_color = FALSE
@@ -1634,7 +1678,7 @@
id = "hair_dye"
description = "Has a high chance of making you look like a mad scientist."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#ff00dd"
var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code
taste_description = "sourness"
@@ -1651,7 +1695,7 @@
id = "barbers_aid"
description = "A solution to hair loss across the world."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#fac34b"
taste_description = "sourness"
/datum/reagent/barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
@@ -1669,7 +1713,7 @@
id = "concentrated_barbers_aid"
description = "A concentrated solution to hair loss across the world."
reagent_state = LIQUID
color = "#C8A5DC"
color = "#ffaf00"
taste_description = "sourness"
/datum/reagent/concentrated_barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
@@ -1842,7 +1886,7 @@
H.update_transform()
..()
/datum/reagent/growthserum/on_mob_delete(mob/living/M)
/datum/reagent/growthserum/on_mob_end_metabolize(mob/living/M)
M.resize = 1/current_size
M.update_transform()
..()
@@ -1896,12 +1940,12 @@
taste_description = "water"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
/datum/reagent/pax/on_mob_add(mob/living/L)
/datum/reagent/pax/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_PACIFISM, id)
ADD_TRAIT(L, TRAIT_PACIFISM, id)
/datum/reagent/pax/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_PACIFISM, id)
/datum/reagent/pax/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_PACIFISM, id)
..()
/datum/reagent/bz_metabolites
@@ -1912,13 +1956,13 @@
taste_description = "acrid cinnamon"
metabolization_rate = 0.2 * REAGENTS_METABOLISM
/datum/reagent/bz_metabolites/on_mob_add(mob/living/L)
/datum/reagent/bz_metabolites/on_mob_metabolize(mob/living/L)
..()
L.add_trait(CHANGELING_HIVEMIND_MUTE, id)
ADD_TRAIT(L, CHANGELING_HIVEMIND_MUTE, id)
/datum/reagent/bz_metabolites/on_mob_delete(mob/living/L)
/datum/reagent/bz_metabolites/on_mob_end_metabolize(mob/living/L)
..()
L.remove_trait(CHANGELING_HIVEMIND_MUTE, id)
REMOVE_TRAIT(L, CHANGELING_HIVEMIND_MUTE, id)
/datum/reagent/bz_metabolites/on_mob_life(mob/living/L)
if(L.mind)
@@ -1933,14 +1977,14 @@
description = "A colorless liquid that suppresses violence on the subjects. Cheaper to synthetize, but wears out faster than normal Pax."
metabolization_rate = 1.5 * REAGENTS_METABOLISM
/datum/reagent/peaceborg/confuse
/datum/reagent/peaceborg_confuse
name = "Dizzying Solution"
id = "dizzysolution"
description = "Makes the target off balance and dizzy"
metabolization_rate = 1.5 * REAGENTS_METABOLISM
taste_description = "dizziness"
/datum/reagent/peaceborg/confuse/on_mob_life(mob/living/carbon/M)
/datum/reagent/peaceborg_confuse/on_mob_life(mob/living/carbon/M)
if(M.confused < 6)
M.confused = CLAMP(M.confused + 3, 0, 5)
if(M.dizziness < 6)
@@ -1949,14 +1993,14 @@
to_chat(M, "You feel confused and disorientated.")
..()
/datum/reagent/peaceborg/tire
/datum/reagent/peaceborg_tire
name = "Tiring Solution"
id = "tiresolution"
description = "An extremely weak stamina-toxin that tires out the target. Completely harmless."
metabolization_rate = 1.5 * REAGENTS_METABOLISM
taste_description = "tiredness"
/datum/reagent/peaceborg/tire/on_mob_life(mob/living/carbon/M)
/datum/reagent/peaceborg_tire/on_mob_life(mob/living/carbon/M)
var/healthcomp = (100 - M.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS.
if(M.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.)
M.adjustStaminaLoss(10)
@@ -1998,4 +2042,42 @@
if(added_length >= 0.20) //Only add the length if it's greater than or equal to 0.2. This is to prevent people from smoking the reagents and causing the penis to update constantly.
P.length += added_length
P.update()
..()
..()
/datum/reagent/changeling_string
name = "UNKNOWN"
id = "changeling_sting_real"
description = "404: Chemical not found."
metabolization_rate = REAGENTS_METABOLISM
color = "#0000FF"
can_synth = FALSE
var/datum/dna/original_dna
var/reagent_ticks = 0
invisible = TRUE
/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C)
if(C && C.dna && data["desired_dna"])
original_dna = new C.dna.type
C.dna.copy_dna(original_dna)
var/datum/dna/new_dna = data["desired_dna"]
new_dna.copy_dna(C.dna)
C.real_name = new_dna.real_name
C.updateappearance(mutcolor_update=1)
C.update_body()
C.domutcheck()
C.regenerate_icons()
..()
/datum/reagent/changeling_string/on_mob_end_metabolize(mob/living/carbon/C)
if(original_dna)
original_dna.copy_dna(C.dna)
C.real_name = original_dna.real_name
C.updateappearance(mutcolor_update=1)
C.update_body()
C.domutcheck()
C.regenerate_icons()
..()
/datum/reagent/changeling_string/Destroy()
qdel(original_dna)
return ..()
@@ -97,7 +97,7 @@
/datum/reagent/toxin/lexorin/on_mob_life(mob/living/carbon/C)
. = TRUE
if(C.has_trait(TRAIT_NOBREATH))
if(HAS_TRAIT(C, TRAIT_NOBREATH))
. = FALSE
if(.)
@@ -135,7 +135,7 @@
taste_description = "mint"
/datum/reagent/toxin/minttoxin/on_mob_life(mob/living/carbon/M)
if(M.has_trait(TRAIT_FAT))
if(HAS_TRAIT(M, TRAIT_FAT))
M.gib()
return ..()
@@ -156,11 +156,11 @@
toxpwr = 0.5
taste_description = "death"
/datum/reagent/toxin/zombiepowder/on_mob_add(mob/living/L)
/datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L)
..()
L.fakedeath(id)
/datum/reagent/toxin/zombiepowder/on_mob_delete(mob/living/L)
/datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/L)
L.cure_fakedeath(id)
..()
@@ -178,12 +178,12 @@
toxpwr = 0.8
taste_description = "death"
/datum/reagent/toxin/ghoulpowder/on_mob_add(mob/living/L)
/datum/reagent/toxin/ghoulpowder/on_mob_metabolize(mob/living/L)
..()
L.add_trait(TRAIT_FAKEDEATH, id)
ADD_TRAIT(L, TRAIT_FAKEDEATH, id)
/datum/reagent/toxin/ghoulpowder/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_FAKEDEATH, id)
/datum/reagent/toxin/ghoulpowder/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_FAKEDEATH, id)
..()
/datum/reagent/toxin/ghoulpowder/on_mob_life(mob/living/carbon/M)
@@ -626,7 +626,7 @@
toxpwr = 0
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/toxin/amanitin/on_mob_delete(mob/living/M)
/datum/reagent/toxin/amanitin/on_mob_end_metabolize(mob/living/M)
var/toxdamage = current_cycle*3*REM
M.log_message("has taken [toxdamage] toxin damage from amanitin toxin", LOG_ATTACK)
M.adjustToxLoss(toxdamage)
@@ -742,7 +742,7 @@
animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING)
return ..()
/datum/reagent/toxin/rotatium/on_mob_delete(mob/living/M)
/datum/reagent/toxin/rotatium/on_mob_end_metabolize(mob/living/M)
if(M && M.hud_used)
var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
for(var/whole_screen in screens)
@@ -779,7 +779,7 @@
*/
return ..()
/datum/reagent/toxin/skewium/on_mob_delete(mob/living/M)
/datum/reagent/toxin/skewium/on_mob_end_metabolize(mob/living/M)
if(M && M.hud_used)
var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
for(var/whole_screen in screens)
@@ -798,7 +798,7 @@
/datum/reagent/toxin/anacea/on_mob_life(mob/living/carbon/M)
var/remove_amt = 5
if(holder.has_reagent("calomel") || holder.has_reagent("pen_acid"))
if(holder.has_reagent("calomel") || holder.has_reagent("pen_acid") || holder.has_reagent("pen_jelly"))
remove_amt = 0.5
for(var/datum/reagent/medicine/R in M.reagents.reagent_list)
M.reagents.remove_reagent(R.id,remove_amt)
@@ -882,8 +882,69 @@
toxpwr = 0
taste_description = "stillness"
/datum/reagent/toxin/mimesbane/on_mob_add(mob/living/L)
L.add_trait(TRAIT_EMOTEMUTE, id)
/datum/reagent/toxin/mimesbane/on_mob_metabolize(mob/living/L)
ADD_TRAIT(L, TRAIT_EMOTEMUTE, id)
/datum/reagent/toxin/mimesbane/on_mob_delete(mob/living/L)
L.remove_trait(TRAIT_EMOTEMUTE, id)
/datum/reagent/toxin/mimesbane/on_mob_end_metabolize(mob/living/L)
REMOVE_TRAIT(L, TRAIT_EMOTEMUTE, id)
/datum/reagent/toxin/bonehurtingjuice //oof ouch
name = "Bone Hurting Juice"
id = "bonehurtingjuice"
description = "A strange substance that looks a lot like water. Drinking it is oddly tempting. Oof ouch."
color = "#AAAAAA77" //RGBA: 170, 170, 170, 77
toxpwr = 0
taste_description = "bone hurting"
overdose_threshold = 20
/datum/reagent/toxin/bonehurtingjuice/on_mob_add(mob/living/carbon/M)
M.say("oof ouch my bones", forced = /datum/reagent/toxin/bonehurtingjuice)
/datum/reagent/toxin/bonehurtingjuice/on_mob_life(mob/living/carbon/M)
M.adjustStaminaLoss(7.5, 0)
if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER))
M.adjustBruteLoss(3.5, 0)
if(prob(12))
switch(rand(1, 3))
if(1)
var/list/possible_says = list("oof.", "ouch!", "my bones.", "oof ouch.", "oof ouch my bones.")
M.say(pick(possible_says), forced = /datum/reagent/toxin/bonehurtingjuice)
if(2)
var/list/possible_mes = list("oofs softly.", "looks like their bones hurt.", "grimaces, as though their bones hurt.")
M.say("*custom " + pick(possible_mes), forced = /datum/reagent/toxin/bonehurtingjuice)
if(3)
to_chat(M, "<span class='warning'>Your bones hurt!</span>")
return ..()
/datum/reagent/toxin/bonehurtingjuice/overdose_process(mob/living/carbon/M)
if(prob(6) && iscarbon(M)) //big oof
var/selected_part
switch(rand(1, 4)) //God help you if the same limb gets picked twice quickly.
if(1)
selected_part = BODY_ZONE_L_ARM
if(2)
selected_part = BODY_ZONE_R_ARM
if(3)
selected_part = BODY_ZONE_L_LEG
if(4)
selected_part = BODY_ZONE_R_LEG
var/obj/item/bodypart/bp = M.get_bodypart(selected_part)
if(M.dna.species.type != /datum/species/skeleton || M.dna.species.type != /datum/species/plasmaman || M.dna.species.type != /datum/species/golem/bone) //We're so sorry skeletons, you're so misunderstood
if(bp)
bp.receive_damage(0, 0, 200)
playsound(M, get_sfx("desceration"), 50, TRUE, -1)
M.visible_message("<span class='warning'>[M]'s bones hurt too much!!</span>", "<span class='danger'>Your bones hurt too much!!</span>")
M.say("OOF!!", forced = /datum/reagent/toxin/bonehurtingjuice)
else //SUCH A LUST FOR REVENGE!!!
to_chat(M, "<span class='warning'>A phantom limb hurts!</span>")
M.say("Why are we still here, just to suffer?", forced = /datum/reagent/toxin/bonehurtingjuice)
else //you just want to socialize
if(bp)
playsound(M, get_sfx("desceration"), 50, TRUE, -1)
M.visible_message("<span class='warning'>[M] rattles loudly and flails around!!</span>", "<span class='danger'>Your bones hurt so much that your missing muscles spasm!!</span>")
M.say("OOF!!", forced=/datum/reagent/toxin/bonehurtingjuice)
bp.receive_damage(200, 0, 0) //But I don't think we should
else
to_chat(M, "<span class='warning'>Your missing arm aches from wherever you left it.</span>")
M.emote("sigh")
return ..()
@@ -94,6 +94,12 @@
results = list("pen_acid" = 6)
required_reagents = list("welding_fuel" = 1, "chlorine" = 1, "ammonia" = 1, "formaldehyde" = 1, "sodium" = 1, "cyanide" = 1)
/datum/chemical_reaction/pen_jelly
name = "Pentetic Jelly"
id = "pen_jelly"
results = list("pen_jelly" = 2)
required_reagents = list("pen_acid" = 1, "slimejelly" = 1)
/datum/chemical_reaction/sal_acid
name = "Salicyclic Acid"
id = "sal_acid"
@@ -64,8 +64,8 @@
strengthdiv = 8
for(var/mob/living/simple_animal/revenant/R in get_hearers_in_view(7,get_turf(holder.my_atom)))
var/deity
if(SSreligion.deity)
deity = SSreligion.deity
if(GLOB.deity)
deity = GLOB.deity
else
deity = "Christ"
to_chat(R, "<span class='userdanger'>The power of [deity] compels you!</span>")
@@ -216,7 +216,7 @@
/datum/chemical_reaction/slime/slimefreeze/on_reaction(datum/reagents/holder)
var/turf/T = get_turf(holder.my_atom)
T.visible_message("<span class='danger'>The slime extract begins to vibrate adorably!</span>")
T.visible_message("<span class='danger'>The slime extract starts to feel extremely cold!</span>")
addtimer(CALLBACK(src, .proc/freeze, holder), 50)
var/obj/item/slime_extract/M = holder.my_atom
deltimer(M.qdel_timer)
@@ -227,7 +227,8 @@
if(holder && holder.my_atom)
var/turf/open/T = get_turf(holder.my_atom)
if(istype(T))
T.atmos_spawn_air("nitrogen=50;TEMP=2.7")
var/datum/gas/gastype = /datum/gas/nitrogen
T.atmos_spawn_air("[initial(gastype.id)]=50;TEMP=2.7")
/datum/chemical_reaction/slime/slimefireproof
name = "Slime Fireproof"
@@ -370,6 +371,11 @@
/datum/chemical_reaction/slime/slimebloodlust/on_reaction(datum/reagents/holder)
for(var/mob/living/simple_animal/slime/slime in viewers(get_turf(holder.my_atom), null))
if(slime.docile) //Undoes docility, but doesn't make rabid.
slime.visible_message("<span class='danger'>[slime] forgets its training, becoming wild once again!</span>")
slime.docile = FALSE
slime.update_name()
continue
slime.rabid = 1
slime.visible_message("<span class='danger'>The [slime] is driven into a frenzy!</span>")
..()
@@ -0,0 +1,212 @@
GLOBAL_LIST_INIT(food_reagents, build_reagents_to_food()) //reagentid = related food types
/proc/build_reagents_to_food()
. = list()
for (var/type in subtypesof(/obj/item/reagent_containers/food))
var/obj/item/reagent_containers/food/item = new type()
for(var/r in item.list_reagents)
if (!.[r])
.[r] = list()
.[r] += type
qdel(item)
//dang plant snowflake
for (var/type in subtypesof(/obj/item/seeds))
var/obj/item/seeds/item = new type()
for(var/r in item.reagents_add)
if (!.[r])
.[r] = list()
.[r] += type
qdel(item)
#define RNGCHEM_INPUT "input"
#define RNGCHEM_CATALYSTS "catalysts"
#define RNGCHEM_OUTPUT "output"
/datum/chemical_reaction/randomized
name = "semi randomized reaction"
var/persistent = FALSE
var/persistence_period = 7 //Will reset every x days
var/created //creation timestamp
var/randomize_container = FALSE
var/list/possible_containers = list()
var/randomize_req_temperature = TRUE
var/min_temp = 1
var/max_temp = 600
var/randomize_inputs = TRUE
var/min_input_reagent_amount = 1
var/max_input_reagent_amount = 10
var/min_input_reagents = 2
var/max_input_reagents = 5
var/list/possible_reagents = list()
var/min_catalysts = 0
var/max_catalysts = 2
var/list/possible_catalysts = list()
var/randomize_results = FALSE
var/min_output_reagent_amount = 1
var/max_output_reagent_amount = 5
var/min_result_reagents = 1
var/max_result_reagents = 1
var/list/possible_results = list()
/datum/chemical_reaction/randomized/proc/GenerateRecipe()
created = world.time
if(randomize_container)
required_container = pick(possible_containers)
if(randomize_req_temperature)
required_temp = rand(min_temp,max_temp)
is_cold_recipe = pick(TRUE,FALSE)
if(randomize_results)
results = list()
var/list/remaining_possible_results = GetPossibleReagents(RNGCHEM_OUTPUT)
var/out_reagent_count = min(rand(min_result_reagents,max_result_reagents),remaining_possible_results.len)
for(var/i in 1 to out_reagent_count)
var/r_id = pick_n_take(remaining_possible_results)
results[r_id] = rand(min_output_reagent_amount,max_output_reagent_amount)
if(randomize_inputs)
var/list/remaining_possible_reagents = GetPossibleReagents(RNGCHEM_INPUT)
var/list/remaining_possible_catalysts = GetPossibleReagents(RNGCHEM_CATALYSTS)
//We're going to assume we're not doing any weird partial reactions for now.
for(var/reagent_type in results)
remaining_possible_catalysts -= reagent_type
remaining_possible_reagents -= reagent_type
var/in_reagent_count = min(rand(min_input_reagents,max_input_reagents),remaining_possible_reagents.len)
if(in_reagent_count <= 0)
return FALSE
required_reagents = list()
for(var/i in 1 to in_reagent_count)
var/r_id = pick_n_take(remaining_possible_reagents)
required_reagents[r_id] = rand(min_input_reagent_amount,max_input_reagent_amount)
remaining_possible_catalysts -= r_id //Can't have same reagents both as catalyst and reagent. Or can we ?
required_catalysts = list()
var/in_catalyst_count = min(rand(min_catalysts,max_catalysts),remaining_possible_catalysts.len)
for(var/i in 1 to in_catalyst_count)
var/r_id = pick_n_take(remaining_possible_catalysts)
required_catalysts[r_id] = rand(min_input_reagent_amount,max_input_reagent_amount)
return TRUE
/datum/chemical_reaction/randomized/proc/GetPossibleReagents(kind)
switch(kind)
if(RNGCHEM_INPUT)
return possible_reagents.Copy()
if(RNGCHEM_CATALYSTS)
return possible_catalysts.Copy()
if(RNGCHEM_OUTPUT)
return possible_results.Copy()
/datum/chemical_reaction/randomized/proc/HasConflicts()
for(var/x in required_reagents)
for(var/datum/chemical_reaction/R in GLOB.chemical_reactions_list[x])
if(chem_recipes_do_conflict(R,src))
return TRUE
return FALSE
/datum/chemical_reaction/randomized/proc/unwrap_reagent_list(list/textreagents)
. = list()
for(var/R in textreagents)
var/pathR = text2path(R)
if(!pathR)
return null
.[pathR] = textreagents[R]
/datum/chemical_reaction/randomized/proc/LoadOldRecipe(recipe_data)
created = text2num(recipe_data["timestamp"])
var/req_reag = unwrap_reagent_list(recipe_data["required_reagents"])
if(!req_reag)
return FALSE
required_reagents = req_reag
var/req_catalysts = unwrap_reagent_list(recipe_data["required_catalysts"])
if(!req_catalysts)
return FALSE
required_catalysts = req_catalysts
required_temp = recipe_data["required_temp"]
is_cold_recipe = recipe_data["is_cold_recipe"]
var/temp_results = unwrap_reagent_list(recipe_data["results"])
if(!temp_results)
return FALSE
results = temp_results
var/containerpath = text2path(recipe_data["required_container"])
if(!containerpath)
return FALSE
required_container = containerpath
return TRUE
/datum/chemical_reaction/randomized/secret_sauce
name = "secret sauce creation"
id = "secretsauce"
persistent = TRUE
persistence_period = 7 //Reset every week
randomize_container = TRUE
possible_containers = list(/obj/item/reagent_containers/glass/bucket) //easy way to ensure no common conflicts
randomize_req_temperature = TRUE
results = list("secret_sauce" =1)
/datum/chemical_reaction/randomized/secret_sauce/GetPossibleReagents(kind)
switch(kind)
if(RNGCHEM_INPUT,RNGCHEM_CATALYSTS)
var/food_reagent_ids = list()
for(var/key in GLOB.food_reagents)
food_reagent_ids += key
return food_reagent_ids
return ..()
/obj/item/paper/secretrecipe
name = "old recipe"
var/recipe_id = "secretsauce"
/obj/item/paper/secretrecipe/examine(mob/user) //Extra secret
if(isobserver(user))
return
. = ..()
/obj/item/paper/secretrecipe/Initialize()
. = ..()
if(SSpersistence.initialized)
UpdateInfo()
else
SSticker.OnRoundstart(CALLBACK(src,.proc/UpdateInfo))
/obj/item/paper/secretrecipe/proc/UpdateInfo()
var/datum/chemical_reaction/recipe = get_chemical_reaction(recipe_id)
if(!recipe)
info = "This recipe is illegible."
var/list/dat = list("<ul>")
for(var/rid in recipe.required_reagents)
var/datum/reagent/R = GLOB.chemical_reagents_list[rid]
dat += "<li>[recipe.required_reagents[rid]]u of [R.name]</li>"
dat += "</ul>"
if(recipe.required_catalysts.len)
dat += "With following present: <ul>"
for(var/rid in recipe.required_catalysts)
var/datum/reagent/R = GLOB.chemical_reagents_list[rid]
dat += "<li>[recipe.required_catalysts[rid]]u of [R.name]</li>"
dat += "</ul>"
dat += "Mix slowly"
if(recipe.required_container)
var/obj/item/I = recipe.required_container
dat += " in [initial(I.name)]"
if(recipe.required_temp != 0)
if(recipe.is_cold_recipe)
dat += " below [recipe.required_temp] degrees"
else
dat += " above [recipe.required_temp] degrees"
dat += "."
info = dat.Join("")
update_icon()
@@ -119,3 +119,10 @@
id = "mimesbane"
results = list("mimesbane" = 3)
required_reagents = list("radium" = 1, "mutetoxin" = 1, "nothing" = 1)
/datum/chemical_reaction/bonehurtingjuice
name = "Bone Hurting Juice"
id = "bonehurtingjuice"
results = list("bonehurtingjuice" = 5)
required_reagents = list("mutagen" = 1, "itching_powder" = 3, "milk" = 1)
mix_message = "<span class='danger'>The mixture suddenly becomes clear and looks a lot like water. You feel a strong urge to drink it.</span>"
+2 -1
View File
@@ -7,6 +7,7 @@
var/amount_per_transfer_from_this = 5
var/list/possible_transfer_amounts = list(5,10,15,20,25,30)
var/volume = 30
var/reagent_flags
var/list/list_reagents = null
var/spawned_disease = null
var/disease_amount = 20
@@ -16,7 +17,7 @@
. = ..()
if(isnum(vol) && vol > 0)
volume = vol
create_reagents(volume)
create_reagents(volume, reagent_flags)
if(spawned_disease)
var/datum/disease/F = new spawned_disease()
var/list/data = list("viruses"= list(F))
@@ -6,7 +6,7 @@
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(1, 2, 3, 4, 5)
volume = 5
container_type = TRANSPARENT
reagent_flags = TRANSPARENT
/obj/item/reagent_containers/dropper/afterattack(obj/target, mob/user , proximity)
. = ..()
@@ -3,7 +3,7 @@
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
volume = 50
container_type = OPENCONTAINER
reagent_flags = OPENCONTAINER
spillable = TRUE
resistance_flags = ACID_PROOF
@@ -194,13 +194,10 @@
reactions. Can hold up to 50 units."
icon_state = "beakernoreact"
materials = list(MAT_METAL=3000)
reagent_flags = OPENCONTAINER | NO_REACT
volume = 50
amount_per_transfer_from_this = 10
/obj/item/reagent_containers/glass/beaker/noreact/Initialize()
. = ..()
reagents.set_reacting(FALSE)
/obj/item/reagent_containers/glass/beaker/bluespace
name = "bluespace beaker"
desc = "A bluespace beaker, powered by experimental bluespace technology \
@@ -291,11 +288,11 @@
to_chat(user, "<span class='userdanger'>[src]'s contents spill all over you!</span>")
reagents.reaction(user, TOUCH)
reagents.clear_reagents()
container_type = NONE
reagent_flags = NONE
/obj/item/reagent_containers/glass/bucket/dropped(mob/user)
. = ..()
container_type = initial(container_type)
reagent_flags = initial(reagent_flags)
/obj/item/reagent_containers/glass/bucket/equip_to_best_slot(var/mob/M)
if(reagents.total_volume) //If there is water in a bucket, don't quick equip it to the head
@@ -10,7 +10,7 @@
volume = 30
possible_transfer_amounts = list()
resistance_flags = ACID_PROOF
container_type = OPENCONTAINER
reagent_flags = OPENCONTAINER
slot_flags = ITEM_SLOT_BELT
var/ignore_flags = 0
var/infinite = FALSE
@@ -73,7 +73,7 @@
desc = "A modified air-needle autoinjector with a small single-use reservoir. It contains an experimental serum."
icon_state = "combat_hypo"
volume = 5
container_type = NONE
reagent_flags = NONE
list_reagents = list("magillitis" = 5)
//MediPens
@@ -88,7 +88,7 @@
amount_per_transfer_from_this = 10
volume = 10
ignore_flags = 1 //so you can medipen through hardsuits
container_type = DRAWABLE
reagent_flags = DRAWABLE
flags_1 = null
list_reagents = list("epinephrine" = 10)
@@ -103,7 +103,7 @@
..()
if(!iscyborg(user))
reagents.maximum_volume = 0 //Makes them useless afterwards
container_type = NONE
reagent_flags = NONE
update_icon()
addtimer(CALLBACK(src, .proc/cyborg_recharge, user), 80)
@@ -8,7 +8,7 @@
righthand_file = 'icons/mob/inhands/equipment/hydroponics_righthand.dmi'
item_flags = NOBLUDGEON
obj_flags = UNIQUE_RENAME
container_type = OPENCONTAINER
reagent_flags = OPENCONTAINER
slot_flags = ITEM_SLOT_BELT
throwforce = 0
w_class = WEIGHT_CLASS_SMALL
@@ -46,6 +46,9 @@
M.visible_message("<span class='danger'>[user] forces [M] to [apply_method] [src].</span>", \
"<span class='userdanger'>[user] forces [M] to [apply_method] [src].</span>")
var/makes_me_think = pick(strings("redpill.json", "redpill_questions"))
if(icon_state == "pill4" && prob(5)) //you take the red pill - you stay in Wonderland, and I show you how deep the rabbit hole goes
addtimer(CALLBACK(GLOBAL_PROC, /proc/to_chat, M, "<span class='notice'>[makes_me_think]</span>"), 50)
log_combat(user, M, "fed", reagents.log_list())
if(reagents.total_volume)
@@ -0,0 +1,177 @@
/obj/item/reagent_containers/rag
name = "damp rag"
desc = "For cleaning up messes, you suppose."
w_class = WEIGHT_CLASS_TINY
icon = 'icons/obj/toy.dmi'
icon_state = "rag"
item_flags = NOBLUDGEON
reagent_flags = OPENCONTAINER
amount_per_transfer_from_this = 5
possible_transfer_amounts = list()
volume = 5
spillable = FALSE
var/wipe_sound
var/soak_efficiency = 1
var/extinguish_efficiency = 0
var/action_speed = 3 SECONDS
var/damp_threshold = 0.5
/obj/item/reagent_containers/rag/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is smothering [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (OXYLOSS)
/obj/item/reagent_containers/rag/examine(mob/user)
. = ..()
if(reagents.total_volume)
to_chat(user, "<span class='notice'>Alt-Click to squeeze the liquids out of it.</span>")
/obj/item/reagent_containers/rag/afterattack(atom/A as obj|turf|area, mob/user,proximity)
. = ..()
if(!proximity)
return
if(iscarbon(A) && A.reagents && reagents.total_volume)
var/mob/living/carbon/C = A
var/reagentlist = pretty_string_from_reagent_list(reagents)
var/log_object = "a damp rag containing [reagentlist]"
if(user.a_intent == INTENT_HARM && !C.is_mouth_covered())
reagents.reaction(C, INGEST)
reagents.trans_to(C, 5)
C.visible_message("<span class='danger'>[user] has smothered \the [C] with \the [src]!</span>", "<span class='userdanger'>[user] has smothered you with \the [src]!</span>", "<span class='italics'>You hear some struggling and muffled cries of surprise.</span>")
log_combat(user, C, "smothered", log_object)
else
reagents.reaction(C, TOUCH)
reagents.remove_all(5)
C.visible_message("<span class='notice'>[user] has touched \the [C] with \the [src].</span>")
log_combat(user, C, "touched", log_object)
else if(istype(A) && src in user)
user.visible_message("[user] starts to wipe down [A] with [src]!", "<span class='notice'>You start to wipe down [A] with [src]...</span>")
if(do_after(user, action_speed, target = A))
user.visible_message("[user] finishes wiping off [A]!", "<span class='notice'>You finish wiping off [A].</span>")
SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
return
/obj/item/reagent_containers/rag/pre_altattackby(mob/living/M, mob/living/user, params)
if(istype(M) && user.a_intent == INTENT_HELP)
user.changeNext_move(CLICK_CD_MELEE)
if(M.on_fire)
user.visible_message("<span class='warning'>\The [user] uses \the [src] to pat out [M == user ? "[user.p_their()]" : "\the [M]'s"] flames!</span>")
if(hitsound)
playsound(M, hitsound, 25, 1)
M.adjust_fire_stacks(-min(extinguish_efficiency, M.fire_stacks))
else
if(reagents.total_volume > (volume * damp_threshold))
to_chat(user, "<span class='warning'>\The [src] is too drenched to be used to dry [user == M ? "yourself" : "\the [M]"] off.</span>")
return TRUE
user.visible_message("<span class='notice'>\The [user] starts drying [M == user ? "[user.p_them()]self" : "\the [M]"] off with \the [src]...</span>")
if(do_mob(user, M, action_speed))
if(reagents.total_volume > (volume * damp_threshold))
return
user.visible_message("<span class='notice'>\The [user] dries [M == user ? "[user.p_them()]self" : "\the [M]"] off with \the [src].</span>")
if(wipe_sound)
playsound(M, wipe_sound, 25, 1)
if(M.fire_stacks)
var/minus_plus = M.fire_stacks < 0 ? 1 : -1
var/amount = min(abs(M.fire_stacks), soak_efficiency)
var/r_id = "fuel"
if(M.fire_stacks < 0)
r_id = "water"
reagents.add_reagent(r_id, amount * 0.3)
M.adjust_fire_stacks(minus_plus * amount)
M.wash_cream()
return TRUE
return ..()
/obj/item/reagent_containers/rag/AltClick(mob/user)
. = ..()
if(reagents.total_volume && user.canUseTopic(src, BE_CLOSE))
to_chat(user, "<span class='notice'>You start squeezing the liquids out of \the [src]...</span>")
if(do_after(user, action_speed, TRUE, src))
to_chat(user, "<span class='notice'>You squeeze \the [src] dry.</span>")
var/atom/react_loc = get_turf(src)
if(ismob(react_loc))
react_loc = react_loc.loc
if(react_loc)
reagents.reaction(react_loc, TOUCH)
reagents.clear_reagents()
/obj/item/reagent_containers/rag/towel
name = "towel"
desc = "A soft cotton towel."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "towel"
item_state = "towel"
slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING
item_flags = NOBLUDGEON | NO_UNIFORM_REQUIRED //so it can be worn on the belt slot even with no uniform.
force = 1
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("whipped")
hitsound = 'sound/items/towelwhip.ogg'
volume = 10
total_mass = 2
wipe_sound = 'sound/items/towelwipe.ogg'
soak_efficiency = 4
extinguish_efficiency = 3
var/flat_icon = "towel_flat"
var/folded_icon = "towel"
var/list/possible_colors
/obj/item/reagent_containers/rag/towel/Initialize()
. = ..()
if(possible_colors)
add_atom_colour(pick(possible_colors), FIXED_COLOUR_PRIORITY)
/obj/item/reagent_containers/rag/towel/attack(mob/living/M, mob/living/user)
if(user.a_intent == INTENT_HARM)
DISABLE_BITFIELD(item_flags, NOBLUDGEON)
. = TRUE
..()
if(.)
ENABLE_BITFIELD(item_flags, NOBLUDGEON)
/obj/item/reagent_containers/rag/towel/equipped(mob/living/user, slot)
. = ..()
switch(slot)
if(SLOT_BELT)
body_parts_covered = GROIN|LEGS
if(SLOT_WEAR_SUIT)
body_parts_covered = CHEST|GROIN|LEGS
if(SLOT_HEAD)
body_parts_covered = HEAD
flags_inv = HIDEHAIR
/obj/item/reagent_containers/rag/towel/dropped(mob/user)
. = ..()
body_parts_covered = NONE
flags_inv = NONE
/obj/item/reagent_containers/rag/towel/attack_self(mob/user)
if(!user.CanReach(src) || !user.dropItemToGround(src))
return
to_chat(user, "<span class='notice'>You lay out \the [src] flat on the ground.</span>")
icon_state = flat_icon
layer = BELOW_OBJ_LAYER
/obj/item/reagent_containers/rag/towel/pickup(mob/living/user)
. = ..()
icon_state = folded_icon
layer = initial(layer)
/obj/item/reagent_containers/rag/towel/on_reagent_change(changetype)
force = initial(force) + round(reagents.total_volume * 0.5)
/obj/item/reagent_containers/rag/towel/random
possible_colors = list("#FF0000","#FF7F00","#FFFF00","#00FF00","#0000FF","#4B0082","#8F00FF")
/obj/item/reagent_containers/rag/towel/syndicate
name = "syndicate towel"
desc = "Truly a weapon of mass destruction."
possible_colors = list("#DD1A1A", "#DB4325", "#E02700")
force = 4
armour_penetration = 10
volume = 20
soak_efficiency = 6
extinguish_efficiency = 5
action_speed = 15
damp_threshold = 0.8
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 50, "acid" = 50) //items don't provide armor to wearers unlike clothing yet.
@@ -7,7 +7,7 @@
lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi'
item_flags = NOBLUDGEON
container_type = OPENCONTAINER
reagent_flags = OPENCONTAINER
slot_flags = ITEM_SLOT_BELT
throwforce = 0
w_class = WEIGHT_CLASS_SMALL
@@ -224,7 +224,7 @@
return
/obj/item/reagent_containers/spray/waterflower/cyborg
container_type = NONE
reagent_flags = NONE
volume = 100
list_reagents = list("water" = 100)
var/generate_amount = 5
@@ -13,7 +13,7 @@
var/busy = FALSE // needed for delayed drawing of blood
var/proj_piercing = 0 //does it pierce through thick clothes when shot with syringe gun
materials = list(MAT_METAL=10, MAT_GLASS=20)
container_type = TRANSPARENT
reagent_flags = TRANSPARENT
/obj/item/reagent_containers/syringe/Initialize()
. = ..()
@@ -249,10 +249,7 @@
name = "cryo syringe"
desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units."
volume = 20
/obj/item/reagent_containers/syringe/noreact/Initialize()
. = ..()
reagents.set_reacting(FALSE)
reagent_flags = TRANSPARENT | NO_REACT
/obj/item/reagent_containers/syringe/piercing
name = "piercing syringe"
@@ -262,3 +259,92 @@
/obj/item/reagent_containers/syringe/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "pouch")
/obj/item/reagent_containers/syringe/dart
name = "medicinal smartdart"
desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented."
volume = 20
amount_per_transfer_from_this = 20
icon_state = "empty"
item_state = "syringe_empty"
var/emptrig = FALSE
/obj/item/reagent_containers/syringe/dart/afterattack(atom/target, mob/user , proximity)
if(busy)
return
if(!proximity)
return
if(!target.reagents)
return
var/mob/living/L
if(isliving(target))
L = target
if(!L.can_inject(user, 1))
return
switch(mode)
if(SYRINGE_DRAW)
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='notice'>The dart is full!</span>")
return
if(L) //living mob
to_chat(user, "<span class='warning'>You can't draw blood using a dart!</span>")
return
else //if not mob
if(!target.reagents.total_volume)
to_chat(user, "<span class='warning'>[target] is empty!</span>")
return
if(!target.is_drawable())
to_chat(user, "<span class='warning'>You cannot directly remove reagents from [target]!</span>")
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You soak the [src] with [trans] units of the solution. It now contains [reagents.total_volume] units.</span>")
if (reagents.total_volume >= reagents.maximum_volume)
mode=!mode
update_icon()
if(SYRINGE_INJECT)
src.visible_message("<span class='danger'>The smartdart gives a frustrated boop! It's fully saturated; You need to shoot someone with it!</span>")
/obj/item/reagent_containers/syringe/dart/attack_self(mob/user)
return
/obj/item/reagent_containers/syringe/dart/update_icon()
cut_overlays()
var/rounded_vol
rounded_vol = "empty"
if(reagents && reagents.total_volume)
if(volume/reagents.total_volume == 1)
rounded_vol="full"
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
if(ismob(loc))
var/mob/M = loc
var/injoverlay
switch(mode)
if (SYRINGE_DRAW)
injoverlay = "draw"
if (SYRINGE_INJECT)
injoverlay = "ready"
add_overlay(injoverlay)
M.update_inv_hands()
/obj/item/reagent_containers/syringe/dart/emp_act(severity)
emptrig = TRUE
..()
/obj/item/reagent_containers/syringe/dart/bluespace
name = "bluespace smartdart"
desc = "A non-harmful dart that can administer medication from a range. Once it hits a patient using it's smart nanofilter technology only medicines contained within the dart are administered to the patient. Additonally, due to capillary action, injection of chemicals past the overdose limit is prevented. Has an extended volume capacity thanks to bluespace foam."
amount_per_transfer_from_this = 50
volume = 50
+1 -2
View File
@@ -5,7 +5,6 @@
icon_state = "water"
density = TRUE
anchored = FALSE
container_type = DRAINABLE | AMOUNT_VISIBLE
pressure_resistance = 2*ONE_ATMOSPHERE
max_integrity = 300
var/tank_volume = 1000 //In units, how much the dispenser can hold
@@ -24,7 +23,7 @@
return ..()
/obj/structure/reagent_dispensers/Initialize()
create_reagents(tank_volume)
create_reagents(tank_volume, DRAINABLE | AMOUNT_VISIBLE)
reagents.add_reagent(reagent_id, tank_volume)
. = ..()