forked from Aurorastation/Aurora.3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Chemistry-Reagents.dm
141 lines (113 loc) · 5.04 KB
/
Chemistry-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
/datum/reagent
var/name = "Reagent"
var/id = "reagent"
var/description = "A non-descript chemical."
var/taste_description = "old rotten bandaids"
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/ingest_met = 0
var/touch_met = 0
var/breathe_met = 0
var/dose = 0
var/max_dose = 0
var/overdose = 0
var/scannable = 0 // Shows up on health analyzers.
var/affects_dead = 0
var/glass_icon_state = null
var/glass_name = null
var/glass_desc = null
var/glass_center_of_mass = null
var/color = "#000000"
var/color_weight = 1
var/unaffected_species = IS_DIONA | IS_MACHINE // Species that aren't affected by this reagent. Does not prevent affect_touch.
var/metabolism_min = 0.01 //How much for the medicine to be present in the system to actually have an effect.
var/list/conflicting_reagents //Reagents that conflict with this medicine, and cause adverse effects when in the blood.
var/list/container_whitelist = list()
var/list/container_blacklist = list()
/datum/reagent/proc/remove_self(var/amount) // Shortcut
if (!holder)
//PROCLOG_WEIRD("Null holder found. Name: [name], id: [id]")
return
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/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(alien & unaffected_species && location != CHEM_TOUCH)
return
if(!dose && volume)//If dose is currently zero, we do the first effect
initial_effect(M, alien)
var/removed = metabolism
if(ingest_met && (location == CHEM_INGEST))
removed = ingest_met
if(touch_met && (location == CHEM_TOUCH))
removed = touch_met
if(breathe_met && (location == CHEM_BREATHE))
removed = breathe_met
removed = min(removed, volume)
max_dose = max(volume, max_dose)
if(overdose && (dose > overdose) && (location != CHEM_TOUCH))
overdose(M, alien, removed, dose/overdose)
dose = min(dose + removed, max_dose)
for(var/conflicting_reagent in conflicting_reagents)
var/amount_min = conflicting_reagents[conflicting_reagent]
if(M.reagents.has_reagent(conflicting_reagent,amount_min))
affect_conflicting(M,alien,removed,conflicting_reagent)
if(removed >= metabolism_min)
switch(location)
if(CHEM_BLOOD)
affect_blood(M, alien, removed)
if(CHEM_INGEST)
affect_ingest(M, alien, removed)
if(CHEM_TOUCH)
affect_touch(M, alien, removed)
if(CHEM_BREATHE)
affect_breathe(M, alien, removed)
remove_self(removed)
//Initial effect is called once when the reagent first starts affecting a mob.
/datum/reagent/proc/initial_effect(var/mob/living/carbon/M, var/alien)
return
/datum/reagent/proc/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
return
/datum/reagent/proc/affect_conflicting(var/mob/living/carbon/M, var/alien, var/removed, var/datum/reagent/conflicting_reagent)
M.adjustToxLoss(removed)
/datum/reagent/proc/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed)
affect_blood(M, alien, removed * 0.5)
/datum/reagent/proc/affect_touch(var/mob/living/carbon/M, var/alien, var/removed)
return
/datum/reagent/proc/affect_breathe(var/mob/living/carbon/M, var/alien, var/removed)
affect_blood(M, alien, removed * 0.75)
/datum/reagent/proc/overdose(var/mob/living/carbon/M, var/alien, var/removed = 0, var/scale = 1) // Overdose effect. Doesn't happen instantly.
M.adjustToxLoss(REM)
/datum/reagent/proc/initialize_data(var/newdata) // Called when the reagent is created.
if(!isnull(newdata))
data = newdata
/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(islist(data))
return data.Copy()
else if(data)
return data
/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)