mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
[MIRROR] Oops, I refactored Chemistry!
This commit is contained in:
committed by
Darlantan
parent
1f33d5696f
commit
ca996648dd
@@ -50,3 +50,11 @@ var/list/tachycardics = list("coffee", "inaprovaline", "hyperzine", "nitroglyce
|
||||
var/list/bradycardics = list("neurotoxin", "cryoxadone", "clonexadone", "space_drugs", "stoxin") // Decrease heart rate.
|
||||
var/list/heartstopper = list("potassium_chlorophoride", "zombie_powder") // This stops the heart.
|
||||
var/list/cheartstopper = list("potassium_chloride") // This stops the heart when overdose is met. -- c = conditional
|
||||
|
||||
#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites
|
||||
#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites
|
||||
#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once
|
||||
#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill
|
||||
#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch
|
||||
#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume)
|
||||
#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever
|
||||
58
code/controllers/subsystems/chemistry.dm
Normal file
58
code/controllers/subsystems/chemistry.dm
Normal file
@@ -0,0 +1,58 @@
|
||||
SUBSYSTEM_DEF(chemistry)
|
||||
name = "Chemistry"
|
||||
wait = 20
|
||||
flags = SS_NO_FIRE
|
||||
init_order = INIT_ORDER_CHEMISTRY
|
||||
|
||||
var/list/chemical_reactions = list()
|
||||
var/list/instant_reactions_by_reagent = list()
|
||||
var/list/distilled_reactions_by_reagent = list()
|
||||
// var/list/fusion_reactions_by_reagent = list() // TODO: Fusion reactions as chemical reactions
|
||||
var/list/chemical_reagents = list()
|
||||
|
||||
/datum/controller/subsystem/chemistry/Recover()
|
||||
log_debug("[name] subsystem Recover().")
|
||||
chemical_reactions = SSchemistry.chemical_reactions
|
||||
chemical_reagents = SSchemistry.chemical_reagents
|
||||
|
||||
/datum/controller/subsystem/chemistry/Initialize()
|
||||
initialize_chemical_reagents()
|
||||
initialize_chemical_reactions()
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/chemistry/stat_entry()
|
||||
..("C: [chemical_reagents.len] | R: [chemical_reactions.len]")
|
||||
|
||||
//Chemical Reactions - Initialises all /decl/chemical_reaction into a list
|
||||
// It is filtered into multiple lists within a list.
|
||||
// For example:
|
||||
// chemical_reactions_by_reagent["phoron"] is a list of all reactions relating to phoron
|
||||
// Note that entries in the list are NOT duplicated. So if a reaction pertains to
|
||||
// more than one chemical it will still only appear in only one of the sublists.
|
||||
/datum/controller/subsystem/chemistry/proc/initialize_chemical_reactions()
|
||||
var/list/paths = decls_repository.get_decls_of_subtype(/decl/chemical_reaction)
|
||||
|
||||
for(var/path in paths)
|
||||
var/decl/chemical_reaction/D = paths[path]
|
||||
chemical_reactions += D
|
||||
if(D.required_reagents && D.required_reagents.len)
|
||||
var/reagent_id = D.required_reagents[1]
|
||||
|
||||
var/list/add_to = instant_reactions_by_reagent // Default to instant reactions list, if something's gone wrong
|
||||
// if(istype(D, /decl/chemical_reaction/fusion)) // TODO: fusion reactions as chemical reactions
|
||||
// add_to = fusion_reactions_by_reagent
|
||||
if(istype(D, /decl/chemical_reaction/distilling))
|
||||
add_to = distilled_reactions_by_reagent
|
||||
|
||||
LAZYINITLIST(add_to[reagent_id])
|
||||
add_to[reagent_id] += D
|
||||
|
||||
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
|
||||
/datum/controller/subsystem/chemistry/proc/initialize_chemical_reagents()
|
||||
var/paths = subtypesof(/datum/reagent)
|
||||
chemical_reagents = list()
|
||||
for(var/path in paths)
|
||||
var/datum/reagent/D = new path()
|
||||
if(!D.name)
|
||||
continue
|
||||
chemical_reagents[D.id] = D
|
||||
@@ -1,54 +0,0 @@
|
||||
PROCESSING_SUBSYSTEM_DEF(chemistry)
|
||||
name = "Chemistry"
|
||||
wait = 20
|
||||
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING
|
||||
init_order = INIT_ORDER_CHEMISTRY
|
||||
var/list/chemical_reactions = list()
|
||||
var/list/chemical_reactions_by_reagent = list()
|
||||
var/list/chemical_reagents = list()
|
||||
|
||||
/datum/controller/subsystem/processing/chemistry/Recover()
|
||||
log_debug("[name] subsystem Recover().")
|
||||
if(SSchemistry.current_thing)
|
||||
log_debug("current_thing was: (\ref[SSchemistry.current_thing])[SSchemistry.current_thing]([SSchemistry.current_thing.type]) - currentrun: [SSchemistry.currentrun.len] vs total: [SSchemistry.processing.len]")
|
||||
var/list/old_processing = SSchemistry.processing.Copy()
|
||||
for(var/datum/D in old_processing)
|
||||
if(CHECK_BITFIELD(D.datum_flags, DF_ISPROCESSING))
|
||||
processing |= D
|
||||
|
||||
chemical_reactions = SSchemistry.chemical_reactions
|
||||
chemical_reagents = SSchemistry.chemical_reagents
|
||||
|
||||
/datum/controller/subsystem/processing/chemistry/Initialize()
|
||||
initialize_chemical_reactions()
|
||||
initialize_chemical_reagents()
|
||||
..()
|
||||
|
||||
//Chemical Reactions - Initialises all /datum/chemical_reaction into a list
|
||||
// It is filtered into multiple lists within a list.
|
||||
// For example:
|
||||
// chemical_reaction_list["phoron"] is a list of all reactions relating to phoron
|
||||
// Note that entries in the list are NOT duplicated. So if a reaction pertains to
|
||||
// more than one chemical it will still only appear in only one of the sublists.
|
||||
/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reactions()
|
||||
var/paths = typesof(/datum/chemical_reaction) - /datum/chemical_reaction
|
||||
chemical_reactions = list()
|
||||
chemical_reactions_by_reagent = list()
|
||||
|
||||
for(var/path in paths)
|
||||
var/datum/chemical_reaction/D = new path
|
||||
chemical_reactions += D
|
||||
if(D.required_reagents && D.required_reagents.len)
|
||||
var/reagent_id = D.required_reagents[1]
|
||||
LAZYINITLIST(chemical_reactions_by_reagent[reagent_id])
|
||||
chemical_reactions_by_reagent[reagent_id] += D
|
||||
|
||||
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
|
||||
/datum/controller/subsystem/processing/chemistry/proc/initialize_chemical_reagents()
|
||||
var/paths = typesof(/datum/reagent) - /datum/reagent
|
||||
chemical_reagents = list()
|
||||
for(var/path in paths)
|
||||
var/datum/reagent/D = new path()
|
||||
if(!D.name)
|
||||
continue
|
||||
chemical_reagents[D.id] = D
|
||||
@@ -118,19 +118,19 @@
|
||||
|
||||
return FALSE
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution
|
||||
/decl/chemical_reaction/instant/blob_reconstitution
|
||||
name = "Hostile Blob Revival"
|
||||
id = "blob_revival"
|
||||
result = null
|
||||
required_reagents = list("phoron" = 60)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution/can_happen(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/blob_reconstitution/can_happen(var/datum/reagents/holder)
|
||||
if(holder.my_atom && istype(holder.my_atom, /obj/item/weapon/blobcore_chunk))
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/blob_reconstitution/on_reaction(var/datum/reagents/holder)
|
||||
var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom
|
||||
if(chunk.can_genesis && chunk.regen())
|
||||
chunk.visible_message("<span class='notice'>[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!</span>")
|
||||
@@ -138,14 +138,14 @@
|
||||
else
|
||||
chunk.visible_message("<span class='warning'>[chunk] shifts strangely, but falls still.</span>")
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution/domination
|
||||
/decl/chemical_reaction/instant/blob_reconstitution/domination
|
||||
name = "Allied Blob Revival"
|
||||
id = "blob_friend"
|
||||
result = null
|
||||
required_reagents = list("hydrophoron" = 40, "peridaxon" = 20, "mutagen" = 20)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/blob_reconstitution/domination/on_reaction(var/datum/reagents/holder)
|
||||
var/obj/item/weapon/blobcore_chunk/chunk = holder.my_atom
|
||||
if(chunk.can_genesis && chunk.regen("neutral"))
|
||||
chunk.visible_message("<span class='notice'>[chunk] bubbles, surrounding itself with a rapidly expanding mass of [chunk.blob_type.name]!</span>")
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
//---Beverages---//
|
||||
//***************//
|
||||
|
||||
/datum/reagent/var/price_tag = null
|
||||
/datum/reagent/var/price_tag = 0
|
||||
|
||||
|
||||
// Juices, soda and similar //
|
||||
|
||||
@@ -274,8 +274,7 @@
|
||||
/datum/event/supply_demand/proc/choose_chemistry_items(var/differentTypes)
|
||||
// Checking if they show up in health analyzer is good huristic for it being a drug
|
||||
var/list/medicineReagents = list()
|
||||
for(var/path in typesof(/datum/chemical_reaction) - /datum/chemical_reaction)
|
||||
var/datum/chemical_reaction/CR = path // Stupid casting required for reading
|
||||
for(var/decl/chemical_reaction/instant/CR in SSchemistry.chemical_reactions)
|
||||
var/datum/reagent/R = SSchemistry.chemical_reagents[initial(CR.result)]
|
||||
if(R && R.scannable)
|
||||
medicineReagents += R
|
||||
@@ -288,8 +287,7 @@
|
||||
|
||||
/datum/event/supply_demand/proc/choose_bar_items(var/differentTypes)
|
||||
var/list/drinkReagents = list()
|
||||
for(var/path in typesof(/datum/chemical_reaction) - /datum/chemical_reaction)
|
||||
var/datum/chemical_reaction/CR = path // Stupid casting required for reading
|
||||
for(var/decl/chemical_reaction/instant/drinks/CR in SSchemistry.chemical_reactions)
|
||||
var/datum/reagent/R = SSchemistry.chemical_reagents[initial(CR.result)]
|
||||
if(istype(R, /datum/reagent/drink) || istype(R, /datum/reagent/ethanol))
|
||||
drinkReagents += R
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
|
||||
//////////////////////// DRINK
|
||||
var/list/drink_recipes = list()
|
||||
for(var/path in typesof(/datum/chemical_reaction/drinks) - /datum/chemical_reaction/drinks)
|
||||
var/datum/chemical_reaction/drinks/CR = new path()
|
||||
drink_recipes[path] = list("Result" = CR.name,
|
||||
for(var/decl/chemical_reaction/instant/drinks/CR in SSchemistry.chemical_reactions)
|
||||
drink_recipes[CR.type] = list("Result" = CR.name,
|
||||
"ResAmt" = CR.result_amount,
|
||||
"Reagents" = CR.required_reagents,
|
||||
"Catalysts" = CR.catalysts)
|
||||
qdel(CR)
|
||||
|
||||
//////////////////////// FOOD
|
||||
var/list/food_recipes = typesof(/datum/recipe) - /datum/recipe
|
||||
@@ -43,16 +41,14 @@
|
||||
qdel(R)
|
||||
|
||||
//////////////////////// FOOD+ (basically condiments, tofu, cheese, soysauce, etc)
|
||||
for(var/path in typesof(/datum/chemical_reaction/food) - /datum/chemical_reaction/food)
|
||||
var/datum/chemical_reaction/food/CR = new path()
|
||||
food_recipes[path] = list("Result" = CR.name,
|
||||
for(var/decl/chemical_reaction/instant/food/CR in SSchemistry.chemical_reactions)
|
||||
food_recipes[CR.type] = list("Result" = CR.name,
|
||||
"ResAmt" = CR.result_amount,
|
||||
"Reagents" = CR.required_reagents,
|
||||
"Catalysts" = CR.catalysts,
|
||||
"Fruit" = list(),
|
||||
"Ingredients" = list(),
|
||||
"Image" = null)
|
||||
qdel(CR)
|
||||
|
||||
//////////////////////// PROCESSING
|
||||
//Items needs further processing into human-readability.
|
||||
|
||||
@@ -276,19 +276,19 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
|
||||
qdel(src)
|
||||
return 1
|
||||
|
||||
/datum/chemical_reaction/promethean_brain_revival
|
||||
/decl/chemical_reaction/instant/promethean_brain_revival
|
||||
name = "Promethean Revival"
|
||||
id = "prom_revival"
|
||||
result = null
|
||||
required_reagents = list("phoron" = 40)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/promethean_brain_revival/can_happen(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/promethean_brain_revival/can_happen(var/datum/reagents/holder)
|
||||
if(holder.my_atom && istype(holder.my_atom, /obj/item/organ/internal/brain/slime))
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/datum/chemical_reaction/promethean_brain_revival/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/promethean_brain_revival/on_reaction(var/datum/reagents/holder)
|
||||
var/obj/item/organ/internal/brain/slime/brain = holder.my_atom
|
||||
if(brain.reviveBody())
|
||||
brain.visible_message("<span class='notice'>[brain] bubbles, surrounding itself with a rapidly expanding mass of slime!</span>")
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define FUSION_ROD_SHEET_AMT 15
|
||||
/obj/machinery/fusion_fuel_compressor
|
||||
var/blitzprogress = 0 //CHOMPEdit
|
||||
name = "fuel compressor"
|
||||
@@ -51,6 +52,7 @@
|
||||
if(istype(thing, /obj/item/stack/material))
|
||||
var/obj/item/stack/material/M = thing
|
||||
var/datum/material/mat = M.get_material()
|
||||
<<<<<<< HEAD
|
||||
if(!blitzprogress)
|
||||
if(!mat.is_fusion_fuel)
|
||||
to_chat(user, "<span class='warning'>It would be pointless to make a fuel rod out of [mat.use_name].</span>")
|
||||
@@ -82,10 +84,34 @@
|
||||
else
|
||||
to_chat(user, "<span class='warning'>A blitz rod is currently in progress! Either add 25 phoron sheets to complete it, or eject the supermatter sheet!</span>")
|
||||
return
|
||||
||||||| parent of 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
if(!mat.is_fusion_fuel)
|
||||
to_chat(user, "<span class='warning'>It would be pointless to make a fuel rod out of [mat.use_name].</span>")
|
||||
return
|
||||
if(M.get_amount() < 15)
|
||||
to_chat(user, "<span class='warning'>You need at least 25 [mat.sheet_plural_name] to make a fuel rod.</span>")
|
||||
return
|
||||
var/obj/item/weapon/fuel_assembly/F = new(get_turf(src), mat.name)
|
||||
visible_message("<span class='notice'>\The [src] compresses the [mat.use_name] into a new fuel assembly.</span>")
|
||||
M.use(15)
|
||||
user.put_in_hands(F)
|
||||
=======
|
||||
if(!mat.is_fusion_fuel)
|
||||
to_chat(user, "<span class='warning'>It would be pointless to make a fuel rod out of [mat.use_name].</span>")
|
||||
return
|
||||
if(M.get_amount() < FUSION_ROD_SHEET_AMT)
|
||||
to_chat(user, "<span class='warning'>You need at least 25 [mat.sheet_plural_name] to make a fuel rod.</span>")
|
||||
return
|
||||
var/obj/item/weapon/fuel_assembly/F = new(get_turf(src), mat.name)
|
||||
visible_message("<span class='notice'>\The [src] compresses the [mat.use_name] into a new fuel assembly.</span>")
|
||||
M.use(FUSION_ROD_SHEET_AMT)
|
||||
user.put_in_hands(F)
|
||||
>>>>>>> 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
|
||||
else if(do_special_fuel_compression(thing, user))
|
||||
return
|
||||
|
||||
<<<<<<< HEAD
|
||||
return ..()
|
||||
|
||||
/obj/machinery/fusion_fuel_compressor/verb/eject_sheet()
|
||||
@@ -98,3 +124,10 @@
|
||||
verbs -= /obj/machinery/fusion_fuel_compressor/verb/eject_sheet
|
||||
blitzprogress = 0
|
||||
//CHOMPEdit End
|
||||
||||||| parent of 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
return ..()
|
||||
=======
|
||||
return ..()
|
||||
|
||||
#undef FUSION_ROD_SHEET_AMT
|
||||
>>>>>>> 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
//Additional fusion reagents. These likely don't have any other use aside from the RUST, but if you want to make stuff with 'em, be my guest.
|
||||
|
||||
/datum/reagent/helium3
|
||||
name = "helium-3"
|
||||
description = "A colorless, odorless, tasteless and generally inert gas used in fusion reactors. Non-radioactive."
|
||||
id = "helium-3"
|
||||
reagent_state = GAS
|
||||
color = "#808080"
|
||||
|
||||
/obj/structure/reagent_dispensers/he3
|
||||
name = "fueltank"
|
||||
desc = "A fueltank."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "weldtank"
|
||||
amount_per_transfer_from_this = 10
|
||||
New()
|
||||
..()
|
||||
reagents.add_reagent("helium-3",1000)
|
||||
@@ -1,519 +0,0 @@
|
||||
#define PROCESS_REACTION_ITER 5 //when processing a reaction, iterate this many times
|
||||
|
||||
/datum/reagents
|
||||
var/list/datum/reagent/reagent_list = list()
|
||||
var/total_volume = 0
|
||||
var/maximum_volume = 100
|
||||
var/atom/my_atom = null
|
||||
|
||||
/datum/reagents/New(var/max = 100, atom/A = null)
|
||||
..()
|
||||
maximum_volume = max
|
||||
my_atom = A
|
||||
|
||||
//I dislike having these here but map-objects are initialised before world/New() is called. >_>
|
||||
if(!SSchemistry.chemical_reagents)
|
||||
//Chemical Reagents - Initialises all /datum/reagent into a list indexed by reagent id
|
||||
var/paths = typesof(/datum/reagent) - /datum/reagent
|
||||
SSchemistry.chemical_reagents = list()
|
||||
for(var/path in paths)
|
||||
var/datum/reagent/D = new path()
|
||||
if(!D.name)
|
||||
continue
|
||||
SSchemistry.chemical_reagents[D.id] = D
|
||||
|
||||
/datum/reagents/Destroy()
|
||||
STOP_PROCESSING(SSchemistry, src)
|
||||
for(var/datum/reagent/R in reagent_list)
|
||||
qdel(R)
|
||||
reagent_list = null
|
||||
if(my_atom && my_atom.reagents == src)
|
||||
my_atom.reagents = null
|
||||
return ..()
|
||||
|
||||
/* Internal procs */
|
||||
|
||||
/datum/reagents/proc/get_free_space() // Returns free space.
|
||||
return maximum_volume - total_volume
|
||||
|
||||
/datum/reagents/proc/get_master_reagent() // Returns reference to the reagent with the biggest volume.
|
||||
var/the_reagent = null
|
||||
var/the_volume = 0
|
||||
|
||||
for(var/datum/reagent/A in reagent_list)
|
||||
if(A.volume > the_volume)
|
||||
the_volume = A.volume
|
||||
the_reagent = A
|
||||
|
||||
return the_reagent
|
||||
|
||||
/datum/reagents/proc/get_master_reagent_name() // Returns the name of the reagent with the biggest volume.
|
||||
var/the_name = null
|
||||
var/the_volume = 0
|
||||
for(var/datum/reagent/A in reagent_list)
|
||||
if(A.volume > the_volume)
|
||||
the_volume = A.volume
|
||||
the_name = A.name
|
||||
|
||||
return the_name
|
||||
|
||||
/datum/reagents/proc/get_master_reagent_id() // Returns the id of the reagent with the biggest volume.
|
||||
var/the_id = null
|
||||
var/the_volume = 0
|
||||
for(var/datum/reagent/A in reagent_list)
|
||||
if(A.volume > the_volume)
|
||||
the_volume = A.volume
|
||||
the_id = A.id
|
||||
|
||||
return the_id
|
||||
|
||||
/datum/reagents/proc/update_total() // Updates volume.
|
||||
total_volume = 0
|
||||
for(var/datum/reagent/R in reagent_list)
|
||||
if(R.volume < MINIMUM_CHEMICAL_VOLUME)
|
||||
del_reagent(R.id)
|
||||
else
|
||||
total_volume += R.volume
|
||||
return
|
||||
|
||||
/datum/reagents/proc/handle_reactions()
|
||||
if(QDELETED(my_atom))
|
||||
return FALSE
|
||||
if(my_atom.flags & NOREACT)
|
||||
return FALSE
|
||||
var/reaction_occurred
|
||||
var/list/eligible_reactions = list()
|
||||
var/list/effect_reactions = list()
|
||||
do
|
||||
reaction_occurred = FALSE
|
||||
for(var/i in reagent_list)
|
||||
var/datum/reagent/R = i
|
||||
if(SSchemistry.chemical_reactions_by_reagent[R.id])
|
||||
eligible_reactions |= SSchemistry.chemical_reactions_by_reagent[R.id]
|
||||
|
||||
for(var/i in eligible_reactions)
|
||||
var/datum/chemical_reaction/C = i
|
||||
if(C.can_happen(src) && C.process(src))
|
||||
effect_reactions |= C
|
||||
reaction_occurred = TRUE
|
||||
eligible_reactions.len = 0
|
||||
while(reaction_occurred)
|
||||
for(var/i in effect_reactions)
|
||||
var/datum/chemical_reaction/C = i
|
||||
C.post_reaction(src)
|
||||
update_total()
|
||||
|
||||
/* Holder-to-chemical */
|
||||
|
||||
/datum/reagents/proc/add_reagent(var/id, var/amount, var/data = null, var/safety = 0)
|
||||
if(!isnum(amount) || amount <= 0)
|
||||
return 0
|
||||
|
||||
update_total()
|
||||
amount = min(amount, get_free_space())
|
||||
|
||||
if(istype(my_atom,/obj/item/weapon/reagent_containers/food)) //The following code is targeted specifically at getting allergen reagents into food items, since for the most part they're not applied by default.
|
||||
var/list/add_reagents = list()
|
||||
var/totalnum = 0
|
||||
|
||||
for(var/item in data) //Try to find the ID
|
||||
var/add_reagent_id = null
|
||||
if(item in SSchemistry.chemical_reagents)
|
||||
add_reagent_id = item
|
||||
else if("[item]juice" in SSchemistry.chemical_reagents)
|
||||
add_reagent_id = "[item]juice"
|
||||
if(add_reagent_id) //If we did find it, add it to our list of reagents to add, and add the number to our total.
|
||||
add_reagents[add_reagent_id] += data[item]
|
||||
totalnum += data[item]
|
||||
|
||||
if(totalnum)
|
||||
var/multconst = amount/totalnum //We're going to add these extra reagents so that they share the ratio described, but only add up to 1x the existing amount at the most
|
||||
for(var/item in add_reagents)
|
||||
add_reagent(item,add_reagents[item]*multconst)
|
||||
|
||||
|
||||
|
||||
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
if(current.id == id)
|
||||
if(current.id == "blood")
|
||||
if(LAZYLEN(data) && !isnull(data["species"]) && !isnull(current.data["species"]) && data["species"] != current.data["species"]) // Species bloodtypes are already incompatible, this just stops it from mixing into the one already in a container.
|
||||
continue
|
||||
|
||||
current.volume += amount
|
||||
if(!isnull(data)) // For all we know, it could be zero or empty string and meaningful
|
||||
current.mix_data(data, amount)
|
||||
update_total()
|
||||
if(!safety)
|
||||
handle_reactions()
|
||||
if(my_atom)
|
||||
my_atom.on_reagent_change()
|
||||
return 1
|
||||
var/datum/reagent/D = SSchemistry.chemical_reagents[id]
|
||||
if(D)
|
||||
var/datum/reagent/R = new D.type()
|
||||
reagent_list += R
|
||||
R.holder = src
|
||||
R.volume = amount
|
||||
R.initialize_data(data)
|
||||
update_total()
|
||||
if(!safety)
|
||||
handle_reactions()
|
||||
if(my_atom)
|
||||
my_atom.on_reagent_change()
|
||||
return 1
|
||||
else
|
||||
crash_with("[my_atom] attempted to add a reagent called '[id]' which doesn't exist. ([usr])")
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/isolate_reagent(reagent)
|
||||
for(var/A in reagent_list)
|
||||
var/datum/reagent/R = A
|
||||
if(R.id != reagent)
|
||||
del_reagent(R.id)
|
||||
update_total()
|
||||
|
||||
/datum/reagents/proc/remove_reagent(var/id, var/amount, var/safety = 0)
|
||||
if(!isnum(amount))
|
||||
return 0
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
if(current.id == id)
|
||||
current.volume -= amount // It can go negative, but it doesn't matter
|
||||
update_total() // Because this proc will delete it then
|
||||
if(!safety)
|
||||
handle_reactions()
|
||||
if(my_atom)
|
||||
my_atom.on_reagent_change()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/del_reagent(var/id)
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
if (current.id == id)
|
||||
current.on_remove(my_atom) //YW Edit: Calls on_remove before the last of the thing is done, used in phorochemistry
|
||||
reagent_list -= current
|
||||
qdel(current)
|
||||
update_total()
|
||||
if(my_atom)
|
||||
my_atom.on_reagent_change()
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/has_reagent(var/id, var/amount = 0)
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
if(current.id == id)
|
||||
if(current.volume >= amount)
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/has_any_reagent(var/list/check_reagents)
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
if(current.id in check_reagents)
|
||||
if(current.volume >= check_reagents[current.id])
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/has_all_reagents(var/list/check_reagents)
|
||||
//this only works if check_reagents has no duplicate entries... hopefully okay since it expects an associative list
|
||||
var/missing = check_reagents.len
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
if(current.id in check_reagents)
|
||||
if(current.volume >= check_reagents[current.id])
|
||||
missing--
|
||||
return !missing
|
||||
|
||||
/datum/reagents/proc/clear_reagents()
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
del_reagent(current.id)
|
||||
return
|
||||
|
||||
/datum/reagents/proc/get_reagent_amount(var/id)
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
if(current.id == id)
|
||||
return current.volume
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/get_data(var/id)
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
if(current.id == id)
|
||||
return current.get_data()
|
||||
return 0
|
||||
|
||||
/datum/reagents/proc/get_reagents()
|
||||
. = list()
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
. += "[current.id] ([current.volume])"
|
||||
return english_list(., "EMPTY", "", ", ", ", ")
|
||||
|
||||
/* Holder-to-holder and similar procs */
|
||||
|
||||
/datum/reagents/proc/remove_any(var/amount = 1) // Removes up to [amount] of reagents from [src]. Returns actual amount removed.
|
||||
amount = min(amount, total_volume)
|
||||
|
||||
if(!amount)
|
||||
return
|
||||
|
||||
var/part = amount / total_volume
|
||||
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
var/amount_to_remove = current.volume * part
|
||||
remove_reagent(current.id, amount_to_remove, 1)
|
||||
|
||||
update_total()
|
||||
handle_reactions()
|
||||
return amount
|
||||
|
||||
/datum/reagents/proc/trans_to_holder(var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Transfers [amount] reagents from [src] to [target], multiplying them by [multiplier]. Returns actual amount removed from [src] (not amount transferred to [target]).
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
amount = max(0, min(amount, total_volume, target.get_free_space() / multiplier))
|
||||
|
||||
if(!amount)
|
||||
return
|
||||
|
||||
var/part = amount / total_volume
|
||||
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
var/amount_to_transfer = current.volume * part
|
||||
target.add_reagent(current.id, amount_to_transfer * multiplier, current.get_data(), safety = 1) // We don't react until everything is in place
|
||||
if(!copy)
|
||||
remove_reagent(current.id, amount_to_transfer, 1)
|
||||
|
||||
if(!copy)
|
||||
handle_reactions()
|
||||
target.handle_reactions()
|
||||
return amount
|
||||
|
||||
/* Holder-to-atom and similar procs */
|
||||
|
||||
//The general proc for applying reagents to things. This proc assumes the reagents are being applied externally,
|
||||
//not directly injected into the contents. It first calls touch, then the appropriate trans_to_*() or splash_mob().
|
||||
//If for some reason touch effects are bypassed (e.g. injecting stuff directly into a reagent container or person),
|
||||
//call the appropriate trans_to_*() proc.
|
||||
/datum/reagents/proc/trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
|
||||
touch(target) //First, handle mere touch effects
|
||||
|
||||
if(ismob(target))
|
||||
return splash_mob(target, amount, copy)
|
||||
if(isturf(target))
|
||||
return trans_to_turf(target, amount, multiplier, copy)
|
||||
if(isobj(target) && target.is_open_container())
|
||||
return trans_to_obj(target, amount, multiplier, copy)
|
||||
return 0
|
||||
|
||||
//Splashing reagents is messier than trans_to, the target's loc gets some of the reagents as well.
|
||||
/datum/reagents/proc/splash(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0, var/min_spill=0, var/max_spill=60)
|
||||
var/spill = 0
|
||||
if(!isturf(target) && target.loc)
|
||||
spill = amount*(rand(min_spill, max_spill)/100)
|
||||
amount -= spill
|
||||
if(spill)
|
||||
splash(target.loc, spill, multiplier, copy, min_spill, max_spill)
|
||||
|
||||
if(!trans_to(target, amount, multiplier, copy))
|
||||
touch(target, amount)
|
||||
|
||||
/datum/reagents/proc/trans_type_to(var/target, var/rtype, var/amount = 1)
|
||||
if (!target)
|
||||
return
|
||||
|
||||
var/datum/reagent/transfering_reagent = get_reagent(rtype)
|
||||
|
||||
if (istype(target, /atom))
|
||||
var/atom/A = target
|
||||
if (!A.reagents || !A.simulated)
|
||||
return
|
||||
|
||||
amount = min(amount, transfering_reagent.volume)
|
||||
|
||||
if(!amount)
|
||||
return
|
||||
|
||||
|
||||
var/datum/reagents/F = new /datum/reagents(amount)
|
||||
var/tmpdata = get_data(rtype)
|
||||
F.add_reagent(rtype, amount, tmpdata)
|
||||
remove_reagent(rtype, amount)
|
||||
|
||||
|
||||
if (istype(target, /atom))
|
||||
return F.trans_to(target, amount) // Let this proc check the atom's type
|
||||
else if (istype(target, /datum/reagents))
|
||||
return F.trans_to_holder(target, amount)
|
||||
|
||||
/datum/reagents/proc/trans_id_to(var/atom/target, var/id, var/amount = 1)
|
||||
if (!target || !target.reagents)
|
||||
return
|
||||
|
||||
amount = min(amount, get_reagent_amount(id))
|
||||
|
||||
if(!amount)
|
||||
return
|
||||
|
||||
var/datum/reagents/F = new /datum/reagents(amount)
|
||||
var/tmpdata = get_data(id)
|
||||
F.add_reagent(id, amount, tmpdata)
|
||||
remove_reagent(id, amount)
|
||||
|
||||
return F.trans_to(target, amount) // Let this proc check the atom's type
|
||||
|
||||
// When applying reagents to an atom externally, touch() is called to trigger any on-touch effects of the reagent.
|
||||
// This does not handle transferring reagents to things.
|
||||
// For example, splashing someone with water will get them wet and extinguish them if they are on fire,
|
||||
// even if they are wearing an impermeable suit that prevents the reagents from contacting the skin.
|
||||
/datum/reagents/proc/touch(var/atom/target, var/amount)
|
||||
if(ismob(target))
|
||||
touch_mob(target, amount)
|
||||
if(isturf(target))
|
||||
touch_turf(target, amount)
|
||||
if(isobj(target))
|
||||
touch_obj(target, amount)
|
||||
return
|
||||
|
||||
/datum/reagents/proc/touch_mob(var/mob/target)
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
current.touch_mob(target, current.volume)
|
||||
|
||||
update_total()
|
||||
|
||||
/datum/reagents/proc/touch_turf(var/turf/target, var/amount)
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
current.touch_turf(target, amount)
|
||||
|
||||
update_total()
|
||||
|
||||
/datum/reagents/proc/touch_obj(var/obj/target, var/amount)
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
|
||||
for(var/datum/reagent/current in reagent_list)
|
||||
current.touch_obj(target, amount)
|
||||
|
||||
update_total()
|
||||
|
||||
// Attempts to place a reagent on the mob's skin.
|
||||
// Reagents are not guaranteed to transfer to the target.
|
||||
// Do not call this directly, call trans_to() instead.
|
||||
/datum/reagents/proc/splash_mob(var/mob/target, var/amount = 1, var/copy = 0)
|
||||
var/perm = 1
|
||||
if(isliving(target)) //will we ever even need to tranfer reagents to non-living mobs?
|
||||
var/mob/living/L = target
|
||||
if(ishuman(L))
|
||||
var/mob/living/carbon/human/H = L
|
||||
if(H.check_shields(0, null, null, null, "the spray") == 1) //If they block the spray, it does nothing.
|
||||
amount = 0
|
||||
perm = L.reagent_permeability()
|
||||
return trans_to_mob(target, amount, CHEM_TOUCH, perm, copy)
|
||||
|
||||
/datum/reagents/proc/trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0) // Transfer after checking into which holder...
|
||||
if(!target || !istype(target))
|
||||
return
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(type == CHEM_BLOOD)
|
||||
var/datum/reagents/R = C.reagents
|
||||
return trans_to_holder(R, amount, multiplier, copy)
|
||||
if(type == CHEM_INGEST)
|
||||
var/datum/reagents/R = C.ingested
|
||||
return C.ingest(src, R, amount, multiplier, copy)
|
||||
if(type == CHEM_TOUCH)
|
||||
var/datum/reagents/R = C.touching
|
||||
return trans_to_holder(R, amount, multiplier, copy)
|
||||
else
|
||||
var/datum/reagents/R = new /datum/reagents(amount)
|
||||
. = trans_to_holder(R, amount, multiplier, copy)
|
||||
R.touch_mob(target)
|
||||
|
||||
/datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Turfs don't have any reagents (at least, for now). Just touch it.
|
||||
if(!target)
|
||||
return
|
||||
|
||||
var/datum/reagents/R = new /datum/reagents(amount * multiplier)
|
||||
. = trans_to_holder(R, amount, multiplier, copy)
|
||||
R.touch_turf(target, amount)
|
||||
return
|
||||
|
||||
/datum/reagents/proc/trans_to_obj(var/obj/target, var/amount = 1, var/multiplier = 1, var/copy = 0) // Objects may or may not; if they do, it's probably a beaker or something and we need to transfer properly; otherwise, just touch.
|
||||
if(!target)
|
||||
return
|
||||
|
||||
if(!target.reagents)
|
||||
var/datum/reagents/R = new /datum/reagents(amount * multiplier)
|
||||
. = trans_to_holder(R, amount, multiplier, copy)
|
||||
R.touch_obj(target, amount)
|
||||
return
|
||||
|
||||
return trans_to_holder(target.reagents, amount, multiplier, copy)
|
||||
|
||||
/* Atom reagent creation - use it all the time */
|
||||
|
||||
/atom/proc/create_reagents(var/max_vol)
|
||||
reagents = new/datum/reagents(max_vol, src)
|
||||
|
||||
// Aurora Cooking Port
|
||||
/datum/reagents/proc/get_reagent(var/id) // Returns reference to reagent matching passed ID
|
||||
for(var/datum/reagent/A in reagent_list)
|
||||
if (A.id == id)
|
||||
return A
|
||||
|
||||
return null
|
||||
|
||||
//Spreads the contents of this reagent holder all over the vicinity of the target turf.
|
||||
/datum/reagents/proc/splash_area(var/turf/epicentre, var/range = 3, var/portion = 1.0, var/multiplier = 1, var/copy = 0)
|
||||
var/list/things = dview(range, epicentre, INVISIBILITY_LIGHTING)
|
||||
var/list/turfs = list()
|
||||
for (var/turf/T in things)
|
||||
turfs += T
|
||||
if (!turfs.len)
|
||||
return//Nowhere to splash to, somehow
|
||||
//Create a temporary holder to hold all the amount that will be spread
|
||||
var/datum/reagents/R = new /datum/reagents(total_volume * portion * multiplier)
|
||||
trans_to_holder(R, total_volume * portion, multiplier, copy)
|
||||
//The exact amount that will be given to each turf
|
||||
var/turfportion = R.total_volume / turfs.len
|
||||
for (var/turf/T in turfs)
|
||||
var/datum/reagents/TR = new /datum/reagents(turfportion)
|
||||
R.trans_to_holder(TR, turfportion, 1, 0)
|
||||
TR.splash_turf(T)
|
||||
qdel(R)
|
||||
|
||||
|
||||
//Spreads the contents of this reagent holder all over the target turf, dividing among things in it.
|
||||
//50% is divided between mobs, 20% between objects, and whatever is left on the turf itself
|
||||
/datum/reagents/proc/splash_turf(var/turf/T, var/amount = null, var/multiplier = 1, var/copy = 0)
|
||||
if (isnull(amount))
|
||||
amount = total_volume
|
||||
else
|
||||
amount = min(amount, total_volume)
|
||||
if (amount <= 0)
|
||||
return
|
||||
var/list/mobs = list()
|
||||
for (var/mob/M in T)
|
||||
mobs += M
|
||||
var/list/objs = list()
|
||||
for (var/obj/O in T)
|
||||
objs += O
|
||||
if (objs.len)
|
||||
var/objportion = (amount * 0.2) / objs.len
|
||||
for (var/o in objs)
|
||||
var/obj/O = o
|
||||
trans_to(O, objportion, multiplier, copy)
|
||||
amount = min(amount, total_volume)
|
||||
if (mobs.len)
|
||||
var/mobportion = (amount * 0.5) / mobs.len
|
||||
for (var/m in mobs)
|
||||
var/mob/M = m
|
||||
trans_to(M, mobportion, multiplier, copy)
|
||||
trans_to(T, total_volume, multiplier, copy)
|
||||
if (total_volume <= 0)
|
||||
qdel(src)
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
/var/list/chemical_reaction_logs = list()
|
||||
|
||||
/proc/log_chemical_reaction(atom/A, datum/chemical_reaction/R, multiplier)
|
||||
/proc/log_chemical_reaction(atom/A, decl/chemical_reaction/R, multiplier)
|
||||
if(!A || !R)
|
||||
return
|
||||
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
|
||||
|
||||
|
||||
/datum/reagent
|
||||
var/name = "Reagent"
|
||||
var/id = "reagent"
|
||||
var/description = "A non-descript chemical."
|
||||
var/taste_description = "bitterness"
|
||||
var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable
|
||||
var/datum/reagents/holder = null
|
||||
var/reagent_state = SOLID
|
||||
var/list/data = null
|
||||
var/volume = 0
|
||||
var/metabolism = REM // This would be 0.2 normally
|
||||
var/list/filtered_organs = list() // Organs that will slow the processing of this chemical.
|
||||
var/mrate_static = FALSE //If the reagent should always process at the same speed, regardless of species, make this TRUE
|
||||
var/ingest_met = 0
|
||||
var/touch_met = 0
|
||||
var/dose = 0
|
||||
var/max_dose = 0
|
||||
var/overdose = 0 //Amount at which overdose starts
|
||||
var/overdose_mod = 1 //Modifier to overdose damage
|
||||
var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch?
|
||||
var/scannable = 0 // Shows up on health analyzers.
|
||||
|
||||
var/affects_dead = 0 // Does this chem process inside a corpse?
|
||||
var/affects_robots = 0 // Does this chem process inside a Synth?
|
||||
|
||||
var/allergen_type = GENERIC // What potential allergens does this contain?
|
||||
var/allergen_factor = 1 // If the potential allergens are mixed and low-volume, they're a bit less dangerous. Needed for drinks because they're a single reagent compared to food which contains multiple seperate reagents.
|
||||
|
||||
var/cup_icon_state = null
|
||||
var/cup_name = null
|
||||
var/cup_desc = null
|
||||
var/cup_center_of_mass = null
|
||||
|
||||
var/color = "#000000"
|
||||
var/color_weight = 1
|
||||
|
||||
var/glass_icon = DRINK_ICON_DEFAULT
|
||||
var/glass_name = "something"
|
||||
var/glass_desc = "It's a glass of... what, exactly?"
|
||||
var/list/glass_special = null // null equivalent to list()
|
||||
|
||||
/datum/reagent/proc/remove_self(var/amount) // Shortcut
|
||||
if(holder)
|
||||
holder.remove_reagent(id, amount)
|
||||
|
||||
// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing.
|
||||
/datum/reagent/proc/touch_mob(var/mob/M, var/amount)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc
|
||||
return
|
||||
|
||||
/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here
|
||||
return
|
||||
|
||||
/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob.
|
||||
if(!istype(M))
|
||||
return
|
||||
if(!affects_dead && M.stat == DEAD)
|
||||
return
|
||||
if(!affects_robots && M.isSynthetic())
|
||||
return
|
||||
if(!istype(location))
|
||||
return
|
||||
|
||||
var/datum/reagents/metabolism/active_metab = location
|
||||
var/removed = metabolism
|
||||
|
||||
var/ingest_rem_mult = 1
|
||||
var/ingest_abs_mult = 1
|
||||
|
||||
if(!mrate_static == TRUE)
|
||||
// Modifiers
|
||||
for(var/datum/modifier/mod in M.modifiers)
|
||||
if(!isnull(mod.metabolism_percent))
|
||||
removed *= mod.metabolism_percent
|
||||
ingest_rem_mult *= mod.metabolism_percent
|
||||
// Species
|
||||
removed *= M.species.metabolic_rate
|
||||
ingest_rem_mult *= M.species.metabolic_rate
|
||||
// Metabolism
|
||||
removed *= active_metab.metabolism_speed
|
||||
ingest_rem_mult *= active_metab.metabolism_speed
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.isSynthetic())
|
||||
if(H.species.has_organ[O_HEART] && (active_metab.metabolism_class == CHEM_BLOOD))
|
||||
var/obj/item/organ/internal/heart/Pump = H.internal_organs_by_name[O_HEART]
|
||||
if(!Pump)
|
||||
removed *= 0.1
|
||||
else if(Pump.standard_pulse_level == PULSE_NONE) // No pulse normally means chemicals process a little bit slower than normal.
|
||||
removed *= 0.8
|
||||
else // Otherwise, chemicals process as per percentage of your current pulse, or, if you have no pulse but are alive, by a miniscule amount.
|
||||
removed *= max(0.1, H.pulse / Pump.standard_pulse_level)
|
||||
|
||||
if(H.species.has_organ[O_STOMACH] && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
var/obj/item/organ/internal/stomach/Chamber = H.internal_organs_by_name[O_STOMACH]
|
||||
if(Chamber)
|
||||
ingest_rem_mult *= max(0.1, 1 - (Chamber.damage / Chamber.max_damage))
|
||||
else
|
||||
ingest_rem_mult = 0.1
|
||||
|
||||
if(H.species.has_organ[O_INTESTINE] && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
var/obj/item/organ/internal/intestine/Tube = H.internal_organs_by_name[O_INTESTINE]
|
||||
if(Tube)
|
||||
ingest_abs_mult *= max(0.1, 1 - (Tube.damage / Tube.max_damage))
|
||||
else
|
||||
ingest_abs_mult = 0.1
|
||||
|
||||
else
|
||||
var/obj/item/organ/internal/heart/machine/Pump = H.internal_organs_by_name[O_PUMP]
|
||||
var/obj/item/organ/internal/stomach/machine/Cycler = H.internal_organs_by_name[O_CYCLER]
|
||||
|
||||
if(active_metab.metabolism_class == CHEM_BLOOD)
|
||||
if(Pump)
|
||||
removed *= 1.1 - Pump.damage / Pump.max_damage
|
||||
else
|
||||
removed *= 0.1
|
||||
|
||||
else if(active_metab.metabolism_class == CHEM_INGEST) // If the pump is damaged, we waste chems from the tank.
|
||||
if(Pump)
|
||||
ingest_abs_mult *= max(0.25, 1 - Pump.damage / Pump.max_damage)
|
||||
|
||||
else
|
||||
ingest_abs_mult *= 0.2
|
||||
|
||||
if(Cycler) // If we're damaged, we empty our tank slower.
|
||||
ingest_rem_mult = max(0.1, 1 - (Cycler.damage / Cycler.max_damage))
|
||||
|
||||
else
|
||||
ingest_rem_mult = 0.1
|
||||
|
||||
else if(active_metab.metabolism_class == CHEM_TOUCH) // Machines don't exactly absorb chemicals.
|
||||
removed *= 0.5
|
||||
|
||||
if(filtered_organs && filtered_organs.len)
|
||||
for(var/organ_tag in filtered_organs)
|
||||
var/obj/item/organ/internal/O = H.internal_organs_by_name[organ_tag]
|
||||
if(O && !O.is_broken() && prob(max(0, O.max_damage - O.damage)))
|
||||
removed *= 0.8
|
||||
if(active_metab.metabolism_class == CHEM_INGEST)
|
||||
ingest_rem_mult *= 0.8
|
||||
|
||||
if(ingest_met && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
removed = ingest_met * ingest_rem_mult
|
||||
if(touch_met && (active_metab.metabolism_class == CHEM_TOUCH))
|
||||
removed = touch_met
|
||||
removed = min(removed, volume)
|
||||
max_dose = max(volume, max_dose)
|
||||
dose = min(dose + removed, max_dose)
|
||||
if(removed >= (metabolism * 0.1) || removed >= 0.1) // If there's too little chemical, don't affect the mob, just remove it
|
||||
switch(active_metab.metabolism_class)
|
||||
if(CHEM_BLOOD)
|
||||
affect_blood(M, alien, removed)
|
||||
if(CHEM_INGEST)
|
||||
affect_ingest(M, alien, removed * ingest_abs_mult)
|
||||
if(CHEM_TOUCH)
|
||||
affect_touch(M, alien, removed)
|
||||
if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH && !can_overdose_touch))
|
||||
overdose(M, alien, removed)
|
||||
if(M.species.allergens & allergen_type) //uhoh, we can't handle this!
|
||||
var/damage_severity = M.species.allergen_damage_severity*allergen_factor
|
||||
var/disable_severity = M.species.allergen_disable_severity*allergen_factor
|
||||
if(M.species.allergen_reaction & AG_TOX_DMG)
|
||||
M.adjustToxLoss(damage_severity)
|
||||
if(M.species.allergen_reaction & AG_OXY_DMG)
|
||||
M.adjustOxyLoss(damage_severity)
|
||||
if(prob(2.5*disable_severity))
|
||||
M.emote(pick("cough","gasp","choke"))
|
||||
if(M.species.allergen_reaction & AG_EMOTE)
|
||||
if(prob(2.5*disable_severity)) //this has a higher base chance, but not *too* high
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
if(M.species.allergen_reaction & AG_PAIN)
|
||||
M.adjustHalLoss(disable_severity)
|
||||
if(M.species.allergen_reaction & AG_WEAKEN)
|
||||
M.Weaken(disable_severity)
|
||||
if(M.species.allergen_reaction & AG_BLURRY)
|
||||
M.eye_blurry = max(M.eye_blurry, disable_severity)
|
||||
if(M.species.allergen_reaction & AG_SLEEPY)
|
||||
M.drowsyness = max(M.drowsyness, disable_severity)
|
||||
remove_self(removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
M.bloodstr.add_reagent(id, removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect.
|
||||
if(alien == IS_DIONA)
|
||||
return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
overdose_mod *= H.species.chemOD_mod
|
||||
// 6 damage per unit at minimum, scales with excessive reagents. Rounding should help keep damage consistent between ingest / inject, but isn't perfect.
|
||||
// Hardcapped at 3.6 damage per tick, or 18 damage per unit at 0.2 metabolic rate so that you can't instakill people with overdoses by feeding them infinite periadaxon.
|
||||
// Overall, max damage is slightly less effective than hydrophoron, and 1/5 as effective as cyanide.
|
||||
M.adjustToxLoss(min(removed * overdose_mod * round(3 + 3 * volume / overdose), 3.6))
|
||||
|
||||
/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created.
|
||||
if(!isnull(newdata))
|
||||
data = newdata
|
||||
return
|
||||
|
||||
/datum/reagent/proc/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that?
|
||||
return
|
||||
|
||||
/datum/reagent/proc/get_data() // Just in case you have a reagent that handles data differently.
|
||||
if(data && istype(data, /list))
|
||||
return data.Copy()
|
||||
else if(data)
|
||||
return data
|
||||
return null
|
||||
|
||||
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
|
||||
holder = null
|
||||
. = ..()
|
||||
|
||||
// Called when reagents are removed from a container, most likely after metabolizing in a mob
|
||||
/datum/reagent/proc/on_remove(var/atom/A)
|
||||
return
|
||||
|
||||
// Called when a mob dies
|
||||
/datum/reagent/proc/on_mob_death(var/mob/M)
|
||||
return
|
||||
|
||||
//on transfer to new container, return 1 to allow it to continue
|
||||
/datum/reagent/proc/on_transfer(var/volume)
|
||||
return 1
|
||||
|
||||
/* DEPRECATED - TODO: REMOVE EVERYWHERE */
|
||||
|
||||
/datum/reagent/proc/reaction_turf(var/turf/target)
|
||||
touch_turf(target)
|
||||
|
||||
/datum/reagent/proc/reaction_obj(var/obj/target)
|
||||
touch_obj(target)
|
||||
|
||||
/datum/reagent/proc/reaction_mob(var/mob/target)
|
||||
touch_mob(target)
|
||||
|
||||
26
code/modules/reagents/holder/distilling.dm
Normal file
26
code/modules/reagents/holder/distilling.dm
Normal file
@@ -0,0 +1,26 @@
|
||||
/datum/reagents/distilling/handle_reactions()
|
||||
if(QDELETED(my_atom))
|
||||
return FALSE
|
||||
if(my_atom.flags & NOREACT)
|
||||
return FALSE
|
||||
var/reaction_occurred
|
||||
var/list/eligible_reactions = list()
|
||||
var/list/effect_reactions = list()
|
||||
do
|
||||
reaction_occurred = FALSE
|
||||
for(var/i in reagent_list)
|
||||
var/datum/reagent/R = i
|
||||
if(SSchemistry.distilled_reactions_by_reagent[R.id])
|
||||
eligible_reactions |= SSchemistry.distilled_reactions_by_reagent[R.id]
|
||||
|
||||
for(var/i in eligible_reactions)
|
||||
var/decl/chemical_reaction/C = i
|
||||
if(C.can_happen(src) && C.process(src))
|
||||
effect_reactions |= C
|
||||
reaction_occurred = TRUE
|
||||
eligible_reactions.len = 0
|
||||
while(reaction_occurred)
|
||||
for(var/i in effect_reactions)
|
||||
var/decl/chemical_reaction/C = i
|
||||
C.post_reaction(src)
|
||||
update_total()
|
||||
1560
code/modules/reagents/holder/holder.dm
Normal file
1560
code/modules/reagents/holder/holder.dm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,21 +1,3 @@
|
||||
#define SOLID 1
|
||||
#define LIQUID 2
|
||||
#define GAS 3
|
||||
|
||||
#define MAX_PILL_SPRITE 24 //max icon state of the pill sprites
|
||||
#define MAX_BOTTLE_SPRITE 4 //max icon state of the pill sprites
|
||||
#define MAX_MULTI_AMOUNT 20 // Max number of pills/patches that can be made at once
|
||||
#define MAX_UNITS_PER_PILL 60 // Max amount of units in a pill
|
||||
#define MAX_UNITS_PER_PATCH 60 // Max amount of units in a patch
|
||||
#define MAX_UNITS_PER_BOTTLE 60 // Max amount of units in a bottle (it's volume)
|
||||
#define MAX_CUSTOM_NAME_LEN 64 // Max length of a custom pill/condiment/whatever
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/obj/machinery/chem_master
|
||||
name = "ChemMaster 3000"
|
||||
desc = "Used to seperate and package chemicals in to patches, pills, or bottles. Warranty void if used to create Space Drugs."
|
||||
@@ -514,349 +496,3 @@
|
||||
/obj/machinery/chem_master/condimaster
|
||||
name = "CondiMaster 3000"
|
||||
condi = 1
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/obj/machinery/reagentgrinder
|
||||
|
||||
name = "All-In-One Grinder"
|
||||
desc = "Grinds stuff into itty bitty bits."
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "juicer1"
|
||||
density = 0
|
||||
anchored = 0
|
||||
use_power = USE_POWER_IDLE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 100
|
||||
circuit = /obj/item/weapon/circuitboard/grinder
|
||||
var/inuse = 0
|
||||
var/obj/item/weapon/reagent_containers/beaker = null
|
||||
var/limit = 10
|
||||
var/list/holdingitems = list()
|
||||
var/list/sheet_reagents = list( //have a number of reageents divisible by REAGENTS_PER_SHEET (default 20) unless you like decimals,
|
||||
/obj/item/stack/material/iron = list("iron"),
|
||||
/obj/item/stack/material/uranium = list("uranium"),
|
||||
/obj/item/stack/material/phoron = list("phoron"),
|
||||
/obj/item/stack/material/gold = list("gold"),
|
||||
/obj/item/stack/material/silver = list("silver"),
|
||||
/obj/item/stack/material/platinum = list("platinum"),
|
||||
/obj/item/stack/material/mhydrogen = list("hydrogen"),
|
||||
/obj/item/stack/material/steel = list("iron", "carbon"),
|
||||
/obj/item/stack/material/plasteel = list("iron", "iron", "carbon", "carbon", "platinum"), //8 iron, 8 carbon, 4 platinum,
|
||||
/obj/item/stack/material/snow = list("water"),
|
||||
/obj/item/stack/material/sandstone = list("silicon", "oxygen"),
|
||||
/obj/item/stack/material/glass = list("silicon"),
|
||||
/obj/item/stack/material/glass/phoronglass = list("platinum", "silicon", "silicon", "silicon"), //5 platinum, 15 silicon,
|
||||
)
|
||||
|
||||
var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
|
||||
var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject")
|
||||
var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind")
|
||||
// var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice")
|
||||
// var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix")
|
||||
|
||||
/obj/machinery/reagentgrinder/Initialize()
|
||||
. = ..()
|
||||
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/reagentgrinder/examine(mob/user)
|
||||
. = ..()
|
||||
if(!in_range(user, src) && !issilicon(user) && !isobserver(user))
|
||||
. += "<span class='warning'>You're too far away to examine [src]'s contents and display!</span>"
|
||||
return
|
||||
|
||||
if(inuse)
|
||||
. += "<span class='warning'>\The [src] is operating.</span>"
|
||||
return
|
||||
|
||||
if(beaker || length(holdingitems))
|
||||
. += "<span class='notice'>\The [src] contains:</span>"
|
||||
if(beaker)
|
||||
. += "<span class='notice'>- \A [beaker].</span>"
|
||||
for(var/i in holdingitems)
|
||||
var/obj/item/O = i
|
||||
. += "<span class='notice'>- \A [O.name].</span>"
|
||||
|
||||
if(!(stat & (NOPOWER|BROKEN)))
|
||||
. += "<span class='notice'>The status display reads:</span>\n"
|
||||
if(beaker)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
. += "<span class='notice'>- [R.volume] units of [R.name].</span>"
|
||||
|
||||
/obj/machinery/reagentgrinder/update_icon()
|
||||
icon_state = "juicer"+num2text(!isnull(beaker))
|
||||
return
|
||||
|
||||
/obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(beaker)
|
||||
if(default_deconstruction_screwdriver(user, O))
|
||||
return
|
||||
if(default_deconstruction_crowbar(user, O))
|
||||
return
|
||||
|
||||
//vorestation edit start - for solargrubs
|
||||
if (istype(O, /obj/item/device/multitool))
|
||||
return ..()
|
||||
//vorestation edit end
|
||||
|
||||
|
||||
if (istype(O,/obj/item/weapon/reagent_containers/glass) || \
|
||||
istype(O,/obj/item/weapon/reagent_containers/food/drinks/glass2) || \
|
||||
istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker))
|
||||
|
||||
if (beaker)
|
||||
return 1
|
||||
else
|
||||
src.beaker = O
|
||||
user.drop_item()
|
||||
O.loc = src
|
||||
update_icon()
|
||||
src.updateUsrDialog()
|
||||
return 0
|
||||
|
||||
if(holdingitems && holdingitems.len >= limit)
|
||||
to_chat(user, "The machine cannot hold anymore items.")
|
||||
return 1
|
||||
|
||||
if(!istype(O))
|
||||
return
|
||||
|
||||
if(istype(O,/obj/item/weapon/storage/bag/plants))
|
||||
var/obj/item/weapon/storage/bag/plants/bag = O
|
||||
var/failed = 1
|
||||
for(var/obj/item/G in O.contents)
|
||||
if(!G.reagents || !G.reagents.total_volume)
|
||||
continue
|
||||
failed = 0
|
||||
bag.remove_from_storage(G, src)
|
||||
holdingitems += G
|
||||
if(holdingitems && holdingitems.len >= limit)
|
||||
break
|
||||
|
||||
if(failed)
|
||||
to_chat(user, "Nothing in the plant bag is usable.")
|
||||
return 1
|
||||
|
||||
if(!O.contents.len)
|
||||
to_chat(user, "You empty \the [O] into \the [src].")
|
||||
else
|
||||
to_chat(user, "You fill \the [src] from \the [O].")
|
||||
|
||||
src.updateUsrDialog()
|
||||
return 0
|
||||
|
||||
if(istype(O,/obj/item/weapon/gripper))
|
||||
var/obj/item/weapon/gripper/B = O //B, for Borg.
|
||||
if(!B.wrapped)
|
||||
to_chat(user, "\The [B] is not holding anything.")
|
||||
return 0
|
||||
else
|
||||
var/B_held = B.wrapped
|
||||
to_chat(user, "You use \the [B] to load \the [src] with \the [B_held].")
|
||||
|
||||
return 0
|
||||
|
||||
if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume))
|
||||
to_chat(user, "\The [O] is not suitable for blending.")
|
||||
return 1
|
||||
|
||||
user.remove_from_mob(O)
|
||||
O.loc = src
|
||||
holdingitems += O
|
||||
return 0
|
||||
|
||||
/obj/machinery/reagentgrinder/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(user.incapacitated() || !Adjacent(user))
|
||||
return
|
||||
replace_beaker(user)
|
||||
|
||||
/obj/machinery/reagentgrinder/attack_hand(mob/user as mob)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/reagentgrinder/interact(mob/user as mob) // The microwave Menu //I am reasonably certain that this is not a microwave
|
||||
if(inuse || user.incapacitated())
|
||||
return
|
||||
|
||||
var/list/options = list()
|
||||
|
||||
if(beaker || length(holdingitems))
|
||||
options["eject"] = radial_eject
|
||||
|
||||
if(isAI(user))
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
options["examine"] = radial_examine
|
||||
|
||||
// if there is no power or it's broken, the procs will fail but the buttons will still show
|
||||
if(length(holdingitems))
|
||||
options["grind"] = radial_grind
|
||||
|
||||
var/choice
|
||||
if(length(options) < 1)
|
||||
return
|
||||
if(length(options) == 1)
|
||||
for(var/key in options)
|
||||
choice = key
|
||||
else
|
||||
choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
|
||||
|
||||
// post choice verification
|
||||
if(inuse || (isAI(user) && stat & NOPOWER) || user.incapacitated())
|
||||
return
|
||||
|
||||
switch(choice)
|
||||
if("eject")
|
||||
eject(user)
|
||||
if("grind")
|
||||
grind(user)
|
||||
if("examine")
|
||||
examine(user)
|
||||
|
||||
/obj/machinery/reagentgrinder/proc/eject(mob/user)
|
||||
if(user.incapacitated())
|
||||
return
|
||||
for(var/obj/item/O in holdingitems)
|
||||
O.loc = src.loc
|
||||
holdingitems -= O
|
||||
holdingitems.Cut()
|
||||
if(beaker)
|
||||
replace_beaker(user)
|
||||
|
||||
/obj/machinery/reagentgrinder/proc/grind()
|
||||
|
||||
power_change()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
// Sanity check.
|
||||
if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
|
||||
return
|
||||
|
||||
playsound(src, 'sound/machines/blender.ogg', 50, 1)
|
||||
inuse = 1
|
||||
|
||||
// Reset the machine.
|
||||
spawn(60)
|
||||
inuse = 0
|
||||
|
||||
// Process.
|
||||
for (var/obj/item/O in holdingitems)
|
||||
|
||||
var/remaining_volume = beaker.reagents.maximum_volume - beaker.reagents.total_volume
|
||||
if(remaining_volume <= 0)
|
||||
break
|
||||
|
||||
if(sheet_reagents[O.type])
|
||||
var/obj/item/stack/stack = O
|
||||
if(istype(stack))
|
||||
var/list/sheet_components = sheet_reagents[stack.type]
|
||||
var/amount_to_take = max(0,min(stack.amount,round(remaining_volume/REAGENTS_PER_SHEET)))
|
||||
if(amount_to_take)
|
||||
stack.use(amount_to_take)
|
||||
if(QDELETED(stack))
|
||||
holdingitems -= stack
|
||||
if(islist(sheet_components))
|
||||
amount_to_take = (amount_to_take/(sheet_components.len))
|
||||
for(var/i in sheet_components)
|
||||
beaker.reagents.add_reagent(i, (amount_to_take*REAGENTS_PER_SHEET))
|
||||
else
|
||||
beaker.reagents.add_reagent(sheet_components, (amount_to_take*REAGENTS_PER_SHEET))
|
||||
continue
|
||||
|
||||
if(O.reagents)
|
||||
O.reagents.trans_to_obj(beaker, min(O.reagents.total_volume, remaining_volume))
|
||||
if(O.reagents.total_volume == 0)
|
||||
holdingitems -= O
|
||||
qdel(O)
|
||||
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
|
||||
break
|
||||
|
||||
/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/weapon/reagent_containers/new_beaker)
|
||||
if(!user)
|
||||
return FALSE
|
||||
if(beaker)
|
||||
if(!user.incapacitated() && Adjacent(user))
|
||||
user.put_in_hands(beaker)
|
||||
else
|
||||
beaker.forceMove(drop_location())
|
||||
beaker = null
|
||||
if(new_beaker)
|
||||
beaker = new_beaker
|
||||
update_icon()
|
||||
return TRUE
|
||||
|
||||
///////////////
|
||||
///////////////
|
||||
// Detects reagents inside most containers, and acts as an infinite identification system for reagent-based unidentified objects.
|
||||
|
||||
/obj/machinery/chemical_analyzer
|
||||
name = "chem analyzer"
|
||||
desc = "Used to precisely scan chemicals and other liquids inside various containers. \
|
||||
It may also identify the liquid contents of unknown objects."
|
||||
description_info = "This machine will try to tell you what reagents are inside of something capable of holding reagents. \
|
||||
It is also used to 'identify' specific reagent-based objects with their properties obscured from inspection by normal means."
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "chem_analyzer"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
use_power = TRUE
|
||||
idle_power_usage = 20
|
||||
clicksound = "button"
|
||||
var/analyzing = FALSE
|
||||
|
||||
/obj/machinery/chemical_analyzer/update_icon()
|
||||
icon_state = "chem_analyzer[analyzing ? "-working":""]"
|
||||
|
||||
/obj/machinery/chemical_analyzer/attackby(obj/item/I, mob/living/user)
|
||||
if(!istype(I))
|
||||
return ..()
|
||||
|
||||
if(default_deconstruction_screwdriver(user, I))
|
||||
return
|
||||
if(default_deconstruction_crowbar(user, I))
|
||||
return
|
||||
|
||||
if(istype(I,/obj/item/weapon/reagent_containers))
|
||||
analyzing = TRUE
|
||||
update_icon()
|
||||
to_chat(user, span("notice", "Analyzing \the [I], please stand by..."))
|
||||
|
||||
if(!do_after(user, 2 SECONDS, src))
|
||||
to_chat(user, span("warning", "Sample moved outside of scan range, please try again and remain still."))
|
||||
analyzing = FALSE
|
||||
update_icon()
|
||||
return
|
||||
|
||||
// First, identify it if it isn't already.
|
||||
if(!I.is_identified(IDENTITY_FULL))
|
||||
var/datum/identification/ID = I.identity
|
||||
if(ID.identification_type == IDENTITY_TYPE_CHEMICAL) // This only solves chemical-based mysteries.
|
||||
I.identify(IDENTITY_FULL, user)
|
||||
|
||||
// Now tell us everything that is inside.
|
||||
if(I.reagents && I.reagents.reagent_list.len)
|
||||
to_chat(user, "<br>") // To add padding between regular chat and the output.
|
||||
for(var/datum/reagent/R in I.reagents.reagent_list)
|
||||
if(!R.name)
|
||||
continue
|
||||
to_chat(user, span("notice", "Contains [R.volume]u of <b>[R.name]</b>.<br>[R.description]<br>"))
|
||||
|
||||
// Last, unseal it if it's an autoinjector.
|
||||
if(istype(I,/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector) && !(I.flags & OPENCONTAINER))
|
||||
I.flags |= OPENCONTAINER
|
||||
to_chat(user, span("notice", "Sample container unsealed.<br>"))
|
||||
|
||||
to_chat(user, span("notice", "Scanning of \the [I] complete."))
|
||||
analyzing = FALSE
|
||||
update_icon()
|
||||
return
|
||||
|
||||
#undef MAX_PILL_SPRITE
|
||||
#undef MAX_BOTTLE_SPRITE
|
||||
#undef MAX_MULTI_AMOUNT
|
||||
#undef MAX_UNITS_PER_PILL
|
||||
#undef MAX_UNITS_PER_PATCH
|
||||
#undef MAX_UNITS_PER_BOTTLE
|
||||
#undef MAX_CUSTOM_NAME_LEN
|
||||
63
code/modules/reagents/machinery/chemalyzer.dm
Normal file
63
code/modules/reagents/machinery/chemalyzer.dm
Normal file
@@ -0,0 +1,63 @@
|
||||
// Detects reagents inside most containers, and acts as an infinite identification system for reagent-based unidentified objects.
|
||||
|
||||
/obj/machinery/chemical_analyzer
|
||||
name = "chem analyzer"
|
||||
desc = "Used to precisely scan chemicals and other liquids inside various containers. \
|
||||
It may also identify the liquid contents of unknown objects."
|
||||
description_info = "This machine will try to tell you what reagents are inside of something capable of holding reagents. \
|
||||
It is also used to 'identify' specific reagent-based objects with their properties obscured from inspection by normal means."
|
||||
icon = 'icons/obj/chemical.dmi'
|
||||
icon_state = "chem_analyzer"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
use_power = TRUE
|
||||
idle_power_usage = 20
|
||||
clicksound = "button"
|
||||
var/analyzing = FALSE
|
||||
|
||||
/obj/machinery/chemical_analyzer/update_icon()
|
||||
icon_state = "chem_analyzer[analyzing ? "-working":""]"
|
||||
|
||||
/obj/machinery/chemical_analyzer/attackby(obj/item/I, mob/living/user)
|
||||
if(!istype(I))
|
||||
return ..()
|
||||
|
||||
if(default_deconstruction_screwdriver(user, I))
|
||||
return
|
||||
if(default_deconstruction_crowbar(user, I))
|
||||
return
|
||||
|
||||
if(istype(I,/obj/item/weapon/reagent_containers))
|
||||
analyzing = TRUE
|
||||
update_icon()
|
||||
to_chat(user, span("notice", "Analyzing \the [I], please stand by..."))
|
||||
|
||||
if(!do_after(user, 2 SECONDS, src))
|
||||
to_chat(user, span("warning", "Sample moved outside of scan range, please try again and remain still."))
|
||||
analyzing = FALSE
|
||||
update_icon()
|
||||
return
|
||||
|
||||
// First, identify it if it isn't already.
|
||||
if(!I.is_identified(IDENTITY_FULL))
|
||||
var/datum/identification/ID = I.identity
|
||||
if(ID.identification_type == IDENTITY_TYPE_CHEMICAL) // This only solves chemical-based mysteries.
|
||||
I.identify(IDENTITY_FULL, user)
|
||||
|
||||
// Now tell us everything that is inside.
|
||||
if(I.reagents && I.reagents.reagent_list.len)
|
||||
to_chat(user, "<br>") // To add padding between regular chat and the output.
|
||||
for(var/datum/reagent/R in I.reagents.reagent_list)
|
||||
if(!R.name)
|
||||
continue
|
||||
to_chat(user, span("notice", "Contains [R.volume]u of <b>[R.name]</b>.<br>[R.description]<br>"))
|
||||
|
||||
// Last, unseal it if it's an autoinjector.
|
||||
if(istype(I,/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector) && !(I.flags & OPENCONTAINER))
|
||||
I.flags |= OPENCONTAINER
|
||||
to_chat(user, span("notice", "Sample container unsealed.<br>"))
|
||||
|
||||
to_chat(user, span("notice", "Scanning of \the [I] complete."))
|
||||
analyzing = FALSE
|
||||
update_icon()
|
||||
return
|
||||
1429
code/modules/reagents/machinery/dispenser/reagent_tank.dm
Normal file
1429
code/modules/reagents/machinery/dispenser/reagent_tank.dm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -53,31 +53,16 @@
|
||||
var/image/overlay_dumping
|
||||
var/image/overlay_connected
|
||||
|
||||
// Our unique beaker, used in its unique recipes to ensure things can only react inside this machine and minimize oddities from trying to transfer to a machine and back.
|
||||
var/obj/item/weapon/reagent_containers/glass/distilling/Reservoir
|
||||
|
||||
var/obj/item/weapon/reagent_containers/glass/InputBeaker
|
||||
var/obj/item/weapon/reagent_containers/glass/OutputBeaker
|
||||
|
||||
// A multiplier for the production amount. This should really only ever be lower than one, otherwise you end up with duping.
|
||||
var/efficiency = 1
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/distilling
|
||||
name = "distilling chamber"
|
||||
desc = "You should not be seeing this."
|
||||
volume = 600
|
||||
|
||||
var/obj/machinery/portable_atmospherics/powered/reagent_distillery/Master
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/distilling/Destroy()
|
||||
Master = null
|
||||
..()
|
||||
|
||||
/obj/machinery/portable_atmospherics/powered/reagent_distillery/Initialize()
|
||||
. = ..()
|
||||
|
||||
Reservoir = new (src)
|
||||
Reservoir.Master = src
|
||||
create_reagents(600, /datum/reagents/distilling)
|
||||
|
||||
if(!base_state)
|
||||
base_state = icon_state
|
||||
@@ -107,8 +92,6 @@
|
||||
overlay_connected = image(icon = src.icon, icon_state = "[base_state]-connector")
|
||||
|
||||
/obj/machinery/portable_atmospherics/powered/reagent_distillery/Destroy()
|
||||
qdel(Reservoir)
|
||||
Reservoir = null
|
||||
if(InputBeaker)
|
||||
qdel(InputBeaker)
|
||||
InputBeaker = null
|
||||
@@ -134,8 +117,8 @@
|
||||
else
|
||||
. += "<span class='notice'>\The [src]'s input beaker is empty!</span>"
|
||||
|
||||
if(Reservoir.reagents.reagent_list.len)
|
||||
. += "<span class='notice'>\The [src]'s internal buffer holds [Reservoir.reagents.total_volume] units of liquid.</span>"
|
||||
if(reagents.reagent_list.len)
|
||||
. += "<span class='notice'>\The [src]'s internal buffer holds [reagents.total_volume] units of liquid.</span>"
|
||||
else
|
||||
. += "<span class='notice'>\The [src]'s internal buffer is empty!</span>"
|
||||
|
||||
@@ -164,7 +147,7 @@
|
||||
to_chat(user, "<span class='notice'>You press \the [src]'s chamber agitator button.</span>")
|
||||
if(on)
|
||||
visible_message("<span class='notice'>\The [src] rattles to life.</span>")
|
||||
Reservoir.reagents.handle_reactions()
|
||||
reagents.handle_reactions()
|
||||
else
|
||||
spawn(1 SECOND)
|
||||
to_chat(user, "<span class='notice'>Nothing happens..</span>")
|
||||
@@ -341,12 +324,12 @@
|
||||
visible_message("<span class='notice'>\The [src]'s motors wind down.</span>")
|
||||
on = FALSE
|
||||
|
||||
if(InputBeaker && Reservoir.reagents.total_volume < Reservoir.reagents.maximum_volume)
|
||||
InputBeaker.reagents.trans_to_holder(Reservoir.reagents, amount = rand(10,20))
|
||||
if(InputBeaker && reagents.total_volume < reagents.maximum_volume)
|
||||
InputBeaker.reagents.trans_to_holder(reagents, amount = rand(10,20))
|
||||
|
||||
if(OutputBeaker && OutputBeaker.reagents.total_volume < OutputBeaker.reagents.maximum_volume)
|
||||
use_power(power_rating * CELLRATE * 0.5)
|
||||
Reservoir.reagents.trans_to_holder(OutputBeaker.reagents, amount = rand(1, 5))
|
||||
reagents.trans_to_holder(OutputBeaker.reagents, amount = rand(1, 5))
|
||||
|
||||
update_icon()
|
||||
|
||||
268
code/modules/reagents/machinery/grinder.dm
Normal file
268
code/modules/reagents/machinery/grinder.dm
Normal file
@@ -0,0 +1,268 @@
|
||||
/obj/machinery/reagentgrinder
|
||||
|
||||
name = "All-In-One Grinder"
|
||||
desc = "Grinds stuff into itty bitty bits."
|
||||
icon = 'icons/obj/kitchen.dmi'
|
||||
icon_state = "juicer1"
|
||||
density = 0
|
||||
anchored = 0
|
||||
use_power = USE_POWER_IDLE
|
||||
idle_power_usage = 5
|
||||
active_power_usage = 100
|
||||
circuit = /obj/item/weapon/circuitboard/grinder
|
||||
var/inuse = 0
|
||||
var/obj/item/weapon/reagent_containers/beaker = null
|
||||
var/limit = 10
|
||||
var/list/holdingitems = list()
|
||||
var/list/sheet_reagents = list( //have a number of reageents divisible by REAGENTS_PER_SHEET (default 20) unless you like decimals,
|
||||
/obj/item/stack/material/iron = list("iron"),
|
||||
/obj/item/stack/material/uranium = list("uranium"),
|
||||
/obj/item/stack/material/phoron = list("phoron"),
|
||||
/obj/item/stack/material/gold = list("gold"),
|
||||
/obj/item/stack/material/silver = list("silver"),
|
||||
/obj/item/stack/material/platinum = list("platinum"),
|
||||
/obj/item/stack/material/mhydrogen = list("hydrogen"),
|
||||
/obj/item/stack/material/steel = list("iron", "carbon"),
|
||||
/obj/item/stack/material/plasteel = list("iron", "iron", "carbon", "carbon", "platinum"), //8 iron, 8 carbon, 4 platinum,
|
||||
/obj/item/stack/material/snow = list("water"),
|
||||
/obj/item/stack/material/sandstone = list("silicon", "oxygen"),
|
||||
/obj/item/stack/material/glass = list("silicon"),
|
||||
/obj/item/stack/material/glass/phoronglass = list("platinum", "silicon", "silicon", "silicon"), //5 platinum, 15 silicon,
|
||||
)
|
||||
|
||||
var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
|
||||
var/static/radial_eject = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_eject")
|
||||
var/static/radial_grind = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_grind")
|
||||
// var/static/radial_juice = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_juice")
|
||||
// var/static/radial_mix = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_mix")
|
||||
|
||||
/obj/machinery/reagentgrinder/Initialize()
|
||||
. = ..()
|
||||
beaker = new /obj/item/weapon/reagent_containers/glass/beaker/large(src)
|
||||
default_apply_parts()
|
||||
|
||||
/obj/machinery/reagentgrinder/examine(mob/user)
|
||||
. = ..()
|
||||
if(!in_range(user, src) && !issilicon(user) && !isobserver(user))
|
||||
. += "<span class='warning'>You're too far away to examine [src]'s contents and display!</span>"
|
||||
return
|
||||
|
||||
if(inuse)
|
||||
. += "<span class='warning'>\The [src] is operating.</span>"
|
||||
return
|
||||
|
||||
if(beaker || length(holdingitems))
|
||||
. += "<span class='notice'>\The [src] contains:</span>"
|
||||
if(beaker)
|
||||
. += "<span class='notice'>- \A [beaker].</span>"
|
||||
for(var/i in holdingitems)
|
||||
var/obj/item/O = i
|
||||
. += "<span class='notice'>- \A [O.name].</span>"
|
||||
|
||||
if(!(stat & (NOPOWER|BROKEN)))
|
||||
. += "<span class='notice'>The status display reads:</span>\n"
|
||||
if(beaker)
|
||||
for(var/datum/reagent/R in beaker.reagents.reagent_list)
|
||||
. += "<span class='notice'>- [R.volume] units of [R.name].</span>"
|
||||
|
||||
/obj/machinery/reagentgrinder/update_icon()
|
||||
icon_state = "juicer"+num2text(!isnull(beaker))
|
||||
return
|
||||
|
||||
/obj/machinery/reagentgrinder/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
if(beaker)
|
||||
if(default_deconstruction_screwdriver(user, O))
|
||||
return
|
||||
if(default_deconstruction_crowbar(user, O))
|
||||
return
|
||||
|
||||
//VOREStation edit start - for solargrubs
|
||||
if (istype(O, /obj/item/device/multitool))
|
||||
return ..()
|
||||
//VOREStation edit end
|
||||
|
||||
if (istype(O,/obj/item/weapon/reagent_containers/glass) || \
|
||||
istype(O,/obj/item/weapon/reagent_containers/food/drinks/glass2) || \
|
||||
istype(O,/obj/item/weapon/reagent_containers/food/drinks/shaker))
|
||||
|
||||
if (beaker)
|
||||
return 1
|
||||
else
|
||||
src.beaker = O
|
||||
user.drop_item()
|
||||
O.loc = src
|
||||
update_icon()
|
||||
src.updateUsrDialog()
|
||||
return 0
|
||||
|
||||
if(holdingitems && holdingitems.len >= limit)
|
||||
to_chat(user, "The machine cannot hold anymore items.")
|
||||
return 1
|
||||
|
||||
if(!istype(O))
|
||||
return
|
||||
|
||||
if(istype(O,/obj/item/weapon/storage/bag/plants))
|
||||
var/obj/item/weapon/storage/bag/plants/bag = O
|
||||
var/failed = 1
|
||||
for(var/obj/item/G in O.contents)
|
||||
if(!G.reagents || !G.reagents.total_volume)
|
||||
continue
|
||||
failed = 0
|
||||
bag.remove_from_storage(G, src)
|
||||
holdingitems += G
|
||||
if(holdingitems && holdingitems.len >= limit)
|
||||
break
|
||||
|
||||
if(failed)
|
||||
to_chat(user, "Nothing in the plant bag is usable.")
|
||||
return 1
|
||||
|
||||
if(!O.contents.len)
|
||||
to_chat(user, "You empty \the [O] into \the [src].")
|
||||
else
|
||||
to_chat(user, "You fill \the [src] from \the [O].")
|
||||
|
||||
src.updateUsrDialog()
|
||||
return 0
|
||||
|
||||
if(istype(O,/obj/item/weapon/gripper))
|
||||
var/obj/item/weapon/gripper/B = O //B, for Borg.
|
||||
if(!B.wrapped)
|
||||
to_chat(user, "\The [B] is not holding anything.")
|
||||
return 0
|
||||
else
|
||||
var/B_held = B.wrapped
|
||||
to_chat(user, "You use \the [B] to load \the [src] with \the [B_held].")
|
||||
|
||||
return 0
|
||||
|
||||
if(!sheet_reagents[O.type] && (!O.reagents || !O.reagents.total_volume))
|
||||
to_chat(user, "\The [O] is not suitable for blending.")
|
||||
return 1
|
||||
|
||||
user.remove_from_mob(O)
|
||||
O.loc = src
|
||||
holdingitems += O
|
||||
return 0
|
||||
|
||||
/obj/machinery/reagentgrinder/AltClick(mob/user)
|
||||
. = ..()
|
||||
if(user.incapacitated() || !Adjacent(user))
|
||||
return
|
||||
replace_beaker(user)
|
||||
|
||||
/obj/machinery/reagentgrinder/attack_hand(mob/user as mob)
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/reagentgrinder/interact(mob/user as mob) // The microwave Menu //I am reasonably certain that this is not a microwave
|
||||
if(inuse || user.incapacitated())
|
||||
return
|
||||
|
||||
var/list/options = list()
|
||||
|
||||
if(beaker || length(holdingitems))
|
||||
options["eject"] = radial_eject
|
||||
|
||||
if(isAI(user))
|
||||
if(stat & NOPOWER)
|
||||
return
|
||||
options["examine"] = radial_examine
|
||||
|
||||
// if there is no power or it's broken, the procs will fail but the buttons will still show
|
||||
if(length(holdingitems))
|
||||
options["grind"] = radial_grind
|
||||
|
||||
var/choice
|
||||
if(length(options) < 1)
|
||||
return
|
||||
if(length(options) == 1)
|
||||
for(var/key in options)
|
||||
choice = key
|
||||
else
|
||||
choice = show_radial_menu(user, src, options, require_near = !issilicon(user))
|
||||
|
||||
// post choice verification
|
||||
if(inuse || (isAI(user) && stat & NOPOWER) || user.incapacitated())
|
||||
return
|
||||
|
||||
switch(choice)
|
||||
if("eject")
|
||||
eject(user)
|
||||
if("grind")
|
||||
grind(user)
|
||||
if("examine")
|
||||
examine(user)
|
||||
|
||||
/obj/machinery/reagentgrinder/proc/eject(mob/user)
|
||||
if(user.incapacitated())
|
||||
return
|
||||
for(var/obj/item/O in holdingitems)
|
||||
O.loc = src.loc
|
||||
holdingitems -= O
|
||||
holdingitems.Cut()
|
||||
if(beaker)
|
||||
replace_beaker(user)
|
||||
|
||||
/obj/machinery/reagentgrinder/proc/grind()
|
||||
|
||||
power_change()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
// Sanity check.
|
||||
if (!beaker || (beaker && beaker.reagents.total_volume >= beaker.reagents.maximum_volume))
|
||||
return
|
||||
|
||||
playsound(src, 'sound/machines/blender.ogg', 50, 1)
|
||||
inuse = 1
|
||||
|
||||
// Reset the machine.
|
||||
spawn(60)
|
||||
inuse = 0
|
||||
|
||||
// Process.
|
||||
for (var/obj/item/O in holdingitems)
|
||||
|
||||
var/remaining_volume = beaker.reagents.maximum_volume - beaker.reagents.total_volume
|
||||
if(remaining_volume <= 0)
|
||||
break
|
||||
|
||||
if(sheet_reagents[O.type])
|
||||
var/obj/item/stack/stack = O
|
||||
if(istype(stack))
|
||||
var/list/sheet_components = sheet_reagents[stack.type]
|
||||
var/amount_to_take = max(0,min(stack.amount,round(remaining_volume/REAGENTS_PER_SHEET)))
|
||||
if(amount_to_take)
|
||||
stack.use(amount_to_take)
|
||||
if(QDELETED(stack))
|
||||
holdingitems -= stack
|
||||
if(islist(sheet_components))
|
||||
amount_to_take = (amount_to_take/(sheet_components.len))
|
||||
for(var/i in sheet_components)
|
||||
beaker.reagents.add_reagent(i, (amount_to_take*REAGENTS_PER_SHEET))
|
||||
else
|
||||
beaker.reagents.add_reagent(sheet_components, (amount_to_take*REAGENTS_PER_SHEET))
|
||||
continue
|
||||
|
||||
if(O.reagents)
|
||||
O.reagents.trans_to_obj(beaker, min(O.reagents.total_volume, remaining_volume))
|
||||
if(O.reagents.total_volume == 0)
|
||||
holdingitems -= O
|
||||
qdel(O)
|
||||
if (beaker.reagents.total_volume >= beaker.reagents.maximum_volume)
|
||||
break
|
||||
|
||||
/obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/weapon/reagent_containers/new_beaker)
|
||||
if(!user)
|
||||
return FALSE
|
||||
if(beaker)
|
||||
if(!user.incapacitated() && Adjacent(user))
|
||||
user.put_in_hands(beaker)
|
||||
else
|
||||
beaker.forceMove(drop_location())
|
||||
beaker = null
|
||||
if(new_beaker)
|
||||
beaker = new_beaker
|
||||
update_icon()
|
||||
return TRUE
|
||||
128
code/modules/reagents/reactions/_reactions.dm
Normal file
128
code/modules/reagents/reactions/_reactions.dm
Normal file
@@ -0,0 +1,128 @@
|
||||
//helper that ensures the reaction rate holds after iterating
|
||||
//Ex. REACTION_RATE(0.3) means that 30% of the reagents will react each chemistry tick (~2 seconds by default).
|
||||
#define REACTION_RATE(rate) (1.0 - (1.0-rate)**(1.0/PROCESS_REACTION_ITER))
|
||||
|
||||
//helper to define reaction rate in terms of half-life
|
||||
//Ex.
|
||||
//HALF_LIFE(0) -> Reaction completes immediately (default chems)
|
||||
//HALF_LIFE(1) -> Half of the reagents react immediately, the rest over the following ticks.
|
||||
//HALF_LIFE(2) -> Half of the reagents are consumed after 2 chemistry ticks.
|
||||
//HALF_LIFE(3) -> Half of the reagents are consumed after 3 chemistry ticks.
|
||||
#define HALF_LIFE(ticks) (ticks? 1.0 - (0.5)**(1.0/(ticks*PROCESS_REACTION_ITER)) : 1.0)
|
||||
|
||||
/decl/chemical_reaction
|
||||
var/name = null
|
||||
var/id = null
|
||||
var/result = null
|
||||
var/list/required_reagents = list()
|
||||
var/list/catalysts = list()
|
||||
var/list/inhibitors = list()
|
||||
var/result_amount = 0
|
||||
|
||||
//how far the reaction proceeds each time it is processed. Used with either REACTION_RATE or HALF_LIFE macros.
|
||||
var/reaction_rate = HALF_LIFE(0)
|
||||
|
||||
//if less than 1, the reaction will be inhibited if the ratio of products/reagents is too high.
|
||||
//0.5 = 50% yield -> reaction will only proceed halfway until products are removed.
|
||||
var/yield = 1.0
|
||||
|
||||
//If limits on reaction rate would leave less than this amount of any reagent (adjusted by the reaction ratios),
|
||||
//the reaction goes to completion. This is to prevent reactions from going on forever with tiny reagent amounts.
|
||||
var/min_reaction = 2
|
||||
|
||||
var/mix_message = "The solution begins to bubble."
|
||||
var/reaction_sound = 'sound/effects/bubbles.ogg'
|
||||
|
||||
var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file.
|
||||
|
||||
/decl/chemical_reaction/proc/can_happen(var/datum/reagents/holder)
|
||||
//check that all the required reagents are present
|
||||
if(!holder.has_all_reagents(required_reagents))
|
||||
return FALSE
|
||||
|
||||
//check that all the required catalysts are present in the required amount
|
||||
if(!holder.has_all_reagents(catalysts))
|
||||
return FALSE
|
||||
|
||||
//check that none of the inhibitors are present in the required amount
|
||||
if(holder.has_any_reagent(inhibitors))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
/decl/chemical_reaction/proc/calc_reaction_progress(var/datum/reagents/holder, var/reaction_limit)
|
||||
var/progress = reaction_limit * reaction_rate //simple exponential progression
|
||||
|
||||
//calculate yield
|
||||
if(1-yield > 0.001) //if yield ratio is big enough just assume it goes to completion
|
||||
/*
|
||||
Determine the max amount of product by applying the yield condition:
|
||||
(max_product/result_amount) / reaction_limit == yield/(1-yield)
|
||||
|
||||
We make use of the fact that:
|
||||
reaction_limit = (holder.get_reagent_amount(reactant) / required_reagents[reactant]) of the limiting reagent.
|
||||
*/
|
||||
var/yield_ratio = yield/(1-yield)
|
||||
var/max_product = yield_ratio * reaction_limit * result_amount //rearrange to obtain max_product
|
||||
var/yield_limit = max(0, max_product - holder.get_reagent_amount(result))/result_amount
|
||||
|
||||
progress = min(progress, yield_limit) //apply yield limit
|
||||
|
||||
//apply min reaction progress - wasn't sure if this should go before or after applying yield
|
||||
//I guess people can just have their miniscule reactions go to completion regardless of yield.
|
||||
for(var/reactant in required_reagents)
|
||||
var/remainder = holder.get_reagent_amount(reactant) - progress*required_reagents[reactant]
|
||||
if(remainder <= min_reaction*required_reagents[reactant])
|
||||
progress = reaction_limit
|
||||
break
|
||||
|
||||
return progress
|
||||
|
||||
/decl/chemical_reaction/process(var/datum/reagents/holder)
|
||||
//determine how far the reaction can proceed
|
||||
var/list/reaction_limits = list()
|
||||
for(var/reactant in required_reagents)
|
||||
reaction_limits += holder.get_reagent_amount(reactant) / required_reagents[reactant]
|
||||
|
||||
//determine how far the reaction proceeds
|
||||
var/reaction_limit = min(reaction_limits)
|
||||
var/progress_limit = calc_reaction_progress(holder, reaction_limit)
|
||||
|
||||
var/reaction_progress = min(reaction_limit, progress_limit) //no matter what, the reaction progress cannot exceed the stoichiometric limit.
|
||||
|
||||
//need to obtain the new reagent's data before anything is altered
|
||||
var/data = send_data(holder, reaction_progress)
|
||||
|
||||
//remove the reactants
|
||||
for(var/reactant in required_reagents)
|
||||
var/amt_used = required_reagents[reactant] * reaction_progress
|
||||
holder.remove_reagent(reactant, amt_used, safety = 1)
|
||||
|
||||
//add the product
|
||||
var/amt_produced = result_amount * reaction_progress
|
||||
if(result)
|
||||
holder.add_reagent(result, amt_produced, data, safety = 1)
|
||||
|
||||
on_reaction(holder, amt_produced)
|
||||
|
||||
return reaction_progress
|
||||
|
||||
//called when a reaction processes
|
||||
/decl/chemical_reaction/proc/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
return
|
||||
|
||||
//called after processing reactions, if they occurred
|
||||
/decl/chemical_reaction/proc/post_reaction(var/datum/reagents/holder)
|
||||
var/atom/container = holder.my_atom
|
||||
if(mix_message && container && !ismob(container))
|
||||
var/turf/T = get_turf(container)
|
||||
var/list/seen = viewers(4, T)
|
||||
for(var/mob/M in seen)
|
||||
if(M.client)
|
||||
M.show_message("<span class='notice'>[bicon(container)] [mix_message]</span>", 1)
|
||||
playsound(T, reaction_sound, 80, 1)
|
||||
|
||||
//obtains any special data that will be provided to the reaction products
|
||||
//this is called just before reactants are removed.
|
||||
/decl/chemical_reaction/proc/send_data(var/datum/reagents/holder, var/reaction_limit)
|
||||
return null
|
||||
@@ -1,4 +1,4 @@
|
||||
/datum/chemical_reaction/distilling
|
||||
/decl/chemical_reaction/distilling
|
||||
// name = null
|
||||
// id = null
|
||||
// result = null
|
||||
@@ -26,32 +26,19 @@
|
||||
var/list/temp_range = list(T0C, T20C)
|
||||
var/temp_shift = 0 // How much the temperature changes when the reaction occurs.
|
||||
|
||||
/datum/chemical_reaction/distilling/can_happen(var/datum/reagents/holder)
|
||||
//check that all the required reagents are present
|
||||
if(!holder.has_all_reagents(required_reagents))
|
||||
return 0
|
||||
/decl/chemical_reaction/distilling/can_happen(var/datum/reagents/holder)
|
||||
if(!istype(holder, /datum/reagents/distilling) || !istype(holder.my_atom, /obj/machinery/portable_atmospherics/powered/reagent_distillery))
|
||||
return FALSE
|
||||
|
||||
//check that all the required catalysts are present in the required amount
|
||||
if(!holder.has_all_reagents(catalysts))
|
||||
return 0
|
||||
|
||||
//check that none of the inhibitors are present in the required amount
|
||||
if(holder.has_any_reagent(inhibitors))
|
||||
return 0
|
||||
|
||||
if(!istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling))
|
||||
return 0
|
||||
|
||||
else // Super special temperature check.
|
||||
var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom
|
||||
var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master
|
||||
// Super special temperature check.
|
||||
var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = holder.my_atom
|
||||
if(RD.current_temp < temp_range[1] || RD.current_temp > temp_range[2])
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/*
|
||||
/datum/chemical_reaction/distilling/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
/decl/chemical_reaction/distilling/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
if(istype(holder.my_atom, /obj/item/weapon/reagent_containers/glass/distilling))
|
||||
var/obj/item/weapon/reagent_containers/glass/distilling/D = holder.my_atom
|
||||
var/obj/machinery/portable_atmospherics/powered/reagent_distillery/RD = D.Master
|
||||
@@ -62,7 +49,7 @@
|
||||
// Subtypes //
|
||||
|
||||
// Biomass
|
||||
/datum/chemical_reaction/distilling/biomass
|
||||
/decl/chemical_reaction/distilling/biomass
|
||||
name = "Distilling Biomass"
|
||||
id = "distill_biomass"
|
||||
result = "biomass"
|
||||
@@ -73,7 +60,7 @@
|
||||
temp_shift = -2
|
||||
|
||||
// Medicinal
|
||||
/datum/chemical_reaction/distilling/inaprovalaze
|
||||
/decl/chemical_reaction/distilling/inaprovalaze
|
||||
name = "Distilling Inaprovalaze"
|
||||
id = "distill_inaprovalaze"
|
||||
result = "inaprovalaze"
|
||||
@@ -84,7 +71,7 @@
|
||||
|
||||
temp_range = list(T0C + 100, T0C + 120)
|
||||
|
||||
/datum/chemical_reaction/distilling/bicaridaze
|
||||
/decl/chemical_reaction/distilling/bicaridaze
|
||||
name = "Distilling Bicaridaze"
|
||||
id = "distill_bicaridaze"
|
||||
result = "bicaridaze"
|
||||
@@ -95,7 +82,7 @@
|
||||
|
||||
temp_range = list(T0C + 110, T0C + 130)
|
||||
|
||||
/datum/chemical_reaction/distilling/dermalaze
|
||||
/decl/chemical_reaction/distilling/dermalaze
|
||||
name = "Distilling Dermalaze"
|
||||
id = "distill_dermalaze"
|
||||
result = "dermalaze"
|
||||
@@ -106,7 +93,7 @@
|
||||
|
||||
temp_range = list(T0C + 115, T0C + 130)
|
||||
|
||||
/datum/chemical_reaction/distilling/spacomycaze
|
||||
/decl/chemical_reaction/distilling/spacomycaze
|
||||
name = "Distilling Spacomycaze"
|
||||
id = "distill_spacomycaze"
|
||||
result = "spacomycaze"
|
||||
@@ -117,7 +104,7 @@
|
||||
|
||||
temp_range = list(T0C + 100, T0C + 120)
|
||||
|
||||
/datum/chemical_reaction/distilling/tricorlidaze
|
||||
/decl/chemical_reaction/distilling/tricorlidaze
|
||||
name = "Distilling Tricorlidaze"
|
||||
id = "distill_tricorlidaze"
|
||||
result = "tricorlidaze"
|
||||
@@ -128,7 +115,7 @@
|
||||
|
||||
temp_range = list(T0C + 100, T0C + 120)
|
||||
|
||||
/datum/chemical_reaction/distilling/synthplas
|
||||
/decl/chemical_reaction/distilling/synthplas
|
||||
name = "Distilling Synthplas"
|
||||
id = "distill_synthplas"
|
||||
result = "synthblood_dilute"
|
||||
@@ -140,7 +127,7 @@
|
||||
temp_range = list(T0C + 110, T0C + 130)
|
||||
|
||||
// Alcohol
|
||||
/datum/chemical_reaction/distilling/beer
|
||||
/decl/chemical_reaction/distilling/beer
|
||||
name = "Distilling Beer"
|
||||
id = "distill_beer"
|
||||
result = "beer"
|
||||
@@ -151,7 +138,7 @@
|
||||
|
||||
temp_range = list(T20C, T20C + 2)
|
||||
|
||||
/datum/chemical_reaction/distilling/ale
|
||||
/decl/chemical_reaction/distilling/ale
|
||||
name = "Distilling Ale"
|
||||
id = "distill_ale"
|
||||
result = "ale"
|
||||
@@ -165,7 +152,7 @@
|
||||
temp_range = list(T0C + 7, T0C + 13)
|
||||
|
||||
// Unique
|
||||
/datum/chemical_reaction/distilling/berserkjuice
|
||||
/decl/chemical_reaction/distilling/berserkjuice
|
||||
name = "Distilling Brute Juice"
|
||||
id = "distill_brutejuice"
|
||||
result = "berserkmed"
|
||||
@@ -175,7 +162,7 @@
|
||||
temp_range = list(T0C + 600, T0C + 700)
|
||||
temp_shift = 4
|
||||
|
||||
/datum/chemical_reaction/distilling/berserkjuice/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
/decl/chemical_reaction/distilling/berserkjuice/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
..()
|
||||
|
||||
if(prob(1))
|
||||
@@ -183,7 +170,7 @@
|
||||
explosion(T, -1, rand(-1, 1), rand(1,2), rand(3,5))
|
||||
return
|
||||
|
||||
/datum/chemical_reaction/distilling/cryogel
|
||||
/decl/chemical_reaction/distilling/cryogel
|
||||
name = "Distilling Cryogellatin"
|
||||
id = "distill_cryoslurry"
|
||||
result = "cryoslurry"
|
||||
@@ -194,7 +181,7 @@
|
||||
temp_range = list(0, 15)
|
||||
temp_shift = 20
|
||||
|
||||
/datum/chemical_reaction/distilling/cryogel/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
/decl/chemical_reaction/distilling/cryogel/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
..()
|
||||
|
||||
if(prob(1))
|
||||
@@ -204,7 +191,7 @@
|
||||
F.start()
|
||||
return
|
||||
|
||||
/datum/chemical_reaction/distilling/lichpowder
|
||||
/decl/chemical_reaction/distilling/lichpowder
|
||||
name = "Distilling Lichpowder"
|
||||
id = "distill_lichpowder"
|
||||
result = "lichpowder"
|
||||
@@ -215,7 +202,7 @@
|
||||
|
||||
temp_range = list(T0C + 100, T0C + 150)
|
||||
|
||||
/datum/chemical_reaction/distilling/necroxadone
|
||||
/decl/chemical_reaction/distilling/necroxadone
|
||||
name = "Distilling Necroxadone"
|
||||
id = "distill_necroxadone"
|
||||
result = "necroxadone"
|
||||
6
code/modules/reagents/reactions/fusion/fusion.dm
Normal file
6
code/modules/reagents/reactions/fusion/fusion.dm
Normal file
@@ -0,0 +1,6 @@
|
||||
// TDOD: Port R-UST fusion reactions to the chemistry system.
|
||||
//They'll operate in a similar manner to distillery reactions,
|
||||
// but will have distinct behaviours (mostly relating to the fusion field) that warrants a separate type
|
||||
/*
|
||||
/decl/chemical_reaction/fusion
|
||||
name = "Fusion"*/
|
||||
1223
code/modules/reagents/reactions/instant/drinks.dm
Normal file
1223
code/modules/reagents/reactions/instant/drinks.dm
Normal file
File diff suppressed because it is too large
Load Diff
198
code/modules/reagents/reactions/instant/drinks_vr.dm
Normal file
198
code/modules/reagents/reactions/instant/drinks_vr.dm
Normal file
@@ -0,0 +1,198 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Special drinks
|
||||
/decl/chemical_reaction/instant/drinks/grubshake
|
||||
name = "Grub protein drink"
|
||||
id = "grubshake"
|
||||
result = "grubshake"
|
||||
required_reagents = list("shockchem" = 5, "water" = 25)
|
||||
result_amount = 30
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/deathbell
|
||||
name = "Deathbell"
|
||||
id = "deathbell"
|
||||
result = "deathbell"
|
||||
required_reagents = list("antifreeze" = 1, "gargleblaster" = 1, "syndicatebomb" =1)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/monstertamer
|
||||
name = "Monster Tamer"
|
||||
id = "monstertamer"
|
||||
result = "monstertamer"
|
||||
required_reagents = list("whiskey" = 1, "protein" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/bigbeer
|
||||
name = "Giant Beer"
|
||||
id = "bigbeer"
|
||||
result = "bigbeer"
|
||||
required_reagents = list("syndicatebomb" = 1, "manlydorf" = 1, "grog" =1)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/sweettea
|
||||
name = "Sweetened Tea"
|
||||
id = "sweettea"
|
||||
result = "sweettea"
|
||||
required_reagents = list("icetea" = 2, "sugar" = 1,)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/unsweettea
|
||||
name = "Unsweetened Tea"
|
||||
id = "unsweettea"
|
||||
result = "unsweettea"
|
||||
required_reagents = list("sweettea" = 3, "phoron" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/galacticpanic
|
||||
name = "Galactic Panic Attack"
|
||||
id = "galacticpanic"
|
||||
result = "galacticpanic"
|
||||
required_reagents = list("gargleblaster" = 1, "singulo" = 1, "phoronspecial" =1, "neurotoxin" = 1, "atomicbomb" = 1, "hippiesdelight" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/bulldog
|
||||
name = "Space Bulldog"
|
||||
id = "bulldog"
|
||||
result = "bulldog"
|
||||
required_reagents = list("whiterussian" = 4, "cola" =1)
|
||||
result_amount = 4
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/sbagliato
|
||||
name = "Negroni Sbagliato"
|
||||
id = "sbagliato"
|
||||
result = "sbagliato"
|
||||
required_reagents = list("wine" = 1, "vermouth" = 1, "sodawater" =1)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/italiancrisis
|
||||
name = "Italian Crisis"
|
||||
id = "italiancrisis"
|
||||
result = "italiancrisis"
|
||||
required_reagents = list("bulldog" = 1, "sbagliato" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/sugarrush
|
||||
name = "Sweet Rush"
|
||||
id = "sugarrush"
|
||||
result = "sugarrush"
|
||||
required_reagents = list("sugar" = 1, "sodawater" = 1, "vodka" =1)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/lotus
|
||||
name = "Lotus"
|
||||
id = "lotus"
|
||||
result = "lotus"
|
||||
required_reagents = list("sbagliato" = 1, "sugarrush" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/shroomjuice
|
||||
name = "Dumb Shroom Juice"
|
||||
id = "shroomjuice"
|
||||
result = "shroomjuice"
|
||||
required_reagents = list("psilocybin" = 1, "applejuice" = 1, "limejuice" =1)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/russianroulette
|
||||
name = "Russian Roulette"
|
||||
id = "russianroulette"
|
||||
result = "russianroulette"
|
||||
required_reagents = list("whiterussian" = 5, "iron" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/lovemaker
|
||||
name = "The Love Maker"
|
||||
id = "lovemaker"
|
||||
result = "lovemaker"
|
||||
required_reagents = list("honey" = 1, "sexonthebeach" = 5)
|
||||
result_amount = 6
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/honeyshot
|
||||
name = "Honey Shot"
|
||||
id = "honeyshot"
|
||||
result = "honeyshot"
|
||||
required_reagents = list("honey" = 1, "vodka" = 1, "grenadine" =1)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/appletini
|
||||
name = "Appletini"
|
||||
id = "appletini"
|
||||
result = "appletini"
|
||||
required_reagents = list("applejuice" = 2, "vodka" = 1)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/glowingappletini
|
||||
name = "Glowing Appletini"
|
||||
id = "glowingappletini"
|
||||
result = "glowingappletini"
|
||||
required_reagents = list("appletini" = 5, "uranium" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/scsatw
|
||||
name = "Slow Comfortable Screw Against the Wall"
|
||||
id = "scsatw"
|
||||
result = "scsatw"
|
||||
required_reagents = list("screwdrivercocktail" = 3, "rum" =1, "whiskey" =1, "gin" =1)
|
||||
result_amount = 6
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/choccymilk
|
||||
name = "Choccy Milk"
|
||||
id = "choccymilk"
|
||||
result = "choccymilk"
|
||||
required_reagents = list("milk" = 3, "coco" = 1)
|
||||
result_amount = 4
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/redspaceflush
|
||||
name = "Redspace Flush"
|
||||
id = "redspaceflush"
|
||||
result = "redspaceflush"
|
||||
required_reagents = list("rum" = 2, "whiskey" = 2, "blood" =1, "phoron" =1)
|
||||
result_amount = 6
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/graveyard
|
||||
name = "Graveyard"
|
||||
id = "graveyard"
|
||||
result = "graveyard"
|
||||
required_reagents = list("cola" = 1, "spacemountainwind" = 1, "dr_gibb" =1, "space_up" = 1)
|
||||
result_amount = 4
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/hairoftherat
|
||||
name = "Hair of the Rat"
|
||||
id = "hairoftherat"
|
||||
result = "hairoftherat"
|
||||
required_reagents = list("monstertamer" = 2, "nutriment" = 1)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/pink_moo
|
||||
name = "Pink Moo"
|
||||
id = "pinkmoo"
|
||||
result = "pinkmoo"
|
||||
required_reagents = list("blackrussian" = 2, "berryshake" = 1)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/originalsin
|
||||
name = "Original Sin"
|
||||
id = "originalsin"
|
||||
result = "originalsin"
|
||||
required_reagents = list("holywine" = 1)
|
||||
catalysts = list("applejuice" = 1)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/windgarita
|
||||
name = "WND-Garita"
|
||||
id = "windgarita"
|
||||
result = "windgarita"
|
||||
required_reagents = list("margarita" = 3, "spacemountainwind" = 2, "melonliquor" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/newyorksour
|
||||
name = "New York Sour"
|
||||
id = "newyorksour"
|
||||
result = "newyorksour"
|
||||
required_reagents = list("whiskeysour" = 3, "wine" = 2, "egg" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/decl/chemical_reaction/instant/drinks/mudslide
|
||||
name = "Mudslide"
|
||||
id = "mudslide"
|
||||
result = "mudslide"
|
||||
required_reagents = list("blackrussian" = 1, "irishcream" = 1)
|
||||
result_amount = 2
|
||||
183
code/modules/reagents/reactions/instant/food.dm
Normal file
183
code/modules/reagents/reactions/instant/food.dm
Normal file
@@ -0,0 +1,183 @@
|
||||
/decl/chemical_reaction/instant/food/hot_ramen
|
||||
name = "Hot Ramen"
|
||||
id = "hot_ramen"
|
||||
result = "hot_ramen"
|
||||
required_reagents = list("water" = 1, "dry_ramen" = 3)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/food/hell_ramen
|
||||
name = "Hell Ramen"
|
||||
id = "hell_ramen"
|
||||
result = "hell_ramen"
|
||||
required_reagents = list("capsaicin" = 1, "hot_ramen" = 6)
|
||||
result_amount = 6
|
||||
|
||||
/decl/chemical_reaction/instant/food/tofu
|
||||
name = "Tofu"
|
||||
id = "tofu"
|
||||
result = null
|
||||
required_reagents = list("soymilk" = 10)
|
||||
catalysts = list("enzyme" = 5)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/food/tofu/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
for(var/i = 1, i <= created_volume, i++)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/tofu(location)
|
||||
return
|
||||
|
||||
/decl/chemical_reaction/instant/food/chocolate_bar
|
||||
name = "Chocolate Bar"
|
||||
id = "chocolate_bar"
|
||||
result = null
|
||||
required_reagents = list("soymilk" = 2, "coco" = 2, "sugar" = 2)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/food/chocolate_bar/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
for(var/i = 1, i <= created_volume, i++)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location)
|
||||
return
|
||||
|
||||
/decl/chemical_reaction/instant/food/chocolate_bar2
|
||||
name = "Chocolate Bar"
|
||||
id = "chocolate_bar"
|
||||
result = null
|
||||
required_reagents = list("milk" = 2, "coco" = 2, "sugar" = 2)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/food/chocolate_bar2/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
for(var/i = 1, i <= created_volume, i++)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(location)
|
||||
return
|
||||
|
||||
/decl/chemical_reaction/instant/food/soysauce
|
||||
name = "Soy Sauce"
|
||||
id = "soysauce"
|
||||
result = "soysauce"
|
||||
required_reagents = list("soymilk" = 4, "sacid" = 1)
|
||||
result_amount = 5
|
||||
|
||||
/decl/chemical_reaction/instant/food/ketchup
|
||||
name = "Ketchup"
|
||||
id = "ketchup"
|
||||
result = "ketchup"
|
||||
required_reagents = list("tomatojuice" = 2, "water" = 1, "sugar" = 1)
|
||||
result_amount = 4
|
||||
|
||||
/decl/chemical_reaction/instant/food/barbecue
|
||||
name = "Barbeque Sauce"
|
||||
id = "barbecue"
|
||||
result = "barbecue"
|
||||
required_reagents = list("tomatojuice" = 2, "applejuice" = 1, "sugar" = 1, "spacespice" = 1)
|
||||
result_amount = 4
|
||||
|
||||
/decl/chemical_reaction/instant/food/peanutbutter
|
||||
name = "Peanut Butter"
|
||||
id = "peanutbutter"
|
||||
result = "peanutbutter"
|
||||
required_reagents = list("peanutoil" = 2, "sugar" = 1, "sodiumchloride" = 1)
|
||||
catalysts = list("enzyme" = 5)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/food/mayonnaise
|
||||
name = "mayonnaise"
|
||||
id = "mayo"
|
||||
result = "mayo"
|
||||
required_reagents = list("egg" = 9, "cornoil" = 5, "lemonjuice" = 5, "sodiumchloride" = 1)
|
||||
result_amount = 15
|
||||
|
||||
/decl/chemical_reaction/instant/food/cheesewheel
|
||||
name = "Cheesewheel"
|
||||
id = "cheesewheel"
|
||||
result = null
|
||||
required_reagents = list("milk" = 40)
|
||||
catalysts = list("enzyme" = 5)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/food/cheesewheel/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
for(var/i = 1, i <= created_volume, i++)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/sliceable/cheesewheel(location)
|
||||
return
|
||||
|
||||
/decl/chemical_reaction/instant/food/meatball
|
||||
name = "Meatball"
|
||||
id = "meatball"
|
||||
result = null
|
||||
required_reagents = list("protein" = 3, "flour" = 5)
|
||||
result_amount = 3
|
||||
|
||||
/decl/chemical_reaction/instant/food/meatball/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
for(var/i = 1, i <= created_volume, i++)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/meatball(location)
|
||||
return
|
||||
|
||||
/decl/chemical_reaction/instant/food/dough
|
||||
name = "Dough"
|
||||
id = "dough"
|
||||
result = null
|
||||
required_reagents = list("egg" = 3, "flour" = 10)
|
||||
inhibitors = list("water" = 1, "beer" = 1) //To prevent it messing with batter recipes
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/food/dough/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
for(var/i = 1, i <= created_volume, i++)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/dough(location)
|
||||
return
|
||||
|
||||
/decl/chemical_reaction/instant/food/syntiflesh
|
||||
name = "Syntiflesh"
|
||||
id = "syntiflesh"
|
||||
result = null
|
||||
required_reagents = list("blood" = 5, "clonexadone" = 5)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/food/syntiflesh/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
for(var/i = 1, i <= created_volume, i++)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/meat/syntiflesh(location)
|
||||
return
|
||||
|
||||
/*
|
||||
====================
|
||||
Aurora Food
|
||||
====================
|
||||
*/
|
||||
|
||||
/decl/chemical_reaction/instant/food/coating/batter
|
||||
name = "Batter"
|
||||
id = "batter"
|
||||
result = "batter"
|
||||
required_reagents = list("egg" = 3, "flour" = 10, "water" = 5, "sodiumchloride" = 2)
|
||||
result_amount = 20
|
||||
|
||||
/decl/chemical_reaction/instant/food/coating/beerbatter
|
||||
name = "Beer Batter"
|
||||
id = "beerbatter"
|
||||
result = "beerbatter"
|
||||
required_reagents = list("egg" = 3, "flour" = 10, "beer" = 5, "sodiumchloride" = 2)
|
||||
result_amount = 20
|
||||
|
||||
/decl/chemical_reaction/instant/food/browniemix
|
||||
name = "Brownie Mix"
|
||||
id = "browniemix"
|
||||
result = "browniemix"
|
||||
required_reagents = list("flour" = 5, "coco" = 5, "sugar" = 5)
|
||||
result_amount = 15
|
||||
|
||||
/decl/chemical_reaction/instant/food/butter
|
||||
name = "Butter"
|
||||
id = "butter"
|
||||
result = null
|
||||
required_reagents = list("cream" = 20, "sodiumchloride" = 1)
|
||||
result_amount = 1
|
||||
|
||||
/decl/chemical_reaction/instant/food/butter/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
for(var/i = 1, i <= created_volume, i++)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/spreads/butter(location)
|
||||
return
|
||||
2
code/modules/reagents/reactions/instant/food_vr.dm
Normal file
2
code/modules/reagents/reactions/instant/food_vr.dm
Normal file
@@ -0,0 +1,2 @@
|
||||
/decl/chemical_reaction/instant/food/syntiflesh
|
||||
required_reagents = list("blood" = 5, "clonexadone" = 1)
|
||||
1135
code/modules/reagents/reactions/instant/instant.dm
Normal file
1135
code/modules/reagents/reactions/instant/instant.dm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Micro/Macro chemicals
|
||||
|
||||
/datum/chemical_reaction/sizeoxadone
|
||||
/decl/chemical_reaction/instant/sizeoxadone
|
||||
name = "sizeoxadone"
|
||||
id = "sizeoxadone"
|
||||
result = "sizeoxadone"
|
||||
@@ -9,7 +9,7 @@
|
||||
catalysts = list("phoron" = 5)
|
||||
result_amount = 5
|
||||
|
||||
/datum/chemical_reaction/macrocillin
|
||||
/decl/chemical_reaction/instant/macrocillin
|
||||
name = "Macrocillin"
|
||||
id = "macrocillin"
|
||||
result = "macrocillin"
|
||||
@@ -17,7 +17,7 @@
|
||||
required_reagents = list("sizeoxadone" = 20, "diethylamine" = 20)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/microcillin
|
||||
/decl/chemical_reaction/instant/microcillin
|
||||
name = "Microcillin"
|
||||
id = "microcillin"
|
||||
result = "microcillin"
|
||||
@@ -25,7 +25,7 @@
|
||||
required_reagents = list("sizeoxadone" = 20, "sodiumchloride" = 20)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/normalcillin
|
||||
/decl/chemical_reaction/instant/normalcillin
|
||||
name = "Normalcillin"
|
||||
id = "normalcillin"
|
||||
result = "normalcillin"
|
||||
@@ -33,13 +33,13 @@
|
||||
required_reagents = list("sizeoxadone" = 20, "leporazine" = 20)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/dontcrossthebeams
|
||||
/decl/chemical_reaction/instant/dontcrossthebeams
|
||||
name = "Don't Cross The Beams"
|
||||
id = "dontcrossthebeams"
|
||||
result = null
|
||||
required_reagents = list("microcillin" = 1, "macrocillin" = 1)
|
||||
|
||||
/datum/chemical_reaction/dontcrossthebeams/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
/decl/chemical_reaction/instant/dontcrossthebeams/on_reaction(var/datum/reagents/holder, var/created_volume)
|
||||
var/location = get_turf(holder.my_atom)
|
||||
playsound(location, 'sound/weapons/gauss_shoot.ogg', 50, 1)
|
||||
var/datum/effect/effect/system/grav_pull/s = new /datum/effect/effect/system/grav_pull
|
||||
@@ -50,13 +50,13 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Miscellaneous Reactions
|
||||
|
||||
/datum/chemical_reaction/xenolazarus
|
||||
/decl/chemical_reaction/instant/xenolazarus
|
||||
name = "Discount Lazarus"
|
||||
id = "discountlazarus"
|
||||
result = null
|
||||
required_reagents = list("monstertamer" = 5, "clonexadone" = 5)
|
||||
|
||||
/datum/chemical_reaction/xenolazarus/on_reaction(var/datum/reagents/holder, var/created_volume) //literally all this does is mash the regenerate button
|
||||
/decl/chemical_reaction/instant/xenolazarus/on_reaction(var/datum/reagents/holder, var/created_volume) //literally all this does is mash the regenerate button
|
||||
if(ishuman(holder.my_atom))
|
||||
var/mob/living/carbon/human/H = holder.my_atom
|
||||
if(H.stat == DEAD && (/mob/living/carbon/human/proc/reconstitute_form in H.verbs)) //no magical regen for non-regenners, and can't force the reaction on live ones
|
||||
@@ -75,10 +75,10 @@
|
||||
H.visible_message("<span class='info'>[H] twitches for a moment, but remains still.</span>") // no nutriment
|
||||
|
||||
|
||||
/datum/chemical_reaction/foam/softdrink
|
||||
/decl/chemical_reaction/instant/foam/softdrink
|
||||
required_reagents = list("cola" = 1, "mint" = 1)
|
||||
|
||||
/datum/chemical_reaction/firefightingfoam //TODO: Make it so we can add this to the foam tanks to refill them
|
||||
/decl/chemical_reaction/instant/firefightingfoam //TODO: Make it so we can add this to the foam tanks to refill them
|
||||
name = "Firefighting Foam"
|
||||
id = "firefighting foam"
|
||||
result = "firefoam"
|
||||
@@ -86,7 +86,7 @@
|
||||
catalysts = list("fluorine" = 10)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/firefightingfoamqol //Please don't abuse this and make us remove it. Seriously.
|
||||
/decl/chemical_reaction/instant/firefightingfoamqol //Please don't abuse this and make us remove it. Seriously.
|
||||
name = "Firefighting Foam EZ"
|
||||
id = "firefighting foam ez"
|
||||
result = "firefoam"
|
||||
@@ -98,14 +98,14 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Vore Drugs
|
||||
|
||||
/datum/chemical_reaction/ickypak
|
||||
/decl/chemical_reaction/instant/ickypak
|
||||
name = "Ickypak"
|
||||
id = "ickypak"
|
||||
result = "ickypak"
|
||||
required_reagents = list("hyperzine" = 4, "fluorosurfactant" = 1)
|
||||
result_amount = 5
|
||||
|
||||
/datum/chemical_reaction/unsorbitol
|
||||
/decl/chemical_reaction/instant/unsorbitol
|
||||
name = "Unsorbitol"
|
||||
id = "unsorbitol"
|
||||
result = "unsorbitol"
|
||||
@@ -114,14 +114,14 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Other Drugs
|
||||
/datum/chemical_reaction/adranol
|
||||
/decl/chemical_reaction/instant/adranol
|
||||
name = "Adranol"
|
||||
id = "adranol"
|
||||
result = "adranol"
|
||||
required_reagents = list("milk" = 2, "hydrogen" = 1, "potassium" = 1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/vermicetol
|
||||
/decl/chemical_reaction/instant/vermicetol
|
||||
name = "Vermicetol"
|
||||
id = "vermicetol"
|
||||
result = "vermicetol"
|
||||
@@ -129,215 +129,16 @@
|
||||
catalysts = list("phoron" = 5)
|
||||
result_amount = 3
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Special drinks
|
||||
/datum/chemical_reaction/drinks/grubshake
|
||||
name = "Grub protein drink"
|
||||
id = "grubshake"
|
||||
result = "grubshake"
|
||||
required_reagents = list("shockchem" = 5, "water" = 25)
|
||||
result_amount = 30
|
||||
|
||||
/datum/chemical_reaction/drinks/deathbell
|
||||
name = "Deathbell"
|
||||
id = "deathbell"
|
||||
result = "deathbell"
|
||||
required_reagents = list("antifreeze" = 1, "gargleblaster" = 1, "syndicatebomb" =1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/monstertamer
|
||||
name = "Monster Tamer"
|
||||
id = "monstertamer"
|
||||
result = "monstertamer"
|
||||
required_reagents = list("whiskey" = 1, "protein" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/drinks/bigbeer
|
||||
name = "Giant Beer"
|
||||
id = "bigbeer"
|
||||
result = "bigbeer"
|
||||
required_reagents = list("syndicatebomb" = 1, "manlydorf" = 1, "grog" =1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/sweettea
|
||||
name = "Sweetened Tea"
|
||||
id = "sweettea"
|
||||
result = "sweettea"
|
||||
required_reagents = list("icetea" = 2, "sugar" = 1,)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/unsweettea
|
||||
name = "Unsweetened Tea"
|
||||
id = "unsweettea"
|
||||
result = "unsweettea"
|
||||
required_reagents = list("sweettea" = 3, "phoron" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/drinks/galacticpanic
|
||||
name = "Galactic Panic Attack"
|
||||
id = "galacticpanic"
|
||||
result = "galacticpanic"
|
||||
required_reagents = list("gargleblaster" = 1, "singulo" = 1, "phoronspecial" =1, "neurotoxin" = 1, "atomicbomb" = 1, "hippiesdelight" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/datum/chemical_reaction/drinks/bulldog
|
||||
name = "Space Bulldog"
|
||||
id = "bulldog"
|
||||
result = "bulldog"
|
||||
required_reagents = list("whiterussian" = 4, "cola" =1)
|
||||
result_amount = 4
|
||||
|
||||
/datum/chemical_reaction/drinks/sbagliato
|
||||
name = "Negroni Sbagliato"
|
||||
id = "sbagliato"
|
||||
result = "sbagliato"
|
||||
required_reagents = list("wine" = 1, "vermouth" = 1, "sodawater" =1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/italiancrisis
|
||||
name = "Italian Crisis"
|
||||
id = "italiancrisis"
|
||||
result = "italiancrisis"
|
||||
required_reagents = list("bulldog" = 1, "sbagliato" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/drinks/sugarrush
|
||||
name = "Sweet Rush"
|
||||
id = "sugarrush"
|
||||
result = "sugarrush"
|
||||
required_reagents = list("sugar" = 1, "sodawater" = 1, "vodka" =1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/lotus
|
||||
name = "Lotus"
|
||||
id = "lotus"
|
||||
result = "lotus"
|
||||
required_reagents = list("sbagliato" = 1, "sugarrush" = 1)
|
||||
result_amount = 2
|
||||
|
||||
/datum/chemical_reaction/drinks/shroomjuice
|
||||
name = "Dumb Shroom Juice"
|
||||
id = "shroomjuice"
|
||||
result = "shroomjuice"
|
||||
required_reagents = list("psilocybin" = 1, "applejuice" = 1, "limejuice" =1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/russianroulette
|
||||
name = "Russian Roulette"
|
||||
id = "russianroulette"
|
||||
result = "russianroulette"
|
||||
required_reagents = list("whiterussian" = 5, "iron" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/datum/chemical_reaction/drinks/lovemaker
|
||||
name = "The Love Maker"
|
||||
id = "lovemaker"
|
||||
result = "lovemaker"
|
||||
required_reagents = list("honey" = 1, "sexonthebeach" = 5)
|
||||
result_amount = 6
|
||||
|
||||
/datum/chemical_reaction/drinks/honeyshot
|
||||
name = "Honey Shot"
|
||||
id = "honeyshot"
|
||||
result = "honeyshot"
|
||||
required_reagents = list("honey" = 1, "vodka" = 1, "grenadine" =1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/appletini
|
||||
name = "Appletini"
|
||||
id = "appletini"
|
||||
result = "appletini"
|
||||
required_reagents = list("applejuice" = 2, "vodka" = 1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/glowingappletini
|
||||
name = "Glowing Appletini"
|
||||
id = "glowingappletini"
|
||||
result = "glowingappletini"
|
||||
required_reagents = list("appletini" = 5, "uranium" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/datum/chemical_reaction/drinks/scsatw
|
||||
name = "Slow Comfortable Screw Against the Wall"
|
||||
id = "scsatw"
|
||||
result = "scsatw"
|
||||
required_reagents = list("screwdrivercocktail" = 3, "rum" =1, "whiskey" =1, "gin" =1)
|
||||
result_amount = 6
|
||||
|
||||
/datum/chemical_reaction/drinks/choccymilk
|
||||
name = "Choccy Milk"
|
||||
id = "choccymilk"
|
||||
result = "choccymilk"
|
||||
required_reagents = list("milk" = 3, "coco" = 1)
|
||||
result_amount = 4
|
||||
|
||||
/datum/chemical_reaction/drinks/redspaceflush
|
||||
name = "Redspace Flush"
|
||||
id = "redspaceflush"
|
||||
result = "redspaceflush"
|
||||
required_reagents = list("rum" = 2, "whiskey" = 2, "blood" =1, "phoron" =1)
|
||||
result_amount = 6
|
||||
|
||||
/datum/chemical_reaction/drinks/graveyard
|
||||
name = "Graveyard"
|
||||
id = "graveyard"
|
||||
result = "graveyard"
|
||||
required_reagents = list("cola" = 1, "spacemountainwind" = 1, "dr_gibb" =1, "space_up" = 1)
|
||||
result_amount = 4
|
||||
|
||||
/datum/chemical_reaction/drinks/hairoftherat
|
||||
name = "Hair of the Rat"
|
||||
id = "hairoftherat"
|
||||
result = "hairoftherat"
|
||||
required_reagents = list("monstertamer" = 2, "nutriment" = 1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/pink_moo
|
||||
name = "Pink Moo"
|
||||
id = "pinkmoo"
|
||||
result = "pinkmoo"
|
||||
required_reagents = list("blackrussian" = 2, "berryshake" = 1)
|
||||
result_amount = 3
|
||||
|
||||
/datum/chemical_reaction/drinks/originalsin
|
||||
name = "Original Sin"
|
||||
id = "originalsin"
|
||||
result = "originalsin"
|
||||
required_reagents = list("holywine" = 1)
|
||||
catalysts = list("applejuice" = 1)
|
||||
result_amount = 1
|
||||
|
||||
/datum/chemical_reaction/drinks/windgarita
|
||||
name = "WND-Garita"
|
||||
id = "windgarita"
|
||||
result = "windgarita"
|
||||
required_reagents = list("margarita" = 3, "spacemountainwind" = 2, "melonliquor" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/datum/chemical_reaction/drinks/newyorksour
|
||||
name = "New York Sour"
|
||||
id = "newyorksour"
|
||||
result = "newyorksour"
|
||||
required_reagents = list("whiskeysour" = 3, "wine" = 2, "egg" = 1)
|
||||
result_amount = 6
|
||||
|
||||
/datum/chemical_reaction/drinks/mudslide
|
||||
name = "Mudslide"
|
||||
id = "mudslide"
|
||||
result = "mudslide"
|
||||
required_reagents = list("blackrussian" = 1, "irishcream" = 1)
|
||||
result_amount = 2
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// Reagent colonies.
|
||||
/datum/chemical_reaction/meatcolony
|
||||
/decl/chemical_reaction/instant/meatcolony
|
||||
name = "protein"
|
||||
id = "meatcolony"
|
||||
result = "protein"
|
||||
required_reagents = list("meatcolony" = 5, "virusfood" = 5)
|
||||
result_amount = 60
|
||||
|
||||
/datum/chemical_reaction/plantcolony
|
||||
/decl/chemical_reaction/instant/plantcolony
|
||||
name = "nutriment"
|
||||
id = "plantcolony"
|
||||
result = "nutriment"
|
||||
@@ -350,7 +151,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime_food
|
||||
/decl/chemical_reaction/instant/slime_food
|
||||
name = "Slime Bork"
|
||||
id = "m_tele2"
|
||||
result = null
|
||||
@@ -378,7 +179,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/chemical_reaction/materials
|
||||
/decl/chemical_reaction/instant/materials
|
||||
name = "Slime materials"
|
||||
id = "slimematerial"
|
||||
result = null
|
||||
@@ -435,7 +236,7 @@
|
||||
C.loc = get_turf(holder.my_atom)
|
||||
|
||||
|
||||
/datum/chemical_reaction/slimelight
|
||||
/decl/chemical_reaction/instant/slimelight
|
||||
name = "Slime Glow"
|
||||
id = "m_glow"
|
||||
result = null
|
||||
@@ -448,7 +249,7 @@
|
||||
F.loc = get_turf(holder.my_atom)
|
||||
|
||||
|
||||
/datum/chemical_reaction/slimephoron
|
||||
/decl/chemical_reaction/instant/slimephoron
|
||||
name = "Slime Phoron"
|
||||
id = "m_plasma"
|
||||
result = null
|
||||
@@ -459,7 +260,7 @@
|
||||
P.amount = 10
|
||||
P.loc = get_turf(holder.my_atom)
|
||||
|
||||
/datum/chemical_reaction/slimefreeze
|
||||
/decl/chemical_reaction/instant/slimefreeze
|
||||
name = "Slime Freeze"
|
||||
id = "m_freeze"
|
||||
result = null
|
||||
@@ -477,7 +278,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/chemical_reaction/slimefrost
|
||||
/decl/chemical_reaction/instant/slimefrost
|
||||
name = "Slime Frost Oil"
|
||||
id = "m_frostoil"
|
||||
result = "frostoil"
|
||||
@@ -487,7 +288,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/chemical_reaction/slimefire
|
||||
/decl/chemical_reaction/instant/slimefire
|
||||
name = "Slime fire"
|
||||
id = "m_fire"
|
||||
result = null
|
||||
@@ -503,7 +304,7 @@
|
||||
spawn (0) target_tile.hotspot_expose(700, 400)
|
||||
|
||||
|
||||
/datum/chemical_reaction/slimeify
|
||||
/decl/chemical_reaction/instant/slimeify
|
||||
name = "Advanced Mutation Toxin"
|
||||
id = "advmutationtoxin2"
|
||||
result = "advmutationtoxin"
|
||||
@@ -514,7 +315,7 @@
|
||||
|
||||
|
||||
|
||||
/datum/chemical_reaction/slimeheal //A slime healing mixture. Why not.
|
||||
/decl/chemical_reaction/instant/slimeheal //A slime healing mixture. Why not.
|
||||
name = "Slime Health"
|
||||
id = "slimeheal"
|
||||
result = "null"
|
||||
@@ -530,14 +331,14 @@
|
||||
C.adjustCloneLoss(-25)
|
||||
C.updatehealth()
|
||||
|
||||
/datum/chemical_reaction/slimejelly
|
||||
/decl/chemical_reaction/instant/slimejelly
|
||||
name = "Slime Jam"
|
||||
id = "m_jam"
|
||||
result = "slimejelly"
|
||||
required_reagents = list("phoron" = 20, "sugar" = 50, "lithium" = 50) //In case a xenobiologist is impatient and is willing to drain their dispenser resources, along with plasma!
|
||||
result_amount = 5
|
||||
|
||||
/datum/chemical_reaction/slimevore
|
||||
/decl/chemical_reaction/instant/slimevore
|
||||
name = "Slime Vore" // Hostile vore mobs only
|
||||
id = "m_tele"
|
||||
result = null
|
||||
@@ -600,9 +401,27 @@
|
||||
for(var/j = 1, j <= rand(1, 3), j++)
|
||||
step(C, pick(NORTH,SOUTH,EAST,WEST))
|
||||
|
||||
/decl/chemical_reaction/instant/slime/sapphire_mutation
|
||||
name = "Slime Mutation Toxins"
|
||||
id = "slime_mutation_tox"
|
||||
result = "mutationtoxin"
|
||||
required_reagents = list("blood" = 5)
|
||||
result_amount = 30
|
||||
required = /obj/item/slime_extract/sapphire
|
||||
|
||||
<<<<<<< HEAD:code/modules/reagents/Chemistry-Recipes_vr.dm
|
||||
/datum/chemical_reaction/food/syntiflesh
|
||||
required_reagents = list("blood" = 5, "clonexadone" = 1)
|
||||
|
||||
/datum/chemical_reaction/biomass
|
||||
result_amount = 6 // Roughly 120u per phoron sheet
|
||||
||||||| parent of 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013:code/modules/reagents/Chemistry-Recipes_vr.dm
|
||||
/datum/chemical_reaction/food/syntiflesh
|
||||
required_reagents = list("blood" = 5, "clonexadone" = 1)
|
||||
|
||||
/datum/chemical_reaction/biomass
|
||||
result_amount = 6 // Roughly 120u per phoron sheet
|
||||
=======
|
||||
/decl/chemical_reaction/instant/biomass
|
||||
result_amount = 6 // Roughly 120u per phoron sheet
|
||||
>>>>>>> 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013:code/modules/reagents/reactions/instant/instant_vr.dm
|
||||
@@ -1,486 +0,0 @@
|
||||
|
||||
|
||||
/obj/structure/reagent_dispensers
|
||||
name = "Dispenser"
|
||||
desc = "..."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "watertank"
|
||||
layer = TABLE_LAYER
|
||||
density = 1
|
||||
anchored = 0
|
||||
pressure_resistance = 2*ONE_ATMOSPHERE
|
||||
|
||||
var/obj/item/hose_connector/input/active/InputSocket
|
||||
var/obj/item/hose_connector/output/active/OutputSocket
|
||||
|
||||
var/amount_per_transfer_from_this = 10
|
||||
var/possible_transfer_amounts = list(10,25,50,100)
|
||||
|
||||
/obj/structure/reagent_dispensers/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
return
|
||||
|
||||
/obj/structure/reagent_dispensers/Destroy()
|
||||
QDEL_NULL(InputSocket)
|
||||
QDEL_NULL(OutputSocket)
|
||||
|
||||
..()
|
||||
|
||||
/obj/structure/reagent_dispensers/Initialize()
|
||||
var/datum/reagents/R = new/datum/reagents(5000)
|
||||
reagents = R
|
||||
R.my_atom = src
|
||||
if (!possible_transfer_amounts)
|
||||
src.verbs -= /obj/structure/reagent_dispensers/verb/set_APTFT
|
||||
|
||||
InputSocket = new(src)
|
||||
InputSocket.carrier = src
|
||||
OutputSocket = new(src)
|
||||
OutputSocket.carrier = src
|
||||
|
||||
. = ..()
|
||||
|
||||
/obj/structure/reagent_dispensers/examine(mob/user)
|
||||
. = ..()
|
||||
if(get_dist(user, src) <= 2)
|
||||
. += "<span class='notice'>It contains:</span>"
|
||||
if(reagents && reagents.reagent_list.len)
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
. += "<span class='notice'>[R.volume] units of [R.name]</span>"
|
||||
else
|
||||
. += "<span class='notice'>Nothing.</span>"
|
||||
|
||||
/obj/structure/reagent_dispensers/verb/set_APTFT() //set amount_per_transfer_from_this
|
||||
set name = "Set transfer amount"
|
||||
set category = "Object"
|
||||
set src in view(1)
|
||||
var/N = input("Amount per transfer from this:","[src]") as null|anything in possible_transfer_amounts
|
||||
if (N)
|
||||
amount_per_transfer_from_this = N
|
||||
|
||||
/obj/structure/reagent_dispensers/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1.0)
|
||||
qdel(src)
|
||||
return
|
||||
if(2.0)
|
||||
if (prob(50))
|
||||
new /obj/effect/effect/water(src.loc)
|
||||
qdel(src)
|
||||
return
|
||||
if(3.0)
|
||||
if (prob(5))
|
||||
new /obj/effect/effect/water(src.loc)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
/obj/structure/reagent_dispensers/blob_act()
|
||||
qdel(src)
|
||||
|
||||
|
||||
|
||||
//Dispensers
|
||||
/obj/structure/reagent_dispensers/watertank
|
||||
name = "watertank"
|
||||
desc = "A watertank."
|
||||
icon = 'icons/obj/objects_vr.dmi' //VOREStation Edit
|
||||
icon_state = "watertank"
|
||||
amount_per_transfer_from_this = 10
|
||||
|
||||
/obj/structure/reagent_dispensers/watertank/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("water", 1000)
|
||||
|
||||
/obj/structure/reagent_dispensers/watertank/high
|
||||
name = "high-capacity water tank"
|
||||
desc = "A highly-pressurized water tank made to hold vast amounts of water.."
|
||||
icon_state = "watertank_high"
|
||||
|
||||
/obj/structure/reagent_dispensers/watertank/high/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("water", 4000)
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank
|
||||
name = "fueltank"
|
||||
desc = "A fueltank."
|
||||
icon = 'icons/obj/objects_vr.dmi' //VOREStation Edit
|
||||
icon_state = "weldtank"
|
||||
amount_per_transfer_from_this = 10
|
||||
var/modded = 0
|
||||
var/obj/item/device/assembly_holder/rig = null
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("fuel",1000)
|
||||
|
||||
//VOREStation Add
|
||||
/obj/structure/reagent_dispensers/fueltank/high
|
||||
name = "high-capacity fuel tank"
|
||||
desc = "A highly-pressurized fuel tank made to hold vast amounts of fuel."
|
||||
icon_state = "weldtank_high"
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/high/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("fuel",4000)
|
||||
|
||||
/obj/structure/reagent_dispensers/foam
|
||||
name = "foamtank"
|
||||
desc = "A foam tank."
|
||||
icon = 'icons/obj/objects_vr.dmi' //VOREStation Edit
|
||||
icon_state = "foamtank"
|
||||
amount_per_transfer_from_this = 10
|
||||
|
||||
/obj/structure/reagent_dispensers/foam/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("firefoam",1000)
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/barrel
|
||||
name = "hazardous barrel"
|
||||
desc = "An open-topped barrel full of nasty-looking liquid."
|
||||
icon_state = "barrel"
|
||||
modded = TRUE
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/barrel/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (W.is_wrench()) //can't wrench it shut, it's always open
|
||||
return
|
||||
return ..()
|
||||
|
||||
//VOREStation Add End
|
||||
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/examine(mob/user)
|
||||
. = ..()
|
||||
if(get_dist(user, src) <= 2)
|
||||
if(modded)
|
||||
. += "<span class='warning'>Fuel faucet is wrenched open, leaking the fuel!</span>"
|
||||
if(rig)
|
||||
. += "<span class='notice'>There is some kind of device rigged to the tank.</span>"
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/attack_hand()
|
||||
if (rig)
|
||||
usr.visible_message("[usr] begins to detach [rig] from \the [src].", "You begin to detach [rig] from \the [src]")
|
||||
if(do_after(usr, 20))
|
||||
usr.visible_message("<span class='notice'>[usr] detaches [rig] from \the [src].</span>", "<span class='notice'>You detach [rig] from \the [src]</span>")
|
||||
rig.loc = get_turf(usr)
|
||||
rig = null
|
||||
overlays = new/list()
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
src.add_fingerprint(user)
|
||||
if (W.is_wrench())
|
||||
user.visible_message("[user] wrenches [src]'s faucet [modded ? "closed" : "open"].", \
|
||||
"You wrench [src]'s faucet [modded ? "closed" : "open"]")
|
||||
modded = modded ? 0 : 1
|
||||
playsound(src, W.usesound, 75, 1)
|
||||
if (modded)
|
||||
message_admins("[key_name_admin(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[loc.x];Y=[loc.y];Z=[loc.z]'>JMP</a>)")
|
||||
log_game("[key_name(user)] opened fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]), leaking fuel.")
|
||||
leak_fuel(amount_per_transfer_from_this)
|
||||
if (istype(W,/obj/item/device/assembly_holder))
|
||||
if (rig)
|
||||
to_chat(user, "<span class='warning'>There is another device in the way.</span>")
|
||||
return ..()
|
||||
user.visible_message("[user] begins rigging [W] to \the [src].", "You begin rigging [W] to \the [src]")
|
||||
if(do_after(user, 20))
|
||||
user.visible_message("<span class='notice'>[user] rigs [W] to \the [src].</span>", "<span class='notice'>You rig [W] to \the [src]</span>")
|
||||
|
||||
var/obj/item/device/assembly_holder/H = W
|
||||
if (istype(H.a_left,/obj/item/device/assembly/igniter) || istype(H.a_right,/obj/item/device/assembly/igniter))
|
||||
message_admins("[key_name_admin(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion. (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[loc.x];Y=[loc.y];Z=[loc.z]'>JMP</a>)")
|
||||
log_game("[key_name(user)] rigged fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) for explosion.")
|
||||
|
||||
rig = W
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
|
||||
var/icon/test = getFlatIcon(W)
|
||||
test.Shift(NORTH,1)
|
||||
test.Shift(EAST,6)
|
||||
overlays += test
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(Proj.get_structure_damage())
|
||||
if(istype(Proj.firer))
|
||||
message_admins("[key_name_admin(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]) (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[loc.x];Y=[loc.y];Z=[loc.z]'>JMP</a>).")
|
||||
log_game("[key_name(Proj.firer)] shot fueltank at [loc.loc.name] ([loc.x],[loc.y],[loc.z]).")
|
||||
|
||||
if(!istype(Proj ,/obj/item/projectile/beam/lasertag) && !istype(Proj ,/obj/item/projectile/beam/practice) )
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/ex_act()
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/blob_act()
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/proc/explode()
|
||||
if (reagents.total_volume > 500)
|
||||
explosion(src.loc,1,2,4)
|
||||
else if (reagents.total_volume > 100)
|
||||
explosion(src.loc,0,1,3)
|
||||
else if (reagents.total_volume > 50)
|
||||
explosion(src.loc,-1,1,2)
|
||||
if(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume)
|
||||
if (modded)
|
||||
explode()
|
||||
else if (temperature > T0C+500)
|
||||
explode()
|
||||
return ..()
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/Move()
|
||||
if (..() && modded)
|
||||
leak_fuel(amount_per_transfer_from_this/10.0)
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/proc/leak_fuel(amount)
|
||||
if (reagents.total_volume == 0)
|
||||
return
|
||||
|
||||
amount = min(amount, reagents.total_volume)
|
||||
reagents.remove_reagent("fuel",amount)
|
||||
new /obj/effect/decal/cleanable/liquid_fuel(src.loc, amount,1)
|
||||
|
||||
/obj/structure/reagent_dispensers/peppertank
|
||||
name = "Pepper Spray Refiller"
|
||||
desc = "Refills pepper spray canisters."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "peppertank"
|
||||
anchored = 1
|
||||
density = 0
|
||||
amount_per_transfer_from_this = 45
|
||||
|
||||
/obj/structure/reagent_dispensers/peppertank/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("condensedcapsaicin",1000)
|
||||
|
||||
|
||||
/obj/structure/reagent_dispensers/water_cooler
|
||||
name = "Water-Cooler"
|
||||
desc = "A machine that dispenses water to drink."
|
||||
amount_per_transfer_from_this = 5
|
||||
icon = 'icons/obj/vending.dmi'
|
||||
icon_state = "water_cooler"
|
||||
possible_transfer_amounts = null
|
||||
anchored = 1
|
||||
var/bottle = 0
|
||||
var/cups = 0
|
||||
var/cupholder = 0
|
||||
|
||||
/obj/structure/reagent_dispensers/water_cooler/full
|
||||
bottle = 1
|
||||
cupholder = 1
|
||||
cups = 10
|
||||
|
||||
/obj/structure/reagent_dispensers/water_cooler/Initialize()
|
||||
. = ..()
|
||||
if(bottle)
|
||||
reagents.add_reagent("water",120)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/reagent_dispensers/water_cooler/examine(mob/user)
|
||||
. = ..()
|
||||
if(cupholder)
|
||||
. += "<span class='notice'>There are [cups] cups in the cup dispenser.</span>"
|
||||
|
||||
/obj/structure/reagent_dispensers/water_cooler/verb/rotate_clockwise()
|
||||
set name = "Rotate Cooler Clockwise"
|
||||
set category = "Object"
|
||||
set src in oview(1)
|
||||
|
||||
if (src.anchored || usr:stat)
|
||||
to_chat(usr, "It is fastened to the floor!")
|
||||
return 0
|
||||
src.set_dir(turn(src.dir, 270))
|
||||
return 1
|
||||
|
||||
/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/I as obj, mob/user as mob)
|
||||
if(I.is_wrench())
|
||||
src.add_fingerprint(user)
|
||||
if(bottle)
|
||||
playsound(src, I.usesound, 50, 1)
|
||||
if(do_after(user, 20) && bottle)
|
||||
to_chat(user, "<span class='notice'>You unfasten the jug.</span>")
|
||||
var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = new /obj/item/weapon/reagent_containers/glass/cooler_bottle( src.loc )
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
var/total_reagent = reagents.get_reagent_amount(R.id)
|
||||
G.reagents.add_reagent(R.id, total_reagent)
|
||||
reagents.clear_reagents()
|
||||
bottle = 0
|
||||
update_icon()
|
||||
else
|
||||
if(anchored)
|
||||
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
|
||||
else
|
||||
user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
|
||||
if(do_after(user, 20 * I.toolspeed, src))
|
||||
if(!src) return
|
||||
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
|
||||
anchored = !anchored
|
||||
playsound(src, I.usesound, 50, 1)
|
||||
return
|
||||
|
||||
if(I.is_screwdriver())
|
||||
if(cupholder)
|
||||
playsound(src, I.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You take the cup dispenser off.</span>")
|
||||
new /obj/item/stack/material/plastic( src.loc )
|
||||
if(cups)
|
||||
for(var/i = 0 to cups)
|
||||
new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc)
|
||||
cups = 0
|
||||
cupholder = 0
|
||||
update_icon()
|
||||
return
|
||||
if(!bottle && !cupholder)
|
||||
playsound(src, I.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You start taking the water-cooler apart.</span>")
|
||||
if(do_after(user, 20 * I.toolspeed) && !bottle && !cupholder)
|
||||
to_chat(user, "<span class='notice'>You take the water-cooler apart.</span>")
|
||||
new /obj/item/stack/material/plastic( src.loc, 4 )
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
if(istype(I, /obj/item/weapon/reagent_containers/glass/cooler_bottle))
|
||||
src.add_fingerprint(user)
|
||||
if(!bottle)
|
||||
if(anchored)
|
||||
var/obj/item/weapon/reagent_containers/glass/cooler_bottle/G = I
|
||||
to_chat(user, "<span class='notice'>You start to screw the bottle onto the water-cooler.</span>")
|
||||
if(do_after(user, 20) && !bottle && anchored)
|
||||
bottle = 1
|
||||
update_icon()
|
||||
to_chat(user, "<span class='notice'>You screw the bottle onto the water-cooler!</span>")
|
||||
for(var/datum/reagent/R in G.reagents.reagent_list)
|
||||
var/total_reagent = G.reagents.get_reagent_amount(R.id)
|
||||
reagents.add_reagent(R.id, total_reagent)
|
||||
qdel(G)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to wrench down the cooler first.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There is already a bottle there!</span>")
|
||||
return 1
|
||||
|
||||
if(istype(I, /obj/item/stack/material/plastic))
|
||||
if(!cupholder)
|
||||
if(anchored)
|
||||
var/obj/item/stack/material/plastic/P = I
|
||||
src.add_fingerprint(user)
|
||||
to_chat(user, "<span class='notice'>You start to attach a cup dispenser onto the water-cooler.</span>")
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
if(do_after(user, 20) && !cupholder && anchored)
|
||||
if (P.use(1))
|
||||
to_chat(user, "<span class='notice'>You attach a cup dispenser onto the water-cooler.</span>")
|
||||
cupholder = 1
|
||||
update_icon()
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need to wrench down the cooler first.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>There is already a cup dispenser there!</span>")
|
||||
return
|
||||
|
||||
/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/user)
|
||||
if(cups)
|
||||
new /obj/item/weapon/reagent_containers/food/drinks/sillycup(src.loc)
|
||||
cups--
|
||||
flick("[icon_state]-vend", src)
|
||||
return
|
||||
|
||||
/obj/structure/reagent_dispensers/water_cooler/update_icon()
|
||||
icon_state = "water_cooler"
|
||||
overlays.Cut()
|
||||
var/image/I
|
||||
if(bottle)
|
||||
I = image(icon, "water_cooler_bottle")
|
||||
overlays += I
|
||||
return
|
||||
|
||||
/obj/structure/reagent_dispensers/beerkeg
|
||||
name = "beer keg"
|
||||
desc = "A beer keg."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "beertankTEMP"
|
||||
amount_per_transfer_from_this = 10
|
||||
|
||||
/obj/structure/reagent_dispensers/beerkeg/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("beer",1000)
|
||||
|
||||
obj/structure/reagent_dispensers/beerkeg/vat
|
||||
name = "Beer vat"
|
||||
desc = "A vat of beer."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "vat"
|
||||
amount_per_transfer_from_this = 15
|
||||
anchored = 1
|
||||
/obj/structure/reagent_dispensers/winevat
|
||||
name = "Wine vat"
|
||||
desc = "A vat of wine."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "vat"
|
||||
amount_per_transfer_from_this = 10
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/reagent_dispensers/winevat/Initialize()
|
||||
..()
|
||||
reagents.add_reagent("wine",1000)
|
||||
|
||||
|
||||
/obj/structure/reagent_dispensers/beerkeg/fakenuke
|
||||
name = "nuclear beer keg"
|
||||
desc = "A beer keg in the form of a nuclear bomb! An absolute blast at parties!"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "nuclearbomb0"
|
||||
|
||||
/obj/structure/reagent_dispensers/virusfood
|
||||
name = "Virus Food Dispenser"
|
||||
desc = "A dispenser of virus food. Yum."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "virusfoodtank"
|
||||
amount_per_transfer_from_this = 10
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/reagent_dispensers/virusfood/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("virusfood", 1000)
|
||||
|
||||
/obj/structure/reagent_dispensers/acid
|
||||
name = "Sulphuric Acid Dispenser"
|
||||
desc = "A dispenser of acid for industrial processes."
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "acidtank"
|
||||
amount_per_transfer_from_this = 10
|
||||
anchored = 1
|
||||
|
||||
/obj/structure/reagent_dispensers/acid/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("sacid", 1000)
|
||||
|
||||
//Cooking oil refill tank
|
||||
/obj/structure/reagent_dispensers/cookingoil
|
||||
name = "cooking oil tank"
|
||||
desc = "A fifty-litre tank of commercial-grade corn oil, intended for use in large scale deep fryers. Store in a cool, dark place"
|
||||
icon = 'icons/obj/objects.dmi'
|
||||
icon_state = "oiltank"
|
||||
amount_per_transfer_from_this = 120
|
||||
|
||||
/obj/structure/reagent_dispensers/cookingoil/New()
|
||||
..()
|
||||
reagents.add_reagent("cornoil",5000)
|
||||
|
||||
/obj/structure/reagent_dispensers/cookingoil/bullet_act(var/obj/item/projectile/Proj)
|
||||
if(Proj.get_structure_damage())
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/cookingoil/ex_act()
|
||||
explode()
|
||||
|
||||
/obj/structure/reagent_dispensers/cookingoil/proc/explode()
|
||||
reagents.splash_area(get_turf(src), 3)
|
||||
visible_message(span("danger", "The [src] bursts open, spreading oil all over the area."))
|
||||
qdel(src)
|
||||
728
code/modules/reagents/reagents/_reagents.dm
Normal file
728
code/modules/reagents/reagents/_reagents.dm
Normal file
@@ -0,0 +1,728 @@
|
||||
<<<<<<< HEAD:code/modules/reagents/Chemistry-Reagents.dm
|
||||
|
||||
|
||||
|
||||
/datum/reagent
|
||||
var/name = "Reagent"
|
||||
var/id = "reagent"
|
||||
var/description = "A non-descript chemical."
|
||||
var/taste_description = "bitterness"
|
||||
var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable
|
||||
var/datum/reagents/holder = null
|
||||
var/reagent_state = SOLID
|
||||
var/list/data = null
|
||||
var/volume = 0
|
||||
var/metabolism = REM // This would be 0.2 normally
|
||||
var/list/filtered_organs = list() // Organs that will slow the processing of this chemical.
|
||||
var/mrate_static = FALSE //If the reagent should always process at the same speed, regardless of species, make this TRUE
|
||||
var/ingest_met = 0
|
||||
var/touch_met = 0
|
||||
var/dose = 0
|
||||
var/max_dose = 0
|
||||
var/overdose = 0 //Amount at which overdose starts
|
||||
var/overdose_mod = 1 //Modifier to overdose damage
|
||||
var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch?
|
||||
var/scannable = 0 // Shows up on health analyzers.
|
||||
|
||||
var/affects_dead = 0 // Does this chem process inside a corpse?
|
||||
var/affects_robots = 0 // Does this chem process inside a Synth?
|
||||
|
||||
var/allergen_type = GENERIC // What potential allergens does this contain?
|
||||
var/allergen_factor = 1 // If the potential allergens are mixed and low-volume, they're a bit less dangerous. Needed for drinks because they're a single reagent compared to food which contains multiple seperate reagents.
|
||||
|
||||
var/cup_icon_state = null
|
||||
var/cup_name = null
|
||||
var/cup_desc = null
|
||||
var/cup_center_of_mass = null
|
||||
|
||||
var/color = "#000000"
|
||||
var/color_weight = 1
|
||||
|
||||
var/glass_icon = DRINK_ICON_DEFAULT
|
||||
var/glass_name = "something"
|
||||
var/glass_desc = "It's a glass of... what, exactly?"
|
||||
var/list/glass_special = null // null equivalent to list()
|
||||
|
||||
/datum/reagent/proc/remove_self(var/amount) // Shortcut
|
||||
if(holder)
|
||||
holder.remove_reagent(id, amount)
|
||||
|
||||
// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing.
|
||||
/datum/reagent/proc/touch_mob(var/mob/M, var/amount)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc
|
||||
return
|
||||
|
||||
/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here
|
||||
return
|
||||
|
||||
/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob.
|
||||
if(!istype(M))
|
||||
return
|
||||
if(!affects_dead && M.stat == DEAD)
|
||||
return
|
||||
if(!affects_robots && M.isSynthetic())
|
||||
return
|
||||
if(!istype(location))
|
||||
return
|
||||
|
||||
var/datum/reagents/metabolism/active_metab = location
|
||||
var/removed = metabolism
|
||||
|
||||
var/ingest_rem_mult = 1
|
||||
var/ingest_abs_mult = 1
|
||||
|
||||
if(!mrate_static == TRUE)
|
||||
// Modifiers
|
||||
for(var/datum/modifier/mod in M.modifiers)
|
||||
if(!isnull(mod.metabolism_percent))
|
||||
removed *= mod.metabolism_percent
|
||||
ingest_rem_mult *= mod.metabolism_percent
|
||||
// Species
|
||||
removed *= M.species.metabolic_rate
|
||||
ingest_rem_mult *= M.species.metabolic_rate
|
||||
// Metabolism
|
||||
removed *= active_metab.metabolism_speed
|
||||
ingest_rem_mult *= active_metab.metabolism_speed
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.isSynthetic())
|
||||
if(H.species.has_organ[O_HEART] && (active_metab.metabolism_class == CHEM_BLOOD))
|
||||
var/obj/item/organ/internal/heart/Pump = H.internal_organs_by_name[O_HEART]
|
||||
if(!Pump)
|
||||
removed *= 0.1
|
||||
else if(Pump.standard_pulse_level == PULSE_NONE) // No pulse normally means chemicals process a little bit slower than normal.
|
||||
removed *= 0.8
|
||||
else // Otherwise, chemicals process as per percentage of your current pulse, or, if you have no pulse but are alive, by a miniscule amount.
|
||||
removed *= max(0.1, H.pulse / Pump.standard_pulse_level)
|
||||
|
||||
if(H.species.has_organ[O_STOMACH] && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
var/obj/item/organ/internal/stomach/Chamber = H.internal_organs_by_name[O_STOMACH]
|
||||
if(Chamber)
|
||||
ingest_rem_mult *= max(0.1, 1 - (Chamber.damage / Chamber.max_damage))
|
||||
else
|
||||
ingest_rem_mult = 0.1
|
||||
|
||||
if(H.species.has_organ[O_INTESTINE] && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
var/obj/item/organ/internal/intestine/Tube = H.internal_organs_by_name[O_INTESTINE]
|
||||
if(Tube)
|
||||
ingest_abs_mult *= max(0.1, 1 - (Tube.damage / Tube.max_damage))
|
||||
else
|
||||
ingest_abs_mult = 0.1
|
||||
|
||||
else
|
||||
var/obj/item/organ/internal/heart/machine/Pump = H.internal_organs_by_name[O_PUMP]
|
||||
var/obj/item/organ/internal/stomach/machine/Cycler = H.internal_organs_by_name[O_CYCLER]
|
||||
|
||||
if(active_metab.metabolism_class == CHEM_BLOOD)
|
||||
if(Pump)
|
||||
removed *= 1.1 - Pump.damage / Pump.max_damage
|
||||
else
|
||||
removed *= 0.1
|
||||
|
||||
else if(active_metab.metabolism_class == CHEM_INGEST) // If the pump is damaged, we waste chems from the tank.
|
||||
if(Pump)
|
||||
ingest_abs_mult *= max(0.25, 1 - Pump.damage / Pump.max_damage)
|
||||
|
||||
else
|
||||
ingest_abs_mult *= 0.2
|
||||
|
||||
if(Cycler) // If we're damaged, we empty our tank slower.
|
||||
ingest_rem_mult = max(0.1, 1 - (Cycler.damage / Cycler.max_damage))
|
||||
|
||||
else
|
||||
ingest_rem_mult = 0.1
|
||||
|
||||
else if(active_metab.metabolism_class == CHEM_TOUCH) // Machines don't exactly absorb chemicals.
|
||||
removed *= 0.5
|
||||
|
||||
if(filtered_organs && filtered_organs.len)
|
||||
for(var/organ_tag in filtered_organs)
|
||||
var/obj/item/organ/internal/O = H.internal_organs_by_name[organ_tag]
|
||||
if(O && !O.is_broken() && prob(max(0, O.max_damage - O.damage)))
|
||||
removed *= 0.8
|
||||
if(active_metab.metabolism_class == CHEM_INGEST)
|
||||
ingest_rem_mult *= 0.8
|
||||
|
||||
if(ingest_met && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
removed = ingest_met * ingest_rem_mult
|
||||
if(touch_met && (active_metab.metabolism_class == CHEM_TOUCH))
|
||||
removed = touch_met
|
||||
removed = min(removed, volume)
|
||||
max_dose = max(volume, max_dose)
|
||||
dose = min(dose + removed, max_dose)
|
||||
if(removed >= (metabolism * 0.1) || removed >= 0.1) // If there's too little chemical, don't affect the mob, just remove it
|
||||
switch(active_metab.metabolism_class)
|
||||
if(CHEM_BLOOD)
|
||||
affect_blood(M, alien, removed)
|
||||
if(CHEM_INGEST)
|
||||
affect_ingest(M, alien, removed * ingest_abs_mult)
|
||||
if(CHEM_TOUCH)
|
||||
affect_touch(M, alien, removed)
|
||||
if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH && !can_overdose_touch))
|
||||
overdose(M, alien, removed)
|
||||
if(M.species.allergens & allergen_type) //uhoh, we can't handle this!
|
||||
var/damage_severity = M.species.allergen_damage_severity*allergen_factor
|
||||
var/disable_severity = M.species.allergen_disable_severity*allergen_factor
|
||||
if(M.species.allergen_reaction & AG_TOX_DMG)
|
||||
M.adjustToxLoss(damage_severity)
|
||||
if(M.species.allergen_reaction & AG_OXY_DMG)
|
||||
M.adjustOxyLoss(damage_severity)
|
||||
if(prob(2.5*disable_severity))
|
||||
M.emote(pick("cough","gasp","choke"))
|
||||
if(M.species.allergen_reaction & AG_EMOTE)
|
||||
if(prob(2.5*disable_severity)) //this has a higher base chance, but not *too* high
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
if(M.species.allergen_reaction & AG_PAIN)
|
||||
M.adjustHalLoss(disable_severity)
|
||||
if(M.species.allergen_reaction & AG_WEAKEN)
|
||||
M.Weaken(disable_severity)
|
||||
if(M.species.allergen_reaction & AG_BLURRY)
|
||||
M.eye_blurry = max(M.eye_blurry, disable_severity)
|
||||
if(M.species.allergen_reaction & AG_SLEEPY)
|
||||
M.drowsyness = max(M.drowsyness, disable_severity)
|
||||
remove_self(removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
M.bloodstr.add_reagent(id, removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect.
|
||||
if(alien == IS_DIONA)
|
||||
return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
overdose_mod *= H.species.chemOD_mod
|
||||
// 6 damage per unit at minimum, scales with excessive reagents. Rounding should help keep damage consistent between ingest / inject, but isn't perfect.
|
||||
// Hardcapped at 3.6 damage per tick, or 18 damage per unit at 0.2 metabolic rate so that you can't instakill people with overdoses by feeding them infinite periadaxon.
|
||||
// Overall, max damage is slightly less effective than hydrophoron, and 1/5 as effective as cyanide.
|
||||
M.adjustToxLoss(min(removed * overdose_mod * round(3 + 3 * volume / overdose), 3.6))
|
||||
|
||||
/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created.
|
||||
if(!isnull(newdata))
|
||||
data = newdata
|
||||
return
|
||||
|
||||
/datum/reagent/proc/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that?
|
||||
return
|
||||
|
||||
/datum/reagent/proc/get_data() // Just in case you have a reagent that handles data differently.
|
||||
if(data && istype(data, /list))
|
||||
return data.Copy()
|
||||
else if(data)
|
||||
return data
|
||||
return null
|
||||
|
||||
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
|
||||
holder = null
|
||||
. = ..()
|
||||
|
||||
// Called when reagents are removed from a container, most likely after metabolizing in a mob
|
||||
/datum/reagent/proc/on_remove(var/atom/A)
|
||||
return
|
||||
|
||||
// Called when a mob dies
|
||||
/datum/reagent/proc/on_mob_death(var/mob/M)
|
||||
return
|
||||
|
||||
//on transfer to new container, return 1 to allow it to continue
|
||||
/datum/reagent/proc/on_transfer(var/volume)
|
||||
return 1
|
||||
|
||||
/* DEPRECATED - TODO: REMOVE EVERYWHERE */
|
||||
|
||||
/datum/reagent/proc/reaction_turf(var/turf/target)
|
||||
touch_turf(target)
|
||||
|
||||
/datum/reagent/proc/reaction_obj(var/obj/target)
|
||||
touch_obj(target)
|
||||
|
||||
/datum/reagent/proc/reaction_mob(var/mob/target)
|
||||
touch_mob(target)
|
||||
|
||||
||||||| parent of 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013:code/modules/reagents/Chemistry-Reagents.dm
|
||||
|
||||
|
||||
|
||||
/datum/reagent
|
||||
var/name = "Reagent"
|
||||
var/id = "reagent"
|
||||
var/description = "A non-descript chemical."
|
||||
var/taste_description = "bitterness"
|
||||
var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable
|
||||
var/datum/reagents/holder = null
|
||||
var/reagent_state = SOLID
|
||||
var/list/data = null
|
||||
var/volume = 0
|
||||
var/metabolism = REM // This would be 0.2 normally
|
||||
var/list/filtered_organs = list() // Organs that will slow the processing of this chemical.
|
||||
var/mrate_static = FALSE //If the reagent should always process at the same speed, regardless of species, make this TRUE
|
||||
var/ingest_met = 0
|
||||
var/touch_met = 0
|
||||
var/dose = 0
|
||||
var/max_dose = 0
|
||||
var/overdose = 0 //Amount at which overdose starts
|
||||
var/overdose_mod = 1 //Modifier to overdose damage
|
||||
var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch?
|
||||
var/scannable = 0 // Shows up on health analyzers.
|
||||
|
||||
var/affects_dead = 0 // Does this chem process inside a corpse?
|
||||
var/affects_robots = 0 // Does this chem process inside a Synth?
|
||||
|
||||
var/allergen_type = GENERIC // What potential allergens does this contain?
|
||||
var/allergen_factor = 1 // If the potential allergens are mixed and low-volume, they're a bit less dangerous. Needed for drinks because they're a single reagent compared to food which contains multiple seperate reagents.
|
||||
|
||||
var/cup_icon_state = null
|
||||
var/cup_name = null
|
||||
var/cup_desc = null
|
||||
var/cup_center_of_mass = null
|
||||
|
||||
var/color = "#000000"
|
||||
var/color_weight = 1
|
||||
|
||||
var/glass_icon = DRINK_ICON_DEFAULT
|
||||
var/glass_name = "something"
|
||||
var/glass_desc = "It's a glass of... what, exactly?"
|
||||
var/list/glass_special = null // null equivalent to list()
|
||||
|
||||
/datum/reagent/proc/remove_self(var/amount) // Shortcut
|
||||
if(holder)
|
||||
holder.remove_reagent(id, amount)
|
||||
|
||||
// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing.
|
||||
/datum/reagent/proc/touch_mob(var/mob/M, var/amount)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc
|
||||
return
|
||||
|
||||
/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here
|
||||
return
|
||||
|
||||
/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob.
|
||||
if(!istype(M))
|
||||
return
|
||||
if(!affects_dead && M.stat == DEAD)
|
||||
return
|
||||
if(!affects_robots && M.isSynthetic())
|
||||
return
|
||||
if(!istype(location))
|
||||
return
|
||||
|
||||
var/datum/reagents/metabolism/active_metab = location
|
||||
var/removed = metabolism
|
||||
|
||||
var/ingest_rem_mult = 1
|
||||
var/ingest_abs_mult = 1
|
||||
|
||||
if(!mrate_static == TRUE)
|
||||
// Modifiers
|
||||
for(var/datum/modifier/mod in M.modifiers)
|
||||
if(!isnull(mod.metabolism_percent))
|
||||
removed *= mod.metabolism_percent
|
||||
ingest_rem_mult *= mod.metabolism_percent
|
||||
// Species
|
||||
removed *= M.species.metabolic_rate
|
||||
ingest_rem_mult *= M.species.metabolic_rate
|
||||
// Metabolism
|
||||
removed *= active_metab.metabolism_speed
|
||||
ingest_rem_mult *= active_metab.metabolism_speed
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.isSynthetic())
|
||||
if(H.species.has_organ[O_HEART] && (active_metab.metabolism_class == CHEM_BLOOD))
|
||||
var/obj/item/organ/internal/heart/Pump = H.internal_organs_by_name[O_HEART]
|
||||
if(!Pump)
|
||||
removed *= 0.1
|
||||
else if(Pump.standard_pulse_level == PULSE_NONE) // No pulse normally means chemicals process a little bit slower than normal.
|
||||
removed *= 0.8
|
||||
else // Otherwise, chemicals process as per percentage of your current pulse, or, if you have no pulse but are alive, by a miniscule amount.
|
||||
removed *= max(0.1, H.pulse / Pump.standard_pulse_level)
|
||||
|
||||
if(H.species.has_organ[O_STOMACH] && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
var/obj/item/organ/internal/stomach/Chamber = H.internal_organs_by_name[O_STOMACH]
|
||||
if(Chamber)
|
||||
ingest_rem_mult *= max(0.1, 1 - (Chamber.damage / Chamber.max_damage))
|
||||
else
|
||||
ingest_rem_mult = 0.1
|
||||
|
||||
if(H.species.has_organ[O_INTESTINE] && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
var/obj/item/organ/internal/intestine/Tube = H.internal_organs_by_name[O_INTESTINE]
|
||||
if(Tube)
|
||||
ingest_abs_mult *= max(0.1, 1 - (Tube.damage / Tube.max_damage))
|
||||
else
|
||||
ingest_abs_mult = 0.1
|
||||
|
||||
else
|
||||
var/obj/item/organ/internal/heart/machine/Pump = H.internal_organs_by_name[O_PUMP]
|
||||
var/obj/item/organ/internal/stomach/machine/Cycler = H.internal_organs_by_name[O_CYCLER]
|
||||
|
||||
if(active_metab.metabolism_class == CHEM_BLOOD)
|
||||
if(Pump)
|
||||
removed *= 1.1 - Pump.damage / Pump.max_damage
|
||||
else
|
||||
removed *= 0.1
|
||||
|
||||
else if(active_metab.metabolism_class == CHEM_INGEST) // If the pump is damaged, we waste chems from the tank.
|
||||
if(Pump)
|
||||
ingest_abs_mult *= max(0.25, 1 - Pump.damage / Pump.max_damage)
|
||||
|
||||
else
|
||||
ingest_abs_mult *= 0.2
|
||||
|
||||
if(Cycler) // If we're damaged, we empty our tank slower.
|
||||
ingest_rem_mult = max(0.1, 1 - (Cycler.damage / Cycler.max_damage))
|
||||
|
||||
else
|
||||
ingest_rem_mult = 0.1
|
||||
|
||||
else if(active_metab.metabolism_class == CHEM_TOUCH) // Machines don't exactly absorb chemicals.
|
||||
removed *= 0.5
|
||||
|
||||
if(filtered_organs && filtered_organs.len)
|
||||
for(var/organ_tag in filtered_organs)
|
||||
var/obj/item/organ/internal/O = H.internal_organs_by_name[organ_tag]
|
||||
if(O && !O.is_broken() && prob(max(0, O.max_damage - O.damage)))
|
||||
removed *= 0.8
|
||||
if(active_metab.metabolism_class == CHEM_INGEST)
|
||||
ingest_rem_mult *= 0.8
|
||||
|
||||
if(ingest_met && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
removed = ingest_met * ingest_rem_mult
|
||||
if(touch_met && (active_metab.metabolism_class == CHEM_TOUCH))
|
||||
removed = touch_met
|
||||
removed = min(removed, volume)
|
||||
max_dose = max(volume, max_dose)
|
||||
dose = min(dose + removed, max_dose)
|
||||
if(removed >= (metabolism * 0.1) || removed >= 0.1) // If there's too little chemical, don't affect the mob, just remove it
|
||||
switch(active_metab.metabolism_class)
|
||||
if(CHEM_BLOOD)
|
||||
affect_blood(M, alien, removed)
|
||||
if(CHEM_INGEST)
|
||||
affect_ingest(M, alien, removed * ingest_abs_mult)
|
||||
if(CHEM_TOUCH)
|
||||
affect_touch(M, alien, removed)
|
||||
if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH && !can_overdose_touch))
|
||||
overdose(M, alien, removed)
|
||||
if(M.species.allergens & allergen_type) //uhoh, we can't handle this!
|
||||
var/damage_severity = M.species.allergen_damage_severity*allergen_factor
|
||||
var/disable_severity = M.species.allergen_disable_severity*allergen_factor
|
||||
if(M.species.allergen_reaction & AG_TOX_DMG)
|
||||
M.adjustToxLoss(damage_severity)
|
||||
if(M.species.allergen_reaction & AG_OXY_DMG)
|
||||
M.adjustOxyLoss(damage_severity)
|
||||
if(prob(2.5*disable_severity))
|
||||
M.emote(pick("cough","gasp","choke"))
|
||||
if(M.species.allergen_reaction & AG_EMOTE)
|
||||
if(prob(2.5*disable_severity)) //this has a higher base chance, but not *too* high
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
if(M.species.allergen_reaction & AG_PAIN)
|
||||
M.adjustHalLoss(disable_severity)
|
||||
if(M.species.allergen_reaction & AG_WEAKEN)
|
||||
M.Weaken(disable_severity)
|
||||
if(M.species.allergen_reaction & AG_BLURRY)
|
||||
M.eye_blurry = max(M.eye_blurry, disable_severity)
|
||||
if(M.species.allergen_reaction & AG_SLEEPY)
|
||||
M.drowsyness = max(M.drowsyness, disable_severity)
|
||||
remove_self(removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
M.bloodstr.add_reagent(id, removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect.
|
||||
if(alien == IS_DIONA)
|
||||
return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
overdose_mod *= H.species.chemOD_mod
|
||||
// 6 damage per unit at minimum, scales with excessive reagents. Rounding should help keep damage consistent between ingest / inject, but isn't perfect.
|
||||
// Hardcapped at 3.6 damage per tick, or 18 damage per unit at 0.2 metabolic rate so that you can't instakill people with overdoses by feeding them infinite periadaxon.
|
||||
// Overall, max damage is slightly less effective than hydrophoron, and 1/5 as effective as cyanide.
|
||||
M.adjustToxLoss(min(removed * overdose_mod * round(3 + 3 * volume / overdose), 3.6))
|
||||
|
||||
/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created.
|
||||
if(!isnull(newdata))
|
||||
data = newdata
|
||||
return
|
||||
|
||||
/datum/reagent/proc/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that?
|
||||
return
|
||||
|
||||
/datum/reagent/proc/get_data() // Just in case you have a reagent that handles data differently.
|
||||
if(data && istype(data, /list))
|
||||
return data.Copy()
|
||||
else if(data)
|
||||
return data
|
||||
return null
|
||||
|
||||
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
|
||||
holder = null
|
||||
. = ..()
|
||||
|
||||
/* DEPRECATED - TODO: REMOVE EVERYWHERE */
|
||||
|
||||
/datum/reagent/proc/reaction_turf(var/turf/target)
|
||||
touch_turf(target)
|
||||
|
||||
/datum/reagent/proc/reaction_obj(var/obj/target)
|
||||
touch_obj(target)
|
||||
|
||||
/datum/reagent/proc/reaction_mob(var/mob/target)
|
||||
touch_mob(target)
|
||||
=======
|
||||
|
||||
|
||||
|
||||
/datum/reagent
|
||||
var/name = "Reagent"
|
||||
var/id = "reagent"
|
||||
var/description = "A non-descript chemical."
|
||||
var/taste_description = "bitterness"
|
||||
var/taste_mult = 1 //how this taste compares to others. Higher values means it is more noticable
|
||||
var/datum/reagents/holder = null
|
||||
var/reagent_state = SOLID
|
||||
var/list/data = null
|
||||
var/volume = 0
|
||||
var/metabolism = REM // This would be 0.2 normally
|
||||
var/list/filtered_organs = list() // Organs that will slow the processing of this chemical.
|
||||
var/mrate_static = FALSE //If the reagent should always process at the same speed, regardless of species, make this TRUE
|
||||
var/ingest_met = 0
|
||||
var/touch_met = 0
|
||||
var/dose = 0
|
||||
var/max_dose = 0
|
||||
var/overdose = 0 //Amount at which overdose starts
|
||||
var/overdose_mod = 1 //Modifier to overdose damage
|
||||
var/can_overdose_touch = FALSE // Can the chemical OD when processing on touch?
|
||||
var/scannable = 0 // Shows up on health analyzers.
|
||||
|
||||
var/affects_dead = 0 // Does this chem process inside a corpse?
|
||||
var/affects_robots = 0 // Does this chem process inside a Synth?
|
||||
|
||||
var/allergen_type = GENERIC // What potential allergens does this contain?
|
||||
var/allergen_factor = 1 // If the potential allergens are mixed and low-volume, they're a bit less dangerous. Needed for drinks because they're a single reagent compared to food which contains multiple seperate reagents.
|
||||
|
||||
var/cup_icon_state = null
|
||||
var/cup_name = null
|
||||
var/cup_desc = null
|
||||
var/cup_center_of_mass = null
|
||||
|
||||
var/color = "#000000"
|
||||
var/color_weight = 1
|
||||
|
||||
var/glass_icon = DRINK_ICON_DEFAULT
|
||||
var/glass_name = "something"
|
||||
var/glass_desc = "It's a glass of... what, exactly?"
|
||||
var/list/glass_special = null // null equivalent to list()
|
||||
|
||||
/datum/reagent/proc/remove_self(var/amount) // Shortcut
|
||||
if(holder)
|
||||
holder.remove_reagent(id, amount)
|
||||
|
||||
// This doesn't apply to skin contact - this is for, e.g. extinguishers and sprays. The difference is that reagent is not directly on the mob's skin - it might just be on their clothing.
|
||||
/datum/reagent/proc/touch_mob(var/mob/M, var/amount)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/touch_obj(var/obj/O, var/amount) // Acid melting, cleaner cleaning, etc
|
||||
return
|
||||
|
||||
/datum/reagent/proc/touch_turf(var/turf/T, var/amount) // Cleaner cleaning, lube lubbing, etc, all go here
|
||||
return
|
||||
|
||||
/datum/reagent/proc/on_mob_life(var/mob/living/carbon/M, var/alien, var/datum/reagents/metabolism/location) // Currently, on_mob_life is called on carbons. Any interaction with non-carbon mobs (lube) will need to be done in touch_mob.
|
||||
if(!istype(M))
|
||||
return
|
||||
if(!affects_dead && M.stat == DEAD)
|
||||
return
|
||||
if(!affects_robots && M.isSynthetic())
|
||||
return
|
||||
if(!istype(location))
|
||||
return
|
||||
|
||||
var/datum/reagents/metabolism/active_metab = location
|
||||
var/removed = metabolism
|
||||
|
||||
var/ingest_rem_mult = 1
|
||||
var/ingest_abs_mult = 1
|
||||
|
||||
if(!mrate_static == TRUE)
|
||||
// Modifiers
|
||||
for(var/datum/modifier/mod in M.modifiers)
|
||||
if(!isnull(mod.metabolism_percent))
|
||||
removed *= mod.metabolism_percent
|
||||
ingest_rem_mult *= mod.metabolism_percent
|
||||
// Species
|
||||
removed *= M.species.metabolic_rate
|
||||
ingest_rem_mult *= M.species.metabolic_rate
|
||||
// Metabolism
|
||||
removed *= active_metab.metabolism_speed
|
||||
ingest_rem_mult *= active_metab.metabolism_speed
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(!H.isSynthetic())
|
||||
if(H.species.has_organ[O_HEART] && (active_metab.metabolism_class == CHEM_BLOOD))
|
||||
var/obj/item/organ/internal/heart/Pump = H.internal_organs_by_name[O_HEART]
|
||||
if(!Pump)
|
||||
removed *= 0.1
|
||||
else if(Pump.standard_pulse_level == PULSE_NONE) // No pulse normally means chemicals process a little bit slower than normal.
|
||||
removed *= 0.8
|
||||
else // Otherwise, chemicals process as per percentage of your current pulse, or, if you have no pulse but are alive, by a miniscule amount.
|
||||
removed *= max(0.1, H.pulse / Pump.standard_pulse_level)
|
||||
|
||||
if(H.species.has_organ[O_STOMACH] && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
var/obj/item/organ/internal/stomach/Chamber = H.internal_organs_by_name[O_STOMACH]
|
||||
if(Chamber)
|
||||
ingest_rem_mult *= max(0.1, 1 - (Chamber.damage / Chamber.max_damage))
|
||||
else
|
||||
ingest_rem_mult = 0.1
|
||||
|
||||
if(H.species.has_organ[O_INTESTINE] && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
var/obj/item/organ/internal/intestine/Tube = H.internal_organs_by_name[O_INTESTINE]
|
||||
if(Tube)
|
||||
ingest_abs_mult *= max(0.1, 1 - (Tube.damage / Tube.max_damage))
|
||||
else
|
||||
ingest_abs_mult = 0.1
|
||||
|
||||
else
|
||||
var/obj/item/organ/internal/heart/machine/Pump = H.internal_organs_by_name[O_PUMP]
|
||||
var/obj/item/organ/internal/stomach/machine/Cycler = H.internal_organs_by_name[O_CYCLER]
|
||||
|
||||
if(active_metab.metabolism_class == CHEM_BLOOD)
|
||||
if(Pump)
|
||||
removed *= 1.1 - Pump.damage / Pump.max_damage
|
||||
else
|
||||
removed *= 0.1
|
||||
|
||||
else if(active_metab.metabolism_class == CHEM_INGEST) // If the pump is damaged, we waste chems from the tank.
|
||||
if(Pump)
|
||||
ingest_abs_mult *= max(0.25, 1 - Pump.damage / Pump.max_damage)
|
||||
|
||||
else
|
||||
ingest_abs_mult *= 0.2
|
||||
|
||||
if(Cycler) // If we're damaged, we empty our tank slower.
|
||||
ingest_rem_mult = max(0.1, 1 - (Cycler.damage / Cycler.max_damage))
|
||||
|
||||
else
|
||||
ingest_rem_mult = 0.1
|
||||
|
||||
else if(active_metab.metabolism_class == CHEM_TOUCH) // Machines don't exactly absorb chemicals.
|
||||
removed *= 0.5
|
||||
|
||||
if(filtered_organs && filtered_organs.len)
|
||||
for(var/organ_tag in filtered_organs)
|
||||
var/obj/item/organ/internal/O = H.internal_organs_by_name[organ_tag]
|
||||
if(O && !O.is_broken() && prob(max(0, O.max_damage - O.damage)))
|
||||
removed *= 0.8
|
||||
if(active_metab.metabolism_class == CHEM_INGEST)
|
||||
ingest_rem_mult *= 0.8
|
||||
|
||||
if(ingest_met && (active_metab.metabolism_class == CHEM_INGEST))
|
||||
removed = ingest_met * ingest_rem_mult
|
||||
if(touch_met && (active_metab.metabolism_class == CHEM_TOUCH))
|
||||
removed = touch_met
|
||||
removed = min(removed, volume)
|
||||
max_dose = max(volume, max_dose)
|
||||
dose = min(dose + removed, max_dose)
|
||||
if(removed >= (metabolism * 0.1) || removed >= 0.1) // If there's too little chemical, don't affect the mob, just remove it
|
||||
switch(active_metab.metabolism_class)
|
||||
if(CHEM_BLOOD)
|
||||
affect_blood(M, alien, removed)
|
||||
if(CHEM_INGEST)
|
||||
affect_ingest(M, alien, removed * ingest_abs_mult)
|
||||
if(CHEM_TOUCH)
|
||||
affect_touch(M, alien, removed)
|
||||
if(overdose && (volume > overdose * M?.species.chemOD_threshold) && (active_metab.metabolism_class != CHEM_TOUCH && !can_overdose_touch))
|
||||
overdose(M, alien, removed)
|
||||
if(M.species.allergens & allergen_type) //uhoh, we can't handle this!
|
||||
var/damage_severity = M.species.allergen_damage_severity*allergen_factor
|
||||
var/disable_severity = M.species.allergen_disable_severity*allergen_factor
|
||||
if(M.species.allergen_reaction & AG_TOX_DMG)
|
||||
M.adjustToxLoss(damage_severity)
|
||||
if(M.species.allergen_reaction & AG_OXY_DMG)
|
||||
M.adjustOxyLoss(damage_severity)
|
||||
if(prob(2.5*disable_severity))
|
||||
M.emote(pick("cough","gasp","choke"))
|
||||
if(M.species.allergen_reaction & AG_EMOTE)
|
||||
if(prob(2.5*disable_severity)) //this has a higher base chance, but not *too* high
|
||||
M.emote(pick("pale","shiver","twitch"))
|
||||
if(M.species.allergen_reaction & AG_PAIN)
|
||||
M.adjustHalLoss(disable_severity)
|
||||
if(M.species.allergen_reaction & AG_WEAKEN)
|
||||
M.Weaken(disable_severity)
|
||||
if(M.species.allergen_reaction & AG_BLURRY)
|
||||
M.eye_blurry = max(M.eye_blurry, disable_severity)
|
||||
if(M.species.allergen_reaction & AG_SLEEPY)
|
||||
M.drowsyness = max(M.drowsyness, disable_severity)
|
||||
remove_self(removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
M.bloodstr.add_reagent(id, removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
return
|
||||
|
||||
/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed) // Overdose effect.
|
||||
if(alien == IS_DIONA)
|
||||
return
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
overdose_mod *= H.species.chemOD_mod
|
||||
// 6 damage per unit at minimum, scales with excessive reagents. Rounding should help keep damage consistent between ingest / inject, but isn't perfect.
|
||||
// Hardcapped at 3.6 damage per tick, or 18 damage per unit at 0.2 metabolic rate so that you can't instakill people with overdoses by feeding them infinite periadaxon.
|
||||
// Overall, max damage is slightly less effective than hydrophoron, and 1/5 as effective as cyanide.
|
||||
M.adjustToxLoss(min(removed * overdose_mod * round(3 + 3 * volume / overdose), 3.6))
|
||||
|
||||
/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created.
|
||||
if(!isnull(newdata))
|
||||
data = newdata
|
||||
return
|
||||
|
||||
/datum/reagent/proc/mix_data(var/newdata, var/newamount) // You have a reagent with data, and new reagent with its own data get added, how do you deal with that?
|
||||
return
|
||||
|
||||
/datum/reagent/proc/get_data() // Just in case you have a reagent that handles data differently.
|
||||
if(data && istype(data, /list))
|
||||
return data.Copy()
|
||||
else if(data)
|
||||
return data
|
||||
return null
|
||||
|
||||
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
|
||||
holder = null
|
||||
. = ..()
|
||||
|
||||
/* DEPRECATED - TODO: REMOVE EVERYWHERE */
|
||||
|
||||
/datum/reagent/proc/reaction_turf(var/turf/target)
|
||||
touch_turf(target)
|
||||
|
||||
/datum/reagent/proc/reaction_obj(var/obj/target)
|
||||
touch_obj(target)
|
||||
|
||||
/datum/reagent/proc/reaction_mob(var/mob/target)
|
||||
touch_mob(target)
|
||||
>>>>>>> 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013:code/modules/reagents/reagents/_reagents.dm
|
||||
@@ -238,14 +238,6 @@
|
||||
reagent_state = SOLID
|
||||
color = "#D0D0D0"
|
||||
|
||||
/datum/reagent/uranium
|
||||
name ="Uranium"
|
||||
id = "uranium"
|
||||
description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive."
|
||||
taste_description = "metal"
|
||||
reagent_state = SOLID
|
||||
color = "#B8B8C0"
|
||||
|
||||
/datum/reagent/platinum
|
||||
name = "Platinum"
|
||||
id = "platinum"
|
||||
@@ -254,6 +246,14 @@
|
||||
reagent_state = SOLID
|
||||
color = "#777777"
|
||||
|
||||
/datum/reagent/uranium
|
||||
name ="Uranium"
|
||||
id = "uranium"
|
||||
description = "A silvery-white metallic chemical element in the actinide series, weakly radioactive."
|
||||
taste_description = "metal"
|
||||
reagent_state = SOLID
|
||||
color = "#B8B8C0"
|
||||
|
||||
/datum/reagent/uranium/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
affect_ingest(M, alien, removed)
|
||||
|
||||
@@ -268,6 +268,55 @@
|
||||
new /obj/effect/decal/cleanable/greenglow(T)
|
||||
return
|
||||
|
||||
/datum/reagent/hydrogen/deuterium
|
||||
name = "Deuterium"
|
||||
id = "deuterium"
|
||||
description = "A isotope of hydrogen. It has one extra neutron, and shares all chemical characteristics with hydrogen."
|
||||
|
||||
/datum/reagent/hydrogen/tritium
|
||||
name = "Tritium"
|
||||
id = "tritium"
|
||||
description = "A radioactive isotope of hydrogen. It has two extra neutrons, and shares all other chemical characteristics with hydrogen."
|
||||
|
||||
/datum/reagent/lithium/lithium6
|
||||
name = "Lithium-6"
|
||||
id = "lithium6"
|
||||
description = "An isotope of lithium. It has 3 neutrons, but shares all chemical characteristics with regular lithium."
|
||||
|
||||
/datum/reagent/helium/helium3
|
||||
name = "Helium-3"
|
||||
id = "helium3"
|
||||
description = "An isotope of helium. It only has one neutron, but shares all chemical characteristics with regular helium."
|
||||
taste_mult = 0
|
||||
reagent_state = GAS
|
||||
color = "#808080"
|
||||
|
||||
/datum/reagent/boron/boron11
|
||||
name = "Boron-11"
|
||||
id = "boron11"
|
||||
description = "An isotope of boron. It has 6 neutrons."
|
||||
taste_description = "metallic" // Apparently noone on the internet knows what boron tastes like. Or at least they won't share
|
||||
|
||||
/datum/reagent/supermatter
|
||||
name = "Supermatter"
|
||||
id = "supermatter"
|
||||
description = "The immense power of a supermatter crystal, in liquid form. You're not entirely sure how that's possible, but it's probably best handled with care."
|
||||
taste_description = "taffy" // 0. The supermatter is tasty, tasty taffy.
|
||||
|
||||
// Same as if you boop it wrong. It touches you, you die
|
||||
/datum/reagent/supermatter/affect_touch(mob/living/carbon/M, alien, removed)
|
||||
. = ..()
|
||||
M.ash()
|
||||
|
||||
/datum/reagent/supermatter/affect_ingest(mob/living/carbon/M, alien, removed)
|
||||
. = ..()
|
||||
M.ash()
|
||||
|
||||
/datum/reagent/supermatter/affect_blood(mob/living/carbon/M, alien, removed)
|
||||
. = ..()
|
||||
M.ash()
|
||||
|
||||
|
||||
/datum/reagent/adrenaline
|
||||
name = "Adrenaline"
|
||||
id = "adrenaline"
|
||||
@@ -28,14 +28,6 @@
|
||||
BI.forceMove(torso)
|
||||
torso.implants += BI
|
||||
|
||||
/datum/chemical_reaction/slime/sapphire_mutation
|
||||
name = "Slime Mutation Toxins"
|
||||
id = "slime_mutation_tox"
|
||||
result = "mutationtoxin"
|
||||
required_reagents = list("blood" = 5)
|
||||
result_amount = 30
|
||||
required = /obj/item/slime_extract/sapphire
|
||||
|
||||
/datum/reagent/nif_repair_nanites
|
||||
name = "Programmed Nanomachines"
|
||||
id = "nifrepairnanites"
|
||||
@@ -70,10 +70,12 @@ won't update every console in existence) but it's more of a hassle to do. Also,
|
||||
return return_name
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/CallReagentName(var/ID)
|
||||
var/datum/reagent/R = SSchemistry.chemical_reagents["[ID]"]
|
||||
if(!R)
|
||||
return ID
|
||||
return R.name
|
||||
var/return_name = ID
|
||||
for(var/datum/reagent/R in SSchemistry.chemical_reagents)
|
||||
if(R.id == ID)
|
||||
return_name = R.name
|
||||
break
|
||||
return return_name
|
||||
|
||||
/obj/machinery/computer/rdconsole/proc/SyncRDevices() //Makes sure it is properly sync'ed up with the devices attached to it (if any).
|
||||
for(var/obj/machinery/r_n_d/D in range(3, src))
|
||||
|
||||
@@ -39,17 +39,17 @@
|
||||
else
|
||||
. += "This extract is inert."
|
||||
|
||||
/datum/chemical_reaction/slime
|
||||
/decl/chemical_reaction/instant/slime
|
||||
var/required = null
|
||||
|
||||
/datum/chemical_reaction/slime/can_happen(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/can_happen(var/datum/reagents/holder)
|
||||
if(holder.my_atom && istype(holder.my_atom, required))
|
||||
var/obj/item/slime_extract/T = holder.my_atom
|
||||
if(T.uses > 0)
|
||||
return ..()
|
||||
return FALSE
|
||||
|
||||
/datum/chemical_reaction/slime/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/on_reaction(var/datum/reagents/holder)
|
||||
var/obj/item/slime_extract/T = holder.my_atom
|
||||
T.uses--
|
||||
if(T.uses <= 0)
|
||||
@@ -67,7 +67,7 @@
|
||||
icon_state = "grey slime extract"
|
||||
description_info = "This extract will create a new grey baby slime if injected with phoron, or some new monkey cubes if injected with blood."
|
||||
|
||||
/datum/chemical_reaction/slime/grey_new_slime
|
||||
/decl/chemical_reaction/instant/slime/grey_new_slime
|
||||
name = "Slime Spawn"
|
||||
id = "m_spawn"
|
||||
result = null
|
||||
@@ -75,12 +75,12 @@
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/grey
|
||||
|
||||
/datum/chemical_reaction/slime/grey_new_slime/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/grey_new_slime/on_reaction(var/datum/reagents/holder)
|
||||
holder.my_atom.visible_message("<span class='warning'>Infused with phoron, the core begins to quiver and grow, and soon a new baby slime emerges from it!</span>")
|
||||
new /mob/living/simple_mob/slime/xenobio(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
/datum/chemical_reaction/slime/grey_monkey
|
||||
/decl/chemical_reaction/instant/slime/grey_monkey
|
||||
name = "Slime Monkey"
|
||||
id = "m_monkey"
|
||||
result = null
|
||||
@@ -88,12 +88,12 @@
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/grey
|
||||
|
||||
/datum/chemical_reaction/slime/grey_monkey/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/grey_monkey/on_reaction(var/datum/reagents/holder)
|
||||
for(var/i = 1 to 4)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/monkeycube(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
/datum/chemical_reaction/slime/grey_slimejelly
|
||||
/decl/chemical_reaction/instant/slime/grey_slimejelly
|
||||
name = "Slime Jelly"
|
||||
id = "m_jelly"
|
||||
result = "slimejelly"
|
||||
@@ -123,7 +123,7 @@
|
||||
color = "#666666"
|
||||
strength = 20
|
||||
|
||||
/datum/chemical_reaction/slime/metal_metamorphic
|
||||
/decl/chemical_reaction/instant/slime/metal_metamorphic
|
||||
name = "Slime Metal"
|
||||
id = "m_metal"
|
||||
required_reagents = list("phoron" = 5)
|
||||
@@ -132,7 +132,7 @@
|
||||
required = /obj/item/slime_extract/metal
|
||||
|
||||
|
||||
/datum/chemical_reaction/metamorphic
|
||||
/decl/chemical_reaction/instant/metamorphic
|
||||
result_amount = REAGENTS_PER_SHEET * 2
|
||||
|
||||
|
||||
@@ -145,42 +145,42 @@
|
||||
|
||||
|
||||
// This is kind of a waste since iron is in the chem dispenser but it would be inconsistent if this wasn't here.
|
||||
/datum/chemical_reaction/metamorphic/iron
|
||||
/decl/chemical_reaction/instant/metamorphic/iron
|
||||
name = "Morph into Iron"
|
||||
id = "morph_iron"
|
||||
required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "iron" = REAGENTS_PER_SHEET)
|
||||
result = "iron"
|
||||
|
||||
|
||||
/datum/chemical_reaction/metamorphic/silver
|
||||
/decl/chemical_reaction/instant/metamorphic/silver
|
||||
name = "Morph into Silver"
|
||||
id = "morph_silver"
|
||||
required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "silver" = REAGENTS_PER_SHEET)
|
||||
result = "silver"
|
||||
|
||||
|
||||
/datum/chemical_reaction/metamorphic/gold
|
||||
/decl/chemical_reaction/instant/metamorphic/gold
|
||||
name = "Morph into Gold"
|
||||
id = "morph_gold"
|
||||
required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "gold" = REAGENTS_PER_SHEET)
|
||||
result = "gold"
|
||||
|
||||
|
||||
/datum/chemical_reaction/metamorphic/platinum
|
||||
/decl/chemical_reaction/instant/metamorphic/platinum
|
||||
name = "Morph into Platinum"
|
||||
id = "morph_platinum"
|
||||
required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "platinum" = REAGENTS_PER_SHEET)
|
||||
result = "platinum"
|
||||
|
||||
|
||||
/datum/chemical_reaction/metamorphic/uranium
|
||||
/decl/chemical_reaction/instant/metamorphic/uranium
|
||||
name = "Morph into Uranium"
|
||||
id = "morph_uranium"
|
||||
required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "uranium" = REAGENTS_PER_SHEET)
|
||||
result = "uranium"
|
||||
|
||||
|
||||
/datum/chemical_reaction/metamorphic/phoron
|
||||
/decl/chemical_reaction/instant/metamorphic/phoron
|
||||
name = "Morph into Phoron"
|
||||
id = "morph_phoron"
|
||||
required_reagents = list("metamorphic" = REAGENTS_PER_SHEET, "phoron" = REAGENTS_PER_SHEET)
|
||||
@@ -188,7 +188,7 @@
|
||||
|
||||
|
||||
// Creates 'alloys' which can be finalized with frost oil.
|
||||
/datum/chemical_reaction/slime/metal_binding
|
||||
/decl/chemical_reaction/instant/slime/metal_binding
|
||||
name = "Slime Binding"
|
||||
id = "m_binding"
|
||||
required_reagents = list("water" = 5)
|
||||
@@ -215,7 +215,7 @@
|
||||
prefill = list("binding" = 60)
|
||||
|
||||
|
||||
/datum/chemical_reaction/binding
|
||||
/decl/chemical_reaction/instant/binding
|
||||
name = "Bind into Steel"
|
||||
id = "bind_steel"
|
||||
result = "steel"
|
||||
@@ -231,7 +231,7 @@
|
||||
color = "#888888"
|
||||
|
||||
|
||||
/datum/chemical_reaction/binding/plasteel // Two parts 'steel', one part platnium matches the smelter alloy recipe.
|
||||
/decl/chemical_reaction/instant/binding/plasteel // Two parts 'steel', one part platnium matches the smelter alloy recipe.
|
||||
name = "Bind into Plasteel"
|
||||
id = "bind_plasteel"
|
||||
required_reagents = list("binding" = REAGENTS_PER_SHEET, "steel" = REAGENTS_PER_SHEET * 2, "platinum" = REAGENTS_PER_SHEET)
|
||||
@@ -258,7 +258,7 @@
|
||||
The extract can also create a slime stability agent when injected with blood, which reduces the odds of newly created slimes mutating into \
|
||||
a different color when a slime reproduces."
|
||||
|
||||
/datum/chemical_reaction/slime/blue_frostoil
|
||||
/decl/chemical_reaction/instant/slime/blue_frostoil
|
||||
name = "Slime Frost Oil"
|
||||
id = "m_frostoil"
|
||||
result = "frostoil"
|
||||
@@ -267,14 +267,14 @@
|
||||
required = /obj/item/slime_extract/blue
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/blue_stability
|
||||
/decl/chemical_reaction/instant/slime/blue_stability
|
||||
name = "Slime Stability"
|
||||
id = "m_stability"
|
||||
required_reagents = list("blood" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/blue
|
||||
|
||||
/datum/chemical_reaction/slime/blue_stability/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/blue_stability/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slimepotion/stabilizer(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -291,14 +291,14 @@
|
||||
can extract from a slime specimen."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/purple_steroid
|
||||
/decl/chemical_reaction/instant/slime/purple_steroid
|
||||
name = "Slime Steroid"
|
||||
id = "m_steroid"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/purple
|
||||
|
||||
/datum/chemical_reaction/slime/purple_steroid/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/purple_steroid/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slimepotion/steroid(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -313,14 +313,14 @@
|
||||
icon_state = "orange slime extract"
|
||||
description_info = "This extract creates a fire when injected with phoron, after a five second delay."
|
||||
|
||||
/datum/chemical_reaction/slime/orange_fire
|
||||
/decl/chemical_reaction/instant/slime/orange_fire
|
||||
name = "Slime Fire"
|
||||
id = "m_fire"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/orange
|
||||
|
||||
/datum/chemical_reaction/slime/orange_fire/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/orange_fire/on_reaction(var/datum/reagents/holder)
|
||||
log_and_message_admins("Orange extract reaction (fire) has been activated in [get_area(holder.my_atom)]. Last fingerprints: [holder.my_atom.fingerprintslast]")
|
||||
holder.my_atom.visible_message("<span class='danger'>\The [src] begins to vibrate violently!</span>")
|
||||
playsound(holder.my_atom, 'sound/effects/phasein.ogg', 75, 1)
|
||||
@@ -350,14 +350,14 @@
|
||||
description_info = "This extract will create a special 10k capacity power cell that self recharges slowly over time, when injected with phoron. \
|
||||
When injected with blood, it will create a glob of slime which glows brightly. If injected with water, it will emit a strong EMP, after a five second delay."
|
||||
|
||||
/datum/chemical_reaction/slime/yellow_emp
|
||||
/decl/chemical_reaction/instant/slime/yellow_emp
|
||||
name = "Slime EMP"
|
||||
id = "m_emp"
|
||||
required_reagents = list("water" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/yellow
|
||||
|
||||
/datum/chemical_reaction/slime/yellow_emp/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/yellow_emp/on_reaction(var/datum/reagents/holder)
|
||||
log_and_message_admins("Yellow extract reaction (emp) has been activated in [get_area(holder.my_atom)]. Last fingerprints: [holder.my_atom.fingerprintslast]")
|
||||
holder.my_atom.visible_message("<span class='danger'>\The [src] begins to vibrate violently!</span>")
|
||||
playsound(holder.my_atom, 'sound/effects/phasein.ogg', 75, 1)
|
||||
@@ -368,26 +368,26 @@
|
||||
..()
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/yellow_battery
|
||||
/decl/chemical_reaction/instant/slime/yellow_battery
|
||||
name = "Slime Cell"
|
||||
id = "m_cell"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/yellow
|
||||
|
||||
/datum/chemical_reaction/slime/yellow_battery/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/yellow_battery/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/weapon/cell/slime(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/yellow_flashlight
|
||||
/decl/chemical_reaction/instant/slime/yellow_flashlight
|
||||
name = "Slime Flashlight"
|
||||
id = "m_flashlight"
|
||||
required_reagents = list("blood" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/yellow
|
||||
|
||||
/datum/chemical_reaction/slime/yellow_flashlight/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/yellow_flashlight/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/device/flashlight/slime(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -401,7 +401,7 @@
|
||||
description_info = "This extract will create 5u liquid gold when injected with phoron."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/gold_gold
|
||||
/decl/chemical_reaction/instant/slime/gold_gold
|
||||
name = "Slime Gold"
|
||||
id = "m_gold"
|
||||
result = "gold"
|
||||
@@ -420,7 +420,7 @@
|
||||
description_info = "This extract will create 5u liquid silver when injected with phoron."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/silver_silver
|
||||
/decl/chemical_reaction/instant/slime/silver_silver
|
||||
name = "Slime Silver"
|
||||
id = "m_silver"
|
||||
result = "silver"
|
||||
@@ -440,7 +440,7 @@
|
||||
description_info = "This extract will create 40u liquid phoron when injected with water."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/dark_purple_phoron
|
||||
/decl/chemical_reaction/instant/slime/dark_purple_phoron
|
||||
name = "Slime Phoron"
|
||||
id = "m_phoron_harvest"
|
||||
result = "phoron"
|
||||
@@ -462,7 +462,7 @@
|
||||
cold-resistant armor like winter coats can protect from this. Note that the user is not immune to the extract's effects."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/dark_blue_cold_snap
|
||||
/decl/chemical_reaction/instant/slime/dark_blue_cold_snap
|
||||
name = "Slime Cold Snap"
|
||||
id = "m_cold_snap"
|
||||
required_reagents = list("phoron" = 5)
|
||||
@@ -470,7 +470,7 @@
|
||||
required = /obj/item/slime_extract/dark_blue
|
||||
|
||||
// This iterates over a ZAS zone's contents, so that things seperated in other zones aren't subjected to the temperature drop.
|
||||
/datum/chemical_reaction/slime/dark_blue_cold_snap/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/dark_blue_cold_snap/on_reaction(var/datum/reagents/holder)
|
||||
var/turf/simulated/T = get_turf(holder.my_atom)
|
||||
if(!T) // Nullspace lacks zones.
|
||||
return
|
||||
@@ -544,14 +544,14 @@
|
||||
out of control."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/red_enrage
|
||||
/decl/chemical_reaction/instant/slime/red_enrage
|
||||
name = "Slime Enrage"
|
||||
id = "m_enrage"
|
||||
required_reagents = list("blood" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/red
|
||||
|
||||
/datum/chemical_reaction/slime/red_enrage/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/red_enrage/on_reaction(var/datum/reagents/holder)
|
||||
for(var/mob/living/simple_mob/slime/S in view(get_turf(holder.my_atom)))
|
||||
if(S.stat)
|
||||
continue
|
||||
@@ -580,14 +580,14 @@
|
||||
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/red_mutation
|
||||
/decl/chemical_reaction/instant/slime/red_mutation
|
||||
name = "Slime Mutation"
|
||||
id = "m_mutation"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/red
|
||||
|
||||
/datum/chemical_reaction/slime/red_mutation/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/red_mutation/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slimepotion/mutator(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -600,7 +600,7 @@
|
||||
icon_state = "green slime extract"
|
||||
description_info = "This extract will create 5u of liquid uranium when injected with phoron."
|
||||
|
||||
/datum/chemical_reaction/slime/green_uranium
|
||||
/decl/chemical_reaction/instant/slime/green_uranium
|
||||
name = "Slime Uranium"
|
||||
id = "m_uranium"
|
||||
result = "uranium"
|
||||
@@ -620,7 +620,7 @@
|
||||
with phoron. When injected with water, it will create an organ-mending agent. The slime medications have a very low threshold for overdosage, however."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/pink_clotting
|
||||
/decl/chemical_reaction/instant/slime/pink_clotting
|
||||
name = "Slime Clotting Med"
|
||||
id = "m_clotting"
|
||||
result = "slime_bleed_fixer"
|
||||
@@ -629,7 +629,7 @@
|
||||
required = /obj/item/slime_extract/pink
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/pink_bone_fix
|
||||
/decl/chemical_reaction/instant/slime/pink_bone_fix
|
||||
name = "Slime Bone Med"
|
||||
id = "m_bone_fixer"
|
||||
result = "slime_bone_fixer"
|
||||
@@ -638,7 +638,7 @@
|
||||
required = /obj/item/slime_extract/pink
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/pink_organ_fix
|
||||
/decl/chemical_reaction/instant/slime/pink_organ_fix
|
||||
name = "Slime Organ Med"
|
||||
id = "m_organ_fixer"
|
||||
result = "slime_organ_fixer"
|
||||
@@ -680,7 +680,7 @@
|
||||
increase the power of the explosion instead of allowing for multiple explosions."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/oil_griff
|
||||
/decl/chemical_reaction/instant/slime/oil_griff
|
||||
name = "Slime Explosion"
|
||||
id = "m_boom"
|
||||
required_reagents = list("blood" = 5)
|
||||
@@ -688,7 +688,7 @@
|
||||
required = /obj/item/slime_extract/oil
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/oil_griff/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/oil_griff/on_reaction(var/datum/reagents/holder)
|
||||
..()
|
||||
var/obj/item/slime_extract/E = holder.my_atom
|
||||
var/power = 1
|
||||
@@ -718,26 +718,26 @@
|
||||
short ranged, random teleporting. When injected with phoron, it creates one 'greater' slime crystal, which allows for a one time precise teleport to \
|
||||
a specific area."
|
||||
|
||||
/datum/chemical_reaction/slime/bluespace_lesser
|
||||
/decl/chemical_reaction/instant/slime/bluespace_lesser
|
||||
name = "Slime Lesser Tele"
|
||||
id = "m_tele_lesser"
|
||||
required_reagents = list("water" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/bluespace
|
||||
|
||||
/datum/chemical_reaction/slime/bluespace_lesser/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/bluespace_lesser/on_reaction(var/datum/reagents/holder)
|
||||
for(var/i = 1 to 5)
|
||||
new /obj/item/slime_crystal(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
/datum/chemical_reaction/slime/bluespace_greater
|
||||
/decl/chemical_reaction/instant/slime/bluespace_greater
|
||||
name = "Slime Greater Tele"
|
||||
id = "m_tele_lesser"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/bluespace
|
||||
|
||||
/datum/chemical_reaction/slime/bluespace_greater/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/bluespace_greater/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/weapon/disposable_teleporter/slime(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -752,14 +752,14 @@
|
||||
'charges' before it goes inert."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/cerulean_enhancer
|
||||
/decl/chemical_reaction/instant/slime/cerulean_enhancer
|
||||
name = "Slime Enhancer"
|
||||
id = "m_enhancer"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/cerulean
|
||||
|
||||
/datum/chemical_reaction/slime/cerulean_enhancer/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/cerulean_enhancer/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slimepotion/enhancer(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -774,26 +774,26 @@
|
||||
injected with water, it will create a very delicious and filling product."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/amber_slimefood
|
||||
/decl/chemical_reaction/instant/slime/amber_slimefood
|
||||
name = "Slime Feeding"
|
||||
id = "m_slime_food"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/amber
|
||||
|
||||
/datum/chemical_reaction/slime/amber_slimefood/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/amber_slimefood/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slimepotion/feeding(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/amber_peoplefood
|
||||
/decl/chemical_reaction/instant/slime/amber_peoplefood
|
||||
name = "Slime Food"
|
||||
id = "m_people_food"
|
||||
required_reagents = list("water" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/amber
|
||||
|
||||
/datum/chemical_reaction/slime/amber_peoplefood/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/amber_peoplefood/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/weapon/reagent_containers/food/snacks/slime(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -809,14 +809,14 @@
|
||||
description_info = "This extract will create one 'slime cube' when injected with phoron. The slime cube is needed to create a Promethean."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/sapphire_promethean
|
||||
/decl/chemical_reaction/instant/slime/sapphire_promethean
|
||||
name = "Slime Promethean"
|
||||
id = "m_promethean"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/sapphire
|
||||
|
||||
/datum/chemical_reaction/slime/sapphire_promethean/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/sapphire_promethean/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slime_cube(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -830,14 +830,14 @@
|
||||
description_info = "This extract will cause all entities close to the extract to become stronger for ten minutes, when injected with phoron. \
|
||||
When injected with blood, makes a slime loyalty agent which will make the slime fight other dangerous entities but not station crew."
|
||||
|
||||
/datum/chemical_reaction/slime/ruby_swole
|
||||
/decl/chemical_reaction/instant/slime/ruby_swole
|
||||
name = "Slime Strength"
|
||||
id = "m_strength"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/ruby
|
||||
|
||||
/datum/chemical_reaction/slime/ruby_swole/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/ruby_swole/on_reaction(var/datum/reagents/holder)
|
||||
for(var/mob/living/L in range(1, holder.my_atom))
|
||||
L.add_modifier(/datum/modifier/slime_strength, 10 MINUTES, src)
|
||||
..()
|
||||
@@ -858,14 +858,14 @@
|
||||
incoming_damage_percent = 0.75
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/ruby_loyalty
|
||||
/decl/chemical_reaction/instant/slime/ruby_loyalty
|
||||
name = "Slime Loyalty"
|
||||
id = "m_strength"
|
||||
required_reagents = list("blood" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/ruby
|
||||
|
||||
/datum/chemical_reaction/slime/ruby_loyalty/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/ruby_loyalty/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slimepotion/loyalty(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -879,14 +879,14 @@
|
||||
icon_state = "emerald slime extract"
|
||||
description_info = "This extract will cause all entities close to the extract to become more agile for ten minutes, when injected with phoron."
|
||||
|
||||
/datum/chemical_reaction/slime/emerald_fast
|
||||
/decl/chemical_reaction/instant/slime/emerald_fast
|
||||
name = "Slime Agility"
|
||||
id = "m_agility"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/emerald
|
||||
|
||||
/datum/chemical_reaction/slime/emerald_fast/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/emerald_fast/on_reaction(var/datum/reagents/holder)
|
||||
for(var/mob/living/L in range(1, holder.my_atom))
|
||||
L.add_modifier(/datum/modifier/slime_agility, 10 MINUTES, src)
|
||||
..()
|
||||
@@ -916,26 +916,26 @@
|
||||
When injected with phoron, it instead creates a slime friendship agent, which makes the slime consider the user their ally. The agent \
|
||||
might be useful on other specimens as well."
|
||||
|
||||
/datum/chemical_reaction/slime/light_pink_docility
|
||||
/decl/chemical_reaction/instant/slime/light_pink_docility
|
||||
name = "Slime Docility"
|
||||
id = "m_docile"
|
||||
required_reagents = list("water" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/light_pink
|
||||
|
||||
/datum/chemical_reaction/slime/light_pink_docility/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/light_pink_docility/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slimepotion/docility(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/light_pink_friendship
|
||||
/decl/chemical_reaction/instant/slime/light_pink_friendship
|
||||
name = "Slime Friendship"
|
||||
id = "m_friendship"
|
||||
required_reagents = list("phoron" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/light_pink
|
||||
|
||||
/datum/chemical_reaction/slime/light_pink_friendship/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/light_pink_friendship/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slimepotion/friendship(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
@@ -952,7 +952,7 @@
|
||||
which makes slimes stop attacking other slime colors."
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/rainbow_random_slime
|
||||
/decl/chemical_reaction/instant/slime/rainbow_random_slime
|
||||
name = "Slime Random Slime"
|
||||
id = "m_rng_slime"
|
||||
required_reagents = list("phoron" = 5)
|
||||
@@ -960,7 +960,7 @@
|
||||
required = /obj/item/slime_extract/rainbow
|
||||
|
||||
|
||||
/datum/chemical_reaction/slime/rainbow_random_slime/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/rainbow_random_slime/on_reaction(var/datum/reagents/holder)
|
||||
var/mob/living/simple_mob/slime/xenobio/S
|
||||
var/list/slime_types = typesof(/mob/living/simple_mob/slime/xenobio)
|
||||
|
||||
@@ -976,14 +976,14 @@
|
||||
new S(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
/datum/chemical_reaction/slime/rainbow_unity
|
||||
/decl/chemical_reaction/instant/slime/rainbow_unity
|
||||
name = "Slime Unity"
|
||||
id = "m_unity"
|
||||
required_reagents = list("water" = 5)
|
||||
result_amount = 1
|
||||
required = /obj/item/slime_extract/rainbow
|
||||
|
||||
/datum/chemical_reaction/slime/rainbow_unity/on_reaction(var/datum/reagents/holder)
|
||||
/decl/chemical_reaction/instant/slime/rainbow_unity/on_reaction(var/datum/reagents/holder)
|
||||
new /obj/item/slimepotion/unity(get_turf(holder.my_atom))
|
||||
..()
|
||||
|
||||
|
||||
@@ -267,6 +267,7 @@
|
||||
#include "code\controllers\subsystems\atoms.dm"
|
||||
#include "code\controllers\subsystems\character_setup.dm"
|
||||
#include "code\controllers\subsystems\chat.dm"
|
||||
#include "code\controllers\subsystems\chemistry.dm"
|
||||
#include "code\controllers\subsystems\circuits.dm"
|
||||
#include "code\controllers\subsystems\dbcore.dm"
|
||||
#include "code\controllers\subsystems\dcs.dm"
|
||||
@@ -304,7 +305,6 @@
|
||||
#include "code\controllers\subsystems\vote.dm"
|
||||
#include "code\controllers\subsystems\xenoarch.dm"
|
||||
#include "code\controllers\subsystems\processing\bellies_vr.dm"
|
||||
#include "code\controllers\subsystems\processing\chemistry.dm"
|
||||
#include "code\controllers\subsystems\processing\fastprocess.dm"
|
||||
#include "code\controllers\subsystems\processing\obj.dm"
|
||||
#include "code\controllers\subsystems\processing\processing.dm"
|
||||
@@ -3550,7 +3550,6 @@
|
||||
#include "code\modules\power\fusion\fusion_circuits.dm"
|
||||
#include "code\modules\power\fusion\fusion_particle_catcher.dm"
|
||||
#include "code\modules\power\fusion\fusion_reactions.dm"
|
||||
#include "code\modules\power\fusion\fusion_reagents.dm"
|
||||
#include "code\modules\power\fusion\magpower.dm"
|
||||
#include "code\modules\power\fusion\core\_core.dm"
|
||||
#include "code\modules\power\fusion\core\core_control.dm"
|
||||
@@ -3725,12 +3724,16 @@
|
||||
#include "code\modules\random_map\noise\ore.dm"
|
||||
#include "code\modules\random_map\noise\tundra.dm"
|
||||
#include "code\modules\reagents\Chemistry-Colours.dm"
|
||||
<<<<<<< HEAD
|
||||
#include "code\modules\reagents\Chemistry-Holder.dm"
|
||||
#include "code\modules\reagents\Chemistry-Holder_ch.dm"
|
||||
||||||| parent of 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
#include "code\modules\reagents\Chemistry-Holder.dm"
|
||||
=======
|
||||
>>>>>>> 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
#include "code\modules\reagents\Chemistry-Logging.dm"
|
||||
#include "code\modules\reagents\Chemistry-Machinery.dm"
|
||||
#include "code\modules\reagents\Chemistry-Machinery_vr.dm"
|
||||
#include "code\modules\reagents\Chemistry-Metabolism.dm"
|
||||
<<<<<<< HEAD
|
||||
#include "code\modules\reagents\Chemistry-Readme.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents-Helpers.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents.dm"
|
||||
@@ -3769,9 +3772,70 @@
|
||||
#include "code\modules\reagents\dispenser\supply.dm"
|
||||
#include "code\modules\reagents\distilling\Distilling-Recipes.dm"
|
||||
#include "code\modules\reagents\distilling\distilling.dm"
|
||||
||||||| parent of 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
#include "code\modules\reagents\Chemistry-Readme.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents-Helpers.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents_vr.dm"
|
||||
#include "code\modules\reagents\Chemistry-Recipes.dm"
|
||||
#include "code\modules\reagents\Chemistry-Recipes_vr.dm"
|
||||
#include "code\modules\reagents\reagent_containers.dm"
|
||||
#include "code\modules\reagents\reagent_dispenser.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Core.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Dispenser.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Food-Drinks.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Food-Drinks_vr.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Medicine.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Medicine_vr.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Modifiers.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Other.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Toxins.dm"
|
||||
#include "code\modules\reagents\Chemistry-Reagents\Chemistry-Reagents-Vore_vr.dm"
|
||||
#include "code\modules\reagents\dispenser\_defines.dm"
|
||||
#include "code\modules\reagents\dispenser\cartridge.dm"
|
||||
#include "code\modules\reagents\dispenser\cartridge_presets.dm"
|
||||
#include "code\modules\reagents\dispenser\cartridge_presets_vr.dm"
|
||||
#include "code\modules\reagents\dispenser\cartridge_spawn.dm"
|
||||
#include "code\modules\reagents\dispenser\dispenser2.dm"
|
||||
#include "code\modules\reagents\dispenser\dispenser2_energy.dm"
|
||||
#include "code\modules\reagents\dispenser\dispenser_presets.dm"
|
||||
#include "code\modules\reagents\dispenser\dispenser_presets_vr.dm"
|
||||
#include "code\modules\reagents\dispenser\supply.dm"
|
||||
#include "code\modules\reagents\distilling\Distilling-Recipes.dm"
|
||||
#include "code\modules\reagents\distilling\distilling.dm"
|
||||
=======
|
||||
#include "code\modules\reagents\holder\distilling.dm"
|
||||
#include "code\modules\reagents\holder\holder.dm"
|
||||
>>>>>>> 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
#include "code\modules\reagents\hoses\connector.dm"
|
||||
#include "code\modules\reagents\hoses\hose.dm"
|
||||
#include "code\modules\reagents\hoses\hose_connector.dm"
|
||||
#include "code\modules\reagents\machinery\chem_master.dm"
|
||||
#include "code\modules\reagents\machinery\chem_master_vr.dm"
|
||||
#include "code\modules\reagents\machinery\chemalyzer.dm"
|
||||
#include "code\modules\reagents\machinery\distillery.dm"
|
||||
#include "code\modules\reagents\machinery\grinder.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\_defines.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\cartridge.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\cartridge_presets.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\cartridge_presets_vr.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\cartridge_spawn.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\dispenser2.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\dispenser2_energy.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\dispenser_presets.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\dispenser_presets_vr.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\reagent_tank.dm"
|
||||
#include "code\modules\reagents\machinery\dispenser\supply.dm"
|
||||
#include "code\modules\reagents\reactions\_reactions.dm"
|
||||
#include "code\modules\reagents\reactions\distilling\distilling.dm"
|
||||
#include "code\modules\reagents\reactions\fusion\fusion.dm"
|
||||
#include "code\modules\reagents\reactions\instant\drinks.dm"
|
||||
#include "code\modules\reagents\reactions\instant\drinks_vr.dm"
|
||||
#include "code\modules\reagents\reactions\instant\food.dm"
|
||||
#include "code\modules\reagents\reactions\instant\food_vr.dm"
|
||||
#include "code\modules\reagents\reactions\instant\instant.dm"
|
||||
#include "code\modules\reagents\reactions\instant\instant_vr.dm"
|
||||
#include "code\modules\reagents\reagent_containers\_reagent_containers.dm"
|
||||
#include "code\modules\reagents\reagent_containers\blood_pack.dm"
|
||||
#include "code\modules\reagents\reagent_containers\blood_pack_vr.dm"
|
||||
#include "code\modules\reagents\reagent_containers\borghypo.dm"
|
||||
@@ -3788,7 +3852,24 @@
|
||||
#include "code\modules\reagents\reagent_containers\syringes.dm"
|
||||
#include "code\modules\reagents\reagent_containers\syringes_vr.dm"
|
||||
#include "code\modules\reagents\reagent_containers\unidentified_hypospray.dm"
|
||||
<<<<<<< HEAD
|
||||
#include "code\modules\reagents\reagent_containers\food\drinks\bluespacecoffee.dm"
|
||||
||||||| parent of 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
=======
|
||||
#include "code\modules\reagents\reagents\_helpers.dm"
|
||||
#include "code\modules\reagents\reagents\_reagents.dm"
|
||||
#include "code\modules\reagents\reagents\core.dm"
|
||||
#include "code\modules\reagents\reagents\dispenser.dm"
|
||||
#include "code\modules\reagents\reagents\food_drinks.dm"
|
||||
#include "code\modules\reagents\reagents\food_drinks_vr.dm"
|
||||
#include "code\modules\reagents\reagents\medicine.dm"
|
||||
#include "code\modules\reagents\reagents\medicine_vr.dm"
|
||||
#include "code\modules\reagents\reagents\modifiers.dm"
|
||||
#include "code\modules\reagents\reagents\other.dm"
|
||||
#include "code\modules\reagents\reagents\other_vr.dm"
|
||||
#include "code\modules\reagents\reagents\toxins.dm"
|
||||
#include "code\modules\reagents\reagents\vore_vr.dm"
|
||||
>>>>>>> 828f6a31bb... Merge pull request #10179 from VOREStation/upstream-merge-8013
|
||||
#include "code\modules\recycling\conveyor2.dm"
|
||||
#include "code\modules\recycling\disposal-construction.dm"
|
||||
#include "code\modules\recycling\disposal.dm"
|
||||
|
||||
Reference in New Issue
Block a user