-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathstatus_display.dm
390 lines (327 loc) · 10.4 KB
/
status_display.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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
// Status display
// (formerly Countdown timer display)
#define CHARS_PER_LINE 5
#define FONT_SIZE "5pt"
#define FONT_COLOR "#09f"
#define FONT_STYLE "Small Fonts"
#define SCROLL_RATE (0.04 SECONDS) // time per pixel
#define LINE1_Y -8
#define LINE2_Y -15
#define SD_BLANK 0 // 0 = Blank
#define SD_EMERGENCY 1 // 1 = Emergency Shuttle timer
#define SD_MESSAGE 2 // 2 = Arbitrary message(s)
#define SD_PICTURE 3 // 3 = alert picture
#define SD_AI_EMOTE 1 // 1 = AI emoticon
#define SD_AI_BSOD 2 // 2 = Blue screen of death
/// Status display which can show images and scrolling text.
/obj/machinery/status_display
name = "status display"
desc = null
icon = 'icons/obj/status_display.dmi'
icon_state = "frame"
density = FALSE
use_power = IDLE_POWER_USE
idle_power_usage = 10
layer = ABOVE_WINDOW_LAYER
var/obj/effect/overlay/status_display_text/message1_overlay
var/obj/effect/overlay/status_display_text/message2_overlay
/// Immediately blank the display.
/obj/machinery/status_display/proc/remove_display()
cut_overlays()
vis_contents.Cut()
if(message1_overlay)
QDEL_NULL(message1_overlay)
if(message2_overlay)
QDEL_NULL(message2_overlay)
/// Immediately change the display to the given picture.
/obj/machinery/status_display/proc/set_picture(state)
remove_display()
add_overlay(state)
/// Immediately change the display to the given two lines.
/obj/machinery/status_display/proc/update_display(line1, line2)
line1 = uppertext(line1)
line2 = uppertext(line2)
if( \
(message1_overlay && message1_overlay.message == line1) && \
(message2_overlay && message2_overlay.message == line2) \
)
return
remove_display()
message1_overlay = new(LINE1_Y, line1)
vis_contents += message1_overlay
message2_overlay = new(LINE2_Y, line2)
vis_contents += message2_overlay
// Timed process - performs nothing in the base class
/obj/machinery/status_display/process()
if(stat & NOPOWER)
// No power, no processing.
remove_display()
return PROCESS_KILL
/// Update the display and, if necessary, re-enable processing.
/obj/machinery/status_display/proc/update()
if (process(SSMACHINES_DT) != PROCESS_KILL)
START_PROCESSING(SSmachines, src)
/obj/machinery/status_display/power_change()
. = ..()
update()
/obj/machinery/status_display/emp_act(severity)
. = ..()
if(stat & (NOPOWER|BROKEN) || . & EMP_PROTECT_SELF)
return
set_picture("ai_bsod")
/obj/machinery/status_display/examine(mob/user)
. = ..()
if (message1_overlay || message2_overlay)
. += "The display says:"
if (message1_overlay.message)
. += "<br>\t<tt>[html_encode(message1_overlay.message)]</tt>"
if (message2_overlay.message)
. += "<br>\t<tt>[html_encode(message2_overlay.message)]</tt>"
// Helper procs for child display types.
/obj/machinery/status_display/proc/display_shuttle_status(obj/docking_port/mobile/shuttle)
if(!shuttle)
// the shuttle is missing - no processing
update_display("shutl?","")
return PROCESS_KILL
else if(shuttle.timer)
var/line1 = "-[shuttle.getModeStr()]-"
var/line2 = shuttle.getTimerStr()
if(length_char(line2) > CHARS_PER_LINE)
line2 = "error"
update_display(line1, line2)
else
// don't kill processing, the timer might turn back on
remove_display()
/obj/machinery/status_display/proc/examine_shuttle(mob/user, obj/docking_port/mobile/shuttle)
if (shuttle)
var/modestr = shuttle.getModeStr()
if (modestr)
if (shuttle.timer)
modestr = "<br>\t<tt>[modestr]: [shuttle.getTimerStr()]</tt>"
else
modestr = "<br>\t<tt>[modestr]</tt>"
return "The display says:<br>\t<tt>[shuttle.name]</tt>[modestr]"
else
return "The display says:<br>\t<tt>Shuttle missing!</tt>"
/**
* Nice overlay to make text smoothly scroll with no client updates after setup.
*/
/obj/effect/overlay/status_display_text
icon = 'icons/obj/status_display.dmi'
vis_flags = VIS_INHERIT_LAYER | VIS_INHERIT_PLANE | VIS_INHERIT_ID
var/message = ""
/obj/effect/overlay/status_display_text/New(yoffset, line)
maptext_y = yoffset
message = line
var/line_length = length_char(line)
if(line_length > CHARS_PER_LINE)
// Marquee text
var/marquee_message = "[line] • [line] • [line]"
var/marqee_length = line_length * 3 + 6
maptext = generate_text(marquee_message, center = FALSE)
maptext_width = 6 * marqee_length
maptext_x = 32
// Mask off to fit in screen.
add_filter("mask", 1, alpha_mask_filter(icon = icon(icon, "outline")))
// Scroll.
var/width = 4 * marqee_length
var/time = (width + 32) * SCROLL_RATE
animate(src, maptext_x = -width, time = time, loop = -1)
animate(maptext_x = 32, time = 0 SECONDS)
else
// Centered text
maptext = generate_text(line, center = TRUE)
maptext_x = 0
/obj/effect/overlay/status_display_text/proc/generate_text(text, center)
return {"<div style="font-size:[FONT_SIZE];color:[FONT_COLOR];font:'[FONT_STYLE]'[center ? ";text-align:center" : ""]" valign="top">[text]</div>"}
/// Evac display which shows shuttle timer or message set by Command.
/obj/machinery/status_display/evac
var/frequency = FREQ_STATUS_DISPLAYS
var/mode = SD_EMERGENCY
var/friendc = FALSE // track if Friend Computer mode
var/last_picture // For when Friend Computer mode is undone
/obj/machinery/status_display/evac/Initialize(mapload)
. = ..()
// register for radio system
SSradio.add_object(src, frequency)
/obj/machinery/status_display/evac/Destroy()
SSradio.remove_object(src,frequency)
return ..()
/obj/machinery/status_display/evac/process()
if(stat & NOPOWER)
// No power, no processing.
remove_display()
return PROCESS_KILL
if(friendc) //Makes all status displays except supply shuttle timer display the eye -- Urist
set_picture("ai_friend")
return PROCESS_KILL
switch(mode)
if(SD_BLANK)
remove_display()
return PROCESS_KILL
if(SD_EMERGENCY)
return display_shuttle_status(SSshuttle.emergency)
if(SD_MESSAGE)
return PROCESS_KILL
if(SD_PICTURE)
set_picture(last_picture)
return PROCESS_KILL
/obj/machinery/status_display/evac/examine(mob/user)
. = ..()
if(mode == SD_EMERGENCY)
. += examine_shuttle(user, SSshuttle.emergency)
else if(!message1_overlay && !message2_overlay)
. += "The display is blank."
/obj/machinery/status_display/evac/receive_signal(datum/signal/signal)
switch(signal.data["command"])
if("blank")
mode = SD_BLANK
remove_display()
if("shuttle")
mode = SD_EMERGENCY
remove_display()
if("message")
mode = SD_MESSAGE
update_display(signal.data["msg1"], signal.data["msg2"])
if("alert")
mode = SD_PICTURE
last_picture = signal.data["picture_state"]
set_picture(last_picture)
if("friendcomputer")
friendc = !friendc
update()
/// Supply display which shows the status of the supply shuttle.
/obj/machinery/status_display/supply
name = "supply display"
/obj/machinery/status_display/supply/process()
if(stat & NOPOWER)
// No power, no processing.
remove_display()
return PROCESS_KILL
var/line1
var/line2
if(!SSshuttle.supply)
// Might be missing in our first update on initialize before shuttles
// have loaded. Cross our fingers that it will soon return.
line1 = "CARGO"
line2 = "shutl?"
else if(SSshuttle.supply.mode == SHUTTLE_IDLE)
if(is_station_level(SSshuttle.supply.z))
line1 = "CARGO"
line2 = "Docked"
else
line1 = "CARGO"
line2 = SSshuttle.supply.getTimerStr()
if(length_char(line2) > CHARS_PER_LINE)
line2 = "Error"
update_display(line1, line2)
/obj/machinery/status_display/supply/examine(mob/user)
. = ..()
var/obj/docking_port/mobile/shuttle = SSshuttle.supply
var/shuttleMsg = null
if (shuttle.mode == SHUTTLE_IDLE)
if (is_station_level(shuttle.z))
shuttleMsg = "Docked"
else
shuttleMsg = "[shuttle.getModeStr()]: [shuttle.getTimerStr()]"
if (shuttleMsg)
. += "The display says:<br>\t<tt>[shuttleMsg]</tt>"
else
. += "The display is blank."
/// General-purpose shuttle status display.
/obj/machinery/status_display/shuttle
name = "shuttle display"
var/shuttle_id
/obj/machinery/status_display/shuttle/process()
if(!shuttle_id || (stat & NOPOWER))
// No power, no processing.
remove_display()
return PROCESS_KILL
return display_shuttle_status(SSshuttle.getShuttle(shuttle_id))
/obj/machinery/status_display/shuttle/examine(mob/user)
. = ..()
if(shuttle_id)
. += examine_shuttle(user, SSshuttle.getShuttle(shuttle_id))
else
. += "The display is blank."
/obj/machinery/status_display/shuttle/vv_edit_var(var_name, var_value)
. = ..()
if(!.)
return
switch(var_name)
if("shuttle_id")
update()
/obj/machinery/status_display/shuttle/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override)
if (port && (shuttle_id == initial(shuttle_id) || override))
shuttle_id = port.shuttle_id
update()
/// Pictograph display which the AI can use to emote.
/obj/machinery/status_display/ai
name = "\improper AI display"
desc = "A small screen which the AI can use to present itself."
var/mode = SD_BLANK
var/emotion = "Neutral"
/obj/machinery/status_display/ai/Initialize(mapload)
. = ..()
GLOB.ai_status_displays.Add(src)
/obj/machinery/status_display/ai/Destroy()
GLOB.ai_status_displays.Remove(src)
. = ..()
/obj/machinery/status_display/ai/attack_ai(mob/living/silicon/ai/user)
if(isAI(user))
user.ai_statuschange()
/obj/machinery/status_display/ai/process()
if(mode == SD_BLANK || (stat & NOPOWER))
remove_display()
return PROCESS_KILL
if(mode == SD_AI_EMOTE)
switch(emotion)
if("Very Happy")
set_picture("ai_veryhappy")
if("Happy")
set_picture("ai_happy")
if("Neutral")
set_picture("ai_neutral")
if("Unsure")
set_picture("ai_unsure")
if("Confused")
set_picture("ai_confused")
if("Sad")
set_picture("ai_sad")
if("BSOD")
set_picture("ai_bsod")
if("Blank")
set_picture("ai_off")
if("Problems?")
set_picture("ai_trollface")
if("Awesome")
set_picture("ai_awesome")
if("Dorfy")
set_picture("ai_urist")
if("Thinking")
set_picture("ai_thinking")
if("Facepalm")
set_picture("ai_facepalm")
if("Friend Computer")
set_picture("ai_friend")
if("Blue Glow")
set_picture("ai_sal")
if("Red Glow")
set_picture("ai_hal")
if("Goon Happy")
set_picture("ai_goon_happy")
if("Goon Sad")
set_picture("ai_goon_sad")
if("Gondola")
set_picture("ai_gondola")
return PROCESS_KILL
if(mode == SD_AI_BSOD)
set_picture("ai_bsod")
return PROCESS_KILL
#undef CHARS_PER_LINE
#undef FONT_SIZE
#undef FONT_COLOR
#undef FONT_STYLE
#undef SCROLL_RATE
#undef LINE1_Y
#undef LINE2_Y