Oops, I refactored Chemistry! (#8013)

Reorganizes Reagents dir structure
Refactors reactions to /decl
SSChemistry is no longer processing

Optimization isn't so optimized
Updates to distillery
New decl repository methods
Further tweaks
This commit is contained in:
Atermonera
2021-04-20 20:31:49 -07:00
committed by GitHub
parent 1574e4c766
commit 0c0dcb1738
46 changed files with 6235 additions and 6226 deletions

View File

@@ -49,3 +49,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

View 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

View File

@@ -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

View File

@@ -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>")

View File

@@ -13,7 +13,7 @@
//---Beverages---//
//***************//
/datum/reagent/var/price_tag = null
/datum/reagent/var/price_tag = 0
// Juices, soda and similar //

View File

@@ -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.

View File

@@ -272,19 +272,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>")

View File

@@ -1,3 +1,4 @@
#define FUSION_ROD_SHEET_AMT 15
/obj/machinery/fusion_fuel_compressor
name = "fuel compressor"
icon = 'icons/obj/machines/power/fusion.dmi'
@@ -53,15 +54,17 @@
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)
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(15)
M.use(FUSION_ROD_SHEET_AMT)
user.put_in_hands(F)
else if(do_special_fuel_compression(thing, user))
return
return ..()
return ..()
#undef FUSION_ROD_SHEET_AMT

View File

@@ -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)

View File

@@ -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

File diff suppressed because it is too large Load Diff

View 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()

View 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

View File

@@ -1,8 +1,8 @@
#define CARTRIDGE_VOLUME_LARGE 500
#define CARTRIDGE_VOLUME_MEDIUM 250
#define CARTRIDGE_VOLUME_SMALL 100
// Chemistry dispenser starts with 21
// ERT dispenser starts with 28
#define DISPENSER_MAX_CARTRIDGES 30
#define CARTRIDGE_VOLUME_LARGE 500
#define CARTRIDGE_VOLUME_MEDIUM 250
#define CARTRIDGE_VOLUME_SMALL 100
// Chemistry dispenser starts with 21
// ERT dispenser starts with 28
#define DISPENSER_MAX_CARTRIDGES 30

View File

@@ -1,95 +1,95 @@
/obj/item/weapon/reagent_containers/chem_disp_cartridge
name = "chemical dispenser cartridge"
desc = "This goes in a chemical dispenser."
icon_state = "cartridge"
w_class = ITEMSIZE_NORMAL
volume = CARTRIDGE_VOLUME_LARGE
amount_per_transfer_from_this = 50
// Large, but inaccurate. Use a chem dispenser or beaker for accuracy.
possible_transfer_amounts = list(50, 100, 250, 500)
unacidable = 1
var/spawn_reagent = null
var/label = ""
/obj/item/weapon/reagent_containers/chem_disp_cartridge/Initialize()
. = ..()
if(spawn_reagent)
reagents.add_reagent(spawn_reagent, volume)
var/datum/reagent/R = SSchemistry.chemical_reagents[spawn_reagent]
setLabel(R.name)
/obj/item/weapon/reagent_containers/chem_disp_cartridge/examine(mob/user)
. = ..()
. += "It has a capacity of [volume] units."
if(reagents.total_volume <= 0)
. += "It is empty."
else
. += "It contains [reagents.total_volume] units of liquid."
if(!is_open_container())
. += "The cap is sealed."
/obj/item/weapon/reagent_containers/chem_disp_cartridge/verb/verb_set_label(L as text)
set name = "Set Cartridge Label"
set category = "Object"
set src in view(usr, 1)
setLabel(L, usr)
/obj/item/weapon/reagent_containers/chem_disp_cartridge/proc/setLabel(L, mob/user = null)
if(L)
if(user)
to_chat(user, "<span class='notice'>You set the label on \the [src] to '[L]'.</span>")
label = L
name = "[initial(name)] - '[L]'"
else
if(user)
to_chat(user, "<span class='notice'>You clear the label on \the [src].</span>")
label = ""
name = initial(name)
/obj/item/weapon/reagent_containers/chem_disp_cartridge/attack_self()
..()
if (is_open_container())
to_chat(usr, "<span class = 'notice'>You put the cap on \the [src].</span>")
flags ^= OPENCONTAINER
else
to_chat(usr, "<span class = 'notice'>You take the cap off \the [src].</span>")
flags |= OPENCONTAINER
/obj/item/weapon/reagent_containers/chem_disp_cartridge/afterattack(obj/target, mob/user , flag)
if (!is_open_container() || !flag)
return
else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
target.add_fingerprint(user)
if(!target.reagents.total_volume && target.reagents)
to_chat(user, "<span class='warning'>\The [target] is empty.</span>")
return
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='warning'>\The [src] is full.</span>")
return
var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill \the [src] with [trans] units of the contents of \the [target].</span>")
else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>\The [src] is empty.</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='warning'>\The [target] is full.</span>")
return
var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] units of the solution to \the [target].</span>")
else
return ..()
/obj/item/weapon/reagent_containers/chem_disp_cartridge
name = "chemical dispenser cartridge"
desc = "This goes in a chemical dispenser."
icon_state = "cartridge"
w_class = ITEMSIZE_NORMAL
volume = CARTRIDGE_VOLUME_LARGE
amount_per_transfer_from_this = 50
// Large, but inaccurate. Use a chem dispenser or beaker for accuracy.
possible_transfer_amounts = list(50, 100, 250, 500)
unacidable = 1
var/spawn_reagent = null
var/label = ""
/obj/item/weapon/reagent_containers/chem_disp_cartridge/Initialize()
. = ..()
if(spawn_reagent)
reagents.add_reagent(spawn_reagent, volume)
var/datum/reagent/R = SSchemistry.chemical_reagents[spawn_reagent]
setLabel(R.name)
/obj/item/weapon/reagent_containers/chem_disp_cartridge/examine(mob/user)
. = ..()
. += "It has a capacity of [volume] units."
if(reagents.total_volume <= 0)
. += "It is empty."
else
. += "It contains [reagents.total_volume] units of liquid."
if(!is_open_container())
. += "The cap is sealed."
/obj/item/weapon/reagent_containers/chem_disp_cartridge/verb/verb_set_label(L as text)
set name = "Set Cartridge Label"
set category = "Object"
set src in view(usr, 1)
setLabel(L, usr)
/obj/item/weapon/reagent_containers/chem_disp_cartridge/proc/setLabel(L, mob/user = null)
if(L)
if(user)
to_chat(user, "<span class='notice'>You set the label on \the [src] to '[L]'.</span>")
label = L
name = "[initial(name)] - '[L]'"
else
if(user)
to_chat(user, "<span class='notice'>You clear the label on \the [src].</span>")
label = ""
name = initial(name)
/obj/item/weapon/reagent_containers/chem_disp_cartridge/attack_self()
..()
if (is_open_container())
to_chat(usr, "<span class = 'notice'>You put the cap on \the [src].</span>")
flags ^= OPENCONTAINER
else
to_chat(usr, "<span class = 'notice'>You take the cap off \the [src].</span>")
flags |= OPENCONTAINER
/obj/item/weapon/reagent_containers/chem_disp_cartridge/afterattack(obj/target, mob/user , flag)
if (!is_open_container() || !flag)
return
else if(istype(target, /obj/structure/reagent_dispensers)) //A dispenser. Transfer FROM it TO us.
target.add_fingerprint(user)
if(!target.reagents.total_volume && target.reagents)
to_chat(user, "<span class='warning'>\The [target] is empty.</span>")
return
if(reagents.total_volume >= reagents.maximum_volume)
to_chat(user, "<span class='warning'>\The [src] is full.</span>")
return
var/trans = target.reagents.trans_to(src, target:amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill \the [src] with [trans] units of the contents of \the [target].</span>")
else if(target.is_open_container() && target.reagents) //Something like a glass. Player probably wants to transfer TO it.
if(!reagents.total_volume)
to_chat(user, "<span class='warning'>\The [src] is empty.</span>")
return
if(target.reagents.total_volume >= target.reagents.maximum_volume)
to_chat(user, "<span class='warning'>\The [target] is full.</span>")
return
var/trans = src.reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] units of the solution to \the [target].</span>")
else
return ..()

View File

@@ -1,108 +1,108 @@
/obj/item/weapon/reagent_containers/chem_disp_cartridge
small
volume = CARTRIDGE_VOLUME_SMALL
medium
volume = CARTRIDGE_VOLUME_MEDIUM
// Multiple
water spawn_reagent = "water"
sugar spawn_reagent = "sugar"
// Chemistry
hydrogen spawn_reagent = "hydrogen"
lithium spawn_reagent = "lithium"
carbon spawn_reagent = "carbon"
nitrogen spawn_reagent = "nitrogen"
oxygen spawn_reagent = "oxygen"
fluorine spawn_reagent = "fluorine"
sodium spawn_reagent = "sodium"
aluminum spawn_reagent = "aluminum"
silicon spawn_reagent = "silicon"
phosphorus spawn_reagent = "phosphorus"
sulfur spawn_reagent = "sulfur"
chlorine spawn_reagent = "chlorine"
potassium spawn_reagent = "potassium"
iron spawn_reagent = "iron"
copper spawn_reagent = "copper"
mercury spawn_reagent = "mercury"
radium spawn_reagent = "radium"
ethanol spawn_reagent = "ethanol"
sacid spawn_reagent = "sacid"
tungsten spawn_reagent = "tungsten"
calcium spawn_reagent = "calcium"
// Bar, alcoholic
beer spawn_reagent = "beer"
kahlua spawn_reagent = "kahlua"
whiskey spawn_reagent = "whiskey"
wine spawn_reagent = "wine"
vodka spawn_reagent = "vodka"
gin spawn_reagent = "gin"
rum spawn_reagent = "rum"
tequila spawn_reagent = "tequilla"
vermouth spawn_reagent = "vermouth"
cognac spawn_reagent = "cognac"
ale spawn_reagent = "ale"
mead spawn_reagent = "mead"
bitters spawn_reagent = "bitters"
cider spawn_reagent = "cider"
// Bar, soft
ice spawn_reagent = "ice"
tea spawn_reagent = "tea"
icetea spawn_reagent = "icetea"
cola spawn_reagent = "cola"
smw spawn_reagent = "spacemountainwind"
dr_gibb spawn_reagent = "dr_gibb"
spaceup spawn_reagent = "space_up"
tonic spawn_reagent = "tonic"
sodawater spawn_reagent = "sodawater"
lemon_lime spawn_reagent = "lemon_lime"
orange spawn_reagent = "orangejuice"
lime spawn_reagent = "limejuice"
watermelon spawn_reagent = "watermelonjuice"
lemon spawn_reagent = "lemonjuice"
// Bar, coffee
coffee spawn_reagent = "coffee"
cafe_latte spawn_reagent = "cafe_latte"
soy_latte spawn_reagent = "soy_latte"
hot_coco spawn_reagent = "hot_coco"
milk spawn_reagent = "milk"
cream spawn_reagent = "cream"
mint spawn_reagent = "mint"
berry spawn_reagent = "berryjuice"
greentea spawn_reagent = "greentea"
decaf spawn_reagent = "decaf"
// ERT
inaprov spawn_reagent = "inaprovaline"
ryetalyn spawn_reagent = "ryetalyn"
paracetamol spawn_reagent = "paracetamol"
tramadol spawn_reagent = "tramadol"
oxycodone spawn_reagent = "oxycodone"
sterilizine spawn_reagent = "sterilizine"
leporazine spawn_reagent = "leporazine"
kelotane spawn_reagent = "kelotane"
dermaline spawn_reagent = "dermaline"
dexalin spawn_reagent = "dexalin"
dexalin/small volume = CARTRIDGE_VOLUME_SMALL // For the medicine cartridge crate, so it's not too easy to get large amounts of dexalin
dexalin_p spawn_reagent = "dexalinp"
tricord spawn_reagent = "tricordrazine"
dylovene spawn_reagent = "anti_toxin"
synaptizine spawn_reagent = "synaptizine"
hyronalin spawn_reagent = "hyronalin"
arithrazine spawn_reagent = "arithrazine"
alkysine spawn_reagent = "alkysine"
imidazoline spawn_reagent = "imidazoline"
peridaxon spawn_reagent = "peridaxon"
bicaridine spawn_reagent = "bicaridine"
hyperzine spawn_reagent = "hyperzine"
rezadone spawn_reagent = "rezadone"
spaceacillin spawn_reagent = "spaceacillin"
ethylredox spawn_reagent = "ethylredoxrazine"
sleeptox spawn_reagent = "stoxin"
chloral spawn_reagent = "chloralhydrate"
cryoxadone spawn_reagent = "cryoxadone"
clonexadone spawn_reagent = "clonexadone"
/obj/item/weapon/reagent_containers/chem_disp_cartridge
small
volume = CARTRIDGE_VOLUME_SMALL
medium
volume = CARTRIDGE_VOLUME_MEDIUM
// Multiple
water spawn_reagent = "water"
sugar spawn_reagent = "sugar"
// Chemistry
hydrogen spawn_reagent = "hydrogen"
lithium spawn_reagent = "lithium"
carbon spawn_reagent = "carbon"
nitrogen spawn_reagent = "nitrogen"
oxygen spawn_reagent = "oxygen"
fluorine spawn_reagent = "fluorine"
sodium spawn_reagent = "sodium"
aluminum spawn_reagent = "aluminum"
silicon spawn_reagent = "silicon"
phosphorus spawn_reagent = "phosphorus"
sulfur spawn_reagent = "sulfur"
chlorine spawn_reagent = "chlorine"
potassium spawn_reagent = "potassium"
iron spawn_reagent = "iron"
copper spawn_reagent = "copper"
mercury spawn_reagent = "mercury"
radium spawn_reagent = "radium"
ethanol spawn_reagent = "ethanol"
sacid spawn_reagent = "sacid"
tungsten spawn_reagent = "tungsten"
calcium spawn_reagent = "calcium"
// Bar, alcoholic
beer spawn_reagent = "beer"
kahlua spawn_reagent = "kahlua"
whiskey spawn_reagent = "whiskey"
wine spawn_reagent = "wine"
vodka spawn_reagent = "vodka"
gin spawn_reagent = "gin"
rum spawn_reagent = "rum"
tequila spawn_reagent = "tequilla"
vermouth spawn_reagent = "vermouth"
cognac spawn_reagent = "cognac"
ale spawn_reagent = "ale"
mead spawn_reagent = "mead"
bitters spawn_reagent = "bitters"
cider spawn_reagent = "cider"
// Bar, soft
ice spawn_reagent = "ice"
tea spawn_reagent = "tea"
icetea spawn_reagent = "icetea"
cola spawn_reagent = "cola"
smw spawn_reagent = "spacemountainwind"
dr_gibb spawn_reagent = "dr_gibb"
spaceup spawn_reagent = "space_up"
tonic spawn_reagent = "tonic"
sodawater spawn_reagent = "sodawater"
lemon_lime spawn_reagent = "lemon_lime"
orange spawn_reagent = "orangejuice"
lime spawn_reagent = "limejuice"
watermelon spawn_reagent = "watermelonjuice"
lemon spawn_reagent = "lemonjuice"
// Bar, coffee
coffee spawn_reagent = "coffee"
cafe_latte spawn_reagent = "cafe_latte"
soy_latte spawn_reagent = "soy_latte"
hot_coco spawn_reagent = "hot_coco"
milk spawn_reagent = "milk"
cream spawn_reagent = "cream"
mint spawn_reagent = "mint"
berry spawn_reagent = "berryjuice"
greentea spawn_reagent = "greentea"
decaf spawn_reagent = "decaf"
// ERT
inaprov spawn_reagent = "inaprovaline"
ryetalyn spawn_reagent = "ryetalyn"
paracetamol spawn_reagent = "paracetamol"
tramadol spawn_reagent = "tramadol"
oxycodone spawn_reagent = "oxycodone"
sterilizine spawn_reagent = "sterilizine"
leporazine spawn_reagent = "leporazine"
kelotane spawn_reagent = "kelotane"
dermaline spawn_reagent = "dermaline"
dexalin spawn_reagent = "dexalin"
dexalin/small volume = CARTRIDGE_VOLUME_SMALL // For the medicine cartridge crate, so it's not too easy to get large amounts of dexalin
dexalin_p spawn_reagent = "dexalinp"
tricord spawn_reagent = "tricordrazine"
dylovene spawn_reagent = "anti_toxin"
synaptizine spawn_reagent = "synaptizine"
hyronalin spawn_reagent = "hyronalin"
arithrazine spawn_reagent = "arithrazine"
alkysine spawn_reagent = "alkysine"
imidazoline spawn_reagent = "imidazoline"
peridaxon spawn_reagent = "peridaxon"
bicaridine spawn_reagent = "bicaridine"
hyperzine spawn_reagent = "hyperzine"
rezadone spawn_reagent = "rezadone"
spaceacillin spawn_reagent = "spaceacillin"
ethylredox spawn_reagent = "ethylredoxrazine"
sleeptox spawn_reagent = "stoxin"
chloral spawn_reagent = "chloralhydrate"
cryoxadone spawn_reagent = "cryoxadone"
clonexadone spawn_reagent = "clonexadone"

View File

@@ -1,205 +1,205 @@
/obj/machinery/chemical_dispenser
name = "chemical dispenser"
desc = "Automagically fabricates chemicals from electricity."
icon = 'icons/obj/chemical.dmi'
icon_state = "dispenser"
clicksound = "switch"
var/list/spawn_cartridges = null // Set to a list of types to spawn one of each on New()
var/list/cartridges = list() // Associative, label -> cartridge
var/obj/item/weapon/reagent_containers/container = null
var/ui_title = "Chemical Dispenser"
var/accept_drinking = 0
var/amount = 30
use_power = USE_POWER_IDLE
idle_power_usage = 100
anchored = 1
/obj/machinery/chemical_dispenser/Initialize()
. = ..()
if(spawn_cartridges)
for(var/type in spawn_cartridges)
add_cartridge(new type(src))
/obj/machinery/chemical_dispenser/examine(mob/user)
. = ..()
. += "It has [cartridges.len] cartridges installed, and has space for [DISPENSER_MAX_CARTRIDGES - cartridges.len] more."
/obj/machinery/chemical_dispenser/verb/rotate_clockwise()
set name = "Rotate Dispenser Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened down!")
return 0
src.set_dir(turn(src.dir, 270))
return 1
/obj/machinery/chemical_dispenser/proc/add_cartridge(obj/item/weapon/reagent_containers/chem_disp_cartridge/C, mob/user)
if(!istype(C))
if(user)
to_chat(user, "<span class='warning'>\The [C] will not fit in \the [src]!</span>")
return
if(cartridges.len >= DISPENSER_MAX_CARTRIDGES)
if(user)
to_chat(user, "<span class='warning'>\The [src] does not have any slots open for \the [C] to fit into!</span>")
return
if(!C.label)
if(user)
to_chat(user, "<span class='warning'>\The [C] does not have a label!</span>")
return
if(cartridges[C.label])
if(user)
to_chat(user, "<span class='warning'>\The [src] already contains a cartridge with that label!</span>")
return
if(user)
user.drop_from_inventory(C)
to_chat(user, "<span class='notice'>You add \the [C] to \the [src].</span>")
C.loc = src
cartridges[C.label] = C
cartridges = sortAssoc(cartridges)
SStgui.update_uis(src)
/obj/machinery/chemical_dispenser/proc/remove_cartridge(label)
. = cartridges[label]
cartridges -= label
SStgui.update_uis(src)
/obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user)
if(W.is_wrench())
playsound(src, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You begin to [anchored ? "un" : ""]fasten \the [src].</span>")
if (do_after(user, 20 * W.toolspeed))
user.visible_message(
"<span class='notice'>\The [user] [anchored ? "un" : ""]fastens \the [src].</span>",
"<span class='notice'>You have [anchored ? "un" : ""]fastened \the [src].</span>",
"You hear a ratchet.")
anchored = !anchored
else
to_chat(user, "<span class='notice'>You decide not to [anchored ? "un" : ""]fasten \the [src].</span>")
else if(istype(W, /obj/item/weapon/reagent_containers/chem_disp_cartridge))
add_cartridge(W, user)
else if(W.is_screwdriver())
var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges
if(!label) return
var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = remove_cartridge(label)
if(C)
to_chat(user, "<span class='notice'>You remove \the [C] from \the [src].</span>")
C.loc = loc
playsound(src, W.usesound, 50, 1)
else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food))
if(container)
to_chat(user, "<span class='warning'>There is already \a [container] on \the [src]!</span>")
return
var/obj/item/weapon/reagent_containers/RC = W
if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food))
to_chat(user, "<span class='warning'>This machine only accepts beakers!</span>")
return
if(!RC.is_open_container())
to_chat(user, "<span class='warning'>You don't see how \the [src] could dispense reagents into \the [RC].</span>")
return
container = RC
user.drop_from_inventory(RC)
RC.loc = src
to_chat(user, "<span class='notice'>You set \the [RC] on \the [src].</span>")
else
return ..()
/obj/machinery/chemical_dispenser/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ChemDispenser", ui_title) // 390, 655
ui.open()
/obj/machinery/chemical_dispenser/tgui_data(mob/user)
var/data[0]
data["amount"] = amount
data["isBeakerLoaded"] = container ? 1 : 0
data["glass"] = accept_drinking
var/beakerContents[0]
if(container && container.reagents && container.reagents.reagent_list.len)
for(var/datum/reagent/R in container.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list...
data["beakerContents"] = beakerContents
if(container)
data["beakerCurrentVolume"] = container.reagents.total_volume
data["beakerMaxVolume"] = container.reagents.maximum_volume
else
data["beakerCurrentVolume"] = null
data["beakerMaxVolume"] = null
var/chemicals[0]
for(var/label in cartridges)
var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label]
chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list...
data["chemicals"] = chemicals
return data
/obj/machinery/chemical_dispenser/tgui_act(action, params)
if(..())
return TRUE
. = TRUE
switch(action)
if("amount")
amount = clamp(round(text2num(params["amount"]), 1), 0, 120) // round to nearest 1 and clamp 0 - 120
if("dispense")
var/label = params["reagent"]
if(cartridges[label] && container && container.is_open_container())
var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label]
playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1)
C.reagents.trans_to(container, amount)
if("remove")
var/amount = text2num(params["amount"])
if(!container || !amount)
return
var/datum/reagents/R = container.reagents
var/id = params["reagent"]
if(amount > 0)
R.remove_reagent(id, amount)
else if(amount == -1) // Isolate
R.isolate_reagent(id)
if("ejectBeaker")
if(container)
container.forceMove(get_turf(src))
if(Adjacent(usr)) // So the AI doesn't get a beaker somehow.
usr.put_in_hands(container)
container = null
else
return FALSE
add_fingerprint(usr)
/obj/machinery/chemical_dispenser/attack_ghost(mob/user)
if(stat & BROKEN)
return
tgui_interact(user)
/obj/machinery/chemical_dispenser/attack_ai(mob/user)
attack_hand(user)
/obj/machinery/chemical_dispenser/attack_hand(mob/user)
if(stat & BROKEN)
return
tgui_interact(user)
/obj/machinery/chemical_dispenser
name = "chemical dispenser"
desc = "Automagically fabricates chemicals from electricity."
icon = 'icons/obj/chemical.dmi'
icon_state = "dispenser"
clicksound = "switch"
var/list/spawn_cartridges = null // Set to a list of types to spawn one of each on New()
var/list/cartridges = list() // Associative, label -> cartridge
var/obj/item/weapon/reagent_containers/container = null
var/ui_title = "Chemical Dispenser"
var/accept_drinking = 0
var/amount = 30
use_power = USE_POWER_IDLE
idle_power_usage = 100
anchored = 1
/obj/machinery/chemical_dispenser/Initialize()
. = ..()
if(spawn_cartridges)
for(var/type in spawn_cartridges)
add_cartridge(new type(src))
/obj/machinery/chemical_dispenser/examine(mob/user)
. = ..()
. += "It has [cartridges.len] cartridges installed, and has space for [DISPENSER_MAX_CARTRIDGES - cartridges.len] more."
/obj/machinery/chemical_dispenser/verb/rotate_clockwise()
set name = "Rotate Dispenser Clockwise"
set category = "Object"
set src in oview(1)
if (src.anchored || usr:stat)
to_chat(usr, "It is fastened down!")
return 0
src.set_dir(turn(src.dir, 270))
return 1
/obj/machinery/chemical_dispenser/proc/add_cartridge(obj/item/weapon/reagent_containers/chem_disp_cartridge/C, mob/user)
if(!istype(C))
if(user)
to_chat(user, "<span class='warning'>\The [C] will not fit in \the [src]!</span>")
return
if(cartridges.len >= DISPENSER_MAX_CARTRIDGES)
if(user)
to_chat(user, "<span class='warning'>\The [src] does not have any slots open for \the [C] to fit into!</span>")
return
if(!C.label)
if(user)
to_chat(user, "<span class='warning'>\The [C] does not have a label!</span>")
return
if(cartridges[C.label])
if(user)
to_chat(user, "<span class='warning'>\The [src] already contains a cartridge with that label!</span>")
return
if(user)
user.drop_from_inventory(C)
to_chat(user, "<span class='notice'>You add \the [C] to \the [src].</span>")
C.loc = src
cartridges[C.label] = C
cartridges = sortAssoc(cartridges)
SStgui.update_uis(src)
/obj/machinery/chemical_dispenser/proc/remove_cartridge(label)
. = cartridges[label]
cartridges -= label
SStgui.update_uis(src)
/obj/machinery/chemical_dispenser/attackby(obj/item/weapon/W, mob/user)
if(W.is_wrench())
playsound(src, W.usesound, 50, 1)
to_chat(user, "<span class='notice'>You begin to [anchored ? "un" : ""]fasten \the [src].</span>")
if (do_after(user, 20 * W.toolspeed))
user.visible_message(
"<span class='notice'>\The [user] [anchored ? "un" : ""]fastens \the [src].</span>",
"<span class='notice'>You have [anchored ? "un" : ""]fastened \the [src].</span>",
"You hear a ratchet.")
anchored = !anchored
else
to_chat(user, "<span class='notice'>You decide not to [anchored ? "un" : ""]fasten \the [src].</span>")
else if(istype(W, /obj/item/weapon/reagent_containers/chem_disp_cartridge))
add_cartridge(W, user)
else if(W.is_screwdriver())
var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges
if(!label) return
var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = remove_cartridge(label)
if(C)
to_chat(user, "<span class='notice'>You remove \the [C] from \the [src].</span>")
C.loc = loc
playsound(src, W.usesound, 50, 1)
else if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food))
if(container)
to_chat(user, "<span class='warning'>There is already \a [container] on \the [src]!</span>")
return
var/obj/item/weapon/reagent_containers/RC = W
if(!accept_drinking && istype(RC,/obj/item/weapon/reagent_containers/food))
to_chat(user, "<span class='warning'>This machine only accepts beakers!</span>")
return
if(!RC.is_open_container())
to_chat(user, "<span class='warning'>You don't see how \the [src] could dispense reagents into \the [RC].</span>")
return
container = RC
user.drop_from_inventory(RC)
RC.loc = src
to_chat(user, "<span class='notice'>You set \the [RC] on \the [src].</span>")
else
return ..()
/obj/machinery/chemical_dispenser/tgui_interact(mob/user, datum/tgui/ui = null)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ChemDispenser", ui_title) // 390, 655
ui.open()
/obj/machinery/chemical_dispenser/tgui_data(mob/user)
var/data[0]
data["amount"] = amount
data["isBeakerLoaded"] = container ? 1 : 0
data["glass"] = accept_drinking
var/beakerContents[0]
if(container && container.reagents && container.reagents.reagent_list.len)
for(var/datum/reagent/R in container.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "id" = R.id, "volume" = R.volume))) // list in a list because Byond merges the first list...
data["beakerContents"] = beakerContents
if(container)
data["beakerCurrentVolume"] = container.reagents.total_volume
data["beakerMaxVolume"] = container.reagents.maximum_volume
else
data["beakerCurrentVolume"] = null
data["beakerMaxVolume"] = null
var/chemicals[0]
for(var/label in cartridges)
var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label]
chemicals.Add(list(list("title" = label, "id" = label, "amount" = C.reagents.total_volume))) // list in a list because Byond merges the first list...
data["chemicals"] = chemicals
return data
/obj/machinery/chemical_dispenser/tgui_act(action, params)
if(..())
return TRUE
. = TRUE
switch(action)
if("amount")
amount = clamp(round(text2num(params["amount"]), 1), 0, 120) // round to nearest 1 and clamp 0 - 120
if("dispense")
var/label = params["reagent"]
if(cartridges[label] && container && container.is_open_container())
var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C = cartridges[label]
playsound(src, 'sound/machines/reagent_dispense.ogg', 25, 1)
C.reagents.trans_to(container, amount)
if("remove")
var/amount = text2num(params["amount"])
if(!container || !amount)
return
var/datum/reagents/R = container.reagents
var/id = params["reagent"]
if(amount > 0)
R.remove_reagent(id, amount)
else if(amount == -1) // Isolate
R.isolate_reagent(id)
if("ejectBeaker")
if(container)
container.forceMove(get_turf(src))
if(Adjacent(usr)) // So the AI doesn't get a beaker somehow.
usr.put_in_hands(container)
container = null
else
return FALSE
add_fingerprint(usr)
/obj/machinery/chemical_dispenser/attack_ghost(mob/user)
if(stat & BROKEN)
return
tgui_interact(user)
/obj/machinery/chemical_dispenser/attack_ai(mob/user)
attack_hand(user)
/obj/machinery/chemical_dispenser/attack_hand(mob/user)
if(stat & BROKEN)
return
tgui_interact(user)

View File

@@ -1,144 +1,144 @@
/obj/machinery/chemical_dispenser/full
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/iron,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/copper,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/radium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/water,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium
)
/obj/machinery/chemical_dispenser/ert
name = "medicine dispenser"
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/inaprov,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ryetalyn,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/paracetamol,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tramadol,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/oxycodone,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sterilizine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/leporazine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/kelotane,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dermaline,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin_p,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tricord,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dylovene,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/synaptizine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hyronalin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/arithrazine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/alkysine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/imidazoline,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/peridaxon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/bicaridine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hyperzine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/rezadone,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceacillin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ethylredox,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sleeptox,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/chloral,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cryoxadone,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/clonexadone
)
/obj/machinery/chemical_dispenser/bar_soft
name = "soft drink dispenser"
desc = "A soda machine."
icon_state = "soda_dispenser"
ui_title = "Soda Dispenser"
accept_drinking = 1
/obj/machinery/chemical_dispenser/bar_soft/full
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/water,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ice,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cream,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cola,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/smw,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/orange,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon
)
/obj/machinery/chemical_dispenser/bar_alc
name = "booze dispenser"
desc = "A beer machine. Like a soda machine, but more fun!"
icon_state = "booze_dispenser"
ui_title = "Booze Dispenser"
accept_drinking = 1
/obj/machinery/chemical_dispenser/bar_alc/full
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/orange,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/beer,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/wine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/gin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/rum,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cider,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ale,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mead
)
/obj/machinery/chemical_dispenser/bar_coffee
name = "coffee dispenser"
desc = "Driving crack dealers out of employment since 2280."
icon_state = "coffee_dispenser"
ui_title = "Coffee Dispenser"
accept_drinking = 1
/obj/machinery/chemical_dispenser/bar_coffee/full
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/milk,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cream,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ice,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mint,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/orange,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/berry,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/greentea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/decaf
)
/obj/machinery/chemical_dispenser/full
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/iron,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/copper,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/radium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/water,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium
)
/obj/machinery/chemical_dispenser/ert
name = "medicine dispenser"
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/inaprov,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ryetalyn,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/paracetamol,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tramadol,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/oxycodone,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sterilizine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/leporazine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/kelotane,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dermaline,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dexalin_p,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tricord,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dylovene,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/synaptizine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hyronalin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/arithrazine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/alkysine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/imidazoline,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/peridaxon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/bicaridine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hyperzine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/rezadone,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceacillin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ethylredox,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sleeptox,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/chloral,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cryoxadone,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/clonexadone
)
/obj/machinery/chemical_dispenser/bar_soft
name = "soft drink dispenser"
desc = "A soda machine."
icon_state = "soda_dispenser"
ui_title = "Soda Dispenser"
accept_drinking = 1
/obj/machinery/chemical_dispenser/bar_soft/full
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/water,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ice,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cream,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cola,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/smw,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/orange,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon
)
/obj/machinery/chemical_dispenser/bar_alc
name = "booze dispenser"
desc = "A beer machine. Like a soda machine, but more fun!"
icon_state = "booze_dispenser"
ui_title = "Booze Dispenser"
accept_drinking = 1
/obj/machinery/chemical_dispenser/bar_alc/full
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/orange,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/beer,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/wine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/gin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/rum,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cider,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ale,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mead
)
/obj/machinery/chemical_dispenser/bar_coffee
name = "coffee dispenser"
desc = "Driving crack dealers out of employment since 2280."
icon_state = "coffee_dispenser"
ui_title = "Coffee Dispenser"
accept_drinking = 1
/obj/machinery/chemical_dispenser/bar_coffee/full
spawn_cartridges = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/milk,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cream,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ice,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mint,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/orange,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/berry,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/greentea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/decaf
)

View File

@@ -1,431 +1,442 @@
/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.dmi'
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.dmi'
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)
/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/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)
/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.dmi'
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.dmi'
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)
/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/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)
/obj/structure/reagent_dispensers/he3
name = "fueltank"
desc = "A fueltank."
icon = 'icons/obj/objects.dmi'
icon_state = "weldtank"
amount_per_transfer_from_this = 10
/obj/structure/reagent_dispenser/he3/Initialize()
..()
reagents.add_reagent("helium3",1000)

View File

@@ -1,238 +1,238 @@
/datum/supply_pack/chemistry_dispenser
name = "Reagent dispenser"
contains = list(
/obj/machinery/chemical_dispenser{anchored = 0}
)
cost = 25
containertype = /obj/structure/largecrate
containername = "reagent dispenser crate"
group = "Reagents"
/datum/supply_pack/beer_dispenser
name = "Booze dispenser"
contains = list(
/obj/machinery/chemical_dispenser/bar_alc{anchored = 0}
)
cost = 25
containertype = /obj/structure/largecrate
containername = "booze dispenser crate"
group = "Reagents"
/datum/supply_pack/soda_dispenser
name = "Soda dispenser"
contains = list(
/obj/machinery/chemical_dispenser/bar_soft{anchored = 0}
)
cost = 25
containertype = /obj/structure/largecrate
containername = "soda dispenser crate"
group = "Reagents"
/datum/supply_pack/reagents
name = "Chemistry dispenser refill"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/iron,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/copper,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/radium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/water,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten
)
cost = 150
containertype = /obj/structure/closet/crate/secure
containername = "chemical crate"
access = list(access_chemistry)
group = "Reagents"
/datum/supply_pack/alcohol_reagents
name = "Bar alcoholic dispenser refill"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/beer,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/wine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/gin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/rum,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ale,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mead,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/bitters
)
cost = 50
containertype = /obj/structure/closet/crate/secure
containername = "alcoholic drinks crate"
access = list(access_bar)
group = "Reagents"
/datum/supply_pack/softdrink_reagents
name = "Bar soft drink dispenser refill"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/water,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ice,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cream,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cola,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/smw,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/orange,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon
)
cost = 50
containertype = /obj/structure/closet/crate
containername = "soft drinks crate"
group = "Reagents"
/datum/supply_pack/coffee_reagents
name = "Coffee machine dispenser refill"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/milk,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cream,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ice
)
cost = 50
containertype = /obj/structure/closet/crate
containername = "coffee drinks crate"
group = "Reagents"
/datum/supply_pack/dispenser_cartridges
name = "Empty dispenser cartridges"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge
)
cost = 15
containertype = /obj/structure/closet/crate
containername = "dispenser cartridge crate"
group = "Reagents"
#define SEC_PACK(_tname, _type, _name, _cname, _cost, _access)\
datum/supply_pack/dispenser_cartridges{\
_tname {\
name = _name ;\
containername = _cname ;\
containertype = /obj/structure/closet/crate/secure;\
access = list( _access );\
cost = _cost ;\
contains = list( _type , _type );\
group = "Reagent Cartridges"\
}\
}
#define PACK(_tname, _type, _name, _cname, _cost)\
datum/supply_pack/dispenser_cartridges{\
_tname {\
name = _name ;\
containername = _cname ;\
containertype = /obj/structure/closet/crate;\
cost = _cost ;\
contains = list( _type , _type );\
group = "Reagent Cartridges"\
}\
}
// Chemistry-restricted (raw reagents excluding sugar/water)
// Datum path Contents type Supply pack name Container name Cost Container access
SEC_PACK(hydrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, "Reagent refill - Hydrogen", "hydrogen reagent cartridge crate", 15, access_chemistry)
SEC_PACK(lithium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, "Reagent refill - Lithium", "lithium reagent cartridge crate", 15, access_chemistry)
SEC_PACK(carbon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, "Reagent refill - Carbon", "carbon reagent cartridge crate", 15, access_chemistry)
SEC_PACK(nitrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, "Reagent refill - Nitrogen", "nitrogen reagent cartridge crate", 15, access_chemistry)
SEC_PACK(oxygen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, "Reagent refill - Oxygen", "oxygen reagent cartridge crate", 15, access_chemistry)
SEC_PACK(fluorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, "Reagent refill - Fluorine", "fluorine reagent cartridge crate", 15, access_chemistry)
SEC_PACK(sodium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, "Reagent refill - Sodium", "sodium reagent cartridge crate", 15, access_chemistry)
SEC_PACK(aluminium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, "Reagent refill - Aluminum", "aluminum reagent cartridge crate", 15, access_chemistry)
SEC_PACK(silicon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, "Reagent refill - Silicon", "silicon reagent cartridge crate", 15, access_chemistry)
SEC_PACK(phosphorus,/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, "Reagent refill - Phosphorus", "phosphorus reagent cartridge crate", 15, access_chemistry)
SEC_PACK(sulfur, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, "Reagent refill - Sulfur", "sulfur reagent cartridge crate", 15, access_chemistry)
SEC_PACK(chlorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, "Reagent refill - Chlorine", "chlorine reagent cartridge crate", 15, access_chemistry)
SEC_PACK(potassium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, "Reagent refill - Potassium", "potassium reagent cartridge crate", 15, access_chemistry)
SEC_PACK(iron, /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, "Reagent refill - Iron", "iron reagent cartridge crate", 15, access_chemistry)
SEC_PACK(copper, /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, "Reagent refill - Copper", "copper reagent cartridge crate", 15, access_chemistry)
SEC_PACK(mercury, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, "Reagent refill - Mercury", "mercury reagent cartridge crate", 15, access_chemistry)
SEC_PACK(radium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, "Reagent refill - Radium", "radium reagent cartridge crate", 15, access_chemistry)
SEC_PACK(ethanol, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, "Reagent refill - Ethanol", "ethanol reagent cartridge crate", 15, access_chemistry)
SEC_PACK(sacid, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, "Reagent refill - Sulfuric Acid", "sulfuric acid reagent cartridge crate", 15, access_chemistry)
SEC_PACK(tungsten, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, "Reagent refill - Tungsten", "tungsten reagent cartridge crate", 15, access_chemistry)
SEC_PACK(calcium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium, "Reagent refill - Calcium", "calcium reagent cartridge crate", 15, access_chemistry)
// Bar-restricted (alcoholic drinks)
// Datum path Contents type Supply pack name Container name Cost Container access
SEC_PACK(beer, /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, "Reagent refill - Beer", "beer reagent cartridge crate", 15, access_bar)
SEC_PACK(kahlua, /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, "Reagent refill - Kahlua", "kahlua reagent cartridge crate", 15, access_bar)
SEC_PACK(whiskey, /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, "Reagent refill - Whiskey", "whiskey reagent cartridge crate", 15, access_bar)
SEC_PACK(wine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, "Reagent refill - Wine", "wine reagent cartridge crate", 15, access_bar)
SEC_PACK(vodka, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, "Reagent refill - Vodka", "vodka reagent cartridge crate", 15, access_bar)
SEC_PACK(gin, /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, "Reagent refill - Gin", "gin reagent cartridge crate", 15, access_bar)
SEC_PACK(rum, /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, "Reagent refill - Rum", "rum reagent cartridge crate", 15, access_bar)
SEC_PACK(tequila, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, "Reagent refill - Tequila", "tequila reagent cartridge crate", 15, access_bar)
SEC_PACK(vermouth, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, "Reagent refill - Vermouth", "vermouth reagent cartridge crate", 15, access_bar)
SEC_PACK(cognac, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, "Reagent refill - Cognac", "cognac reagent cartridge crate", 15, access_bar)
SEC_PACK(ale, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, "Reagent refill - Ale", "ale reagent cartridge crate", 15, access_bar)
SEC_PACK(mead, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, "Reagent refill - Mead", "mead reagent cartridge crate", 15, access_bar)
// Unrestricted (water, sugar, non-alcoholic drinks)
// Datum path Contents type Supply pack name Container name Cost
PACK(water, /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, "Reagent refill - Water", "water reagent cartridge crate", 15)
PACK(sugar, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, "Reagent refill - Sugar", "sugar reagent cartridge crate", 15)
PACK(ice, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, "Reagent refill - Ice", "ice reagent cartridge crate", 15)
PACK(tea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, "Reagent refill - Tea", "tea reagent cartridge crate", 15)
PACK(icetea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, "Reagent refill - Iced Tea", "iced tea reagent cartridge crate", 15)
PACK(cola, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, "Reagent refill - Space Cola", "\improper Space Cola reagent cartridge crate", 15)
PACK(smw, /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, "Reagent refill - Space Mountain Wind", "\improper Space Mountain Wind reagent cartridge crate", 15)
PACK(dr_gibb, /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, "Reagent refill - Dr. Gibb", "\improper Dr. Gibb reagent cartridge crate", 15)
PACK(spaceup, /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, "Reagent refill - Space-Up", "\improper Space-Up reagent cartridge crate", 15)
PACK(tonic, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, "Reagent refill - Tonic Water", "tonic water reagent cartridge crate", 15)
PACK(sodawater, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, "Reagent refill - Soda Water", "soda water reagent cartridge crate", 15)
PACK(lemon_lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, "Reagent refill - Lemon-Lime Juice", "lemon-lime juice reagent cartridge crate", 15)
PACK(orange, /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, "Reagent refill - Orange Juice", "orange juice reagent cartridge crate", 15)
PACK(lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, "Reagent refill - Lime Juice", "lime juice reagent cartridge crate", 15)
PACK(lemon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, "Reagent refill - Lemon Juice", "lemon juice reagent cartridge crate", 15)
PACK(watermelon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, "Reagent refill - Watermelon Juice", "watermelon juice reagent cartridge crate", 15)
PACK(coffee, /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, "Reagent refill - Coffee", "coffee reagent cartridge crate", 15)
PACK(cafe_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, "Reagent refill - Cafe Latte", "cafe latte reagent cartridge crate", 15)
PACK(soy_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, "Reagent refill - Soy Latte", "soy latte reagent cartridge crate", 15)
PACK(hot_coco, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, "Reagent refill - Hot Coco", "hot coco reagent cartridge crate", 15)
PACK(milk, /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, "Reagent refill - Milk", "milk reagent cartridge crate", 15)
PACK(cream, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, "Reagent refill - Cream", "cream reagent cartridge crate", 15)
#undef SEC_PACK
#undef PACK
/datum/supply_pack/chemistry_dispenser
name = "Reagent dispenser"
contains = list(
/obj/machinery/chemical_dispenser{anchored = 0}
)
cost = 25
containertype = /obj/structure/largecrate
containername = "reagent dispenser crate"
group = "Reagents"
/datum/supply_pack/beer_dispenser
name = "Booze dispenser"
contains = list(
/obj/machinery/chemical_dispenser/bar_alc{anchored = 0}
)
cost = 25
containertype = /obj/structure/largecrate
containername = "booze dispenser crate"
group = "Reagents"
/datum/supply_pack/soda_dispenser
name = "Soda dispenser"
contains = list(
/obj/machinery/chemical_dispenser/bar_soft{anchored = 0}
)
cost = 25
containertype = /obj/structure/largecrate
containername = "soda dispenser crate"
group = "Reagents"
/datum/supply_pack/reagents
name = "Chemistry dispenser refill"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/iron,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/copper,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/radium,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/water,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten
)
cost = 150
containertype = /obj/structure/closet/crate/secure
containername = "chemical crate"
access = list(access_chemistry)
group = "Reagents"
/datum/supply_pack/alcohol_reagents
name = "Bar alcoholic dispenser refill"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/beer,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/wine,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/gin,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/rum,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ale,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/mead,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/bitters
)
cost = 50
containertype = /obj/structure/closet/crate/secure
containername = "alcoholic drinks crate"
access = list(access_bar)
group = "Reagents"
/datum/supply_pack/softdrink_reagents
name = "Bar soft drink dispenser refill"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/water,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ice,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cream,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cola,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/smw,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/orange,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lime,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon
)
cost = 50
containertype = /obj/structure/closet/crate
containername = "soft drinks crate"
group = "Reagents"
/datum/supply_pack/coffee_reagents
name = "Coffee machine dispenser refill"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/milk,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/cream,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/tea,
/obj/item/weapon/reagent_containers/chem_disp_cartridge/ice
)
cost = 50
containertype = /obj/structure/closet/crate
containername = "coffee drinks crate"
group = "Reagents"
/datum/supply_pack/dispenser_cartridges
name = "Empty dispenser cartridges"
contains = list(
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge,
/obj/item/weapon/reagent_containers/chem_disp_cartridge
)
cost = 15
containertype = /obj/structure/closet/crate
containername = "dispenser cartridge crate"
group = "Reagents"
#define SEC_PACK(_tname, _type, _name, _cname, _cost, _access)\
datum/supply_pack/dispenser_cartridges{\
_tname {\
name = _name ;\
containername = _cname ;\
containertype = /obj/structure/closet/crate/secure;\
access = list( _access );\
cost = _cost ;\
contains = list( _type , _type );\
group = "Reagent Cartridges"\
}\
}
#define PACK(_tname, _type, _name, _cname, _cost)\
datum/supply_pack/dispenser_cartridges{\
_tname {\
name = _name ;\
containername = _cname ;\
containertype = /obj/structure/closet/crate;\
cost = _cost ;\
contains = list( _type , _type );\
group = "Reagent Cartridges"\
}\
}
// Chemistry-restricted (raw reagents excluding sugar/water)
// Datum path Contents type Supply pack name Container name Cost Container access
SEC_PACK(hydrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hydrogen, "Reagent refill - Hydrogen", "hydrogen reagent cartridge crate", 15, access_chemistry)
SEC_PACK(lithium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lithium, "Reagent refill - Lithium", "lithium reagent cartridge crate", 15, access_chemistry)
SEC_PACK(carbon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/carbon, "Reagent refill - Carbon", "carbon reagent cartridge crate", 15, access_chemistry)
SEC_PACK(nitrogen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/nitrogen, "Reagent refill - Nitrogen", "nitrogen reagent cartridge crate", 15, access_chemistry)
SEC_PACK(oxygen, /obj/item/weapon/reagent_containers/chem_disp_cartridge/oxygen, "Reagent refill - Oxygen", "oxygen reagent cartridge crate", 15, access_chemistry)
SEC_PACK(fluorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/fluorine, "Reagent refill - Fluorine", "fluorine reagent cartridge crate", 15, access_chemistry)
SEC_PACK(sodium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodium, "Reagent refill - Sodium", "sodium reagent cartridge crate", 15, access_chemistry)
SEC_PACK(aluminium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/aluminum, "Reagent refill - Aluminum", "aluminum reagent cartridge crate", 15, access_chemistry)
SEC_PACK(silicon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/silicon, "Reagent refill - Silicon", "silicon reagent cartridge crate", 15, access_chemistry)
SEC_PACK(phosphorus,/obj/item/weapon/reagent_containers/chem_disp_cartridge/phosphorus, "Reagent refill - Phosphorus", "phosphorus reagent cartridge crate", 15, access_chemistry)
SEC_PACK(sulfur, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sulfur, "Reagent refill - Sulfur", "sulfur reagent cartridge crate", 15, access_chemistry)
SEC_PACK(chlorine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/chlorine, "Reagent refill - Chlorine", "chlorine reagent cartridge crate", 15, access_chemistry)
SEC_PACK(potassium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/potassium, "Reagent refill - Potassium", "potassium reagent cartridge crate", 15, access_chemistry)
SEC_PACK(iron, /obj/item/weapon/reagent_containers/chem_disp_cartridge/iron, "Reagent refill - Iron", "iron reagent cartridge crate", 15, access_chemistry)
SEC_PACK(copper, /obj/item/weapon/reagent_containers/chem_disp_cartridge/copper, "Reagent refill - Copper", "copper reagent cartridge crate", 15, access_chemistry)
SEC_PACK(mercury, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mercury, "Reagent refill - Mercury", "mercury reagent cartridge crate", 15, access_chemistry)
SEC_PACK(radium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/radium, "Reagent refill - Radium", "radium reagent cartridge crate", 15, access_chemistry)
SEC_PACK(ethanol, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ethanol, "Reagent refill - Ethanol", "ethanol reagent cartridge crate", 15, access_chemistry)
SEC_PACK(sacid, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sacid, "Reagent refill - Sulfuric Acid", "sulfuric acid reagent cartridge crate", 15, access_chemistry)
SEC_PACK(tungsten, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tungsten, "Reagent refill - Tungsten", "tungsten reagent cartridge crate", 15, access_chemistry)
SEC_PACK(calcium, /obj/item/weapon/reagent_containers/chem_disp_cartridge/calcium, "Reagent refill - Calcium", "calcium reagent cartridge crate", 15, access_chemistry)
// Bar-restricted (alcoholic drinks)
// Datum path Contents type Supply pack name Container name Cost Container access
SEC_PACK(beer, /obj/item/weapon/reagent_containers/chem_disp_cartridge/beer, "Reagent refill - Beer", "beer reagent cartridge crate", 15, access_bar)
SEC_PACK(kahlua, /obj/item/weapon/reagent_containers/chem_disp_cartridge/kahlua, "Reagent refill - Kahlua", "kahlua reagent cartridge crate", 15, access_bar)
SEC_PACK(whiskey, /obj/item/weapon/reagent_containers/chem_disp_cartridge/whiskey, "Reagent refill - Whiskey", "whiskey reagent cartridge crate", 15, access_bar)
SEC_PACK(wine, /obj/item/weapon/reagent_containers/chem_disp_cartridge/wine, "Reagent refill - Wine", "wine reagent cartridge crate", 15, access_bar)
SEC_PACK(vodka, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vodka, "Reagent refill - Vodka", "vodka reagent cartridge crate", 15, access_bar)
SEC_PACK(gin, /obj/item/weapon/reagent_containers/chem_disp_cartridge/gin, "Reagent refill - Gin", "gin reagent cartridge crate", 15, access_bar)
SEC_PACK(rum, /obj/item/weapon/reagent_containers/chem_disp_cartridge/rum, "Reagent refill - Rum", "rum reagent cartridge crate", 15, access_bar)
SEC_PACK(tequila, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tequila, "Reagent refill - Tequila", "tequila reagent cartridge crate", 15, access_bar)
SEC_PACK(vermouth, /obj/item/weapon/reagent_containers/chem_disp_cartridge/vermouth, "Reagent refill - Vermouth", "vermouth reagent cartridge crate", 15, access_bar)
SEC_PACK(cognac, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cognac, "Reagent refill - Cognac", "cognac reagent cartridge crate", 15, access_bar)
SEC_PACK(ale, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ale, "Reagent refill - Ale", "ale reagent cartridge crate", 15, access_bar)
SEC_PACK(mead, /obj/item/weapon/reagent_containers/chem_disp_cartridge/mead, "Reagent refill - Mead", "mead reagent cartridge crate", 15, access_bar)
// Unrestricted (water, sugar, non-alcoholic drinks)
// Datum path Contents type Supply pack name Container name Cost
PACK(water, /obj/item/weapon/reagent_containers/chem_disp_cartridge/water, "Reagent refill - Water", "water reagent cartridge crate", 15)
PACK(sugar, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sugar, "Reagent refill - Sugar", "sugar reagent cartridge crate", 15)
PACK(ice, /obj/item/weapon/reagent_containers/chem_disp_cartridge/ice, "Reagent refill - Ice", "ice reagent cartridge crate", 15)
PACK(tea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tea, "Reagent refill - Tea", "tea reagent cartridge crate", 15)
PACK(icetea, /obj/item/weapon/reagent_containers/chem_disp_cartridge/icetea, "Reagent refill - Iced Tea", "iced tea reagent cartridge crate", 15)
PACK(cola, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cola, "Reagent refill - Space Cola", "\improper Space Cola reagent cartridge crate", 15)
PACK(smw, /obj/item/weapon/reagent_containers/chem_disp_cartridge/smw, "Reagent refill - Space Mountain Wind", "\improper Space Mountain Wind reagent cartridge crate", 15)
PACK(dr_gibb, /obj/item/weapon/reagent_containers/chem_disp_cartridge/dr_gibb, "Reagent refill - Dr. Gibb", "\improper Dr. Gibb reagent cartridge crate", 15)
PACK(spaceup, /obj/item/weapon/reagent_containers/chem_disp_cartridge/spaceup, "Reagent refill - Space-Up", "\improper Space-Up reagent cartridge crate", 15)
PACK(tonic, /obj/item/weapon/reagent_containers/chem_disp_cartridge/tonic, "Reagent refill - Tonic Water", "tonic water reagent cartridge crate", 15)
PACK(sodawater, /obj/item/weapon/reagent_containers/chem_disp_cartridge/sodawater, "Reagent refill - Soda Water", "soda water reagent cartridge crate", 15)
PACK(lemon_lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon_lime, "Reagent refill - Lemon-Lime Juice", "lemon-lime juice reagent cartridge crate", 15)
PACK(orange, /obj/item/weapon/reagent_containers/chem_disp_cartridge/orange, "Reagent refill - Orange Juice", "orange juice reagent cartridge crate", 15)
PACK(lime, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lime, "Reagent refill - Lime Juice", "lime juice reagent cartridge crate", 15)
PACK(lemon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/lemon, "Reagent refill - Lemon Juice", "lemon juice reagent cartridge crate", 15)
PACK(watermelon, /obj/item/weapon/reagent_containers/chem_disp_cartridge/watermelon, "Reagent refill - Watermelon Juice", "watermelon juice reagent cartridge crate", 15)
PACK(coffee, /obj/item/weapon/reagent_containers/chem_disp_cartridge/coffee, "Reagent refill - Coffee", "coffee reagent cartridge crate", 15)
PACK(cafe_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cafe_latte, "Reagent refill - Cafe Latte", "cafe latte reagent cartridge crate", 15)
PACK(soy_latte, /obj/item/weapon/reagent_containers/chem_disp_cartridge/soy_latte, "Reagent refill - Soy Latte", "soy latte reagent cartridge crate", 15)
PACK(hot_coco, /obj/item/weapon/reagent_containers/chem_disp_cartridge/hot_coco, "Reagent refill - Hot Coco", "hot coco reagent cartridge crate", 15)
PACK(milk, /obj/item/weapon/reagent_containers/chem_disp_cartridge/milk, "Reagent refill - Milk", "milk reagent cartridge crate", 15)
PACK(cream, /obj/item/weapon/reagent_containers/chem_disp_cartridge/cream, "Reagent refill - Cream", "cream reagent cartridge crate", 15)
#undef SEC_PACK
#undef PACK

View File

@@ -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()

View File

@@ -0,0 +1,263 @@
/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
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

View 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

View File

@@ -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
// 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 FALSE
//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
if(RD.current_temp < temp_range[1] || RD.current_temp > temp_range[2])
return 0
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"

View 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"*/

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View File

@@ -1,305 +1,305 @@
/*
NOTE: IF YOU UPDATE THE REAGENT-SYSTEM, ALSO UPDATE THIS README.
Structure: /////////////////// //////////////////////////
// Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents.
/////////////////// //////////////////////////
| |
The object that holds everything. V
reagent_list var (list) A List of datums, each datum is a reagent.
| | |
V V V
reagents (datums) Reagents. I.e. Water , antitoxins or mercury.
Random important notes:
An objects on_reagent_change will be called every time the objects reagents change.
Useful if you want to update the objects icon etc.
About the Holder:
The holder (reagents datum) is the datum that holds a list of all reagents
currently in the object.It also has all the procs needed to manipulate reagents
Vars:
list/datum/reagent/reagent_list
List of reagent datums.
total_volume
Total volume of all reagents.
maximum_volume
Maximum volume.
atom/my_atom
Reference to the object that contains this.
Procs:
get_free_space()
Returns the remaining free volume in the holder.
get_master_reagent()
Returns the reference to the reagent with the largest volume
get_master_reagent_name()
Ditto, but returns the name.
get_master_reagent_id()
Ditto, but returns ID.
update_total()
Updates total volume, called automatically.
handle_reactions()
Checks reagents and triggers any reactions that happen. Usually called automatically.
add_reagent(var/id, var/amount, var/data = null, var/safety = 0)
Adds [amount] units of [id] reagent. [data] will be passed to reagent's mix_data() or initialize_data(). If [safety] is 0, handle_reactions() will be called. Returns 1 if successful, 0 otherwise.
remove_reagent(var/id, var/amount, var/safety = 0)
Ditto, but removes reagent. Returns 1 if successful, 0 otherwise.
del_reagent(var/id)
Removes all of the reagent.
has_reagent(var/id, var/amount = 0)
Checks if holder has at least [amount] of [id] reagent. Returns 1 if the reagent is found and volume is above [amount]. Returns 0 otherwise.
clear_reagents()
Removes all reagents.
get_reagent_amount(var/id)
Returns reagent volume. Returns 0 if reagent is not found.
get_data(var/id)
Returns get_data() of the reagent.
get_reagents()
Returns a string containing all reagent ids and volumes, e.g. "carbon(4),nittrogen(5)".
remove_any(var/amount = 1)
Removes up to [amount] of reagents from [src]. Returns actual amount removed.
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 [copy] is 1, copies reagents instead.
touch(var/atom/target)
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.
Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type.
Not recommended to use this directly, since trans_to() calls it before attempting to transfer.
touch_mob(var/mob/target)
Calls each reagent's touch_mob(target).
touch_turf(var/turf/target)
Calls each reagent's touch_turf(target).
touch_obj(var/obj/target)
Calls each reagent's touch_obj(target).
trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
The general proc for applying reagents to things externally (as opposed to directly injected into the contents).
It first calls touch, then the appropriate trans_to_*() or splash_mob().
If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc.
Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy).
trans_id_to(var/atom/target, var/id, var/amount = 1)
Transfers [amount] of [id] to [target]. Returns amount transferred.
splash_mob(var/mob/target, var/amount = 1, var/clothes = 1)
Checks mob's clothing if [clothes] is 1 and transfers [amount] reagents to mob's skin.
Don't call this directly. Call apply_to() instead.
trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0)
Transfers [amount] reagents to the mob's appropriate holder, depending on [type]. Ignores protection.
trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
Turfs don't currently have any reagents. Puts [amount] reagents into a temporary holder, calls touch_turf(target) from it, and deletes it.
trans_to_obj(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
If target has reagents, transfers [amount] to it. Otherwise, same as trans_to_turf().
atom/proc/create_reagents(var/max_vol)
Creates a new reagent datum.
About Reagents:
Reagents are all the things you can mix and fille in bottles etc. This can be anything from
rejuvs over water to... iron.
Vars:
name
Name that shows up in-game.
id
ID that is used for internal tracking. MUST BE UNIQUE.
description
Description that shows up in-game.
datum/reagents/holder
Reference to holder.
reagent_state
Could be GAS, LIQUID, or SOLID. Affects nothing. Reserved for future use.
list/data
Use varies by reagent. Custom variable. For example, blood stores blood group and viruses.
volume
Current volume.
metabolism
How quickly reagent is processed in mob's bloodstream; by default aslo affects ingest and touch metabolism.
ingest_met
How quickly reagent is processed when ingested; [metabolism] is used if zero.
touch_met
Ditto when touching.
dose
How much of the reagent has been processed, limited by [max_dose]. Used for reagents with varying effects (e.g. ethanol or rezadone) and overdosing.
max_dose
Maximum amount of reagent that has ever been in a mob. Exists so dose won't grow infinitely when small amounts of reagent are added over time.
overdose
If [dose] is bigger than [overdose], overdose() proc is called every tick.
scannable
If set to 1, will show up on health analyzers by name.
affects_dead
If set to 1, will affect dead players. Used by Adminordrazine.
glass_icon_state
Used by drinks. icon_state of the glass when this reagent is the master reagent.
glass_name
Ditto for glass name.
glass_desc
Ditto for glass desciption.
glass_center_of_mass
Used for glass placement on tables.
color
"#RRGGBB" or "#RRGGBBAA" where A is alpha channel.
color_weight
How much reagent affects color of holder. Used by paint.
Procs:
remove_self(var/amount)
Removes [amount] of itself.
touch_mob(var/mob/M)
Called when reagent is in another holder and not splashing the mob. Can be used with noncarbons.
touch_obj(var/obj/O)
How reagent reacts with objects.
touch_turf(var/turf/T)
How reagent reacts with turfs.
on_mob_life(var/mob/living/carbon/M, var/alien, var/location)
Makes necessary checks and calls one of affect procs.
affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
How reagent affects mob when injected. [removed] is the amount of reagent that has been removed this tick. [alien] is the mob's reagent flag.
affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
Ditto, ingested. Defaults to affect_blood with halved dose.
affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
Ditto, touching.
overdose(var/mob/living/carbon/M, var/alien)
Called when dose is above overdose. Defaults to M.adjustToxLoss(REM).
initialize_data(var/newdata)
Called when reagent is created. Defaults to setting [data] to [newdata].
mix_data(var/newdata, var/newamount)
Called when [newamount] of reagent with [newdata] data is added to the current reagent. Used by paint.
get_data()
Returns data. Can be overriden.
About Recipes:
Recipes are simple datums that contain a list of required reagents and a result.
They also have a proc that is called when the recipe is matched.
Vars:
name
Name of the reaction, currently unused.
id
ID of the reaction, must be unique.
result
ID of the resulting reagent. Can be null.
list/required_reagents
Reagents that are required for the reaction and are used up during it.
list/catalysts
Ditto, but not used up.
list/inhibitors
Opposite, prevent the reaction from happening.
result_amount
Amount of resulting reagent.
mix_message
Message that is shown to mobs when reaction happens.
Procs:
can_happen(var/datum/reagents/holder)
Customizable. If it returns 0, reaction will not happen. Defaults to always returning 1. Used by slime core reactions.
on_reaction(var/datum/reagents/holder, var/created_volume)
Called when reaction happens. Used by explosives.
send_data(var/datum/reagents/T)
Sets resulting reagent's data. Used by blood paint.
About the Tools:
By default, all atom have a reagents var - but its empty. if you want to use an object for the chem.
system you'll need to add something like this in its new proc:
atom/proc/create_reagents(var/max_volume)
Other important stuff:
amount_per_transfer_from_this var
This var is mostly used by beakers and bottles.
It simply tells us how much to transfer when
'pouring' our reagents into something else.
atom/proc/is_open_container()
Checks atom/var/flags & OPENCONTAINER.
If this returns 1 , you can use syringes, beakers etc
to manipulate the contents of this object.
If it's 0, you'll need to write your own custom reagent
transfer code since you will not be able to use the standard
tools to manipulate it.
/*
NOTE: IF YOU UPDATE THE REAGENT-SYSTEM, ALSO UPDATE THIS README.
Structure: /////////////////// //////////////////////////
// Mob or object // -------> // Reagents var (datum) // Is a reference to the datum that holds the reagents.
/////////////////// //////////////////////////
| |
The object that holds everything. V
reagent_list var (list) A List of datums, each datum is a reagent.
| | |
V V V
reagents (datums) Reagents. I.e. Water , antitoxins or mercury.
Random important notes:
An objects on_reagent_change will be called every time the objects reagents change.
Useful if you want to update the objects icon etc.
About the Holder:
The holder (reagents datum) is the datum that holds a list of all reagents
currently in the object.It also has all the procs needed to manipulate reagents
Vars:
list/datum/reagent/reagent_list
List of reagent datums.
total_volume
Total volume of all reagents.
maximum_volume
Maximum volume.
atom/my_atom
Reference to the object that contains this.
Procs:
get_free_space()
Returns the remaining free volume in the holder.
get_master_reagent()
Returns the reference to the reagent with the largest volume
get_master_reagent_name()
Ditto, but returns the name.
get_master_reagent_id()
Ditto, but returns ID.
update_total()
Updates total volume, called automatically.
handle_reactions()
Checks reagents and triggers any reactions that happen. Usually called automatically.
add_reagent(var/id, var/amount, var/data = null, var/safety = 0)
Adds [amount] units of [id] reagent. [data] will be passed to reagent's mix_data() or initialize_data(). If [safety] is 0, handle_reactions() will be called. Returns 1 if successful, 0 otherwise.
remove_reagent(var/id, var/amount, var/safety = 0)
Ditto, but removes reagent. Returns 1 if successful, 0 otherwise.
del_reagent(var/id)
Removes all of the reagent.
has_reagent(var/id, var/amount = 0)
Checks if holder has at least [amount] of [id] reagent. Returns 1 if the reagent is found and volume is above [amount]. Returns 0 otherwise.
clear_reagents()
Removes all reagents.
get_reagent_amount(var/id)
Returns reagent volume. Returns 0 if reagent is not found.
get_data(var/id)
Returns get_data() of the reagent.
get_reagents()
Returns a string containing all reagent ids and volumes, e.g. "carbon(4),nittrogen(5)".
remove_any(var/amount = 1)
Removes up to [amount] of reagents from [src]. Returns actual amount removed.
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 [copy] is 1, copies reagents instead.
touch(var/atom/target)
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.
Basically just defers to touch_mob(target), touch_turf(target), or touch_obj(target), depending on target's type.
Not recommended to use this directly, since trans_to() calls it before attempting to transfer.
touch_mob(var/mob/target)
Calls each reagent's touch_mob(target).
touch_turf(var/turf/target)
Calls each reagent's touch_turf(target).
touch_obj(var/obj/target)
Calls each reagent's touch_obj(target).
trans_to(var/atom/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
The general proc for applying reagents to things externally (as opposed to directly injected into the contents).
It first calls touch, then the appropriate trans_to_*() or splash_mob().
If for some reason you want touch effects to be bypassed (e.g. injecting stuff directly into a reagent container or person), call the appropriate trans_to_*() proc.
Calls touch() before checking the type of [target], calling splash_mob(target, amount), trans_to_turf(target, amount, multiplier, copy), or trans_to_obj(target, amount, multiplier, copy).
trans_id_to(var/atom/target, var/id, var/amount = 1)
Transfers [amount] of [id] to [target]. Returns amount transferred.
splash_mob(var/mob/target, var/amount = 1, var/clothes = 1)
Checks mob's clothing if [clothes] is 1 and transfers [amount] reagents to mob's skin.
Don't call this directly. Call apply_to() instead.
trans_to_mob(var/mob/target, var/amount = 1, var/type = CHEM_BLOOD, var/multiplier = 1, var/copy = 0)
Transfers [amount] reagents to the mob's appropriate holder, depending on [type]. Ignores protection.
trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
Turfs don't currently have any reagents. Puts [amount] reagents into a temporary holder, calls touch_turf(target) from it, and deletes it.
trans_to_obj(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0)
If target has reagents, transfers [amount] to it. Otherwise, same as trans_to_turf().
atom/proc/create_reagents(var/max_vol)
Creates a new reagent datum.
About Reagents:
Reagents are all the things you can mix and fille in bottles etc. This can be anything from
rejuvs over water to... iron.
Vars:
name
Name that shows up in-game.
id
ID that is used for internal tracking. MUST BE UNIQUE.
description
Description that shows up in-game.
datum/reagents/holder
Reference to holder.
reagent_state
Could be GAS, LIQUID, or SOLID. Affects nothing. Reserved for future use.
list/data
Use varies by reagent. Custom variable. For example, blood stores blood group and viruses.
volume
Current volume.
metabolism
How quickly reagent is processed in mob's bloodstream; by default aslo affects ingest and touch metabolism.
ingest_met
How quickly reagent is processed when ingested; [metabolism] is used if zero.
touch_met
Ditto when touching.
dose
How much of the reagent has been processed, limited by [max_dose]. Used for reagents with varying effects (e.g. ethanol or rezadone) and overdosing.
max_dose
Maximum amount of reagent that has ever been in a mob. Exists so dose won't grow infinitely when small amounts of reagent are added over time.
overdose
If [dose] is bigger than [overdose], overdose() proc is called every tick.
scannable
If set to 1, will show up on health analyzers by name.
affects_dead
If set to 1, will affect dead players. Used by Adminordrazine.
glass_icon_state
Used by drinks. icon_state of the glass when this reagent is the master reagent.
glass_name
Ditto for glass name.
glass_desc
Ditto for glass desciption.
glass_center_of_mass
Used for glass placement on tables.
color
"#RRGGBB" or "#RRGGBBAA" where A is alpha channel.
color_weight
How much reagent affects color of holder. Used by paint.
Procs:
remove_self(var/amount)
Removes [amount] of itself.
touch_mob(var/mob/M)
Called when reagent is in another holder and not splashing the mob. Can be used with noncarbons.
touch_obj(var/obj/O)
How reagent reacts with objects.
touch_turf(var/turf/T)
How reagent reacts with turfs.
on_mob_life(var/mob/living/carbon/M, var/alien, var/location)
Makes necessary checks and calls one of affect procs.
affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
How reagent affects mob when injected. [removed] is the amount of reagent that has been removed this tick. [alien] is the mob's reagent flag.
affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
Ditto, ingested. Defaults to affect_blood with halved dose.
affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
Ditto, touching.
overdose(var/mob/living/carbon/M, var/alien)
Called when dose is above overdose. Defaults to M.adjustToxLoss(REM).
initialize_data(var/newdata)
Called when reagent is created. Defaults to setting [data] to [newdata].
mix_data(var/newdata, var/newamount)
Called when [newamount] of reagent with [newdata] data is added to the current reagent. Used by paint.
get_data()
Returns data. Can be overriden.
About Recipes:
Recipes are simple datums that contain a list of required reagents and a result.
They also have a proc that is called when the recipe is matched.
Vars:
name
Name of the reaction, currently unused.
id
ID of the reaction, must be unique.
result
ID of the resulting reagent. Can be null.
list/required_reagents
Reagents that are required for the reaction and are used up during it.
list/catalysts
Ditto, but not used up.
list/inhibitors
Opposite, prevent the reaction from happening.
result_amount
Amount of resulting reagent.
mix_message
Message that is shown to mobs when reaction happens.
Procs:
can_happen(var/datum/reagents/holder)
Customizable. If it returns 0, reaction will not happen. Defaults to always returning 1. Used by slime core reactions.
on_reaction(var/datum/reagents/holder, var/created_volume)
Called when reaction happens. Used by explosives.
send_data(var/datum/reagents/T)
Sets resulting reagent's data. Used by blood paint.
About the Tools:
By default, all atom have a reagents var - but its empty. if you want to use an object for the chem.
system you'll need to add something like this in its new proc:
atom/proc/create_reagents(var/max_volume)
Other important stuff:
amount_per_transfer_from_this var
This var is mostly used by beakers and bottles.
It simply tells us how much to transfer when
'pouring' our reagents into something else.
atom/proc/is_open_container()
Checks atom/var/flags & OPENCONTAINER.
If this returns 1 , you can use syringes, beakers etc
to manipulate the contents of this object.
If it's 0, you'll need to write your own custom reagent
transfer code since you will not be able to use the standard
tools to manipulate it.
*/

View File

@@ -1,145 +1,145 @@
/obj/item/weapon/reagent_containers
name = "Container"
desc = "..."
icon = 'icons/obj/chemical.dmi'
icon_state = null
w_class = ITEMSIZE_SMALL
var/amount_per_transfer_from_this = 5
var/possible_transfer_amounts = list(5,10,15,25,30)
var/volume = 30
/obj/item/weapon/reagent_containers/verb/set_APTFT() //set amount_per_transfer_from_this
set name = "Set transfer amount"
set category = "Object"
set src in range(0)
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/item/weapon/reagent_containers/Initialize()
. = ..()
if(!possible_transfer_amounts)
src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT
create_reagents(volume)
/obj/item/weapon/reagent_containers/attack_self(mob/user as mob)
return
/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user, flag)
return
/obj/item/weapon/reagent_containers/proc/reagentlist() // For attack logs
if(reagents)
return reagents.get_reagents()
return "No reagent holder"
/obj/item/weapon/reagent_containers/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) // This goes into afterattack
if(!istype(target))
return 0
if(!target.reagents || !target.reagents.total_volume)
to_chat(user, "<span class='notice'>[target] is empty.</span>")
return 1
if(reagents && !reagents.get_free_space())
to_chat(user, "<span class='notice'>[src] is full.</span>")
return 1
var/trans = target.reagents.trans_to_obj(src, target:amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
return 1
/obj/item/weapon/reagent_containers/proc/standard_splash_mob(var/mob/user, var/mob/target) // This goes into afterattack
if(!istype(target))
return
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return 1
if(target.reagents && !target.reagents.get_free_space())
to_chat(user, "<span class='notice'>[target] is full.</span>")
return 1
var/contained = reagentlist()
add_attack_logs(user,target,"Splashed with [src.name] containing [contained]")
user.visible_message("<span class='danger'>[target] has been splashed with something by [user]!</span>", "<span class = 'notice'>You splash the solution onto [target].</span>")
reagents.splash(target, reagents.total_volume)
return 1
/obj/item/weapon/reagent_containers/proc/self_feed_message(var/mob/user)
to_chat(user, "<span class='notice'>You eat \the [src]</span>")
/obj/item/weapon/reagent_containers/proc/other_feed_message_start(var/mob/user, var/mob/target)
user.visible_message("<span class='warning'>[user] is trying to feed [target] \the [src]!</span>")
/obj/item/weapon/reagent_containers/proc/other_feed_message_finish(var/mob/user, var/mob/target)
user.visible_message("<span class='warning'>[user] has fed [target] \the [src]!</span>")
/obj/item/weapon/reagent_containers/proc/feed_sound(var/mob/user)
return
/obj/item/weapon/reagent_containers/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack
if(!istype(target))
return 0
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='notice'>\The [src] is empty.</span>")
return 1
if(target == user)
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = user
if(!H.check_has_mouth())
to_chat(user, "Where do you intend to put \the [src]? You don't have a mouth!")
return
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
to_chat(user, "<span class='warning'>\The [blocked] is in the way!</span>")
return
user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things
self_feed_message(user)
reagents.trans_to_mob(user, issmall(user) ? CEILING(amount_per_transfer_from_this/2, 1) : amount_per_transfer_from_this, CHEM_INGEST)
feed_sound(user)
return 1
else
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
if(!H.check_has_mouth())
to_chat(user, "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!")
return
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
to_chat(user, "<span class='warning'>\The [blocked] is in the way!</span>")
return
other_feed_message_start(user, target)
user.setClickCooldown(user.get_attack_speed(src))
if(!do_mob(user, target))
return
other_feed_message_finish(user, target)
var/contained = reagentlist()
add_attack_logs(user,target,"Fed from [src.name] containing [contained]")
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INGEST)
feed_sound(user)
return 1
/obj/item/weapon/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level
if(!target.is_open_container() || !target.reagents)
return 0
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return 1
if(!target.reagents.get_free_space())
to_chat(user, "<span class='notice'>[target] is full.</span>")
return 1
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] units of the solution to [target].</span>")
return 1
/obj/item/weapon/reagent_containers
name = "Container"
desc = "..."
icon = 'icons/obj/chemical.dmi'
icon_state = null
w_class = ITEMSIZE_SMALL
var/amount_per_transfer_from_this = 5
var/possible_transfer_amounts = list(5,10,15,25,30)
var/volume = 30
/obj/item/weapon/reagent_containers/verb/set_APTFT() //set amount_per_transfer_from_this
set name = "Set transfer amount"
set category = "Object"
set src in range(0)
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/item/weapon/reagent_containers/Initialize()
. = ..()
if(!possible_transfer_amounts)
src.verbs -= /obj/item/weapon/reagent_containers/verb/set_APTFT
create_reagents(volume)
/obj/item/weapon/reagent_containers/attack_self(mob/user as mob)
return
/obj/item/weapon/reagent_containers/afterattack(obj/target, mob/user, flag)
return
/obj/item/weapon/reagent_containers/proc/reagentlist() // For attack logs
if(reagents)
return reagents.get_reagents()
return "No reagent holder"
/obj/item/weapon/reagent_containers/proc/standard_dispenser_refill(var/mob/user, var/obj/structure/reagent_dispensers/target) // This goes into afterattack
if(!istype(target))
return 0
if(!target.reagents || !target.reagents.total_volume)
to_chat(user, "<span class='notice'>[target] is empty.</span>")
return 1
if(reagents && !reagents.get_free_space())
to_chat(user, "<span class='notice'>[src] is full.</span>")
return 1
var/trans = target.reagents.trans_to_obj(src, target:amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You fill [src] with [trans] units of the contents of [target].</span>")
return 1
/obj/item/weapon/reagent_containers/proc/standard_splash_mob(var/mob/user, var/mob/target) // This goes into afterattack
if(!istype(target))
return
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return 1
if(target.reagents && !target.reagents.get_free_space())
to_chat(user, "<span class='notice'>[target] is full.</span>")
return 1
var/contained = reagentlist()
add_attack_logs(user,target,"Splashed with [src.name] containing [contained]")
user.visible_message("<span class='danger'>[target] has been splashed with something by [user]!</span>", "<span class = 'notice'>You splash the solution onto [target].</span>")
reagents.splash(target, reagents.total_volume)
return 1
/obj/item/weapon/reagent_containers/proc/self_feed_message(var/mob/user)
to_chat(user, "<span class='notice'>You eat \the [src]</span>")
/obj/item/weapon/reagent_containers/proc/other_feed_message_start(var/mob/user, var/mob/target)
user.visible_message("<span class='warning'>[user] is trying to feed [target] \the [src]!</span>")
/obj/item/weapon/reagent_containers/proc/other_feed_message_finish(var/mob/user, var/mob/target)
user.visible_message("<span class='warning'>[user] has fed [target] \the [src]!</span>")
/obj/item/weapon/reagent_containers/proc/feed_sound(var/mob/user)
return
/obj/item/weapon/reagent_containers/proc/standard_feed_mob(var/mob/user, var/mob/target) // This goes into attack
if(!istype(target))
return 0
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='notice'>\The [src] is empty.</span>")
return 1
if(target == user)
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = user
if(!H.check_has_mouth())
to_chat(user, "Where do you intend to put \the [src]? You don't have a mouth!")
return
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
to_chat(user, "<span class='warning'>\The [blocked] is in the way!</span>")
return
user.setClickCooldown(user.get_attack_speed(src)) //puts a limit on how fast people can eat/drink things
self_feed_message(user)
reagents.trans_to_mob(user, issmall(user) ? CEILING(amount_per_transfer_from_this/2, 1) : amount_per_transfer_from_this, CHEM_INGEST)
feed_sound(user)
return 1
else
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
if(!H.check_has_mouth())
to_chat(user, "Where do you intend to put \the [src]? \The [H] doesn't have a mouth!")
return
var/obj/item/blocked = H.check_mouth_coverage()
if(blocked)
to_chat(user, "<span class='warning'>\The [blocked] is in the way!</span>")
return
other_feed_message_start(user, target)
user.setClickCooldown(user.get_attack_speed(src))
if(!do_mob(user, target))
return
other_feed_message_finish(user, target)
var/contained = reagentlist()
add_attack_logs(user,target,"Fed from [src.name] containing [contained]")
reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_INGEST)
feed_sound(user)
return 1
/obj/item/weapon/reagent_containers/proc/standard_pour_into(var/mob/user, var/atom/target) // This goes into afterattack and yes, it's atom-level
if(!target.is_open_container() || !target.reagents)
return 0
if(!reagents || !reagents.total_volume)
to_chat(user, "<span class='notice'>[src] is empty.</span>")
return 1
if(!target.reagents.get_free_space())
to_chat(user, "<span class='notice'>[target] is full.</span>")
return 1
var/trans = reagents.trans_to(target, amount_per_transfer_from_this)
to_chat(user, "<span class='notice'>You transfer [trans] units of the solution to [target].</span>")
return 1

View File

@@ -1,237 +1,237 @@
/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)

View File

@@ -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"

View File

@@ -72,14 +72,9 @@ won't update every console in existence) but it's more of a hassle to do. Also,
/obj/machinery/computer/rdconsole/proc/CallReagentName(var/ID)
var/return_name = ID
var/datum/reagent/temp_reagent
for(var/R in (typesof(/datum/reagent) - /datum/reagent))
temp_reagent = null
temp_reagent = new R()
if(temp_reagent.id == ID)
return_name = temp_reagent.name
qdel(temp_reagent)
temp_reagent = null
for(var/datum/reagent/R in SSchemistry.chemical_reagents)
if(R.id == ID)
return_name = R.name
break
return return_name

View File

@@ -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))
..()

View File

@@ -214,6 +214,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\dcs.dm"
#include "code\controllers\subsystems\events.dm"
@@ -246,7 +247,6 @@
#include "code\controllers\subsystems\timer.dm"
#include "code\controllers\subsystems\vote.dm"
#include "code\controllers\subsystems\xenoarch.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"
@@ -2710,7 +2710,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"
@@ -2832,36 +2831,33 @@
#include "code\modules\random_map\noise\ore.dm"
#include "code\modules\random_map\noise\tundra.dm"
#include "code\modules\reagents\Chemistry-Colours.dm"
#include "code\modules\reagents\Chemistry-Holder.dm"
#include "code\modules\reagents\Chemistry-Logging.dm"
#include "code\modules\reagents\Chemistry-Machinery.dm"
#include "code\modules\reagents\Chemistry-Metabolism.dm"
#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-Recipes.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-Medicine.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\dispenser\_defines.dm"
#include "code\modules\reagents\dispenser\cartridge.dm"
#include "code\modules\reagents\dispenser\cartridge_presets.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\supply.dm"
#include "code\modules\reagents\distilling\Distilling-Recipes.dm"
#include "code\modules\reagents\distilling\distilling.dm"
#include "code\modules\reagents\holder\holder.dm"
#include "code\modules\reagents\holder\distilling.dm"
#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\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_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\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\food.dm"
#include "code\modules\reagents\reactions\instant\instant.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\borghypo.dm"
#include "code\modules\reagents\reagent_containers\dropper.dm"
@@ -2872,6 +2868,15 @@
#include "code\modules\reagents\reagent_containers\spray.dm"
#include "code\modules\reagents\reagent_containers\syringes.dm"
#include "code\modules\reagents\reagent_containers\unidentified_hypospray.dm"
#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\medicine.dm"
#include "code\modules\reagents\reagents\modifiers.dm"
#include "code\modules\reagents\reagents\other.dm"
#include "code\modules\reagents\reagents\toxins.dm"
#include "code\modules\recycling\conveyor2.dm"
#include "code\modules\recycling\disposal-construction.dm"
#include "code\modules\recycling\disposal.dm"