/
reagents.dm
263 lines (223 loc) · 10.5 KB
/
reagents.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#define REM REAGENTS_EFFECT_MULTIPLIER
GLOBAL_LIST_INIT(name2reagent, build_name2reagent())
/proc/build_name2reagent()
. = list()
for (var/t in subtypesof(/datum/reagent))
var/datum/reagent/R = t
if (length(initial(R.name)))
.[ckey(initial(R.name))] = t
//Various reagents
//Toxin & acid reagents
//Hydroponics stuff
/// A single reagent
/datum/reagent
/// datums don't have names by default
var/name = "Reagent"
/// nor do they have descriptions
var/description = ""
///J/(K*mol)
var/specific_heat = SPECIFIC_HEAT_DEFAULT
/// used by taste messages
var/taste_description = "metaphorical salt"
///how this taste compares to others. Higher values means it is more noticable
var/taste_mult = 1
/// use for specialty drinks.
var/glass_name = "glass of ...what?"
/// desc applied to glasses with this reagent
var/glass_desc = "You can't really tell what this is."
/// Otherwise just sets the icon to a normal glass with the mixture of the reagents in the glass.
var/glass_icon_state = null
/// used for shot glasses, mostly for alcohol
var/shot_glass_icon_state = null
/// fallback icon if the reagent has no glass or shot glass icon state. Used for restaurants.
var/fallback_icon_state = null
/// reagent holder this belongs to
var/datum/reagents/holder = null
/// LIQUID, SOLID, GAS
var/reagent_state = LIQUID
/// special data associated with this like viruses etc
var/list/data
/// increments everytime on_mob_life is called
var/current_cycle = 0
///pretend this is moles
var/volume = 0
/// pH of the reagent
var/ph = 7
///Purity of the reagent - for use with internal reaction mechanics only. Use below (creation_purity) if you're writing purity effects into a reagent's use mechanics.
var/purity = 1
///the purity of the reagent on creation (i.e. when it's added to a mob and it's purity split it into 2 chems; the purity of the resultant chems are kept as 1, this tracks what the purity was before that)
var/creation_purity = 1
///The molar mass of the reagent - if you're adding a reagent that doesn't have a recipe, just add a random number between 10 - 800. Higher numbers are "harder" but it's mostly arbitary.
var/mass
/// color it looks in containers etc
var/color = "#000000" // rgb: 0, 0, 0
///how fast the reagent is metabolized by the mob
var/metabolization_rate = REAGENTS_METABOLISM
/// appears unused
var/overrides_metab = 0
/// above this overdoses happen
var/overdose_threshold = 0
/// You fucked up and this is now triggering its overdose effects, purge that shit quick.
var/overdosed = FALSE
///if false stops metab in liverless mobs
var/self_consuming = FALSE
///affects how far it travels when sprayed
var/reagent_weight = 1
///is it currently metabolizing
var/metabolizing = FALSE
/// is it bad for you? Currently only used for borghypo. C2s and Toxins have it TRUE by default.
var/harmful = FALSE
/// Are we from a material? We might wanna know that for special stuff. Like metalgen. Is replaced with a ref of the material on New()
var/datum/material/material
///A list of causes why this chem should skip being removed, if the length is 0 it will be removed from holder naturally, if this is >0 it will not be removed from the holder.
var/list/reagent_removal_skip_list = list()
///The set of exposure methods this penetrates skin with.
var/penetrates_skin = VAPOR
/// See fermi_readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_INVISIBLE, REAGENT_SNEAKYNAME, REAGENT_SPLITRETAINVOL, REAGENT_CANSYNTH, REAGENT_IMPURE
var/chemical_flags = NONE
///impure chem values (see fermi_readme.dm for more details on impure/inverse/failed mechanics):
/// What chemical path is made when metabolised as a function of purity
var/impure_chem = /datum/reagent/impurity
/// If the impurity is below 0.5, replace ALL of the chem with inverse_chem upon metabolising
var/inverse_chem_val = 0.25
/// What chem is metabolised when purity is below inverse_chem_val
var/inverse_chem = /datum/reagent/inverse
///what chem is made at the end of a reaction IF the purity is below the recipies purity_min at the END of a reaction only
var/failed_chem = /datum/reagent/consumable/failed_reaction
///Thermodynamic vars
///How hot this reagent burns when it's on fire - null means it can't burn
var/burning_temperature = null
///How much is consumed when it is burnt per second
var/burning_volume = 0.5
///Assoc list with key type of addiction this reagent feeds, and value amount of addiction points added per unit of reagent metabolzied (which means * REAGENTS_METABOLISM every life())
var/list/addiction_types = null
///The amount a robot will pay for a glass of this (20 units but can be higher if you pour more, be frugal!)
var/glass_price
/datum/reagent/New()
SHOULD_CALL_PARENT(TRUE)
. = ..()
if(material)
material = GET_MATERIAL_REF(material)
if(glass_price)
AddElement(/datum/element/venue_price, glass_price)
if(!mass)
mass = rand(10, 800)
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
. = ..()
holder = null
/// Applies this reagent to an [/atom]
/datum/reagent/proc/expose_atom(atom/exposed_atom, reac_volume)
SHOULD_CALL_PARENT(TRUE)
. = 0
. |= SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_ATOM, exposed_atom, reac_volume)
. |= SEND_SIGNAL(exposed_atom, COMSIG_ATOM_EXPOSE_REAGENT, src, reac_volume)
/// Applies this reagent to a [/mob/living]
/datum/reagent/proc/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0)
SHOULD_CALL_PARENT(TRUE)
. = SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_MOB, exposed_mob, methods, reac_volume, show_message, touch_protection)
if((methods & penetrates_skin) && exposed_mob.reagents) //smoke, foam, spray
var/amount = round(reac_volume*clamp((1 - touch_protection), 0, 1), 0.1)
if(amount >= 0.5)
exposed_mob.reagents.add_reagent(type, amount, added_purity = purity)
/// Applies this reagent to an [/obj]
/datum/reagent/proc/expose_obj(obj/exposed_obj, reac_volume)
SHOULD_CALL_PARENT(TRUE)
return SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_OBJ, exposed_obj, reac_volume)
/// Applies this reagent to a [/turf]
/datum/reagent/proc/expose_turf(turf/exposed_turf, reac_volume)
SHOULD_CALL_PARENT(TRUE)
return SEND_SIGNAL(src, COMSIG_REAGENT_EXPOSE_TURF, exposed_turf, reac_volume)
///Called whenever a reagent is on fire, or is in a holder that is on fire. (WIP)
/datum/reagent/proc/burn(datum/reagents/holder)
return
/// Called from [/datum/reagents/proc/metabolize]
/datum/reagent/proc/on_mob_life(mob/living/carbon/M, delta_time, times_fired)
current_cycle++
if(length(reagent_removal_skip_list))
return
holder.remove_reagent(type, metabolization_rate * M.metabolism_efficiency * delta_time) //By default it slowly disappears.
/*
Used to run functions before a reagent is transfered. Returning TRUE will block the transfer attempt.
Primarily used in reagents/reaction_agents
*/
/datum/reagent/proc/intercept_reagents_transfer(datum/reagents/target)
return FALSE
///Called after a reagent is transfered
/datum/reagent/proc/on_transfer(atom/A, methods=TOUCH, trans_volume)
return
/// Called when this reagent is first added to a mob
/datum/reagent/proc/on_mob_add(mob/living/L, amount)
overdose_threshold /= max(normalise_creation_purity(), 1) //Maybe??? Seems like it would help pure chems be even better but, if I normalised this to 1, then everything would take a 25% reduction
return
/// Called when this reagent is removed while inside a mob
/datum/reagent/proc/on_mob_delete(mob/living/L)
SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "[type]_overdose")
return
/// Called when this reagent first starts being metabolized by a liver
/datum/reagent/proc/on_mob_metabolize(mob/living/L)
return
/// Called when this reagent stops being metabolized by a liver
/datum/reagent/proc/on_mob_end_metabolize(mob/living/L)
return
/// Called when a reagent is inside of a mob when they are dead
/datum/reagent/proc/on_mob_dead(mob/living/carbon/C, delta_time)
if(!(chemical_flags & REAGENT_DEAD_PROCESS))
return
current_cycle++
if(length(reagent_removal_skip_list))
return
holder.remove_reagent(type, metabolization_rate * C.metabolism_efficiency * delta_time)
/// Called by [/datum/reagents/proc/conditional_update_move]
/datum/reagent/proc/on_move(mob/M)
return
/// Called after add_reagents creates a new reagent.
/datum/reagent/proc/on_new(data)
return
/// Called when two reagents of the same are mixing.
/datum/reagent/proc/on_merge(data, amount)
return
/// Called by [/datum/reagents/proc/conditional_update]
/datum/reagent/proc/on_update(atom/A)
return
/// Called when the reagent container is hit by an explosion
/datum/reagent/proc/on_ex_act(severity)
return
/// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects
/datum/reagent/proc/overdose_process(mob/living/M, delta_time, times_fired)
return
/// Called when an overdose starts
/datum/reagent/proc/overdose_start(mob/living/M)
to_chat(M, span_userdanger("You feel like you took too much of [name]!"))
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[type]_overdose", /datum/mood_event/overdose, name)
return
/**
* New, standardized method for chemicals to affect hydroponics trays.
* Defined on a per-chem level as opposed to by the tray.
* Can affect plant's health, stats, or cause the plant to react in certain ways.
*/
/datum/reagent/proc/on_hydroponics_apply(obj/item/seeds/myseed, datum/reagents/chems, obj/machinery/hydroponics/mytray, mob/user)
if(!mytray)
return
/// Should return a associative list where keys are taste descriptions and values are strength ratios
/datum/reagent/proc/get_taste_description(mob/living/taster)
return list("[taste_description]" = 1)
/**
* Used when you want the default reagents purity to be equal to the normal effects
* (i.e. if default purity is 0.75, and your reacted purity is 1, then it will return 1.33)
*
* Arguments
* * normalise_num_to - what number/purity value you're normalising to. If blank it will default to the compile value of purity for this chem
* * creation_purity - creation_purity override, if desired. This is the purity of the reagent that you're normalising from.
*/
/datum/reagent/proc/normalise_creation_purity(normalise_num_to, creation_purity)
if(!normalise_num_to)
normalise_num_to = initial(purity)
if(!creation_purity)
creation_purity = src.creation_purity
return creation_purity / normalise_num_to
/proc/pretty_string_from_reagent_list(list/reagent_list)
//Convert reagent list to a printable string for logging etc
var/list/rs = list()
for (var/datum/reagent/R in reagent_list)
rs += "[R.name], [R.volume]"
return rs.Join(" | ")