-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathSleeper.dm
365 lines (327 loc) · 11.7 KB
/
Sleeper.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
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
#define SLEEPER_TEND "Treat Injuries"
#define SLEEPER_ORGANS "Repair Organs"
#define SLEEPER_CHEMPURGE "Purge Toxins"
#define SLEEPER_HEAL_RATE 2
/obj/machinery/sleep_console
name = "sleeper console"
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "console"
density = FALSE
/obj/machinery/sleeper
name = "sleeper"
desc = "An enclosed machine used to stabilize and heal patients."
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
base_icon_state = "sleeper"
density = FALSE
state_open = TRUE
circuit = /obj/item/circuitboard/machine/sleeper
clicksound = 'sound/machines/pda_button1.ogg'
///efficiency, used to increase the effect of some healing methods
var/efficiency = 1
///treatments currently available for use
var/list/available_treatments
///if the patient is able to use the sleeper's controls
var/controls_inside = FALSE
///treatments unlocked by manipulator by tier
var/list/treatments = list(
list(SLEEPER_TEND),
list(SLEEPER_ORGANS),
list(SLEEPER_CHEMPURGE),
list()
)
///the current active treatment
var/active_treatment = null
///if the sleeper puts its patient into stasis
var/stasis = FALSE
var/enter_message = "<span class='notice'><b>You feel cool air surround you. You go numb as your senses turn inward.</b></span>"
var/open_sound = 'sound/machines/podopen.ogg'
var/close_sound = 'sound/machines/podclose.ogg'
payment_department = ACCOUNT_MED
fair_market_price = 5
///what chemical we're injecting with the "sedate" function
var/sedate_chem = /datum/reagent/medicine/morphine
///maximum allowed chemical volume
var/sedate_limit = 20
///what are we putting in the tgui
var/sedate_button_text = "Sedate"
/obj/machinery/sleeper/Initialize(mapload)
. = ..()
occupant_typecache = GLOB.typecache_living
update_appearance(UPDATE_ICON)
/obj/machinery/sleeper/RefreshParts()
var/E
for(var/obj/item/stock_parts/matter_bin/B in component_parts)
E += B.rating
var/I
for(var/obj/item/stock_parts/manipulator/M in component_parts)
I += M.rating
efficiency = initial(efficiency)* E
available_treatments = list()
for(var/i in 1 to I)
if(!length(treatments[i]))
continue
available_treatments |= treatments[i]
stasis = (I >= 4)
/obj/machinery/sleeper/update_icon_state()
icon_state = "[base_icon_state][state_open ? "-open" : null]"
return ..()
/obj/machinery/sleeper/container_resist(mob/living/user)
visible_message(span_notice("[occupant] emerges from [src]!"),
span_notice("You climb out of [src]!"))
open_machine()
/obj/machinery/sleeper/Exited(atom/movable/user)
if (!state_open && user == occupant)
container_resist(user)
/obj/machinery/sleeper/relaymove(mob/user)
if (!state_open)
container_resist(user)
/obj/machinery/sleeper/open_machine()
if(!state_open && !panel_open)
active_treatment = null
var/mob/living/mob_occupant = occupant
if(mob_occupant)
mob_occupant.remove_status_effect(STATUS_EFFECT_STASIS)
flick("[base_icon_state]-anim", src)
if(open_sound)
playsound(src, open_sound, 40)
..()
/obj/machinery/sleeper/close_machine(mob/user)
if((isnull(user) || istype(user)) && state_open && !panel_open)
flick("[base_icon_state]-anim", src)
..(user)
var/mob/living/mob_occupant = occupant
if(mob_occupant && mob_occupant.stat != DEAD)
to_chat(occupant, "[enter_message]")
if(mob_occupant && stasis)
mob_occupant.extinguish_mob()
if(close_sound)
playsound(src, close_sound, 40)
/obj/machinery/sleeper/emp_act(severity)
. = ..()
if (. & EMP_PROTECT_SELF)
return
if(is_operational() && occupant)
open_machine()
/obj/machinery/sleeper/emag_act(mob/user, obj/item/card/emag/emag_card)
if(obj_flags & EMAGGED)
return FALSE
to_chat(user, span_danger("You disable the chemical injection inhibitors on the sleeper..."))
obj_flags |= EMAGGED
return TRUE
/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user)
if(user.stat || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
return
if(isliving(user))
var/mob/living/L = user
if(!(L.mobility_flags & MOBILITY_STAND))
return
close_machine(target)
/obj/machinery/sleeper/screwdriver_act(mob/living/user, obj/item/I)
. = TRUE
if(..())
return
if(occupant)
to_chat(user, span_warning("[src] is currently occupied!"))
return
if(state_open)
to_chat(user, span_warning("[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch!"))
return
if(default_deconstruction_screwdriver(user, "[base_icon_state]-o", base_icon_state, I))
return
return FALSE
/obj/machinery/sleeper/wrench_act(mob/living/user, obj/item/I)
. = ..()
if(default_change_direction_wrench(user, I))
return TRUE
/obj/machinery/sleeper/crowbar_act(mob/living/user, obj/item/I)
. = ..()
if(default_pry_open(I))
return TRUE
if(default_deconstruction_crowbar(I))
return TRUE
/obj/machinery/sleeper/default_pry_open(obj/item/I) //wew
. = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR
if(.)
I.play_tool_sound(src, 50)
visible_message(span_notice("[usr] pries open [src]."), span_notice("You pry open [src]."))
open_machine()
/obj/machinery/sleeper/ui_state(mob/user)
if(controls_inside)
return GLOB.default_state
return GLOB.notcontained_state
/obj/machinery/sleeper/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Sleeper", name)
ui.open()
/obj/machinery/sleeper/AltClick(mob/user)
if(!user.canUseTopic(src, !issilicon(user)))
return
if(state_open)
close_machine()
else
open_machine()
/obj/machinery/sleeper/examine(mob/user)
. = ..()
. += span_notice("Alt-click [src] to [state_open ? "close" : "open"] it.")
/obj/machinery/sleeper/process()
..()
check_nap_violations()
if(issilicon(occupant))
return
var/mob/living/carbon/C = occupant
if(C)
if(stasis && (C.stat == DEAD || C.health < 0))
C.apply_status_effect(STATUS_EFFECT_STASIS, null, TRUE, -1)
else
C.remove_status_effect(STATUS_EFFECT_STASIS)
if(obj_flags & EMAGGED)
var/existing = C.reagents.get_reagent_amount(/datum/reagent/toxin/amanitin)
C.reagents.add_reagent(/datum/reagent/toxin/amanitin, max(0, 1.5 - existing)) //this should be enough that you immediately eat shit on exiting but not before
switch(active_treatment)
if(SLEEPER_TEND)
C.heal_bodypart_damage(SLEEPER_HEAL_RATE + efficiency, SLEEPER_HEAL_RATE + efficiency)
if(SLEEPER_ORGANS)
var/heal_reps = efficiency * 2
var/list/organs = list(ORGAN_SLOT_EARS,ORGAN_SLOT_EYES,ORGAN_SLOT_LIVER,ORGAN_SLOT_LUNGS,ORGAN_SLOT_STOMACH,ORGAN_SLOT_HEART)
for(var/i in 1 to heal_reps)
organs = shuffle(organs)
for(var/o in organs)
var/healed = FALSE
var/obj/item/organ/heal_target = C.getorganslot(o)
if(heal_target?.damage >= 1)
var/organ_healing = C.stat == DEAD ? 0.5 : 1
heal_target.applyOrganDamage(-organ_healing)
healed = TRUE
if(healed)
break
if(SLEEPER_CHEMPURGE)
C.adjustToxLoss(-(SLEEPER_HEAL_RATE + efficiency))
if(obj_flags & EMAGGED)
return
var/purge_rate = 0.5 * efficiency
for(var/datum/reagent/R in C.reagents.reagent_list)
if(istype(R, /datum/reagent/toxin))
C.reagents.remove_reagent(R.type,purge_rate)
if(R.overdosed)
C.reagents.remove_reagent(R.type,purge_rate)
else
active_treatment = null
/obj/machinery/sleeper/nap_violation(mob/violator)
open_machine()
/obj/machinery/sleeper/ui_data(mob/user)
var/list/data = list()
data["knowledge"] = IS_MEDICAL(user)
data["occupied"] = occupant ? 1 : 0
data["open"] = state_open
data["active_treatment"] = active_treatment
data["can_sedate"] = can_sedate()
data["sedate_text"] = sedate_button_text
data["treatments"] = list()
for(var/T in available_treatments)
data["treatments"] += T
/*data["chems"] = list()
for(var/chem in available_chems)
var/datum/reagent/R = GLOB.chemical_reagents_list[chem]
data["chems"] += list(list("name" = R.name, "id" = R.type, "allowed" = chem_allowed(chem), "desc" = R.description))*/
data["occupant"] = list()
var/mob/living/mob_occupant = occupant
if(mob_occupant)
data["occupant"]["name"] = mob_occupant.name
switch(mob_occupant.stat)
if(CONSCIOUS)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "good"
if(SOFT_CRIT)
data["occupant"]["stat"] = "Conscious"
data["occupant"]["statstate"] = "average"
if(UNCONSCIOUS)
data["occupant"]["stat"] = "Unconscious"
data["occupant"]["statstate"] = "average"
if(DEAD)
data["occupant"]["stat"] = "Dead"
data["occupant"]["statstate"] = "bad"
data["occupant"]["health"] = mob_occupant.health
data["occupant"]["maxHealth"] = mob_occupant.maxHealth
data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD
data["occupant"]["bruteLoss"] = mob_occupant.getBruteLoss()
data["occupant"]["oxyLoss"] = mob_occupant.getOxyLoss()
data["occupant"]["toxLoss"] = mob_occupant.getToxLoss()
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
data["occupant"]["reagents"] = list()
if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len)
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume))
return data
/obj/machinery/sleeper/ui_act(action, params)
if(..())
return
playsound(src, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, TRUE, 2)
var/mob/living/mob_occupant = occupant
check_nap_violations()
switch(action)
if("door")
if(state_open)
close_machine()
else
open_machine()
. = TRUE
if("set")
var/treatment = params["treatment"]
if(!is_operational() || !mob_occupant || isnull(treatment))
return
active_treatment = treatment
. = TRUE
if("sedate")
if(can_sedate())
mob_occupant.reagents.add_reagent(sedate_chem, 10)
if(usr)
log_combat(usr,occupant, "injected morphine into", addition = "via [src]")
. = TRUE
/obj/machinery/sleeper/proc/can_sedate()
var/mob/living/mob_occupant = occupant
if(!mob_occupant || !mob_occupant.reagents)
return
return mob_occupant.reagents.get_reagent_amount(sedate_chem) + 10 <= sedate_limit
/obj/machinery/sleeper/syndie
icon_state = "sleeper_s"
base_icon_state = "sleeper_s"
controls_inside = TRUE
/obj/machinery/sleeper/syndie/fullupgrade/Initialize(mapload)
. = ..()
component_parts = list()
component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null)
component_parts += new /obj/item/stock_parts/manipulator/femto(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/sheet/glass(null)
component_parts += new /obj/item/stack/cable_coil(null)
RefreshParts()
/obj/machinery/sleeper/clockwork
name = "soothing sleeper"
desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch."
icon_state = "sleeper_clockwork"
base_icon_state = "sleeper_clockwork"
enter_message = "<span class='bold inathneq_small'>You hear the gentle hum and click of machinery, and are lulled into a sense of peace.</span>"
efficiency = 3
available_treatments = list(SLEEPER_TEND, SLEEPER_ORGANS, SLEEPER_CHEMPURGE)
stasis = TRUE
/obj/machinery/sleeper/clockwork/process()
if(occupant && isliving(occupant))
var/mob/living/L = occupant
if(GLOB.clockwork_vitality) //If there's Vitality, the sleeper has passive healing
GLOB.clockwork_vitality = max(0, GLOB.clockwork_vitality - 1)
L.adjustBruteLoss(-1)
L.adjustFireLoss(-1)
L.adjustOxyLoss(-5)
/obj/machinery/sleeper/clockwork/RefreshParts()
return
/obj/machinery/sleeper/old
icon_state = "oldpod"
base_icon_state = "oldpod"
#undef SLEEPER_TEND
#undef SLEEPER_ORGANS
#undef SLEEPER_CHEMPURGE
#undef SLEEPER_HEAL_RATE