/
neutral.dm
295 lines (245 loc) · 9.38 KB
/
neutral.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
//entirely neutral or internal status effects go here
/// tracks the damage dealt to this mob by kinetic crushers
/datum/status_effect/crusher_damage
id = "crusher_damage"
duration = -1
status_type = STATUS_EFFECT_UNIQUE
alert_type = null
var/total_damage = 0
/datum/status_effect/syphon_mark
id = "syphon_mark"
duration = 50
status_type = STATUS_EFFECT_MULTIPLE
alert_type = null
on_remove_on_mob_delete = TRUE
var/obj/item/borg/upgrade/modkit/bounty/reward_target
/datum/status_effect/syphon_mark/on_creation(mob/living/new_owner, obj/item/borg/upgrade/modkit/bounty/new_reward_target)
. = ..()
if(.)
reward_target = new_reward_target
/datum/status_effect/syphon_mark/on_apply()
if(owner.stat == DEAD)
return FALSE
return ..()
/datum/status_effect/syphon_mark/proc/get_kill()
if(!QDELETED(reward_target))
reward_target.get_kill(owner)
/datum/status_effect/syphon_mark/tick()
if(owner.stat == DEAD)
get_kill()
qdel(src)
/datum/status_effect/syphon_mark/on_remove()
get_kill()
. = ..()
/datum/status_effect/adaptive_learning
id = "adaptive_learning"
duration = 30 SECONDS
status_type = STATUS_EFFECT_REFRESH
alert_type = null
var/bonus_damage = 0
/datum/status_effect/high_five
id = "high_five"
duration = 10 SECONDS
alert_type = null
status_type = STATUS_EFFECT_REFRESH
/// Message displayed when wizards perform this together
var/critical_success = "high-five EPICALLY!"
/// Message displayed when normal people perform this together
var/success = "high-five!"
/// Message displayed when this status effect is applied.
var/request = "requests a high-five."
/// Item to be shown in the pop-up balloon.
var/obj/item/item_path = /obj/item/latexballon
/// Sound effect played when this emote is completed.
var/sound_effect = 'sound/weapons/slap.ogg'
/// So we don't leave folks with god-mode
/datum/status_effect/high_five/proc/wiz_cleanup(mob/living/carbon/user, mob/living/carbon/highfived)
user.status_flags &= ~GODMODE
highfived.status_flags &= ~GODMODE
user.remove_status_effect(type)
highfived.remove_status_effect(type)
/datum/status_effect/high_five/on_apply()
if(!iscarbon(owner))
return FALSE
. = ..()
var/mob/living/carbon/user = owner
var/is_wiz = iswizard(user)
var/both_wiz = FALSE
for(var/mob/living/carbon/C in orange(1, user))
if(!C.has_status_effect(type) || C == user)
continue
if(is_wiz && iswizard(C))
user.visible_message("<span class='biggerdanger'><b>[user.name]</b> and <b>[C.name]</b> [critical_success]</span>")
user.status_flags |= GODMODE
C.status_flags |= GODMODE
explosion(get_turf(user), 5, 2, 1, 3, cause = id)
// explosions have a spawn so this makes sure that we don't get gibbed
addtimer(CALLBACK(src, PROC_REF(wiz_cleanup), user, C), 0.3 SECONDS) //I want to be sure this lasts long enough, with lag.
add_attack_logs(user, C, "caused a wizard [id] explosion")
both_wiz = TRUE
user.do_attack_animation(C, no_effect = TRUE)
C.do_attack_animation(user, no_effect = TRUE)
playsound(user, sound_effect, 80)
if(!both_wiz)
user.visible_message("<span class='notice'><b>[user.name]</b> and <b>[C.name]</b> [success]</span>")
user.remove_status_effect(type)
C.remove_status_effect(type)
return FALSE
return TRUE // DO NOT AUTOREMOVE
owner.custom_emote(EMOTE_VISIBLE, request)
owner.create_point_bubble_from_path(item_path, FALSE)
/datum/status_effect/high_five/on_timeout()
owner.visible_message("[owner] [get_missed_message()]")
/datum/status_effect/high_five/proc/get_missed_message()
var/list/missed_highfive_messages = list(
"lowers [owner.p_their()] hand, it looks like [owner.p_they()] [owner.p_were()] left hanging...",
"seems to awkwardly wave at nobody in particular.",
"moves [owner.p_their()] hand directly to [owner.p_their()] forehead in shame.",
"fully commits and high-fives empty space.",
"high-fives [owner.p_their()] other hand shamefully before wiping away a tear.",
"goes for a handshake, then a fistbump, before pulling [owner.p_their()] hand back...? <i>What [owner.p_are()] [owner.p_they()] doing?</i>"
)
return pick(missed_highfive_messages)
/datum/status_effect/high_five/dap
id = "dap"
critical_success = "dap each other up EPICALLY!"
success = "dap each other up!"
request = "requests someone to dap them up!"
sound_effect = 'sound/effects/snap.ogg'
item_path = /obj/item/melee/touch_attack/fake_disintegrate // EI-NATH!
/datum/status_effect/high_five/dap/get_missed_message()
return "sadly can't find anybody to give daps to, and daps [owner.p_themselves()]. Shameful."
/datum/status_effect/high_five/handshake
id = "handshake"
critical_success = "give each other an EPIC handshake!"
success = "give each other a handshake!"
request = "requests a handshake!"
sound_effect = "sound/weapons/thudswoosh.ogg"
/datum/status_effect/high_five/handshake/get_missed_message()
var/list/missed_messages = list(
"drops [owner.p_their()] hand, shamefully.",
"grabs [owner.p_their()] outstretched hand with [owner.p_their()] other hand and gives [owner.p_themselves()] a handshake.",
"balls [owner.p_their()] hand into a fist, slowly bringing it back in."
)
return pick(missed_messages)
/// A status effect that can have a certain amount of "bonus" duration added, which extends the duration every tick,
/// although there is a maximum amount of bonus time that can be active at any given time.
/datum/status_effect/limited_bonus
/// How much extra time has been added
var/bonus_time = 0
/// How much extra time to apply per tick
var/bonus_time_per_tick = 1 SECONDS
/// How much maximum bonus time can be active at once
var/max_bonus_time = 1 MINUTES
/datum/status_effect/limited_bonus/tick()
. = ..()
// Sure, we could do some fancy stuff with clamping, and it'd probably be a little cleaner.
// This keeps the math simple and easier to use later
if(bonus_time > bonus_time_per_tick)
duration += bonus_time_per_tick
bonus_time -= bonus_time_per_tick
/datum/status_effect/limited_bonus/proc/extend(extra_time)
bonus_time = clamp(bonus_time + extra_time, 0, max_bonus_time)
/datum/status_effect/limited_bonus/revivable
id = "revivable"
alert_type = null
status_type = STATUS_EFFECT_UNIQUE
duration = BASE_DEFIB_TIME_LIMIT
/datum/status_effect/limited_bonus/revivable/on_apply()
. = ..()
if(!iscarbon(owner))
return FALSE
RegisterSignal(owner, COMSIG_HUMAN_RECEIVE_CPR, PROC_REF(on_cpr))
RegisterSignal(owner, COMSIG_LIVING_REVIVE, PROC_REF(on_revive))
owner.med_hud_set_status() // update revivability after adding the status effect
/datum/status_effect/limited_bonus/revivable/proc/on_cpr(mob/living/carbon/human/H, new_seconds)
SIGNAL_HANDLER // COMSIG_HUMAN_RECEIVE_CPR
extend(new_seconds)
/datum/status_effect/limited_bonus/revivable/proc/on_revive()
SIGNAL_HANDLER // COMSIG_LIVING_REVIVE
qdel(src)
/datum/status_effect/limited_bonus/revivable/on_remove()
// Update HUDs once the status effect is deleted to show non-revivability
INVOKE_ASYNC(owner, TYPE_PROC_REF(/mob/living, med_hud_set_status))
. = ..()
/datum/status_effect/charging
id = "charging"
alert_type = null
/datum/status_effect/impact_immune
id = "impact_immune"
alert_type = null
/datum/status_effect/recently_succumbed
id = "recently_succumbed"
alert_type = null
duration = 1 MINUTES
status_type = STATUS_EFFECT_REFRESH
#define LWAP_LOCK_CAP 10
/datum/status_effect/lwap_scope
id = "lwap_scope"
alert_type = null
duration = -1
tick_interval = 4
/// The number of people the gun has locked on to. Caps at 10 for sanity.
var/locks = 0
/// What direction the owner was in when using the scope.
var/owner_dir = 0
/datum/status_effect/lwap_scope/on_creation(mob/living/new_owner, stored_dir = 0)
owner_dir = stored_dir
return ..()
/datum/status_effect/lwap_scope/tick()
locks = 0
var/turf/owner_turf = get_turf(owner)
var/scope_turf
for(var/turf/T in RANGE_EDGE_TURFS(7, owner_turf))
if(get_dir(owner, T) != owner_dir)
continue
if(T in range(owner, 6))
continue
scope_turf = T
break
if(scope_turf)
for(var/mob/living/L in range(10, scope_turf))
if(locks >= LWAP_LOCK_CAP)
return
if(L == owner || L.stat == DEAD || isslime(L) || ismonkeybasic(L)) //xenobio moment
continue
new /obj/effect/temp_visual/single_user/lwap_ping(owner.loc, owner, L)
locks++
#undef LWAP_LOCK_CAP
/datum/status_effect/delayed
id = "delayed_status_effect"
status_type = STATUS_EFFECT_MULTIPLE
alert_type = null
var/prevent_signal = null
var/datum/callback/expire_proc = null
/datum/status_effect/delayed/on_creation(mob/living/new_owner, new_duration, datum/callback/new_expire_proc, new_prevent_signal = null)
if(!new_duration || !istype(new_expire_proc))
qdel(src)
return
duration = new_duration
expire_proc = new_expire_proc
. = ..()
if(new_prevent_signal)
RegisterSignal(owner, new_prevent_signal, PROC_REF(prevent_action))
prevent_signal = new_prevent_signal
/datum/status_effect/proc/prevent_action()
SIGNAL_HANDLER
qdel(src)
/datum/status_effect/delayed/on_remove()
if(prevent_signal)
UnregisterSignal(owner, prevent_signal)
. = ..()
/datum/status_effect/delayed/on_timeout()
. = ..()
expire_proc.Invoke()
/datum/status_effect/action_status_effect
alert_type = null
tick_interval = -1
/datum/status_effect/action_status_effect/remove_handcuffs
id = "remove_handcuffs"
/datum/status_effect/action_status_effect/break_handcuffs
id = "break_handcuffs"
/datum/status_effect/action_status_effect/remove_muzzle
id = "remove_muzzle"
/datum/status_effect/action_status_effect/unbuckle
id = "unbuckle"