-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathartefact.dm
476 lines (406 loc) · 14.8 KB
/
artefact.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
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
//Apprenticeship contract - moved to antag_spawner.dm
///////////////////////////Veil Render//////////////////////
/obj/item/veilrender
name = "veil render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast city."
icon = 'icons/obj/weapons/khopesh.dmi'
icon_state = "render"
item_state = "knife"
lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi'
force = 15
throwforce = 10
w_class = WEIGHT_CLASS_NORMAL
hitsound = 'sound/weapons/bladeslice.ogg'
var/charges = 1
var/spawn_type = /obj/singularity/wizard
var/spawn_amt = 1
var/activate_descriptor = "reality"
var/rend_desc = "You should run now."
var/spawn_fast = 0 //if 1, ignores checking for mobs on loc before spawning
/obj/item/veilrender/Initialize(mapload)
. = ..()
AddComponent(/datum/component/butchering, 80, 100)
/obj/item/veilrender/attack_self(mob/user)
if(charges > 0)
new /obj/effect/rend(get_turf(user), spawn_type, spawn_amt, rend_desc, spawn_fast)
charges--
user.visible_message(span_boldannounce("[src] hums with power as [user] deals a blow to [activate_descriptor] itself!"))
else
to_chat(user, span_danger("The unearthly energies that powered the blade are now dormant."))
/obj/effect/rend
name = "tear in the fabric of reality"
desc = "You should run now."
icon = 'icons/effects/effects.dmi'
icon_state = "rift"
density = TRUE
anchored = TRUE
var/spawn_path = /mob/living/simple_animal/cow //defaulty cows to prevent unintentional narsies
var/spawn_amt_left = 20
var/spawn_fast = 0
/obj/effect/rend/New(loc, spawn_type, spawn_amt, desc, spawn_fast)
src.spawn_path = spawn_type
src.spawn_amt_left = spawn_amt
src.desc = desc
src.spawn_fast = spawn_fast
START_PROCESSING(SSobj, src)
return
/obj/effect/rend/process()
if(!spawn_fast)
if(locate(/mob) in loc)
return
new spawn_path(loc)
spawn_amt_left--
if(spawn_amt_left <= 0)
qdel(src)
/obj/effect/rend/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/nullrod))
user.visible_message(span_danger("[user] seals \the [src] with \the [I]."))
qdel(src)
return
else
return ..()
/obj/effect/rend/singularity_pull()
return
/obj/effect/rend/singularity_pull()
return
/obj/item/veilrender/vealrender
name = "veal render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast farm."
spawn_type = /mob/living/simple_animal/cow
spawn_amt = 20
activate_descriptor = "hunger"
rend_desc = "Reverberates with the sound of ten thousand moos."
/obj/item/veilrender/honkrender
name = "honk render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast circus."
spawn_type = /mob/living/simple_animal/hostile/retaliate/clown
spawn_amt = 10
activate_descriptor = "depression"
rend_desc = "Gently wafting with the sounds of endless laughter."
icon_state = "clownrender"
/obj/item/veilrender/honkrender/honkhulkrender
name = "superior honk render"
desc = "A wicked curved blade of alien origin, recovered from the ruins of a vast circus. This one gleams with a special light."
spawn_type = /mob/living/simple_animal/hostile/retaliate/clown/clownhulk
spawn_amt = 5
activate_descriptor = "depression"
rend_desc = "Gently wafting with the sounds of mirthful grunting."
icon_state = "clownrender"
////TEAR IN REALITY
/obj/singularity/wizard
name = "tear in the fabric of reality"
desc = "This isn't right."
icon = 'icons/effects/224x224.dmi'
icon_state = "reality"
pixel_x = -96
pixel_y = -96
dissipate = 0
move_self = 0
consume_range = 3
grav_pull = 4
current_size = STAGE_FOUR
allowed_size = STAGE_FOUR
/obj/singularity/wizard/process()
move()
eat()
return
/obj/singularity/wizard/attack_tk(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
var/datum/component/mood/insaneinthemembrane = C.GetComponent(/datum/component/mood)
if(insaneinthemembrane.sanity < 15)
return //they've already seen it and are about to die, or are just too insane to care
to_chat(C, span_userdanger("OH GOD! NONE OF IT IS REAL! NONE OF IT IS REEEEEEEEEEEEEEEEEEEEEEEEAL!"))
insaneinthemembrane.sanity = 0
for(var/lore in typesof(/datum/brain_trauma/severe))
C.gain_trauma(lore)
addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/singularity/wizard, deranged), C), 100)
/obj/singularity/wizard/proc/deranged(mob/living/carbon/C)
if(!C || C.stat == DEAD)
return
C.vomit(0, TRUE, TRUE, 3, TRUE)
C.spew_organ(3, 2)
C.death()
/obj/singularity/wizard/mapped/admin_investigate_setup()
return
/////////////////////////////////////////Scrying///////////////////
/obj/item/scrying
name = "scrying orb"
desc = "An incandescent orb of otherworldly energy, merely holding it gives you vision and hearing beyond mortal means, and staring into it lets you see the entire universe."
icon = 'icons/obj/projectiles.dmi'
icon_state ="bluespace"
throw_speed = 3
throw_range = 7
throwforce = 15
damtype = BURN
force = 15
hitsound = 'sound/items/welder2.ogg'
var/mob/current_owner
/obj/item/scrying/Initialize(mapload)
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/scrying/Destroy()
STOP_PROCESSING(SSobj, src)
. = ..()
/obj/item/scrying/process()
var/mob/holder = get(loc, /mob)
if(current_owner && current_owner != holder)
to_chat(current_owner, span_notice("Your otherworldly vision fades..."))
REMOVE_TRAIT(current_owner, TRAIT_SIXTHSENSE, SCRYING_ORB)
REMOVE_TRAIT(current_owner, TRAIT_XRAY_VISION, SCRYING_ORB)
current_owner.update_sight()
current_owner = null
if(!current_owner)
current_owner = holder
to_chat(current_owner, span_notice("You can see...everything!"))
ADD_TRAIT(current_owner, TRAIT_SIXTHSENSE, SCRYING_ORB)
ADD_TRAIT(current_owner, TRAIT_XRAY_VISION, SCRYING_ORB)
current_owner.update_sight()
/obj/item/scrying/attack_self(mob/user)
visible_message(span_danger("[user] stares into [src], their eyes glazing over."))
user.ghostize(1)
/////////////////////////////////////////Necromantic Stone///////////////////
/obj/item/necromantic_stone
name = "necromantic stone"
desc = "A shard capable of resurrecting humans as skeleton thralls."
icon = 'icons/obj/wizard.dmi'
icon_state = "necrostone"
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
var/list/spooky_scaries = list()
var/unlimited = 0
/obj/item/necromantic_stone/unlimited
unlimited = 1
/obj/item/necromantic_stone/attack(mob/living/carbon/human/M, mob/living/carbon/human/user)
if(!istype(M))
return ..()
if(!istype(user) || !user.canUseTopic(M, BE_CLOSE))
return
if(M.stat != DEAD)
to_chat(user, span_warning("This artifact can only affect the dead!"))
return
for(var/mob/dead/observer/ghost in GLOB.dead_mob_list) //excludes new players
if(ghost.mind && ghost.mind.current == M && ghost.client) //the dead mobs list can contain clientless mobs
ghost.reenter_corpse()
break
if(!M.mind || !M.client)
to_chat(user, span_warning("There is no soul connected to this body..."))
return
check_spooky()//clean out/refresh the list
if(spooky_scaries.len >= 3 && !unlimited)
to_chat(user, span_warning("This artifact can only affect three undead at a time!"))
return
M.set_species(/datum/species/skeleton, icon_update=0)
M.revive(full_heal = 1, admin_revive = 1)
spooky_scaries |= M
to_chat(M, "[span_userdanger("You have been revived by ")]<B>[user.real_name]!</B>")
to_chat(M, span_userdanger("[user.p_theyre(TRUE)] your master now, assist [user.p_them()] even if it costs you your new life!"))
equip_roman_skeleton(M)
desc = "A shard capable of resurrecting humans as skeleton thralls[unlimited ? "." : ", [spooky_scaries.len]/3 active thralls."]"
/obj/item/necromantic_stone/proc/check_spooky()
if(unlimited) //no point, the list isn't used.
return
for(var/X in spooky_scaries)
if(!ishuman(X))
spooky_scaries.Remove(X)
continue
var/mob/living/carbon/human/H = X
if(H.stat == DEAD)
H.dust(TRUE)
spooky_scaries.Remove(X)
continue
listclearnulls(spooky_scaries)
//Funny gimmick, skeletons always seem to wear roman/ancient armour
/obj/item/necromantic_stone/proc/equip_roman_skeleton(mob/living/carbon/human/H)
for(var/obj/item/I in H)
H.dropItemToGround(I)
var/hat = pick(/obj/item/clothing/head/helmet/roman, /obj/item/clothing/head/helmet/roman/legionnaire)
H.equip_to_slot_or_del(new hat(H), ITEM_SLOT_HEAD)
H.equip_to_slot_or_del(new /obj/item/clothing/under/costume/roman(H), ITEM_SLOT_ICLOTHING)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/roman(H), ITEM_SLOT_FEET)
H.put_in_hands(new /obj/item/shield/riot/roman(H), TRUE)
H.put_in_hands(new /obj/item/claymore(H), TRUE)
H.equip_to_slot_or_del(new /obj/item/melee/spear(H), ITEM_SLOT_BACK)
/obj/item/voodoo
name = "wicker doll"
desc = "Something creepy about it."
icon = 'icons/obj/wizard.dmi'
icon_state = "voodoo"
item_state = "electronic"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
var/mob/living/carbon/human/target = null
var/list/mob/living/carbon/human/possible = list()
var/obj/item/voodoo_link = null
var/cooldown_time = 30 //3s
var/cooldown = 0
max_integrity = 10
resistance_flags = FLAMMABLE
/obj/item/voodoo/attackby(obj/item/I, mob/user, params)
if(target && cooldown < world.time)
if(I.is_hot())
to_chat(target, span_userdanger("You suddenly feel very hot"))
target.adjust_bodytemperature(50)
GiveHint(target)
else if(I.get_sharpness() == SHARP_POINTY)
to_chat(target, span_userdanger("You feel a stabbing pain in [parse_zone(user.zone_selected)]!"))
target.Paralyze(40)
GiveHint(target)
else if(istype(I, /obj/item/bikehorn))
to_chat(target, span_userdanger("HONK"))
SEND_SOUND(target, 'sound/items/airhorn.ogg')
target.adjustEarDamage(0,3)
GiveHint(target)
cooldown = world.time +cooldown_time
return
if(!voodoo_link)
if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL)
if (user.transferItemToLoc(I,src))
voodoo_link = I
to_chat(user, "You attach [I] to the doll.")
update_targets()
/obj/item/voodoo/check_eye(mob/user)
if(loc != user)
user.reset_perspective(null)
user.unset_machine()
/obj/item/voodoo/attack_self(mob/user)
if(!target && possible.len)
target = input(user, "Select your victim!", "Voodoo") as null|anything in possible
return
if(user.zone_selected == BODY_ZONE_CHEST)
if(voodoo_link)
target = null
voodoo_link.forceMove(drop_location())
to_chat(user, span_notice("You remove the [voodoo_link] from the doll."))
voodoo_link = null
update_targets()
return
if(target && cooldown < world.time)
switch(user.zone_selected)
if(BODY_ZONE_PRECISE_MOUTH)
var/wgw = sanitize(input(user, "What would you like the victim to say", "Voodoo", null) as text)
target.say(wgw, forced = "voodoo doll")
log_game("[key_name(user)] made [key_name(target)] say [wgw] with a voodoo doll.")
if(BODY_ZONE_PRECISE_EYES)
user.set_machine(src)
user.reset_perspective(target)
spawn(100)
user.reset_perspective(null)
user.unset_machine()
if(BODY_ZONE_R_LEG,BODY_ZONE_L_LEG)
to_chat(user, span_notice("You move the doll's legs around."))
var/turf/T = get_step(target,pick(GLOB.cardinals))
target.Move(T)
if(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM)
target.click_random_mob()
GiveHint(target)
if(BODY_ZONE_HEAD)
to_chat(user, span_notice("You smack the doll's head with your hand."))
target.adjust_dizzy(10)
to_chat(target, span_warning("You suddenly feel as if your head was hit with a hammer!"))
GiveHint(target,user)
cooldown = world.time + cooldown_time
/obj/item/voodoo/proc/update_targets()
possible = list()
if(!voodoo_link)
return
var/list/prints = voodoo_link.return_fingerprints()
if(!length(prints))
return FALSE
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
if(prints[md5(H.dna.unique_identity)])
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
if(prob(50) || force)
var/way = dir2text(get_dir(victim,get_turf(src)))
to_chat(victim, span_notice("You feel a dark presence from [way]"))
if(prob(20) || force)
var/area/A = get_area(src)
to_chat(victim, span_notice("You feel a dark presence from [A.name]"))
/obj/item/voodoo/suicide_act(mob/living/carbon/user)
user.visible_message(span_suicide("[user] links the voodoo doll to [user.p_them()]self and sits on it, infinitely crushing [user.p_them()]self! It looks like [user.p_theyre()] trying to commit suicide!"))
user.gib()
return(BRUTELOSS)
/obj/item/voodoo/fire_act(exposed_temperature, exposed_volume)
if(target)
target.adjust_fire_stacks(20)
target.ignite_mob()
GiveHint(target,1)
return ..()
//Provides a decent heal, need to pump every 6 seconds
/obj/item/organ/heart/cursed/wizard
pump_delay = 60
heal_brute = 25
heal_burn = 25
heal_oxy = 25
//Warp Whistle: Provides uncontrolled long distance teleportation.
/obj/item/warp_whistle
name = "warp whistle"
desc = "One toot on this whistle will send you to a far away land!"
icon = 'icons/obj/wizard.dmi'
icon_state = "whistle"
var/on_cooldown = 0 //0: usable, 1: in use, 2: on cooldown
var/mob/living/carbon/last_user
/obj/item/warp_whistle/proc/interrupted(mob/living/carbon/user)
if(!user || QDELETED(src) || user.notransform)
on_cooldown = FALSE
return TRUE
return FALSE
/obj/item/warp_whistle/proc/end_effect(mob/living/carbon/user)
user.invisibility = initial(user.invisibility)
user.status_flags &= ~GODMODE
user.update_mobility()
/obj/item/warp_whistle/attack_self(mob/living/carbon/user)
if(!istype(user) || on_cooldown)
return
on_cooldown = TRUE
last_user = user
var/turf/T = get_turf(user)
playsound(T,'sound/magic/warpwhistle.ogg', 200, 1)
user.mobility_flags &= ~MOBILITY_MOVE
new /obj/effect/temp_visual/tornado(T)
sleep(2 SECONDS)
if(interrupted(user))
return
user.invisibility = INVISIBILITY_MAXIMUM
user.status_flags |= GODMODE
sleep(2 SECONDS)
if(interrupted(user))
end_effect(user)
return
var/breakout = 0
while(breakout < 50)
var/turf/potential_T = find_safe_turf()
if(T.z != potential_T.z || abs(get_dist_euclidian(potential_T,T)) > 50 - breakout)
do_teleport(user, potential_T, channel = TELEPORT_CHANNEL_MAGIC)
user.mobility_flags &= ~MOBILITY_MOVE
T = potential_T
break
breakout += 1
new /obj/effect/temp_visual/tornado(T)
sleep(2 SECONDS)
end_effect(user)
if(interrupted(user))
return
on_cooldown = 2
sleep(4 SECONDS)
on_cooldown = 0
/obj/item/warp_whistle/Destroy()
if(on_cooldown == 1 && last_user) //Flute got dunked somewhere in the teleport
end_effect(last_user)
return ..()
/obj/effect/temp_visual/tornado
icon = 'icons/obj/wizard.dmi'
icon_state = "tornado"
name = "tornado"
desc = "This thing sucks!"
layer = FLY_LAYER
randomdir = 0
duration = 40
pixel_x = 500
/obj/effect/temp_visual/tornado/Initialize(mapload)
. = ..()
animate(src, pixel_x = -500, time = 4 SECONDS)