initial commit - cross reference with 5th port - obviously has compile errors

This commit is contained in:
LetterJay
2016-07-03 02:17:19 -05:00
commit 35a1723e98
4355 changed files with 2221257 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
// Replaces chemgrenade stuff, allowing reagent explosions to be called from anywhere.
// It should be called using a location, the range, and a list of reagents involved.
// Threatscale is a multiplier for the 'threat' of the grenade. If you're increasing the affected range drastically, you might want to improve this.
// Extra heat affects the temperature of the mixture, and may cause it to react in different ways.
proc/chem_splash(turf/epicenter, affected_range = 3, list/datum/reagents/reactants = list(), extra_heat = 0, threatscale = 1, adminlog = 1)
if(!istype(epicenter, /turf) || !reactants.len || threatscale <= 0)
return
var/has_reagents
var/total_reagents
for(var/datum/reagents/R in reactants)
if(R.total_volume)
has_reagents = 1
total_reagents += R.total_volume
if(!has_reagents)
return
var/datum/reagents/splash_holder = new/datum/reagents(total_reagents*threatscale)
splash_holder.my_atom = epicenter // For some reason this is setting my_atom to null, and causing runtime errors.
var/total_temp = 0
for(var/datum/reagents/R in reactants)
R.trans_to(splash_holder, R.total_volume, threatscale, 1, 1)
total_temp += R.chem_temp
splash_holder.chem_temp = (total_temp/reactants.len) + extra_heat // Average temperature of reagents + extra heat.
splash_holder.handle_reactions() // React them now.
if(splash_holder.total_volume && affected_range >= 0) //The possible reactions didnt use up all reagents, so we spread it around.
var/datum/effect_system/steam_spread/steam = new /datum/effect_system/steam_spread()
steam.set_up(10, 0, epicenter)
steam.attach(epicenter)
steam.start()
var/list/viewable = view(affected_range, epicenter)
var/list/accessible = list(epicenter)
for(var/i=1; i<=affected_range; i++)
var/list/turflist = list()
for(var/turf/T in (orange(i, epicenter) - orange(i-1, epicenter)))
turflist |= T
for(var/turf/T in turflist)
if( !(get_dir(T,epicenter) in cardinal) && (abs(T.x - epicenter.x) == abs(T.y - epicenter.y) ))
turflist.Remove(T)
turflist.Add(T) // we move the purely diagonal turfs to the end of the list.
for(var/turf/T in turflist)
if(T in accessible) continue
for(var/turf/NT in orange(1, T))
if(!(NT in accessible)) continue
if(!(get_dir(T,NT) in cardinal)) continue
if(!NT.CanAtmosPass(T)) continue
accessible |= T
break
var/list/reactable = accessible
for(var/turf/T in accessible)
for(var/atom/A in T.GetAllContents())
if(!(A in viewable)) continue
reactable |= A
if(extra_heat >= 300)
T.hotspot_expose(extra_heat*2, 5)
if(!reactable.len) //Nothing to react with. Probably means we're in nullspace.
return
var/fraction = 0.5/accessible.len // In a 100u mix. A small grenade spreads ~1.5u units per affected tile. A large grenade spreads ~0.75u, and a bomb spreads ~0.4u
for(var/atom/A in reactable)
splash_holder.reaction(A, TOUCH, fraction)
qdel(splash_holder)
return 1
+21
View File
@@ -0,0 +1,21 @@
/proc/mix_color_from_reagents(list/reagent_list)
if(!istype(reagent_list))
return
var/color
var/vol_counter = 0
var/vol_temp
for(var/datum/reagent/R in reagent_list)
vol_temp = R.volume
vol_counter += vol_temp
if(!color)
color = R.color
else if (length(color) >= length(R.color))
color = BlendRGB(color, R.color, vol_temp/vol_counter)
else
color = BlendRGB(R.color, color, vol_temp/vol_counter)
return color
+665
View File
@@ -0,0 +1,665 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
var/const/TOUCH = 1 //splashing
var/const/INGEST = 2 //ingestion
var/const/VAPOR = 3 //foam, spray, blob attack
var/const/PATCH = 4 //patches
var/const/INJECT = 5 //injection
///////////////////////////////////////////////////////////////////////////////////
/datum/reagents
var/list/datum/reagent/reagent_list = new/list()
var/total_volume = 0
var/maximum_volume = 100
var/atom/my_atom = null
var/chem_temp = 150
var/last_tick = 1
var/addiction_tick = 1
var/list/datum/reagent/addiction_list = new/list()
var/flags
/datum/reagents/New(maximum=100)
maximum_volume = maximum
if(!(flags & REAGENT_NOREACT))
START_PROCESSING(SSobj, src)
//I dislike having these here but map-objects are initialised before world/New() is called. >_>
if(!chemical_reagents_list)
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
var/paths = subtypesof(/datum/reagent)
chemical_reagents_list = list()
for(var/path in paths)
var/datum/reagent/D = new path()
chemical_reagents_list[D.id] = D
if(!chemical_reactions_list)
//Chemical Reactions - Initialises all /datum/chemical_reaction into a list
// It is filtered into multiple lists within a list.
// For example:
// chemical_reaction_list["plasma"] is a list of all reactions relating to plasma
var/paths = subtypesof(/datum/chemical_reaction)
chemical_reactions_list = list()
for(var/path in paths)
var/datum/chemical_reaction/D = new path()
var/list/reaction_ids = list()
if(D.required_reagents && D.required_reagents.len)
for(var/reaction in D.required_reagents)
reaction_ids += reaction
// Create filters based on each reagent id in the required reagents list
for(var/id in reaction_ids)
if(!chemical_reactions_list[id])
chemical_reactions_list[id] = list()
chemical_reactions_list[id] += D
break // Don't bother adding ourselves to other reagent ids, it is redundant.
/datum/reagents/Destroy()
. = ..()
STOP_PROCESSING(SSobj, src)
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
qdel(R)
reagent_list.Cut()
reagent_list = null
if(my_atom && my_atom.reagents == src)
my_atom.reagents = null
/datum/reagents/proc/remove_any(amount = 1)
var/total_transfered = 0
var/current_list_element = 1
current_list_element = rand(1, reagent_list.len)
while(total_transfered != amount)
if(total_transfered >= amount)
break
if(total_volume <= 0 || !reagent_list.len)
break
if(current_list_element > reagent_list.len)
current_list_element = 1
var/datum/reagent/R = reagent_list[current_list_element]
remove_reagent(R.id, 1)
current_list_element++
total_transfered++
update_total()
handle_reactions()
return total_transfered
/datum/reagents/proc/remove_all(amount = 1)
if(total_volume > 0)
var/part = amount / total_volume
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
remove_reagent(R.id, R.volume * part)
update_total()
handle_reactions()
return amount
/datum/reagents/proc/get_master_reagent_name()
var/name
var/max_volume = 0
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
if(R.volume > max_volume)
max_volume = R.volume
name = R.name
return name
/datum/reagents/proc/get_master_reagent_id()
var/id
var/max_volume = 0
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
if(R.volume > max_volume)
max_volume = R.volume
id = R.id
return id
/datum/reagents/proc/trans_to(obj/target, amount=1, multiplier=1, preserve_data=1, no_react = 0)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
if(!target || !total_volume)
return
var/datum/reagents/R
if(istype(target, /datum/reagents))
R = target
else
if(!target.reagents || src.total_volume<=0)
return
R = target.reagents
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
var/part = amount / src.total_volume
var/trans_data = null
for(var/reagent in reagent_list)
var/datum/reagent/T = reagent
var/transfer_amount = T.volume * part
if(preserve_data)
trans_data = copy_data(T)
R.add_reagent(T.id, transfer_amount * multiplier, trans_data, chem_temp, no_react = 1) //we only handle reaction after every reagent has been transfered.
remove_reagent(T.id, transfer_amount)
update_total()
R.update_total()
if(!no_react)
R.handle_reactions()
src.handle_reactions()
return amount
/datum/reagents/proc/copy_to(obj/target, amount=1, multiplier=1, preserve_data=1)
if(!target)
return
if(!target.reagents || src.total_volume<=0)
return
var/datum/reagents/R = target.reagents
amount = min(min(amount, total_volume), R.maximum_volume-R.total_volume)
var/part = amount / total_volume
var/trans_data = null
for(var/reagent in reagent_list)
var/datum/reagent/T = reagent
var/copy_amount = T.volume * part
if(preserve_data)
trans_data = T.data
R.add_reagent(T.id, copy_amount * multiplier, trans_data)
src.update_total()
R.update_total()
R.handle_reactions()
src.handle_reactions()
return amount
/datum/reagents/proc/trans_id_to(obj/target, reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N
if (!target)
return
if (!target.reagents || src.total_volume<=0 || !src.get_reagent_amount(reagent))
return
var/datum/reagents/R = target.reagents
if(src.get_reagent_amount(reagent)<amount)
amount = src.get_reagent_amount(reagent)
amount = min(amount, R.maximum_volume-R.total_volume)
var/trans_data = null
for (var/datum/reagent/current_reagent in src.reagent_list)
if(current_reagent.id == reagent)
if(preserve_data)
trans_data = current_reagent.data
R.add_reagent(current_reagent.id, amount, trans_data, src.chem_temp)
src.remove_reagent(current_reagent.id, amount, 1)
break
src.update_total()
R.update_total()
R.handle_reactions()
//src.handle_reactions() Don't need to handle reactions on the source since you're (presumably isolating and) transferring a specific reagent.
return amount
/*
if (!target) return
var/total_transfered = 0
var/current_list_element = 1
var/datum/reagents/R = target.reagents
var/trans_data = null
//if(R.total_volume + amount > R.maximum_volume) return 0
current_list_element = rand(1,reagent_list.len) //Eh, bandaid fix.
while(total_transfered != amount)
if(total_transfered >= amount) break //Better safe than sorry.
if(total_volume <= 0 || !reagent_list.len) break
if(R.total_volume >= R.maximum_volume) break
if(current_list_element > reagent_list.len) current_list_element = 1
var/datum/reagent/current_reagent = reagent_list[current_list_element]
if(preserve_data)
trans_data = current_reagent.data
R.add_reagent(current_reagent.id, (1 * multiplier), trans_data)
src.remove_reagent(current_reagent.id, 1)
current_list_element++
total_transfered++
src.update_total()
R.update_total()
R.handle_reactions()
handle_reactions()
return total_transfered
*/
/datum/reagents/proc/metabolize(mob/living/carbon/C, can_overdose = 0)
if(C)
chem_temp = C.bodytemperature
handle_reactions()
var/need_mob_update = 0
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
if(!R.holder)
continue
if(!C)
C = R.holder.my_atom
if(C && R)
if(C.reagent_check(R) != 1)
if(can_overdose)
if(R.overdose_threshold)
if(R.volume >= R.overdose_threshold && !R.overdosed)
R.overdosed = 1
need_mob_update += R.overdose_start(C)
if(R.addiction_threshold)
if(R.volume >= R.addiction_threshold && !is_type_in_list(R, addiction_list))
var/datum/reagent/new_reagent = new R.type()
addiction_list.Add(new_reagent)
if(R.overdosed)
need_mob_update += R.overdose_process(C)
if(is_type_in_list(R,addiction_list))
for(var/addiction in addiction_list)
var/datum/reagent/A = addiction
if(istype(R, A))
A.addiction_stage = -15 // you're satisfied for a good while.
need_mob_update += R.on_mob_life(C)
if(can_overdose)
if(addiction_tick == 6)
addiction_tick = 1
for(var/addiction in addiction_list)
var/datum/reagent/R = addiction
if(C && R)
R.addiction_stage++
switch(R.addiction_stage)
if(1 to 10)
need_mob_update += R.addiction_act_stage1(C)
if(10 to 20)
need_mob_update += R.addiction_act_stage2(C)
if(20 to 30)
need_mob_update += R.addiction_act_stage3(C)
if(30 to 40)
need_mob_update += R.addiction_act_stage4(C)
if(40 to INFINITY)
C << "<span class='notice'>You feel like you've gotten over your need for [R.name].</span>"
addiction_list.Remove(R)
addiction_tick++
if(C && need_mob_update) //some of the metabolized reagents had effects on the mob that requires some updates.
C.updatehealth()
C.update_canmove()
C.update_stamina()
update_total()
/datum/reagents/process()
if(flags & REAGENT_NOREACT)
STOP_PROCESSING(SSobj, src)
return
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
R.on_tick()
/datum/reagents/proc/set_reacting(react = TRUE)
if(react)
// Order is important, process() can remove from processing if
// the flag is present
flags &= ~(REAGENT_NOREACT)
START_PROCESSING(SSobj, src)
else
STOP_PROCESSING(SSobj, src)
flags |= REAGENT_NOREACT
/datum/reagents/proc/conditional_update_move(atom/A, Running = 0)
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
R.on_move (A, Running)
update_total()
/datum/reagents/proc/conditional_update(atom/A)
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
R.on_update (A)
update_total()
/datum/reagents/proc/handle_reactions()
if(flags & REAGENT_NOREACT)
return //Yup, no reactions here. No siree.
var/reaction_occured = 0
do
reaction_occured = 0
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
for(var/reaction in chemical_reactions_list[R.id]) // Was a big list but now it should be smaller since we filtered it with our reagent id
if(!reaction)
continue
var/datum/chemical_reaction/C = reaction
var/total_required_reagents = C.required_reagents.len
var/total_matching_reagents = 0
var/total_required_catalysts = C.required_catalysts.len
var/total_matching_catalysts= 0
var/matching_container = 0
var/matching_other = 0
var/list/multipliers = new/list()
var/required_temp = C.required_temp
for(var/B in C.required_reagents)
if(!has_reagent(B, C.required_reagents[B]))
break
total_matching_reagents++
multipliers += round(get_reagent_amount(B) / C.required_reagents[B])
for(var/B in C.required_catalysts)
if(!has_reagent(B, C.required_catalysts[B]))
break
total_matching_catalysts++
if(!C.required_container)
matching_container = 1
else
if(my_atom.type == C.required_container)
matching_container = 1
if (isliving(my_atom)) //Makes it so certain chemical reactions don't occur in mobs
if (C.mob_react)
return
if(!C.required_other)
matching_other = 1
else if(istype(my_atom, /obj/item/slime_extract))
var/obj/item/slime_extract/M = my_atom
if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this
matching_other = 1
if(required_temp == 0)
required_temp = chem_temp
if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts && matching_container && matching_other && chem_temp >= required_temp)
var/multiplier = min(multipliers)
for(var/B in C.required_reagents)
remove_reagent(B, (multiplier * C.required_reagents[B]), safety = 1)
var/created_volume = C.result_amount*multiplier
if(C.result)
feedback_add_details("chemical_reaction","[C.result]|[C.result_amount*multiplier]")
multiplier = max(multiplier, 1) //this shouldnt happen ...
add_reagent(C.result, C.result_amount*multiplier, null, chem_temp)
var/list/seen = viewers(4, get_turf(my_atom))
if(!istype(my_atom, /mob)) // No bubbling mobs
if(C.mix_sound)
playsound(get_turf(my_atom), C.mix_sound, 80, 1)
for(var/mob/M in seen)
M << "<span class='notice'>\icon[my_atom] [C.mix_message]</span>"
if(istype(my_atom, /obj/item/slime_extract))
var/obj/item/slime_extract/ME2 = my_atom
ME2.Uses--
if(ME2.Uses <= 0) // give the notification that the slime core is dead
for(var/mob/M in seen)
M << "<span class='notice'>\icon[my_atom] \The [my_atom]'s power is consumed in the reaction.</span>"
ME2.name = "used slime extract"
ME2.desc = "This extract has been used up."
C.on_reaction(src, created_volume)
reaction_occured = 1
break
while(reaction_occured)
update_total()
return 0
/datum/reagents/proc/isolate_reagent(reagent)
for(var/_reagent in reagent_list)
var/datum/reagent/R = _reagent
if(R.id != reagent)
del_reagent(R.id)
update_total()
/datum/reagents/proc/del_reagent(reagent)
for(var/_reagent in reagent_list)
var/datum/reagent/R = _reagent
if(R.id == reagent)
if(istype(my_atom, /mob/living))
var/mob/living/M = my_atom
R.on_mob_delete(M)
qdel(R)
reagent_list -= R
update_total()
my_atom.on_reagent_change()
check_ignoreslow(my_atom)
check_gofast(my_atom)
check_goreallyfast(my_atom)
return 1
/datum/reagents/proc/check_ignoreslow(mob/M)
if(istype(M, /mob))
if(M.reagents.has_reagent("morphine")||M.reagents.has_reagent("ephedrine"))
return 1
else
M.status_flags &= ~IGNORESLOWDOWN
/datum/reagents/proc/check_gofast(mob/M)
if(istype(M, /mob))
if(M.reagents.has_reagent("unholywater")||M.reagents.has_reagent("nuka_cola")||M.reagents.has_reagent("stimulants"))
return 1
else
M.status_flags &= ~GOTTAGOFAST
/datum/reagents/proc/check_goreallyfast(mob/M)
if(istype(M, /mob))
if(M.reagents.has_reagent("methamphetamine"))
return 1
else
M.status_flags &= ~GOTTAGOREALLYFAST
/datum/reagents/proc/update_total()
total_volume = 0
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
if(R.volume < 0.1)
del_reagent(R.id)
else
total_volume += R.volume
return 0
/datum/reagents/proc/clear_reagents()
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
del_reagent(R.id)
return 0
/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1)
if(isliving(A))
var/touch_protection = 0
if(method == VAPOR)
var/mob/living/L = A
touch_protection = L.get_permeability_protection()
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection)
else if(isturf(A))
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
R.reaction_turf(A, R.volume * volume_modifier, show_message)
else if(isobj(A))
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
R.reaction_obj(A, R.volume * volume_modifier, show_message)
/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0)
if(!isnum(amount) || !amount)
return 1
update_total()
if(total_volume + amount > maximum_volume)
amount = (maximum_volume - total_volume) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen.
chem_temp = round(((amount * reagtemp) + (total_volume * chem_temp)) / (total_volume + amount)) //equalize with new chems
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
R.volume += amount
update_total()
my_atom.on_reagent_change()
R.on_merge(data)
if(!no_react)
handle_reactions()
return 0
var/datum/reagent/D = chemical_reagents_list[reagent]
if(D)
var/datum/reagent/R = new D.type(data)
reagent_list += R
R.holder = src
R.volume = amount
if(data)
R.data = data
R.on_new(data)
update_total()
my_atom.on_reagent_change()
if(!no_react)
handle_reactions()
return 0
else
WARNING("[my_atom] attempted to add a reagent called ' [reagent] ' which doesn't exist. ([usr])")
if(!no_react)
handle_reactions()
return 1
/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data=null) // Like add_reagent but you can enter a list. Format it like this: list("toxin" = 10, "beer" = 15)
for(var/r_id in list_reagents)
var/amt = list_reagents[r_id]
add_reagent(r_id, amt, data)
/datum/reagents/proc/remove_reagent(reagent, amount, safety)//Added a safety check for the trans_id_to
if(isnull(amount))
amount = INFINITY
if(!isnum(amount))
return 1
for(var/A in reagent_list)
var/datum/reagent/R = A
if (R.id == reagent)
R.volume -= amount
update_total()
if(!safety)//So it does not handle reactions when it need not to
handle_reactions()
my_atom.on_reagent_change()
return 0
return 1
/datum/reagents/proc/has_reagent(reagent, amount = -1)
for(var/_reagent in reagent_list)
var/datum/reagent/R = _reagent
if (R.id == reagent)
if(!amount)
return R
else
if(R.volume >= amount)
return R
else
return 0
return 0
/datum/reagents/proc/get_reagent_amount(reagent)
for(var/_reagent in reagent_list)
var/datum/reagent/R = _reagent
if (R.id == reagent)
return R.volume
return 0
/datum/reagents/proc/get_reagents()
var/list/names = list()
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
names += R.name
return jointext(names, ",")
/datum/reagents/proc/remove_all_type(reagent_type, amount, strict = 0, safety = 1) // Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included.
if(!isnum(amount)) return 1
var/has_removed_reagent = 0
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
var/matches = 0
// Switch between how we check the reagent type
if(strict)
if(R.type == reagent_type)
matches = 1
else
if(istype(R, reagent_type))
matches = 1
// We found a match, proceed to remove the reagent. Keep looping, we might find other reagents of the same type.
if(matches)
// Have our other proc handle removement
has_removed_reagent = remove_reagent(R.id, amount, safety)
return has_removed_reagent
//two helper functions to preserve data across reactions (needed for xenoarch)
/datum/reagents/proc/get_data(reagent_id)
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
if(R.id == reagent_id)
//world << "proffering a data-carrying reagent ([reagent_id])"
return R.data
/datum/reagents/proc/set_data(reagent_id, new_data)
for(var/reagent in reagent_list)
var/datum/reagent/R = reagent
if(R.id == reagent_id)
//world << "reagent data set ([reagent_id])"
R.data = new_data
/datum/reagents/proc/copy_data(datum/reagent/current_reagent)
if(!current_reagent || !current_reagent.data)
return null
if(!istype(current_reagent.data, /list))
return current_reagent.data
var/list/trans_data = current_reagent.data.Copy()
// We do this so that introducing a virus to a blood sample
// doesn't automagically infect all other blood samples from
// the same donor.
//
// Technically we should probably copy all data lists, but
// that could possibly eat up a lot of memory needlessly
// if most data lists are read-only.
if(trans_data["viruses"])
var/list/v = trans_data["viruses"]
trans_data["viruses"] = v.Copy()
return trans_data
/datum/reagents/proc/get_reagent(type)
. = locate(type) in reagent_list
///////////////////////////////////////////////////////////////////////////////////
// Convenience proc to create a reagents holder for an atom
// Max vol is maximum volume of holder
/atom/proc/create_reagents(max_vol)
if(reagents)
qdel(reagents)
reagents = new/datum/reagents(max_vol)
reagents.my_atom = src
@@ -0,0 +1,361 @@
/obj/machinery/chem_dispenser
name = "chem dispenser"
desc = "Creates and dispenses chemicals."
density = 1
anchored = 1
icon = 'icons/obj/chemical.dmi'
icon_state = "dispenser"
use_power = 1
idle_power_usage = 40
interact_offline = 1
var/energy = 100
var/max_energy = 100
var/amount = 30
var/recharged = 0
var/recharge_delay = 5
var/image/icon_beaker = null
var/obj/item/weapon/reagent_containers/beaker = null
var/list/dispensable_reagents = list(
"hydrogen",
"lithium",
"carbon",
"nitrogen",
"oxygen",
"fluorine",
"sodium",
"aluminium",
"silicon",
"phosphorus",
"sulfur",
"chlorine",
"potassium",
"iron",
"copper",
"mercury",
"radium",
"water",
"ethanol",
"sugar",
"sacid",
"welding_fuel",
"silver",
"iodine",
"bromine",
"stable_plasma"
)
var/list/emagged_reagents = list(
"space_drugs",
"morphine",
"carpotoxin",
"mine_salve",
"toxin"
)
/obj/machinery/chem_dispenser/New()
..()
recharge()
dispensable_reagents = sortList(dispensable_reagents)
/obj/machinery/chem_dispenser/process()
if(recharged < 0)
recharge()
recharged = recharge_delay
else
recharged -= 1
/obj/machinery/chem_dispenser/proc/recharge()
if(stat & (BROKEN|NOPOWER)) return
var/addenergy = 1
var/oldenergy = energy
energy = min(energy + addenergy, max_energy)
if(energy != oldenergy)
use_power(2500)
/obj/machinery/chem_dispenser/emag_act(mob/user)
if(emagged)
user << "<span class='warning'>\The [src] has no functional safeties to emag.</span>"
return
user << "<span class='notice'>You short out \the [src]'s safeties.</span>"
dispensable_reagents |= emagged_reagents//add the emagged reagents to the dispensable ones
emagged = 1
/obj/machinery/chem_dispenser/ex_act(severity, target)
if(severity < 3)
..()
/obj/machinery/chem_dispenser/blob_act(obj/effect/blob/B)
if(prob(50))
qdel(src)
/obj/machinery/chem_dispenser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "chem_dispenser", name, 550, 550, master_ui, state)
ui.open()
/obj/machinery/chem_dispenser/ui_data()
var/data = list()
data["amount"] = amount
data["energy"] = energy
data["maxEnergy"] = max_energy
data["isBeakerLoaded"] = beaker ? 1 : 0
var beakerContents[0]
var beakerCurrentVolume = 0
if(beaker && beaker.reagents && beaker.reagents.reagent_list.len)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
beakerCurrentVolume += R.volume
data["beakerContents"] = beakerContents
if (beaker)
data["beakerCurrentVolume"] = beakerCurrentVolume
data["beakerMaxVolume"] = beaker.volume
data["beakerTransferAmounts"] = beaker.possible_transfer_amounts
else
data["beakerCurrentVolume"] = null
data["beakerMaxVolume"] = null
data["beakerTransferAmounts"] = null
var chemicals[0]
for(var/re in dispensable_reagents)
var/datum/reagent/temp = chemical_reagents_list[re]
if(temp)
chemicals.Add(list(list("title" = temp.name, "id" = temp.id)))
data["chemicals"] = chemicals
return data
/obj/machinery/chem_dispenser/ui_act(action, params)
if(..())
return
switch(action)
if("amount")
var/target = text2num(params["target"])
if(target in beaker.possible_transfer_amounts)
amount = target
. = TRUE
if("dispense")
var/reagent = params["reagent"]
if(beaker && dispensable_reagents.Find(reagent))
var/datum/reagents/R = beaker.reagents
var/free = R.maximum_volume - R.total_volume
var/actual = min(amount, energy * 10, free)
R.add_reagent(reagent, actual)
energy = max(energy - actual / 10, 0)
. = TRUE
if("remove")
var/amount = text2num(params["amount"])
if(beaker && amount in beaker.possible_transfer_amounts)
beaker.reagents.remove_all(amount)
. = TRUE
if("eject")
if(beaker)
beaker.loc = loc
beaker = null
cut_overlays()
. = TRUE
/obj/machinery/chem_dispenser/attackby(obj/item/I, mob/user, params)
if(default_unfasten_wrench(user, I))
return
if(istype(I, /obj/item/weapon/reagent_containers) && (I.flags & OPENCONTAINER))
var/obj/item/weapon/reagent_containers/B = I
. = 1 //no afterattack
if(beaker)
user << "<span class='warning'>A container is already loaded into the machine!</span>"
return
if(!user.drop_item()) // Can't let go?
return
beaker = B
beaker.loc = src
user << "<span class='notice'>You add \the [B] to the machine.</span>"
if(!icon_beaker)
icon_beaker = image('icons/obj/chemical.dmi', src, "disp_beaker") //randomize beaker overlay position.
icon_beaker.pixel_x = rand(-10,5)
add_overlay(icon_beaker)
else if(user.a_intent != "harm" && !istype(I, /obj/item/weapon/card/emag))
user << "<span class='warning'>You can't load \the [I] into the machine!</span>"
else
return ..()
/obj/machinery/chem_dispenser/constructable
name = "portable chem dispenser"
icon = 'icons/obj/chemical.dmi'
icon_state = "minidispenser"
energy = 10
max_energy = 10
amount = 5
recharge_delay = 30
dispensable_reagents = list()
var/list/dispensable_reagent_tiers = list(
list(
"hydrogen",
"oxygen",
"silicon",
"phosphorus",
"sulfur",
"carbon",
"nitrogen",
"water"
),
list(
"lithium",
"sugar",
"sacid",
"copper",
"mercury",
"sodium",
"iodine",
"bromine"
),
list(
"ethanol",
"chlorine",
"potassium",
"aluminium",
"radium",
"fluorine",
"iron",
"welding_fuel",
"silver",
"stable_plasma"
),
list(
"oil",
"ash",
"acetone",
"saltpetre",
"ammonia",
"diethylamine"
)
)
/obj/machinery/chem_dispenser/constructable/New()
..()
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/chem_dispenser(null)
B.apply_default_parts(src)
/obj/item/weapon/circuitboard/machine/chem_dispenser
name = "circuit board (Portable Chem Dispenser)"
build_path = /obj/machinery/chem_dispenser/constructable
origin_tech = "materials=4;programming=4;plasmatech=4;biotech=3"
req_components = list(
/obj/item/weapon/stock_parts/matter_bin = 2,
/obj/item/weapon/stock_parts/capacitor = 1,
/obj/item/weapon/stock_parts/manipulator = 1,
/obj/item/weapon/stock_parts/console_screen = 1,
/obj/item/weapon/stock_parts/cell = 1)
def_components = list(/obj/item/weapon/stock_parts/cell = /obj/item/weapon/stock_parts/cell/high)
/obj/machinery/chem_dispenser/constructable/RefreshParts()
var/time = 0
var/temp_energy = 0
var/i
for(var/obj/item/weapon/stock_parts/matter_bin/M in component_parts)
temp_energy += M.rating
temp_energy--
max_energy = temp_energy * 5 //max energy = (bin1.rating + bin2.rating - 1) * 5, 5 on lowest 25 on highest
for(var/obj/item/weapon/stock_parts/capacitor/C in component_parts)
time += C.rating
for(var/obj/item/weapon/stock_parts/cell/P in component_parts)
time += round(P.maxcharge, 10000) / 10000
recharge_delay /= time/2 //delay between recharges, double the usual time on lowest 50% less than usual on highest
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
for(i=1, i<=M.rating, i++)
dispensable_reagents |= dispensable_reagent_tiers[i]
dispensable_reagents = sortList(dispensable_reagents)
/obj/machinery/chem_dispenser/constructable/attackby(obj/item/I, mob/user, params)
..()
if(default_deconstruction_screwdriver(user, "minidispenser-o", "minidispenser", I))
return
if(exchange_parts(user, I))
return
if(default_deconstruction_crowbar(I))
return
return ..()
/obj/machinery/chem_dispenser/constructable/deconstruction()
if(beaker)
beaker.loc = loc
beaker = null
/obj/machinery/chem_dispenser/drinks
name = "soda dispenser"
desc = "Contains a large reservoir of soft drinks."
anchored = 1
icon = 'icons/obj/chemical.dmi'
icon_state = "soda_dispenser"
amount = 10
dispensable_reagents = list(
"water",
"ice",
"coffee",
"cream",
"tea",
"icetea",
"cola",
"spacemountainwind",
"dr_gibb",
"space_up",
"tonic",
"sodawater",
"lemon_lime",
"sugar",
"orangejuice",
"limejuice",
"tomatojuice",
"lemonjuice"
)
emagged_reagents = list(
"thirteenloko",
"whiskeycola",
"mindbreaker",
"tirizene"
)
/obj/machinery/chem_dispenser/drinks/beer
name = "booze dispenser"
desc = "Contains a large reservoir of the good stuff."
anchored = 1
icon = 'icons/obj/chemical.dmi'
icon_state = "booze_dispenser"
dispensable_reagents = list(
"beer",
"kahlua",
"whiskey",
"wine",
"vodka",
"gin",
"rum",
"tequila",
"vermouth",
"cognac",
"ale",
"absinthe",
"hcider"
)
emagged_reagents = list(
"ethanol",
"iron",
"minttoxin",
"atomicbomb"
)
/obj/machinery/chem_dispenser/mutagen
name = "mutagen dispenser"
desc = "Creates and dispenses mutagen."
dispensable_reagents = list("mutagen")
emagged_reagents = list("plasma")
@@ -0,0 +1,129 @@
/obj/machinery/chem_heater
name = "chemical heater"
density = 1
anchored = 1
icon = 'icons/obj/chemical.dmi'
icon_state = "mixer0b"
use_power = 1
idle_power_usage = 40
var/obj/item/weapon/reagent_containers/beaker = null
var/target_temperature = 300
var/heater_coefficient = 0.10
var/on = FALSE
/obj/machinery/chem_heater/New()
..()
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/chem_heater(null)
B.apply_default_parts(src)
/obj/item/weapon/circuitboard/machine/chem_heater
name = "circuit board (Chemical Heater)"
build_path = /obj/machinery/chem_heater
origin_tech = "programming=2;engineering=2;biotech=2"
req_components = list(
/obj/item/weapon/stock_parts/micro_laser = 1,
/obj/item/weapon/stock_parts/console_screen = 1)
/obj/machinery/chem_heater/RefreshParts()
heater_coefficient = 0.10
for(var/obj/item/weapon/stock_parts/micro_laser/M in component_parts)
heater_coefficient *= M.rating
/obj/machinery/chem_heater/process()
..()
if(stat & NOPOWER)
return
if(on)
if(beaker)
if(beaker.reagents.chem_temp > target_temperature)
beaker.reagents.chem_temp += min(-1, (target_temperature - beaker.reagents.chem_temp) * heater_coefficient)
if(beaker.reagents.chem_temp < target_temperature)
beaker.reagents.chem_temp += max(1, (target_temperature - beaker.reagents.chem_temp) * heater_coefficient)
beaker.reagents.chem_temp = round(beaker.reagents.chem_temp)
beaker.reagents.handle_reactions()
/obj/machinery/chem_heater/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "mixer0b", "mixer0b", I))
return
if(exchange_parts(user, I))
return
if(default_deconstruction_crowbar(I))
return
if(istype(I, /obj/item/weapon/reagent_containers) && (I.flags & OPENCONTAINER))
. = 1 //no afterattack
if(beaker)
user << "<span class='warning'>A beaker is already loaded into the machine!</span>"
return
if(!user.drop_item())
return
beaker = I
I.loc = src
user << "<span class='notice'>You add the beaker to the machine.</span>"
icon_state = "mixer1b"
return
return ..()
/obj/machinery/chem_heater/deconstruction()
eject_beaker()
/obj/machinery/chem_heater/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "chem_heater", name, 275, 400, master_ui, state)
ui.open()
/obj/machinery/chem_heater/ui_data()
var/data = list()
data["targetTemp"] = target_temperature
data["isActive"] = on
data["isBeakerLoaded"] = beaker ? 1 : 0
data["currentTemp"] = beaker ? beaker.reagents.chem_temp : null
data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null
data["beakerMaxVolume"] = beaker ? beaker.volume : null
var beakerContents[0]
if(beaker)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
data["beakerContents"] = beakerContents
return data
/obj/machinery/chem_heater/ui_act(action, params)
if(..())
return
switch(action)
if("power")
on = !on
. = TRUE
if("temperature")
var/target = params["target"]
var/adjust = text2num(params["adjust"])
if(target == "input")
target = input("New target temperature:", name, target_temperature) as num|null
if(!isnull(target) && !..())
. = TRUE
else if(adjust)
target = target_temperature + adjust
else if(text2num(target) != null)
target = text2num(target)
. = TRUE
if(.)
target_temperature = Clamp(target, 0, 1000)
if("eject")
on = FALSE
eject_beaker()
. = TRUE
/obj/machinery/chem_heater/proc/eject_beaker()
if(beaker)
beaker.loc = get_turf(src)
beaker.reagents.handle_reactions()
beaker = null
icon_state = "mixer0b"
@@ -0,0 +1,324 @@
/obj/machinery/chem_master
name = "ChemMaster 3000"
desc = "Used to seperate chemicals and distribute them in a variety of forms."
density = 1
anchored = 1
icon = 'icons/obj/chemical.dmi'
icon_state = "mixer0"
use_power = 1
idle_power_usage = 20
var/obj/item/weapon/reagent_containers/beaker = null
var/obj/item/weapon/storage/pill_bottle/bottle = null
var/mode = 1
var/condi = 0
var/screen = "home"
var/analyzeVars[0]
var/useramount = 30 // Last used amount
/obj/machinery/chem_master/New()
create_reagents(100)
add_overlay("waitlight")
var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/chem_master(null)
B.apply_default_parts(src)
/obj/item/weapon/circuitboard/machine/chem_master
name = "circuit board (ChemMaster 3000)"
build_path = /obj/machinery/chem_master
origin_tech = "materials=3;programming=2;biotech=3"
req_components = list(
/obj/item/weapon/reagent_containers/glass/beaker = 2,
/obj/item/weapon/stock_parts/manipulator = 1,
/obj/item/weapon/stock_parts/console_screen = 1)
/obj/item/weapon/circuitboard/machine/chem_master/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/screwdriver))
var/new_name = "ChemMaster"
var/new_path = /obj/machinery/chem_master
if(build_path == /obj/machinery/chem_master)
new_name = "CondiMaster"
new_path = /obj/machinery/chem_master/condimaster
build_path = new_path
name = "circuit board ([new_name] 3000)"
user << "<span class='notice'>You change the circuit board setting to \"[new_name]\".</span>"
else
return ..()
/obj/machinery/chem_master/RefreshParts()
reagents.maximum_volume = 0
for(var/obj/item/weapon/reagent_containers/glass/beaker/B in component_parts)
reagents.maximum_volume += B.reagents.maximum_volume
/obj/machinery/chem_master/ex_act(severity, target)
if(severity < 3)
..()
/obj/machinery/chem_master/blob_act(obj/effect/blob/B)
if (prob(50))
qdel(src)
/obj/machinery/chem_master/power_change()
if(powered())
stat &= ~NOPOWER
else
spawn(rand(0, 15))
stat |= NOPOWER
/obj/machinery/chem_master/attackby(obj/item/I, mob/user, params)
if(default_deconstruction_screwdriver(user, "mixer0_nopower", "mixer0", I))
if(beaker)
beaker.loc = src.loc
beaker = null
reagents.clear_reagents()
if(bottle)
bottle.loc = src.loc
bottle = null
return
else if(exchange_parts(user, I))
return
else if(default_deconstruction_crowbar(I))
return
if(default_unfasten_wrench(user, I))
return
if(istype(I, /obj/item/weapon/reagent_containers) && (I.flags & OPENCONTAINER))
. = 1 // no afterattack
if(panel_open)
user << "<span class='warning'>You can't use the [src.name] while its panel is opened!</span>"
return
if(beaker)
user << "<span class='warning'>A container is already loaded in the machine!</span>"
return
if(!user.drop_item())
return
beaker = I
beaker.loc = src
user << "<span class='notice'>You add the beaker to the machine.</span>"
src.updateUsrDialog()
icon_state = "mixer1"
else if(!condi && istype(I, /obj/item/weapon/storage/pill_bottle))
if(bottle)
user << "<span class='warning'>A pill bottle is already loaded into the machine!</span>"
return
if(!user.drop_item())
return
bottle = I
bottle.loc = src
user << "<span class='notice'>You add the pill bottle into the dispenser slot.</span>"
src.updateUsrDialog()
else
return ..()
/obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
datum/tgui/master_ui = null, datum/ui_state/state = default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "chem_master", name, 500, 550, master_ui, state)
ui.open()
/obj/machinery/chem_master/ui_data(mob/user)
var/list/data = list()
data["isBeakerLoaded"] = beaker ? 1 : 0
data["beakerCurrentVolume"] = beaker ? beaker.reagents.total_volume : null
data["beakerMaxVolume"] = beaker ? beaker.volume : null
data["mode"] = mode
data["condi"] = condi
data["screen"] = screen
data["analyzeVars"] = analyzeVars
data["isPillBottleLoaded"] = bottle ? 1 : 0
if(bottle)
data["pillBotContent"] = bottle.contents.len
data["pillBotMaxContent"] = bottle.storage_slots
var beakerContents[0]
if(beaker)
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list...
data["beakerContents"] = beakerContents
var bufferContents[0]
if(reagents.total_volume)
for(var/datum/reagent/N in reagents.reagent_list)
bufferContents.Add(list(list("name" = N.name, "id" = N.id, "volume" = N.volume))) // ^
data["bufferContents"] = bufferContents
return data
/obj/machinery/chem_master/ui_act(action, params)
if(..())
return
switch(action)
if("eject")
if(beaker)
beaker.loc = src.loc
beaker = null
reagents.clear_reagents()
icon_state = "mixer0"
. = TRUE
if("ejectp")
if(bottle)
bottle.loc = src.loc
bottle = null
. = TRUE
if("transferToBuffer")
if(beaker)
var/id = params["id"]
var/amount = text2num(params["amount"])
if (amount > 0)
beaker.reagents.trans_id_to(src, id, amount)
. = TRUE
else if (amount == -1) // -1 means custom amount
useramount = input("Enter the Amount you want to transfer:", name, useramount) as num|null
beaker.reagents.trans_id_to(src, id, useramount)
. = TRUE
if("transferFromBuffer")
var/id = params["id"]
var/amount = text2num(params["amount"])
if (amount > 0)
if(mode)
reagents.trans_id_to(beaker, id, amount)
. = TRUE
else
reagents.remove_reagent(id, amount)
. = TRUE
if("toggleMode")
mode = !mode
. = TRUE
if("createPill")
var/many = params["many"]
if(reagents.total_volume == 0) return
if(!condi)
var/amount = 1
var/vol_each = min(reagents.total_volume, 50)
if(text2num(many))
amount = min(max(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many pills?", amount) as num|null), 0), 10)
if(!amount)
return
vol_each = min(reagents.total_volume / amount, 50)
var/name = stripped_input(usr,"Name:","Name your pill!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
if(!name || !reagents.total_volume)
return
var/obj/item/weapon/reagent_containers/pill/P
for(var/i = 0; i < amount; i++)
if(bottle && bottle.contents.len < bottle.storage_slots)
P = new/obj/item/weapon/reagent_containers/pill(bottle)
else
P = new/obj/item/weapon/reagent_containers/pill(src.loc)
P.name = trim("[name] pill")
P.pixel_x = rand(-7, 7) //random position
P.pixel_y = rand(-7, 7)
reagents.trans_to(P,vol_each)
else
var/name = stripped_input(usr, "Name:", "Name your pack!", reagents.get_master_reagent_name(), MAX_NAME_LEN)
if(!name || !reagents.total_volume)
return
var/obj/item/weapon/reagent_containers/food/condiment/pack/P = new/obj/item/weapon/reagent_containers/food/condiment/pack(src.loc)
P.originalname = name
P.name = trim("[name] pack")
P.desc = "A small condiment pack. The label says it contains [name]."
reagents.trans_to(P,10)
. = TRUE
if("createPatch")
var/many = params["many"]
if(reagents.total_volume == 0) return
var/amount = 1
var/vol_each = min(reagents.total_volume, 40)
if(text2num(many))
amount = min(max(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many patches?", amount) as num|null), 0), 10)
if(!amount)
return
vol_each = min(reagents.total_volume / amount, 40)
var/name = stripped_input(usr,"Name:","Name your patch!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
if(!name || !reagents.total_volume)
return
var/obj/item/weapon/reagent_containers/pill/P
for(var/i = 0; i < amount; i++)
P = new/obj/item/weapon/reagent_containers/pill/patch(src.loc)
P.name = trim("[name] patch")
P.pixel_x = rand(-7, 7) //random position
P.pixel_y = rand(-7, 7)
reagents.trans_to(P,vol_each)
. = TRUE
if("createBottle")
var/name = stripped_input(usr, "Name:","Name your bottle!", (reagents.total_volume ? reagents.get_master_reagent_name() : " "), MAX_NAME_LEN)
if(!name)
return
var/obj/item/weapon/reagent_containers/P
if(condi)
var/obj/item/weapon/reagent_containers/food/condiment/C = new(src.loc)
C.originalname = name
P = C
else
P = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
P.pixel_x = rand(-7, 7) //random position
P.pixel_y = rand(-7, 7)
P.name = trim("[name] bottle")
reagents.trans_to(P, P.volume)
. = TRUE
if("analyze")
var/datum/reagent/R = chemical_reagents_list[params["id"]]
if(R)
var/state = "Unknown"
if(initial(R.reagent_state) == 1)
state = "Solid"
else if(initial(R.reagent_state) == 2)
state = "Liquid"
else if(initial(R.reagent_state) == 3)
state = "Gas"
var/const/P = 3 //The number of seconds between life ticks
var/T = initial(R.metabolization_rate) * (60 / P)
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
screen = "analyze"
return
if("goScreen")
screen = params["screen"]
. = TRUE
/obj/machinery/chem_master/proc/isgoodnumber(num)
if(isnum(num))
if(num > 200)
num = 200
else if(num < 0)
num = 0
else
num = round(num)
return num
else
return 0
/obj/machinery/chem_master/condimaster
name = "CondiMaster 3000"
desc = "Used to create condiments and other cooking supplies."
condi = 1
/obj/item/weapon/circuitboard/machine/chem_master/condi
name = "circuit board (CondiMaster 3000)"
build_path = /obj/machinery/chem_master/condimaster
@@ -0,0 +1,290 @@
/obj/machinery/computer/pandemic
name = "PanD.E.M.I.C 2200"
desc = "Used to work with viruses."
density = 1
anchored = 1
icon = 'icons/obj/chemical.dmi'
icon_state = "mixer0"
circuit = /obj/item/weapon/circuitboard/computer/pandemic
use_power = 1
idle_power_usage = 20
var/temp_html = ""
var/wait = null
var/obj/item/weapon/reagent_containers/beaker = null
/obj/machinery/computer/pandemic/New()
..()
update_icon()
/obj/machinery/computer/pandemic/proc/GetVirusByIndex(index)
if(beaker && beaker.reagents)
if(beaker.reagents.reagent_list.len)
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
if(BL)
if(BL.data && BL.data["viruses"])
var/list/viruses = BL.data["viruses"]
return viruses[index]
return null
/obj/machinery/computer/pandemic/proc/GetResistancesByIndex(index)
if(beaker && beaker.reagents)
if(beaker.reagents.reagent_list.len)
var/datum/reagent/blood/BL = locate() in beaker.reagents.reagent_list
if(BL)
if(BL.data && BL.data["resistances"])
var/list/resistances = BL.data["resistances"]
return resistances[index]
return null
/obj/machinery/computer/pandemic/proc/GetVirusTypeByIndex(index)
var/datum/disease/D = GetVirusByIndex(index)
if(D)
return D.GetDiseaseID()
return null
/obj/machinery/computer/pandemic/proc/replicator_cooldown(waittime)
wait = 1
update_icon()
spawn(waittime)
src.wait = null
update_icon()
playsound(src.loc, 'sound/machines/ping.ogg', 30, 1)
/obj/machinery/computer/pandemic/update_icon()
if(stat & BROKEN)
icon_state = (beaker ? "mixer1_b" : "mixer0_b")
return
icon_state = "mixer[(beaker)?"1":"0"][(powered()) ? "" : "_nopower"]"
if(wait)
cut_overlays()
else
add_overlay("waitlight")
/obj/machinery/computer/pandemic/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
if(!beaker) return
if (href_list["create_vaccine"])
if(!src.wait)
var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
if(B)
B.pixel_x = rand(-3, 3)
B.pixel_y = rand(-3, 3)
var/path = GetResistancesByIndex(text2num(href_list["create_vaccine"]))
var/vaccine_type = path
var/vaccine_name = "Unknown"
if(!ispath(vaccine_type))
if(archive_diseases[path])
var/datum/disease/D = archive_diseases[path]
if(D)
vaccine_name = D.name
vaccine_type = path
else if(vaccine_type)
var/datum/disease/D = new vaccine_type(0, null)
if(D)
vaccine_name = D.name
if(vaccine_type)
B.name = "[vaccine_name] vaccine bottle"
B.reagents.add_reagent("vaccine", 15, list(vaccine_type))
replicator_cooldown(200)
else
src.temp_html = "The replicator is not ready yet."
src.updateUsrDialog()
return
else if (href_list["create_virus_culture"])
if(!wait)
var/type = GetVirusTypeByIndex(text2num(href_list["create_virus_culture"]))//the path is received as string - converting
var/datum/disease/D = null
if(!ispath(type))
D = GetVirusByIndex(text2num(href_list["create_virus_culture"]))
var/datum/disease/advance/A = archive_diseases[D.GetDiseaseID()]
if(A)
D = new A.type(0, A)
else if(type)
if(type in diseases) // Make sure this is a disease
D = new type(0, null)
if(!D)
return
var/name = stripped_input(usr,"Name:","Name the culture",D.name,MAX_NAME_LEN)
if(name == null || wait)
return
var/obj/item/weapon/reagent_containers/glass/bottle/B = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
B.icon_state = "bottle3"
B.pixel_x = rand(-3, 3)
B.pixel_y = rand(-3, 3)
replicator_cooldown(50)
var/list/data = list("viruses"=list(D))
B.name = "[name] culture bottle"
B.desc = "A small bottle. Contains [D.agent] culture in synthblood medium."
B.reagents.add_reagent("blood",20,data)
src.updateUsrDialog()
else
src.temp_html = "The replicator is not ready yet."
src.updateUsrDialog()
return
else if (href_list["empty_beaker"])
beaker.reagents.clear_reagents()
src.updateUsrDialog()
return
else if (href_list["eject"])
beaker:loc = src.loc
beaker = null
icon_state = "mixer0"
src.updateUsrDialog()
return
else if(href_list["clear"])
src.temp_html = ""
src.updateUsrDialog()
return
else if(href_list["name_disease"])
var/new_name = stripped_input(usr, "Name the Disease", "New Name", "", MAX_NAME_LEN)
if(!new_name)
return
if(..())
return
var/id = GetVirusTypeByIndex(text2num(href_list["name_disease"]))
if(archive_diseases[id])
var/datum/disease/advance/A = archive_diseases[id]
A.AssignName(new_name)
for(var/datum/disease/advance/AD in SSdisease.processing)
AD.Refresh()
src.updateUsrDialog()
else
usr << browse(null, "window=pandemic")
src.updateUsrDialog()
return
src.add_fingerprint(usr)
return
/obj/machinery/computer/pandemic/attack_hand(mob/user)
if(..())
return
user.set_machine(src)
var/dat = ""
if(src.temp_html)
dat = "[src.temp_html]<BR><BR><A href='?src=\ref[src];clear=1'>Main Menu</A>"
else if(!beaker)
dat += "Please insert beaker.<BR>"
dat += "<A href='?src=\ref[user];mach_close=pandemic'>Close</A>"
else
var/datum/reagents/R = beaker.reagents
var/datum/reagent/blood/Blood = null
for(var/datum/reagent/blood/B in R.reagent_list)
if(B)
Blood = B
break
if(!R.total_volume||!R.reagent_list.len)
dat += "The beaker is empty<BR>"
else if(!Blood)
dat += "No blood sample found in beaker."
else if(!Blood.data)
dat += "No blood data found in beaker."
else
dat += "<h3>Blood sample data:</h3>"
dat += "<b>Blood DNA:</b> [(Blood.data["blood_DNA"]||"none")]<BR>"
dat += "<b>Blood Type:</b> [(Blood.data["blood_type"]||"none")]<BR>"
if(Blood.data["viruses"])
var/list/vir = Blood.data["viruses"]
if(vir.len)
var/i = 0
for(var/datum/disease/D in Blood.data["viruses"])
i++
if(!(D.visibility_flags & HIDDEN_PANDEMIC))
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = D
D = archive_diseases[A.GetDiseaseID()]
if(D && D.name == "Unknown")
dat += "<b><a href='?src=\ref[src];name_disease=[i]'>Name Disease</a></b><BR>"
if(!D)
CRASH("We weren't able to get the advance disease from the archive.")
dat += "<b>Disease Agent:</b> [D?"[D.agent] - <A href='?src=\ref[src];create_virus_culture=[i]'>Create virus culture bottle</A>":"none"]<BR>"
dat += "<b>Common name:</b> [(D.name||"none")]<BR>"
dat += "<b>Description: </b> [(D.desc||"none")]<BR>"
dat += "<b>Spread:</b> [(D.spread_text||"none")]<BR>"
dat += "<b>Possible cure:</b> [(D.cure_text||"none")]<BR><BR>"
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/A = D
dat += "<b>Symptoms:</b> "
var/english_symptoms = list()
for(var/datum/symptom/S in A.symptoms)
english_symptoms += S.name
dat += english_list(english_symptoms)
else
dat += "No detectable virus in the sample."
else
dat += "No detectable virus in the sample."
dat += "<BR><b>Contains antibodies to:</b> "
if(Blood.data["resistances"])
var/list/res = Blood.data["resistances"]
if(res.len)
dat += "<ul>"
var/i = 0
for(var/type in Blood.data["resistances"])
i++
var/disease_name = "Unknown"
if(!ispath(type))
var/datum/disease/advance/A = archive_diseases[type]
if(A)
disease_name = A.name
else
var/datum/disease/D = new type(0, null)
disease_name = D.name
dat += "<li>[disease_name] - <A href='?src=\ref[src];create_vaccine=[i]'>Create vaccine bottle</A></li>"
dat += "</ul><BR>"
else
dat += "nothing<BR>"
else
dat += "nothing<BR>"
dat += "<BR><A href='?src=\ref[src];eject=1'>Eject beaker</A>[((R.total_volume&&R.reagent_list.len) ? "-- <A href='?src=\ref[src];empty_beaker=1'>Empty beaker</A>":"")]<BR>"
dat += "<A href='?src=\ref[user];mach_close=pandemic'>Close</A>"
user << browse("<TITLE>[src.name]</TITLE><BR>[dat]", "window=pandemic;size=575x400")
onclose(user, "pandemic")
return
/obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/reagent_containers) && (I.flags & OPENCONTAINER))
. = 1 //no afterattack
if(stat & (NOPOWER|BROKEN))
return
if(beaker)
user << "<span class='warning'>A beaker is already loaded into the machine!</span>"
return
if(!user.drop_item())
return
beaker = I
beaker.loc = src
user << "<span class='notice'>You add the beaker to the machine.</span>"
src.updateUsrDialog()
icon_state = "mixer1"
else
return ..()
/obj/machinery/computer/pandemic/deconstruction()
if(beaker)
beaker.loc = get_turf(src)
..()
@@ -0,0 +1,415 @@
/obj/machinery/reagentgrinder
name = "All-In-One Grinder"
desc = "Used to grind things up into raw materials."
icon = 'icons/obj/kitchen.dmi'
icon_state = "juicer1"
layer = BELOW_OBJ_LAYER
anchored = 1
use_power = 1
idle_power_usage = 5
active_power_usage = 100
pass_flags = PASSTABLE
var/operating = 0
var/obj/item/weapon/reagent_containers/beaker = null
var/limit = 10
var/list/blend_items = list (
//Sheets
/obj/item/stack/sheet/mineral/plasma = list("plasma" = 20),
/obj/item/stack/sheet/metal = list("iron" = 20),
/obj/item/stack/sheet/plasteel = list("iron" = 20, "plasma" = 20),
/obj/item/stack/sheet/mineral/wood = list("carbon" = 20),
/obj/item/stack/sheet/glass = list("silicon" = 20),
/obj/item/stack/sheet/rglass = list("silicon" = 20, "iron" = 20),
/obj/item/stack/sheet/mineral/uranium = list("uranium" = 20),
/obj/item/stack/sheet/mineral/bananium = list("banana" = 20),
/obj/item/stack/sheet/mineral/silver = list("silver" = 20),
/obj/item/stack/sheet/mineral/gold = list("gold" = 20),
/obj/item/weapon/grown/nettle/basic = list("sacid" = 0),
/obj/item/weapon/grown/nettle/death = list("facid" = 0),
/obj/item/weapon/grown/novaflower = list("capsaicin" = 0, "condensedcapsaicin" = 0),
//Blender Stuff
/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans = list("soymilk" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("ketchup" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5),
/obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5),
/obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0),
/obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5),
//Grinder stuff, but only if dry
/obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0),
//All types that you can put into the grinder to transfer the reagents to the beaker. !Put all recipes above this.!
/obj/item/weapon/reagent_containers/pill = list(),
/obj/item/weapon/reagent_containers/food = list(),
/obj/item/weapon/reagent_containers/honeycomb = list()
)
var/list/juice_items = list (
//Juicer Stuff
/obj/item/weapon/reagent_containers/food/snacks/grown/corn = list("corn_starch" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato = list("tomatojuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/carrot = list("carrotjuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/berries = list("berryjuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/banana = list("banana" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/potato = list("potato" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon = list("lemonjuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange = list("orangejuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime = list("limejuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/watermelon = list("watermelonjuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/watermelonslice = list("watermelonjuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/berries/poison = list("poisonberryjuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/pumpkin = list("pumpkinjuice" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/blumpkin = list("blumpkinjuice" = 0),
)
var/list/dried_items = list(
//Grinder stuff, but only if dry,
/obj/item/weapon/reagent_containers/food/snacks/grown/coffee/robusta = list("coffeepowder" = 0, "morphine" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/coffee = list("coffeepowder" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tea/astra = list("teapowder" = 0, "salglu_solution" = 0),
/obj/item/weapon/reagent_containers/food/snacks/grown/tea = list("teapowder" = 0)
)
var/list/holdingitems = list()
/obj/machinery/reagentgrinder/New()
..()
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
return
/obj/machinery/reagentgrinder/update_icon()
icon_state = "juicer"+num2text(!isnull(beaker))
return
/obj/machinery/reagentgrinder/attackby(obj/item/I, mob/user, params)
if(default_unfasten_wrench(user, I))
return
if (istype(I, /obj/item/weapon/reagent_containers) && (I.flags & OPENCONTAINER) )
if (!beaker)
if(!user.drop_item())
return 1
beaker = I
beaker.loc = src
update_icon()
src.updateUsrDialog()
else
user << "<span class='warning'>There's already a container inside.</span>"
return 1 //no afterattack
if(is_type_in_list(I, dried_items))
if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/grown))
var/obj/item/weapon/reagent_containers/food/snacks/grown/G = I
if(!G.dry)
user << "<span class='warning'>You must dry that first!</span>"
return 1
if(holdingitems && holdingitems.len >= limit)
usr << "The machine cannot hold anymore items."
return 1
//Fill machine with a bag!
if(istype(I, /obj/item/weapon/storage/bag))
var/obj/item/weapon/storage/bag/B = I
for (var/obj/item/weapon/reagent_containers/food/snacks/grown/G in B.contents)
B.remove_from_storage(G, src)
holdingitems += G
if(holdingitems && holdingitems.len >= limit) //Sanity checking so the blender doesn't overfill
user << "<span class='notice'>You fill the All-In-One grinder to the brim.</span>"
break
if(!I.contents.len)
user << "<span class='notice'>You empty the plant bag into the All-In-One grinder.</span>"
src.updateUsrDialog()
return 1
if (!is_type_in_list(I, blend_items) && !is_type_in_list(I, juice_items))
if(user.a_intent == "harm")
return ..()
else
user << "<span class='warning'>Cannot refine into a reagent!</span>"
return 1
if(user.drop_item())
I.loc = src
holdingitems += I
src.updateUsrDialog()
return 0
/obj/machinery/reagentgrinder/attack_paw(mob/user)
return src.attack_hand(user)
/obj/machinery/reagentgrinder/attack_ai(mob/user)
return 0
/obj/machinery/reagentgrinder/attack_hand(mob/user)
user.set_machine(src)
interact(user)
/obj/machinery/reagentgrinder/interact(mob/user) // The microwave Menu
var/is_chamber_empty = 0
var/is_beaker_ready = 0
var/processing_chamber = ""
var/beaker_contents = ""
var/dat = ""
if(!operating)
for (var/obj/item/O in holdingitems)
processing_chamber += "\A [O.name]<BR>"
if (!processing_chamber)
is_chamber_empty = 1
processing_chamber = "Nothing."
if (!beaker)
beaker_contents = "<B>No beaker attached.</B><br>"
else
is_beaker_ready = 1
beaker_contents = "<B>The beaker contains:</B><br>"
var/anything = 0
for(var/datum/reagent/R in beaker.reagents.reagent_list)
anything = 1
beaker_contents += "[R.volume] - [R.name]<br>"
if(!anything)
beaker_contents += "Nothing<br>"
dat = {"
<b>Processing chamber contains:</b><br>
[processing_chamber]<br>
[beaker_contents]<hr>
"}
if (is_beaker_ready && !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>"
if(holdingitems && holdingitems.len > 0)
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>"
else
dat += "Please wait..."
var/datum/browser/popup = new(user, "reagentgrinder", "All-In-One Grinder")
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open(1)
return
/obj/machinery/reagentgrinder/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
if(operating)
updateUsrDialog()
return
switch(href_list["action"])
if ("grind")
grind()
if("juice")
juice()
if("eject")
eject()
if ("detach")
detach()
/obj/machinery/reagentgrinder/proc/detach()
if (usr.stat != 0)
return
if (!beaker)
return
beaker.loc = src.loc
beaker = null
update_icon()
updateUsrDialog()
/obj/machinery/reagentgrinder/proc/eject()
if (usr.stat != 0)
return
if (holdingitems && holdingitems.len == 0)
return
for(var/obj/item/O in holdingitems)
O.loc = src.loc
holdingitems -= O
holdingitems = list()
updateUsrDialog()
/obj/machinery/reagentgrinder/proc/is_allowed(obj/item/weapon/reagent_containers/O)
for (var/i in blend_items)
if(istype(O, i))
return 1
return 0
/obj/machinery/reagentgrinder/proc/get_allowed_by_id(obj/item/O)
for (var/i in blend_items)
if (istype(O, i))
return blend_items[i]
/obj/machinery/reagentgrinder/proc/get_allowed_snack_by_id(obj/item/weapon/reagent_containers/food/snacks/O)
for(var/i in blend_items)
if(istype(O, i))
return blend_items[i]
/obj/machinery/reagentgrinder/proc/get_allowed_juice_by_id(obj/item/weapon/reagent_containers/food/snacks/O)
for(var/i in juice_items)
if(istype(O, i))
return juice_items[i]
/obj/machinery/reagentgrinder/proc/get_grownweapon_amount(obj/item/weapon/grown/O)
if (!istype(O) || !O.seed)
return 5
else if (O.seed.potency == -1)
return 5
else
return round(O.seed.potency)
/obj/machinery/reagentgrinder/proc/get_juice_amount(obj/item/weapon/reagent_containers/food/snacks/grown/O)
if (!istype(O) || !O.seed)
return 5
else if (O.seed.potency == -1)
return 5
else
return round(5*sqrt(O.seed.potency))
/obj/machinery/reagentgrinder/proc/remove_object(obj/item/O)
holdingitems -= O
qdel(O)
/obj/machinery/reagentgrinder/proc/juice()
power_change()
if(stat & (NOPOWER|BROKEN))
return
if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
return
playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1)
var/offset = prob(50) ? -2 : 2
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking
operating = 1
updateUsrDialog()
spawn(50)
pixel_x = initial(pixel_x) //return to its spot after shaking
operating = 0
updateUsrDialog()
//Snacks
for (var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/allowed = get_allowed_juice_by_id(O)
if(isnull(allowed))
break
for (var/r_id in allowed)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
var/amount = get_juice_amount(O)
beaker.reagents.add_reagent(r_id, min(amount, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
remove_object(O)
/obj/machinery/reagentgrinder/proc/grind()
power_change()
if(stat & (NOPOWER|BROKEN))
return
if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
return
playsound(src.loc, 'sound/machines/blender.ogg', 50, 1)
var/offset = prob(50) ? -2 : 2
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking
operating = 1
updateUsrDialog()
spawn(60)
pixel_x = initial(pixel_x) //return to its spot after shaking
operating = 0
updateUsrDialog()
//Snacks and Plants
for (var/obj/item/weapon/reagent_containers/food/snacks/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/allowed = get_allowed_snack_by_id(O)
if(isnull(allowed))
break
for (var/r_id in allowed)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
var/amount = allowed[r_id]
if(amount <= 0)
if(amount == 0)
if (O.reagents != null && O.reagents.has_reagent("nutriment"))
beaker.reagents.add_reagent(r_id, min(O.reagents.get_reagent_amount("nutriment"), space))
O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space))
else
if (O.reagents != null && O.reagents.has_reagent("nutriment"))
beaker.reagents.add_reagent(r_id, min(round(O.reagents.get_reagent_amount("nutriment")*abs(amount)), space))
O.reagents.remove_reagent("nutriment", min(O.reagents.get_reagent_amount("nutriment"), space))
else
O.reagents.trans_id_to(beaker, r_id, min(amount, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
if(O.reagents.reagent_list.len == 0)
remove_object(O)
//Sheets
for (var/obj/item/stack/sheet/O in holdingitems)
var/allowed = get_allowed_by_id(O)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
for(var/i = 1; i <= round(O.amount, 1); i++)
for (var/r_id in allowed)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
var/amount = allowed[r_id]
beaker.reagents.add_reagent(r_id,min(amount, space))
if (space < amount)
break
if (i == round(O.amount, 1))
remove_object(O)
break
//Plants
for (var/obj/item/weapon/grown/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/allowed = get_allowed_by_id(O)
for (var/r_id in allowed)
var/space = beaker.reagents.maximum_volume - beaker.reagents.total_volume
var/amount = allowed[r_id]
if (amount == 0)
if (O.reagents != null && O.reagents.has_reagent(r_id))
beaker.reagents.add_reagent(r_id,min(O.reagents.get_reagent_amount(r_id), space))
else
beaker.reagents.add_reagent(r_id,min(amount, space))
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
remove_object(O)
//Everything else - Transfers reagents from it into beaker
for (var/obj/item/weapon/reagent_containers/O in holdingitems)
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
break
var/amount = O.reagents.total_volume
O.reagents.trans_to(beaker, amount)
if(!O.reagents.total_volume)
remove_object(O)
+270
View File
@@ -0,0 +1,270 @@
/*
NOTE: IF YOU UPDATE THE REAGENT-SYSTEM, ALSO UPDATE THIS README.
Structure: /////////////////// //////////////////////////
// Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents.
/////////////////// //////////////////////////
| |
The object that holds everything. V
reagent_list var (list) A List of datums, each datum is a reagent.
| | |
V V V
reagents (datums) Reagents. I.e. Water , cryoxadone or mercury.
Random important notes:
An objects on_reagent_change will be called every time the objects reagents change.
Useful if you want to update the objects icon etc.
About the Holder:
The holder (reagents datum) is the datum that holds a list of all reagents
currently in the object.It also has all the procs needed to manipulate reagents
remove_any(var/amount)
This proc removes reagents from the holder until the passed amount
is matched. It'll try to remove some of ALL reagents contained.
remove_all(var/amount)
This proc removes reagents from the holder equally.
trans_to(var/obj/target, var/amount)
This proc equally transfers the contents of the holder to another
objects holder. You need to pass it the object (not the holder) you want
to transfer to and the amount you want to transfer. Its return value is the
actual amount transfered (if one of the objects is full/empty)
trans_id_to(var/obj/target, var/reagent, var/amount)
Same as above but only for a specific reagent in the reagent list.
If the specified amount is greater than what is available, it will use
the amount of the reagent that is available. If no reagent exists, returns null.
metabolize(var/mob/M)
This proc is called by the mobs life proc. It simply calls on_mob_life for
all contained reagents. You shouldnt have to use this one directly.
handle_reactions()
This proc check all recipes and, on a match, uses them.
It will also call the recipe's on_reaction proc (for explosions or w/e).
Currently, this proc is automatically called by trans_to.
isolate_reagent(var/reagent)
Pass it a reagent id and it will remove all reagents but that one.
It's that simple.
del_reagent(var/reagent)
Completely remove the reagent with the matching id.
reaction_fire(exposed_temp)
Simply calls the reaction_fire procs of all contained reagents.
update_total()
This one simply updates the total volume of the holder.
(the volume of all reagents added together)
clear_reagents()
This proc removes ALL reagents from the holder.
reaction(var/atom/A, var/method=TOUCH, var/volume_modifier=0)
This proc calls the appropriate reaction procs of the reagents.
I.e. if A is an object, it will call the reagents reaction_obj
proc. The method var is used for reaction on mobs. It simply tells
us if the mob TOUCHed the reagent, if it INGESTed the reagent, if the reagent
was VAPORIZEd on them, if the reagent was INJECTed, or transfered via a PATCH to them.
Since the volume can be checked in a reagents proc, you might want to
use the volume_modifier var to modifiy the passed value without actually
changing the volume of the reagents.
If you're not sure if you need to use this the answer is very most likely 'No'.
You'll want to use this proc whenever an atom first comes in
contact with the reagents of a holder. (in the 'splash' part of a beaker i.e.)
More on the reaction in the reagent part of this readme.
add_reagent(var/reagent, var/amount, var/data)
Attempts to add X of the matching reagent to the holder.
You wont use this much. Mostly in new procs for pre-filled
objects.
remove_reagent(var/reagent, var/amount)
The exact opposite of the add_reagent proc.
has_reagent(var/reagent, var/amount)
Returns 1 if the holder contains this reagent.
Or 0 if not.
If you pass it an amount it will additionally check
if the amount is matched. This is optional.
get_reagent_amount(var/reagent)
Returns the amount of the matching reagent inside the
holder. Returns 0 if the reagent is missing.
Important variables:
total_volume
This variable contains the total volume of all reagents in this holder.
reagent_list
This is a list of all contained reagents. More specifically, references
to the reagent datums.
maximum_volume
This is the maximum volume of the holder.
my_atom
This is the atom the holder is 'in'. Useful if you need to find the location.
(i.e. for explosions)
About Reagents:
Reagents are all the things you can mix and fille in bottles etc. This can be anything from
rejuvs over water to ... iron. Each reagent also has a few procs - i'll explain those below.
reaction_mob(var/mob/M, var/method=TOUCH)
This is called by the holder's reation proc.
This version is only called when the reagent
reacts with a mob. The method var can be either
TOUCH or INGEST. You'll want to put stuff like
acid-facemelting in here.
reaction_obj(var/obj/O)
This is called by the holder's reation proc.
This version is called when the reagents reacts
with an object. You'll want to put stuff like
object melting in here ... or something. i dunno.
reaction_turf(var/turf/T)
This is called by the holder's reation proc.
This version is called when the reagents reacts
with a turf. You'll want to put stuff like extra
slippery floors for lube or something in here.
on_mob_life(var/mob/M)
This proc is called everytime the mobs life proc executes.
This is the place where you put damage for toxins ,
drowsyness for sleep toxins etc etc.
You'll want to call the parents proc by using ..() .
If you dont, the chemical will stay in the mob forever -
unless you write your own piece of code to slowly remove it.
(Should be pretty easy, 1 line of code)
Important variables:
holder
This variable contains a reference to the holder the chemical is 'in'
volume
This is the volume of the reagent.
id
The id of the reagent
name
The name of the reagent.
data
This var can be used for whatever the fuck you want. I used it for the sleep
toxins to make them work slowly instead of instantly. You could also use this
for DNA in a blood reagent or ... well whatever you want.
color
This is a hexadecimal color that represents the reagent outside of containers,
you define it as "#RRGGBB", or, red green blue. You can also define it using the
rgb() proc, which returns a hexadecimal value too. The color is black by default.
A good website for color calculations: http://www.psyclops.com/tools/rgb/
About Recipes:
Recipes are simple datums that contain a list of required reagents and a result.
They also have a proc that is called when the recipe is matched.
on_reaction(var/datum/reagents/holder, var/created_volume)
This proc is called when the recipe is matched.
You'll want to add explosions etc here.
To find the location you'll have to do something
like get_turf(holder.my_atom)
name & id
Should be pretty obvious.
result
This var contains the id of the resulting reagent.
required_reagents
This is a list of ids of the required reagents.
Each id also needs an associated value that gives us the minimum required amount
of that reagent. The handle_reaction proc can detect mutiples of the same recipes
so for most cases you want to set the required amount to 1.
required_catalysts
This is a list of the ids of the required catalysts.
Functionally similar to required_reagents, it is a list of reagents that are required
for the reaction. However, unlike required_reagents, catalysts are NOT consumed.
They mearly have to be present in the container.
result_amount
This is the amount of the resulting reagent this recipe will produce.
I recommend you set this to the total volume of all required reagent.
required_container
The container the recipe has to take place in in order to happen. Leave this blank/null
if you want the reaction to happen anywhere.
required_other
Basically like a reagent's data variable. You can set extra requirements for a
reaction with this.
required_temp
This is the required temperature.
About the Tools:
By default, all atom have a reagents var - but its empty. if you want to use an object for the chem.
system you'll need to add something like this in its new proc:
var/datum/reagents/R = new/datum/reagents(100) <<<<< create a new datum , 100 is the maximum_volume of the new holder datum.
reagents = R <<<<< assign the new datum to the objects reagents var
R.my_atom = src <<<<< set the holders my_atom to src so that we know where we are.
This can also be done by calling a convenience proc:
atom/proc/create_reagents(var/max_volume)
Other important stuff:
amount_per_transfer_from_this var
This var is mostly used by beakers and bottles.
It simply tells us how much to transfer when
'pouring' our reagents into something else.
atom/proc/is_open_container()
Checks atom/var/flags & OPENCONTAINER.
If this returns 1 , you can use syringes, beakers etc
to manipulate the contents of this object.
If it's 0, you'll need to write your own custom reagent
transfer code since you will not be able to use the standard
tools to manipulate it.
*/
/* GOON CHEMS README:
Credit goes to Cogwerks, and all the other goonstation coders
for the original idea and implementation of this over at goonstation.
THE REQUESTED DON'T PORT LIST: IF YOU PORT THESE THE GOONS WILL MURDER US IN OUR SLEEP SO PLEASE DON'T KTHX - Iamgoofball
Any of the Secret Chems
Goon in-joke chems (Eg. Cat Drugs, Hairgrownium)
Liquid Electricity
Rajajajah
*/
+115
View File
@@ -0,0 +1,115 @@
#define SOLID 1
#define LIQUID 2
#define GAS 3
#define REM REAGENTS_EFFECT_MULTIPLIER
//Various reagents
//Toxin & acid reagents
//Hydroponics stuff
/datum/reagent
var/name = "Reagent"
var/id = "reagent"
var/description = ""
var/datum/reagents/holder = null
var/reagent_state = LIQUID
var/list/data
var/current_cycle = 0
var/volume = 0
var/color = "#000000" // rgb: 0, 0, 0
var/can_synth = 1
var/metabolization_rate = REAGENTS_METABOLISM //how fast the reagent is metabolized by the mob
var/overrides_metab = 0
var/overdose_threshold = 0
var/addiction_threshold = 0
var/addiction_stage = 0
var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick.
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
. = ..()
holder = null
/datum/reagent/proc/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
if(!istype(M))
return 0
if(method == VAPOR) //smoke, foam, spray
if(M.reagents)
var/modifier = Clamp((1 - touch_protection), 0, 1)
var/amount = round(reac_volume*modifier, 0.1)
if(amount >= 0.5)
M.reagents.add_reagent(id, amount)
return 1
/datum/reagent/proc/reaction_obj(obj/O, volume)
return
/datum/reagent/proc/reaction_turf(turf/T, volume)
return
/datum/reagent/proc/on_mob_life(mob/living/M)
current_cycle++
holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
return
// Called when this reagent is removed while inside a mob
/datum/reagent/proc/on_mob_delete(mob/M)
return
/datum/reagent/proc/on_move(mob/M)
return
// Called after add_reagents creates a new reagent.
/datum/reagent/proc/on_new(data)
return
// Called when two reagents of the same are mixing.
/datum/reagent/proc/on_merge(data)
return
/datum/reagent/proc/on_update(atom/A)
return
// Called every time reagent containers process.
/datum/reagent/proc/on_tick(data)
return
// Called when the reagent container is hit by an explosion
/datum/reagent/proc/on_ex_act(severity)
return
// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects
/datum/reagent/proc/overdose_process(mob/living/M)
return
/datum/reagent/proc/overdose_start(mob/living/M)
M << "<span class='userdanger'>You feel like you took too much of [name]!</span>"
return
/datum/reagent/proc/addiction_act_stage1(mob/living/M)
if(prob(30))
M << "<span class='notice'>You feel like some [name] right about now.</span>"
return
/datum/reagent/proc/addiction_act_stage2(mob/living/M)
if(prob(30))
M << "<span class='notice'>You feel like you need [name]. You just can't get enough.</span>"
return
/datum/reagent/proc/addiction_act_stage3(mob/living/M)
if(prob(30))
M << "<span class='danger'>You have an intense craving for [name].</span>"
return
/datum/reagent/proc/addiction_act_stage4(mob/living/M)
if(prob(30))
M << "<span class='boldannounce'>You're not feeling good at all! You really need some [name].</span>"
return
/proc/pretty_string_from_reagent_list(var/list/reagent_list)
//Convert reagent list to a printable string for logging etc
var/result = "| "
for (var/datum/reagent/R in reagent_list)
result += "[R.name], [R.volume] | "
return result
@@ -0,0 +1,752 @@
#define ALCOHOL_THRESHOLD_MODIFIER 0.05 //Greater numbers mean that less alcohol has greater intoxication potential
#define ALCOHOL_RATE 0.005 //The rate at which alcohol affects you
////////////// I don't know who made this header before I refactored alcohols but I'm going to fucking strangle them because it was so ugly, holy Christ
// ALCOHOLS //
//////////////
/datum/reagent/consumable/ethanol
name = "Ethanol"
id = "ethanol"
description = "A well-known alcohol with a variety of applications."
color = "#404030" // rgb: 64, 64, 48
nutriment_factor = 0
var/boozepwr = 65 //Higher numbers equal higher hardness, higher hardness equals more intense alcohol poisoning
/*
Boozepwr Chart
Note that all higher effects of alcohol poisoning will inherit effects for smaller amounts (i.e. light poisoning inherts from slight poisoning)
In addition, severe effects won't always trigger unless the drink is poisonously strong
All effects don't start immediately, but rather get worse over time; the rate is affected by the imbiber's alcohol tolerance
0: Non-alcoholic
1-10: Barely classifiable as alcohol - occassional slurring
11-20: Slight alcohol content - slurring
21-30: Below average - imbiber begins to look slightly drunk
31-40: Just below average - no unique effects
41-50: Average - mild disorientation, imbiber begins to look drunk
51-60: Just above average - disorientation, vomiting, imbiber begins to look heavily drunk
61-70: Above average - small chance of blurry vision, imbiber begins to look smashed
71-80: High alcohol content - blurry vision, imbiber completely shitfaced
81-90: Extremely high alcohol content - heavy toxin damage, passing out
91-100: Dangerously toxic - swift death
*/
/datum/reagent/consumable/ethanol/on_mob_life(mob/living/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER)
H.drunkenness = max((H.drunkenness + (sqrt(volume) * boozepwr * ALCOHOL_RATE)), 0) //Volume, power, and server alcohol rate effect how quickly one gets drunk
return ..() || .
/datum/reagent/consumable/ethanol/reaction_obj(obj/O, reac_volume)
if(istype(O,/obj/item/weapon/paper))
var/obj/item/weapon/paper/paperaffected = O
paperaffected.clearpaper()
usr << "<span class='notice'>[paperaffected]'s ink washes away.</span>"
if(istype(O,/obj/item/weapon/book))
if(reac_volume >= 5)
var/obj/item/weapon/book/affectedbook = O
affectedbook.dat = null
usr << "<span class='notice'>Through thorough application, you wash away [affectedbook]'s writing.</span>"
else
usr << "<span class='warning'>The ink smears, but doesn't wash away!</span>"
return
/datum/reagent/consumable/ethanol/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with ethanol isn't quite as good as fuel.
if(!istype(M, /mob/living))
return
if(method == TOUCH || method == VAPOR)
M.adjust_fire_stacks(reac_volume / 15)
return ..()
/datum/reagent/consumable/ethanol/beer
name = "Beer"
id = "beer"
description = "An alcoholic beverage brewed since ancient times on Old Earth. Still popular today."
color = "#664300" // rgb: 102, 67, 0
nutriment_factor = 1 * REAGENTS_METABOLISM
boozepwr = 25
/datum/reagent/consumable/ethanol/beer/green
name = "Green Beer"
id = "greenbeer"
description = "An alcoholic beverage brewed since ancient times on Old Earth. This variety is dyed a festive green."
color = "#A8E61D"
/datum/reagent/consumable/ethanol/beer/green/on_mob_life(mob/living/M)
if(M.color != color)
M.color = color
return ..()
/datum/reagent/consumable/ethanol/beer/green/on_mob_delete(mob/living/M)
M.color = initial(M.color)
/datum/reagent/consumable/ethanol/kahlua
name = "Kahlua"
id = "kahlua"
description = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936!"
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
/datum/reagent/consumable/ethanol/kahlua/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
M.AdjustSleeping(-2, 0)
M.Jitter(5)
return ..()
/datum/reagent/consumable/ethanol/whiskey
name = "Whiskey"
id = "whiskey"
description = "A superb and well-aged single-malt whiskey. Damn."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 75
/datum/reagent/consumable/ethanol/thirteenloko
name = "Thirteen Loko"
id = "thirteenloko"
description = "A potent mixture of caffeine and alcohol."
color = "#102000" // rgb: 16, 32, 0
nutriment_factor = 1 * REAGENTS_METABOLISM
boozepwr = 80
/datum/reagent/consumable/ethanol/thirteenloko/on_mob_life(mob/living/M)
M.drowsyness = max(0,M.drowsyness-7)
M.AdjustSleeping(-2)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
return ..()
/datum/reagent/consumable/ethanol/vodka
name = "Vodka"
id = "vodka"
description = "Number one drink AND fueling choice for Russians worldwide."
color = "#0064C8" // rgb: 0, 100, 200
boozepwr = 65
/datum/reagent/consumable/ethanol/vodka/on_mob_life(mob/living/M)
M.radiation = max(M.radiation-2,0)
return ..()
/datum/reagent/consumable/ethanol/bilk
name = "Bilk"
id = "bilk"
description = "This appears to be beer mixed with milk. Disgusting."
color = "#895C4C" // rgb: 137, 92, 76
nutriment_factor = 2 * REAGENTS_METABOLISM
boozepwr = 15
/datum/reagent/consumable/ethanol/bilk/on_mob_life(mob/living/M)
if(M.getBruteLoss() && prob(10))
M.heal_organ_damage(1,0, 0)
. = 1
return ..() || .
/datum/reagent/consumable/ethanol/threemileisland
name = "Three Mile Island Iced Tea"
id = "threemileisland"
description = "Made for a woman, strong enough for a man."
color = "#666340" // rgb: 102, 99, 64
boozepwr = 10
/datum/reagent/consumable/ethanol/threemileisland/on_mob_life(mob/living/M)
M.set_drugginess(50)
return ..()
/datum/reagent/consumable/ethanol/gin
name = "Gin"
id = "gin"
description = "It's gin. In space. I say, good sir."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
/datum/reagent/consumable/ethanol/rum
name = "Rum"
id = "rum"
description = "Yohoho and all that."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 60
/datum/reagent/consumable/ethanol/tequila
name = "Tequila"
id = "tequila"
description = "A strong and mildly flavoured, Mexican produced spirit. Feeling thirsty, hombre?"
color = "#FFFF91" // rgb: 255, 255, 145
boozepwr = 70
/datum/reagent/consumable/ethanol/vermouth
name = "Vermouth"
id = "vermouth"
description = "You suddenly feel a craving for a martini..."
color = "#91FF91" // rgb: 145, 255, 145
boozepwr = 45
/datum/reagent/consumable/ethanol/wine
name = "Wine"
id = "wine"
description = "An premium alcoholic beverage made from distilled grape juice."
color = "#7E4043" // rgb: 126, 64, 67
boozepwr = 35
/datum/reagent/consumable/ethanol/lizardwine
name = "Lizard wine"
id = "lizardwine"
description = "An alcoholic beverage from Space China, made by infusing lizard tails in ethanol."
color = "#7E4043" // rgb: 126, 64, 67
boozepwr = 45
/datum/reagent/consumable/ethanol/grappa
name = "Grappa"
id = "grappa"
description = "A fine Italian brandy, for when regular wine just isn't alcoholic enough for you."
color = "#F8EBF1"
boozepwr = 45
/datum/reagent/consumable/ethanol/cognac
name = "Cognac"
id = "cognac"
description = "A sweet and strongly alchoholic drink, made after numerous distillations and years of maturing. Classy as fornication."
color = "#AB3C05" // rgb: 171, 60, 5
boozepwr = 75
/datum/reagent/consumable/ethanol/absinthe
name = "Absinthe"
id = "absinthe"
description = "A powerful alcoholic drink. Rumored to cause hallucinations but does not."
color = rgb(10, 206, 0)
boozepwr = 80 //Very strong even by default
/datum/reagent/consumable/ethanol/absinthe/on_mob_life(mob/living/M)
if(prob(10))
M.hallucination += 4 //Reference to the urban myth
..()
/datum/reagent/consumable/ethanol/hooch
name = "Hooch"
id = "hooch"
description = "Either someone's failure at cocktail making or attempt in alchohol production. In any case, do you really want to drink that?"
color = "#664300" // rgb: 102, 67, 0
boozepwr = 100
/datum/reagent/consumable/ethanol/ale
name = "Ale"
id = "ale"
description = "A dark alchoholic beverage made by malted barley and yeast."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 65
/datum/reagent/consumable/ethanol/goldschlager
name = "Goldschlager"
id = "goldschlager"
description = "100 proof cinnamon schnapps, made for alcoholic teen girls on spring break."
color = "#FFFF91" // rgb: 255, 255, 145
boozepwr = 25
/datum/reagent/consumable/ethanol/patron
name = "Patron"
id = "patron"
description = "Tequila with silver in it, a favorite of alcoholic women in the club scene."
color = "#585840" // rgb: 88, 88, 64
boozepwr = 60
/datum/reagent/consumable/ethanol/gintonic
name = "Gin and Tonic"
id = "gintonic"
description = "An all time classic, mild cocktail."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 25
/datum/reagent/consumable/ethanol/cuba_libre
name = "Cuba Libre"
id = "cubalibre"
description = "Rum, mixed with cola. Viva la revolucion."
color = "#3E1B00" // rgb: 62, 27, 0
boozepwr = 50
/datum/reagent/consumable/ethanol/cuba_libre/on_mob_life(mob/living/M)
if(M.mind && M.mind.special_role in list("Revolutionary", "Head Revolutionary")) //Cuba Libre, the traditional drink of revolutions! Heals revolutionaries.
M.adjustBruteLoss(-1, 0)
M.adjustFireLoss(-1, 0)
M.adjustToxLoss(-1, 0)
M.adjustOxyLoss(-5, 0)
. = 1
return ..() || .
/datum/reagent/consumable/ethanol/whiskey_cola
name = "Whiskey Cola"
id = "whiskeycola"
description = "Whiskey, mixed with cola. Surprisingly refreshing."
color = "#3E1B00" // rgb: 62, 27, 0
boozepwr = 70
/datum/reagent/consumable/ethanol/martini
name = "Classic Martini"
id = "martini"
description = "Vermouth with Gin. Not quite how 007 enjoyed it, but still delicious."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 60
/datum/reagent/consumable/ethanol/vodkamartini
name = "Vodka Martini"
id = "vodkamartini"
description = "Vodka with Gin. Not quite how 007 enjoyed it, but still delicious."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 65
/datum/reagent/consumable/ethanol/white_russian
name = "White Russian"
id = "whiterussian"
description = "That's just, like, your opinion, man..."
color = "#A68340" // rgb: 166, 131, 64
boozepwr = 50
/datum/reagent/consumable/ethanol/screwdrivercocktail
name = "Screwdriver"
id = "screwdrivercocktail"
description = "Vodka, mixed with plain ol' orange juice. The result is surprisingly delicious."
color = "#A68310" // rgb: 166, 131, 16
boozepwr = 55
/datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_life(mob/living/M)
if(M.mind && M.mind.assigned_role in list("Station Engineer", "Atmospheric Technician", "Chief Engineer")) //Engineers lose radiation poisoning at a massive rate.
M.radiation = max(M.radiation - 25, 0)
return ..()
/datum/reagent/consumable/ethanol/booger
name = "Booger"
id = "booger"
description = "Ewww..."
color = "#8CFF8C" // rgb: 140, 255, 140
boozepwr = 45
/datum/reagent/consumable/ethanol/bloody_mary
name = "Bloody Mary"
id = "bloodymary"
description = "A strange yet pleasurable mixture made of vodka, tomato and lime juice. Or at least you THINK the red stuff is tomato juice."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 55
/datum/reagent/consumable/ethanol/brave_bull
name = "Brave Bull"
id = "bravebull"
description = "It's just as effective as Dutch-Courage!."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 80
/datum/reagent/consumable/ethanol/brave_bull/on_mob_life(mob/living/M)
if(M.maxHealth == initial(M.maxHealth)) //Brave Bull makes you sturdier, and thus capable of withstanding a tiny bit more punishment.
M.maxHealth += 5
M.health += 5
return ..()
/datum/reagent/consumable/ethanol/brave_bull/on_mob_delete(mob/living/M)
if(M.maxHealth != initial(M.maxHealth))
M.maxHealth = initial(M.maxHealth)
/datum/reagent/consumable/ethanol/tequila_sunrise
name = "Tequila Sunrise"
id = "tequilasunrise"
description = "Tequila and orange juice. Much like a Screwdriver, only Mexican~"
color = "#FFE48C" // rgb: 255, 228, 140
boozepwr = 45
/datum/reagent/consumable/ethanol/toxins_special
name = "Toxins Special"
id = "toxinsspecial"
description = "This thing is ON FIRE! CALL THE DAMN SHUTTLE!"
color = "#664300" // rgb: 102, 67, 0
boozepwr = 25
/datum/reagent/consumable/ethanol/toxins_special/on_mob_life(var/mob/living/M as mob)
if (M.bodytemperature < 330)
M.bodytemperature = min(330, M.bodytemperature + (15 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055
return ..()
/datum/reagent/consumable/ethanol/beepsky_smash
name = "Beepsky Smash"
id = "beepskysmash"
description = "Drink this and prepare for the LAW."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 90 //THE FIST OF THE LAW IS STRONG AND HARD
metabolization_rate = 0.8
/datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/M)
M.Stun(2, 0)
return ..()
/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
/datum/reagent/consumable/ethanol/manly_dorf
name = "The Manly Dorf"
id = "manlydorf"
description = "Beer and Ale, brought together in a delicious mix. Intended for true men only."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 100 //For the manly only
/datum/reagent/consumable/ethanol/longislandicedtea
name = "Long Island Iced Tea"
id = "longislandicedtea"
description = "The liquor cabinet, brought together in a delicious mix. Intended for middle-aged alcoholic women only."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
/datum/reagent/consumable/ethanol/moonshine
name = "Moonshine"
id = "moonshine"
description = "You've really hit rock bottom now... your liver packed its bags and left last night."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 95
/datum/reagent/consumable/ethanol/b52
name = "B-52"
id = "b52"
description = "Coffee, Irish Cream, and cognac. You will get bombed."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 85
/datum/reagent/consumable/ethanol/irishcoffee
name = "Irish Coffee"
id = "irishcoffee"
description = "Coffee, and alcohol. More fun than a Mimosa to drink in the morning."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
/datum/reagent/consumable/ethanol/margarita
name = "Margarita"
id = "margarita"
description = "On the rocks with salt on the rim. Arriba~!"
color = "#8CFF8C" // rgb: 140, 255, 140
boozepwr = 35
/datum/reagent/consumable/ethanol/black_russian
name = "Black Russian"
id = "blackrussian"
description = "For the lactose-intolerant. Still as classy as a White Russian."
color = "#360000" // rgb: 54, 0, 0
boozepwr = 70
/datum/reagent/consumable/ethanol/manhattan
name = "Manhattan"
id = "manhattan"
description = "The Detective's undercover drink of choice. He never could stomach gin..."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 30
/datum/reagent/consumable/ethanol/manhattan_proj
name = "Manhattan Project"
id = "manhattan_proj"
description = "A scientist's drink of choice, for pondering ways to blow up the station."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
/datum/reagent/consumable/ethanol/manhattan_proj/on_mob_life(mob/living/M)
M.set_drugginess(30)
return ..()
/datum/reagent/consumable/ethanol/whiskeysoda
name = "Whiskey Soda"
id = "whiskeysoda"
description = "For the more refined griffon."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 70
/datum/reagent/consumable/ethanol/antifreeze
name = "Anti-freeze"
id = "antifreeze"
description = "The ultimate refreshment. Not what it sounds like."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
/datum/reagent/consumable/ethanol/antifreeze/on_mob_life(mob/living/M)
if (M.bodytemperature < 330)
M.bodytemperature = min(330, M.bodytemperature + (20 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055
return ..()
/datum/reagent/consumable/ethanol/barefoot
name = "Barefoot"
id = "barefoot"
description = "Barefoot and pregnant."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
/datum/reagent/consumable/ethanol/barefoot/on_mob_life(mob/living/M)
if(ishuman(M)) //Barefoot causes the imbiber to quickly regenerate brute trauma if they're not wearing shoes.
var/mob/living/carbon/human/H = M
if(!H.shoes)
H.adjustBruteLoss(-3, 0)
. = 1
return ..() || .
/datum/reagent/consumable/ethanol/snowwhite
name = "Snow White"
id = "snowwhite"
description = "A cold refreshment."
color = "#FFFFFF" // rgb: 255, 255, 255
boozepwr = 35
/datum/reagent/consumable/ethanol/demonsblood //Prevents the imbiber from being dragged into a pool of blood by a slaughter demon.
name = "Demon's Blood"
id = "demonsblood"
description = "AHHHH!!!!"
color = "#820000" // rgb: 130, 0, 0
boozepwr = 75
/datum/reagent/consumable/ethanol/devilskiss //If eaten by a slaughter demon, the demon will regret it.
name = "Devil's Kiss"
id = "devilskiss"
description = "Creepy time!"
color = "#A68310" // rgb: 166, 131, 16
boozepwr = 70
/datum/reagent/consumable/ethanol/vodkatonic
name = "Vodka and Tonic"
id = "vodkatonic"
description = "For when a gin and tonic isn't Russian enough."
color = "#0064C8" // rgb: 0, 100, 200
boozepwr = 70
/datum/reagent/consumable/ethanol/ginfizz
name = "Gin Fizz"
id = "ginfizz"
description = "Refreshingly lemony, deliciously dry."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
/datum/reagent/consumable/ethanol/bahama_mama
name = "Bahama Mama"
id = "bahama_mama"
description = "Tropical cocktail."
color = "#FF7F3B" // rgb: 255, 127, 59
boozepwr = 35
/datum/reagent/consumable/ethanol/singulo
name = "Singulo"
id = "singulo"
description = "A blue-space beverage!"
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 35
/datum/reagent/consumable/ethanol/sbiten
name = "Sbiten"
id = "sbiten"
description = "A spicy Vodka! Might be a little hot for the little guys!"
color = "#664300" // rgb: 102, 67, 0
boozepwr = 70
/datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/M)
if (M.bodytemperature < 360)
M.bodytemperature = min(360, M.bodytemperature + (50 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055
return ..()
/datum/reagent/consumable/ethanol/red_mead
name = "Red Mead"
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
/datum/reagent/consumable/ethanol/mead
name = "Mead"
id = "mead"
description = "A Viking drink, though a cheap one."
color = "#664300" // rgb: 102, 67, 0
nutriment_factor = 1 * REAGENTS_METABOLISM
boozepwr = 50
/datum/reagent/consumable/ethanol/iced_beer
name = "Iced Beer"
id = "iced_beer"
description = "A beer which is so cold the air around it freezes."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 15
/datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/M)
if(M.bodytemperature > 270)
M.bodytemperature = max(270, M.bodytemperature - (20 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055
return ..()
/datum/reagent/consumable/ethanol/grog
name = "Grog"
id = "grog"
description = "Watered down rum, Nanotrasen approves!"
color = "#664300" // rgb: 102, 67, 0
boozepwr = 1 //Basically nothing
/datum/reagent/consumable/ethanol/aloe
name = "Aloe"
id = "aloe"
description = "So very, very, very good."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
/datum/reagent/consumable/ethanol/andalusia
name = "Andalusia"
id = "andalusia"
description = "A nice, strange named drink."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 40
/datum/reagent/consumable/ethanol/alliescocktail
name = "Allies Cocktail"
id = "alliescocktail"
description = "A drink made from your allies. Not as sweet as those made from your enemies."
color = "#664300" // rgb: 102, 67, 0
boozepwr = 45
/datum/reagent/consumable/ethanol/acid_spit
name = "Acid Spit"
id = "acidspit"
description = "A drink for the daring, can be deadly if incorrectly prepared!"
color = "#365000" // rgb: 54, 80, 0
boozepwr = 80
/datum/reagent/consumable/ethanol/amasec
name = "Amasec"
id = "amasec"
description = "Official drink of the Nanotrasen Gun-Club!"
color = "#664300" // rgb: 102, 67, 0
boozepwr = 35
/datum/reagent/consumable/ethanol/changelingsting
name = "Changeling Sting"
id = "changelingsting"
description = "You take a tiny sip and feel a burning sensation..."
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 95
/datum/reagent/consumable/ethanol/changelingsting/on_mob_life(mob/living/M)
if(M.mind && M.mind.changeling) //Changeling Sting assists in the recharging of changeling chemicals.
M.mind.changeling.chem_charges += metabolization_rate
M.mind.changeling.chem_charges = Clamp(M.mind.changeling.chem_charges, 0, M.mind.changeling.chem_storage)
return ..()
/datum/reagent/consumable/ethanol/irishcarbomb
name = "Irish Car Bomb"
id = "irishcarbomb"
description = "Mmm, tastes like chocolate cake..."
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 25
/datum/reagent/consumable/ethanol/syndicatebomb
name = "Syndicate Bomb"
id = "syndicatebomb"
description = "Tastes like terrorism!"
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 90
/datum/reagent/consumable/ethanol/syndicatebomb/on_mob_life(mob/living/M)
if(prob(5))
playsound(get_turf(M), 'sound/effects/explosionfar.ogg', 100, 1)
return ..()
/datum/reagent/consumable/ethanol/erikasurprise
name = "Erika Surprise"
id = "erikasurprise"
description = "The surprise is, it's green!"
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 35
/datum/reagent/consumable/ethanol/driestmartini
name = "Driest Martini"
id = "driestmartini"
description = "Only for the experienced. You think you see sand floating in the glass."
nutriment_factor = 1 * REAGENTS_METABOLISM
color = "#2E6671" // rgb: 46, 102, 113
boozepwr = 65
/datum/reagent/consumable/ethanol/bananahonk
name = "Banana Mama"
id = "bananahonk"
description = "A drink from Clown Heaven."
nutriment_factor = 1 * REAGENTS_METABOLISM
color = "#FFFF91" // rgb: 255, 255, 140
boozepwr = 60
/datum/reagent/consumable/ethanol/bananahonk/on_mob_life(mob/living/M)
if( ( istype(M, /mob/living/carbon/human) && M.job in list("Clown") ) || istype(M, /mob/living/carbon/monkey) )
M.heal_organ_damage(1,1, 0)
. = 1
return ..() || .
/datum/reagent/consumable/ethanol/silencer
name = "Silencer"
id = "silencer"
description = "A drink from Mime Heaven."
nutriment_factor = 1 * REAGENTS_METABOLISM
color = "#664300" // rgb: 102, 67, 0
boozepwr = 59 //Proof that clowns are better than mimes right here
/datum/reagent/consumable/ethanol/silencer/on_mob_life(mob/living/M)
if(istype(M, /mob/living/carbon/human) && M.job in list("Mime"))
M.heal_organ_damage(1,1)
. = 1
return ..() || .
/datum/reagent/consumable/ethanol/drunkenblumpkin
name = "Drunken Blumpkin"
id = "drunkenblumpkin"
description = "A weird mix of whiskey and blumpkin juice."
color = "#1EA0FF" // rgb: 102, 67, 0
boozepwr = 50
/datum/reagent/consumable/ethanol/whiskey_sour //Requested since we had whiskey cola and soda but not sour.
name = "Whiskey Sour"
id = "whiskey_sour"
description = "Lemon juice/whiskey/sugar mixture. Moderate alcohol content."
color = rgb(255, 201, 49)
boozepwr = 35
/datum/reagent/consumable/ethanol/hcider
name = "Hard Cider"
id = "hcider"
description = "Apple juice, for adults."
color = "#CD6839"
nutriment_factor = 1 * REAGENTS_METABOLISM
boozepwr = 25
/datum/reagent/consumable/ethanol/fetching_fizz //A reference to one of my favorite games of all time. Pulls nearby ores to the imbiber!
name = "Fetching Fizz"
id = "fetching_fizz"
description = "Whiskey sour/iron/uranium mixture resulting in highly magnetic slurry. Mild alcohol content." //Requires no alcohol to make but has alcohol anyway because ~magic~
color = rgb(255, 91, 15)
boozepwr = 10
metabolization_rate = 0.1 * REAGENTS_METABOLISM
/datum/reagent/consumable/ethanol/fetching_fizz/on_mob_life(mob/living/M)
for(var/obj/item/weapon/ore/O in orange(3, M))
step_towards(O, get_turf(M))
return ..()
//Another reference. Heals those in critical condition extremely quickly.
/datum/reagent/consumable/ethanol/hearty_punch
name = "Hearty Punch"
id = "hearty_punch"
description = "Brave bull/syndicate bomb/absinthe mixture resulting in an energizing beverage. Mild alcohol content."
color = rgb(140, 0, 0)
boozepwr = 10
metabolization_rate = 0.1 * REAGENTS_METABOLISM
/datum/reagent/consumable/ethanol/hearty_punch/on_mob_life(mob/living/M)
if(M.stat == UNCONSCIOUS && M.health <= 0)
M.adjustBruteLoss(-7, 0)
M.adjustFireLoss(-7, 0)
M.adjustToxLoss(-7, 0)
M.adjustOxyLoss(-7, 0)
M.adjustCloneLoss(-7, 0)
. = 1
return ..() || .
/datum/reagent/consumable/ethanol/bacchus_blessing //An EXTREMELY powerful drink. Smashed in seconds, dead in minutes.
name = "Bacchus' Blessing"
id = "bacchus_blessing"
description = "Unidentifiable mixture. Unmeasurably high alcohol content."
color = rgb(51, 19, 3) //Sickly brown
boozepwr = 300 //I warned you
@@ -0,0 +1,666 @@
// These can only be applied by blobs. They are what blobs are made out of.
/datum/reagent/blob
name = "Unknown"
description = "shouldn't exist and you should adminhelp immediately."
color = "#FFFFFF"
var/complementary_color = "#000000" //a color that's complementary to the normal blob color
var/shortdesc = null //just damage and on_mob effects, doesn't include special, blob-tile only effects
var/analyzerdescdamage = "Unknown. Report this bug to a coder, or just adminhelp."
var/analyzerdesceffect = "N/A"
var/blobbernaut_message = "slams" //blobbernaut attack verb
var/message = "The blob strikes you" //message sent to any mob hit by the blob
var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt
/datum/reagent/blob/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
return 0 //the dead, and blob mobs, don't cause reactions
return round(reac_volume * min(1.5 - touch_protection, 1), 0.1) //full touch protection means 50% volume, any prot below 0.5 means 100% volume.
/datum/reagent/blob/proc/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause) //when the blob takes damage, do this
return damage
/datum/reagent/blob/proc/death_reaction(obj/effect/blob/B, cause) //when a blob dies, do this
return
/datum/reagent/blob/proc/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T) //when the blob expands, do this
return
/datum/reagent/blob/proc/tesla_reaction(obj/effect/blob/B, power) //when the blob is hit by a tesla bolt, do this
return 1 //return 0 to ignore damage
/datum/reagent/blob/proc/extinguish_reaction(obj/effect/blob/B) //when the blob is hit with water, do this
return
/datum/reagent/blob/proc/emp_reaction(obj/effect/blob/B, severity) //when the blob is hit with an emp, do this
return
//does low toxin damage, but creates fragile spores when expanding or killed by weak attacks
/datum/reagent/blob/sporing_pods
name = "Sporing Pods"
id = "sporing_pods"
description = "will do very low toxin damage and produce fragile spores when killed or on expanding."
shortdesc = "will do very low toxin damage."
analyzerdescdamage = "Does very low toxin damage."
analyzerdesceffect = "Produces spores when expanding and when killed."
color = "#E88D5D"
complementary_color = "#5DB8E8"
message_living = ", and you feel sick"
/datum/reagent/blob/sporing_pods/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
M.apply_damage(0.2*reac_volume, TOX)
/datum/reagent/blob/sporing_pods/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
if(!isnull(cause) && damage <= 20 && original_health - damage <= 0 && prob(30)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 30% chance of a shitty spore.
B.visible_message("<span class='warning'><b>A spore floats free of the blob!</b></span>")
var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc)
BS.overmind = B.overmind
BS.update_icons()
B.overmind.blob_mobs.Add(BS)
return ..()
/datum/reagent/blob/sporing_pods/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
if(prob(12))
var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(T)
BS.overmind = B.overmind
BS.update_icons()
newB.overmind.blob_mobs.Add(BS)
//does brute damage but can replicate when damaged and has a chance of expanding again
/datum/reagent/blob/replicating_foam
name = "Replicating Foam"
id = "replicating_foam"
description = "will do medium brute damage, take increased brute damage, and expand when burned."
shortdesc = "will do medium brute damage."
analyzerdescdamage = "Does medium brute damage."
analyzerdesceffect = "Expands when attacked with burn damage, will occasionally expand again when expanding, and is fragile to brute damage."
color = "#7B5A57"
complementary_color = "#57787B"
/datum/reagent/blob/replicating_foam/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
M.apply_damage(0.5*reac_volume, BRUTE)
/datum/reagent/blob/replicating_foam/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
var/effectivedamage = damage
if(damage_type == BRUTE)
effectivedamage = damage * 2
if(damage_type == BURN && effectivedamage > 0 && original_health - effectivedamage > 0 && prob(75))
var/obj/effect/blob/newB = B.expand(null, null, 0)
if(newB)
newB.health = original_health - effectivedamage
newB.check_health(cause)
newB.update_icon()
return effectivedamage
/datum/reagent/blob/replicating_foam/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
if(prob(30))
newB.expand() //do it again!
//does brute damage, shifts away when damaged
/datum/reagent/blob/shifting_fragments
name = "Shifting Fragments"
id = "shifting_fragments"
description = "will do medium brute damage and shift away from damage."
shortdesc = "will do medium brute damage."
analyzerdescdamage = "Does medium brute damage."
analyzerdesceffect = "When attacked, may shift away from the attacker."
color = "#C8963C"
complementary_color = "#3C6EC8"
/datum/reagent/blob/shifting_fragments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
M.apply_damage(0.6*reac_volume, BRUTE)
/datum/reagent/blob/shifting_fragments/expand_reaction(obj/effect/blob/B, obj/effect/blob/newB, turf/T)
if(istype(B, /obj/effect/blob/normal) || (istype(B, /obj/effect/blob/shield) && prob(20)))
newB.forceMove(get_turf(B))
B.forceMove(T)
/datum/reagent/blob/shifting_fragments/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
if(cause && damage > 0 && original_health - damage > 0 && prob(40))
var/list/blobstopick = list()
for(var/obj/effect/blob/OB in orange(1, B))
if((istype(OB, /obj/effect/blob/normal) || istype(OB, /obj/effect/blob/shield)) && OB.overmind && OB.overmind.blob_reagent_datum.id == B.overmind.blob_reagent_datum.id)
blobstopick += OB //as long as the blob picked is valid; ie, a normal or shield blob that has the same chemical as we do, we can swap with it
if(blobstopick.len)
var/obj/effect/blob/targeted = pick(blobstopick) //randomize the blob chosen, because otherwise it'd tend to the lower left
var/turf/T = get_turf(targeted)
targeted.forceMove(get_turf(B))
B.forceMove(T) //swap the blobs
return ..()
//does low burn and a lot of stamina damage, immune to tesla bolts, weak to EMP
/datum/reagent/blob/energized_fibers
name = "Energized Fibers"
id = "energized_fibers"
description = "will do low burn and high stamina damage and conduct electricity, but is weak to EMPs."
shortdesc = "will do low burn and high stamina damage."
analyzerdescdamage = "Does low burn damage and massively drains stamina."
analyzerdesceffect = "Is immune to electricity and will easily conduct it, but is weak to EMPs."
color = "#EFD65A"
complementary_color = "#5A73EF"
blobbernaut_message = "shocks"
message_living = ", and you feel a strong tingling sensation"
/datum/reagent/blob/energized_fibers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
M.apply_damage(0.6*reac_volume, BURN)
if(M)
M.adjustStaminaLoss(0.6*reac_volume)
/datum/reagent/blob/energized_fibers/tesla_reaction(obj/effect/blob/B, power)
return 0
/datum/reagent/blob/energized_fibers/emp_reaction(obj/effect/blob/B, severity)
var/damage = rand(30, 50) - severity * rand(10, 15)
B.take_damage(damage, BURN)
//sets you on fire, does burn damage, weak to water
/datum/reagent/blob/boiling_oil
name = "Boiling Oil"
id = "boiling_oil"
description = "will do medium burn damage and set targets on fire, but is weak to water."
shortdesc = "will do medium burn damage and set targets on fire."
analyzerdescdamage = "Does medium burn damage and sets targets on fire."
analyzerdesceffect = "Takes damage from water and other extinguishing liquids."
color = "#B68D00"
complementary_color = "#0029B6"
blobbernaut_message = "splashes"
message = "The blob splashes you with burning oil"
message_living = ", and you feel your skin char and melt"
/datum/reagent/blob/boiling_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
M.adjust_fire_stacks(round(reac_volume/10))
M.IgniteMob()
if(M)
M.apply_damage(0.6*reac_volume, BURN)
if(iscarbon(M))
M.emote("scream")
/datum/reagent/blob/boiling_oil/extinguish_reaction(obj/effect/blob/B)
B.take_damage(rand(1, 3), BURN)
//does burn and toxin damage, explodes into flame when hit with burn damage
/datum/reagent/blob/flammable_goo
name = "Flammable Goo"
id = "flammable_goo"
description = "will do medium burn and toxin damage, make targets flammable, and ignite when burned."
shortdesc = "will do medium burn and toxin damage, and make targets flammable."
analyzerdescdamage = "Does medium burn damage, medium toxin damage, and makes targets flammable."
analyzerdesceffect = "Releases bursts of flame when attacked with burn damage, but takes additional burn damage."
color = "#BE5532"
complementary_color = "#329BBE"
blobbernaut_message = "splashes"
message = "The blob splashes you with a thin goo"
message_living = ", and you smell a faint, sweet scent"
/datum/reagent/blob/flammable_goo/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
M.adjust_fire_stacks(round(reac_volume/8)) //apply, but don't ignite
M.apply_damage(0.4*reac_volume, TOX)
if(M)
M.apply_damage(0.4*reac_volume, BURN)
/datum/reagent/blob/flammable_goo/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
if(cause && damage_type == BURN)
for(var/turf/open/T in range(1, B))
var/obj/effect/blob/C = locate() in T
if(!(C && C.overmind && C.overmind.blob_reagent_datum.id == B.overmind.blob_reagent_datum.id) && prob(80))
PoolOrNew(/obj/effect/hotspot, T)
return damage * 1.5
return ..()
//does toxin damage, targets think they're not hurt at all
/datum/reagent/blob/regenerative_materia
name = "Regenerative Materia"
id = "regenerative_materia"
description = "will do low toxin damage and cause targets to believe they are fully healed."
analyzerdescdamage = "Does low toxin damage and injects a toxin that causes the target to believe they are fully healed."
color = "#C8A5DC"
complementary_color = "#B9DCA5"
message_living = ", and you feel <i>alive</i>"
/datum/reagent/blob/regenerative_materia/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(M.reagents)
M.reagents.add_reagent("regenerative_materia", 0.2*reac_volume)
M.apply_damage(0.5*reac_volume, TOX)
/datum/reagent/blob/regenerative_materia/on_mob_life(mob/living/M)
M.adjustToxLoss(1*REM)
if(iscarbon(M))
var/mob/living/carbon/N = M
N.hal_screwyhud = 5 //fully healed, honest
..()
/datum/reagent/blob/regenerative_materia/on_mob_delete(mob/living/M)
if(iscarbon(M))
var/mob/living/carbon/N = M
N.hal_screwyhud = 0
..()
//toxin, hallucination, and some bonus spore toxin
/datum/reagent/blob/hallucinogenic_nectar
name = "Hallucinogenic Nectar"
id = "hallucinogenic_nectar"
description = "will do low toxin damage, vivid hallucinations, and inject targets with toxins."
analyzerdescdamage = "Does low toxin damage and injects a toxin that causes vivid hallucinations and blurried vision."
color = "#CD7794"
complementary_color = "#77CDB0"
blobbernaut_message = "splashes"
message = "The blob splashes you with sticky nectar"
message_living = ", and you feel really good"
/datum/reagent/blob/hallucinogenic_nectar/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
M.hallucination += reac_volume
M.adjust_drugginess(reac_volume)
if(M.reagents)
M.reagents.add_reagent("spore", 0.2*reac_volume)
M.apply_damage(0.5*reac_volume, TOX)
//kills sleeping targets and turns them into blob zombies
/datum/reagent/blob/zombifying_feelers
name = "Zombifying Feelers"
id = "zombifying_feelers"
description = "will do low toxin damage and turn sleeping targets into blob zombies."
analyzerdescdamage = "Does low toxin damage and kills unconscious humans, turning them into blob zombies."
color = "#828264"
complementary_color = "#646482"
message_living = ", and you feel tired"
/datum/reagent/blob/zombifying_feelers/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(O && ishuman(M) && M.stat == UNCONSCIOUS)
M.death() //sleeping in a fight? bad plan.
var/mob/living/simple_animal/hostile/blob/blobspore/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(get_turf(M))
BS.overmind = O
BS.update_icons()
O.blob_mobs.Add(BS)
BS.Zombify(M)
if(M)
M.apply_damage(0.4*reac_volume, TOX)
//toxin, stamina, and some bonus spore toxin
/datum/reagent/blob/envenomed_filaments
name = "Envenomed Filaments"
id = "envenomed_filaments"
description = "will do medium toxin and stamina damage, and inject targets with toxins."
analyzerdescdamage = "Does medium toxin damage, drains stamina, and injects a weak toxin."
color = "#9ACD32"
complementary_color = "#6532CD"
message_living = ", and you feel sick and nauseated"
/datum/reagent/blob/envenomed_filaments/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(M.reagents)
M.reagents.add_reagent("spore", 0.2*reac_volume)
M.apply_damage(0.4*reac_volume, TOX)
if(M)
M.adjustStaminaLoss(0.4*reac_volume)
//does brute, fire, and toxin over a few seconds
/datum/reagent/blob/poisonous_strands
name = "Poisonous Strands"
id = "poisonous_strands"
description = "will inject targets with poison."
analyzerdescdamage = "Injects a highly lethal poison that will gradually liquify the target's internal organs."
color = "#7D6EB4"
complementary_color = "#A5B46E"
blobbernaut_message = "injects"
message_living = ", and you feel like your insides are melting"
/datum/reagent/blob/poisonous_strands/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(M.reagents)
M.reagents.add_reagent("poisonous_strands", 0.12*reac_volume)
/datum/reagent/blob/poisonous_strands/on_mob_life(mob/living/M)
M.adjustBruteLoss(1.5*REM)
M.adjustFireLoss(1.5*REM)
M.adjustToxLoss(1.5*REM)
..()
//does oxygen damage, randomly pushes or pulls targets
/datum/reagent/blob/cyclonic_grid
name = "Cyclonic Grid"
id = "cyclonic_grid"
description = "will cause high oxygen damage and randomly throw targets to or from it."
analyzerdescdamage = "Does high oxygen damage and randomly throws targets at or away from it."
color = "#9BCD9B"
complementary_color = "#CD9BCD"
message = "The blob blasts you with a gust of air"
message_living = ", and you can't catch your breath"
/datum/reagent/blob/cyclonic_grid/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
reagent_vortex(M, rand(0, 1), reac_volume)
M.losebreath += round(0.05*reac_volume)
M.apply_damage(0.6*reac_volume, OXY)
//does tons of oxygen damage and a little brute
/datum/reagent/blob/lexorin_jelly
name = "Lexorin Jelly"
id = "lexorin_jelly"
description = "will cause low brute and high oxygen damage, and cause targets to be unable to breathe."
analyzerdescdamage = "Does low brute damage, high oxygen damage, and prevents targets from breathing."
color = "#00E5B1"
complementary_color = "#E50034"
message_living = ", and your lungs feel heavy and weak"
/datum/reagent/blob/lexorin_jelly/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
M.losebreath += round(0.2*reac_volume)
M.apply_damage(0.2*reac_volume, BRUTE)
if(M)
M.apply_damage(0.6*reac_volume, OXY)
//does aoe brute damage when hitting targets, is immune to explosions
/datum/reagent/blob/explosive_lattice
name = "Explosive Lattice"
id = "explosive_lattice"
description = "will do brute damage in an area around targets and is resistant to explosions."
shortdesc = "will do brute damage in an area around targets."
analyzerdescdamage = "Does medium brute damage and causes damage to everyone near its targets."
analyzerdesceffect = "Is highly resistant to explosions."
color = "#8B2500"
complementary_color = "#00668B"
blobbernaut_message = "blasts"
message = "The blob blasts you"
/datum/reagent/blob/explosive_lattice/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(reac_volume >= 10) //if it's not a spore cloud, bad time incoming
var/obj/effect/overlay/temp/explosion/E = PoolOrNew(/obj/effect/overlay/temp/explosion, get_turf(M))
E.alpha = 150
for(var/mob/living/L in orange(M, 1))
if("blob" in L.faction) //no friendly fire
continue
L.apply_damage(0.6*reac_volume, BRUTE)
if(M)
M.apply_damage(0.6*reac_volume, BRUTE)
else
M.apply_damage(0.8*reac_volume, BRUTE)
/datum/reagent/blob/explosive_lattice/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
if(isnull(cause))
if(damage_type == BRUTE)
return 0 //no-sell the explosion we do not take damage
if(damage_type == BURN)
return damage * 1.5 //take more from fire, tesla, and flashbangs
return ..()
//does semi-random brute damage and reacts to brute damage
/datum/reagent/blob/reactive_gelatin
name = "Reactive Gelatin"
id = "reactive_gelatin"
description = "will do random brute damage and react to brute damage."
shortdesc = "will do random brute damage."
analyzerdescdamage = "Does random brute damage."
analyzerdesceffect = "When attacked with brute damage, will lash out, attacking everything near it."
color = "#FFA500"
complementary_color = "#005AFF"
blobbernaut_message = "pummels"
message = "The blob pummels you"
/datum/reagent/blob/reactive_gelatin/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
var/damage = rand(5, 35)/25
M.apply_damage(damage*reac_volume, BRUTE)
/datum/reagent/blob/reactive_gelatin/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
if(damage && damage_type == BRUTE && original_health - damage > 0) //is there any damage, is it brute, and will we be alive
if(isliving(cause))
B.visible_message("<span class='warning'><b>The blob retaliates, lashing out!</b></span>")
for(var/atom/A in range(1, B))
A.blob_act(B)
return ..()
//does low burn damage and stamina damage and cools targets down
/datum/reagent/blob/cryogenic_liquid
name = "Cryogenic Liquid"
id = "cryogenic_liquid"
description = "will do low burn and stamina damage, and cause targets to freeze."
analyzerdescdamage = "Does low burn damage, drains stamina, and injects targets with a freezing liquid."
color = "#8BA6E9"
complementary_color = "#E9CE8B"
blobbernaut_message = "splashes"
message = "The blob splashes you with an icy liquid"
message_living = ", and you feel cold and tired"
/datum/reagent/blob/cryogenic_liquid/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(M.reagents)
M.reagents.add_reagent("frostoil", 0.3*reac_volume)
M.reagents.add_reagent("ice", 0.3*reac_volume)
M.apply_damage(0.4*reac_volume, BURN)
if(M)
M.adjustStaminaLoss(0.3*reac_volume)
//does burn damage and EMPs, slightly fragile
/datum/reagent/blob/electromagnetic_web
name = "Electromagnetic Web"
id = "electromagnetic_web"
description = "will do low burn damage and EMP targets, but is very fragile."
shortdesc = "will do low burn damage and EMP targets."
analyzerdescdamage = "Does low burn damage and EMPs targets."
analyzerdesceffect = "Is fragile to all types of damage, but takes massive damage from brute. In addition, releases a small EMP when killed."
color = "#83ECEC"
complementary_color = "#EC8383"
blobbernaut_message = "lashes"
message = "The blob lashes you"
message_living = ", and you hear a faint buzzing"
/datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(prob(reac_volume*2))
M.emp_act(2)
if(M)
M.apply_damage(0.6*reac_volume, BURN)
/datum/reagent/blob/electromagnetic_web/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
if(damage_type == BRUTE) //take full brute
switch(B.brute_resist)
if(0.5)
return damage * 2
if(0.25)
return damage * 4
if(0.1)
return damage * 10
return damage * 1.25 //a laser will do 25 damage, which will kill any normal blob
/datum/reagent/blob/electromagnetic_web/death_reaction(obj/effect/blob/B, cause)
if(cause)
empulse(B.loc, 1, 3) //less than screen range, so you can stand out of range to avoid it
//does brute damage, bonus damage for each nearby blob, and spreads damage out
/datum/reagent/blob/synchronous_mesh
name = "Synchronous Mesh"
id = "synchronous_mesh"
description = "will do brute damage for each nearby blob and spread damage between nearby blobs."
shortdesc = "will do brute damage for each nearby blob."
analyzerdescdamage = "Does brute damage, increasing for each blob near the target."
analyzerdesceffect = "When attacked, spreads damage between all blobs near the attacked blob."
color = "#65ADA2"
complementary_color = "#AD6570"
blobbernaut_message = "synchronously strikes"
message = "The blobs strike you"
/datum/reagent/blob/synchronous_mesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
M.apply_damage(0.1*reac_volume, BRUTE)
if(M && reac_volume)
for(var/obj/effect/blob/B in range(1, M)) //if the target is completely surrounded, this is 2.4*reac_volume bonus damage, total of 2.5*reac_volume
if(M)
B.blob_attack_animation(M) //show them they're getting a bad time
M.apply_damage(0.3*reac_volume, BRUTE)
/datum/reagent/blob/synchronous_mesh/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
if(!isnull(cause)) //the cause isn't fire or bombs, so split the damage
var/damagesplit = 1 //maximum split is 9, reducing the damage each blob takes to 11% but doing that damage to 9 blobs
for(var/obj/effect/blob/C in orange(1, B))
if(!istype(C, /obj/effect/blob/core) && !istype(C, /obj/effect/blob/node) && C.overmind && C.overmind.blob_reagent_datum.id == B.overmind.blob_reagent_datum.id) //if it doesn't have the same chemical or is a core or node, don't split damage to it
damagesplit += 1
for(var/obj/effect/blob/C in orange(1, B))
if(!istype(C, /obj/effect/blob/core) && !istype(C, /obj/effect/blob/node) && C.overmind && C.overmind.blob_reagent_datum.id == B.overmind.blob_reagent_datum.id) //only hurt blobs that have the same overmind chemical and aren't cores or nodes
C.take_damage(damage/damagesplit, CLONE, B, 0)
return damage / damagesplit
else
return damage * 1.25
//does brute damage through armor and bio resistance
/datum/reagent/blob/penetrating_spines
name = "Penetrating Spines"
id = "penetrating_spines"
description = "will do medium brute damage through armor and bio resistance."
analyzerdescdamage = "Does medium brute damage, ignoring armor and bio resistance."
color = "#6E4664"
complementary_color = "#466E50"
blobbernaut_message = "stabs"
message = "The blob stabs you"
/datum/reagent/blob/penetrating_spines/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
if(M.stat == DEAD || istype(M, /mob/living/simple_animal/hostile/blob))
return 0 //the dead, and blob mobs, don't cause reactions
M.adjustBruteLoss(0.7*reac_volume)
/datum/reagent/blob/adaptive_nexuses
name = "Adaptive Nexuses"
id = "adaptive_nexuses"
description = "will do medium brute damage and kill unconscious targets, giving you bonus resources."
shortdesc = "will do medium brute damage and kill unconscious targets, giving your overmind bonus resources."
analyzerdescdamage = "Does medium brute damage and kills unconscious humans, reaping resources from them."
color = "#4A64C0"
complementary_color = "#823ABB"
/datum/reagent/blob/adaptive_nexuses/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
if(O && ishuman(M) && M.stat == UNCONSCIOUS)
PoolOrNew(/obj/effect/overlay/temp/revenant, get_turf(M))
var/points = rand(5, 10)
O.add_points(points)
O << "<span class='notice'>Gained [points] resources from the death of [M].</span>"
M.death()
if(M)
M.apply_damage(0.5*reac_volume, BRUTE)
//does low brute damage, oxygen damage, and stamina damage and wets tiles when damaged
/datum/reagent/blob/pressurized_slime
name = "Pressurized Slime"
id = "pressurized_slime"
description = "will do low brute, oxygen, and stamina damage, and wet tiles when damaged or killed."
shortdesc = "will do low brute, oxygen, and stamina damage, and wet tiles under targets."
analyzerdescdamage = "Does low brute damage, low oxygen damage, drains stamina, and wets tiles under targets, extinguishing them."
analyzerdesceffect = "When attacked or killed, wets nearby tiles, extinguishing anything on them."
color = "#AAAABB"
complementary_color = "#BBBBAA"
blobbernaut_message = "emits slime at"
message = "The blob splashes into you"
message_living = ", and you gasp for breath"
/datum/reagent/blob/pressurized_slime/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
var/turf/open/T = get_turf(M)
if(istype(T) && prob(reac_volume))
T.MakeSlippery(min_wet_time = 10, wet_time_to_add = 5)
M.adjust_fire_stacks(-(reac_volume / 10))
M.ExtinguishMob()
M.apply_damage(0.1*reac_volume, BRUTE)
if(M)
M.apply_damage(0.3*reac_volume, OXY)
if(M)
M.adjustStaminaLoss(0.3*reac_volume)
/datum/reagent/blob/pressurized_slime/damage_reaction(obj/effect/blob/B, original_health, damage, damage_type, cause)
extinguisharea(B, damage)
return ..()
/datum/reagent/blob/pressurized_slime/death_reaction(obj/effect/blob/B, cause)
if(!isnull(cause))
B.visible_message("<span class='warning'><b>The blob ruptures, spraying the area with liquid!</b></span>")
extinguisharea(B, 50)
/datum/reagent/blob/pressurized_slime/proc/extinguisharea(obj/effect/blob/B, probchance)
for(var/turf/open/T in range(1, B))
if(prob(probchance))
T.MakeSlippery(min_wet_time = 10, wet_time_to_add = 5)
for(var/obj/O in T)
O.extinguish()
for(var/mob/living/L in T)
L.adjust_fire_stacks(-2.5)
L.ExtinguishMob()
//does brute damage and throws or pulls nearby objects at the target
/datum/reagent/blob/dark_matter
name = "Dark Matter"
id = "dark_matter"
description = "will do medium brute damage and pull nearby objects and enemies at the target."
analyzerdescdamage = "Does medium brute damage and pulls nearby objects and creatures at the target."
color = "#61407E"
complementary_color = "#5D7E40"
message = "You feel a thrum as the blob strikes you, and everything flies at you"
/datum/reagent/blob/dark_matter/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
reagent_vortex(M, 0, reac_volume)
M.apply_damage(0.3*reac_volume, BRUTE)
//does brute damage and throws or pushes nearby objects away from the target
/datum/reagent/blob/b_sorium
name = "Sorium"
id = "b_sorium"
description = "will do medium brute damage and throw nearby objects and enemies away from the target."
analyzerdescdamage = "Does medium brute damage and pushes nearby objects and creatures away from the target."
color = "#808000"
complementary_color = "#000080"
message = "The blob slams into you and sends you flying"
/datum/reagent/blob/b_sorium/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/O)
reac_volume = ..()
reagent_vortex(M, 1, reac_volume)
M.apply_damage(0.3*reac_volume, BRUTE)
/datum/reagent/blob/proc/reagent_vortex(mob/living/M, setting_type, reac_volume)
if(M && reac_volume)
var/turf/pull = get_turf(M)
var/range_power = Clamp(round(reac_volume/5, 1), 1, 5)
for(var/atom/movable/X in range(range_power,pull))
if(istype(X, /obj/effect))
continue
if(isliving(X))
var/mob/living/L = X
if("blob" in L.faction) //no friendly throwpulling
continue
if(!X.anchored)
var/distance = get_dist(X, pull)
var/moving_power = max(range_power - distance, 1)
if(moving_power > 2) //if the vortex is powerful and we're close, we get thrown
if(setting_type)
var/atom/throw_target = get_edge_target_turf(X, get_dir(X, get_step_away(X, pull)))
var/throw_range = 5 - distance
X.throw_at_fast(throw_target, throw_range, 1)
else
X.throw_at_fast(pull, distance, 1)
else
spawn(0)
if(setting_type)
for(var/i in 0 to moving_power-1)
sleep(2)
if(!step_away(X, pull))
break
else
for(var/i in 0 to moving_power-1)
sleep(2)
if(!step_towards(X, pull))
break
/datum/reagent/blob/proc/send_message(mob/living/M)
var/totalmessage = message
if(message_living && !issilicon(M))
totalmessage += message_living
totalmessage += "!"
M << "<span class='userdanger'>[totalmessage]</span>"
@@ -0,0 +1,606 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////// DRINKS BELOW, Beer is up there though, along with cola. Cap'n Pete's Cuban Spiced Rum////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/reagent/consumable/orangejuice
name = "Orange juice"
id = "orangejuice"
description = "Both delicious AND rich in Vitamin C, what more do you need?"
color = "#E78108" // rgb: 231, 129, 8
/datum/reagent/consumable/orangejuice/on_mob_life(mob/living/M)
if(M.getOxyLoss() && prob(30))
M.adjustOxyLoss(-1, 0)
. = 1
..()
/datum/reagent/consumable/tomatojuice
name = "Tomato Juice"
id = "tomatojuice"
description = "Tomatoes made into juice. What a waste of big, juicy tomatoes, huh?"
color = "#731008" // rgb: 115, 16, 8
/datum/reagent/consumable/tomatojuice/on_mob_life(mob/living/M)
if(M.getFireLoss() && prob(20))
M.heal_organ_damage(0,1, 0)
. = 1
..()
/datum/reagent/consumable/limejuice
name = "Lime Juice"
id = "limejuice"
description = "The sweet-sour juice of limes."
color = "#365E30" // rgb: 54, 94, 48
/datum/reagent/consumable/limejuice/on_mob_life(mob/living/M)
if(M.getToxLoss() && prob(20))
M.adjustToxLoss(-1*REM, 0)
. = 1
..()
/datum/reagent/consumable/carrotjuice
name = "Carrot juice"
id = "carrotjuice"
description = "It is just like a carrot but without crunching."
color = "#973800" // rgb: 151, 56, 0
/datum/reagent/consumable/carrotjuice/on_mob_life(mob/living/M)
M.adjust_blurriness(-1)
M.adjust_blindness(-1)
switch(current_cycle)
if(1 to 20)
//nothing
if(21 to INFINITY)
if(prob(current_cycle-10))
M.cure_nearsighted()
..()
return
/datum/reagent/consumable/berryjuice
name = "Berry Juice"
id = "berryjuice"
description = "A delicious blend of several different kinds of berries."
color = "#863333" // rgb: 134, 51, 51
/datum/reagent/consumable/poisonberryjuice
name = "Poison Berry Juice"
id = "poisonberryjuice"
description = "A tasty juice blended from various kinds of very deadly and toxic berries."
color = "#863353" // rgb: 134, 51, 83
/datum/reagent/consumable/poisonberryjuice/on_mob_life(mob/living/M)
M.adjustToxLoss(1, 0)
. = 1
..()
/datum/reagent/consumable/watermelonjuice
name = "Watermelon Juice"
id = "watermelonjuice"
description = "Delicious juice made from watermelon."
color = "#863333" // rgb: 134, 51, 51
/datum/reagent/consumable/lemonjuice
name = "Lemon Juice"
id = "lemonjuice"
description = "This juice is VERY sour."
color = "#863333" // rgb: 175, 175, 0
/datum/reagent/consumable/banana
name = "Banana Juice"
id = "banana"
description = "The raw essence of a banana. HONK"
color = "#863333" // rgb: 175, 175, 0
/datum/reagent/consumable/banana/on_mob_life(mob/living/M)
if( ( istype(M, /mob/living/carbon/human) && M.job in list("Clown") ) || istype(M, /mob/living/carbon/monkey) )
M.heal_organ_damage(1,1, 0)
. = 1
..()
/datum/reagent/consumable/nothing
name = "Nothing"
id = "nothing"
description = "Absolutely nothing."
/datum/reagent/consumable/nothing/on_mob_life(mob/living/M)
if(istype(M, /mob/living/carbon/human) && M.job in list("Mime"))
M.heal_organ_damage(1,1, 0)
. = 1
..()
/datum/reagent/consumable/potato_juice
name = "Potato Juice"
id = "potato"
description = "Juice of the potato. Bleh."
nutriment_factor = 2 * REAGENTS_METABOLISM
color = "#302000" // rgb: 48, 32, 0
/datum/reagent/consumable/grapejuice
name = "Grape juice"
id = "grapejuice"
description = "The juice of a bunch of grapes. Guaranteed non-alcoholic."
color = "#290029" // dark purple
/datum/reagent/consumable/milk
name = "Milk"
id = "milk"
description = "An opaque white liquid produced by the mammary glands of mammals."
color = "#DFDFDF" // rgb: 223, 223, 223
/datum/reagent/consumable/milk/on_mob_life(mob/living/M)
if(M.getBruteLoss() && prob(20))
M.heal_organ_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_organ_damage(1,0, 0)
. = 1
..()
/datum/reagent/consumable/soymilk
name = "Soy Milk"
id = "soymilk"
description = "An opaque white liquid made from soybeans."
color = "#DFDFC7" // rgb: 223, 223, 199
/datum/reagent/consumable/soymilk/on_mob_life(mob/living/M)
if(M.getBruteLoss() && prob(20))
M.heal_organ_damage(1,0, 0)
. = 1
..()
/datum/reagent/consumable/cream
name = "Cream"
id = "cream"
description = "The fatty, still liquid part of milk. Why don't you mix this with sum scotch, eh?"
color = "#DFD7AF" // rgb: 223, 215, 175
/datum/reagent/consumable/cream/on_mob_life(mob/living/M)
if(M.getBruteLoss() && prob(20))
M.heal_organ_damage(1,0, 0)
. = 1
..()
/datum/reagent/consumable/coffee
name = "Coffee"
id = "coffee"
description = "Coffee is a brewed drink prepared from roasted seeds, commonly called coffee beans, of the coffee plant."
color = "#482000" // rgb: 72, 32, 0
nutriment_factor = 0
overdose_threshold = 80
/datum/reagent/consumable/coffee/overdose_process(mob/living/M)
M.Jitter(5)
..()
/datum/reagent/consumable/coffee/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
M.AdjustSleeping(-2, 0)
if (M.bodytemperature < 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = min(310, M.bodytemperature + (25 * TEMPERATURE_DAMAGE_COEFFICIENT))
if(holder.has_reagent("frostoil"))
holder.remove_reagent("frostoil", 5)
..()
. = 1
/datum/reagent/consumable/tea
name = "Tea"
id = "tea"
description = "Tasty black tea, it has antioxidants, it's good for you!"
color = "#101000" // rgb: 16, 16, 0
nutriment_factor = 0
/datum/reagent/consumable/tea/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-2)
M.drowsyness = max(0,M.drowsyness-1)
M.jitteriness = max(0,M.jitteriness-3)
M.AdjustSleeping(-1, 0)
if(M.getToxLoss() && prob(20))
M.adjustToxLoss(-1, 0)
if (M.bodytemperature < 310) //310 is the normal bodytemp. 310.055
M.bodytemperature = min(310, M.bodytemperature + (20 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
. = 1
/datum/reagent/consumable/tea/arnold_palmer
name = "Arnold Palmer"
id = "arnold_palmer"
description = "Encourages the patient to go golfing."
color = "#FFB766"
nutriment_factor = 2
/datum/reagent/consumable/tea/arnold_palmer/on_mob_life(mob/living/M)
if(prob(5))
M << "<span class = 'notice'>[pick("You remember to square your shoulders.","You remember to keep your head down.","You can't decide between squaring your shoulders and keeping your head down.","You remember to relax.","You think about how someday you'll get two strokes off your golf game.")]</span>"
..()
. = 1
/datum/reagent/consumable/icecoffee
name = "Iced Coffee"
id = "icecoffee"
description = "Coffee and ice, refreshing and cool."
color = "#102838" // rgb: 16, 40, 56
nutriment_factor = 0
/datum/reagent/consumable/icecoffee/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
M.AdjustSleeping(-2, 0)
if (M.bodytemperature > 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
..()
. = 1
/datum/reagent/consumable/icetea
name = "Iced Tea"
id = "icetea"
description = "No relation to a certain rap artist/ actor."
color = "#104038" // rgb: 16, 64, 56
nutriment_factor = 0
/datum/reagent/consumable/icetea/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-2)
M.drowsyness = max(0,M.drowsyness-1)
M.AdjustSleeping(-2, 0)
if(M.getToxLoss() && prob(20))
M.adjustToxLoss(-1, 0)
if (M.bodytemperature > 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
. = 1
/datum/reagent/consumable/space_cola
name = "Cola"
id = "cola"
description = "A refreshing beverage."
color = "#100800" // rgb: 16, 8, 0
/datum/reagent/consumable/space_cola/on_mob_life(mob/living/M)
M.drowsyness = max(0,M.drowsyness-5)
if (M.bodytemperature > 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
/datum/reagent/consumable/nuka_cola
name = "Nuka Cola"
id = "nuka_cola"
description = "Cola, cola never changes."
color = "#100800" // rgb: 16, 8, 0
/datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/M)
M.Jitter(20)
M.set_drugginess(30)
M.dizziness +=5
M.drowsyness = 0
M.AdjustSleeping(-2, 0)
M.status_flags |= GOTTAGOFAST
if (M.bodytemperature > 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
. = 1
/datum/reagent/consumable/spacemountainwind
name = "SM Wind"
id = "spacemountainwind"
description = "Blows right through you like a space wind."
color = "#102000" // rgb: 16, 32, 0
/datum/reagent/consumable/spacemountainwind/on_mob_life(mob/living/M)
M.drowsyness = max(0,M.drowsyness-7)
M.AdjustSleeping(-1, 0)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
..()
. = 1
/datum/reagent/consumable/dr_gibb
name = "Dr. Gibb"
id = "dr_gibb"
description = "A delicious blend of 42 different flavours"
color = "#102000" // rgb: 16, 32, 0
/datum/reagent/consumable/dr_gibb/on_mob_life(mob/living/M)
M.drowsyness = max(0,M.drowsyness-6)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055
..()
/datum/reagent/consumable/space_up
name = "Space-Up"
id = "space_up"
description = "Tastes like a hull breach in your mouth."
color = "#00FF00" // rgb: 0, 255, 0
/datum/reagent/consumable/space_up/on_mob_life(mob/living/M)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (8 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055
..()
/datum/reagent/consumable/lemon_lime
name = "Lemon Lime"
description = "A tangy substance made of 0.5% natural citrus!"
id = "lemon_lime"
color = "#8CFF00" // rgb: 135, 255, 0
/datum/reagent/consumable/lemon_lime/on_mob_life(mob/living/M)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (8 * TEMPERATURE_DAMAGE_COEFFICIENT)) //310 is the normal bodytemp. 310.055
..()
/datum/reagent/consumable/sodawater
name = "Soda Water"
id = "sodawater"
description = "A can of club soda. Why not make a scotch and soda?"
color = "#619494" // rgb: 97, 148, 148
/datum/reagent/consumable/sodawater/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
/datum/reagent/consumable/tonic
name = "Tonic Water"
id = "tonic"
description = "It tastes strange but at least the quinine keeps the Space Malaria at bay."
color = "#0064C8" // rgb: 0, 100, 200
/datum/reagent/consumable/tonic/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
M.AdjustSleeping(-2, 0)
if (M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
. = 1
/datum/reagent/consumable/ice
name = "Ice"
id = "ice"
description = "Frozen water, your dentist wouldn't like you chewing this."
reagent_state = SOLID
color = "#619494" // rgb: 97, 148, 148
/datum/reagent/consumable/ice/on_mob_life(mob/living/M)
M.bodytemperature = max( M.bodytemperature - 5 * TEMPERATURE_DAMAGE_COEFFICIENT, 0)
..()
/datum/reagent/consumable/soy_latte
name = "Soy Latte"
id = "soy_latte"
description = "A nice and tasty beverage while you are reading your hippie books."
color = "#664300" // rgb: 102, 67, 0
/datum/reagent/consumable/soy_latte/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
M.SetSleeping(0, 0)
if (M.bodytemperature < 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = min(310, M.bodytemperature + (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
if(M.getBruteLoss() && prob(20))
M.heal_organ_damage(1,0, 0)
..()
. = 1
/datum/reagent/consumable/cafe_latte
name = "Cafe Latte"
id = "cafe_latte"
description = "A nice, strong and tasty beverage while you are reading."
color = "#664300" // rgb: 102, 67, 0
/datum/reagent/consumable/cafe_latte/on_mob_life(mob/living/M)
M.dizziness = max(0,M.dizziness-5)
M.drowsyness = max(0,M.drowsyness-3)
M.SetSleeping(0, 0)
if (M.bodytemperature < 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = min(310, M.bodytemperature + (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
M.Jitter(5)
if(M.getBruteLoss() && prob(20))
M.heal_organ_damage(1,0, 0)
..()
. = 1
/datum/reagent/consumable/doctor_delight
name = "The Doctor's Delight"
id = "doctorsdelight"
description = "A gulp a day keeps the Medibot away! A mixture of juices that heals most damage types fairly quickly at the cost of hunger."
color = "#FF8CFF" // rgb: 255, 140, 255
/datum/reagent/consumable/doctor_delight/on_mob_life(mob/living/M)
M.adjustBruteLoss(-0.5, 0)
M.adjustFireLoss(-0.5, 0)
M.adjustToxLoss(-0.5, 0)
M.adjustOxyLoss(-0.5, 0)
if(M.nutrition && (M.nutrition - 2 > 0))
if(!(M.mind && M.mind.assigned_role == "Medical Doctor")) //Drains the nutrition of the holder. Not medical doctors though, since it's the Doctor's Delight!
M.nutrition -= 2
..()
. = 1
/datum/reagent/consumable/chocolatepudding
name = "Chocolate Pudding"
id = "chocolatepudding"
description = "A great dessert for chocolate lovers."
color = "#800000"
nutriment_factor = 4 * REAGENTS_METABOLISM
/datum/reagent/consumable/vanillapudding
name = "Vanilla Pudding"
id = "vanillapudding"
description = "A great dessert for vanilla lovers."
color = "#FAFAD2"
nutriment_factor = 4 * REAGENTS_METABOLISM
/datum/reagent/consumable/cherryshake
name = "Cherry Shake"
id = "cherryshake"
description = "A cherry flavored milkshake."
color = "#FFB6C1"
nutriment_factor = 4 * REAGENTS_METABOLISM
/datum/reagent/consumable/bluecherryshake
name = "Blue Cherry Shake"
id = "bluecherryshake"
description = "An exotic milkshake."
color = "#00F1FF"
nutriment_factor = 4 * REAGENTS_METABOLISM
/datum/reagent/consumable/pumpkin_latte
name = "Pumpkin Latte"
id = "pumpkin_latte"
description = "A mix of pumpkin juice and coffee."
color = "#F4A460"
nutriment_factor = 3 * REAGENTS_METABOLISM
/datum/reagent/consumable/gibbfloats
name = "Gibb Floats"
id = "gibbfloats"
description = "Icecream on top of a Dr. Gibb glass."
color = "#B22222"
nutriment_factor = 3 * REAGENTS_METABOLISM
/datum/reagent/consumable/pumpkinjuice
name = "Pumpkin Juice"
id = "pumpkinjuice"
description = "Juiced from real pumpkin."
color = "#FFA500"
/datum/reagent/consumable/blumpkinjuice
name = "Blumpkin Juice"
id = "blumpkinjuice"
description = "Juiced from real blumpkin."
color = "#00BFFF"
/datum/reagent/consumable/triple_citrus
name = "Triple Citrus"
id = "triple_citrus"
description = "A solution."
color = "#C8A5DC"
/datum/reagent/consumable/grape_soda
name = "Grape soda"
id = "grapesoda"
description = "Beloved of children and teetotalers."
color = "#E6CDFF"
//////////////////////////////////////////////The ten friggen million reagents that get you drunk//////////////////////////////////////////////
/datum/reagent/consumable/atomicbomb
name = "Atomic Bomb"
id = "atomicbomb"
description = "Nuclear proliferation never tasted so good."
color = "#666300" // rgb: 102, 99, 0
/datum/reagent/consumable/atomicbomb/on_mob_life(mob/living/M)
M.set_drugginess(50)
M.confused = max(M.confused+2,0)
M.Dizzy(10)
if (!M.slurring)
M.slurring = 1
M.slurring += 3
switch(current_cycle)
if(51 to 200)
M.Sleeping(5, 0)
. = 1
if(201 to INFINITY)
M.AdjustSleeping(2, 0)
M.adjustToxLoss(2, 0)
. = 1
..()
/datum/reagent/consumable/gargle_blaster
name = "Pan-Galactic Gargle Blaster"
id = "gargleblaster"
description = "Whoah, this stuff looks volatile!"
color = "#664300" // rgb: 102, 67, 0
/datum/reagent/consumable/gargle_blaster/on_mob_life(mob/living/M)
M.dizziness +=6
switch(current_cycle)
if(15 to 45)
if(!M.slurring)
M.slurring = 1
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)
. = 1
..()
/datum/reagent/consumable/neurotoxin
name = "Neurotoxin"
id = "neurotoxin"
description = "A strong neurotoxin that puts the subject into a death-like state."
color = "#2E2E61" // rgb: 46, 46, 97
/datum/reagent/consumable/neurotoxin/on_mob_life(mob/living/carbon/M)
M.Weaken(3, 1, 0)
M.dizziness +=6
switch(current_cycle)
if(15 to 45)
if(!M.slurring)
M.slurring = 1
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)
..()
. = 1
/datum/reagent/consumable/hippies_delight
name = "Hippie's Delight"
id = "hippiesdelight"
description = "You just don't get it maaaan."
color = "#664300" // rgb: 102, 67, 0
nutriment_factor = 0
metabolization_rate = 0.2 * REAGENTS_METABOLISM
/datum/reagent/consumable/hippies_delight/on_mob_life(mob/living/M)
if (!M.slurring)
M.slurring = 1
switch(current_cycle)
if(1 to 5)
M.Dizzy(10)
M.set_drugginess(30)
if(prob(10))
M.emote(pick("twitch","giggle"))
if(5 to 10)
M.Jitter(20)
M.Dizzy(20)
M.set_drugginess(45)
if(prob(20))
M.emote(pick("twitch","giggle"))
if (10 to 200)
M.Jitter(40)
M.Dizzy(40)
M.set_drugginess(60)
if(prob(30))
M.emote(pick("twitch","giggle"))
if(200 to INFINITY)
M.Jitter(60)
M.Dizzy(60)
M.set_drugginess(75)
if(prob(40))
M.emote(pick("twitch","giggle"))
if(prob(30))
M.adjustToxLoss(2, 0)
. = 1
..()
@@ -0,0 +1,329 @@
/datum/reagent/drug
name = "Drug"
id = "drug"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/drug/space_drugs
name = "Space drugs"
id = "space_drugs"
description = "An illegal chemical compound used as drug."
color = "#60A584" // rgb: 96, 165, 132
overdose_threshold = 30
/datum/reagent/drug/space_drugs/on_mob_life(mob/living/M)
M.set_drugginess(15)
if(isturf(M.loc) && !istype(M.loc, /turf/open/space))
if(M.canmove)
if(prob(10)) step(M, pick(cardinal))
if(prob(7))
M.emote(pick("twitch","drool","moan","giggle"))
..()
/datum/reagent/drug/space_drugs/overdose_start(mob/living/M)
M << "<span class='userdanger'>You start tripping hard!</span>"
/datum/reagent/drug/space_drugs/overdose_process(mob/living/M)
if(M.hallucination < volume && prob(20))
M.hallucination += 5
..()
/datum/reagent/drug/nicotine
name = "Nicotine"
id = "nicotine"
description = "Slightly reduces stun times. If overdosed it will deal toxin and oxygen damage."
reagent_state = LIQUID
color = "#60A584" // rgb: 96, 165, 132
addiction_threshold = 30
/datum/reagent/drug/nicotine/on_mob_life(mob/living/M)
if(prob(1))
var/smoke_message = pick("You feel relaxed.", "You feel calmed.","You feel alert.","You feel rugged.")
M << "<span class='notice'>[smoke_message]</span>"
M.AdjustStunned(-1, 0)
M.adjustStaminaLoss(-0.5*REM, 0)
..()
. = 1
/datum/reagent/drug/crank
name = "Crank"
id = "crank"
description = "Reduces stun times by about 200%. If overdosed or addicted it will deal significant Toxin, Brute and Brain damage."
reagent_state = LIQUID
color = "#FA00C8"
overdose_threshold = 20
addiction_threshold = 10
/datum/reagent/drug/crank/on_mob_life(mob/living/M)
var/high_message = pick("You feel jittery.", "You feel like you gotta go fast.", "You feel like you need to step it up.")
if(prob(5))
M << "<span class='notice'>[high_message]</span>"
M.AdjustParalysis(-1, 0)
M.AdjustStunned(-1, 0)
M.AdjustWeakened(-1, 0)
..()
. = 1
/datum/reagent/drug/crank/overdose_process(mob/living/M)
M.adjustBrainLoss(2*REM)
M.adjustToxLoss(2*REM, 0)
M.adjustBruteLoss(2*REM, 0)
..()
. = 1
/datum/reagent/drug/crank/addiction_act_stage1(mob/living/M)
M.adjustBrainLoss(5*REM)
..()
/datum/reagent/drug/crank/addiction_act_stage2(mob/living/M)
M.adjustToxLoss(5*REM, 0)
..()
. = 1
/datum/reagent/drug/crank/addiction_act_stage3(mob/living/M)
M.adjustBruteLoss(5*REM, 0)
..()
. = 1
/datum/reagent/drug/crank/addiction_act_stage4(mob/living/M)
M.adjustBrainLoss(5*REM)
M.adjustToxLoss(5*REM, 0)
M.adjustBruteLoss(5*REM, 0)
..()
. = 1
/datum/reagent/drug/krokodil
name = "Krokodil"
id = "krokodil"
description = "Cools and calms you down. If overdosed it will deal significant Brain and Toxin damage. If addicted it will begin to deal fatal amounts of Brute damage as the subject's skin falls off."
reagent_state = LIQUID
color = "#0064B4"
overdose_threshold = 20
addiction_threshold = 15
/datum/reagent/drug/krokodil/on_mob_life(mob/living/M)
var/high_message = pick("You feel calm.", "You feel collected.", "You feel like you need to relax.")
if(prob(5))
M << "<span class='notice'>[high_message]</span>"
..()
/datum/reagent/drug/krokodil/overdose_process(mob/living/M)
M.adjustBrainLoss(0.25*REM)
M.adjustToxLoss(0.25*REM, 0)
..()
. = 1
/datum/reagent/drug/krokodil/addiction_act_stage1(mob/living/M)
M.adjustBrainLoss(2*REM)
M.adjustToxLoss(2*REM, 0)
..()
. = 1
/datum/reagent/krokodil/addiction_act_stage2(mob/living/M)
if(prob(25))
M << "<span class='danger'>Your skin feels loose...</span>"
..()
/datum/reagent/drug/krokodil/addiction_act_stage3(mob/living/M)
if(prob(25))
M << "<span class='danger'>Your skin starts to peel away...</span>"
M.adjustBruteLoss(3*REM, 0)
..()
. = 1
/datum/reagent/drug/krokodil/addiction_act_stage4(mob/living/carbon/human/M)
CHECK_DNA_AND_SPECIES(M)
if(!istype(M.dna.species, /datum/species/krokodil_addict))
M << "<span class='userdanger'>Your skin falls off easily!</span>"
M.adjustBruteLoss(50*REM, 0) // holy shit your skin just FELL THE FUCK OFF
M.set_species(/datum/species/krokodil_addict)
else
M.adjustBruteLoss(5*REM, 0)
..()
. = 1
/datum/reagent/drug/methamphetamine
name = "Methamphetamine"
id = "methamphetamine"
description = "Reduces stun times by about 300%, speeds the user up, and allows the user to quickly recover stamina while dealing a small amount of Brain damage. If overdosed the subject will move randomly, laugh randomly, drop items and suffer from Toxin and Brain damage. If addicted the subject will constantly jitter and drool, before becoming dizzy and losing motor control and eventually suffer heavy toxin damage."
reagent_state = LIQUID
color = "#FAFAFA"
overdose_threshold = 20
addiction_threshold = 10
metabolization_rate = 0.75 * REAGENTS_METABOLISM
/datum/reagent/drug/methamphetamine/on_mob_life(mob/living/M)
var/high_message = pick("You feel hyper.", "You feel like you need to go faster.", "You feel like you can run the world.")
if(prob(5))
M << "<span class='notice'>[high_message]</span>"
M.AdjustParalysis(-2, 0)
M.AdjustStunned(-2, 0)
M.AdjustWeakened(-2, 0)
M.adjustStaminaLoss(-2, 0)
M.status_flags |= GOTTAGOREALLYFAST
M.Jitter(2)
M.adjustBrainLoss(0.25)
if(prob(5))
M.emote(pick("twitch", "shiver"))
..()
. = 1
/datum/reagent/drug/methamphetamine/overdose_process(mob/living/M)
if(M.canmove && !istype(M.loc, /atom/movable))
for(var/i = 0, i < 4, i++)
step(M, pick(cardinal))
if(prob(20))
M.emote("laugh")
if(prob(33))
M.visible_message("<span class='danger'>[M]'s hands flip out and flail everywhere!</span>")
var/obj/item/I = M.get_active_hand()
if(I)
M.drop_item()
..()
M.adjustToxLoss(1, 0)
M.adjustBrainLoss(pick(0.5, 0.6, 0.7, 0.8, 0.9, 1))
. = 1
/datum/reagent/drug/methamphetamine/addiction_act_stage1(mob/living/M)
M.Jitter(5)
if(prob(20))
M.emote(pick("twitch","drool","moan"))
..()
/datum/reagent/drug/methamphetamine/addiction_act_stage2(mob/living/M)
M.Jitter(10)
M.Dizzy(10)
if(prob(30))
M.emote(pick("twitch","drool","moan"))
..()
/datum/reagent/drug/methamphetamine/addiction_act_stage3(mob/living/M)
if(M.canmove && !istype(M.loc, /atom/movable))
for(var/i = 0, i < 4, i++)
step(M, pick(cardinal))
M.Jitter(15)
M.Dizzy(15)
if(prob(40))
M.emote(pick("twitch","drool","moan"))
..()
/datum/reagent/drug/methamphetamine/addiction_act_stage4(mob/living/carbon/human/M)
if(M.canmove && !istype(M.loc, /atom/movable))
for(var/i = 0, i < 8, i++)
step(M, pick(cardinal))
M.Jitter(20)
M.Dizzy(20)
M.adjustToxLoss(5, 0)
if(prob(50))
M.emote(pick("twitch","drool","moan"))
..()
. = 1
/datum/reagent/drug/bath_salts
name = "Bath Salts"
id = "bath_salts"
description = "Makes you nearly impervious to stuns and grants a stamina regeneration buff, but you will be a nearly uncontrollable tramp-bearded raving lunatic."
reagent_state = LIQUID
color = "#FAFAFA"
overdose_threshold = 20
addiction_threshold = 10
/datum/reagent/drug/bath_salts/on_mob_life(mob/living/M)
var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.")
if(prob(5))
M << "<span class='notice'>[high_message]</span>"
M.AdjustParalysis(-3, 0)
M.AdjustStunned(-3, 0)
M.AdjustWeakened(-3, 0)
M.adjustStaminaLoss(-5, 0)
M.adjustBrainLoss(0.5)
M.adjustToxLoss(0.1, 0)
M.hallucination += 10
if(M.canmove && !istype(M.loc, /atom/movable))
step(M, pick(cardinal))
step(M, pick(cardinal))
..()
. = 1
/datum/reagent/drug/bath_salts/overdose_process(mob/living/M)
M.hallucination += 10
if(M.canmove && !istype(M.loc, /atom/movable))
for(var/i = 0, i < 8, i++)
step(M, pick(cardinal))
if(prob(20))
M.emote(pick("twitch","drool","moan"))
if(prob(33))
var/obj/item/I = M.get_active_hand()
if(I)
M.drop_item()
..()
/datum/reagent/drug/bath_salts/addiction_act_stage1(mob/living/M)
M.hallucination += 10
if(M.canmove && !istype(M.loc, /atom/movable))
for(var/i = 0, i < 8, i++)
step(M, pick(cardinal))
M.Jitter(5)
M.adjustBrainLoss(10)
if(prob(20))
M.emote(pick("twitch","drool","moan"))
..()
/datum/reagent/drug/bath_salts/addiction_act_stage2(mob/living/M)
M.hallucination += 20
if(M.canmove && !istype(M.loc, /atom/movable))
for(var/i = 0, i < 8, i++)
step(M, pick(cardinal))
M.Jitter(10)
M.Dizzy(10)
M.adjustBrainLoss(10)
if(prob(30))
M.emote(pick("twitch","drool","moan"))
..()
/datum/reagent/drug/bath_salts/addiction_act_stage3(mob/living/M)
M.hallucination += 30
if(M.canmove && !istype(M.loc, /atom/movable))
for(var/i = 0, i < 12, i++)
step(M, pick(cardinal))
M.Jitter(15)
M.Dizzy(15)
M.adjustBrainLoss(10)
if(prob(40))
M.emote(pick("twitch","drool","moan"))
..()
/datum/reagent/drug/bath_salts/addiction_act_stage4(mob/living/carbon/human/M)
M.hallucination += 40
if(M.canmove && !istype(M.loc, /atom/movable))
for(var/i = 0, i < 16, i++)
step(M, pick(cardinal))
M.Jitter(50)
M.Dizzy(50)
M.adjustToxLoss(5, 0)
M.adjustBrainLoss(10)
if(prob(50))
M.emote(pick("twitch","drool","moan"))
..()
. = 1
/datum/reagent/drug/aranesp
name = "Aranesp"
id = "aranesp"
description = "Amps you up and gets you going, fixes all stamina damage you might have but can cause toxin and oxygen damage.."
reagent_state = LIQUID
color = "#78FFF0"
/datum/reagent/drug/aranesp/on_mob_life(mob/living/M)
var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.")
if(prob(5))
M << "<span class='notice'>[high_message]</span>"
M.adjustStaminaLoss(-18, 0)
M.adjustToxLoss(0.5, 0)
if(prob(50))
M.losebreath++
M.adjustOxyLoss(1, 0)
..()
. = 1
@@ -0,0 +1,461 @@
///////////////////////////////////////////////////////////////////
//Food Reagents
//////////////////////////////////////////////////////////////////
// Part of the food code. Also is where all the food
// condiments, additives, and such go.
/datum/reagent/consumable
name = "Consumable"
id = "consumable"
var/nutriment_factor = 1 * REAGENTS_METABOLISM
/datum/reagent/consumable/on_mob_life(mob/living/M)
current_cycle++
M.nutrition += nutriment_factor
holder.remove_reagent(src.id, metabolization_rate)
/datum/reagent/consumable/nutriment
name = "Nutriment"
id = "nutriment"
description = "All the vitamins, minerals, and carbohydrates the body needs in pure form."
reagent_state = SOLID
nutriment_factor = 15 * REAGENTS_METABOLISM
color = "#664330" // rgb: 102, 67, 48
/datum/reagent/consumable/nutriment/on_mob_life(mob/living/M)
if(prob(50))
M.heal_organ_damage(1,0, 0)
. = 1
if(iscarbon(M))
var/mob/living/carbon/C = M
if(C.blood_volume < BLOOD_VOLUME_NORMAL)
C.blood_volume += 0.4
..()
/datum/reagent/consumable/vitamin
name = "Vitamin"
id = "vitamin"
description = "All the best vitamins, minerals, and carbohydrates the body needs in pure form."
reagent_state = SOLID
color = "#664330" // rgb: 102, 67, 48
/datum/reagent/consumable/vitamin/on_mob_life(mob/living/M)
if(prob(50))
M.heal_organ_damage(1,1, 0)
. = 1
if(M.satiety < 600)
M.satiety += 30
if(iscarbon(M))
var/mob/living/carbon/C = M
if(C.blood_volume < BLOOD_VOLUME_NORMAL)
C.blood_volume += 0.5
..()
/datum/reagent/consumable/sugar
name = "Sugar"
id = "sugar"
description = "The organic compound commonly known as table sugar and sometimes called saccharose. This white, odorless, crystalline powder has a pleasing, sweet taste."
reagent_state = SOLID
color = "#FFFFFF" // rgb: 255, 255, 255
nutriment_factor = 10 * REAGENTS_METABOLISM
metabolization_rate = 2 * REAGENTS_METABOLISM
overdose_threshold = 200 // Hyperglycaemic shock
/datum/reagent/consumable/sugar/overdose_start(mob/living/M)
M << "<span class='userdanger'>You go into hyperglycaemic shock! Lay off the twinkies!</span>"
M.AdjustSleeping(30, 0)
. = 1
/datum/reagent/consumable/sugar/overdose_process(mob/living/M)
M.AdjustSleeping(3, 0)
..()
. = 1
/datum/reagent/consumable/virus_food
name = "Virus Food"
id = "virusfood"
description = "A mixture of water and milk. Virus cells can use this mixture to reproduce."
nutriment_factor = 2 * REAGENTS_METABOLISM
color = "#899613" // rgb: 137, 150, 19
/datum/reagent/consumable/soysauce
name = "Soysauce"
id = "soysauce"
description = "A salty sauce made from the soy plant."
nutriment_factor = 2 * REAGENTS_METABOLISM
color = "#792300" // rgb: 121, 35, 0
/datum/reagent/consumable/ketchup
name = "Ketchup"
id = "ketchup"
description = "Ketchup, catsup, whatever. It's tomato paste."
nutriment_factor = 5 * REAGENTS_METABOLISM
color = "#731008" // rgb: 115, 16, 8
/datum/reagent/consumable/capsaicin
name = "Capsaicin Oil"
id = "capsaicin"
description = "This is what makes chilis hot."
color = "#B31008" // rgb: 179, 16, 8
/datum/reagent/consumable/capsaicin/on_mob_life(mob/living/M)
switch(current_cycle)
if(1 to 15)
M.bodytemperature += 5 * TEMPERATURE_DAMAGE_COEFFICIENT
if(holder.has_reagent("cryostylane"))
holder.remove_reagent("cryostylane", 5)
if(isslime(M))
M.bodytemperature += rand(5,20)
if(15 to 25)
M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT
if(isslime(M))
M.bodytemperature += rand(10,20)
if(25 to 35)
M.bodytemperature += 15 * TEMPERATURE_DAMAGE_COEFFICIENT
if(isslime(M))
M.bodytemperature += rand(15,20)
if(35 to INFINITY)
M.bodytemperature += 20 * TEMPERATURE_DAMAGE_COEFFICIENT
if(isslime(M))
M.bodytemperature += rand(20,25)
..()
/datum/reagent/consumable/frostoil
name = "Frost Oil"
id = "frostoil"
description = "A special oil that noticably chills the body. Extracted from Icepeppers and slimes."
color = "#8BA6E9" // rgb: 139, 166, 233
/datum/reagent/consumable/frostoil/on_mob_life(mob/living/M)
switch(current_cycle)
if(1 to 15)
M.bodytemperature -= 10 * TEMPERATURE_DAMAGE_COEFFICIENT
if(holder.has_reagent("capsaicin"))
holder.remove_reagent("capsaicin", 5)
if(isslime(M))
M.bodytemperature -= rand(5,20)
if(15 to 25)
M.bodytemperature -= 20 * TEMPERATURE_DAMAGE_COEFFICIENT
if(isslime(M))
M.bodytemperature -= rand(10,20)
if(25 to 35)
M.bodytemperature -= 30 * TEMPERATURE_DAMAGE_COEFFICIENT
if(prob(1))
M.emote("shiver")
if(isslime(M))
M.bodytemperature -= rand(15,20)
if(35 to INFINITY)
M.bodytemperature -= 40 * TEMPERATURE_DAMAGE_COEFFICIENT
if(prob(5))
M.emote("shiver")
if(isslime(M))
M.bodytemperature -= rand(20,25)
..()
/datum/reagent/consumable/frostoil/reaction_turf(turf/T, reac_volume)
if(reac_volume >= 5)
for(var/mob/living/simple_animal/slime/M in T)
M.adjustToxLoss(rand(15,30))
if(reac_volume >= 1) // Make Freezy Foam and anti-fire grenades!
if(istype(T, /turf/open))
var/turf/open/OT = T
OT.MakeSlippery(wet_setting=TURF_WET_ICE, min_wet_time=10, wet_time_to_add=reac_volume) // Is less effective in high pressure/high heat capacity environments. More effective in low pressure.
OT.air.temperature -= MOLES_CELLSTANDARD*100*reac_volume/OT.air.heat_capacity() // reduces environment temperature by 5K per unit.
/datum/reagent/consumable/condensedcapsaicin
name = "Condensed Capsaicin"
id = "condensedcapsaicin"
description = "A chemical agent used for self-defense and in police work."
color = "#B31008" // rgb: 179, 16, 8
/datum/reagent/consumable/condensedcapsaicin/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(!istype(M, /mob/living/carbon/human) && !istype(M, /mob/living/carbon/monkey))
return
var/mob/living/carbon/victim = M
if(method == TOUCH || method == VAPOR)
//check for protection
var/mouth_covered = 0
var/eyes_covered = 0
var/obj/item/safe_thing = null
//monkeys and humans can have masks
if( victim.wear_mask )
if ( victim.wear_mask.flags_cover & MASKCOVERSEYES )
eyes_covered = 1
safe_thing = victim.wear_mask
if ( victim.wear_mask.flags_cover & MASKCOVERSMOUTH )
mouth_covered = 1
safe_thing = victim.wear_mask
//only humans can have helmets and glasses
if(istype(victim, /mob/living/carbon/human))
var/mob/living/carbon/human/H = victim
if( H.head )
if ( H.head.flags_cover & MASKCOVERSEYES )
eyes_covered = 1
safe_thing = H.head
if ( H.head.flags_cover & MASKCOVERSMOUTH )
mouth_covered = 1
safe_thing = H.head
if(H.glasses)
eyes_covered = 1
if ( !safe_thing )
safe_thing = H.glasses
//actually handle the pepperspray effects
if ( eyes_covered && mouth_covered )
return
else if ( mouth_covered ) // Reduced effects if partially protected
if(prob(5))
victim.emote("scream")
victim.blur_eyes(3)
victim.blind_eyes(2)
victim.confused = max(M.confused, 3)
victim.damageoverlaytemp = 60
victim.Weaken(3)
victim.drop_item()
return
else if ( eyes_covered ) // Eye cover is better than mouth cover
victim.blur_eyes(3)
victim.damageoverlaytemp = 30
return
else // Oh dear :D
if(prob(5))
victim.emote("scream")
victim.blur_eyes(5)
victim.blind_eyes(3)
victim.confused = max(M.confused, 6)
victim.damageoverlaytemp = 75
victim.Weaken(5)
victim.drop_item()
victim.update_damage_hud()
/datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/M)
if(prob(5))
M.visible_message("<span class='warning'>[M] [pick("dry heaves!","coughs!","splutters!")]</span>")
..()
/datum/reagent/consumable/sodiumchloride
name = "Table Salt"
id = "sodiumchloride"
description = "A salt made of sodium chloride. Commonly used to season food."
reagent_state = SOLID
color = "#FFFFFF" // rgb: 255,255,255
/datum/reagent/consumable/sodiumchloride/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(!istype(M))
return
if(M.has_bane(BANE_SALT))
M.mind.disrupt_spells(-200)
/datum/reagent/consumable/sodiumchloride/reaction_turf(turf/T, reac_volume) //Creates an umbra-blocking salt pile
if(!istype(T))
return
if(reac_volume < 1)
return
new/obj/effect/decal/cleanable/salt(T)
/datum/reagent/consumable/blackpepper
name = "Black Pepper"
id = "blackpepper"
description = "A powder ground from peppercorns. *AAAACHOOO*"
reagent_state = SOLID
// no color (ie, black)
/datum/reagent/consumable/coco
name = "Coco Powder"
id = "cocoa"
description = "A fatty, bitter paste made from coco beans."
reagent_state = SOLID
nutriment_factor = 5 * REAGENTS_METABOLISM
color = "#302000" // rgb: 48, 32, 0
/datum/reagent/consumable/hot_coco
name = "Hot Chocolate"
id = "hot_coco"
description = "Made with love! And coco beans."
nutriment_factor = 3 * REAGENTS_METABOLISM
color = "#403010" // rgb: 64, 48, 16
/datum/reagent/consumable/hot_coco/on_mob_life(mob/living/M)
if (M.bodytemperature < 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = min(310, M.bodytemperature + (5 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
/datum/reagent/mushroomhallucinogen
name = "Mushroom Hallucinogen"
id = "mushroomhallucinogen"
description = "A strong hallucinogenic drug derived from certain species of mushroom."
color = "#E700E7" // rgb: 231, 0, 231
metabolization_rate = 0.2 * REAGENTS_METABOLISM
/datum/reagent/mushroomhallucinogen/on_mob_life(mob/living/M)
if(!M.slurring)
M.slurring = 1
switch(current_cycle)
if(1 to 5)
M.Dizzy(5)
M.set_drugginess(30)
if(prob(10))
M.emote(pick("twitch","giggle"))
if(5 to 10)
M.Jitter(10)
M.Dizzy(10)
M.set_drugginess(35)
if(prob(20))
M.emote(pick("twitch","giggle"))
if (10 to INFINITY)
M.Jitter(20)
M.Dizzy(20)
M.set_drugginess(40)
if(prob(30))
M.emote(pick("twitch","giggle"))
..()
/datum/reagent/consumable/sprinkles
name = "Sprinkles"
id = "sprinkles"
description = "Multi-colored little bits of sugar, commonly found on donuts. Loved by cops."
color = "#FF00FF" // rgb: 255, 0, 255
/datum/reagent/consumable/sprinkles/on_mob_life(mob/living/M)
if(istype(M, /mob/living/carbon/human) && M.job in list("Security Officer", "Head of Security", "Detective", "Warden"))
M.heal_organ_damage(1,1, 0)
. = 1
..()
/datum/reagent/consumable/cornoil
name = "Corn Oil"
id = "cornoil"
description = "An oil derived from various types of corn."
nutriment_factor = 20 * REAGENTS_METABOLISM
color = "#302000" // rgb: 48, 32, 0
/datum/reagent/consumable/cornoil/reaction_turf(turf/open/T, reac_volume)
if (!istype(T))
return
T.MakeSlippery(min_wet_time = 10, wet_time_to_add = reac_volume*2)
var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T)
if(hotspot)
var/datum/gas_mixture/lowertemp = T.remove_air( T:air:total_moles() )
lowertemp.temperature = max( min(lowertemp.temperature-2000,lowertemp.temperature / 2) ,0)
lowertemp.react()
T.assume_air(lowertemp)
qdel(hotspot)
/datum/reagent/consumable/enzyme
name = "Universal Enzyme"
id = "enzyme"
description = "A universal enzyme used in the preperation of certain chemicals and foods."
color = "#365E30" // rgb: 54, 94, 48
/datum/reagent/consumable/dry_ramen
name = "Dry Ramen"
id = "dry_ramen"
description = "Space age food, since August 25, 1958. Contains dried noodles, vegetables, and chemicals that boil in contact with water."
reagent_state = SOLID
color = "#302000" // rgb: 48, 32, 0
/datum/reagent/consumable/hot_ramen
name = "Hot Ramen"
id = "hot_ramen"
description = "The noodles are boiled, the flavors are artificial, just like being back in school."
nutriment_factor = 5 * REAGENTS_METABOLISM
color = "#302000" // rgb: 48, 32, 0
/datum/reagent/consumable/hot_ramen/on_mob_life(mob/living/M)
if (M.bodytemperature < 310)//310 is the normal bodytemp. 310.055
M.bodytemperature = min(310, M.bodytemperature + (10 * TEMPERATURE_DAMAGE_COEFFICIENT))
..()
/datum/reagent/consumable/hell_ramen
name = "Hell Ramen"
id = "hell_ramen"
description = "The noodles are boiled, the flavors are artificial, just like being back in school."
nutriment_factor = 5 * REAGENTS_METABOLISM
color = "#302000" // rgb: 48, 32, 0
/datum/reagent/consumable/hell_ramen/on_mob_life(mob/living/M)
M.bodytemperature += 10 * TEMPERATURE_DAMAGE_COEFFICIENT
..()
/datum/reagent/consumable/flour
name = "Flour"
id = "flour"
description = "This is what you rub all over yourself to pretend to be a ghost."
reagent_state = SOLID
color = "#FFFFFF" // rgb: 0, 0, 0
/datum/reagent/consumable/flour/reaction_turf(turf/T, reac_volume)
if(!istype(T, /turf/open/space))
var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/flour(T)
reagentdecal.reagents.add_reagent("flour", reac_volume)
/datum/reagent/consumable/cherryjelly
name = "Cherry Jelly"
id = "cherryjelly"
description = "Totally the best. Only to be spread on foods with excellent lateral symmetry."
color = "#801E28" // rgb: 128, 30, 40
/datum/reagent/consumable/bluecherryjelly
name = "Blue Cherry Jelly"
id = "bluecherryjelly"
description = "Blue and tastier kind of cherry jelly."
color = "#00F0FF"
/datum/reagent/consumable/rice
name = "Rice"
id = "rice"
description = "tiny nutritious grains"
reagent_state = SOLID
nutriment_factor = 3 * REAGENTS_METABOLISM
color = "#FFFFFF" // rgb: 0, 0, 0
/datum/reagent/consumable/vanilla
name = "Vanilla Powder"
id = "vanilla"
description = "A fatty, bitter paste made from vanilla pods."
reagent_state = SOLID
nutriment_factor = 5 * REAGENTS_METABOLISM
color = "#FFFACD"
/datum/reagent/consumable/eggyolk
name = "Egg Yolk"
id = "eggyolk"
description = "It's full of protein."
color = "#FFB500"
/datum/reagent/consumable/corn_starch
name = "Corn Starch"
id = "corn_starch"
description = "A slippery solution."
color = "#C8A5DC"
/datum/reagent/consumable/corn_syrup
name = "Corn Syrup"
id = "corn_syrup"
description = "Decays into sugar."
color = "#C8A5DC"
metabolization_rate = 3 * REAGENTS_METABOLISM
/datum/reagent/consumable/corn_syrup/on_mob_life(mob/living/M)
holder.add_reagent("sugar", 3)
..()
/datum/reagent/consumable/honey
name = "honey"
id = "honey"
description = "Sweet sweet honey, decays into sugar."
color = "#d3a308"
nutriment_factor = 15 * REAGENTS_METABOLISM
/datum/reagent/consumable/honey/on_mob_life(mob/living/M)
M.reagents.add_reagent("sugar",3)
if(prob(20))
M.heal_organ_damage(3,1)
..()
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,208 @@
/datum/reagent/thermite
name = "Thermite"
id = "thermite"
description = "Thermite produces an aluminothermic reaction known as a thermite reaction. Can be used to melt walls."
reagent_state = SOLID
color = "#550000"
/datum/reagent/thermite/reaction_turf(turf/T, reac_volume)
if(reac_volume >= 1 && istype(T, /turf/closed/wall))
var/turf/closed/wall/Wall = T
if(istype(Wall, /turf/closed/wall/r_wall))
Wall.thermite = Wall.thermite+(reac_volume*2.5)
else
Wall.thermite = Wall.thermite+(reac_volume*10)
Wall.overlays = list()
Wall.add_overlay(image('icons/effects/effects.dmi',"thermite"))
/datum/reagent/thermite/on_mob_life(mob/living/M)
M.adjustFireLoss(1, 0)
..()
. = 1
/datum/reagent/nitroglycerin
name = "Nitroglycerin"
id = "nitroglycerin"
description = "Nitroglycerin is a heavy, colorless, oily, explosive liquid obtained by nitrating glycerol."
color = "#808080" // rgb: 128, 128, 128
/datum/reagent/stabilizing_agent
name = "Stabilizing Agent"
id = "stabilizing_agent"
description = "Keeps unstable chemicals stable. This does not work on everything."
reagent_state = LIQUID
color = "#FFFF00"
/datum/reagent/clf3
name = "Chlorine Trifluoride"
id = "clf3"
description = "Makes a temporary 3x3 fireball when it comes into existence, so be careful when mixing. ClF3 applied to a surface burns things that wouldn't otherwise burn, sometimes through the very floors of the station and exposing it to the vacuum of space."
reagent_state = LIQUID
color = "#FFC8C8"
metabolization_rate = 4
/datum/reagent/clf3/on_mob_life(mob/living/M)
M.adjust_fire_stacks(2)
var/burndmg = max(0.3*M.fire_stacks, 0.3)
M.adjustFireLoss(burndmg, 0)
..()
. = 1
/datum/reagent/clf3/reaction_turf(turf/T, reac_volume)
if(istype(T, /turf/open/floor/plating))
var/turf/open/floor/plating/F = T
if(prob(10 + F.burnt + 5*F.broken)) //broken or burnt plating is more susceptible to being destroyed
F.ChangeTurf(F.baseturf)
if(istype(T, /turf/open/floor/))
var/turf/open/floor/F = T
if(prob(reac_volume))
F.make_plating()
else if(prob(reac_volume))
F.burn_tile()
if(istype(F, /turf/open/floor/))
for(var/turf/turf in range(1,F))
if(!locate(/obj/effect/hotspot) in turf)
PoolOrNew(/obj/effect/hotspot, F)
if(istype(T, /turf/closed/wall/))
var/turf/closed/wall/W = T
if(prob(reac_volume))
W.ChangeTurf(/turf/open/floor/plating)
/datum/reagent/clf3/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(istype(M))
if(method != INGEST && method != INJECT)
M.adjust_fire_stacks(min(reac_volume/5, 10))
M.IgniteMob()
if(!locate(/obj/effect/hotspot) in M.loc)
PoolOrNew(/obj/effect/hotspot, M.loc)
/datum/reagent/sorium
name = "Sorium"
id = "sorium"
description = "Sends everything flying from the detonation point."
reagent_state = LIQUID
color = "#5A64C8"
/datum/reagent/liquid_dark_matter
name = "Liquid Dark Matter"
id = "liquid_dark_matter"
description = "Sucks everything into the detonation point."
reagent_state = LIQUID
color = "#210021"
/datum/reagent/blackpowder
name = "Black Powder"
id = "blackpowder"
description = "Explodes. Violently."
reagent_state = LIQUID
color = "#000000"
metabolization_rate = 0.05
/datum/reagent/blackpowder/on_ex_act()
var/location = get_turf(holder.my_atom)
var/datum/effect_system/reagents_explosion/e = new()
e.set_up(1 + round(volume/6, 1), location, 0, 0, message = 0)
e.start()
holder.clear_reagents()
/datum/reagent/flash_powder
name = "Flash Powder"
id = "flash_powder"
description = "Makes a very bright flash."
reagent_state = LIQUID
color = "#C8C8C8"
/datum/reagent/smoke_powder
name = "Smoke Powder"
id = "smoke_powder"
description = "Makes a large cloud of smoke that can carry reagents."
reagent_state = LIQUID
color = "#C8C8C8"
/datum/reagent/sonic_powder
name = "Sonic Powder"
id = "sonic_powder"
description = "Makes a deafening noise."
reagent_state = LIQUID
color = "#C8C8C8"
/datum/reagent/phlogiston
name = "Phlogiston"
id = "phlogiston"
description = "Catches you on fire and makes you ignite."
reagent_state = LIQUID
color = "#FA00AF"
/datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
M.IgniteMob()
..()
/datum/reagent/phlogiston/on_mob_life(mob/living/M)
M.adjust_fire_stacks(1)
var/burndmg = max(0.3*M.fire_stacks, 0.3)
M.adjustFireLoss(burndmg, 0)
..()
. = 1
/datum/reagent/napalm
name = "Napalm"
id = "napalm"
description = "Very flammable."
reagent_state = LIQUID
color = "#FA00AF"
/datum/reagent/napalm/on_mob_life(mob/living/M)
M.adjust_fire_stacks(1)
..()
/datum/reagent/napalm/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(istype(M))
if(method != INGEST && method != INJECT)
M.adjust_fire_stacks(min(reac_volume/4, 20))
/datum/reagent/cryostylane
name = "Cryostylane"
id = "cryostylane"
description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Cryostylane slowly cools all other reagents in the mob down to 0K."
color = "#0000DC"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/cryostylane/on_mob_life(mob/living/M) //TODO: code freezing into an ice cube
if(M.reagents.has_reagent("oxygen"))
M.reagents.remove_reagent("oxygen", 0.5)
M.bodytemperature -= 15
..()
/datum/reagent/cryostylane/on_tick()
if(holder.has_reagent("oxygen"))
holder.remove_reagent("oxygen", 1)
holder.chem_temp -= 10
holder.handle_reactions()
..()
/datum/reagent/cryostylane/reaction_turf(turf/T, reac_volume)
if(reac_volume >= 5)
for(var/mob/living/simple_animal/slime/M in T)
M.adjustToxLoss(rand(15,30))
/datum/reagent/pyrosium
name = "Pyrosium"
id = "pyrosium"
description = "Comes into existence at 20K. As long as there is sufficient oxygen for it to react with, Pyrosium slowly cools all other reagents in the mob down to 0K."
color = "#64FAC8"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/pyrosium/on_mob_life(mob/living/M)
if(M.reagents.has_reagent("oxygen"))
M.reagents.remove_reagent("oxygen", 0.5)
M.bodytemperature += 15
..()
/datum/reagent/pyrosium/on_tick()
if(holder.has_reagent("oxygen"))
holder.remove_reagent("oxygen", 1)
holder.chem_temp += 10
holder.handle_reactions()
..()
@@ -0,0 +1,751 @@
//////////////////////////Poison stuff (Toxins & Acids)///////////////////////
/datum/reagent/toxin
name = "Toxin"
id = "toxin"
description = "A toxic chemical."
color = "#CF3600" // rgb: 207, 54, 0
var/toxpwr = 1.5
/datum/reagent/toxin/on_mob_life(mob/living/M)
if(toxpwr)
M.adjustToxLoss(toxpwr*REM, 0)
. = 1
..()
/datum/reagent/toxin/amatoxin
name = "Amatoxin"
id = "amatoxin"
description = "A powerful poison derived from certain species of mushroom."
color = "#792300" // rgb: 121, 35, 0
toxpwr = 2.5
/datum/reagent/toxin/mutagen
name = "Unstable mutagen"
id = "mutagen"
description = "Might cause unpredictable mutations. Keep away from children."
color = "#00FF00"
toxpwr = 0
/datum/reagent/toxin/mutagen/reaction_mob(mob/living/carbon/M, method=TOUCH, reac_volume)
if(!..())
return
if(!M.has_dna())
return //No robots, AIs, aliens, Ians or other mobs should be affected by this.
if((method==VAPOR && prob(min(33, reac_volume))) || method==INGEST || method==PATCH || method==INJECT)
randmuti(M)
if(prob(98))
randmutb(M)
else
randmutg(M)
M.updateappearance()
M.domutcheck()
..()
/datum/reagent/toxin/mutagen/on_mob_life(mob/living/carbon/M)
if(istype(M))
M.apply_effect(5,IRRADIATE,0)
return ..()
/datum/reagent/toxin/plasma
name = "Plasma"
id = "plasma"
description = "Plasma in its liquid form."
color = "#8228A0"
toxpwr = 3
/datum/reagent/toxin/plasma/on_mob_life(mob/living/M)
if(holder.has_reagent("epinephrine"))
holder.remove_reagent("epinephrine", 2*REM)
if(iscarbon(M))
var/mob/living/carbon/C = M
C.adjustPlasma(20)
return ..()
/datum/reagent/toxin/plasma/reaction_obj(obj/O, reac_volume)
if((!O) || (!reac_volume))
return 0
O.atmos_spawn_air("plasma=[reac_volume];TEMP=[T20C]")
/datum/reagent/toxin/plasma/reaction_turf(turf/open/T, reac_volume)
if(istype(T))
T.atmos_spawn_air("plasma=[reac_volume];TEMP=[T20C]")
return
/datum/reagent/toxin/plasma/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with plasma is stronger than fuel!
if(!istype(M, /mob/living))
return
if(method == TOUCH || method == VAPOR)
M.adjust_fire_stacks(reac_volume / 5)
return
..()
/datum/reagent/toxin/lexorin
name = "Lexorin"
id = "lexorin"
description = "A powerful poison used to stop respiration."
color = "#7DC3A0"
toxpwr = 0
/datum/reagent/toxin/lexorin/on_mob_life(mob/living/M)
. = TRUE
var/mob/living/carbon/C
if(iscarbon(M))
C = M
CHECK_DNA_AND_SPECIES(C)
if(NOBREATH in C.dna.species.specflags)
. = FALSE
if(.)
M.adjustOxyLoss(5, 0)
if(C)
C.losebreath += 2
if(prob(20))
M.emote("gasp")
..()
/datum/reagent/toxin/slimejelly
name = "Slime Jelly"
id = "slimejelly"
description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL."
color = "#801E28" // rgb: 128, 30, 40
toxpwr = 0
/datum/reagent/toxin/slimejelly/on_mob_life(mob/living/M)
if(prob(10))
M << "<span class='danger'>Your insides are burning!</span>"
M.adjustToxLoss(rand(20,60)*REM, 0)
. = 1
else if(prob(40))
M.heal_organ_damage(5*REM,0, 0)
. = 1
..()
/datum/reagent/toxin/minttoxin
name = "Mint Toxin"
id = "minttoxin"
description = "Useful for dealing with undesirable customers."
color = "#CF3600" // rgb: 207, 54, 0
toxpwr = 0
/datum/reagent/toxin/minttoxin/on_mob_life(mob/living/M)
if(M.disabilities & FAT)
M.gib()
return ..()
/datum/reagent/toxin/carpotoxin
name = "Carpotoxin"
id = "carpotoxin"
description = "A deadly neurotoxin produced by the dreaded spess carp."
color = "#003333" // rgb: 0, 51, 51
toxpwr = 2
/datum/reagent/toxin/zombiepowder
name = "Zombie Powder"
id = "zombiepowder"
description = "A strong neurotoxin that puts the subject into a death-like state."
reagent_state = SOLID
color = "#669900" // rgb: 102, 153, 0
toxpwr = 0.5
/datum/reagent/toxin/zombiepowder/on_mob_life(mob/living/carbon/M)
M.status_flags |= FAKEDEATH
M.adjustOxyLoss(0.5*REM, 0)
M.Weaken(5, 0)
M.silent = max(M.silent, 5)
M.tod = worldtime2text()
..()
. = 1
/datum/reagent/toxin/zombiepowder/on_mob_delete(mob/M)
M.status_flags &= ~FAKEDEATH
..()
/datum/reagent/toxin/mindbreaker
name = "Mindbreaker Toxin"
id = "mindbreaker"
description = "A powerful hallucinogen. Not a thing to be messed with."
color = "#B31008" // rgb: 139, 166, 233
toxpwr = 0
/datum/reagent/toxin/mindbreaker/on_mob_life(mob/living/M)
M.hallucination += 10
return ..()
/datum/reagent/toxin/plantbgone
name = "Plant-B-Gone"
id = "plantbgone"
description = "A harmful toxic mixture to kill plantlife. Do not ingest!"
color = "#49002E" // rgb: 73, 0, 46
toxpwr = 1
/datum/reagent/toxin/plantbgone/reaction_obj(obj/O, reac_volume)
if(istype(O,/obj/structure/alien/weeds))
var/obj/structure/alien/weeds/alien_weeds = O
alien_weeds.take_damage(rand(15,35), BRUTE, 0) // Kills alien weeds pretty fast
else if(istype(O,/obj/effect/glowshroom)) //even a small amount is enough to kill it
qdel(O)
else if(istype(O,/obj/effect/spacevine))
var/obj/effect/spacevine/SV = O
SV.on_chem_effect(src)
/datum/reagent/toxin/plantbgone/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == VAPOR)
if(iscarbon(M))
var/mob/living/carbon/C = M
if(!C.wear_mask) // If not wearing a mask
var/damage = min(round(0.4*reac_volume, 0.1),10)
C.adjustToxLoss(damage)
/datum/reagent/toxin/plantbgone/weedkiller
name = "Weed Killer"
id = "weedkiller"
description = "A harmful toxic mixture to kill weeds. Do not ingest!"
color = "#4B004B" // rgb: 75, 0, 75
/datum/reagent/toxin/pestkiller
name = "Pest Killer"
id = "pestkiller"
description = "A harmful toxic mixture to kill pests. Do not ingest!"
color = "#4B004B" // rgb: 75, 0, 75
toxpwr = 1
/datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == VAPOR)
if(iscarbon(M))
var/mob/living/carbon/C = M
if(!C.wear_mask) // If not wearing a mask
var/damage = min(round(0.4*reac_volume, 0.1),10)
C.adjustToxLoss(damage)
/datum/reagent/toxin/spore
name = "Spore Toxin"
id = "spore"
description = "A natural toxin produced by blob spores that inhibits vision when ingested."
color = "#9ACD32"
toxpwr = 1
/datum/reagent/toxin/spore/on_mob_life(mob/living/M)
M.damageoverlaytemp = 60
M.update_damage_hud()
M.blur_eyes(3)
return ..()
/datum/reagent/toxin/spore_burning
name = "Burning Spore Toxin"
id = "spore_burning"
description = "A natural toxin produced by blob spores that induces combustion in its victim."
color = "#9ACD32"
toxpwr = 0.5
/datum/reagent/toxin/spore_burning/on_mob_life(mob/living/M)
M.adjust_fire_stacks(2)
M.IgniteMob()
return ..()
/datum/reagent/toxin/chloralhydrate
name = "Chloral Hydrate"
id = "chloralhydrate"
description = "A powerful sedative that induces confusion and drowsiness before putting its target to sleep."
reagent_state = SOLID
color = "#000067" // rgb: 0, 0, 103
toxpwr = 0
metabolization_rate = 1.5 * REAGENTS_METABOLISM
/datum/reagent/toxin/chloralhydrate/on_mob_life(mob/living/M)
switch(current_cycle)
if(1 to 10)
M.confused += 2
M.drowsyness += 2
if(10 to 50)
M.Sleeping(2, 0)
. = 1
if(51 to INFINITY)
M.Sleeping(2, 0)
M.adjustToxLoss((current_cycle - 50)*REM, 0)
. = 1
..()
/datum/reagent/toxin/chloralhydrate/delayed
id = "chloralhydrate2"
/datum/reagent/toxin/chloralhydrate/delayed/on_mob_life(mob/living/M)
switch(current_cycle)
if(1 to 10)
return
if(10 to 20)
M.confused += 1
M.drowsyness += 1
if(20 to INFINITY)
M.Sleeping(2, 0)
..()
/datum/reagent/toxin/beer2 //disguised as normal beer for use by emagged brobots
name = "Beer"
id = "beer2"
description = "A specially-engineered sedative disguised as beer. It induces instant sleep in its target."
color = "#664300" // rgb: 102, 67, 0
metabolization_rate = 1.5 * REAGENTS_METABOLISM
/datum/reagent/toxin/beer2/on_mob_life(mob/living/M)
switch(current_cycle)
if(1 to 50)
M.Sleeping(2, 0)
if(51 to INFINITY)
M.Sleeping(2, 0)
M.adjustToxLoss((current_cycle - 50)*REM, 0)
return ..()
/datum/reagent/toxin/coffeepowder
name = "Coffee Grounds"
id = "coffeepowder"
description = "Finely ground coffee beans, used to make coffee."
reagent_state = SOLID
color = "#5B2E0D" // rgb: 91, 46, 13
toxpwr = 0.5
/datum/reagent/toxin/teapowder
name = "Ground Tea Leaves"
id = "teapowder"
description = "Finely shredded tea leaves, used for making tea."
reagent_state = SOLID
color = "#7F8400" // rgb: 127, 132, 0
toxpwr = 0.5
/datum/reagent/toxin/mutetoxin //the new zombie powder.
name = "Mute Toxin"
id = "mutetoxin"
description = "A nonlethal poison that inhibits speech in its victim."
color = "#F0F8FF" // rgb: 240, 248, 255
toxpwr = 0
/datum/reagent/toxin/mutetoxin/on_mob_life(mob/living/carbon/M)
M.silent = max(M.silent, 3)
..()
/datum/reagent/toxin/staminatoxin
name = "Tirizene"
id = "tirizene"
description = "A nonlethal poison that causes extreme fatigue and weakness in its victim."
color = "#6E2828"
data = 13
toxpwr = 0
/datum/reagent/toxin/staminatoxin/on_mob_life(mob/living/carbon/M)
M.adjustStaminaLoss(REM * data, 0)
data = max(data - 1, 3)
..()
. = 1
/datum/reagent/toxin/polonium
name = "Polonium"
id = "polonium"
description = "An extremely radioactive material in liquid form. Ingestion results in fatal irradiation."
reagent_state = LIQUID
color = "#787878"
metabolization_rate = 0.125 * REAGENTS_METABOLISM
toxpwr = 0
/datum/reagent/toxin/polonium/on_mob_life(mob/living/M)
M.radiation += 4
..()
/datum/reagent/toxin/histamine
name = "Histamine"
id = "histamine"
description = "Histamine's effects become more dangerous depending on the dosage amount. They range from mildly annoying to incredibly lethal."
reagent_state = LIQUID
color = "#FA6464"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
overdose_threshold = 30
toxpwr = 0
/datum/reagent/toxin/histamine/on_mob_life(mob/living/M)
if(prob(50))
switch(pick(1, 2, 3, 4))
if(1)
M << "<span class='danger'>You can barely see!</span>"
M.blur_eyes(3)
if(2)
M.emote("cough")
if(3)
M.emote("sneeze")
if(4)
if(prob(75))
M << "You scratch at an itch."
M.adjustBruteLoss(2*REM, 0)
. = 1
..()
/datum/reagent/toxin/histamine/overdose_process(mob/living/M)
M.adjustOxyLoss(2*REM, 0)
M.adjustBruteLoss(2*REM, 0)
M.adjustToxLoss(2*REM, 0)
..()
. = 1
/datum/reagent/toxin/formaldehyde
name = "Formaldehyde"
id = "formaldehyde"
description = "Formaldehyde, on its own, is a fairly weak toxin. It contains trace amounts of Histamine, very rarely making it decay into Histamine.."
reagent_state = LIQUID
color = "#B4004B"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
toxpwr = 1
/datum/reagent/toxin/formaldehyde/on_mob_life(mob/living/M)
if(prob(5))
holder.add_reagent("histamine", pick(5,15))
holder.remove_reagent("formaldehyde", 1.2)
else
return ..()
/datum/reagent/toxin/venom
name = "Venom"
id = "venom"
description = "An exotic poison extracted from highly toxic fauna. Causes scaling amounts of toxin damage and bruising depending and dosage. Often decays into Histamine."
reagent_state = LIQUID
color = "#F0FFF0"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
toxpwr = 0
/datum/reagent/toxin/venom/on_mob_life(mob/living/M)
toxpwr = 0.2*volume
M.adjustBruteLoss((0.3*volume)*REM, 0)
. = 1
if(prob(15))
M.reagents.add_reagent("histamine", pick(5,10))
M.reagents.remove_reagent("venom", 1.1)
else
..()
/datum/reagent/toxin/neurotoxin2
name = "Neurotoxin"
id = "neurotoxin2"
description = "Neurotoxin will inhibit brain function and cause toxin damage before eventually knocking out its victim."
reagent_state = LIQUID
color = "#64916E"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
toxpwr = 0
/datum/reagent/toxin/neurotoxin2/on_mob_life(mob/living/M)
if(M.brainloss + M.toxloss <= 60)
M.adjustBrainLoss(1*REM)
M.adjustToxLoss(1*REM, 0)
. = 1
if(current_cycle >= 18)
M.Sleeping(2, 0)
. = 1
..()
/datum/reagent/toxin/cyanide
name = "Cyanide"
id = "cyanide"
description = "An infamous poison known for its use in assassination. Causes small amounts of toxin damage with a small chance of oxygen damage or a stun."
reagent_state = LIQUID
color = "#00B4FF"
metabolization_rate = 0.125 * REAGENTS_METABOLISM
toxpwr = 1.25
/datum/reagent/toxin/cyanide/on_mob_life(mob/living/M)
if(prob(5))
M.losebreath += 1
if(prob(8))
M << "You feel horrendously weak!"
M.Stun(2, 0)
M.adjustToxLoss(2*REM, 0)
return ..()
/datum/reagent/toxin/questionmark // food poisoning
name = "Bad Food"
id = "????"
description = "????"
reagent_state = LIQUID
color = "#d6d6d8"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
toxpwr = 0.5
/datum/reagent/toxin/itching_powder
name = "Itching Powder"
id = "itching_powder"
description = "A powder that induces itching upon contact with the skin. Causes the victim to scratch at their itches and has a very low chance to decay into Histamine."
reagent_state = LIQUID
color = "#C8C8C8"
metabolization_rate = 0.4 * REAGENTS_METABOLISM
toxpwr = 0
/datum/reagent/toxin/itching_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
if(method == TOUCH || method == VAPOR)
M.reagents.add_reagent("itching_powder", reac_volume)
/datum/reagent/toxin/itching_powder/on_mob_life(mob/living/M)
if(prob(15))
M << "You scratch at your head."
M.adjustBruteLoss(0.2*REM, 0)
. = 1
if(prob(15))
M << "You scratch at your leg."
M.adjustBruteLoss(0.2*REM, 0)
. = 1
if(prob(15))
M << "You scratch at your arm."
M.adjustBruteLoss(0.2*REM, 0)
. = 1
if(prob(3))
M.reagents.add_reagent("histamine",rand(1,3))
M.reagents.remove_reagent("itching_powder",1.2)
return
..()
/datum/reagent/toxin/initropidril
name = "Initropidril"
id = "initropidril"
description = "A powerful poison with insidious effects. It can cause stuns, lethal breathing failure, and cardiac arrest."
reagent_state = LIQUID
color = "#7F10C0"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
toxpwr = 2.5
/datum/reagent/toxin/initropidril/on_mob_life(mob/living/M)
if(prob(25))
var/picked_option = rand(1,3)
switch(picked_option)
if(1)
M.Stun(3, 0)
M.Weaken(3, 0)
. = 1
if(2)
M.losebreath += 10
M.adjustOxyLoss(rand(5,25), 0)
. = 1
if(3)
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(!H.heart_attack)
H.heart_attack = 1 // rip in pepperoni
if(H.stat == CONSCIOUS)
H.visible_message("<span class='userdanger'>[H] clutches at their chest as if their heart stopped!</span>")
else
H.losebreath += 10
H.adjustOxyLoss(rand(5,25), 0)
. = 1
return ..() || .
/datum/reagent/toxin/pancuronium
name = "Pancuronium"
id = "pancuronium"
description = "An undetectable toxin that swiftly incapacitates its victim. May also cause breathing failure."
reagent_state = LIQUID
color = "#195096"
metabolization_rate = 0.25 * REAGENTS_METABOLISM
toxpwr = 0
/datum/reagent/toxin/pancuronium/on_mob_life(mob/living/M)
if(current_cycle >= 10)
M.Paralyse(2, 0)
. = 1
if(prob(20))
M.losebreath += 4
..()
/datum/reagent/toxin/sodium_thiopental
name = "Sodium Thiopental"
id = "sodium_thiopental"
description = "Sodium Thiopental induces heavy weakness in its target as well as unconsciousness."
reagent_state = LIQUID
color = "#6496FA"
metabolization_rate = 0.75 * REAGENTS_METABOLISM
toxpwr = 0
/datum/reagent/toxin/sodium_thiopental/on_mob_life(mob/living/M)
if(current_cycle >= 10)
M.Sleeping(2, 0)
M.adjustStaminaLoss(10*REM, 0)
..()
. = 1
/datum/reagent/toxin/sulfonal
name = "Sulfonal"
id = "sulfonal"
description = "A stealthy poison that deals minor toxin damage and eventually puts the target to sleep."
reagent_state = LIQUID
color = "#7DC3A0"
metabolization_rate = 0.125 * REAGENTS_METABOLISM
toxpwr = 0.5
/datum/reagent/toxin/sulfonal/on_mob_life(mob/living/M)
if(current_cycle >= 22)
M.Sleeping(2, 0)
return ..()
/datum/reagent/toxin/amanitin
name = "Amanitin"
id = "amanitin"
description = "A very powerful delayed toxin. Upon full metabolization, a massive amount of toxin damage will be dealt depending on how long it has been in the victim's bloodstream."
reagent_state = LIQUID
color = "#FFFFFF"
toxpwr = 0
metabolization_rate = 0.5 * REAGENTS_METABOLISM
/datum/reagent/toxin/amanitin/on_mob_delete(mob/living/M)
M.adjustToxLoss(current_cycle*3*REM)
..()
/datum/reagent/toxin/lipolicide
name = "Lipolicide"
id = "lipolicide"
description = "A powerful toxin that will destroy fat cells, massively reducing body weight in a short time. More deadly to those without nutriment in their body."
reagent_state = LIQUID
color = "#F0FFF0"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
toxpwr = 0.5
/datum/reagent/toxin/lipolicide/on_mob_life(mob/living/M)
if(!holder.has_reagent("nutriment"))
M.adjustToxLoss(0.5*REM, 0)
M.nutrition = max( M.nutrition - 5 * REAGENTS_METABOLISM, 0)
M.overeatduration = 0
return ..()
/datum/reagent/toxin/coniine
name = "Coniine"
id = "coniine"
description = "Coniine metabolizes extremely slowly, but deals high amounts of toxin damage and stops breathing."
reagent_state = LIQUID
color = "#7DC3A0"
metabolization_rate = 0.06 * REAGENTS_METABOLISM
toxpwr = 1.75
/datum/reagent/toxin/coniine/on_mob_life(mob/living/M)
M.losebreath += 5
return ..()
/datum/reagent/toxin/curare
name = "Curare"
id = "curare"
description = "Causes slight toxin damage followed by chain-stunning and oxygen damage."
reagent_state = LIQUID
color = "#191919"
metabolization_rate = 0.125 * REAGENTS_METABOLISM
toxpwr = 1
/datum/reagent/toxin/curare/on_mob_life(mob/living/M)
if(current_cycle >= 11)
M.Weaken(3, 0)
M.adjustOxyLoss(1*REM, 0)
. = 1
..()
/datum/reagent/toxin/heparin //Based on a real-life anticoagulant. I'm not a doctor, so this won't be realistic.
name = "Heparin"
id = "heparin"
description = "A powerful anticoagulant. Victims will bleed uncontrollably and suffer scaling bruising."
reagent_state = LIQUID
color = "#C8C8C8" //RGB: 200, 200, 200
metabolization_rate = 0.2 * REAGENTS_METABOLISM
toxpwr = 0
/datum/reagent/toxin/heparin/on_mob_life(mob/living/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.bleed_rate = min(H.bleed_rate + 2, 8)
H.adjustBruteLoss(1, 0) //Brute damage increases with the amount they're bleeding
. = 1
return ..() || .
/datum/reagent/toxin/teslium //Teslium. Causes periodic shocks, and makes shocks against the target much more effective.
name = "Teslium"
id = "teslium"
description = "An unstable, electrically-charged metallic slurry. Periodically electrocutes its victim, and makes electrocutions against them more deadly."
reagent_state = LIQUID
color = "#20324D" //RGB: 32, 50, 77
metabolization_rate = 0.5 * REAGENTS_METABOLISM
toxpwr = 0
var/shock_timer = 0
/datum/reagent/toxin/teslium/on_mob_life(mob/living/M)
shock_timer++
if(shock_timer >= rand(5,30)) //Random shocks are wildly unpredictable
shock_timer = 0
M.electrocute_act(rand(5,20), "Teslium in their body", 1, 1) //Override because it's caused from INSIDE of you
playsound(M, "sparks", 50, 1)
..()
//ACID
/datum/reagent/toxin/acid
name = "Sulphuric acid"
id = "sacid"
description = "A strong mineral acid with the molecular formula H2SO4."
color = "#00FF32"
toxpwr = 1
var/acidpwr = 10 //the amount of protection removed from the armour
/datum/reagent/toxin/acid/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume)
if(!istype(C))
return
reac_volume = round(reac_volume,0.1)
if(method == INGEST)
C.adjustBruteLoss(min(6*toxpwr, reac_volume * toxpwr))
return
if(method == INJECT)
C.adjustBruteLoss(1.5 * min(6*toxpwr, reac_volume * toxpwr))
return
C.acid_act(acidpwr, toxpwr, reac_volume)
/datum/reagent/toxin/acid/reaction_obj(obj/O, reac_volume)
if(istype(O.loc, /mob)) //handled in human acid_act()
return
reac_volume = round(reac_volume,0.1)
O.acid_act(acidpwr, reac_volume)
/datum/reagent/toxin/acid/reaction_turf(turf/T, reac_volume)
if (!istype(T))
return
reac_volume = round(reac_volume,0.1)
for(var/obj/O in T)
O.acid_act(acidpwr, reac_volume)
/datum/reagent/toxin/acid/fluacid
name = "Fluorosulfuric acid"
id = "facid"
description = "Fluorosulfuric acid is a an extremely corrosive chemical substance."
color = "#5050FF"
toxpwr = 2
acidpwr = 42.0
/datum/reagent/toxin/acid/fluacid/on_mob_life(mob/living/M)
M.adjustFireLoss(current_cycle/10, 0) // I rode a tank, held a general's rank
. = 1 // When the blitzkrieg raged and the bodies stank
..() // Pleased to meet you, hope you guess my name
/datum/reagent/toxin/peaceborg/confuse
name = "Dizzying Solution"
id = "dizzysolution"
description = "Makes the target off balance and dizzy"
toxpwr = 0
metabolization_rate = 1.5 * REAGENTS_METABOLISM
/datum/reagent/toxin/peaceborg/confuse/on_mob_life(mob/living/M)
M.confused += 1
M.Dizzy(1)
if(prob(20))
M << "You feel confused and disorientated."
..()
/datum/reagent/toxin/peaceborg/tire
name = "Tiring Solution"
id = "tiresolution"
description = "An extremely weak stamina-toxin that tires out the target. Completely harmless."
toxpwr = 0
metabolization_rate = 1.5 * REAGENTS_METABOLISM
/datum/reagent/toxin/peaceborg/tire/on_mob_life(mob/living/M)
if(M.staminaloss < 50)
M.adjustStaminaLoss(10)
if(prob(30))
M << "You should sit down and take a rest..."
..()
@@ -0,0 +1,91 @@
/datum/chemical_reaction
var/name = null
var/id = null
var/result = null
var/list/required_reagents = new/list()
var/list/required_catalysts = new/list()
// Both of these variables are mostly going to be used with slime cores - but if you want to, you can use them for other things
var/atom/required_container = null // the container required for the reaction to happen
var/required_other = 0 // an integer required for the reaction to happen
var/result_amount = 0
var/secondary = 0 // set to nonzero if secondary reaction
var/mob_react = 0 //Determines if a chemical reaction can occur inside a mob
var/required_temp = 0
var/mix_message = "The solution begins to bubble." //The message shown to nearby people upon mixing, if applicable
var/mix_sound = 'sound/effects/bubbles.ogg' //The sound played upon mixing, if applicable
/datum/chemical_reaction/proc/on_reaction(datum/reagents/holder, created_volume)
return
//I recommend you set the result amount to the total volume of all components.
var/list/chemical_mob_spawn_meancritters = list() // list of possible hostile mobs
var/list/chemical_mob_spawn_nicecritters = list() // and possible friendly mobs
/datum/chemical_reaction/proc/chemical_mob_spawn(datum/reagents/holder, amount_to_spawn, reaction_name, mob_faction = "chemicalsummon")
if(holder && holder.my_atom)
if (chemical_mob_spawn_meancritters.len <= 0 || chemical_mob_spawn_nicecritters.len <= 0)
for (var/T in typesof(/mob/living/simple_animal))
var/mob/living/simple_animal/SA = T
switch(initial(SA.gold_core_spawnable))
if(1)
chemical_mob_spawn_meancritters += T
if(2)
chemical_mob_spawn_nicecritters += T
var/atom/A = holder.my_atom
var/turf/T = get_turf(A)
var/area/my_area = get_area(T)
var/message = "A [reaction_name] reaction has occured in [my_area.name]. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>JMP</A>)"
message += " (<A HREF='?_src_=vars;Vars=\ref[A]'>VV</A>)"
var/mob/M = get(A, /mob)
if(M)
message += " - Carried By: [key_name_admin(M)](<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>?</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</A>)"
else
message += " - Last Fingerprint: [(A.fingerprintslast ? A.fingerprintslast : "N/A")]"
message_admins(message, 0, 1)
playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1)
for(var/mob/living/carbon/C in viewers(get_turf(holder.my_atom), null))
C.flash_eyes()
for(var/i = 1, i <= amount_to_spawn, i++)
var/chosen
if (reaction_name == "Friendly Gold Slime")
chosen = pick(chemical_mob_spawn_nicecritters)
else
chosen = pick(chemical_mob_spawn_meancritters)
var/mob/living/simple_animal/C = new chosen
C.faction |= mob_faction
C.loc = get_turf(holder.my_atom)
if(prob(50))
for(var/j = 1, j <= rand(1, 3), j++)
step(C, pick(NORTH,SOUTH,EAST,WEST))
/datum/chemical_reaction/proc/goonchem_vortex(turf/T, setting_type, range)
for(var/atom/movable/X in orange(range, T))
if(istype(X, /obj/effect))
continue
if(!X.anchored)
var/distance = get_dist(X, T)
var/moving_power = max(range - distance, 1)
if(moving_power > 2) //if the vortex is powerful and we're close, we get thrown
if(setting_type)
var/atom/throw_target = get_edge_target_turf(X, get_dir(X, get_step_away(X, T)))
X.throw_at_fast(throw_target, moving_power, 1)
else
X.throw_at_fast(T, moving_power, 1)
else
spawn(0) //so everything moves at the same time.
if(setting_type)
for(var/i = 0, i < moving_power, i++)
sleep(2)
if(!step_away(X, T))
break
else
for(var/i = 0, i < moving_power, i++)
sleep(2)
if(!step_towards(X, T))
break
@@ -0,0 +1,48 @@
/datum/chemical_reaction/space_drugs
name = "Space Drugs"
id = "space_drugs"
result = "space_drugs"
required_reagents = list("mercury" = 1, "sugar" = 1, "lithium" = 1)
result_amount = 3
/datum/chemical_reaction/crank
name = "Crank"
id = "crank"
result = "crank"
required_reagents = list("diphenhydramine" = 1, "ammonia" = 1, "lithium" = 1, "sacid" = 1, "welding_fuel" = 1)
result_amount = 5
mix_message = "The mixture violently reacts, leaving behind a few crystalline shards."
required_temp = 390
/datum/chemical_reaction/krokodil
name = "Krokodil"
id = "krokodil"
result = "krokodil"
required_reagents = list("diphenhydramine" = 1, "morphine" = 1, "cleaner" = 1, "potassium" = 1, "phosphorus" = 1, "welding_fuel" = 1)
result_amount = 6
mix_message = "The mixture dries into a pale blue powder."
required_temp = 380
/datum/chemical_reaction/methamphetamine
name = "methamphetamine"
id = "methamphetamine"
result = "methamphetamine"
required_reagents = list("ephedrine" = 1, "iodine" = 1, "phosphorus" = 1, "hydrogen" = 1)
result_amount = 4
required_temp = 374
/datum/chemical_reaction/bath_salts
name = "bath_salts"
id = "bath_salts"
result = "bath_salts"
required_reagents = list("????" = 1, "saltpetre" = 1, "nutriment" = 1, "cleaner" = 1, "enzyme" = 1, "tea" = 1, "mercury" = 1)
result_amount = 7
required_temp = 374
/datum/chemical_reaction/aranesp
name = "aranesp"
id = "aranesp"
result = "aranesp"
required_reagents = list("epinephrine" = 1, "atropine" = 1, "morphine" = 1)
result_amount = 3
@@ -0,0 +1,250 @@
/datum/chemical_reaction/leporazine
name = "Leporazine"
id = "leporazine"
result = "leporazine"
required_reagents = list("silicon" = 1, "copper" = 1)
required_catalysts = list("plasma" = 5)
result_amount = 2
/datum/chemical_reaction/rezadone
name = "Rezadone"
id = "rezadone"
result = "rezadone"
required_reagents = list("carpotoxin" = 1, "cryptobiolin" = 1, "copper" = 1)
result_amount = 3
/datum/chemical_reaction/spaceacillin
name = "Spaceacillin"
id = "spaceacillin"
result = "spaceacillin"
required_reagents = list("cryptobiolin" = 1, "epinephrine" = 1)
result_amount = 2
/datum/chemical_reaction/inacusiate
name = "inacusiate"
id = "inacusiate"
result = "inacusiate"
required_reagents = list("water" = 1, "carbon" = 1, "charcoal" = 1)
result_amount = 2
/datum/chemical_reaction/synaptizine
name = "Synaptizine"
id = "synaptizine"
result = "synaptizine"
required_reagents = list("sugar" = 1, "lithium" = 1, "water" = 1)
result_amount = 3
/datum/chemical_reaction/charcoal
name = "Charcoal"
id = "charcoal"
result = "charcoal"
required_reagents = list("ash" = 1, "sodiumchloride" = 1)
result_amount = 2
mix_message = "The mixture yields a fine black powder."
required_temp = 380
/datum/chemical_reaction/silver_sulfadiazine
name = "Silver Sulfadiazine"
id = "silver_sulfadiazine"
result = "silver_sulfadiazine"
required_reagents = list("ammonia" = 1, "silver" = 1, "sulfur" = 1, "oxygen" = 1, "chlorine" = 1)
result_amount = 5
/datum/chemical_reaction/salglu_solution
name = "Saline-Glucose Solution"
id = "salglu_solution"
result = "salglu_solution"
required_reagents = list("sodiumchloride" = 1, "water" = 1, "sugar" = 1)
result_amount = 3
/datum/chemical_reaction/mine_salve
name = "Miner's Salve"
id = "mine_salve"
result = "mine_salve"
required_reagents = list("oil" = 1, "water" = 1, "iron" = 1)
result_amount = 3
/datum/chemical_reaction/mine_salve2
name = "Miner's Salve"
id = "mine_salve"
result = "mine_salve"
required_reagents = list("plasma" = 5, "iron" = 5, "sugar" = 1) // A sheet of plasma, a twinkie and a sheet of metal makes four of these
result_amount = 15
/datum/chemical_reaction/synthflesh
name = "Synthflesh"
id = "synthflesh"
result = "synthflesh"
required_reagents = list("blood" = 1, "carbon" = 1, "styptic_powder" = 1)
result_amount = 3
/datum/chemical_reaction/styptic_powder
name = "Styptic Powder"
id = "styptic_powder"
result = "styptic_powder"
required_reagents = list("aluminium" = 1, "hydrogen" = 1, "oxygen" = 1, "sacid" = 1)
result_amount = 4
mix_message = "The solution yields an astringent powder."
/datum/chemical_reaction/calomel
name = "Calomel"
id = "calomel"
result = "calomel"
required_reagents = list("mercury" = 1, "chlorine" = 1)
result_amount = 2
required_temp = 374
/datum/chemical_reaction/potass_iodide
name = "Potassium Iodide"
id = "potass_iodide"
result = "potass_iodide"
required_reagents = list("potassium" = 1, "iodine" = 1)
result_amount = 2
/datum/chemical_reaction/pen_acid
name = "Pentetic Acid"
id = "pen_acid"
result = "pen_acid"
required_reagents = list("welding_fuel" = 1, "chlorine" = 1, "ammonia" = 1, "formaldehyde" = 1, "sodium" = 1, "cyanide" = 1)
result_amount = 6
/datum/chemical_reaction/sal_acid
name = "Salicyclic Acid"
id = "sal_acid"
result = "sal_acid"
required_reagents = list("sodium" = 1, "phenol" = 1, "carbon" = 1, "oxygen" = 1, "sacid" = 1)
result_amount = 5
/datum/chemical_reaction/oxandrolone
name = "Oxandrolone"
id = "oxandrolone"
result = "oxandrolone"
required_reagents = list("carbon" = 3, "phenol" = 1, "hydrogen" = 1, "oxygen" = 1)
result_amount = 6
/datum/chemical_reaction/salbutamol
name = "Salbutamol"
id = "salbutamol"
result = "salbutamol"
required_reagents = list("sal_acid" = 1, "lithium" = 1, "aluminium" = 1, "bromine" = 1, "ammonia" = 1)
result_amount = 5
/datum/chemical_reaction/perfluorodecalin
name = "Perfluorodecalin"
id = "perfluorodecalin"
result = "perfluorodecalin"
required_reagents = list("hydrogen" = 1, "fluorine" = 1, "oil" = 1)
result_amount = 3
required_temp = 370
mix_message = "The mixture rapidly turns into a dense pink liquid."
/datum/chemical_reaction/ephedrine
name = "Ephedrine"
id = "ephedrine"
result = "ephedrine"
required_reagents = list("sugar" = 1, "oil" = 1, "hydrogen" = 1, "diethylamine" = 1)
result_amount = 4
mix_message = "The solution fizzes and gives off toxic fumes."
/datum/chemical_reaction/diphenhydramine
name = "Diphenhydramine"
id = "diphenhydramine"
result = "diphenhydramine"
required_reagents = list("oil" = 1, "carbon" = 1, "bromine" = 1, "diethylamine" = 1, "ethanol" = 1)
result_amount = 4
mix_message = "The mixture dries into a pale blue powder."
/datum/chemical_reaction/oculine
name = "Oculine"
id = "oculine"
result = "oculine"
required_reagents = list("charcoal" = 1, "carbon" = 1, "hydrogen" = 1)
result_amount = 3
mix_message = "The mixture sputters loudly and becomes a pale pink color."
/datum/chemical_reaction/atropine
name = "Atropine"
id = "atropine"
result = "atropine"
required_reagents = list("ethanol" = 1, "acetone" = 1, "diethylamine" = 1, "phenol" = 1, "sacid" = 1)
result_amount = 5
/datum/chemical_reaction/epinephrine
name = "Epinephrine"
id = "epinephrine"
result = "epinephrine"
required_reagents = list("phenol" = 1, "acetone" = 1, "diethylamine" = 1, "oxygen" = 1, "chlorine" = 1, "hydrogen" = 1)
result_amount = 6
/datum/chemical_reaction/strange_reagent
name = "Strange Reagent"
id = "strange_reagent"
result = "strange_reagent"
required_reagents = list("omnizine" = 1, "holywater" = 1, "mutagen" = 1)
result_amount = 3
/datum/chemical_reaction/mannitol
name = "Mannitol"
id = "mannitol"
result = "mannitol"
required_reagents = list("sugar" = 1, "hydrogen" = 1, "water" = 1)
result_amount = 3
mix_message = "The solution slightly bubbles, becoming thicker."
/datum/chemical_reaction/mutadone
name = "Mutadone"
id = "mutadone"
result = "mutadone"
required_reagents = list("mutagen" = 1, "acetone" = 1, "bromine" = 1)
result_amount = 3
/datum/chemical_reaction/antihol
name = "antihol"
id = "antihol"
result = "antihol"
required_reagents = list("ethanol" = 1, "charcoal" = 1, "copper" = 1)
result_amount = 3
/datum/chemical_reaction/cryoxadone
name = "Cryoxadone"
id = "cryoxadone"
result = "cryoxadone"
required_reagents = list("stable_plasma" = 1, "acetone" = 1, "mutagen" = 1)
result_amount = 3
/datum/chemical_reaction/haloperidol
name = "Haloperidol"
id = "haloperidol"
result = "haloperidol"
required_reagents = list("chlorine" = 1, "fluorine" = 1, "aluminium" = 1, "potass_iodide" = 1, "oil" = 1)
result_amount = 5
/datum/chemical_reaction/bicaridine
name = "Bicaridine"
id = "bicaridine"
result = "bicaridine"
required_reagents = list("carbon" = 1, "oxygen" = 1, "sugar" = 1)
result_amount = 3
/datum/chemical_reaction/kelotane
name = "Kelotane"
id = "kelotane"
result = "kelotane"
required_reagents = list("carbon" = 1, "silicon" = 1)
result_amount = 2
/datum/chemical_reaction/antitoxin
name = "Antitoxin"
id = "antitoxin"
result = "antitoxin"
required_reagents = list("nitrogen" = 1, "silicon" = 1, "potassium" = 1)
result_amount = 3
/datum/chemical_reaction/tricordrazine
name = "Tricordrazine"
id = "tricordrazine"
result = "tricordrazine"
required_reagents = list("bicaridine" = 1, "kelotane" = 1, "antitoxin" = 1)
result_amount = 3
@@ -0,0 +1,519 @@
/datum/chemical_reaction/sterilizine
name = "Sterilizine"
id = "sterilizine"
result = "sterilizine"
required_reagents = list("ethanol" = 1, "charcoal" = 1, "chlorine" = 1)
result_amount = 3
/datum/chemical_reaction/lube
name = "Space Lube"
id = "lube"
result = "lube"
required_reagents = list("water" = 1, "silicon" = 1, "oxygen" = 1)
result_amount = 4
/datum/chemical_reaction/spraytan
name = "Spray Tan"
id = "spraytan"
result = "spraytan"
required_reagents = list("orangejuice" = 1, "oil" = 1)
result_amount = 2
/datum/chemical_reaction/spraytan2
name = "Spray Tan"
id = "spraytan"
result = "spraytan"
required_reagents = list("orangejuice" = 1, "cornoil" = 1)
result_amount = 2
/datum/chemical_reaction/impedrezene
name = "Impedrezene"
id = "impedrezene"
result = "impedrezene"
required_reagents = list("mercury" = 1, "oxygen" = 1, "sugar" = 1)
result_amount = 2
/datum/chemical_reaction/cryptobiolin
name = "Cryptobiolin"
id = "cryptobiolin"
result = "cryptobiolin"
required_reagents = list("potassium" = 1, "oxygen" = 1, "sugar" = 1)
result_amount = 3
/datum/chemical_reaction/glycerol
name = "Glycerol"
id = "glycerol"
result = "glycerol"
required_reagents = list("cornoil" = 3, "sacid" = 1)
result_amount = 1
/datum/chemical_reaction/sodiumchloride
name = "Sodium Chloride"
id = "sodiumchloride"
result = "sodiumchloride"
required_reagents = list("water" = 1, "sodium" = 1, "chlorine" = 1)
result_amount = 3
/datum/chemical_reaction/plasmasolidification
name = "Solid Plasma"
id = "solidplasma"
result = null
required_reagents = list("iron" = 5, "frostoil" = 5, "plasma" = 20)
result_amount = 1
mob_react = 1
/datum/chemical_reaction/plasmasolidification/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
new /obj/item/stack/sheet/mineral/plasma(location)
return
/datum/chemical_reaction/capsaicincondensation
name = "Capsaicincondensation"
id = "capsaicincondensation"
result = "condensedcapsaicin"
required_reagents = list("capsaicin" = 1, "ethanol" = 5)
result_amount = 5
/datum/chemical_reaction/soapification
name = "Soapification"
id = "soapification"
result = null
required_reagents = list("liquidgibs" = 10, "lye" = 10) // requires two scooped gib tiles
required_temp = 374
result_amount = 1
mob_react = 1
/datum/chemical_reaction/soapification/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
new /obj/item/weapon/soap/homemade(location)
return
/datum/chemical_reaction/candlefication
name = "Candlefication"
id = "candlefication"
result = null
required_reagents = list("liquidgibs" = 5, "oxygen" = 5) //
required_temp = 374
result_amount = 1
mob_react = 1
/datum/chemical_reaction/candlefication/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
new /obj/item/candle(location)
return
/datum/chemical_reaction/meatification
name = "Meatification"
id = "meatification"
result = null
required_reagents = list("liquidgibs" = 10, "nutriment" = 10, "carbon" = 10)
result_amount = 1
mob_react = 1
/datum/chemical_reaction/meatification/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/meatproduct(location)
return
/datum/chemical_reaction/carbondioxide
name = "Direct Carbon Oxidation"
id = "burningcarbon"
result = "co2"
required_reagents = list("carbon" = 1, "oxygen" = 2)
required_temp = 777 // pure carbon isn't especially reactive.
result_amount = 3
////////////////////////////////// VIROLOGY //////////////////////////////////////////
/datum/chemical_reaction/virus_food
name = "Virus Food"
id = "virusfood"
result = "virusfood"
required_reagents = list("water" = 5, "milk" = 5)
result_amount = 15
/datum/chemical_reaction/virus_food_mutagen
name = "mutagenic agar"
id = "mutagenvirusfood"
result = "mutagenvirusfood"
required_reagents = list("mutagen" = 1, "virusfood" = 1)
result_amount = 1
/datum/chemical_reaction/virus_food_synaptizine
name = "virus rations"
id = "synaptizinevirusfood"
result = "synaptizinevirusfood"
required_reagents = list("synaptizine" = 1, "virusfood" = 1)
result_amount = 1
/datum/chemical_reaction/virus_food_plasma
name = "virus plasma"
id = "plasmavirusfood"
result = "plasmavirusfood"
required_reagents = list("plasma" = 1, "virusfood" = 1)
result_amount = 1
/datum/chemical_reaction/virus_food_plasma_synaptizine
name = "weakened virus plasma"
id = "weakplasmavirusfood"
result = "weakplasmavirusfood"
required_reagents = list("synaptizine" = 1, "plasmavirusfood" = 1)
result_amount = 2
/datum/chemical_reaction/virus_food_mutagen_sugar
name = "sucrose agar"
id = "sugarvirusfood"
result = "sugarvirusfood"
required_reagents = list("sugar" = 1, "mutagenvirusfood" = 1)
result_amount = 2
/datum/chemical_reaction/virus_food_mutagen_salineglucose
name = "sucrose agar"
id = "salineglucosevirusfood"
result = "sugarvirusfood"
required_reagents = list("salglu_solution" = 1, "mutagenvirusfood" = 1)
result_amount = 2
/datum/chemical_reaction/mix_virus
name = "Mix Virus"
id = "mixvirus"
result = "blood"
required_reagents = list("virusfood" = 1)
required_catalysts = list("blood" = 1)
var/level_min = 0
var/level_max = 2
/datum/chemical_reaction/mix_virus/on_reaction(datum/reagents/holder, created_volume)
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list
if(B && B.data)
var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"]
if(D)
D.Evolve(level_min, level_max)
/datum/chemical_reaction/mix_virus/mix_virus_2
name = "Mix Virus 2"
id = "mixvirus2"
required_reagents = list("mutagen" = 1)
level_min = 2
level_max = 4
/datum/chemical_reaction/mix_virus/mix_virus_3
name = "Mix Virus 3"
id = "mixvirus3"
required_reagents = list("plasma" = 1)
level_min = 4
level_max = 6
/datum/chemical_reaction/mix_virus/mix_virus_4
name = "Mix Virus 4"
id = "mixvirus4"
required_reagents = list("uranium" = 1)
level_min = 5
level_max = 6
/datum/chemical_reaction/mix_virus/mix_virus_5
name = "Mix Virus 5"
id = "mixvirus5"
required_reagents = list("mutagenvirusfood" = 1)
level_min = 3
level_max = 3
/datum/chemical_reaction/mix_virus/mix_virus_6
name = "Mix Virus 6"
id = "mixvirus6"
required_reagents = list("sugarvirusfood" = 1)
level_min = 4
level_max = 4
/datum/chemical_reaction/mix_virus/mix_virus_7
name = "Mix Virus 7"
id = "mixvirus7"
required_reagents = list("weakplasmavirusfood" = 1)
level_min = 5
level_max = 5
/datum/chemical_reaction/mix_virus/mix_virus_8
name = "Mix Virus 8"
id = "mixvirus8"
required_reagents = list("plasmavirusfood" = 1)
level_min = 6
level_max = 6
/datum/chemical_reaction/mix_virus/mix_virus_9
name = "Mix Virus 9"
id = "mixvirus9"
required_reagents = list("synaptizinevirusfood" = 1)
level_min = 1
level_max = 1
/datum/chemical_reaction/mix_virus/rem_virus
name = "Devolve Virus"
id = "remvirus"
required_reagents = list("synaptizine" = 1)
required_catalysts = list("blood" = 1)
/datum/chemical_reaction/mix_virus/rem_virus/on_reaction(datum/reagents/holder, created_volume)
var/datum/reagent/blood/B = locate(/datum/reagent/blood) in holder.reagent_list
if(B && B.data)
var/datum/disease/advance/D = locate(/datum/disease/advance) in B.data["viruses"]
if(D)
D.Devolve()
////////////////////////////////// foam and foam precursor ///////////////////////////////////////////////////
/datum/chemical_reaction/surfactant
name = "Foam surfactant"
id = "foam surfactant"
result = "fluorosurfactant"
required_reagents = list("fluorine" = 2, "carbon" = 2, "sacid" = 1)
result_amount = 5
/datum/chemical_reaction/foam
name = "Foam"
id = "foam"
result = null
required_reagents = list("fluorosurfactant" = 1, "water" = 1)
result_amount = 2
mob_react = 1
/datum/chemical_reaction/foam/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
for(var/mob/M in viewers(5, location))
M << "<span class='danger'>The solution spews out foam!</span>"
var/datum/effect_system/foam_spread/s = new()
s.set_up(created_volume, location, holder)
s.start()
holder.clear_reagents()
return
/datum/chemical_reaction/metalfoam
name = "Metal Foam"
id = "metalfoam"
result = null
required_reagents = list("aluminium" = 3, "foaming_agent" = 1, "facid" = 1)
result_amount = 5
mob_react = 1
/datum/chemical_reaction/metalfoam/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
for(var/mob/M in viewers(5, location))
M << "<span class='danger'>The solution spews out a metallic foam!</span>"
var/datum/effect_system/foam_spread/metal/s = new()
s.set_up(created_volume, location, holder, 1)
s.start()
holder.clear_reagents()
/datum/chemical_reaction/ironfoam
name = "Iron Foam"
id = "ironlfoam"
result = null
required_reagents = list("iron" = 3, "foaming_agent" = 1, "facid" = 1)
result_amount = 5
mob_react = 1
/datum/chemical_reaction/ironfoam/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
for(var/mob/M in viewers(5, location))
M << "<span class='danger'>The solution spews out a metallic foam!</span>"
var/datum/effect_system/foam_spread/metal/s = new()
s.set_up(created_volume, location, holder, 2)
s.start()
holder.clear_reagents()
/datum/chemical_reaction/foaming_agent
name = "Foaming Agent"
id = "foaming_agent"
result = "foaming_agent"
required_reagents = list("lithium" = 1, "hydrogen" = 1)
result_amount = 1
/////////////////////////////// Cleaning and hydroponics /////////////////////////////////////////////////
/datum/chemical_reaction/ammonia
name = "Ammonia"
id = "ammonia"
result = "ammonia"
required_reagents = list("hydrogen" = 3, "nitrogen" = 1)
result_amount = 3
/datum/chemical_reaction/diethylamine
name = "Diethylamine"
id = "diethylamine"
result = "diethylamine"
required_reagents = list ("ammonia" = 1, "ethanol" = 1)
result_amount = 2
/datum/chemical_reaction/space_cleaner
name = "Space cleaner"
id = "cleaner"
result = "cleaner"
required_reagents = list("ammonia" = 1, "water" = 1)
result_amount = 2
/datum/chemical_reaction/plantbgone
name = "Plant-B-Gone"
id = "plantbgone"
result = "plantbgone"
required_reagents = list("toxin" = 1, "water" = 4)
result_amount = 5
/datum/chemical_reaction/weedkiller
name = "Weed Killer"
id = "weedkiller"
result = "weedkiller"
required_reagents = list("toxin" = 1, "ammonia" = 4)
result_amount = 5
/datum/chemical_reaction/pestkiller
name = "Pest Killer"
id = "pestkiller"
result = "pestkiller"
required_reagents = list("toxin" = 1, "ethanol" = 4)
result_amount = 5
/datum/chemical_reaction/drying_agent
name = "Drying agent"
id = "drying_agent"
result = "drying_agent"
required_reagents = list("stable_plasma" = 2, "ethanol" = 1, "sodium" = 1)
result_amount = 3
//////////////////////////////////// Other goon stuff ///////////////////////////////////////////
/datum/chemical_reaction/acetone
name = "acetone"
id = "acetone"
result = "acetone"
required_reagents = list("oil" = 1, "welding_fuel" = 1, "oxygen" = 1)
result_amount = 3
/datum/chemical_reaction/carpet
name = "carpet"
id = "carpet"
result = "carpet"
required_reagents = list("space_drugs" = 1, "blood" = 1)
result_amount = 2
/datum/chemical_reaction/oil
name = "Oil"
id = "oil"
result = "oil"
required_reagents = list("welding_fuel" = 1, "carbon" = 1, "hydrogen" = 1)
result_amount = 3
/datum/chemical_reaction/phenol
name = "phenol"
id = "phenol"
result = "phenol"
required_reagents = list("water" = 1, "chlorine" = 1, "oil" = 1)
result_amount = 3
/datum/chemical_reaction/ash
name = "Ash"
id = "ash"
result = "ash"
required_reagents = list("oil" = 1)
result_amount = 1
required_temp = 480
/datum/chemical_reaction/colorful_reagent
name = "colorful_reagent"
id = "colorful_reagent"
result = "colorful_reagent"
required_reagents = list("stable_plasma" = 1, "radium" = 1, "space_drugs" = 1, "cryoxadone" = 1, "triple_citrus" = 1)
result_amount = 5
/datum/chemical_reaction/life
name = "Life"
id = "life"
result = null
required_reagents = list("strange_reagent" = 1, "synthflesh" = 1, "blood" = 1)
result_amount = 1
required_temp = 374
/datum/chemical_reaction/life/on_reaction(datum/reagents/holder, created_volume)
chemical_mob_spawn(holder, 1, "Life")
/datum/chemical_reaction/corgium
name = "corgium"
id = "corgium"
result = null
required_reagents = list("nutriment" = 1, "colorful_reagent" = 1, "strange_reagent" = 1, "blood" = 1)
result_amount = 1
required_temp = 374
/datum/chemical_reaction/corgium/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
new /mob/living/simple_animal/pet/dog/corgi(location)
..()
/datum/chemical_reaction/hair_dye
name = "hair_dye"
id = "hair_dye"
result = "hair_dye"
required_reagents = list("colorful_reagent" = 1, "radium" = 1, "space_drugs" = 1)
result_amount = 5
/datum/chemical_reaction/barbers_aid
name = "barbers_aid"
id = "barbers_aid"
result = "barbers_aid"
required_reagents = list("carpet" = 1, "radium" = 1, "space_drugs" = 1)
result_amount = 5
/datum/chemical_reaction/concentrated_barbers_aid
name = "concentrated_barbers_aid"
id = "concentrated_barbers_aid"
result = "concentrated_barbers_aid"
required_reagents = list("barbers_aid" = 1, "mutagen" = 1)
result_amount = 2
/datum/chemical_reaction/saltpetre
name = "saltpetre"
id = "saltpetre"
result = "saltpetre"
required_reagents = list("potassium" = 1, "nitrogen" = 1, "oxygen" = 3)
result_amount = 3
/datum/chemical_reaction/lye
name = "lye"
id = "lye"
result = "lye"
required_reagents = list("sodium" = 1, "hydrogen" = 1, "oxygen" = 1)
result_amount = 3
/datum/chemical_reaction/lye2
name = "lye"
id = "lye"
result = "lye"
required_reagents = list("ash" = 1, "water" = 1)
result_amount = 2
/datum/chemical_reaction/royal_bee_jelly
name = "royal bee jelly"
id = "royal_bee_jelly"
result = "royal_bee_jelly"
required_reagents = list("mutagen" = 10, "honey" = 40)
result_amount = 5
@@ -0,0 +1,411 @@
/datum/chemical_reaction/reagent_explosion
name = "Generic explosive"
id = "reagent_explosion"
result = null
var/strengthdiv = 10
var/modifier = 0
/datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, created_volume)
var/turf/T = get_turf(holder.my_atom)
var/inside_msg
if(ismob(holder.my_atom))
var/mob/M = holder.my_atom
inside_msg = " inside [key_name_admin(M)]"
var/lastkey = holder.my_atom.fingerprintslast
var/touch_msg = "N/A"
if(lastkey)
var/mob/toucher = get_mob_by_key(lastkey)
touch_msg = "[key_name_admin(lastkey)]<A HREF='?_src_=holder;adminmoreinfo=\ref[toucher]'>?</A> (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[toucher]'>FLW</A>)"
message_admins("Reagent explosion reaction occured at <a href='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[T.loc.name] (JMP)</a>[inside_msg]. Last Fingerprint: [touch_msg].")
log_game("Reagent explosion reaction occured at [T.loc.name] ([T.x],[T.y],[T.z]). Last Fingerprint: [lastkey ? lastkey : "N/A"]." )
var/datum/effect_system/reagents_explosion/e = new()
e.set_up(modifier + round(created_volume/strengthdiv, 1), T, 0, 0)
e.start()
holder.clear_reagents()
/datum/chemical_reaction/reagent_explosion/nitroglycerin
name = "Nitroglycerin"
id = "nitroglycerin"
result = "nitroglycerin"
required_reagents = list("glycerol" = 1, "facid" = 1, "sacid" = 1)
result_amount = 2
strengthdiv = 2
/datum/chemical_reaction/reagent_explosion/nitroglycerin/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
holder.remove_reagent("nitroglycerin", created_volume)
..()
/datum/chemical_reaction/reagent_explosion/nitroglycerin_explosion
name = "Nitroglycerin explosion"
id = "nitroglycerin_explosion"
required_reagents = list("nitroglycerin" = 1)
result_amount = 1
required_temp = 474
strengthdiv = 2
/datum/chemical_reaction/reagent_explosion/potassium_explosion
name = "Explosion"
id = "potassium_explosion"
required_reagents = list("water" = 1, "potassium" = 1)
result_amount = 2
strengthdiv = 10
/datum/chemical_reaction/reagent_explosion/potassium_explosion/holyboom
name = "Holy Explosion"
id = "holyboom"
required_reagents = list("holywater" = 1, "potassium" = 1)
/datum/chemical_reaction/reagent_explosion/potassium_explosion/holyboom/on_reaction(datum/reagents/holder, created_volume)
if(created_volume >= 150)
playsound(get_turf(holder.my_atom), 'sound/effects/pray.ogg', 80, 0, round(created_volume/48))
strengthdiv = 8
for(var/mob/living/simple_animal/revenant/R in get_hearers_in_view(7,get_turf(holder.my_atom)))
var/diety = ticker.Bible_deity_name
if(!ticker.Bible_deity_name)
diety = "Christ"
R << "<span class='userdanger'>The power of [diety] compels you!</span>"
R.stun(20)
R.reveal(100)
R.adjustHealth(50)
sleep(20)
for(var/mob/living/carbon/C in get_hearers_in_view(round(created_volume/48,1),get_turf(holder.my_atom)))
if(iscultist(C) || is_handofgod_cultist(C))
C << "<span class='userdanger'>The divine explosion sears you!</span>"
C.Weaken(2)
C.adjust_fire_stacks(5)
C.IgniteMob()
..()
/datum/chemical_reaction/blackpowder
name = "Black Powder"
id = "blackpowder"
result = "blackpowder"
required_reagents = list("saltpetre" = 1, "charcoal" = 1, "sulfur" = 1)
result_amount = 3
/datum/chemical_reaction/reagent_explosion/blackpowder_explosion
name = "Black Powder Kaboom"
id = "blackpowder_explosion"
required_reagents = list("blackpowder" = 1)
result_amount = 1
required_temp = 474
strengthdiv = 6
modifier = 1
mix_message = "<span class='boldannounce'>Sparks start flying around the black powder!</span>"
/datum/chemical_reaction/reagent_explosion/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume)
sleep(rand(50,100))
..()
/datum/chemical_reaction/thermite
name = "Thermite"
id = "thermite"
result = "thermite"
required_reagents = list("aluminium" = 1, "iron" = 1, "oxygen" = 1)
result_amount = 3
/datum/chemical_reaction/emp_pulse
name = "EMP Pulse"
id = "emp_pulse"
result = null
required_reagents = list("uranium" = 1, "iron" = 1) // Yes, laugh, it's the best recipe I could think of that makes a little bit of sense
result_amount = 2
/datum/chemical_reaction/emp_pulse/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
// 100 created volume = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes.
// 200 created volume = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades.
empulse(location, round(created_volume / 24), round(created_volume / 14), 1)
holder.clear_reagents()
/datum/chemical_reaction/stabilizing_agent
name = "stabilizing_agent"
id = "stabilizing_agent"
result = "stabilizing_agent"
required_reagents = list("iron" = 1, "oxygen" = 1, "hydrogen" = 1)
result_amount = 3
/datum/chemical_reaction/clf3
name = "Chlorine Trifluoride"
id = "clf3"
result = "clf3"
required_reagents = list("chlorine" = 1, "fluorine" = 3)
result_amount = 4
required_temp = 424
/datum/chemical_reaction/clf3/on_reaction(datum/reagents/holder, created_volume)
var/turf/T = get_turf(holder.my_atom)
for(var/turf/turf in range(1,T))
PoolOrNew(/obj/effect/hotspot, turf)
holder.chem_temp = 1000 // hot as shit
/datum/chemical_reaction/reagent_explosion/methsplosion/
name = "Meth explosion"
id = "methboom1"
result = "methboom1"
result_amount = 1
required_temp = 380 //slightly above the meth mix time.
required_reagents = list("methamphetamine" = 1)
strengthdiv = 6
modifier = 1
/datum/chemical_reaction/reagent_explosion/methsplosion/on_reaction(datum/reagents/holder, created_volume)
var/turf/T = get_turf(holder.my_atom)
for(var/turf/turf in range(1,T))
PoolOrNew(/obj/effect/hotspot, turf)
holder.chem_temp = 1000 // hot as shit
..()
/datum/chemical_reaction/reagent_explosion/methsplosion/methboom2
required_reagents = list("diethylamine" = 1, "iodine" = 1, "phosphorus" = 1, "hydrogen" = 1) //diethylamine is often left over from mixing the ephedrine.
required_temp = 300 //room temperature, chilling it even a little will prevent the explosion
result_amount = 4
/datum/chemical_reaction/sorium
name = "Sorium"
id = "sorium"
result = "sorium"
required_reagents = list("mercury" = 1, "oxygen" = 1, "nitrogen" = 1, "carbon" = 1)
result_amount = 4
/datum/chemical_reaction/sorium/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
holder.remove_reagent("sorium", created_volume)
var/turf/T = get_turf(holder.my_atom)
var/range = Clamp(sqrt(created_volume), 1, 6)
goonchem_vortex(T, 1, range)
/datum/chemical_reaction/sorium_vortex
name = "sorium_vortex"
id = "sorium_vortex"
result = null
result_amount = 1
required_reagents = list("sorium" = 1)
required_temp = 474
/datum/chemical_reaction/sorium_vortex/on_reaction(datum/reagents/holder, created_volume)
var/turf/T = get_turf(holder.my_atom)
var/range = Clamp(sqrt(created_volume), 1, 6)
goonchem_vortex(T, 1, range)
/datum/chemical_reaction/liquid_dark_matter
name = "Liquid Dark Matter"
id = "liquid_dark_matter"
result = "liquid_dark_matter"
required_reagents = list("stable_plasma" = 1, "radium" = 1, "carbon" = 1)
result_amount = 3
/datum/chemical_reaction/liquid_dark_matter/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
holder.remove_reagent("liquid_dark_matter", created_volume)
var/turf/T = get_turf(holder.my_atom)
var/range = Clamp(sqrt(created_volume), 1, 6)
goonchem_vortex(T, 0, range)
/datum/chemical_reaction/ldm_vortex
name = "LDM Vortex"
id = "ldm_vortex"
result = null
result_amount = 1
required_reagents = list("liquid_dark_matter" = 1)
required_temp = 474
/datum/chemical_reaction/ldm_vortex/on_reaction(datum/reagents/holder, created_volume)
var/turf/T = get_turf(holder.my_atom)
var/range = Clamp(sqrt(created_volume/2), 1, 6)
goonchem_vortex(T, 0, range)
/datum/chemical_reaction/flash_powder
name = "Flash powder"
id = "flash_powder"
result = "flash_powder"
required_reagents = list("aluminium" = 1, "potassium" = 1, "sulfur" = 1 )
result_amount = 3
/datum/chemical_reaction/flash_powder/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
var/location = get_turf(holder.my_atom)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(2, 1, location)
s.start()
for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location))
if(C.flash_eyes())
if(get_dist(C, location) < 4)
C.Weaken(5)
else
C.Stun(5)
holder.remove_reagent("flash_powder", created_volume)
/datum/chemical_reaction/flash_powder_flash
name = "Flash powder activation"
id = "flash_powder_flash"
result = null
required_reagents = list("flash_powder" = 1)
result_amount = 1
required_temp = 374
/datum/chemical_reaction/flash_powder_flash/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(2, 1, location)
s.start()
for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location))
if(C.flash_eyes())
if(get_dist(C, location) < 4)
C.Weaken(5)
else
C.Stun(5)
/datum/chemical_reaction/smoke_powder
name = "smoke_powder"
id = "smoke_powder"
result = "smoke_powder"
required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1)
result_amount = 3
/datum/chemical_reaction/smoke_powder/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
holder.remove_reagent("smoke_powder", created_volume)
var/smoke_radius = round(sqrt(created_volume / 2), 1)
var/location = get_turf(holder.my_atom)
var/datum/effect_system/smoke_spread/chem/S = new
S.attach(location)
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
if(S)
S.set_up(holder, smoke_radius, 0, location)
S.start()
if(holder && holder.my_atom)
holder.clear_reagents()
/datum/chemical_reaction/smoke_powder_smoke
name = "smoke_powder_smoke"
id = "smoke_powder_smoke"
result = null
required_reagents = list("smoke_powder" = 1)
required_temp = 374
result_amount = 1
secondary = 1
mob_react = 1
/datum/chemical_reaction/smoke_powder_smoke/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
var/smoke_radius = round(sqrt(created_volume / 2), 1)
var/datum/effect_system/smoke_spread/chem/S = new
S.attach(location)
playsound(location, 'sound/effects/smoke.ogg', 50, 1, -3)
if(S)
S.set_up(holder, smoke_radius, 0, location)
S.start()
if(holder && holder.my_atom)
holder.clear_reagents()
/datum/chemical_reaction/sonic_powder
name = "sonic_powder"
id = "sonic_powder"
result = "sonic_powder"
required_reagents = list("oxygen" = 1, "cola" = 1, "phosphorus" = 1)
result_amount = 3
/datum/chemical_reaction/sonic_powder/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
holder.remove_reagent("sonic_powder", created_volume)
var/location = get_turf(holder.my_atom)
playsound(location, 'sound/effects/bang.ogg', 25, 1)
for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location))
if(C.check_ear_prot())
continue
C.show_message("<span class='warning'>BANG</span>", 2)
C.Stun(5)
C.Weaken(5)
C.setEarDamage(C.ear_damage + rand(0, 5), max(C.ear_deaf,15))
if(C.ear_damage >= 15)
C << "<span class='warning'>Your ears start to ring badly!</span>"
else if(C.ear_damage >= 5)
C << "<span class='warning'>Your ears start to ring!</span>"
/datum/chemical_reaction/sonic_powder_deafen
name = "sonic_powder_deafen"
id = "sonic_powder_deafen"
result = null
required_reagents = list("sonic_powder" = 1)
required_temp = 374
result_amount = 1
/datum/chemical_reaction/sonic_powder_deafen/on_reaction(datum/reagents/holder, created_volume)
var/location = get_turf(holder.my_atom)
playsound(location, 'sound/effects/bang.ogg', 25, 1)
for(var/mob/living/carbon/C in get_hearers_in_view(created_volume/10, location))
if(C.check_ear_prot())
continue
C.show_message("<span class='warning'>BANG</span>", 2)
C.Stun(5)
C.Weaken(5)
C.setEarDamage(C.ear_damage + rand(0, 5), max(C.ear_deaf,15))
if(C.ear_damage >= 15)
C << "<span class='warning'>Your ears start to ring badly!</span>"
else if(C.ear_damage >= 5)
C << "<span class='warning'>Your ears start to ring!</span>"
/datum/chemical_reaction/phlogiston
name = "phlogiston"
id = "phlogiston"
result = "phlogiston"
required_reagents = list("phosphorus" = 1, "sacid" = 1, "stable_plasma" = 1)
result_amount = 3
/datum/chemical_reaction/phlogiston/on_reaction(datum/reagents/holder, created_volume)
if(holder.has_reagent("stabilizing_agent"))
return
var/turf/open/T = get_turf(holder.my_atom)
if(istype(T))
T.atmos_spawn_air("plasma=[created_volume];TEMP=1000")
holder.clear_reagents()
return
/datum/chemical_reaction/napalm
name = "Napalm"
id = "napalm"
result = "napalm"
required_reagents = list("oil" = 1, "welding_fuel" = 1, "ethanol" = 1 )
result_amount = 3
/datum/chemical_reaction/cryostylane
name = "cryostylane"
id = "cryostylane"
result = "cryostylane"
required_reagents = list("water" = 1, "stable_plasma" = 1, "nitrogen" = 1)
result_amount = 3
/datum/chemical_reaction/cryostylane/on_reaction(datum/reagents/holder, created_volume)
holder.chem_temp = 20 // cools the fuck down
return
/datum/chemical_reaction/pyrosium
name = "pyrosium"
id = "pyrosium"
result = "pyrosium"
required_reagents = list("stable_plasma" = 1, "radium" = 1, "phosphorus" = 1)
result_amount = 3
/datum/chemical_reaction/pyrosium/on_reaction(datum/reagents/holder, created_volume)
holder.chem_temp = 20 // also cools the fuck down
return
@@ -0,0 +1,711 @@
//Grey
/datum/chemical_reaction/slimespawn
name = "Slime Spawn"
id = "m_spawn"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/grey
required_other = 1
/datum/chemical_reaction/slimespawn/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/mob/living/simple_animal/slime/S
S = new(get_turf(holder.my_atom), "grey")
S.visible_message("<span class='danger'>Infused with plasma, the \
core begins to quiver and grow, and soon a new baby slime \
emerges from it!</span>")
/datum/chemical_reaction/slimeinaprov
name = "Slime epinephrine"
id = "m_inaprov"
result = "epinephrine"
required_reagents = list("water" = 5)
result_amount = 3
required_other = 1
required_container = /obj/item/slime_extract/grey
/datum/chemical_reaction/slimeinaprov/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
/datum/chemical_reaction/slimemonkey
name = "Slime Monkey"
id = "m_monkey"
result = null
required_reagents = list("blood" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/grey
required_other = 1
/datum/chemical_reaction/slimemonkey/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
for(var/i = 1, i <= 3, i++)
var /obj/item/weapon/reagent_containers/food/snacks/monkeycube/M = new /obj/item/weapon/reagent_containers/food/snacks/monkeycube
M.loc = get_turf(holder.my_atom)
//Green
/datum/chemical_reaction/slimemutate
name = "Mutation Toxin"
id = "mutationtoxin"
result = "mutationtoxin"
required_reagents = list("plasma" = 1)
result_amount = 1
required_other = 1
required_container = /obj/item/slime_extract/green
/datum/chemical_reaction/slimemutate/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
//Mutated Green
/datum/chemical_reaction/slimemutate_unstable
name = "Unstable Mutation Toxin"
id = "unstablemutationtoxin"
result = "unstablemutationtoxin"
required_reagents = list("radium" = 1)
result_amount = 1
required_other = 1
required_container = /obj/item/slime_extract/green
mix_message = "<span class='info'>The mixture rapidly expands and contracts, its appearance shifting into a sickening green.</span>"
/datum/chemical_reaction/slimemutate_unstable/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
//Metal
/datum/chemical_reaction/slimemetal
name = "Slime Metal"
id = "m_metal"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/metal
required_other = 1
/datum/chemical_reaction/slimemetal/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal
M.amount = 15
M.loc = get_turf(holder.my_atom)
var/obj/item/stack/sheet/plasteel/P = new /obj/item/stack/sheet/plasteel
P.amount = 5
P.loc = get_turf(holder.my_atom)
//Gold
/datum/chemical_reaction/slimecrit
name = "Slime Crit"
id = "m_tele"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/gold
required_other = 1
/datum/chemical_reaction/slimecrit/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/turf/T = get_turf(holder.my_atom)
T.visible_message("<span class='danger'>The slime extract begins to vibrate violently !</span>")
addtimer(src, "chemical_mob_spawn", 50, FALSE, holder, 5, "Gold Slime")
/datum/chemical_reaction/slimecritlesser
name = "Slime Crit Lesser"
id = "m_tele3"
result = null
required_reagents = list("blood" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/gold
required_other = 1
/datum/chemical_reaction/slimecritlesser/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/turf/T = get_turf(holder.my_atom)
T.visible_message("<span class='danger'>The slime extract begins to vibrate violently !</span>")
addtimer(src, "chemical_mob_spawn", 50, FALSE, holder, 3, "Lesser Gold Slime", "neutral")
/datum/chemical_reaction/slimecritfriendly
name = "Slime Crit Friendly"
id = "m_tele5"
result = null
required_reagents = list("water" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/gold
required_other = 1
/datum/chemical_reaction/slimecritfriendly/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/turf/T = get_turf(holder.my_atom)
T.visible_message("<span class='danger'>The slime extract begins to vibrate adorably !</span>")
addtimer(src, "chemical_mob_spawn", 50, FALSE, holder, 1, "Friendly Gold Slime", "neutral")
//Silver
/datum/chemical_reaction/slimebork
name = "Slime Bork"
id = "m_tele2"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/silver
required_other = 1
/datum/chemical_reaction/slimebork/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/list/blocked = list(/obj/item/weapon/reagent_containers/food/snacks,
/obj/item/weapon/reagent_containers/food/snacks/store/bread,
/obj/item/weapon/reagent_containers/food/snacks/breadslice,
/obj/item/weapon/reagent_containers/food/snacks/store/cake,
/obj/item/weapon/reagent_containers/food/snacks/cakeslice,
/obj/item/weapon/reagent_containers/food/snacks/store,
/obj/item/weapon/reagent_containers/food/snacks/pie,
/obj/item/weapon/reagent_containers/food/snacks/kebab,
/obj/item/weapon/reagent_containers/food/snacks/pizza,
/obj/item/weapon/reagent_containers/food/snacks/pizzaslice,
/obj/item/weapon/reagent_containers/food/snacks/salad,
/obj/item/weapon/reagent_containers/food/snacks/meat,
/obj/item/weapon/reagent_containers/food/snacks/meat/slab,
/obj/item/weapon/reagent_containers/food/snacks/soup,
/obj/item/weapon/reagent_containers/food/snacks/grown,
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom,
)
blocked |= typesof(/obj/item/weapon/reagent_containers/food/snacks/customizable)
var/list/borks = typesof(/obj/item/weapon/reagent_containers/food/snacks) - blocked
// BORK BORK BORK
playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1)
for(var/mob/living/carbon/C in viewers(get_turf(holder.my_atom), null))
C.flash_eyes()
for(var/i = 1, i <= 4 + rand(1,2), i++)
var/chosen = pick(borks)
var/obj/B = new chosen
if(B)
B.loc = get_turf(holder.my_atom)
if(prob(50))
for(var/j = 1, j <= rand(1, 3), j++)
step(B, pick(NORTH,SOUTH,EAST,WEST))
/datum/chemical_reaction/slimebork2
name = "Slime Bork 2"
id = "m_tele4"
result = null
required_reagents = list("water" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/silver
required_other = 1
/datum/chemical_reaction/slimebork2/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/list/borks = subtypesof(/obj/item/weapon/reagent_containers/food/drinks)
// BORK BORK BORK
playsound(get_turf(holder.my_atom), 'sound/effects/phasein.ogg', 100, 1)
for(var/mob/living/carbon/M in viewers(get_turf(holder.my_atom), null))
M.flash_eyes()
for(var/i = 1, i <= 4 + rand(1,2), i++)
var/chosen = pick(borks)
var/obj/B = new chosen
if(B)
B.loc = get_turf(holder.my_atom)
if(prob(50))
for(var/j = 1, j <= rand(1, 3), j++)
step(B, pick(NORTH,SOUTH,EAST,WEST))
//Blue
/datum/chemical_reaction/slimefrost
name = "Slime Frost Oil"
id = "m_frostoil"
result = "frostoil"
required_reagents = list("plasma" = 1)
result_amount = 10
required_container = /obj/item/slime_extract/blue
required_other = 1
/datum/chemical_reaction/slimefrost/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
/datum/chemical_reaction/slimestabilizer
name = "Slime Stabilizer"
id = "m_slimestabilizer"
result = null
required_reagents = list("blood" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/blue
required_other = 1
/datum/chemical_reaction/slimestabilizer/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion/stabilizer/P = new /obj/item/slimepotion/stabilizer
P.loc = get_turf(holder.my_atom)
//Dark Blue
/datum/chemical_reaction/slimefreeze
name = "Slime Freeze"
id = "m_freeze"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/darkblue
required_other = 1
/datum/chemical_reaction/slimefreeze/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/turf/T = get_turf(holder.my_atom)
T.visible_message("<span class='danger'>The slime extract begins to vibrate adorably!</span>")
addtimer(src, "freeze", 50, FALSE, holder)
/datum/chemical_reaction/slimefreeze/proc/freeze(datum/reagents/holder)
if(holder && holder.my_atom)
var/turf/T = get_turf(holder.my_atom)
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
for(var/mob/living/M in range(T, 7))
M.bodytemperature -= 240
M << "<span class='notice'>You feel a chill!</span>"
/datum/chemical_reaction/slimefireproof
name = "Slime Fireproof"
id = "m_fireproof"
result = null
required_reagents = list("water" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/darkblue
required_other = 1
/datum/chemical_reaction/slimefireproof/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion/fireproof/P = new /obj/item/slimepotion/fireproof
P.loc = get_turf(holder.my_atom)
//Orange
/datum/chemical_reaction/slimecasp
name = "Slime Capsaicin Oil"
id = "m_capsaicinoil"
result = "capsaicin"
required_reagents = list("blood" = 1)
result_amount = 10
required_container = /obj/item/slime_extract/orange
required_other = 1
/datum/chemical_reaction/slimecasp/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
/datum/chemical_reaction/slimefire
name = "Slime fire"
id = "m_fire"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/orange
required_other = 1
/datum/chemical_reaction/slimefire/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/turf/TU = get_turf(holder.my_atom)
TU.visible_message("<span class='danger'>The slime extract begins to vibrate adorably!</span>")
addtimer(src, "burn", 50, FALSE, holder)
/datum/chemical_reaction/slimefire/proc/burn(datum/reagents/holder)
if(holder && holder.my_atom)
var/turf/open/T = get_turf(holder.my_atom)
if(istype(T))
T.atmos_spawn_air("plasma=50;TEMP=1000")
//Yellow
/datum/chemical_reaction/slimeoverload
name = "Slime EMP"
id = "m_emp"
result = null
required_reagents = list("blood" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/yellow
required_other = 1
/datum/chemical_reaction/slimeoverload/on_reaction(datum/reagents/holder, created_volume)
feedback_add_details("slime_cores_used","[type]")
empulse(get_turf(holder.my_atom), 3, 7)
/datum/chemical_reaction/slimecell
name = "Slime Powercell"
id = "m_cell"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/yellow
required_other = 1
/datum/chemical_reaction/slimecell/on_reaction(datum/reagents/holder, created_volume)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/weapon/stock_parts/cell/high/slime/P = new /obj/item/weapon/stock_parts/cell/high/slime
P.loc = get_turf(holder.my_atom)
/datum/chemical_reaction/slimeglow
name = "Slime Glow"
id = "m_glow"
result = null
required_reagents = list("water" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/yellow
required_other = 1
/datum/chemical_reaction/slimeglow/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/turf/T = get_turf(holder.my_atom)
T.visible_message("<span class='danger'>The slime begins to emit a soft light. Squeezing it will cause it to grow brightly.</span>")
var/obj/item/device/flashlight/slime/F = new /obj/item/device/flashlight/slime
F.loc = get_turf(holder.my_atom)
//Purple
/datum/chemical_reaction/slimepsteroid
name = "Slime Steroid"
id = "m_steroid"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/purple
required_other = 1
/datum/chemical_reaction/slimepsteroid/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion/steroid/P = new /obj/item/slimepotion/steroid
P.loc = get_turf(holder.my_atom)
/datum/chemical_reaction/slimejam
name = "Slime Jam"
id = "m_jam"
result = "slimejelly"
required_reagents = list("sugar" = 1)
result_amount = 10
required_container = /obj/item/slime_extract/purple
required_other = 1
/datum/chemical_reaction/slimejam/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
//Dark Purple
/datum/chemical_reaction/slimeplasma
name = "Slime Plasma"
id = "m_plasma"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/darkpurple
required_other = 1
/datum/chemical_reaction/slimeplasma/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/stack/sheet/mineral/plasma/P = new /obj/item/stack/sheet/mineral/plasma
P.amount = 3
P.loc = get_turf(holder.my_atom)
//Red
/datum/chemical_reaction/slimemutator
name = "Slime Mutator"
id = "m_slimemutator"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/red
required_other = 1
/datum/chemical_reaction/slimemutator/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion/mutator/P = new /obj/item/slimepotion/mutator
P.loc = get_turf(holder.my_atom)
/datum/chemical_reaction/slimebloodlust
name = "Bloodlust"
id = "m_bloodlust"
result = null
required_reagents = list("blood" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/red
required_other = 1
/datum/chemical_reaction/slimebloodlust/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
for(var/mob/living/simple_animal/slime/slime in viewers(get_turf(holder.my_atom), null))
slime.rabid = 1
slime.visible_message("<span class='danger'>The [slime] is driven into a frenzy!</span>")
/datum/chemical_reaction/slimespeed
name = "Slime Speed"
id = "m_speed"
result = null
required_reagents = list("water" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/red
required_other = 1
/datum/chemical_reaction/slimespeed/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion/speed/P = new /obj/item/slimepotion/speed
P.loc = get_turf(holder.my_atom)
//Pink
/datum/chemical_reaction/docility
name = "Docility Potion"
id = "m_potion"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/pink
required_other = 1
/datum/chemical_reaction/docility/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion/docility/P = new /obj/item/slimepotion/docility
P.loc = get_turf(holder.my_atom)
//Black
/datum/chemical_reaction/slimemutate2
name = "Advanced Mutation Toxin"
id = "mutationtoxin2"
result = "amutationtoxin"
required_reagents = list("plasma" = 1)
result_amount = 1
required_other = 1
required_container = /obj/item/slime_extract/black
/datum/chemical_reaction/slimemutate2/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
//Oil
/datum/chemical_reaction/slimeexplosion
name = "Slime Explosion"
id = "m_explosion"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/oil
required_other = 1
/datum/chemical_reaction/slimeexplosion/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/turf/T = get_turf(holder.my_atom)
var/lastkey = holder.my_atom.fingerprintslast
var/touch_msg = "N/A"
if(lastkey)
var/mob/toucher = get_mob_by_key(lastkey)
touch_msg = "[key_name_admin(lastkey)]<A HREF='?_src_=holder;adminmoreinfo=\ref[toucher]'>?</A>(<A HREF='?_src_=holder;adminplayerobservefollow=\ref[toucher]'>FLW</A>)."
message_admins("Slime Explosion reaction started at <a href='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[T.loc.name] (JMP)</a>. Last Fingerprint: [touch_msg]")
log_game("Slime Explosion reaction started at [T.loc.name] ([T.x],[T.y],[T.z]). Last Fingerprint: [lastkey ? lastkey : "N/A"].")
T.visible_message("<span class='danger'>The slime extract begins to vibrate violently !</span>")
addtimer(src, "boom", 50, FALSE, holder)
/datum/chemical_reaction/slimeexplosion/proc/boom(datum/reagents/holder)
if(holder && holder.my_atom)
explosion(get_turf(holder.my_atom), 1 ,3, 6)
//Light Pink
/datum/chemical_reaction/slimepotion2
name = "Slime Potion 2"
id = "m_potion2"
result = null
result_amount = 1
required_container = /obj/item/slime_extract/lightpink
required_reagents = list("plasma" = 1)
required_other = 1
/datum/chemical_reaction/slimepotion2/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion/sentience/P = new /obj/item/slimepotion/sentience
P.loc = get_turf(holder.my_atom)
//Adamantine
/datum/chemical_reaction/slimegolem
name = "Slime Golem"
id = "m_golem"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/adamantine
required_other = 1
/datum/chemical_reaction/slimegolem/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/effect/golemrune/Z = new /obj/effect/golemrune
Z.loc = get_turf(holder.my_atom)
notify_ghosts("Golem rune created in [get_area(Z)].", 'sound/effects/ghost2.ogg', source = Z)
//Bluespace
/datum/chemical_reaction/slimefloor2
name = "Bluespace Floor"
id = "m_floor2"
result = null
required_reagents = list("blood" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/bluespace
required_other = 1
/datum/chemical_reaction/slimefloor2/on_reaction(datum/reagents/holder, created_volume)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/stack/tile/bluespace/P = new /obj/item/stack/tile/bluespace
P.amount = 25
P.loc = get_turf(holder.my_atom)
/datum/chemical_reaction/slimecrystal
name = "Slime Crystal"
id = "m_crystal"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/bluespace
required_other = 1
/datum/chemical_reaction/slimecrystal/on_reaction(datum/reagents/holder, created_volume)
feedback_add_details("slime_cores_used","[type]")
if(holder.my_atom)
var/obj/item/weapon/ore/bluespace_crystal/BC = new(get_turf(holder.my_atom))
BC.visible_message("<span class='notice'>The [BC.name] appears out of thin air!</span>")
//Cerulean
/datum/chemical_reaction/slimepsteroid2
name = "Slime Steroid 2"
id = "m_steroid2"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/cerulean
required_other = 1
/datum/chemical_reaction/slimepsteroid2/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion/enhancer/P = new /obj/item/slimepotion/enhancer
P.loc = get_turf(holder.my_atom)
/datum/chemical_reaction/slime_territory
name = "Slime Territory"
id = "s_territory"
result = null
required_reagents = list("blood" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/cerulean
required_other = 1
/datum/chemical_reaction/slime_territory/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/areaeditor/blueprints/slime/P = new /obj/item/areaeditor/blueprints/slime
P.loc = get_turf(holder.my_atom)
//Sepia
/datum/chemical_reaction/slimestop
name = "Slime Stop"
id = "m_stop"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/sepia
required_other = 1
/datum/chemical_reaction/slimestop/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/mob/mob = get_mob_by_key(holder.my_atom.fingerprintslast)
var/obj/effect/timestop/T = new /obj/effect/timestop
T.loc = get_turf(holder.my_atom)
T.immune += mob
T.timestop()
/datum/chemical_reaction/slimecamera
name = "Slime Camera"
id = "m_camera"
result = null
required_reagents = list("water" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/sepia
required_other = 1
/datum/chemical_reaction/slimecamera/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/device/camera/P = new /obj/item/device/camera
P.loc = get_turf(holder.my_atom)
var/obj/item/device/camera_film/Z = new /obj/item/device/camera_film
Z.loc = get_turf(holder.my_atom)
/datum/chemical_reaction/slimefloor
name = "Sepia Floor"
id = "m_floor"
result = null
required_reagents = list("blood" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/sepia
required_other = 1
/datum/chemical_reaction/slimefloor/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/stack/tile/sepia/P = new /obj/item/stack/tile/sepia
P.amount = 25
P.loc = get_turf(holder.my_atom)
//Pyrite
/datum/chemical_reaction/slimepaint
name = "Slime Paint"
id = "s_paint"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/pyrite
required_other = 1
/datum/chemical_reaction/slimepaint/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/list/paints = subtypesof(/obj/item/weapon/paint)
var/chosen = pick(paints)
var/obj/P = new chosen
if(P)
P.loc = get_turf(holder.my_atom)
//Rainbow :o)
/datum/chemical_reaction/slimeRNG
name = "Random Core"
id = "slimerng"
result = null
required_reagents = list("plasma" = 1)
result_amount = 1
required_other = 1
required_container = /obj/item/slime_extract/rainbow
/datum/chemical_reaction/slimeRNG/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/mob/living/simple_animal/slime/random/S
S = new(get_turf(holder.my_atom))
S.visible_message("<span class='danger'>Infused with plasma, the \
core begins to quiver and grow, and soon a new baby slime emerges \
from it!</span>")
/datum/chemical_reaction/slime_transfer
name = "Transfer Potion"
id = "slimetransfer"
result = null
required_reagents = list("blood" = 1)
result_amount = 1
required_other = 1
required_container = /obj/item/slime_extract/rainbow
/datum/chemical_reaction/slime_transfer/on_reaction(datum/reagents/holder)
feedback_add_details("slime_cores_used","[type]")
var/obj/item/slimepotion/transference/P = new /obj/item/slimepotion/transference
P.loc = get_turf(holder.my_atom)
@@ -0,0 +1,112 @@
/datum/chemical_reaction/formaldehyde
name = "formaldehyde"
id = "Formaldehyde"
result = "formaldehyde"
required_reagents = list("ethanol" = 1, "oxygen" = 1, "silver" = 1)
result_amount = 3
required_temp = 420
/datum/chemical_reaction/neurotoxin2
name = "neurotoxin2"
id = "neurotoxin2"
result = "neurotoxin2"
required_reagents = list("space_drugs" = 1)
result_amount = 1
required_temp = 674
/datum/chemical_reaction/cyanide
name = "Cyanide"
id = "cyanide"
result = "cyanide"
required_reagents = list("oil" = 1, "ammonia" = 1, "oxygen" = 1)
result_amount = 3
required_temp = 380
/datum/chemical_reaction/itching_powder
name = "Itching Powder"
id = "itching_powder"
result = "itching_powder"
required_reagents = list("welding_fuel" = 1, "ammonia" = 1, "charcoal" = 1)
result_amount = 3
/datum/chemical_reaction/facid
name = "Fluorosulfuric acid"
id = "facid"
result = "facid"
required_reagents = list("sacid" = 1, "fluorine" = 1, "hydrogen" = 1, "potassium" = 1)
result_amount = 4
required_temp = 380
/datum/chemical_reaction/sulfonal
name = "sulfonal"
id = "sulfonal"
result = "sulfonal"
required_reagents = list("acetone" = 1, "diethylamine" = 1, "sulfur" = 1)
result_amount = 3
/datum/chemical_reaction/lipolicide
name = "lipolicide"
id = "lipolicide"
result = "lipolicide"
required_reagents = list("mercury" = 1, "diethylamine" = 1, "ephedrine" = 1)
result_amount = 3
/datum/chemical_reaction/mutagen
name = "Unstable mutagen"
id = "mutagen"
result = "mutagen"
required_reagents = list("radium" = 1, "phosphorus" = 1, "chlorine" = 1)
result_amount = 3
/datum/chemical_reaction/lexorin
name = "Lexorin"
id = "lexorin"
result = "lexorin"
required_reagents = list("plasma" = 1, "hydrogen" = 1, "nitrogen" = 1)
result_amount = 3
/datum/chemical_reaction/chloralhydrate
name = "Chloral Hydrate"
id = "chloralhydrate"
result = "chloralhydrate"
required_reagents = list("ethanol" = 1, "chlorine" = 3, "water" = 1)
result_amount = 1
/datum/chemical_reaction/mutetoxin //i'll just fit this in here snugly between other unfun chemicals :v
name = "Mute toxin"
id = "mutetoxin"
result = "mutetoxin"
required_reagents = list("uranium" = 2, "water" = 1, "carbon" = 1)
result_amount = 2
/datum/chemical_reaction/zombiepowder
name = "Zombie Powder"
id = "zombiepowder"
result = "zombiepowder"
required_reagents = list("carpotoxin" = 5, "morphine" = 5, "copper" = 5)
result_amount = 2
/datum/chemical_reaction/mindbreaker
name = "Mindbreaker Toxin"
id = "mindbreaker"
result = "mindbreaker"
required_reagents = list("silicon" = 1, "hydrogen" = 1, "charcoal" = 1)
result_amount = 5
/datum/chemical_reaction/teslium
name = "Teslium"
id = "teslium"
result = "teslium"
required_reagents = list("plasma" = 1, "silver" = 1, "blackpowder" = 1)
result_amount = 3
mix_message = "<span class='danger'>A jet of sparks flies from the mixture as it merges into a flickering slurry.</span>"
required_temp = 400
/datum/chemical_reaction/heparin
name = "Heparin"
id = "Heparin"
result = "heparin"
required_reagents = list("formaldehyde" = 1, "sodium" = 1, "chlorine" = 1, "lithium" = 1)
result_amount = 4
mix_message = "<span class='danger'>The mixture thins and loses all color.</span>"
+111
View File
@@ -0,0 +1,111 @@
/obj/item/weapon/reagent_containers
name = "Container"
desc = "..."
icon = 'icons/obj/chemical.dmi'
icon_state = null
w_class = 1
var/amount_per_transfer_from_this = 5
var/list/possible_transfer_amounts = list(5,10,15,20,25,30)
var/volume = 30
var/list/list_reagents = null
var/spawned_disease = null
var/disease_amount = 20
var/spillable = 0
/obj/item/weapon/reagent_containers/New(location, vol = 0)
..()
if (isnum(vol) && vol > 0)
volume = vol
create_reagents(volume)
if(spawned_disease)
var/datum/disease/F = new spawned_disease(0)
var/list/data = list("viruses"= list(F))
reagents.add_reagent("blood", disease_amount, data)
if(list_reagents)
reagents.add_reagent_list(list_reagents)
/obj/item/weapon/reagent_containers/attack_self(mob/user)
if(possible_transfer_amounts.len)
var/i=0
for(var/A in possible_transfer_amounts)
i++
if(A == amount_per_transfer_from_this)
if(i<possible_transfer_amounts.len)
amount_per_transfer_from_this = possible_transfer_amounts[i+1]
else
amount_per_transfer_from_this = possible_transfer_amounts[1]
user << "<span class='notice'>[src]'s transfer amount is now [amount_per_transfer_from_this] units.</span>"
return
/obj/item/weapon/reagent_containers/attack(mob/M, mob/user, def_zone)
if(user.a_intent == "harm")
return ..()
/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user , flag)
return
/obj/item/weapon/reagent_containers/proc/reagentlist(obj/item/weapon/reagent_containers/snack) //Attack logs for regents in pills
var/data
if(snack.reagents.reagent_list && snack.reagents.reagent_list.len) //find a reagent list if there is and check if it has entries
for (var/datum/reagent/R in snack.reagents.reagent_list) //no reagents will be left behind
data += "[R.id]([R.volume] units); " //Using IDs because SOME chemicals(I'm looking at you, chlorhydrate-beer) have the same names as other chemicals.
return data
else return "No reagents"
/obj/item/weapon/reagent_containers/proc/canconsume(mob/eater, mob/user)
if(!iscarbon(eater))
return 0
var/mob/living/carbon/C = eater
var/covered = ""
if(C.is_mouth_covered(head_only = 1))
covered = "headgear"
else if(C.is_mouth_covered(mask_only = 1))
covered = "mask"
if(covered)
var/who = (isnull(user) || eater == user) ? "your" : "their"
user << "<span class='warning'>You have to remove [who] [covered] first!</span>"
return 0
return 1
/obj/item/weapon/reagent_containers/ex_act()
if(reagents)
for(var/datum/reagent/R in reagents.reagent_list)
R.on_ex_act()
..()
/obj/item/weapon/reagent_containers/fire_act()
reagents.chem_temp += 30
reagents.handle_reactions()
..()
/obj/item/weapon/reagent_containers/throw_impact(atom/target)
. = ..()
if(!reagents || !reagents.total_volume || !spillable)
return
if(ismob(target) && target.reagents)
reagents.total_volume *= rand(5,10) * 0.1 //Not all of it makes contact with the target
var/mob/M = target
var/R
target.visible_message("<span class='danger'>[M] has been splashed with something!</span>", \
"<span class='userdanger'>[M] has been splashed with something!</span>")
for(var/datum/reagent/A in reagents.reagent_list)
R += A.id + " ("
R += num2text(A.volume) + "),"
if(thrownby)
add_logs(thrownby, M, "splashed", R)
reagents.reaction(target, TOUCH)
else if((target.CanPass(src, get_turf(src))) && thrownby && thrownby.mind && thrownby.mind.assigned_role == "Bartender")
visible_message("<span class='notice'>[src] lands onto the [target.name] without spilling a single drop.</span>")
return
else
visible_message("<span class='notice'>[src] spills its contents all over [target].</span>")
reagents.reaction(target, TOUCH)
if(qdeleted(src))
return
reagents.clear_reagents()
@@ -0,0 +1,92 @@
/obj/item/weapon/reagent_containers/blood
name = "blood pack"
desc = "Contains blood used for transfusion. Must be attached to an IV drip."
icon = 'icons/obj/bloodpack.dmi'
icon_state = "empty"
volume = 200
var/blood_type = null
var/labelled = 0
/obj/item/weapon/reagent_containers/blood/New()
..()
if(blood_type != null)
reagents.add_reagent("blood", 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
update_icon()
/obj/item/weapon/reagent_containers/blood/on_reagent_change()
if(reagents)
var/datum/reagent/blood/B = reagents.has_reagent("blood")
if(B && B.data && B.data["blood_type"])
blood_type = B.data["blood_type"]
else
blood_type = null
update_pack_name()
update_icon()
/obj/item/weapon/reagent_containers/blood/proc/update_pack_name()
if(!labelled)
if(volume)
if(blood_type)
name = "blood pack [blood_type]"
else
name = "blood pack"
else
name = "empty blood pack"
/obj/item/weapon/reagent_containers/blood/update_icon()
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
if(0 to 9)
icon_state = "empty"
if(10 to 50)
icon_state = "half"
if(51 to INFINITY)
icon_state = "full"
/obj/item/weapon/reagent_containers/blood/random/New()
blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L")
..()
/obj/item/weapon/reagent_containers/blood/APlus
blood_type = "A+"
/obj/item/weapon/reagent_containers/blood/AMinus
blood_type = "A-"
/obj/item/weapon/reagent_containers/blood/BPlus
blood_type = "B+"
/obj/item/weapon/reagent_containers/blood/BMinus
blood_type = "B-"
/obj/item/weapon/reagent_containers/blood/OPlus
blood_type = "O+"
/obj/item/weapon/reagent_containers/blood/OMinus
blood_type = "O-"
/obj/item/weapon/reagent_containers/blood/lizard
blood_type = "L"
/obj/item/weapon/reagent_containers/blood/empty
name = "empty blood pack"
icon_state = "empty"
/obj/item/weapon/reagent_containers/blood/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/weapon/pen) || istype(I, /obj/item/toy/crayon))
var/t = stripped_input(user, "What would you like to label the blood pack?", name, null, 53)
if(!user.canUseTopic(src))
return
if(user.get_active_hand() != I)
return
if(loc != user)
return
if(t)
labelled = 1
name = "blood pack - [t]"
else
labelled = 0
update_pack_name()
else
return ..()
@@ -0,0 +1,228 @@
/*
Contains:
Borg Hypospray
Borg Shaker
Nothing to do with hydroponics in here. Sorry to dissapoint you.
*/
/*
Borg Hypospray
*/
/obj/item/weapon/reagent_containers/borghypo
name = "cyborg hypospray"
desc = "An advanced chemical synthesizer and injection system, designed for heavy-duty medical equipment."
icon = 'icons/obj/syringe.dmi'
item_state = "hypo"
icon_state = "borghypo"
amount_per_transfer_from_this = 5
volume = 30
possible_transfer_amounts = list()
var/mode = 1
var/charge_cost = 50
var/charge_tick = 0
var/recharge_time = 5 //Time it takes for shots to recharge (in seconds)
var/bypass_protection = 0 //If the hypospray can go through armor or thick material
var/list/datum/reagents/reagent_list = list()
var/list/reagent_ids = list("dexalin", "kelotane", "bicaridine", "antitoxin", "epinephrine", "spaceacillin")
var/list/modes = list() //Basically the inverse of reagent_ids. Instead of having numbers as "keys" and strings as values it has strings as keys and numbers as values.
//Used as list for input() in shakers.
/obj/item/weapon/reagent_containers/borghypo/New()
..()
var/iteration = 1
for(var/R in reagent_ids)
add_reagent(R)
modes[R] = iteration
iteration++
START_PROCESSING(SSobj, src)
/obj/item/weapon/reagent_containers/borghypo/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/weapon/reagent_containers/borghypo/process() //Every [recharge_time] seconds, recharge some reagents for the cyborg
charge_tick++
if(charge_tick >= recharge_time)
regenerate_reagents()
charge_tick = 0
//update_icon()
return 1
// Purely for testing purposes I swear~ //don't lie to me
/*
/obj/item/weapon/reagent_containers/borghypo/verb/add_cyanide()
set src in world
add_reagent("cyanide")
*/
// Use this to add more chemicals for the borghypo to produce.
/obj/item/weapon/reagent_containers/borghypo/proc/add_reagent(reagent)
reagent_ids |= reagent
var/datum/reagents/RG = new(30)
RG.my_atom = src
reagent_list += RG
var/datum/reagents/R = reagent_list[reagent_list.len]
R.add_reagent(reagent, 30)
/obj/item/weapon/reagent_containers/borghypo/proc/regenerate_reagents()
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
for(var/i in 1 to reagent_ids.len)
var/datum/reagents/RG = reagent_list[i]
if(RG.total_volume < RG.maximum_volume) //Don't recharge reagents and drain power if the storage is full.
R.cell.use(charge_cost) //Take power from borg...
RG.add_reagent(reagent_ids[i], 5) //And fill hypo with reagent.
/obj/item/weapon/reagent_containers/borghypo/attack(mob/living/carbon/M, mob/user)
var/datum/reagents/R = reagent_list[mode]
if(!R.total_volume)
user << "<span class='notice'>The injector is empty.</span>"
return
if(!istype(M))
return
if(R.total_volume && M.can_inject(user, 1, bypass_protection))
M << "<span class='warning'>You feel a tiny prick!</span>"
user << "<span class='notice'>You inject [M] with the injector.</span>"
var/fraction = min(amount_per_transfer_from_this/R.total_volume, 1)
R.reaction(M, INJECT, fraction)
if(M.reagents)
var/trans = R.trans_to(M, amount_per_transfer_from_this)
user << "<span class='notice'>[trans] unit\s injected. [R.total_volume] unit\s remaining.</span>"
var/list/injected = list()
for(var/datum/reagent/RG in R.reagent_list)
injected += RG.name
add_logs(user, M, "injected", src, "(CHEMICALS: [english_list(injected)])")
/obj/item/weapon/reagent_containers/borghypo/attack_self(mob/user)
var/chosen_reagent = modes[input(user, "What reagent do you want to dispense?") as null|anything in reagent_ids]
if(!chosen_reagent)
return
mode = chosen_reagent
playsound(loc, 'sound/effects/pop.ogg', 50, 0)
var/datum/reagent/R = chemical_reagents_list[reagent_ids[mode]]
user << "<span class='notice'>[src] is now dispensing '[R.name]'.</span>"
return
/obj/item/weapon/reagent_containers/borghypo/examine(mob/user)
usr = user
..()
DescribeContents() //Because using the standardized reagents datum was just too cool for whatever fuckwit wrote this
/obj/item/weapon/reagent_containers/borghypo/proc/DescribeContents()
var/empty = 1
for(var/datum/reagents/RS in reagent_list)
var/datum/reagent/R = locate() in RS.reagent_list
if(R)
usr << "<span class='notice'>It currently has [R.volume] unit\s of [R.name] stored.</span>"
empty = 0
if(empty)
usr << "<span class='warning'>It is currently empty! Allow some time for the internal syntheszier to produce more.</span>"
/obj/item/weapon/reagent_containers/borghypo/hacked
icon_state = "borghypo_s"
reagent_ids = list ("facid", "mutetoxin", "cyanide", "sodium_thiopental", "heparin", "lexorin")
/obj/item/weapon/reagent_containers/borghypo/syndicate
name = "syndicate cyborg hypospray"
desc = "An experimental piece of Syndicate technology used to produce powerful restorative nanites used to very quickly restore injuries of all types. Also metabolizes potassium iodide, for radiation poisoning, and morphine, for offense."
icon_state = "borghypo_s"
charge_cost = 20
recharge_time = 2
reagent_ids = list("syndicate_nanites", "potass_iodide", "morphine")
bypass_protection = 1
/*
Borg Shaker
*/
/obj/item/weapon/reagent_containers/borghypo/borgshaker
name = "cyborg shaker"
desc = "An advanced drink synthesizer and mixer."
icon = 'icons/obj/drinks.dmi'
icon_state = "shaker"
possible_transfer_amounts = list(5,10,20)
charge_cost = 20 //Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
recharge_time = 3
reagent_ids = list("beer", "orangejuice", "limejuice", "tomatojuice", "cola", "tonic", "sodawater", "ice", "cream", "whiskey", "vodka", "rum", "gin", "tequila", "vermouth", "wine", "kahlua", "cognac", "ale")
/obj/item/weapon/reagent_containers/borghypo/borgshaker/attack(mob/M, mob/user)
return //Can't inject stuff with a shaker, can we? //not with that attitude
/obj/item/weapon/reagent_containers/borghypo/borgshaker/regenerate_reagents()
if(isrobot(src.loc))
var/mob/living/silicon/robot/R = src.loc
if(R && R.cell)
for(var/i in modes) //Lots of reagents in this one, so it's best to regenrate them all at once to keep it from being tedious.
var/valueofi = modes[i]
var/datum/reagents/RG = reagent_list[valueofi]
if(RG.total_volume < RG.maximum_volume)
R.cell.use(charge_cost)
RG.add_reagent(reagent_ids[valueofi], 5)
/obj/item/weapon/reagent_containers/borghypo/borgshaker/afterattack(obj/target, mob/user, proximity)
if(!proximity) return
else if(target.is_open_container() && target.reagents)
var/datum/reagents/R = reagent_list[mode]
if(!R.total_volume)
user << "<span class='warning'>[src] is currently out of this ingredient! Please allow some time for the synthesizer to produce more.</span>"
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "<span class='notice'>[target] is full.</span>"
return
var/trans = R.trans_to(target, amount_per_transfer_from_this)
user << "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>"
/obj/item/weapon/reagent_containers/borghypo/borgshaker/DescribeContents()
var/empty = 1
var/datum/reagents/RS = reagent_list[mode]
var/datum/reagent/R = locate() in RS.reagent_list
if(R)
usr << "<span class='notice'>It currently has [R.volume] unit\s of [R.name] stored.</span>"
empty = 0
if(empty)
usr << "<span class='warning'>It is currently empty! Please allow some time for the synthesizer to produce more.</span>"
/obj/item/weapon/reagent_containers/borghypo/borgshaker/hacked
..()
name = "cyborg shaker"
desc = "Will mix drinks that knock them dead."
icon = 'icons/obj/drinks.dmi'
icon_state = "threemileislandglass"
possible_transfer_amounts = list(5,10,20)
charge_cost = 20 //Lots of reagents all regenerating at once, so the charge cost is lower. They also regenerate faster.
recharge_time = 3
reagent_ids = list("beer2")
/obj/item/weapon/reagent_containers/borghypo/peace
name = "Peace Hypospray"
reagent_ids = list("dizzysolution","tiresolution")
/obj/item/weapon/reagent_containers/borghypo/peace/hacked
desc = "Everything's peaceful in death!"
icon_state = "borghypo_s"
reagent_ids = list("dizzysolution","tiresolution","tirizene","sulfonal","sodium_thiopental","cyanide","neurotoxin2")
/obj/item/weapon/reagent_containers/borghypo/epi
name = "epinephrine injector"
desc = "An advanced chemical synthesizer and injection system, designed to stabilize patients.."
reagent_ids = list("epinephrine")
@@ -0,0 +1,338 @@
//Not to be confused with /obj/item/weapon/reagent_containers/food/drinks/bottle
/obj/item/weapon/reagent_containers/glass/bottle
name = "bottle"
desc = "A small bottle."
icon_state = "bottle"
item_state = "atoxinbottle"
possible_transfer_amounts = list(5,10,15,25,30)
volume = 30
/obj/item/weapon/reagent_containers/glass/bottle/New()
..()
if(!icon_state)
icon_state = "bottle"
update_icon()
/obj/item/weapon/reagent_containers/glass/bottle/on_reagent_change()
update_icon()
/obj/item/weapon/reagent_containers/glass/bottle/update_icon()
overlays.Cut()
if(reagents.total_volume)
var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]-10")
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
if(0 to 9)
filling.icon_state = "[icon_state]-10"
if(10 to 29)
filling.icon_state = "[icon_state]25"
if(30 to 49)
filling.icon_state = "[icon_state]50"
if(50 to 69)
filling.icon_state = "[icon_state]75"
if(70 to INFINITY)
filling.icon_state = "[icon_state]100"
filling.color = mix_color_from_reagents(reagents.reagent_list)
overlays += filling
/obj/item/weapon/reagent_containers/glass/bottle/epinephrine
name = "epinephrine bottle"
desc = "A small bottle. Contains epinephrine - used to stabilize patients."
icon_state = "bottle16"
list_reagents = list("epinephrine" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/toxin
name = "toxin bottle"
desc = "A small bottle of toxins. Do not drink, it is poisonous."
icon_state = "bottle12"
list_reagents = list("toxin" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/cyanide
name = "cyanide bottle"
desc = "A small bottle of cyanide. Bitter almonds?"
icon_state = "bottle12"
list_reagents = list("cyanide" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/morphine
name = "morphine bottle"
desc = "A small bottle of morphine."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle20"
list_reagents = list("morphine" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/chloralhydrate
name = "Chloral Hydrate Bottle"
desc = "A small bottle of Choral Hydrate. Mickey's Favorite!"
icon_state = "bottle20"
list_reagents = list("chloralhydrate" = 15)
/obj/item/weapon/reagent_containers/glass/bottle/charcoal
name = "antitoxin bottle"
desc = "A small bottle of charcoal."
icon_state = "bottle17"
list_reagents = list("charcoal" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/mutagen
name = "unstable mutagen bottle"
desc = "A small bottle of unstable mutagen. Randomly changes the DNA structure of whoever comes in contact."
icon_state = "bottle20"
list_reagents = list("mutagen" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/plasma
name = "liquid plasma bottle"
desc = "A small bottle of liquid plasma. Extremely toxic and reacts with micro-organisms inside blood."
icon_state = "bottle8"
list_reagents = list("plasma" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/synaptizine
name = "synaptizine bottle"
desc = "A small bottle of synaptizine."
icon_state = "bottle20"
list_reagents = list("synaptizine" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/ammonia
name = "ammonia bottle"
desc = "A small bottle of ammonia."
icon_state = "bottle20"
list_reagents = list("ammonia" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/diethylamine
name = "diethylamine bottle"
desc = "A small bottle of diethylamine."
icon_state = "bottle17"
list_reagents = list("diethylamine" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/facid
name = "Fluorosulfuric Acid Bottle"
desc = "A small bottle. Contains a small amount of Fluorosulfuric Acid"
icon_state = "bottle17"
list_reagents = list("facid" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/adminordrazine
name = "Adminordrazine Bottle"
desc = "A small bottle. Contains the liquid essence of the gods."
icon = 'icons/obj/drinks.dmi'
icon_state = "holyflask"
list_reagents = list("adminordrazine" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/capsaicin
name = "Capsaicin Bottle"
desc = "A small bottle. Contains hot sauce."
icon_state = "bottle3"
list_reagents = list("capsaicin" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/frostoil
name = "Frost Oil Bottle"
desc = "A small bottle. Contains cold sauce."
icon_state = "bottle17"
list_reagents = list("frostoil" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/traitor
name = "syndicate bottle"
desc = "A small bottle. Contains a random nasty chemical."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle16"
var/extra_reagent = null
/obj/item/weapon/reagent_containers/glass/bottle/traitor/New()
..()
extra_reagent = pick("polonium", "histamine", "formaldehyde", "venom", "neurotoxin2", "cyanide")
reagents.add_reagent("[extra_reagent]", 3)
/obj/item/weapon/reagent_containers/glass/bottle/polonium
name = "polonium bottle"
desc = "A small bottle. Contains Polonium."
icon_state = "bottle16"
list_reagents = list("polonium" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/venom
name = "venom bottle"
desc = "A small bottle. Contains Venom."
icon_state = "bottle16"
list_reagents = list("venom" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/neurotoxin2
name = "neurotoxin bottle"
desc = "A small bottle. Contains Neurotoxin."
icon_state = "bottle16"
list_reagents = list("neurotoxin2" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/formaldehyde
name = "formaldehyde bottle"
desc = "A small bottle. Contains Formaldehyde."
icon_state = "bottle16"
list_reagents = list("formaldehyde" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/initropidril
name = "initropidril bottle"
desc = "A small bottle. Contains initropidril."
icon_state = "bottle16"
list_reagents = list("initropidril" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/pancuronium
name = "pancuronium bottle"
desc = "A small bottle. Contains pancuronium."
icon_state = "bottle16"
list_reagents = list("pancuronium" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/sodium_thiopental
name = "sodium thiopental bottle"
desc = "A small bottle. Contains sodium thiopental."
icon_state = "bottle16"
list_reagents = list("sodium_thiopental" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/coniine
name = "coniine bottle"
desc = "A small bottle. Contains coniine."
icon_state = "bottle16"
list_reagents = list("coniine" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/curare
name = "curare bottle"
desc = "A small bottle. Contains curare."
icon_state = "bottle16"
list_reagents = list("curare" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/amanitin
name = "amanitin bottle"
desc = "A small bottle. Contains amanitin."
icon_state = "bottle16"
list_reagents = list("amanitin" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/histamine
name = "histamine bottle"
desc = "A small bottle. Contains Histamine."
icon_state = "bottle16"
list_reagents = list("histamine" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/diphenhydramine
name = "antihistamine bottle"
desc = "A small bottle of diphenhydramine."
icon_state = "bottle20"
list_reagents = list("diphenhydramine" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/potass_iodide
name = "anti-radiation bottle"
desc = "A small bottle of potassium iodide."
icon_state = "bottle11"
list_reagents = list("potass_iodide" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/salglu_solution
name = "saline-glucose solution bottle"
desc = "A small bottle of saline-glucose solution."
icon_state = "bottle1"
list_reagents = list("salglu_solution" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/atropine
name = "atropine bottle"
desc = "A small bottle of atropine."
icon_state = "bottle12"
list_reagents = list("atropine" = 30)
/obj/item/weapon/reagent_containers/glass/bottle/flu_virion
name = "Flu virion culture bottle"
desc = "A small bottle. Contains H13N1 flu virion culture in synthblood medium."
icon_state = "bottle3"
spawned_disease = /datum/disease/advance/flu
/obj/item/weapon/reagent_containers/glass/bottle/epiglottis_virion
name = "Epiglottis virion culture bottle"
desc = "A small bottle. Contains Epiglottis virion culture in synthblood medium."
icon_state = "bottle3"
spawned_disease = /datum/disease/advance/voice_change
/obj/item/weapon/reagent_containers/glass/bottle/liver_enhance_virion
name = "Liver enhancement virion culture bottle"
desc = "A small bottle. Contains liver enhancement virion culture in synthblood medium."
icon_state = "bottle3"
spawned_disease = /datum/disease/advance/heal
/obj/item/weapon/reagent_containers/glass/bottle/hullucigen_virion
name = "Hullucigen virion culture bottle"
desc = "A small bottle. Contains hullucigen virion culture in synthblood medium."
icon_state = "bottle3"
spawned_disease = /datum/disease/advance/hullucigen
/obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat
name = "Pierrot's Throat culture bottle"
desc = "A small bottle. Contains H0NI<42 virion culture in synthblood medium."
icon_state = "bottle3"
spawned_disease = /datum/disease/pierrot_throat
/obj/item/weapon/reagent_containers/glass/bottle/cold
name = "Rhinovirus culture bottle"
desc = "A small bottle. Contains XY-rhinovirus culture in synthblood medium."
icon_state = "bottle3"
spawned_disease = /datum/disease/advance/cold
/obj/item/weapon/reagent_containers/glass/bottle/retrovirus
name = "Retrovirus culture bottle"
desc = "A small bottle. Contains a retrovirus culture in a synthblood medium."
icon_state = "bottle3"
spawned_disease = /datum/disease/dna_retrovirus
/obj/item/weapon/reagent_containers/glass/bottle/gbs
name = "GBS culture bottle"
desc = "A small bottle. Contains Gravitokinetic Bipotential SADS+ culture in synthblood medium."//Or simply - General BullShit
icon_state = "bottle3"
amount_per_transfer_from_this = 5
spawned_disease = /datum/disease/gbs
/obj/item/weapon/reagent_containers/glass/bottle/fake_gbs
name = "GBS culture bottle"
desc = "A small bottle. Contains Gravitokinetic Bipotential SADS- culture in synthblood medium."//Or simply - General BullShit
icon_state = "bottle3"
spawned_disease = /datum/disease/fake_gbs
/obj/item/weapon/reagent_containers/glass/bottle/brainrot
name = "Brainrot culture bottle"
desc = "A small bottle. Contains Cryptococcus Cosmosis culture in synthblood medium."
icon_state = "bottle3"
spawned_disease = /datum/disease/brainrot
/obj/item/weapon/reagent_containers/glass/bottle/magnitis
name = "Magnitis culture bottle"
desc = "A small bottle. Contains a small dosage of Fukkos Miracos."
icon_state = "bottle3"
spawned_disease = /datum/disease/magnitis
/obj/item/weapon/reagent_containers/glass/bottle/wizarditis
name = "Wizarditis culture bottle"
desc = "A small bottle. Contains a sample of Rincewindus Vulgaris."
icon_state = "bottle3"
spawned_disease = /datum/disease/wizarditis
/obj/item/weapon/reagent_containers/glass/bottle/anxiety
name = "Severe Anxiety culture bottle"
desc = "A small bottle. Contains a sample of Lepidopticides."
icon_state = "bottle3"
spawned_disease = /datum/disease/anxiety
/obj/item/weapon/reagent_containers/glass/bottle/beesease
name = "Beesease culture bottle"
desc = "A small bottle. Contains a sample of invasive Apidae."
icon_state = "bottle3"
spawned_disease = /datum/disease/beesease
/obj/item/weapon/reagent_containers/glass/bottle/fluspanish
name = "Spanish flu culture bottle"
desc = "A small bottle. Contains a sample of Inquisitius."
icon_state = "bottle3"
spawned_disease = /datum/disease/fluspanish
/obj/item/weapon/reagent_containers/glass/bottle/tuberculosis
name = "Fungal Tuberculosis culture bottle"
desc = "A small bottle. Contains a sample of Fungal Tubercle bacillus."
icon_state = "bottle3"
spawned_disease = /datum/disease/tuberculosis
/obj/item/weapon/reagent_containers/glass/bottle/tuberculosiscure
name = "BVAK bottle"
desc = "A small bottle containing Bio Virus Antidote Kit."
icon_state = "bottle5"
list_reagents = list("atropine" = 5, "epinephrine" = 5, "salbutamol" = 10, "spaceacillin" = 10)
@@ -0,0 +1,95 @@
/obj/item/weapon/reagent_containers/dropper
name = "dropper"
desc = "A dropper. Holds up to 5 units."
icon = 'icons/obj/chemical.dmi'
icon_state = "dropper0"
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(1, 2, 3, 4, 5)
volume = 5
/obj/item/weapon/reagent_containers/dropper/afterattack(obj/target, mob/user , proximity)
if(!proximity) return
if(!target.reagents) return
if(reagents.total_volume > 0)
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "<span class='notice'>[target] is full.</span>"
return
if(!target.is_open_container() && !ismob(target) && !istype(target,/obj/item/weapon/reagent_containers/food) && !istype(target, /obj/item/clothing/mask/cigarette)) //You can inject humans and food but you cant remove the shit.
user << "<span class='warning'>You cannot directly fill [target]!</span>"
return
var/trans = 0
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
if(ismob(target))
if(ishuman(target))
var/mob/living/carbon/human/victim = target
var/obj/item/safe_thing = null
if(victim.wear_mask)
if(victim.wear_mask.flags_cover & MASKCOVERSEYES)
safe_thing = victim.wear_mask
if(victim.head)
if(victim.head.flags_cover & MASKCOVERSEYES)
safe_thing = victim.head
if(victim.glasses)
if(!safe_thing)
safe_thing = victim.glasses
if(safe_thing)
if(!safe_thing.reagents)
safe_thing.create_reagents(100)
reagents.reaction(safe_thing, TOUCH, fraction)
trans = reagents.trans_to(safe_thing, amount_per_transfer_from_this)
target.visible_message("<span class='danger'>[user] tries to squirt something into [target]'s eyes, but fails!</span>", \
"<span class='userdanger'>[user] tries to squirt something into [target]'s eyes, but fails!</span>")
user << "<span class='notice'>You transfer [trans] unit\s of the solution.</span>"
update_icon()
return
else if(isalien(target)) //hiss-hiss has no eyes!
target << "<span class='danger'>[target] does not seem to have any eyes!</span>"
return
target.visible_message("<span class='danger'>[user] squirts something into [target]'s eyes!</span>", \
"<span class='userdanger'>[user] squirts something into [target]'s eyes!</span>")
reagents.reaction(target, TOUCH, fraction)
var/mob/M = target
var/R
if(reagents)
for(var/datum/reagent/A in src.reagents.reagent_list)
R += A.id + " ("
R += num2text(A.volume) + "),"
add_logs(user, M, "squirted", R)
trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
user << "<span class='notice'>You transfer [trans] unit\s of the solution.</span>"
update_icon()
else
if(!target.is_open_container() && !istype(target,/obj/structure/reagent_dispensers))
user << "<span class='notice'>You cannot directly remove reagents from [target].</span>"
return
if(!target.reagents.total_volume)
user << "<span class='warning'>[target] is empty!</span>"
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
user << "<span class='notice'>You fill [src] with [trans] unit\s of the solution.</span>"
update_icon()
/obj/item/weapon/reagent_containers/dropper/update_icon()
cut_overlays()
if(reagents.total_volume)
var/image/filling = image('icons/obj/reagentfillings.dmi', src, "dropper")
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
@@ -0,0 +1,273 @@
/obj/item/weapon/reagent_containers/glass
name = "glass"
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5, 10, 15, 20, 25, 30, 50)
volume = 50
flags = OPENCONTAINER
spillable = 1
/obj/item/weapon/reagent_containers/glass/attack(mob/M, mob/user, obj/target)
if(!canconsume(M, user))
return
if(!spillable)
return
if(!reagents || !reagents.total_volume)
user << "<span class='warning'>[src] is empty!</span>"
return
if(istype(M))
if(user.a_intent == "harm")
var/R
M.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [M]!</span>", \
"<span class='userdanger'>[user] splashes the contents of [src] onto [M]!</span>")
if(reagents)
for(var/datum/reagent/A in reagents.reagent_list)
R += A.id + " ("
R += num2text(A.volume) + "),"
reagents.reaction(M, TOUCH)
add_logs(user, M, "splashed", R)
reagents.clear_reagents()
else
if(M != user)
M.visible_message("<span class='danger'>[user] attempts to feed something to [M].</span>", \
"<span class='userdanger'>[user] attempts to feed something to you.</span>")
if(!do_mob(user, M))
return
if(!reagents || !reagents.total_volume)
return // The drink might be empty after the delay, such as by spam-feeding
M.visible_message("<span class='danger'>[user] feeds something to [M].</span>", "<span class='userdanger'>[user] feeds something to you.</span>")
add_logs(user, M, "fed", reagentlist(src))
else
user << "<span class='notice'>You swallow a gulp of [src].</span>"
var/fraction = min(5/reagents.total_volume, 1)
reagents.reaction(M, INGEST, fraction)
spawn(5)
reagents.trans_to(M, 5)
playsound(M.loc,'sound/items/drink.ogg', rand(10,50), 1)
/obj/item/weapon/reagent_containers/glass/afterattack(obj/target, mob/user, proximity)
if((!proximity) || !check_allowed_items(target,target_self=1)) return
else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
if(target.reagents && !target.reagents.total_volume)
user << "<span class='warning'>[target] is empty and can't be refilled!</span>"
return
if(reagents.total_volume >= reagents.maximum_volume)
user << "<span class='notice'>[src] is full.</span>"
return
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
user << "<span class='notice'>You fill [src] with [trans] unit\s of the contents of [target].</span>"
else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
user << "<span class='warning'>[src] is empty!</span>"
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "<span class='notice'>[target] is full.</span>"
return
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
user << "<span class='notice'>You transfer [trans] unit\s of the solution to [target].</span>"
else if(reagents.total_volume)
if(user.a_intent == "harm")
user.visible_message("<span class='danger'>[user] splashes the contents of [src] onto [target]!</span>", \
"<span class='notice'>You splash the contents of [src] onto [target].</span>")
reagents.reaction(target, TOUCH)
reagents.clear_reagents()
/obj/item/weapon/reagent_containers/glass/attackby(obj/item/I, mob/user, params)
var/hotness = I.is_hot()
if(hotness)
var/added_heat = (hotness / 100) //ishot returns a temperature
if(reagents)
if(reagents.chem_temp < hotness) //can't be heated to be hotter than the source
reagents.chem_temp += added_heat
user << "<span class='notice'>You heat [src] with [I].</span>"
reagents.handle_reactions()
else
user << "<span class='warning'>[src] is already hotter than [I]!</span>"
if(istype(I,/obj/item/weapon/reagent_containers/food/snacks/egg)) //breaking eggs
var/obj/item/weapon/reagent_containers/food/snacks/egg/E = I
if(reagents)
if(reagents.total_volume >= reagents.maximum_volume)
user << "<span class='notice'>[src] is full.</span>"
else
user << "<span class='notice'>You break [E] in [src].</span>"
reagents.add_reagent("eggyolk", 5)
qdel(E)
return
..()
/obj/item/weapon/reagent_containers/glass/beaker
name = "beaker"
desc = "A beaker. It can hold up to 50 units."
icon = 'icons/obj/chemical.dmi'
icon_state = "beaker"
item_state = "beaker"
materials = list(MAT_GLASS=500)
/obj/item/weapon/reagent_containers/glass/beaker/New()
..()
update_icon()
/obj/item/weapon/reagent_containers/glass/beaker/on_reagent_change()
update_icon()
/obj/item/weapon/reagent_containers/glass/beaker/update_icon()
cut_overlays()
if(reagents.total_volume)
var/image/filling = image('icons/obj/reagentfillings.dmi', src, "[icon_state]10")
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
if(0 to 9)
filling.icon_state = "[icon_state]-10"
if(10 to 24)
filling.icon_state = "[icon_state]10"
if(25 to 49)
filling.icon_state = "[icon_state]25"
if(50 to 74)
filling.icon_state = "[icon_state]50"
if(75 to 79)
filling.icon_state = "[icon_state]75"
if(80 to 90)
filling.icon_state = "[icon_state]80"
if(91 to INFINITY)
filling.icon_state = "[icon_state]100"
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
/obj/item/weapon/reagent_containers/glass/beaker/large
name = "large beaker"
desc = "A large beaker. Can hold up to 100 units."
icon_state = "beakerlarge"
materials = list(MAT_GLASS=2500)
volume = 100
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100)
flags = OPENCONTAINER
/obj/item/weapon/reagent_containers/glass/beaker/noreact
name = "cryostasis beaker"
desc = "A cryostasis beaker that allows for chemical storage without \
reactions. Can hold up to 50 units."
icon_state = "beakernoreact"
materials = list(MAT_METAL=3000)
volume = 50
amount_per_transfer_from_this = 10
origin_tech = "materials=2;engineering=3;plasmatech=3"
flags = OPENCONTAINER
/obj/item/weapon/reagent_containers/glass/beaker/noreact/New()
..()
reagents.set_reacting(FALSE)
/obj/item/weapon/reagent_containers/glass/beaker/bluespace
name = "bluespace beaker"
desc = "A bluespace beaker, powered by experimental bluespace technology \
and Element Cuban combined with the Compound Pete. Can hold up to \
300 units."
icon_state = "beakerbluespace"
materials = list(MAT_GLASS=3000)
volume = 300
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10,15,20,25,30,50,100,300)
flags = OPENCONTAINER
origin_tech = "bluespace=5;materials=4;plasmatech=4"
/obj/item/weapon/reagent_containers/glass/beaker/cryoxadone
list_reagents = list("cryoxadone" = 30)
/obj/item/weapon/reagent_containers/glass/beaker/sulphuric
list_reagents = list("sacid" = 50)
/obj/item/weapon/reagent_containers/glass/beaker/slime
list_reagents = list("slimejelly" = 50)
/obj/item/weapon/reagent_containers/glass/beaker/large/styptic
name = "styptic reserve tank"
list_reagents = list("styptic_powder" = 50)
/obj/item/weapon/reagent_containers/glass/beaker/large/silver_sulfadiazine
name = "silver sulfadiazine reserve tank"
list_reagents = list("silver_sulfadiazine" = 50)
/obj/item/weapon/reagent_containers/glass/beaker/large/charcoal
name = "antitoxin reserve tank"
list_reagents = list("charcoal" = 50)
/obj/item/weapon/reagent_containers/glass/beaker/large/epinephrine
name = "epinephrine reserve tank"
list_reagents = list("epinephrine" = 50)
/obj/item/weapon/reagent_containers/glass/bucket
name = "bucket"
desc = "It's a bucket."
icon = 'icons/obj/janitor.dmi'
icon_state = "bucket"
item_state = "bucket"
materials = list(MAT_METAL=200)
w_class = 3
amount_per_transfer_from_this = 20
possible_transfer_amounts = list(10,15,20,25,30,50,70)
volume = 70
flags = OPENCONTAINER
flags_inv = HIDEHAIR
slot_flags = SLOT_HEAD
armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0) //Weak melee protection, because you can wear it on your head
slot_equipment_priority = list( \
slot_back, slot_wear_id,\
slot_w_uniform, slot_wear_suit,\
slot_wear_mask, slot_head,\
slot_shoes, slot_gloves,\
slot_ears, slot_glasses,\
slot_belt, slot_s_store,\
slot_l_store, slot_r_store,\
slot_drone_storage
)
/obj/item/weapon/reagent_containers/glass/bucket/attackby(obj/O, mob/user, params)
if(istype(O, /obj/item/weapon/mop))
if(reagents.total_volume < 1)
user << "<span class='warning'>[src] is out of water!</span>"
else
reagents.trans_to(O, 5)
user << "<span class='notice'>You wet [O] in [src].</span>"
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
else if(isprox(O))
user << "<span class='notice'>You add [O] to [src].</span>"
qdel(O)
user.unEquip(src)
qdel(src)
user.put_in_hands(new /obj/item/weapon/bucket_sensor)
else
..()
/obj/item/weapon/reagent_containers/glass/bucket/equipped(mob/user, slot)
..()
if(slot == slot_head && reagents.total_volume)
user << "<span class='userdanger'>[src]'s contents spill all over you!</span>"
reagents.reaction(user, TOUCH)
reagents.clear_reagents()
/obj/item/weapon/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
var/index = slot_equipment_priority.Find(slot_head)
slot_equipment_priority.Remove(slot_head)
. = ..()
slot_equipment_priority.Insert(index, slot_head)
return
return ..()
@@ -0,0 +1,143 @@
/obj/item/weapon/reagent_containers/hypospray
name = "hypospray"
desc = "The DeForest Medical Corporation hypospray is a sterile, air-needle autoinjector for rapid administration of drugs to patients."
icon = 'icons/obj/syringe.dmi'
item_state = "hypo"
icon_state = "hypo"
amount_per_transfer_from_this = 5
volume = 30
possible_transfer_amounts = list()
flags = OPENCONTAINER
slot_flags = SLOT_BELT
var/ignore_flags = 0
var/infinite = FALSE
/obj/item/weapon/reagent_containers/hypospray/attack_paw(mob/user)
return attack_hand(user)
/obj/item/weapon/reagent_containers/hypospray/attack(mob/living/M, mob/user)
if(!reagents.total_volume)
user << "<span class='warning'>[src] is empty!</span>"
return
if(!iscarbon(M))
return
if(reagents.total_volume && (ignore_flags || M.can_inject(user, 1))) // Ignore flag should be checked first or there will be an error message.
M << "<span class='warning'>You feel a tiny prick!</span>"
user << "<span class='notice'>You inject [M] with [src].</span>"
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
reagents.reaction(M, INJECT, fraction)
if(M.reagents)
var/list/injected = list()
for(var/datum/reagent/R in reagents.reagent_list)
injected += R.name
var/trans = 0
if(!infinite)
trans = reagents.trans_to(M, amount_per_transfer_from_this)
else
trans = reagents.copy_to(M, amount_per_transfer_from_this)
user << "<span class='notice'>[trans] unit\s injected. [reagents.total_volume] unit\s remaining in [src].</span>"
var/contained = english_list(injected)
add_logs(user, M, "injected", src, "([contained])")
/obj/item/weapon/reagent_containers/hypospray/CMO
list_reagents = list("omnizine" = 30)
/obj/item/weapon/reagent_containers/hypospray/combat
name = "combat stimulant injector"
desc = "A modified air-needle autoinjector, used by support operatives to quickly heal injuries in combat."
amount_per_transfer_from_this = 10
icon_state = "combat_hypo"
volume = 90
ignore_flags = 1 // So they can heal their comrades.
list_reagents = list("epinephrine" = 30, "omnizine" = 30, "leporazine" = 15, "atropine" = 15)
/obj/item/weapon/reagent_containers/hypospray/combat/nanites
desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with expensive medical nanites for rapid healing."
volume = 100
list_reagents = list("nanites" = 80, "synaptizine" = 20)
//MediPens
/obj/item/weapon/reagent_containers/hypospray/medipen
name = "epinephrine medipen"
desc = "A rapid and safe way to stabilize patients in critical condition for personnel without advanced medical knowledge."
icon_state = "medipen"
item_state = "medipen"
amount_per_transfer_from_this = 10
volume = 10
ignore_flags = 1 //so you can medipen through hardsuits
flags = null
list_reagents = list("epinephrine" = 10)
/obj/item/weapon/reagent_containers/hypospray/medipen/attack(mob/M, mob/user)
if(!reagents.total_volume)
user << "<span class='warning'>[src] is empty!</span>"
return
..()
update_icon()
spawn(80)
if(isrobot(user) && !reagents.total_volume)
var/mob/living/silicon/robot/R = user
if(R.cell.use(100))
reagents.add_reagent_list(list_reagents)
update_icon()
return
/obj/item/weapon/reagent_containers/hypospray/medipen/update_icon()
if(reagents.total_volume > 0)
icon_state = initial(icon_state)
else
icon_state = "[initial(icon_state)]0"
/obj/item/weapon/reagent_containers/hypospray/medipen/examine()
..()
if(reagents && reagents.reagent_list.len)
usr << "<span class='notice'>It is currently loaded.</span>"
else
usr << "<span class='notice'>It is spent.</span>"
/obj/item/weapon/reagent_containers/hypospray/medipen/stimpack //goliath kiting
name = "stimpack medipen"
desc = "A rapid way to stimulate your body's adrenaline, allowing for freer movement in restrictive armor."
icon_state = "stimpen"
volume = 20
amount_per_transfer_from_this = 20
list_reagents = list("ephedrine" = 10, "coffee" = 10)
/obj/item/weapon/reagent_containers/hypospray/medipen/stimpack/traitor
desc = "A modified stimulants autoinjector for use in combat situations. Has a mild healing effect."
list_reagents = list("stimulants" = 10, "omnizine" = 10)
/obj/item/weapon/reagent_containers/hypospray/medipen/morphine
name = "morphine medipen"
desc = "A rapid way to get you out of a tight situation and fast! You'll feel rather drowsy, though."
list_reagents = list("morphine" = 10)
/obj/item/weapon/reagent_containers/hypospray/medipen/tuberculosiscure
name = "BVAK autoinjector"
desc = "Bio Virus Antidote Kit autoinjector. Has a two use system for yourself, and someone else. Inject when infected."
icon_state = "stimpen"
volume = 60
amount_per_transfer_from_this = 30
list_reagents = list("atropine" = 10, "epinephrine" = 10, "salbutamol" = 20, "spaceacillin" = 20)
/obj/item/weapon/reagent_containers/hypospray/medipen/survival
name = "survival medipen"
desc = "A medipen for surviving in the harshest of environments, heals and protects from environmental hazards. "
icon_state = "stimpen"
volume = 82
amount_per_transfer_from_this = 82
list_reagents = list("nanites" = 2, "salbutamol" = 10, "coffee" = 20, "leporazine" = 20, "tricordrazine" = 15, "epinephrine" = 10, "omnizine" = 5, "stimulants" = 10)
/obj/item/weapon/reagent_containers/hypospray/medipen/species_mutator
name = "species mutator medipen"
desc = "Embark on a whirlwind tour of racial insensitivity by \
literally appropriating other races."
volume = 1
amount_per_transfer_from_this = 1
list_reagents = list("unstablemutationtoxin" = 1)
@@ -0,0 +1,31 @@
/obj/item/weapon/reagent_containers/pill/patch
name = "chemical patch"
desc = "A chemical patch for touch based applications."
icon = 'icons/obj/chemical.dmi'
icon_state = "bandaid"
item_state = "bandaid"
possible_transfer_amounts = list()
volume = 40
apply_type = PATCH
apply_method = "apply"
self_delay = 30 // three seconds
/obj/item/weapon/reagent_containers/pill/patch/afterattack(obj/target, mob/user , proximity)
return // thanks inheritance again
/obj/item/weapon/reagent_containers/pill/patch/canconsume(mob/eater, mob/user)
if(!iscarbon(eater))
return 0
return 1 // Masks were stopping people from "eating" patches. Thanks, inheritance.
/obj/item/weapon/reagent_containers/pill/patch/styptic
name = "brute patch"
desc = "Helps with brute injuries."
list_reagents = list("styptic_powder" = 20)
icon_state = "bandaid_brute"
/obj/item/weapon/reagent_containers/pill/patch/silver_sulf
name = "burn patch"
desc = "Helps with burn injuries."
list_reagents = list("silver_sulfadiazine" = 20)
icon_state = "bandaid_burn"
@@ -0,0 +1,152 @@
/obj/item/weapon/reagent_containers/pill
name = "pill"
desc = "A tablet or capsule."
icon = 'icons/obj/chemical.dmi'
icon_state = "pill"
item_state = "pill"
possible_transfer_amounts = list()
volume = 50
var/apply_type = INGEST
var/apply_method = "swallow"
var/roundstart = 0
var/self_delay = 0 //pills are instant, this is because patches inheret their aplication from pills
/obj/item/weapon/reagent_containers/pill/New()
..()
if(!icon_state)
icon_state = "pill[rand(1,20)]"
if(reagents.total_volume && roundstart)
name += " ([reagents.total_volume]u)"
/obj/item/weapon/reagent_containers/pill/attack_self(mob/user)
return
/obj/item/weapon/reagent_containers/pill/attack(mob/M, mob/user, def_zone, self_delay)
if(!canconsume(M, user))
return 0
if(M == user)
M.visible_message("<span class='notice'>[user] attempts to [apply_method] [src].</span>")
if(self_delay)
if(!do_mob(user, M, self_delay))
return 0
M << "<span class='notice'>You [apply_method] [src].</span>"
else
M.visible_message("<span class='danger'>[user] attempts to force [M] to [apply_method] [src].</span>", \
"<span class='userdanger'>[user] attempts to force [M] to [apply_method] [src].</span>")
if(!do_mob(user, M))
return 0
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>")
user.unEquip(src) //icon update
add_logs(user, M, "fed", reagentlist(src))
loc = M //Put the pill inside the mob. This fixes the issue where the pill appears to drop to the ground after someone eats it.
if(reagents.total_volume)
reagents.reaction(M, apply_type)
reagents.trans_to(M, reagents.total_volume)
qdel(src)
return 1
else
qdel(src)
return 1
return 0
/obj/item/weapon/reagent_containers/pill/afterattack(obj/target, mob/user , proximity)
if(!proximity) return
if(target.is_open_container() != 0 && target.reagents)
if(!target.reagents.total_volume)
user << "<span class='warning'>[target] is empty! There's nothing to dissolve [src] in.</span>"
return
user << "<span class='notice'>You dissolve [src] in [target].</span>"
for(var/mob/O in viewers(2, user)) //viewers is necessary here because of the small radius
O << "<span class='warning'>[user] slips something into [target]!</span>"
reagents.trans_to(target, reagents.total_volume)
spawn(5)
qdel(src)
/obj/item/weapon/reagent_containers/pill/tox
name = "toxins pill"
desc = "Highly toxic."
icon_state = "pill5"
list_reagents = list("toxin" = 50)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/cyanide
name = "cyanide pill"
desc = "Don't swallow this."
icon_state = "pill5"
list_reagents = list("cyanide" = 50)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/adminordrazine
name = "adminordrazine pill"
desc = "It's magic. We don't have to explain it."
icon_state = "pill16"
list_reagents = list("adminordrazine" = 50)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/morphine
name = "morphine pill"
desc = "Commonly used to treat insomnia."
icon_state = "pill8"
list_reagents = list("morphine" = 30)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/stimulant
name = "stimulant pill"
desc = "Often taken by overworked employees, athletes, and the inebriated. You'll snap to attention immediately!"
icon_state = "pill19"
list_reagents = list("ephedrine" = 10, "antihol" = 10, "coffee" = 30)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/salbutamol
name = "salbutamol pill"
desc = "Used to treat oxygen deprivation."
icon_state = "pill16"
list_reagents = list("salbutamol" = 30)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/charcoal
name = "antitoxin pill"
desc = "Neutralizes many common toxins."
icon_state = "pill17"
list_reagents = list("charcoal" = 50)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/epinephrine
name = "epinephrine pill"
desc = "Used to stabilize patients."
icon_state = "pill5"
list_reagents = list("epinephrine" = 15)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/mannitol
name = "mannitol pill"
desc = "Used to treat brain damage."
icon_state = "pill17"
list_reagents = list("mannitol" = 50)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/mutadone
name = "mutadone pill"
desc = "Used to treat genetic damage."
icon_state = "pill20"
list_reagents = list("mutadone" = 50)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/salicyclic
name = "salicylic acid pill"
desc = "Used to dull pain."
icon_state = "pill9"
list_reagents = list("sal_acid" = 24)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/oxandrolone
name = "oxandrolone pill"
desc = "Used to stimulate burn healing."
icon_state = "pill11"
list_reagents = list("oxandrolone" = 24)
roundstart = 1
/obj/item/weapon/reagent_containers/pill/insulin
name = "insulin pill"
desc = "Handles hyperglycaemic coma."
icon_state = "pill18"
list_reagents = list("insulin" = 50)
roundstart = 1
@@ -0,0 +1,213 @@
/obj/item/weapon/reagent_containers/spray
name = "spray bottle"
desc = "A spray bottle, with an unscrewable top."
icon = 'icons/obj/janitor.dmi'
icon_state = "cleaner"
item_state = "cleaner"
flags = OPENCONTAINER | NOBLUDGEON
slot_flags = SLOT_BELT
throwforce = 0
w_class = 2
throw_speed = 3
throw_range = 7
var/stream_mode = 0 //whether we use the more focused mode
var/current_range = 3 //the range of tiles the sprayer will reach.
var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode.
var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode.
var/stream_amount = 10 //the amount of reagents transfered when in stream mode.
amount_per_transfer_from_this = 5
volume = 250
possible_transfer_amounts = list()
/obj/item/weapon/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user)
if(istype(A, /obj/item/weapon/reagent_containers) || istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics))
return
if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution
if(!A.reagents.total_volume && A.reagents)
user << "<span class='notice'>\The [A] is empty.</span>"
return
if(reagents.total_volume >= reagents.maximum_volume)
user << "<span class='notice'>\The [src] is full.</span>"
return
var/trans = A.reagents.trans_to(src, 50) //transfer 50u , using the spray's transfer amount would take too long to refill
user << "<span class='notice'>You fill \the [src] with [trans] units of the contents of \the [A].</span>"
return
if(reagents.total_volume < amount_per_transfer_from_this)
user << "<span class='warning'>\The [src] is empty!</span>"
return
spray(A)
playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
user.changeNext_move(CLICK_CD_RANGE*2)
user.newtonian_move(get_dir(A, user))
var/turf/T = get_turf(src)
if(reagents.has_reagent("sacid"))
message_admins("[key_name_admin(user)] fired sulphuric acid from \a [src] at (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[get_area(src)] ([T.x], [T.y], [T.z])</a>).")
log_game("[key_name(user)] fired sulphuric acid from \a [src] at [get_area(src)] ([T.x], [T.y], [T.z]).")
if(reagents.has_reagent("facid"))
message_admins("[key_name_admin(user)] fired Fluacid from \a [src] at (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[get_area(src)] ([T.x], [T.y], [T.z])</a>).")
log_game("[key_name(user)] fired Fluacid from \a [src] at [get_area(src)] ([T.x], [T.y], [T.z]).")
if(reagents.has_reagent("lube"))
message_admins("[key_name_admin(user)] fired Space lube from \a [src] at (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[get_area(src)] ([T.x], [T.y], [T.z])</a>).")
log_game("[key_name(user)] fired Space lube from \a [src] at [get_area(src)] ([T.x], [T.y], [T.z]).")
return
/obj/item/weapon/reagent_containers/spray/proc/spray(atom/A)
var/range = max(min(spray_range, get_dist(src, A)), 1)
var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src))
D.create_reagents(amount_per_transfer_from_this)
var/puff_reagent_left = range //how many turf, mob or dense objet we can react with before we consider the chem puff consumed
if(stream_mode)
reagents.trans_to(D, amount_per_transfer_from_this)
puff_reagent_left = 1
else
reagents.trans_to(D, amount_per_transfer_from_this, 1/range)
D.color = mix_color_from_reagents(D.reagents.reagent_list)
var/wait_step = max(round(2+3/range), 2)
spawn(0)
var/range_left = range
for(var/i=0, i<range, i++)
range_left--
step_towards(D,A)
sleep(wait_step)
for(var/atom/T in get_turf(D))
if(T == D || T.invisibility) //we ignore the puff itself and stuff below the floor
continue
if(puff_reagent_left <= 0)
break
if(stream_mode)
if(ismob(T))
var/mob/M = T
if(!M.lying || !range_left)
D.reagents.reaction(M, VAPOR)
puff_reagent_left -= 1
else if(!range_left)
D.reagents.reaction(T, VAPOR)
else
D.reagents.reaction(T, VAPOR)
if(ismob(T))
puff_reagent_left -= 1
if(puff_reagent_left > 0 && (!stream_mode || !range_left))
D.reagents.reaction(get_turf(D), VAPOR)
puff_reagent_left -= 1
if(puff_reagent_left <= 0) // we used all the puff so we delete it.
qdel(D)
return
qdel(D)
/obj/item/weapon/reagent_containers/spray/attack_self(mob/user)
stream_mode = !stream_mode
if(stream_mode)
amount_per_transfer_from_this = stream_amount
current_range = stream_range
else
amount_per_transfer_from_this = initial(amount_per_transfer_from_this)
current_range = spray_range
user << "<span class='notice'>You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use.</span>"
/obj/item/weapon/reagent_containers/spray/verb/empty()
set name = "Empty Spray Bottle"
set category = "Object"
set src in usr
if(usr.incapacitated())
return
if (alert(usr, "Are you sure you want to empty that?", "Empty Bottle:", "Yes", "No") != "Yes")
return
if(isturf(usr.loc) && src.loc == usr)
usr << "<span class='notice'>You empty \the [src] onto the floor.</span>"
reagents.reaction(usr.loc)
src.reagents.clear_reagents()
//space cleaner
/obj/item/weapon/reagent_containers/spray/cleaner
name = "space cleaner"
desc = "BLAM!-brand non-foaming space cleaner!"
list_reagents = list("cleaner" = 250)
/obj/item/weapon/reagent_containers/spray/spraytan
name = "spray tan"
volume = 50
desc = "Gyaro brand spray tan. Do not spray near eyes or other orifices."
list_reagents = list("spraytan" = 50)
//pepperspray
/obj/item/weapon/reagent_containers/spray/pepper
name = "pepperspray"
desc = "Manufactured by UhangInc, used to blind and down an opponent quickly."
icon = 'icons/obj/weapons.dmi'
icon_state = "pepperspray"
item_state = "pepperspray"
volume = 40
stream_range = 4
amount_per_transfer_from_this = 5
list_reagents = list("condensedcapsaicin" = 40)
//water flower
/obj/item/weapon/reagent_containers/spray/waterflower
name = "water flower"
desc = "A seemingly innocent sunflower...with a twist."
icon = 'icons/obj/hydroponics/harvest.dmi'
icon_state = "sunflower"
item_state = "sunflower"
amount_per_transfer_from_this = 1
volume = 10
list_reagents = list("water" = 10)
/obj/item/weapon/reagent_containers/spray/waterflower/attack_self(mob/user) //Don't allow changing how much the flower sprays
return
//chemsprayer
/obj/item/weapon/reagent_containers/spray/chemsprayer
name = "chem sprayer"
desc = "A utility used to spray large amounts of reagents in a given area."
icon = 'icons/obj/guns/projectile.dmi'
icon_state = "chemsprayer"
item_state = "chemsprayer"
throwforce = 0
w_class = 3
stream_mode = 1
current_range = 7
spray_range = 4
stream_range = 7
amount_per_transfer_from_this = 10
volume = 600
origin_tech = "combat=3;materials=3;engineering=3"
/obj/item/weapon/reagent_containers/spray/chemsprayer/spray(atom/A)
var/direction = get_dir(src, A)
var/turf/T = get_turf(A)
var/turf/T1 = get_step(T,turn(direction, 90))
var/turf/T2 = get_step(T,turn(direction, -90))
var/list/the_targets = list(T,T1,T2)
for(var/i=1, i<=3, i++) // intialize sprays
if(reagents.total_volume < 1)
return
..(the_targets[i])
/obj/item/weapon/reagent_containers/spray/chemsprayer/bioterror
list_reagents = list("sodium_thiopental" = 100, "coniine" = 100, "venom" = 100, "condensedcapsaicin" = 100, "initropidril" = 100, "polonium" = 100)
// Plant-B-Gone
/obj/item/weapon/reagent_containers/spray/plantbgone // -- Skie
name = "Plant-B-Gone"
desc = "Kills those pesky weeds!"
icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "plantbgone"
item_state = "plantbgone"
volume = 100
list_reagents = list("plantbgone" = 100)
@@ -0,0 +1,246 @@
#define SYRINGE_DRAW 0
#define SYRINGE_INJECT 1
/obj/item/weapon/reagent_containers/syringe
name = "syringe"
desc = "A syringe that can hold up to 15 units."
icon = 'icons/obj/syringe.dmi'
item_state = "syringe_0"
icon_state = "0"
amount_per_transfer_from_this = 5
possible_transfer_amounts = list()
volume = 15
var/mode = SYRINGE_DRAW
var/busy = 0 // needed for delayed drawing of blood
var/projectile_type = /obj/item/projectile/bullet/dart/syringe
materials = list(MAT_METAL=10, MAT_GLASS=20)
/obj/item/weapon/reagent_containers/syringe/New()
..()
if(list_reagents) //syringe starts in inject mode if its already got something inside
mode = SYRINGE_INJECT
update_icon()
/obj/item/weapon/reagent_containers/syringe/on_reagent_change()
update_icon()
/obj/item/weapon/reagent_containers/syringe/pickup(mob/user)
..()
update_icon()
/obj/item/weapon/reagent_containers/syringe/dropped(mob/user)
..()
update_icon()
/obj/item/weapon/reagent_containers/syringe/attack_self(mob/user)
mode = !mode
update_icon()
/obj/item/weapon/reagent_containers/syringe/attack_hand()
..()
update_icon()
/obj/item/weapon/reagent_containers/syringe/attack_paw()
return attack_hand()
/obj/item/weapon/reagent_containers/syringe/attackby(obj/item/I, mob/user, params)
return
/obj/item/weapon/reagent_containers/syringe/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)
user << "<span class='notice'>The syringe is full.</span>"
return
if(L) //living mob
var/drawn_amount = reagents.maximum_volume - reagents.total_volume
if(target != user)
target.visible_message("<span class='danger'>[user] is trying to take a blood sample from [target]!</span>", \
"<span class='userdanger'>[user] is trying to take a blood sample from [target]!</span>")
busy = 1
if(!do_mob(user, target))
busy = 0
return
if(reagents.total_volume >= reagents.maximum_volume)
return
busy = 0
if(L.transfer_blood_to(src, drawn_amount))
user.visible_message("[user] takes a blood sample from [L].")
else
user << "<span class='warning'>You are unable to draw any blood from [L]!</span>"
else //if not mob
if(!target.reagents.total_volume)
user << "<span class='warning'>[target] is empty!</span>"
return
if(!target.is_open_container() && !istype(target,/obj/structure/reagent_dispensers) && !istype(target,/obj/item/slime_extract))
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) // transfer from, transfer to - who cares?
user << "<span class='notice'>You fill [src] with [trans] units of the solution.</span>"
if (reagents.total_volume >= reagents.maximum_volume)
mode=!mode
update_icon()
if(SYRINGE_INJECT)
if(!reagents.total_volume)
user << "<span class='notice'>[src] is empty.</span>"
return
if(!target.is_open_container() && !ismob(target) && !istype(target, /obj/item/weapon/reagent_containers/food) && !istype(target, /obj/item/slime_extract) && !istype(target, /obj/item/clothing/mask/cigarette) && !istype(target, /obj/item/weapon/storage/fancy/cigarettes))
user << "<span class='warning'>You cannot directly fill [target]!</span>"
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
user << "<span class='notice'>[target] is full.</span>"
return
if(L) //living mob
if(L != user)
L.visible_message("<span class='danger'>[user] is trying to inject [L]!</span>", \
"<span class='userdanger'>[user] is trying to inject [L]!</span>")
if(!do_mob(user, L))
return
if(!reagents.total_volume)
return
if(L.reagents.total_volume >= L.reagents.maximum_volume)
return
L.visible_message("<span class='danger'>[user] injects [L] with the syringe!", \
"<span class='userdanger'>[user] injects [L] with the syringe!")
var/list/rinject = list()
for(var/datum/reagent/R in reagents.reagent_list)
rinject += R.name
var/contained = english_list(rinject)
if(L != user)
add_logs(user, L, "injected", src, addition="which had [contained]")
else
log_attack("<font color='red'>[user.name] ([user.ckey]) injected [L.name] ([L.ckey]) with [src.name], which had [contained] (INTENT: [uppertext(user.a_intent)])</font>")
L.attack_log += "\[[time_stamp()]\] <font color='orange'>Injected themselves ([contained]) with [src.name].</font>"
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
reagents.reaction(L, INJECT, fraction)
reagents.trans_to(target, amount_per_transfer_from_this)
user << "<span class='notice'>You inject [amount_per_transfer_from_this] units of the solution. The syringe now contains [reagents.total_volume] units.</span>"
if (reagents.total_volume <= 0 && mode==SYRINGE_INJECT)
mode = SYRINGE_DRAW
update_icon()
/obj/item/weapon/reagent_containers/syringe/update_icon()
var/rounded_vol = Clamp(round((reagents.total_volume / volume * 15),5), 0, 15)
cut_overlays()
if(ismob(loc))
var/injoverlay
switch(mode)
if (SYRINGE_DRAW)
injoverlay = "draw"
if (SYRINGE_INJECT)
injoverlay = "inject"
add_overlay(injoverlay)
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
if(reagents.total_volume)
var/image/filling = image('icons/obj/reagentfillings.dmi', src, "syringe10")
filling.icon_state = "syringe[rounded_vol]"
filling.color = mix_color_from_reagents(reagents.reagent_list)
add_overlay(filling)
/obj/item/weapon/reagent_containers/syringe/epinephrine
name = "syringe (epinephrine)"
desc = "Contains epinephrine - used to stabilize patients."
list_reagents = list("epinephrine" = 15)
/obj/item/weapon/reagent_containers/syringe/charcoal
name = "syringe (charcoal)"
desc = "Contains charcoal."
list_reagents = list("charcoal" = 15)
/obj/item/weapon/reagent_containers/syringe/antiviral
name = "syringe (spaceacillin)"
desc = "Contains antiviral agents."
list_reagents = list("spaceacillin" = 15)
/obj/item/weapon/reagent_containers/syringe/bioterror
name = "bioterror syringe"
desc = "Contains several paralyzing reagents."
list_reagents = list("neurotoxin" = 5, "mutetoxin" = 5, "sodium_thiopental" = 5)
/obj/item/weapon/reagent_containers/syringe/stimulants
name = "Stimpack"
desc = "Contains stimulants."
amount_per_transfer_from_this = 50
volume = 50
list_reagents = list("stimulants" = 50)
/obj/item/weapon/reagent_containers/syringe/calomel
name = "syringe (calomel)"
desc = "Contains calomel."
list_reagents = list("calomel" = 15)
/obj/item/weapon/reagent_containers/syringe/lethal
name = "lethal injection syringe"
desc = "A syringe used for lethal injections. It can hold up to 50 units."
amount_per_transfer_from_this = 50
volume = 50
/obj/item/weapon/reagent_containers/syringe/lethal/choral
list_reagents = list("chloralhydrate" = 50)
/obj/item/weapon/reagent_containers/syringe/mulligan
name = "Mulligan"
desc = "A syringe used to completely change the users identity."
amount_per_transfer_from_this = 1
volume = 1
list_reagents = list("mulligan" = 1)
/obj/item/weapon/reagent_containers/syringe/gluttony
name = "Gluttony's Blessing"
desc = "A syringe recovered from a dread place. It probably isn't wise to use."
amount_per_transfer_from_this = 1
volume = 1
list_reagents = list("gluttonytoxin" = 1)
/obj/item/weapon/reagent_containers/syringe/bluespace
name = "bluespace syringe"
desc = "An advanced syringe that can hold 60 units of chemicals"
amount_per_transfer_from_this = 20
volume = 60
origin_tech = "bluespace=4;materials=4;biotech=4"
/obj/item/weapon/reagent_containers/syringe/noreact
name = "cryo syringe"
desc = "An advanced syringe that stops reagents inside from reacting. It can hold up to 20 units."
volume = 20
origin_tech = "materials=3;engineering=3"
/obj/item/weapon/reagent_containers/syringe/noreact/New()
. = ..()
reagents.set_reacting(FALSE)
/obj/item/weapon/reagent_containers/syringe/piercing
name = "piercing syringe"
desc = "A diamond-tipped syringe that pierces armor when launched at high velocity. It can hold up to 10 units."
volume = 10
projectile_type = /obj/item/projectile/bullet/dart/syringe/piercing
origin_tech = "combat=3;materials=4;engineering=5"
+192
View File
@@ -0,0 +1,192 @@
/obj/structure/reagent_dispensers
name = "Dispenser"
desc = "..."
icon = 'icons/obj/objects.dmi'
icon_state = "water"
density = 1
anchored = 0
pressure_resistance = 2*ONE_ATMOSPHERE
var/tank_volume = 1000 //In units, how much the dispenser can hold
var/reagent_id = "water" //The ID of the reagent that the dispenser uses
/obj/structure/reagent_dispensers/ex_act(severity, target)
switch(severity)
if(1)
qdel(src)
return
if(2)
if (prob(50))
qdel(src)
return
if(3)
if (prob(5))
qdel(src)
return
else
return
/obj/structure/reagent_dispensers/blob_act(obj/effect/blob/B)
if(prob(50))
qdel(src)
/obj/structure/reagent_dispensers/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/reagent_containers))
return 0 //so we can refill them via their afterattack.
else
return ..()
/obj/structure/reagent_dispensers/New()
create_reagents(tank_volume)
reagents.add_reagent(reagent_id, tank_volume)
..()
/obj/structure/reagent_dispensers/examine(mob/user)
..()
if(reagents.total_volume)
user << "<span class='notice'>It has [reagents.total_volume] units left.</span>"
else
user << "<span class='danger'>It's empty.</span>"
/obj/structure/reagent_dispensers/watertank
name = "water tank"
desc = "A water tank."
icon_state = "water"
/obj/structure/reagent_dispensers/watertank/ex_act(severity, target)
switch(severity)
if(1)
qdel(src)
return
if(2)
if (prob(50))
PoolOrNew(/obj/effect/particle_effect/water, src.loc)
qdel(src)
return
if(3)
if (prob(5))
PoolOrNew(/obj/effect/particle_effect/water, src.loc)
qdel(src)
return
else
return
/obj/structure/reagent_dispensers/watertank/blob_act(obj/effect/blob/B)
if(prob(50))
PoolOrNew(/obj/effect/particle_effect/water, loc)
qdel(src)
/obj/structure/reagent_dispensers/watertank/high
name = "high-capacity water tank"
desc = "A highly-pressurized water tank made to hold gargantuan amounts of water.."
icon_state = "water_high" //I was gonna clean my room...
tank_volume = 100000
/obj/structure/reagent_dispensers/fueltank
name = "fuel tank"
desc = "A tank full of industrial welding fuel. Do not consume."
icon_state = "fuel"
reagent_id = "welding_fuel"
/obj/structure/reagent_dispensers/fueltank/bullet_act(obj/item/projectile/Proj)
..()
if(istype(Proj) && !Proj.nodamage && ((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE)))
message_admins("[key_name_admin(Proj.firer)] triggered a fueltank explosion via projectile.")
log_game("[key_name(Proj.firer)] triggered a fueltank explosion via projectile.")
boom()
/obj/structure/reagent_dispensers/fueltank/proc/boom()
explosion(get_turf(src), 0, 1, 5, flame_range = 5)
qdel(src)
/obj/structure/reagent_dispensers/fueltank/blob_act(obj/effect/blob/B)
boom()
/obj/structure/reagent_dispensers/fueltank/ex_act()
boom()
/obj/structure/reagent_dispensers/fueltank/fire_act()
boom()
/obj/structure/reagent_dispensers/fueltank/tesla_act()
..() //extend the zap
boom()
/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/weapon/weldingtool))
if(!reagents.has_reagent("welding_fuel"))
user << "<span class='warning'>[src] is out of fuel!</span>"
return
var/obj/item/weapon/weldingtool/W = I
if(!W.welding)
if(W.reagents.has_reagent("welding_fuel", W.max_fuel))
user << "<span class='warning'>Your [W.name] is already full!</span>"
return
reagents.trans_to(W, W.max_fuel)
user.visible_message("<span class='notice'>[user] refills \his [W.name].</span>", "<span class='notice'>You refill [W].</span>")
playsound(src, 'sound/effects/refill.ogg', 50, 1)
update_icon()
else
user.visible_message("<span class='warning'>[user] catastrophically fails at refilling \his [W.name]!</span>", "<span class='userdanger'>That was stupid of you.</span>")
message_admins("[key_name_admin(user)] triggered a fueltank explosion via welding tool.")
log_game("[key_name(user)] triggered a fueltank explosion via welding tool.")
boom()
return
return ..()
/obj/structure/reagent_dispensers/peppertank
name = "pepper spray refiller"
desc = "Contains condensed capsaicin for use in law \"enforcement.\""
icon_state = "pepper"
anchored = 1
density = 0
reagent_id = "condensedcapsaicin"
/obj/structure/reagent_dispensers/peppertank/New()
..()
if(prob(1))
desc = "IT'S PEPPER TIME, BITCH!"
/obj/structure/reagent_dispensers/water_cooler
name = "liquid cooler"
desc = "A machine that dispenses liquid to drink."
icon = 'icons/obj/vending.dmi'
icon_state = "water_cooler"
anchored = 1
tank_volume = 500
var/paper_cups = 25 //Paper cups left from the cooler
/obj/structure/reagent_dispensers/water_cooler/examine(mob/user)
..()
user << "There are [paper_cups ? paper_cups : "no"] paper cups left."
/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user)
if(!paper_cups)
user << "<span class='warning'>There aren't any cups left!</span>"
return
user.visible_message("<span class='notice'>[user] takes a cup from [src].</span>", "<span class='notice'>You take a paper cup from [src].</span>")
var/obj/item/weapon/reagent_containers/food/drinks/sillycup/S = new(get_turf(src))
user.put_in_hands(S)
paper_cups--
/obj/structure/reagent_dispensers/beerkeg
name = "beer keg"
desc = "Beer is liquid bread, it's good for you..."
icon_state = "beer"
reagent_id = "beer"
/obj/structure/reagent_dispensers/beerkeg/blob_act(obj/effect/blob/B)
explosion(src.loc,0,3,5,7,10)
/obj/structure/reagent_dispensers/virusfood
name = "virus food dispenser"
desc = "A dispenser of low-potency virus mutagenic."
icon_state = "virus_food"
anchored = 1
reagent_id = "virusfood"