mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-08-28 08:26:13 +01:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
/datum/targetable/spell/animatedead
|
||||
name = "Animate Dead"
|
||||
desc = "Turns a human corpse into a skeletal minion."
|
||||
icon_state = "pet"
|
||||
targeted = 1
|
||||
max_range = 1
|
||||
cooldown = 850
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
cooldown_staff = 1
|
||||
sticky = 1
|
||||
|
||||
cast(mob/target)
|
||||
if(!holder)
|
||||
return
|
||||
if(target.stat != 2)
|
||||
boutput(holder.owner, "<span style=\"color:red\">That person is still alive! Find a corpse.</span>")
|
||||
return 1 // No cooldown when it fails.
|
||||
|
||||
holder.owner.say("EI NECRIS")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/AnimateDeadLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/obj/critter/magiczombie/UMMACTUALLYITSASKELETONNOWFUCKZOMBIESFOREVER = new /obj/critter/magiczombie(get_turf(target)) // what the fuck
|
||||
UMMACTUALLYITSASKELETONNOWFUCKZOMBIESFOREVER.CustomizeMagZom(target.real_name)
|
||||
|
||||
boutput(holder.owner, "<span style=\"color:blue\">You saturate [target] with dark magic!</span>")
|
||||
holder.owner.visible_message("<span style=\"color:red\">[holder.owner] rips the skeleton from [target]'s corpse!</span>")
|
||||
|
||||
for(var/obj/item/I in target)
|
||||
if(istype(target, /obj/item))
|
||||
target.u_equip(I)
|
||||
if(I)
|
||||
I.set_loc(target.loc)
|
||||
I.dropped(target)
|
||||
target.gib(1)
|
||||
@@ -0,0 +1,57 @@
|
||||
/datum/targetable/spell/blind
|
||||
name = "Blind"
|
||||
desc = "Makes the victim temporarily unable to see."
|
||||
icon_state = "blind"
|
||||
targeted = 1
|
||||
cooldown = 100
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
sticky = 1
|
||||
|
||||
cast(mob/target)
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.say("YSTIGG MITAZIM")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/BlindLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(4, 1, target)
|
||||
s.start()
|
||||
|
||||
if (target.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(holder.owner, "<span style=\"color:red\">[target] has divine protection from magic.</span>")
|
||||
target.visible_message("<span style=\"color:red\">The spell fails to work on [target]!</span>")
|
||||
return
|
||||
|
||||
if (iswizard(target) && target.wizard_spellpower())
|
||||
target.visible_message("<span style=\"color:red\">The spell fails to work on [target]!</span>")
|
||||
return
|
||||
|
||||
var/obj/overlay/B = new /obj/overlay(target.loc)
|
||||
B.icon_state = "blspell"
|
||||
B.icon = 'icons/obj/wizard.dmi'
|
||||
B.name = "spell"
|
||||
B.anchored = 1
|
||||
B.density = 0
|
||||
B.layer = MOB_EFFECT_LAYER
|
||||
target.canmove = 0
|
||||
spawn(5)
|
||||
qdel(B)
|
||||
target.canmove = 1
|
||||
boutput(target, "<span style=\"color:blue\">Your eyes cry out in pain!</span>")
|
||||
target.visible_message("<span style=\"color:red\">Sparks fly out of [target]'s eyes!</span>")
|
||||
if (holder.owner.wizard_spellpower())
|
||||
target.weakened += 2
|
||||
target.bioHolder.AddEffect("bad_eyesight")
|
||||
spawn(450)
|
||||
if (target) target.bioHolder.RemoveEffect("bad_eyesight")
|
||||
target.take_eye_damage(10, 1)
|
||||
target.change_eye_blurry(20)
|
||||
else
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell doesn't last as long without a staff to focus it!</span>")
|
||||
target.weakened += 1
|
||||
target.bioHolder.AddEffect("bad_eyesight")
|
||||
spawn(300)
|
||||
target.bioHolder.RemoveEffect("bad_eyesight")
|
||||
target.take_eye_damage(5, 1)
|
||||
target.change_eye_blurry(10)
|
||||
@@ -0,0 +1,67 @@
|
||||
/datum/targetable/spell/blink
|
||||
name = "Blink"
|
||||
desc = "Teleport randomly to a nearby tile."
|
||||
icon_state = "blink"
|
||||
targeted = 0
|
||||
cooldown = 100
|
||||
requires_robes = 1
|
||||
restricted_area_check = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
var/mob/living/carbon/human/H = holder.owner
|
||||
|
||||
holder.owner.say("SYCAR TYN")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/BlinkLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/accuracy = 3
|
||||
if(holder.owner.wizard_spellpower())
|
||||
accuracy = 1
|
||||
else
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell is weak without a staff to focus it!</span>")
|
||||
|
||||
if(H.burning)
|
||||
boutput(holder.owner, "<span style=\"color:blue\">The flames sputter out as you blink away.</span>")
|
||||
H.set_burning(0)
|
||||
|
||||
var/targetx = holder.owner.x
|
||||
var/targety = holder.owner.y
|
||||
|
||||
if(holder.owner.dir == 1)
|
||||
targety = holder.owner.y + 4
|
||||
targetx = holder.owner.x
|
||||
else if(holder.owner.dir == 4)
|
||||
targetx = holder.owner.x + 4
|
||||
targety = holder.owner.y
|
||||
else if(holder.owner.dir == 2)
|
||||
targety = holder.owner.y - 4
|
||||
targetx = holder.owner.x
|
||||
else if(holder.owner.dir == 8)
|
||||
targetx = holder.owner.x - 4
|
||||
targety = holder.owner.y
|
||||
|
||||
var/turf/targetturf = locate(targetx, targety, holder.owner.z)
|
||||
|
||||
playsound(holder.owner.loc, "sound/effects/mag_teleport.ogg", 25, 1, -1)
|
||||
|
||||
var/list/turfs = new/list()
|
||||
for(var/turf/T in orange(accuracy,targetturf))
|
||||
if(istype(T,/turf/space)) continue
|
||||
if(T.density) continue
|
||||
if(T.x>world.maxx-4 || T.x<4) continue //putting them at the edge is dumb
|
||||
if(T.y>world.maxy-4 || T.y<4) continue
|
||||
turfs += T
|
||||
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
|
||||
smoke.set_up(10, 0, holder.owner.loc)
|
||||
smoke.start()
|
||||
var/turf/picked = null
|
||||
if (turfs.len) picked = pick(turfs)
|
||||
if(!isturf(picked))
|
||||
boutput(holder.owner, "<span style=\"color:red\">It's too dangerous to blink there!</span>")
|
||||
return
|
||||
if(picked.loc.name == "Chapel" && get_corruption_percent() < 40)
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell fails due to divine intervention! You should move away from the Chapel.</span>")
|
||||
else
|
||||
animate_blink(holder.owner)
|
||||
holder.owner.set_loc(picked)
|
||||
@@ -0,0 +1,61 @@
|
||||
/datum/targetable/spell/bullcharge
|
||||
name = "Bull's Charge"
|
||||
desc = "Records the casters movement for 4 seconds after which the spell will fire and throw & heavily damage everyone in it's recorded Path."
|
||||
icon_state = "scream" // Vaguely matching placeholder.
|
||||
targeted = 0
|
||||
cooldown = 150
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.say("RAMI TIN")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/BullChargeLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/list/path = list()
|
||||
var/turf/first = holder.owner.loc
|
||||
var/turf/prev = first
|
||||
for(var/i = 0, i < 40, i++)
|
||||
var/turf/curr = holder.owner.loc
|
||||
animate_bullspellground(curr, "#aaddff")
|
||||
if(prev != curr)
|
||||
path += curr
|
||||
prev = curr
|
||||
sleep(1)
|
||||
|
||||
playsound(holder.owner.loc, "sound/effects/bull.ogg", 25, 1, -1)
|
||||
|
||||
var/list/affected = list()
|
||||
var/obj/effects/bullshead/B = new/obj/effects/bullshead(first)
|
||||
for(var/turf/T in path)
|
||||
B.dir = get_dir(B, T)
|
||||
B.loc = T
|
||||
animate_bullspellground(T, "#5599ff")
|
||||
for (var/atom/movable/M in T)
|
||||
if (M.anchored || affected.Find(M) || M == holder.owner)
|
||||
continue
|
||||
affected += M
|
||||
spawn(0) M.throw_at(get_edge_cheap(T, B.dir), 30, 1)
|
||||
if (ismob(M))
|
||||
var/mob/some_idiot = M
|
||||
some_idiot.weakened += 3
|
||||
some_idiot.TakeDamage("chest", 33, 0, 0, DAMAGE_BLUNT)
|
||||
sleep(1)
|
||||
|
||||
qdel(B)
|
||||
|
||||
/obj/effects/bullshead
|
||||
name = "magic"
|
||||
desc = "i aint gotta explain shit"
|
||||
density = 0
|
||||
opacity = 0
|
||||
anchored = 1
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "bull"
|
||||
|
||||
New()
|
||||
src.alpha = 245
|
||||
animate(src, alpha = 1, time = 30)
|
||||
@@ -0,0 +1,58 @@
|
||||
/datum/targetable/spell/clairvoyance
|
||||
name = "Clairvoyance"
|
||||
desc = "Finds the location of a target."
|
||||
icon_state = "clairvoyance"
|
||||
targeted = 0
|
||||
cooldown = 600
|
||||
requires_robes = 1
|
||||
cooldown_staff = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.say("HAIDAN SEEHQ")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/ClairvoyanceLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/list/mob/targets = list()
|
||||
for (var/mob/living/carbon/human/H in world)
|
||||
targets += H
|
||||
|
||||
if (targets.len > 1)
|
||||
targets = sortNames(targets)
|
||||
|
||||
var/t1 = input(holder.owner, "Select target", "Clairvoyance") as null|anything in targets
|
||||
if (!t1)
|
||||
return 1
|
||||
|
||||
var/mob/M = targets[t1]
|
||||
if (!M || !ismob(M))
|
||||
return 1
|
||||
|
||||
var/atom/target_loc = M.loc
|
||||
if (holder.owner.z == 2)
|
||||
if (M.z == 2)
|
||||
boutput(holder.owner, "<span style=\"color:blue\"><B>[M.real_name]</B> is in [target_loc.loc].</span>")
|
||||
return
|
||||
else
|
||||
boutput(holder.owner, "<span style=\"color:red\"><B>[M.real_name]</B> isn't in VR!</span>")
|
||||
return
|
||||
if (M.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(holder.owner, "<span style=\"color:red\">[M] has divine protection. Your scrying spell fails!</span>")
|
||||
boutput(M, "<span style=\"color:red\">You sense a Wizard's scrying spell!</span>")
|
||||
else
|
||||
var/spellstring = "<B>[M.real_name]</B> is "
|
||||
if (!istype(target_loc, /turf))
|
||||
if (target_loc.loc.name == "Chapel")
|
||||
spellstring = "<span style=\"color:red\">Your scrying spell fails! It just can't seem to find [M.real_name].</span>"
|
||||
boutput(M, "<span style=\"color:red\">You sense a Wizard's scrying spell!</span>")
|
||||
return
|
||||
if(istype(target_loc, /mob))
|
||||
spellstring += "somehow inside <b>[target_loc.name]</b> in <b>[target_loc.loc.loc]</b>."
|
||||
else if(istype(target_loc, /obj))
|
||||
spellstring += "inside \a <b>[target_loc.name]</b> in <b>[target_loc.loc.loc]</b>."
|
||||
else
|
||||
spellstring += "in [target_loc.loc]."
|
||||
if (M.stat == 2)
|
||||
spellstring += " They also seem to be dead."
|
||||
|
||||
boutput(holder.owner, "<span style=\"color:blue\">[spellstring]</span>")
|
||||
@@ -0,0 +1,102 @@
|
||||
/datum/targetable/spell/cluwne
|
||||
name = "Clown's Revenge"
|
||||
desc = "Turns the target into a fat cursed clown."
|
||||
icon_state = "clownrevenge"
|
||||
targeted = 1
|
||||
max_range = 1
|
||||
cooldown = 1250
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
sticky = 1
|
||||
|
||||
cast(mob/target)
|
||||
if(!holder)
|
||||
return
|
||||
var/mob/living/carbon/human/H = target
|
||||
if (!istype(H))
|
||||
boutput(holder.owner, "Your target must be human!")
|
||||
return 1
|
||||
holder.owner.say("NWOLC EGNEVER")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/CluwneLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
|
||||
smoke.set_up(5, 0, H.loc)
|
||||
smoke.attach(H)
|
||||
smoke.start()
|
||||
|
||||
if (H.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(holder.owner, "<span style=\"color:red\">[H] has divine protection from magic.</span>")
|
||||
H.visible_message("<span style=\"color:red\">The spell has no effect on [H]!</span>")
|
||||
return
|
||||
|
||||
if (iswizard(H) && H.wizard_spellpower())
|
||||
H.visible_message("<span style=\"color:red\">The spell has no effect on [H]!</span>")
|
||||
return
|
||||
|
||||
// NPCs should always be cluwnable, I guess (Convair880)?
|
||||
if (H.mind && (H.mind.assigned_role != "Cluwne") || (!H.mind || !H.client))
|
||||
boutput(H, "<span style=\"color:red\"><B>You HONK painfully!</B></span>")
|
||||
H.take_brain_damage(80)
|
||||
H.stuttering = 120
|
||||
if (H.mind)
|
||||
H.mind.assigned_role = "Cluwne"
|
||||
H.contract_disease(/datum/ailment/disability/clumsy,null,null,1)
|
||||
H.contract_disease(/datum/ailment/disease/cluwneing_around,null,null,1)
|
||||
playsound(get_turf(H), pick("sound/voice/cluwnelaugh1.ogg","sound/voice/cluwnelaugh2.ogg","sound/voice/cluwnelaugh3.ogg"), 100, 0, 0, max(0.7, min(1.4, 1.0 + (30 - H.bioHolder.age)/50)))
|
||||
H.nutrition = 9000
|
||||
H.change_misstep_chance(66)
|
||||
|
||||
animate_clownspell(H)
|
||||
//H.unequip_all()
|
||||
H.drop_from_slot(H.w_uniform)
|
||||
H.drop_from_slot(H.shoes)
|
||||
H.drop_from_slot(H.wear_mask)
|
||||
H.drop_from_slot(H.gloves)
|
||||
H.equip_if_possible(new /obj/item/clothing/under/gimmick/cursedclown(H), H.slot_w_uniform)
|
||||
H.equip_if_possible(new /obj/item/clothing/shoes/cursedclown_shoes(H), H.slot_shoes)
|
||||
H.equip_if_possible(new /obj/item/clothing/mask/cursedclown_hat(H), H.slot_wear_mask)
|
||||
H.equip_if_possible(new /obj/item/clothing/gloves/cursedclown_gloves(H), H.slot_gloves)
|
||||
H.real_name = "cluwne"
|
||||
spawn (25) // Don't remove.
|
||||
if (H) H.assign_gimmick_skull() // The mask IS your new face, my friend (Convair880).
|
||||
else
|
||||
boutput(H, "<span style=\"color:red\"><b>You don't feel very funny.</b></span>")
|
||||
H.take_brain_damage(-120)
|
||||
H.stuttering = 0
|
||||
if (H.mind)
|
||||
H.mind.assigned_role = "Lawyer"
|
||||
H.change_misstep_chance(-INFINITY)
|
||||
H.nutrition = 0
|
||||
|
||||
animate_clownspell(H)
|
||||
for(var/datum/ailment_data/A in H.ailments)
|
||||
if(istype(A.master,/datum/ailment/disability/clumsy))
|
||||
H.cure_disease(A)
|
||||
var/obj/old_uniform = H.w_uniform
|
||||
var/obj/item/the_id = H.wear_id
|
||||
|
||||
if(H.w_uniform && findtext("[H.w_uniform.type]","clown"))
|
||||
H.w_uniform = new /obj/item/clothing/under/suit(H)
|
||||
qdel(old_uniform)
|
||||
|
||||
if(H.shoes && findtext("[H.shoes.type]","clown"))
|
||||
qdel(H.shoes)
|
||||
H.shoes = new /obj/item/clothing/shoes/black(H)
|
||||
|
||||
if(the_id && the_id:registered == H.real_name)
|
||||
if (istype(the_id, /obj/item/card/id))
|
||||
the_id:assignment = "Lawyer"
|
||||
the_id:name = "[H.real_name]'s ID Card (Lawyer)"
|
||||
else if (istype(the_id, /obj/item/device/pda2))
|
||||
the_id:assignment = "Lawyer"
|
||||
the_id:ID_card:assignment = "Lawyer"
|
||||
the_id:ID_card:name = "[H.real_name]'s ID Card (Lawyer)"
|
||||
H.wear_id = the_id
|
||||
|
||||
for(var/obj/item/W in H)
|
||||
if (findtext("[W.type]","clown"))
|
||||
H.u_equip(W)
|
||||
if (W)
|
||||
W.set_loc(target.loc)
|
||||
W.dropped(H)
|
||||
W.layer = initial(W.layer)
|
||||
@@ -0,0 +1,94 @@
|
||||
/datum/targetable/spell/doppelganger
|
||||
name = "Doppelganger"
|
||||
desc = "Creates a clone of you while temporarily making you undetectable. The clone keeps moving in whatever direction you were facing when you cast the spell."
|
||||
icon_state = "doppelganger"
|
||||
targeted = 0
|
||||
cooldown = 300
|
||||
requires_robes = 1
|
||||
restricted_area_check = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
var/the_dir = holder.owner.dir
|
||||
var/ground = 0
|
||||
|
||||
if (!isturf(holder.owner.loc))
|
||||
return 1
|
||||
|
||||
ground = holder.owner.lying
|
||||
|
||||
var/obj/overlay/P = new/obj/overlay()
|
||||
P.name = holder.owner.name
|
||||
P.icon = holder.owner.icon
|
||||
P.icon_state = holder.owner.icon_state
|
||||
P.density = 1
|
||||
P.desc = "Wait ... that's not [P.name]!!!"
|
||||
|
||||
var/obj/dummy/spell_doppel/D = new/obj/dummy/spell_doppel()
|
||||
|
||||
for(var/X in holder.owner.overlays)
|
||||
var/image/I = X
|
||||
P.overlays += I
|
||||
|
||||
holder.owner.say("GIN EMUS") // ^-- No speech bubble.
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/DopplegangerLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/turf/curr_turf = get_turf(holder.owner)
|
||||
|
||||
P.dir = the_dir
|
||||
P.set_loc(curr_turf)
|
||||
D.set_loc(curr_turf)
|
||||
holder.owner.set_loc(D)
|
||||
|
||||
if(!ground)
|
||||
spawn(0)
|
||||
while(P)
|
||||
step(P, the_dir)
|
||||
sleep(2)
|
||||
|
||||
spawn(100)
|
||||
holder.owner.set_loc(D.loc)
|
||||
qdel(D)
|
||||
qdel(P)
|
||||
|
||||
/obj/dummy/spell_doppel
|
||||
name = ""
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "nothing"
|
||||
invisibility = 100
|
||||
var/can_move = 1
|
||||
mouse_opacity = 0
|
||||
density = 0
|
||||
anchored = 1
|
||||
|
||||
/obj/dummy/spell_doppel/relaymove(var/mob/user, direction)
|
||||
if (!src.can_move) return
|
||||
|
||||
var/turf/newloc = get_step(src, direction)
|
||||
if (newloc.density) return
|
||||
|
||||
switch(direction)
|
||||
if(NORTH)
|
||||
src.y++
|
||||
if(SOUTH)
|
||||
src.y--
|
||||
if(EAST)
|
||||
src.x++
|
||||
if(WEST)
|
||||
src.x--
|
||||
if(NORTHEAST)
|
||||
src.y++
|
||||
src.x++
|
||||
if(NORTHWEST)
|
||||
src.y++
|
||||
src.x--
|
||||
if(SOUTHEAST)
|
||||
src.y--
|
||||
src.x++
|
||||
if(SOUTHWEST)
|
||||
src.y--
|
||||
src.x--
|
||||
|
||||
src.can_move = 0
|
||||
spawn(2) src.can_move = 1
|
||||
@@ -0,0 +1,82 @@
|
||||
/datum/targetable/spell/fireball
|
||||
name = "Fireball"
|
||||
desc = "Launches an explosive fireball at the target."
|
||||
icon_state = "fireball"
|
||||
targeted = 1
|
||||
target_anything = 1
|
||||
cooldown = 200
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
sticky = 1
|
||||
|
||||
cast(atom/target)
|
||||
holder.owner.say("MHOL HOTTOV")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/FireballLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/obj/overlay/A = new /obj/overlay(holder.owner.loc)
|
||||
playsound(holder.owner.loc, "sound/effects/mag_fireballlaunch.ogg", 25, 1, -1)
|
||||
A.icon_state = "fireball"
|
||||
A.icon = 'icons/obj/wizard.dmi'
|
||||
A.name = "a fireball"
|
||||
A.anchored = 0
|
||||
A.density = 0
|
||||
A.flags |= TABLEPASS
|
||||
A.fingerprintslast = "[holder.owner.key]"
|
||||
//A.sd_SetLuminosity(4)
|
||||
//A.sd_SetColor(0.95, 0.25, 0)
|
||||
spawn(0)
|
||||
for(var/i = 0, i < 100, i++)
|
||||
step_to(A, target, 0)
|
||||
if (get_dist(A, target) <= 1)
|
||||
var/mob/M = target
|
||||
if (istype(M))
|
||||
if (ishuman(M))
|
||||
if (M.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(holder.owner, "<span style=\"color:red\">[M] has divine protection from magic.</span>")
|
||||
M.visible_message("<span style=\"color:red\">The fireball strikes [M] with no effect whatsoever!</span>")
|
||||
playsound(M.loc, "sound/effects/bamf.ogg", 25, 1, -1)
|
||||
qdel(A)
|
||||
return
|
||||
if (iswizard(M) && M.wizard_spellpower())
|
||||
M.visible_message("<span style=\"color:red\">The fireball poofs into harmless smoke as it strikes [M]!</span>")
|
||||
playsound(M.loc, "sound/effects/bamf.ogg", 25, 1, -1)
|
||||
qdel(A)
|
||||
return
|
||||
var/turf/T = get_turf(target)
|
||||
if (holder.owner.wizard_spellpower())
|
||||
if (istype(M))
|
||||
random_brute_damage(M, 25)
|
||||
M.lastattacker = holder.owner
|
||||
M.lastattackertime = world.time
|
||||
M.TakeDamage("chest", 0, 20, 0, DAMAGE_BURN)
|
||||
for(var/mob/living/L in range(2, T))
|
||||
spawn(0)
|
||||
L.weakened += 5
|
||||
step(L,get_dir(T, L))
|
||||
spawn(5)
|
||||
if (target)
|
||||
step(L,get_dir(T, L))
|
||||
spawn(10)
|
||||
if (target)
|
||||
step(L,get_dir(T, L))
|
||||
if (target)
|
||||
explosion(A, T, -1, -1, 2, 2)
|
||||
fireflash(T, 1)
|
||||
qdel(A)
|
||||
return
|
||||
else
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell is weak without a staff to focus it!</span>")
|
||||
if (istype(M))
|
||||
M.weakened += 5
|
||||
M.lastattacker = holder.owner
|
||||
M.lastattackertime = world.time
|
||||
random_brute_damage(M, 10)
|
||||
M.TakeDamage("chest", 0, 10, 0, DAMAGE_BURN)
|
||||
else
|
||||
explosion(A, T, -1, -1, 1, 1)
|
||||
fireflash(T,0)
|
||||
playsound(T, "sound/effects/bamf.ogg", 25, 1, -1)
|
||||
target.visible_message("<span style=\"color:red\">[target] is struck by the fireball!</span>")
|
||||
qdel(A)
|
||||
sleep(2)
|
||||
qdel(A)
|
||||
@@ -0,0 +1,55 @@
|
||||
/datum/targetable/spell/forcewall
|
||||
name = "Forcewall"
|
||||
desc = "Create a forcewall which extends out to your sides."
|
||||
icon_state = "forcewall"
|
||||
targeted = 0
|
||||
cooldown = 100
|
||||
requires_robes = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.say("BRIXHUN MOHTYR")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/ForcewallLoud.ogg", 50, 0, -1)
|
||||
if(!holder.owner.wizard_spellpower())
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell is weak without a staff to focus it!</span>")
|
||||
|
||||
playsound(holder.owner.loc, "sound/effects/mag_forcewall.ogg", 25, 1, -1)
|
||||
var/forcefield1
|
||||
var/forcefield2
|
||||
var/forcefield3
|
||||
var/forcefield4
|
||||
var/forcefield5
|
||||
|
||||
if (holder.owner.dir == NORTH || holder.owner.dir == SOUTH)
|
||||
forcefield1 = new /obj/forcefield(locate(holder.owner.x, holder.owner.y, holder.owner.z))
|
||||
forcefield2 = new /obj/forcefield(locate(holder.owner.x + 1, holder.owner.y, holder.owner.z))
|
||||
forcefield3 = new /obj/forcefield(locate(holder.owner.x - 1, holder.owner.y, holder.owner.z))
|
||||
if (holder.owner.wizard_spellpower()) forcefield4 = new /obj/forcefield(locate(holder.owner.x + 2, holder.owner.y, holder.owner.z))
|
||||
if (holder.owner.wizard_spellpower()) forcefield5 = new /obj/forcefield(locate(holder.owner.x - 2, holder.owner.y, holder.owner.z))
|
||||
else
|
||||
forcefield1 = new /obj/forcefield(locate(holder.owner.x, holder.owner.y, holder.owner.z))
|
||||
forcefield2 = new /obj/forcefield(locate(holder.owner.x, holder.owner.y + 1, holder.owner.z))
|
||||
forcefield3 = new /obj/forcefield(locate(holder.owner.x, holder.owner.y - 1, holder.owner.z))
|
||||
if (holder.owner.wizard_spellpower()) forcefield4 = new /obj/forcefield(locate(holder.owner.x,holder.owner.y + 2,holder.owner.z))
|
||||
if (holder.owner.wizard_spellpower()) forcefield5 = new /obj/forcefield(locate(holder.owner.x,holder.owner.y - 2,holder.owner.z))
|
||||
|
||||
spawn(300)
|
||||
qdel(forcefield1)
|
||||
qdel(forcefield2)
|
||||
qdel(forcefield3)
|
||||
if (forcefield4)
|
||||
qdel(forcefield4)
|
||||
if (forcefield5)
|
||||
qdel(forcefield5)
|
||||
|
||||
/obj/forcefield
|
||||
desc = "A space wizard's magic wall."
|
||||
name = "Forcewall"
|
||||
desc = "An impenetrable magic barrier. Its only flaw is that it cannot last long."
|
||||
icon = 'icons/obj/wizard.dmi'
|
||||
icon_state = "forcewall"
|
||||
anchored = 1.0
|
||||
opacity = 0
|
||||
density = 1
|
||||
luminosity = 3
|
||||
@@ -0,0 +1,62 @@
|
||||
/datum/targetable/spell/golem
|
||||
name = "Summon Golem"
|
||||
desc = "Summons a Golem made of the reagent you currently hold."
|
||||
icon_state = "golem"
|
||||
targeted = 0
|
||||
cooldown = 500
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
cooldown_staff = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
var/obj/item/AnItem = null //temp item holder for processing
|
||||
var/datum/reagents/TheReagents = null //reagent holder
|
||||
|
||||
//get reagent container if there is one, and check to see it has some reagents
|
||||
if (holder.owner.r_hand != null)
|
||||
AnItem = holder.owner.r_hand
|
||||
if(istype(AnItem, /obj/item/reagent_containers/))
|
||||
if(AnItem.reagents.total_volume)
|
||||
TheReagents = AnItem.reagents
|
||||
else
|
||||
AnItem = null
|
||||
|
||||
|
||||
|
||||
if (holder.owner.l_hand != null && !AnItem)
|
||||
AnItem = holder.owner.l_hand
|
||||
if(istype(AnItem, /obj/item/reagent_containers/))
|
||||
if(AnItem.reagents.total_volume)
|
||||
TheReagents = AnItem.reagents
|
||||
else
|
||||
AnItem = null
|
||||
|
||||
|
||||
if(!AnItem)
|
||||
boutput(holder.owner, "<span style=\"color:red\">You must be holding a container in your hand.</span>")
|
||||
return 1 // No cooldown when it fails.
|
||||
|
||||
if(!TheReagents)
|
||||
boutput(holder.owner, "<span style=\"color:red\">You have no material to convert into a golem.</span>")
|
||||
return 1
|
||||
|
||||
|
||||
holder.owner.say("CLAE MASHON")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/GolemLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/obj/critter/golem/TheGolem
|
||||
if (istype(AnItem, /obj/item/reagent_containers/food/snacks/ingredient/egg/bee))
|
||||
TheGolem = new /obj/critter/domestic_bee(get_turf(holder.owner))
|
||||
TheGolem.name = "Bee Golem"
|
||||
TheGolem.desc = "A greater domestic space bee that has been created with magic, but is otherwise completely identical to any other member of its species."
|
||||
else
|
||||
TheGolem = new /obj/critter/golem(get_turf(holder.owner))
|
||||
TheGolem.CustomizeGolem(TheReagents)
|
||||
|
||||
qdel(TheReagents)
|
||||
qdel(AnItem)
|
||||
boutput(holder.owner, "<span style=\"color:blue\">You conjure up [TheGolem]!</span>")
|
||||
holder.owner.visible_message("<span style=\"color:red\">[holder.owner] conjures up [TheGolem]!</span>")
|
||||
playsound(holder.owner.loc, "sound/effects/mag_golem.ogg", 25, 1, -1)
|
||||
@@ -0,0 +1,168 @@
|
||||
/datum/targetable/spell/iceburst
|
||||
name = "Ice Burst"
|
||||
desc = "Launches freezing bolts at nearby foes."
|
||||
icon_state = "iceburst"
|
||||
targeted = 0
|
||||
cooldown = 200
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
var/count = 0
|
||||
var/count2 = 0
|
||||
var/moblimit = 3
|
||||
|
||||
for(var/mob/living/M as mob in oview())
|
||||
if(M.stat == 2) continue
|
||||
count2++
|
||||
if(!count2)
|
||||
boutput(holder.owner, "Noone is in range!")
|
||||
return 1
|
||||
|
||||
holder.owner.say("NYTH ERRIN")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/IceburstLoud.ogg", 50, 0, -1)
|
||||
if(!holder.owner.wizard_spellpower())
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell is weak without a staff to focus it!</span>")
|
||||
|
||||
for (var/mob/living/M as mob in oview())
|
||||
if(M.stat == 2) continue
|
||||
if (ishuman(M))
|
||||
if (M.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(holder.owner, "<span style=\"color:red\">[M] has divine protection! The spell refuses to target \him!</span>")
|
||||
continue
|
||||
if (iswizard(M) && M.wizard_spellpower())
|
||||
boutput(holder.owner, "<span style=\"color:red\">[M] has arcane protection! The spell refuses to target \him!</span>")
|
||||
continue
|
||||
|
||||
playsound(holder.owner.loc, "sound/effects/mag_iceburstlaunch.ogg", 25, 1, -1)
|
||||
if ((!holder.owner.wizard_spellpower() && count >= 1) || (count >= moblimit)) break
|
||||
count++
|
||||
spawn(0)
|
||||
var/obj/overlay/A = new /obj/overlay( holder.owner.loc )
|
||||
A.icon_state = "icem"
|
||||
A.icon = 'icons/obj/wizard.dmi'
|
||||
A.name = "ice bolt"
|
||||
A.anchored = 0
|
||||
A.density = 0
|
||||
A.layer = MOB_EFFECT_LAYER
|
||||
//A.sd_SetLuminosity(3)
|
||||
//A.sd_SetColor(0, 0.1, 0.8)
|
||||
var/i
|
||||
for(i=0, i<20, i++)
|
||||
if (holder.owner.wizard_spellpower())
|
||||
if (!locate(/obj/decal/icefloor) in A.loc)
|
||||
var/obj/decal/icefloor/B = new /obj/decal/icefloor(A.loc)
|
||||
//B.sd_SetLuminosity(1)
|
||||
//B.sd_SetColor(0, 0.1, 0.8)
|
||||
spawn(200)
|
||||
qdel (B)
|
||||
step_to(A,M,0)
|
||||
if (get_dist(A,M) == 0)
|
||||
boutput(M, text("<span style=\"color:blue\">You are chilled by a burst of magical ice!</span>"))
|
||||
M.visible_message("<span style=\"color:red\">[M] is struck by magical ice!</span>")
|
||||
playsound(holder.owner.loc, "sound/effects/mag_iceburstimpact.ogg", 25, 1, -1)
|
||||
M.bodytemperature = 0
|
||||
M.lastattacker = holder.owner
|
||||
M.lastattackertime = world.time
|
||||
qdel(A)
|
||||
if(prob(40))
|
||||
M.visible_message("<span style=\"color:red\">[M] is frozen solid!</span>")
|
||||
new /obj/icecube(M.loc, M)
|
||||
return
|
||||
sleep(5)
|
||||
qdel(A)
|
||||
|
||||
// /obj/decal/icefloor moved to decal.dm
|
||||
|
||||
/obj/icecube
|
||||
name = "ice cube"
|
||||
desc = "That is a surprisingly large ice cube."
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "icecube"
|
||||
density = 1
|
||||
layer = EFFECTS_LAYER_BASE
|
||||
var/health = 10
|
||||
var/steam_on_death = 1
|
||||
|
||||
New(loc, mob/iced as mob)
|
||||
..()
|
||||
if(iced && !isAI(iced) && !istype(iced, /mob/living/intangible/blob_overmind))
|
||||
if(istype(iced.loc, /obj/icecube)) //Already in a cube?
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
iced.set_loc(src)
|
||||
|
||||
src.underlays += iced
|
||||
boutput(iced, "<span style=\"color:red\">You are trapped within [src]!</span>") // since this is used in at least two places to trap people in things other than ice cubes
|
||||
src.health *= (rand(10,20)/10)
|
||||
return
|
||||
|
||||
relaymove(mob/user as mob)
|
||||
if (user.stat)
|
||||
return
|
||||
|
||||
if(prob(25))
|
||||
src.health--
|
||||
if(src.health <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
attack_hand(mob/user as mob)
|
||||
user.visible_message("<span class='combat'><b>[user]</b> kicks [src]!</span>", "<span style=\"color:blue\">You kick [src].</span>")
|
||||
|
||||
src.health -= 2
|
||||
if(src.health <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
bullet_act(var/obj/projectile/P)
|
||||
var/damage = 0
|
||||
damage = round(((P.power/2)*P.proj_data.ks_ratio), 1.0)
|
||||
if (damage < 1)
|
||||
return
|
||||
|
||||
if(src.material) src.material.triggerOnAttacked(src, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter) )
|
||||
for(var/atom/A in src)
|
||||
if(A.material)
|
||||
A.material.triggerOnAttacked(A, P.shooter, src, (ismob(P.shooter) ? P.shooter:equipped() : P.shooter))
|
||||
|
||||
switch(P.proj_data.damage_type)
|
||||
if(D_KINETIC)
|
||||
src.health -= (damage*2)
|
||||
if(D_PIERCING)
|
||||
src.health -= (damage/2)
|
||||
if(D_ENERGY)
|
||||
src.health -= (damage/4)
|
||||
|
||||
if(src.health <= 0)
|
||||
qdel(src)
|
||||
|
||||
return
|
||||
|
||||
attackby(obj/item/W as obj, mob/user as mob)
|
||||
src.health -= W.force
|
||||
if(src.health <= 0)
|
||||
qdel(src)
|
||||
return
|
||||
..()
|
||||
return
|
||||
|
||||
disposing()
|
||||
for(var/atom/movable/AM in src)
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
M.visible_message("<span style=\"color:red\"><b>[M]</b> breaks out of [src]!</span>","<span style=\"color:red\">You break out of [src]!</span>")
|
||||
AM.set_loc(src.loc)
|
||||
|
||||
if (steam_on_death)
|
||||
if (!(locate(/datum/effects/system/steam_spread) in src.loc))
|
||||
var/datum/effects/system/steam_spread/steam = unpool(/datum/effects/system/steam_spread)
|
||||
steam.set_up(10, 0, get_turf(src))
|
||||
steam.attach(src)
|
||||
steam.start()
|
||||
|
||||
..()
|
||||
return
|
||||
@@ -0,0 +1,49 @@
|
||||
/datum/targetable/spell/kill
|
||||
name = "Shocking Grasp"
|
||||
desc = "Kills the victim with electrical power. Takes a few seconds to cast."
|
||||
icon_state = "grasp"
|
||||
targeted = 1
|
||||
max_range = 1
|
||||
cooldown = 600
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
sticky = 1
|
||||
|
||||
cast(mob/target)
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.visible_message("<span style=\"color:red\"><b>[holder.owner] begins to cast a spell on [target]!</b></span>")
|
||||
playsound(holder.owner.loc, "sound/effects/elec_bzzz.ogg", 25, 1, -1)
|
||||
if (do_mob(holder.owner, target, 20))
|
||||
holder.owner.say("EI NATH")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/ShockingGraspLoud.ogg", 50, 0, -1)
|
||||
playsound(holder.owner.loc, "sound/effects/elec_bigzap.ogg", 25, 1, -1)
|
||||
|
||||
if (ishuman(target))
|
||||
if (target.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(holder.owner, "<span style=\"color:red\">[target] has divine protection from magic.</span>")
|
||||
target.visible_message("<span style=\"color:red\">The electric charge courses through [target] harmlessly!</span>")
|
||||
return
|
||||
else if (iswizard(target) && target.wizard_spellpower())
|
||||
target.visible_message("<span style=\"color:red\">The electric charge somehow completely misses [target]!</span>")
|
||||
return
|
||||
|
||||
if (holder.owner.wizard_spellpower())
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(4, 1, target)
|
||||
s.start()
|
||||
target.elecgib()
|
||||
else
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(4, 1, target)
|
||||
s.start()
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell is weak without a staff to focus it!</span>")
|
||||
target.visible_message("<span style=\"color:red\">[target] is severely burned by an electrical charge!</span>")
|
||||
target.lastattacker = holder.owner
|
||||
target.lastattackertime = world.time
|
||||
target.TakeDamage("chest", 0, 80, 0, DAMAGE_BURN)
|
||||
target.stunned += 10
|
||||
target.weakened += 10
|
||||
target.stuttering += 15
|
||||
else
|
||||
return 1 // no cooldown if it fails
|
||||
@@ -0,0 +1,34 @@
|
||||
/datum/targetable/spell/knock
|
||||
name = "Knock"
|
||||
desc = "Opens nearby doors."
|
||||
icon_state = "knock"
|
||||
targeted = 0
|
||||
cooldown = 100
|
||||
requires_robes = 1
|
||||
restricted_area_check = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.say("AULIE OXIN FIERA")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/KnockLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/SPrange = 1
|
||||
if (holder.owner.wizard_spellpower())
|
||||
SPrange = 5
|
||||
else
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell only works at point blank without a staff to focus it!</span>")
|
||||
for(var/obj/machinery/door/G in oview(SPrange, holder.owner))
|
||||
spawn(1)
|
||||
G.open()
|
||||
for(var/obj/storage/F in oview(SPrange, holder.owner))
|
||||
if (F.locked)
|
||||
F.locked = 0
|
||||
spawn(1)
|
||||
F.open()
|
||||
for(var/mob/living/silicon/robot/E in oview(SPrange, holder.owner))
|
||||
spawn(1)
|
||||
E.spellopen()
|
||||
for(var/obj/machinery/bot/B in oview(SPrange, holder.owner))
|
||||
B.locked = 0
|
||||
B.req_access = null
|
||||
@@ -0,0 +1,76 @@
|
||||
/datum/targetable/spell/magicmissile
|
||||
name = "Magic Missile"
|
||||
desc = "Attacks nearby foes with stunning projectiles."
|
||||
icon_state = "missile"
|
||||
targeted = 0
|
||||
cooldown = 200
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
var/mob_count = 0, mob_count2 = 0
|
||||
var/mob_limit = 6
|
||||
|
||||
for(var/mob/living/M as mob in oview())
|
||||
if(M.stat == 2) continue
|
||||
mob_count++
|
||||
if(!mob_count)
|
||||
boutput(holder.owner, "Noone is in range!")
|
||||
return 1 // cast failed
|
||||
|
||||
holder.owner.say("ICEE BEEYEM")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/MagicMissileLoud.ogg", 50, 0, -1)
|
||||
if(!holder.owner.wizard_spellpower())
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell is weak without a staff to focus it!</span>")
|
||||
|
||||
for (var/mob/living/M as mob in oview())
|
||||
if (M.stat == 2) continue
|
||||
if (ishuman(M))
|
||||
if (M.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(holder.owner, "<span style=\"color:red\">[M] has divine protection! The spell refuses to target \him!</span>")
|
||||
continue
|
||||
if (iswizard(M) && M.wizard_spellpower())
|
||||
boutput(holder.owner, "<span style=\"color:red\">[M] has arcane protection! The spell refuses to target \him!</span>")
|
||||
continue
|
||||
|
||||
playsound(holder.owner.loc, "sound/effects/mag_magmislaunch.ogg", 25, 1, -1)
|
||||
if ((!holder.owner.wizard_spellpower() && mob_count2 >= 1) || (mob_count2 >= mob_limit)) break
|
||||
mob_count2++
|
||||
spawn(0)
|
||||
var/obj/overlay/A = new /obj/overlay(holder.owner.loc)
|
||||
A.icon_state = "magicm"
|
||||
A.icon = 'icons/obj/wizard.dmi'
|
||||
A.name = "a magic missile"
|
||||
A.anchored = 0
|
||||
A.density = 0
|
||||
A.layer = EFFECTS_LAYER_1
|
||||
A.flags |= TABLEPASS
|
||||
//A.sd_SetLuminosity(3)
|
||||
//A.sd_SetColor(0.7, 0, 0.7)
|
||||
var/i
|
||||
for(i=0, i<20, i++)
|
||||
var/obj/overlay/B = new /obj/overlay(A.loc)
|
||||
B.icon_state = "magicmd"
|
||||
B.icon = 'icons/obj/wizard.dmi'
|
||||
B.name = "trail"
|
||||
B.anchored = 1
|
||||
B.density = 0
|
||||
B.layer = EFFECTS_LAYER_BASE
|
||||
spawn(5)
|
||||
qdel(B)
|
||||
step_to(A,M,0)
|
||||
if (get_dist(A,M) == 0)
|
||||
M.weakened += (5 - (min(mob_count2,4)))
|
||||
boutput(M, text("<span style=\"color:blue\">The magic missile SLAMS into you!</span>"))
|
||||
M.visible_message("<span style=\"color:red\">[M] is struck by a magic missile!</span>")
|
||||
playsound(M.loc, "sound/effects/mag_magmisimpact.ogg", 25, 1, -1)
|
||||
M.TakeDamage("chest", 0, 10, 0, DAMAGE_BURN)
|
||||
random_brute_damage(M, 5)
|
||||
M.lastattacker = holder.owner
|
||||
M.lastattackertime = world.time
|
||||
qdel(A)
|
||||
return
|
||||
sleep(6)
|
||||
qdel(A)
|
||||
@@ -0,0 +1,34 @@
|
||||
/datum/targetable/spell/magshield
|
||||
name = "Spell Shield"
|
||||
desc = "Temporarily shield yourself from melee attacks and projectiles. It also absorbs some of the blast of explosions."
|
||||
icon_state = "spellshield"
|
||||
targeted = 0
|
||||
cooldown = 300
|
||||
requires_robes = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
if(holder.owner.spellshield)
|
||||
boutput(holder.owner, "<span style=\"color:red\">You already have a Spell Shield active!</span>")
|
||||
return
|
||||
|
||||
holder.owner.say("XYZZYX")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/MagicshieldLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/image/shield_overlay = null
|
||||
|
||||
holder.owner.spellshield = 1
|
||||
shield_overlay = image('icons/effects/effects.dmi', holder.owner, "enshield", MOB_LAYER+1)
|
||||
holder.owner.underlays += shield_overlay
|
||||
boutput(holder.owner, "<span style=\"color:blue\"><b>You are surrounded by a magical barrier!</b></span>")
|
||||
holder.owner.visible_message("<span style=\"color:red\">[holder.owner] is encased in a protective shield.</span>")
|
||||
playsound(holder.owner,"sound/effects/MagShieldUp.ogg",50,1)
|
||||
spawn(100)
|
||||
if(holder.owner && holder.owner.spellshield)
|
||||
holder.owner.spellshield = 0
|
||||
holder.owner.underlays -= shield_overlay
|
||||
shield_overlay = null
|
||||
boutput(holder.owner, "<span style=\"color:blue\"><b>Your magical barrier fades away!</b></span>")
|
||||
holder.owner.visible_message("<span style=\"color:red\">The shield protecting [holder.owner] fades away.</span>")
|
||||
playsound(usr,"sound/effects/MagShieldDown.ogg", 50, 1)
|
||||
@@ -0,0 +1,31 @@
|
||||
/datum/targetable/spell/mutate
|
||||
name = "Empower"
|
||||
desc = "Temporarily superpowers your body and mind."
|
||||
icon_state = "mutate"
|
||||
targeted = 0
|
||||
cooldown = 400
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.say("BIRUZ BENNAR")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/MutateLoud.ogg", 50, 0, -1)
|
||||
boutput(holder.owner, "<span style=\"color:blue\">Your mind and muscles are magically empowered!</span>")
|
||||
holder.owner.visible_message("<span style=\"color:red\">[holder.owner] glows with a POWERFUL aura!</span>")
|
||||
|
||||
if (!holder.owner.bioHolder.HasEffect("hulk"))
|
||||
holder.owner.bioHolder.AddEffect("hulk")
|
||||
if (!holder.owner.bioHolder.HasEffect("telekinesis") && holder.owner.wizard_spellpower())
|
||||
holder.owner.bioHolder.AddEffect("telekinesis")
|
||||
var/SPtime = 150
|
||||
if (holder.owner.wizard_spellpower())
|
||||
SPtime = 300
|
||||
else
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell doesn't last as long without a staff to focus it!</span>")
|
||||
spawn (SPtime)
|
||||
if (holder.owner.bioHolder.HasEffect("telekinesis"))
|
||||
holder.owner.bioHolder.RemoveEffect("telekinesis")
|
||||
if (holder.owner.bioHolder.HasEffect("hulk"))
|
||||
holder.owner.bioHolder.RemoveEffect("hulk")
|
||||
@@ -0,0 +1,161 @@
|
||||
/datum/targetable/spell/pandemonium
|
||||
name = "Pandemonium"
|
||||
desc = "Calls upon spirits of chaos to summon unpredictable effects."
|
||||
icon_state = "pandemonium"
|
||||
targeted = 0
|
||||
cooldown = 400
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.say("WATT LEHFUQUE")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/PandemoniumLoud.ogg", 50, 0, -1)
|
||||
|
||||
var/list/available_effects = list("babel", "boost", "roar", "signaljam", "grilles", "meteors")
|
||||
|
||||
var/protectuser = 1
|
||||
if (!holder.owner.wizard_spellpower())
|
||||
boutput(holder.owner, "<span style=\"color:red\">Without your staff to focus your spell, it may backfire!</span>")
|
||||
protectuser = 0
|
||||
|
||||
var/people_in_range = 0
|
||||
for (var/mob/living/carbon/M in range(7, holder.owner))
|
||||
if (M == holder.owner) continue
|
||||
people_in_range++
|
||||
|
||||
if (people_in_range)
|
||||
available_effects += "fireburst"
|
||||
available_effects += "tripballs"
|
||||
available_effects += "flashbang"
|
||||
available_effects += "screech"
|
||||
|
||||
var/string_of_effects = " "
|
||||
for (var/X in available_effects)
|
||||
string_of_effects += "[X] "
|
||||
|
||||
var/mob/living/carbon/human/W = holder.owner
|
||||
|
||||
switch(pick(available_effects))
|
||||
if("fireburst") W.PAND_Fireburst(protectuser)
|
||||
if("babel") W.PAND_Babel(protectuser)
|
||||
if("tripballs") W.PAND_Tripballs(protectuser)
|
||||
if("flashbang") W.PAND_Flashbang(protectuser)
|
||||
if("meteors") W.PAND_Meteors(protectuser)
|
||||
if("screech") W.PAND_Screech(protectuser)
|
||||
if("boost") W.PAND_Boost(protectuser)
|
||||
if("roar") W.PAND_Roar(protectuser)
|
||||
if("signaljam") W.PAND_Signaljam(protectuser)
|
||||
if("grilles") W.PAND_Grilles(protectuser)
|
||||
|
||||
// holy shit someone clean this up and just move it into the main spell proc, this is ridiclous
|
||||
/mob/living/carbon/human/proc/PAND_Fireburst(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> radiates a wave of burning heat!</span>", src), 1)
|
||||
playsound(src, "sound/effects/bamf.ogg", 80, 1)
|
||||
for (var/mob/living/carbon/human/M in range(6, src))
|
||||
if (M == src && protectuser) continue
|
||||
if (iswizard(M) && M.wizard_spellpower()) continue
|
||||
boutput(M, "<span style=\"color:red\">You suddenly burst into flames!</span>")
|
||||
M.update_burning(30)
|
||||
|
||||
/mob/living/carbon/human/proc/PAND_Babel(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> emits a faint smell of cheese!</span>", src), 1)
|
||||
playsound(src, "sound/misc/superfart.ogg", 80, 1)
|
||||
for (var/mob/living/carbon/human/M in mobs)
|
||||
if (M == src && protectuser) continue
|
||||
if (ishuman(M))
|
||||
if (M.bioHolder.HasEffect("training_chaplain")) continue
|
||||
if (iswizard(M) && M.wizard_spellpower()) continue
|
||||
M.bioHolder.AddEffect("accent_swedish", timeleft = 15)
|
||||
M.bioHolder.AddEffect("accent_comic", timeleft = 15)
|
||||
M.bioHolder.AddEffect("accent_elvis", timeleft = 15)
|
||||
M.bioHolder.AddEffect("accent_chav", timeleft = 15)
|
||||
|
||||
/mob/living/carbon/human/proc/PAND_Tripballs(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> radiates a confusing aura!</span>", src), 1)
|
||||
playsound(src, "sound/effects/bionic_sound.ogg", 80, 1)
|
||||
for (var/mob/living/carbon/human/M in range(25, src))
|
||||
if (M == src && protectuser) continue
|
||||
if (ishuman(M))
|
||||
if (M.bioHolder.HasEffect("training_chaplain")) continue
|
||||
if (iswizard(M) && M.wizard_spellpower()) continue
|
||||
boutput(M, "<span style=\"color:red\">You feel extremely strange!</span>")
|
||||
M.reagents.add_reagent("LSD", 20)
|
||||
M.reagents.add_reagent("THC", 20)
|
||||
M.reagents.add_reagent("psilocybin", 20)
|
||||
|
||||
/mob/living/carbon/human/proc/PAND_Flashbang(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> explodes into a brilliant flash of light!</span>", src), 1)
|
||||
playsound(src.loc, "sound/weapons/flashbang.ogg", 50, 1)
|
||||
for(var/mob/N in AIviewers(src, null))
|
||||
if(get_dist(N, src) <= 6)
|
||||
if(N != src)
|
||||
if (ishuman(N))
|
||||
if (N.bioHolder && N.bioHolder.HasEffect("training_chaplain"))
|
||||
continue
|
||||
if (iswizard(N) && N.wizard_spellpower())
|
||||
continue
|
||||
N.apply_flash(30, 5)
|
||||
if(N.client) shake_camera(N, 6, 4)
|
||||
|
||||
/mob/living/carbon/human/proc/PAND_Meteors(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> summons meteors!</span>", src), 1)
|
||||
for(var/turf/T in orange(1, src))
|
||||
if(!T.density)
|
||||
var/target_dir = get_dir(src.loc, T)
|
||||
var/turf/U = get_edge_target_turf(src, target_dir)
|
||||
new /obj/newmeteor/small(my_spawn = T, trg = U)
|
||||
|
||||
/mob/living/carbon/human/proc/PAND_Screech(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> emits a horrible shriek!</span>", src), 1)
|
||||
playsound(src.loc, "sound/effects/screech.ogg", 25, 1, -1)
|
||||
|
||||
for (var/mob/living/H in hearers(src, null))
|
||||
if (H == src && protectuser)
|
||||
continue
|
||||
if (ishuman(H) && H.bioHolder && H.bioHolder.HasEffect("training_chaplain"))
|
||||
H.show_text("You are immune to [src]'s screech!", "blue")
|
||||
continue
|
||||
if (iswizard(H) && H.wizard_spellpower())
|
||||
continue
|
||||
if (isvampire(H) && H.check_vampire_power(3) == 1)
|
||||
H.show_text("You are immune to [src]'s screech!", "blue")
|
||||
continue
|
||||
|
||||
H.apply_sonic_stun(0, 3, 0, 0, 0, 8)
|
||||
|
||||
sonic_attack_environmental_effect(src, 7, list("light", "window", "r_window"))
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/PAND_Boost(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> glows with magical power!</span>", src), 1)
|
||||
playsound(src.loc, "sound/mksounds/boost.ogg", 25, 1, -1)
|
||||
src.bioHolder.AddEffect("arcane_power", timeleft = 60)
|
||||
|
||||
/mob/living/carbon/human/proc/PAND_Roar(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> emits a horrific reverberating roar!</span>", src), 1)
|
||||
world << sound('sound/effects/mag_pandroar.ogg')
|
||||
for (var/mob/living/carbon/human/M in mobs)
|
||||
if (M == src && protectuser) continue
|
||||
if (ishuman(M))
|
||||
if (M.bioHolder.HasEffect("training_chaplain")) continue
|
||||
if (iswizard(M) && M.wizard_spellpower()) continue
|
||||
boutput(M, "<span style=\"color:red\">A horrifying noise stuns you in sheer terror!</span>")
|
||||
M.stunned += 3
|
||||
M.stuttering += 10
|
||||
|
||||
/mob/living/carbon/human/proc/PAND_Signaljam(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> emits a wave of electrical interference!</span>", src), 1)
|
||||
playsound(src.loc, "sound/effects/mag_warp.ogg", 25, 1, -1)
|
||||
for (var/mob/living/carbon/human/M in mobs)
|
||||
if (M.ears) boutput(M, "<span style=\"color:red\">Your headset speaker suddenly bursts into weird static!</span>")
|
||||
solar_flare = 1
|
||||
sleep(100)
|
||||
solar_flare = 0
|
||||
|
||||
/mob/living/carbon/human/proc/PAND_Grilles(var/protectuser = 1)
|
||||
for(var/mob/O in AIviewers(src, null)) O.show_message(text("<span style=\"color:red\"><B>[]</B> reshapes the metal around \him!</span>", src), 1)
|
||||
playsound(src.loc, "sound/effects/grillehit.ogg", 25, 1, -1)
|
||||
for(var/turf/simulated/floor/T in view(src,7))
|
||||
if (prob(33)) new /obj/grille/steel(T)
|
||||
@@ -0,0 +1,131 @@
|
||||
/datum/targetable/spell/phaseshift
|
||||
name = "Phase Shift"
|
||||
desc = "Become incorporeal and move through walls."
|
||||
icon_state = "phaseshift"
|
||||
targeted = 0
|
||||
cooldown = 300
|
||||
requires_robes = 1
|
||||
cooldown_staff = 1
|
||||
restricted_area_check = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
if (spell_invisibility(holder.owner, 1, 0, 1, 1) != 1) // Dry run. Can we phaseshift?
|
||||
return 1
|
||||
|
||||
holder.owner.say("PHEE CABUE")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/MistFormLoud.ogg", 50, 0, -1)
|
||||
var/SPtime = 35
|
||||
if(holder.owner.wizard_spellpower())
|
||||
SPtime = 50
|
||||
else
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell doesn't last as long without a staff to focus it!</span>")
|
||||
playsound(holder.owner.loc, "sound/effects/mag_phase.ogg", 25, 1, -1)
|
||||
spell_invisibility(holder.owner, SPtime, 0, 1)
|
||||
|
||||
// Merged some stuff from wizard and vampire phaseshift for easy of use (Convair880).
|
||||
/proc/spell_invisibility(var/mob/H, var/time, var/check_for_watchers = 0, var/stop_burning = 0, var/dry_run_only = 0)
|
||||
if (!H || !ismob(H))
|
||||
return
|
||||
if (!isturf(H.loc))
|
||||
H.show_text("You can't seem to turn incorporeal here.", "red")
|
||||
return
|
||||
if (H.stat || H.paralysis > 0)
|
||||
H.show_text("You can't turn incorporeal when you are incapacitated.", "red")
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(H)
|
||||
if (T && isrestrictedz(T.z))
|
||||
H.show_text("You can't seem to turn incorporeal here.", "red")
|
||||
return
|
||||
|
||||
if (check_for_watchers == 1)
|
||||
if (H.client)
|
||||
for (var/mob/living/L in view(H.client.view, H))
|
||||
if (L.stat == 0 && L.sight_check(1) && L.ckey != H.ckey)
|
||||
H.show_text("You can only use that when nobody can see you!", "red")
|
||||
return
|
||||
|
||||
if (dry_run_only)
|
||||
return 1 // Return 1 if we got this far in the test run.
|
||||
|
||||
if (stop_burning == 1)
|
||||
var/mob/living/carbon/human/HH = H
|
||||
if (istype(HH) && HH.burning)
|
||||
boutput(HH, "<span style=\"color:blue\">The flames sputter out as you phase shift.</span>")
|
||||
HH.set_burning(0)
|
||||
|
||||
spawn(0)
|
||||
var/mobloc = get_turf(H.loc)
|
||||
var/obj/dummy/spell_invis/holder = new /obj/dummy/spell_invis( mobloc )
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( mobloc )
|
||||
animation.name = "water"
|
||||
animation.density = 0
|
||||
animation.anchored = 1
|
||||
animation.icon = 'icons/mob/mob.dmi'
|
||||
animation.icon_state = "liquify"
|
||||
animation.layer = EFFECTS_LAYER_BASE
|
||||
animation.master = holder
|
||||
flick("liquify",animation)
|
||||
H.set_loc(holder)
|
||||
var/datum/effects/system/steam_spread/steam = unpool(/datum/effects/system/steam_spread)
|
||||
steam.set_up(10, 0, mobloc)
|
||||
steam.start()
|
||||
sleep(time)
|
||||
mobloc = get_turf(H.loc)
|
||||
animation.set_loc(mobloc)
|
||||
steam.location = mobloc
|
||||
steam.start()
|
||||
H.canmove = 0
|
||||
sleep(20)
|
||||
flick("reappear",animation)
|
||||
sleep(5)
|
||||
H.set_loc(mobloc)
|
||||
H.canmove = 1
|
||||
qdel(animation)
|
||||
for (var/obj/junk_to_dump in holder.contents)
|
||||
junk_to_dump.set_loc(mobloc)
|
||||
|
||||
qdel(holder)
|
||||
|
||||
/obj/dummy/spell_invis
|
||||
name = "water"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "nothing"
|
||||
invisibility = 101
|
||||
var/canmove = 1
|
||||
density = 0
|
||||
anchored = 1
|
||||
|
||||
/obj/dummy/spell_invis/relaymove(var/mob/user, direction)
|
||||
if (!src.canmove) return
|
||||
switch(direction)
|
||||
if(NORTH)
|
||||
src.y++
|
||||
if(SOUTH)
|
||||
src.y--
|
||||
if(EAST)
|
||||
src.x++
|
||||
if(WEST)
|
||||
src.x--
|
||||
if(NORTHEAST)
|
||||
src.y++
|
||||
src.x++
|
||||
if(NORTHWEST)
|
||||
src.y++
|
||||
src.x--
|
||||
if(SOUTHEAST)
|
||||
src.y--
|
||||
src.x++
|
||||
if(SOUTHWEST)
|
||||
src.y--
|
||||
src.x--
|
||||
src.canmove = 0
|
||||
spawn(2) src.canmove = 1
|
||||
|
||||
/obj/dummy/spell_invis/ex_act(blah)
|
||||
return
|
||||
|
||||
/obj/dummy/spell_invis/bullet_act(blah,blah)
|
||||
return
|
||||
@@ -0,0 +1,32 @@
|
||||
/datum/targetable/spell/rathens
|
||||
name = "Rathen's Secret"
|
||||
desc = "Summons a powerful shockwave around you that tears the arses and limbs off of enemies."
|
||||
icon_state = "arsenath"
|
||||
targeted = 0
|
||||
cooldown = 500
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.say("ARSE NATH!")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/RathensSecretLoud.ogg", 50, 0, -1)
|
||||
|
||||
playsound(holder.owner, "sound/misc/superfart.ogg", 25, 1)
|
||||
|
||||
for (var/mob/*living/carbon/human*//H in oview(holder.owner))
|
||||
if (H.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(usr, "<span style=\"color:red\">[H]'s butt has divine protection from magic.</span>")
|
||||
H.visible_message("<span style=\"color:red\">The spell fails to work on [H]!</span>")
|
||||
continue
|
||||
if (iswizard(H) && H.wizard_spellpower())
|
||||
H.visible_message("<span style=\"color:red\">[H] magically farts the spell away!</span>")
|
||||
playsound(H, "sound/vox/Poo.ogg", 25, 1)
|
||||
continue
|
||||
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
|
||||
smoke.set_up(5, 0, H:loc)
|
||||
smoke.attach(H)
|
||||
smoke.start()
|
||||
ass_explosion(H, 1, 7)
|
||||
// See bigfart.dm for the ass_explosion() proc. The third value represents the probability of limb loss in percent.
|
||||
@@ -0,0 +1,65 @@
|
||||
/datum/targetable/spell/shock
|
||||
name = "Shocking Touch"
|
||||
desc = "Shocks the victim with electrical power, which can arc to nearby people and stun them. Takes a few seconds to cast."
|
||||
icon_state = "grasp"
|
||||
targeted = 1
|
||||
max_range = 2
|
||||
cooldown = 800
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
sticky = 1
|
||||
var/wattage = 100000
|
||||
var/burn_damage = 100
|
||||
var/target_damage_modifier = 1.95
|
||||
var/arc_range = 3
|
||||
|
||||
cast(mob/target)
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.visible_message("<span style=\"color:red\"><b>[holder.owner] begins to cast a spell on [target]!</b></span>")
|
||||
playsound(holder.owner.loc, "sound/effects/elec_bzzz.ogg", 25, 1, -1)
|
||||
if (do_mob(holder.owner, target, 10))
|
||||
holder.owner.say("EI NATH")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/ShockingGraspLoud.ogg", 50, 0, -1)
|
||||
playsound(holder.owner.loc, "sound/effects/elec_bigzap.ogg", 25, 1, -1)
|
||||
|
||||
if (ishuman(target))
|
||||
if (target.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(holder.owner, "<span style=\"color:red\">[target] has divine protection from magic.</span>")
|
||||
target.visible_message("<span style=\"color:red\">The electric charge courses through [target] harmlessly!</span>")
|
||||
return
|
||||
else if (iswizard(target) && target.wizard_spellpower())
|
||||
target.visible_message("<span style=\"color:red\">The electric charge somehow completely misses [target]!</span>")
|
||||
return
|
||||
|
||||
if (holder.owner.wizard_spellpower())
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(4, 1, target)
|
||||
s.start()
|
||||
//target.elecgib()
|
||||
arcFlash(holder.owner, target, 0) // we just want the effect, the damage is taken care of below
|
||||
target.TakeDamage("chest", 0, burn_damage / target_damage_modifier, 0, DAMAGE_BURN)
|
||||
var/count = 0
|
||||
for (var/mob/living/L in oview(src.arc_range, target))
|
||||
if (iswizard(L))
|
||||
continue
|
||||
count++
|
||||
for (var/mob/living/L in oview(src.arc_range, target))
|
||||
if (iswizard(L))
|
||||
continue
|
||||
arcFlash(target, L, max(src.wattage / count, 1)) // adds some randomness to the damage
|
||||
target.TakeDamage("chest", 0, burn_damage / count, 0, DAMAGE_BURN)
|
||||
else
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(4, 1, target)
|
||||
s.start()
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell is weak without a staff to focus it!</span>")
|
||||
target.visible_message("<span style=\"color:red\">[target] is severely burned by an electrical charge!</span>")
|
||||
target.lastattacker = holder.owner
|
||||
target.lastattackertime = world.time
|
||||
target.TakeDamage("chest", 0, 40, 0, DAMAGE_BURN)
|
||||
target.stunned += 6
|
||||
target.weakened += 6
|
||||
target.stuttering += 10
|
||||
else
|
||||
return 1 // no cooldown if it fails
|
||||
@@ -0,0 +1,69 @@
|
||||
/datum/targetable/spell/shockwave
|
||||
name = "Shockwave"
|
||||
desc = "Violently throws nearby targets away from the caster."
|
||||
icon_state = "shockwave"
|
||||
targeted = 0
|
||||
cooldown = 400
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
|
||||
cast()
|
||||
if(!holder)
|
||||
return
|
||||
holder.owner.say("ERATH QUUK")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/EarthquakeLoud.ogg", 50, 0, -1)
|
||||
|
||||
playsound(holder.owner.loc, "sound/effects/exlow.ogg", 25, 1, -1)
|
||||
|
||||
new/obj/effects/shockwave(holder.owner.loc)
|
||||
|
||||
var/list/range1 = orange(1, holder.owner.loc)
|
||||
var/list/range2 = orange(2, holder.owner.loc)
|
||||
var/list/range3 = orange(3, holder.owner.loc)
|
||||
|
||||
var/list/affected = list()
|
||||
get_edge_target_turf(src, holder.owner.dir)
|
||||
for(var/atom/A in range1)
|
||||
if(affected.Find(A)) continue
|
||||
affected += A
|
||||
//animate_shockwave(A)
|
||||
if(hasvar(A, "weakened")) A:weakened += 3
|
||||
if(istype(A, /atom/movable))
|
||||
if(!isturf(A) && hasvar(A, "anchored") && !A:anchored)
|
||||
spawn(0) A:throw_at(get_edge_cheap(A, get_dir(holder.owner, A)), 30, 1)
|
||||
sleep(3)
|
||||
for(var/atom/A in range1 ^ range2)
|
||||
if(affected.Find(A)) continue
|
||||
affected += A
|
||||
//animate_shockwave(A)
|
||||
if(hasvar(A, "weakened")) A:weakened += 3
|
||||
if(istype(A, /atom/movable))
|
||||
if(!isturf(A) && hasvar(A, "anchored") && !A:anchored)
|
||||
spawn(0) A:throw_at(get_edge_cheap(A, get_dir(holder.owner, A)), 30, 1)
|
||||
sleep(3)
|
||||
for(var/atom/A in range2 ^ range3)
|
||||
if(affected.Find(A)) continue
|
||||
affected += A
|
||||
//animate_shockwave(A)
|
||||
if(hasvar(A, "weakened")) A:weakened += 3
|
||||
if(istype(A, /atom/movable))
|
||||
if(!isturf(A) && hasvar(A, "anchored") && !A:anchored)
|
||||
spawn(0) A:throw_at(get_edge_cheap(A, get_dir(holder.owner, A)), 30, 1)
|
||||
|
||||
/obj/effects/shockwave
|
||||
name = "shockwave"
|
||||
desc = ""
|
||||
anchored = 1
|
||||
layer = EFFECTS_LAYER_1
|
||||
density = 0
|
||||
opacity = 0
|
||||
icon = 'icons/effects/224x224.dmi'
|
||||
icon_state = "shockwave"
|
||||
pixel_y = -96
|
||||
pixel_x = -96
|
||||
|
||||
New()
|
||||
src.Scale(0,0)
|
||||
animate(src, matrix(1.4, MATRIX_SCALE), time = 6, color = "#ffdddd", easing = LINEAR_EASING)
|
||||
animate(time = 2, alpha = 0)
|
||||
spawn(8) qdel(src)
|
||||
@@ -0,0 +1,85 @@
|
||||
// Simple buff for the staff. Maybe it's less of a wasted spell slot now (Convair880).
|
||||
/datum/targetable/spell/summon_staff
|
||||
name = "Summon Staff of Cthulhu"
|
||||
desc = "Returns the staff to your active hand."
|
||||
icon_state = "staff"
|
||||
targeted = 0
|
||||
cooldown = 600
|
||||
requires_robes = 1
|
||||
|
||||
cast(mob/target)
|
||||
if (!holder)
|
||||
return 1
|
||||
|
||||
var/mob/living/M = holder.owner
|
||||
|
||||
if (!M)
|
||||
return 1
|
||||
|
||||
// Ability holder only checks for M.stat and wizard power, we need more than that here.
|
||||
if (M.stunned > 0 || M.weakened > 0 || M.paralysis > 0 || M.stat != 0 || M.restrained())
|
||||
boutput(M, __red("Not when you're incapacitated or restrained."))
|
||||
return 1
|
||||
|
||||
M.say("KOMH HEIRE")
|
||||
//playsound(M.loc, "sound/voice/wizard/[not_done_yet].ogg", 50, 0, -1)
|
||||
|
||||
var/list/staves = list()
|
||||
var/we_hold_it = 0
|
||||
for (var/obj/item/staff/cthulhu/S in world)
|
||||
if (M.mind && M.mind.key == S.wizard_key)
|
||||
if (S == M.find_in_hand(S))
|
||||
we_hold_it = 1
|
||||
continue
|
||||
if (!(S in staves))
|
||||
staves["[S.name] #[staves.len + 1] [ismob(S.loc) ? "carried by [S.loc.name]" : "at [get_area(S)]"]"] += S
|
||||
|
||||
switch (staves.len)
|
||||
if (-INFINITY to 0)
|
||||
if (we_hold_it != 0)
|
||||
boutput(M, __red("You're already holding your staff."))
|
||||
return 1 // No cooldown.
|
||||
else
|
||||
boutput(M, __red("You were unable to summon your staff."))
|
||||
return 0
|
||||
|
||||
if (1)
|
||||
var/obj/item/staff/cthulhu/S2
|
||||
for (var/C in staves)
|
||||
S2 = staves[C]
|
||||
break
|
||||
|
||||
if (!S2 || !istype(S2))
|
||||
boutput(M, __red("You were unable to summon your staff."))
|
||||
return 0
|
||||
|
||||
S2.send_staff_to_target_mob(M)
|
||||
|
||||
// There could be multiple, I suppose.
|
||||
if (2 to INFINITY)
|
||||
var/t1 = input("Please select a staff to summon", "Target Selection", null, null) as null|anything in staves
|
||||
if (!t1)
|
||||
return 1
|
||||
|
||||
var/obj/item/staff/cthulhu/S3 = staves[t1]
|
||||
|
||||
if (!M || !ismob(M))
|
||||
return 0
|
||||
if (!S3 || !istype(S3))
|
||||
boutput(M, __red("You were unable to summon your staff."))
|
||||
return 0
|
||||
if (!isliving(M) || !M.mind || !iswizard(M))
|
||||
boutput(M, __red("You seem to have lost all magical abilities."))
|
||||
return 0
|
||||
if (M.wizard_castcheck() == 0)
|
||||
return 0 // Has own user feedback.
|
||||
if (M.stunned > 0 || M.weakened > 0 || M.paralysis > 0 || M.stat != 0 || M.restrained())
|
||||
boutput(M, __red("Not when you're incapacitated or restrained."))
|
||||
return 0
|
||||
if (M.mind.key != S3.wizard_key)
|
||||
boutput(M, __red("You were unable to summon your staff."))
|
||||
return 0
|
||||
|
||||
S3.send_staff_to_target_mob(M)
|
||||
|
||||
return 0
|
||||
@@ -0,0 +1,153 @@
|
||||
/datum/targetable/spell/teleport
|
||||
name = "Teleport"
|
||||
desc = "Teleports you to an area of your choice after a short delay."
|
||||
icon_state = "phaseshift"
|
||||
targeted = 0
|
||||
cooldown = 450
|
||||
requires_robes = 1
|
||||
cooldown_staff = 1
|
||||
restricted_area_check = 1
|
||||
|
||||
cast()
|
||||
if (!holder)
|
||||
return 1
|
||||
|
||||
if (holder.owner && ismob(holder.owner) && holder.owner.teleportscroll(0, 3) == 1)
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
// These two procs were so similar that I combined them (Convair880).
|
||||
/mob/proc/teleportscroll(var/effect = 0, var/perform_check = 0, var/obj/item_to_check = null)
|
||||
if (src.paralysis > 0 || src.stat != 0)
|
||||
boutput(src, "<span style=\"color:red\">Not when you're incapacitated.</span>")
|
||||
return 0
|
||||
|
||||
if (!isturf(src.loc)) // Teleport doesn't go along well with doppelgaenger or phaseshift.
|
||||
boutput(src, "<span style=\"color:red\">You can't seem to teleport from here.</span>")
|
||||
return 0
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if (!T || !isturf(T))
|
||||
boutput(src, "<span style=\"color:red\">You can't seem to teleport from here.</span>")
|
||||
return 0
|
||||
if (isrestrictedz(T.z))
|
||||
boutput(src, "<span style=\"color:red\">You can't seem to teleport from here.</span>")
|
||||
return 0
|
||||
|
||||
var/A
|
||||
A = input("Area to jump to", "Teleportation", A) in teleareas
|
||||
var/area/thearea = teleareas[A]
|
||||
|
||||
if (!thearea || !istype(thearea))
|
||||
src.show_text("Invalid selection.", "red")
|
||||
return 0
|
||||
|
||||
// You can keep the selection window open, so we have to do the checks again (individual item/spell procs handle the first batch).
|
||||
switch (perform_check)
|
||||
if (1)
|
||||
var/obj/item/teleportation_scroll/scroll_check = item_to_check
|
||||
if (!scroll_check || !istype(scroll_check))
|
||||
src.show_text("The scroll appears to have been destroyed.", "red")
|
||||
return 0
|
||||
if (!iswizard(src))
|
||||
boutput(src, "<span style=\"color:red\">The scroll is illegible!</span>")
|
||||
return 0
|
||||
if (scroll_check.uses < 1)
|
||||
src.show_text("The scroll is depleted!", "src")
|
||||
return 0
|
||||
if (scroll_check.loc != src && scroll_check.loc != src.back) // Pocket or backpack.
|
||||
src.show_text("You reach for the scroll, but it's just too far away.", "red")
|
||||
return 0
|
||||
|
||||
if (2)
|
||||
var/obj/machinery/computer/pod/comp_check = item_to_check
|
||||
if (!comp_check || !istype(comp_check))
|
||||
src.show_text("The computer appears to have been destroyed.", "red")
|
||||
return 0
|
||||
if (comp_check.stat & (NOPOWER|BROKEN))
|
||||
src.show_text("[comp_check] is out of order.", "red")
|
||||
return 0
|
||||
if (get_dist(src, comp_check) > 1)
|
||||
src.show_text("[comp_check] is too far away.", "red")
|
||||
return 0
|
||||
|
||||
if (3)
|
||||
if (!iswizard(src))
|
||||
boutput(src, "<span style=\"color:red\">You seem to have lost all magical abilities.</span>")
|
||||
return 0
|
||||
if (src.wizard_castcheck() == 0)
|
||||
return 0 // Has own user feedback.
|
||||
|
||||
if (src.paralysis > 0 || src.stat != 0)
|
||||
boutput(src, "<span style=\"color:red\">Not when you're incapacitated.</span>")
|
||||
return 0
|
||||
|
||||
if (!isturf(src.loc))
|
||||
boutput(src, "<span style=\"color:red\">You can't seem to teleport from here.</span>")
|
||||
return 0
|
||||
|
||||
var/turf/T2 = get_turf(src)
|
||||
if (!T2 || !isturf(T2))
|
||||
boutput(src, "<span style=\"color:red\">You can't seem to teleport from here.</span>")
|
||||
return 0
|
||||
if (isrestrictedz(T2.z))
|
||||
boutput(src, "<span style=\"color:red\">You can't seem to teleport from here.</span>")
|
||||
return 0
|
||||
|
||||
switch (perform_check)
|
||||
if (1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] magically disappears!</b></span>")
|
||||
|
||||
if (2)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src]</b> presses a button and teleports away.</span>")
|
||||
|
||||
if (3) // Spell-specific stuff.
|
||||
src.say("SCYAR NILA [uppertext(A)]")
|
||||
playsound(src.loc, "sound/voice/wizard/TeleportLoud.ogg", 50, 0, -1)
|
||||
src.visible_message("<span style=\"color:red\"><b>[src] begins to fade away!</b></span>")
|
||||
animate_teleport_wiz(src)
|
||||
sleep(40) // Animation.
|
||||
|
||||
var/mob/living/carbon/human/H = src
|
||||
if (istype(H) && H.burning)
|
||||
boutput(H, "<span style=\"color:blue\">The flames sputter out as you phase shift.</span>")
|
||||
H.set_burning(0)
|
||||
|
||||
playsound(src.loc, "sound/effects/mag_teleport.ogg", 25, 1, -1)
|
||||
|
||||
var/list/L = list()
|
||||
for (var/turf/T3 in get_area_turfs(thearea.type))
|
||||
if (!T3.density)
|
||||
var/clear = 1
|
||||
for (var/obj/O in T3)
|
||||
if (O.density)
|
||||
clear = 0
|
||||
break
|
||||
if (clear)
|
||||
L += T3
|
||||
|
||||
if (effect)
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(5, 1, src.loc)
|
||||
|
||||
if (perform_check == 3)
|
||||
src.set_loc(pick(L))
|
||||
s.start() // Effect second because we had sound effects etc at the old loc.
|
||||
else
|
||||
s.start()
|
||||
src.set_loc(pick(L))
|
||||
|
||||
else
|
||||
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
|
||||
smoke.set_up(5, 0, src.loc)
|
||||
smoke.attach(src)
|
||||
|
||||
if (perform_check == 3)
|
||||
src.set_loc(pick(L))
|
||||
smoke.start()
|
||||
else
|
||||
smoke.start()
|
||||
src.set_loc(pick(L))
|
||||
|
||||
return 1
|
||||
@@ -0,0 +1,46 @@
|
||||
/datum/targetable/spell/warp
|
||||
name = "Warp"
|
||||
desc = "Teleports a foe away."
|
||||
icon_state = "warp"
|
||||
targeted = 1
|
||||
cooldown = 100
|
||||
requires_robes = 1
|
||||
offensive = 1
|
||||
restricted_area_check = 1
|
||||
sticky = 1
|
||||
|
||||
cast(mob/target)
|
||||
if(!holder)
|
||||
return
|
||||
|
||||
holder.owner.say("GHEIT AUT")
|
||||
playsound(holder.owner.loc, "sound/voice/wizard/WarpLoud.ogg", 50, 0, -1)
|
||||
|
||||
if (target.bioHolder.HasEffect("training_chaplain"))
|
||||
boutput(holder.owner, "<span style=\"color:red\">[target] has divine protection from magic.</span>")
|
||||
playsound(target.loc, "sound/effects/mag_warp.ogg", 25, 1, -1)
|
||||
target.visible_message("<span style=\"color:red\">The spell fails to work on [target]!</span>")
|
||||
return
|
||||
|
||||
if (iswizard(target) && target.wizard_spellpower())
|
||||
target.visible_message("<span style=\"color:red\">The spell fails to work on [target]!</span>")
|
||||
playsound(target.loc, "sound/effects/mag_warp.ogg", 25, 1, -1)
|
||||
return
|
||||
|
||||
var/telerange = 10
|
||||
if (holder.owner.wizard_spellpower())
|
||||
telerange = 25
|
||||
else
|
||||
boutput(holder.owner, "<span style=\"color:red\">Your spell is weak without a staff to focus it!</span>")
|
||||
var/datum/effects/system/spark_spread/s = unpool(/datum/effects/system/spark_spread)
|
||||
s.set_up(4, 1, target)
|
||||
s.start()
|
||||
var/list/randomturfs = new/list()
|
||||
for(var/turf/T in orange(target, telerange))
|
||||
if(istype(T, /turf/space) || T.density) continue
|
||||
randomturfs.Add(T)
|
||||
boutput(target, "<span style=\"color:blue\">You are caught in a magical warp field!</span>")
|
||||
animate_blink(target)
|
||||
target.visible_message("<span style=\"color:red\">[target] is warped away!</span>")
|
||||
playsound(target.loc, "sound/effects/mag_warp.ogg", 25, 1, -1)
|
||||
target.set_loc(pick(randomturfs))
|
||||
Reference in New Issue
Block a user