mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-01-26 17:03:25 +00:00
Object spell system v1.1
Completely revamped the classes, it's even more streamlined now. Got a few bugs and tweaks (namely, blind doesn't work, fireball got buffed up as compensation for not dealing additional damage to the target), but it's okay, since nobody uses those anyway. Fixed the bug with emagged borg laws. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1465 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
@@ -1,19 +1,32 @@
|
||||
var/list/spells = list(/obj/spell/blind,/obj/spell/blink,/obj/spell/conjure,/obj/spell/disable_tech,/obj/spell/disintegrate,/obj/spell/ethereal_jaunt,/obj/spell/fireball,/obj/spell/forcewall,/obj/spell/knock,/obj/spell/magic_missile,/obj/spell/mind_transfer,/obj/spell/mutate,/obj/spell/smoke,/obj/spell/teleport) //needed for the badmin verb for now
|
||||
var/list/spells = typesof(/obj/spell) //needed for the badmin verb for now
|
||||
|
||||
/obj/spell
|
||||
name = "Spell"
|
||||
desc = "A wizard spell"
|
||||
density = 0
|
||||
opacity = 0
|
||||
|
||||
var/school = "evocation" //not relevant at now, but may be important later if there are changes to how spells work. the ones I used for now will probably be changed... maybe spell presets? lacking flexibility but with some other benefit?
|
||||
var/charge_type = "recharge" //can be recharge or charges, see charge_max and charge_counter descriptions
|
||||
var/charge_max = 100 //recharge time in deciseconds if charge_type = "recharge" or starting charges if charge_type = "charges"
|
||||
var/charge_counter = 0 //can only cast spells if it equals recharge, ++ each decisecond if charge_type = "recharge" or -- each cast if charge_type = "charges"
|
||||
var/clothes_req = 1 //see if it requires clothes
|
||||
var/stat_allowed = 0 //see if it requires being conscious
|
||||
var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells
|
||||
var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell
|
||||
var/invocation_type = "none" //can be none, whisper and shout
|
||||
var/range = 7 //the range of the spell
|
||||
var/message = "derp herp" //whatever it says to the guy affected by it. not always needed
|
||||
var/range = 7 //the range of the spell; outer radius for aoe spells
|
||||
var/message = "" //whatever it says to the guy affected by it
|
||||
var/selection_type = "view" //can be "range" or "view"
|
||||
|
||||
var/overlay = 0
|
||||
var/overlay_icon = 'wizard.dmi'
|
||||
var/overlay_icon_state = "spell"
|
||||
var/overlay_lifespan = 0
|
||||
|
||||
var/sparks_spread = 0
|
||||
var/sparks_amt = 0 //cropped at 10
|
||||
var/smoke_spread = 0 //1 - harmless, 2 - harmful
|
||||
var/smoke_amt = 0 //cropped at 10
|
||||
|
||||
/obj/spell/proc/cast_check() //checks if the spell can be cast based on its settings
|
||||
|
||||
@@ -23,7 +36,7 @@ var/list/spells = list(/obj/spell/blind,/obj/spell/blink,/obj/spell/conjure,/obj
|
||||
|
||||
switch(charge_type)
|
||||
if("recharge")
|
||||
if(charge_counter != charge_max)
|
||||
if(charge_counter < charge_max)
|
||||
usr << "[name] is still recharging."
|
||||
return 0
|
||||
if("charges")
|
||||
@@ -46,6 +59,12 @@ var/list/spells = list(/obj/spell/blind,/obj/spell/blink,/obj/spell/conjure,/obj
|
||||
usr << "I don't feel strong enough without my hat."
|
||||
return 0
|
||||
|
||||
switch(charge_type)
|
||||
if("recharge")
|
||||
charge_counter = 0 //doesn't start recharging until the targets selecting ends
|
||||
if("charges")
|
||||
charge_counter-- //returns the charge if the targets selecting fails
|
||||
|
||||
return 1
|
||||
|
||||
/obj/spell/proc/invocation() //spelling the spell out and setting it on recharge/reducing charges amount
|
||||
@@ -60,18 +79,181 @@ var/list/spells = list(/obj/spell/blind,/obj/spell/blink,/obj/spell/conjure,/obj
|
||||
if("whisper")
|
||||
usr.whisper(invocation)
|
||||
|
||||
switch(charge_type)
|
||||
if("recharge")
|
||||
charge_counter = 0
|
||||
|
||||
spawn(0)
|
||||
while(charge_counter < charge_max)
|
||||
sleep(1)
|
||||
charge_counter++
|
||||
if("charges")
|
||||
charge_counter--
|
||||
|
||||
/obj/spell/New()
|
||||
..()
|
||||
|
||||
charge_counter = charge_max
|
||||
charge_counter = charge_max
|
||||
|
||||
/obj/spell/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
choose_targets()
|
||||
|
||||
/obj/spell/proc/choose_targets() //depends on subtype - /targeted or /aoe_turf
|
||||
return
|
||||
|
||||
/obj/spell/proc/start_recharge()
|
||||
while(charge_counter < charge_max)
|
||||
sleep(1)
|
||||
charge_counter++
|
||||
|
||||
/obj/spell/proc/perform(list/targets)
|
||||
before_cast(targets)
|
||||
invocation()
|
||||
spawn(0)
|
||||
if(charge_type == "recharge")
|
||||
start_recharge()
|
||||
cast(targets)
|
||||
after_cast(targets)
|
||||
|
||||
/obj/spell/proc/before_cast(list/targets)
|
||||
if(overlay)
|
||||
for(var/atom/target in targets)
|
||||
var/location
|
||||
if(istype(target,/mob))
|
||||
location = target.loc
|
||||
else if(istype(target,/turf))
|
||||
location = target
|
||||
var/obj/overlay/spell = new /obj/overlay(location)
|
||||
spell.icon = overlay_icon
|
||||
spell.icon_state = overlay_icon_state
|
||||
spell.anchored = 1
|
||||
spell.density = 0
|
||||
spawn(overlay_lifespan)
|
||||
del(spell)
|
||||
|
||||
/obj/spell/proc/after_cast(list/targets)
|
||||
for(var/atom/target in targets)
|
||||
var/location
|
||||
if(istype(target,/mob))
|
||||
location = target.loc
|
||||
else if(istype(target,/turf))
|
||||
location = target
|
||||
if(istype(target,/mob) && message)
|
||||
target << text("[message]")
|
||||
if(sparks_spread)
|
||||
var/datum/effects/system/spark_spread/sparks = new /datum/effects/system/spark_spread()
|
||||
sparks.set_up(sparks_amt, 0, location) //no idea what the 0 is
|
||||
sparks.start()
|
||||
if(smoke_spread)
|
||||
if(smoke_spread == 1)
|
||||
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
|
||||
smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is
|
||||
smoke.start()
|
||||
else if(smoke_spread == 2)
|
||||
var/datum/effects/system/bad_smoke_spread/smoke = new /datum/effects/system/bad_smoke_spread()
|
||||
smoke.set_up(smoke_amt, 0, location) //no idea what the 0 is
|
||||
smoke.start()
|
||||
|
||||
/obj/spell/proc/cast(list/targets)
|
||||
return
|
||||
|
||||
/obj/spell/proc/revert_cast() //resets recharge or readds a charge
|
||||
switch(charge_type)
|
||||
if("recharge")
|
||||
charge_counter = charge_max
|
||||
if("charges")
|
||||
charge_counter++
|
||||
|
||||
return
|
||||
|
||||
|
||||
/obj/spell/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob
|
||||
var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range
|
||||
var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast
|
||||
var/include_usr = 0 //if it includes usr in the target list
|
||||
|
||||
/obj/spell/aoe_turf //affects all turfs in view or range (depends)
|
||||
var/inner_radius = -1 //for all your ring spell needs
|
||||
|
||||
/obj/spell/targeted/choose_targets()
|
||||
var/list/targets = list()
|
||||
|
||||
switch(selection_type)
|
||||
if("range")
|
||||
switch(max_targets)
|
||||
if(0)
|
||||
for(var/mob/target in range(usr,range))
|
||||
targets += target
|
||||
if(1)
|
||||
if(range < 0)
|
||||
targets += usr
|
||||
else
|
||||
var/possible_targets = range(usr,range)
|
||||
if(!include_usr && usr in possible_targets)
|
||||
possible_targets -= usr
|
||||
targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets
|
||||
else
|
||||
var/list/possible_targets = list()
|
||||
for(var/mob/target in range(usr,range))
|
||||
possible_targets += target
|
||||
for(var/i=1,i<=max_targets,i++)
|
||||
if(!possible_targets.len)
|
||||
break
|
||||
if(target_ignore_prev)
|
||||
var/target = pick(possible_targets)
|
||||
possible_targets -= target
|
||||
targets += target
|
||||
else
|
||||
targets += pick(possible_targets)
|
||||
if("view")
|
||||
switch(max_targets)
|
||||
if(0)
|
||||
for(var/mob/target in view(usr,range))
|
||||
targets += target
|
||||
if(1)
|
||||
if(range < 0)
|
||||
targets += usr
|
||||
else
|
||||
var/possible_targets = view(usr,range)
|
||||
if(!include_usr && usr in possible_targets)
|
||||
possible_targets -= usr
|
||||
targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets
|
||||
else
|
||||
var/list/possible_targets = list()
|
||||
for(var/mob/target in view(usr,range))
|
||||
possible_targets += target
|
||||
for(var/i=1,i<=max_targets,i++)
|
||||
if(!possible_targets.len)
|
||||
break
|
||||
if(target_ignore_prev)
|
||||
var/target = pick(possible_targets)
|
||||
possible_targets -= target
|
||||
targets += target
|
||||
else
|
||||
targets += pick(possible_targets)
|
||||
|
||||
if(!include_usr && (usr in targets))
|
||||
targets -= usr
|
||||
|
||||
if(!targets.len) //doesn't waste the spell
|
||||
revert_cast()
|
||||
return
|
||||
|
||||
perform(targets)
|
||||
|
||||
return
|
||||
|
||||
/obj/spell/aoe_turf/choose_targets()
|
||||
var/list/targets = list()
|
||||
|
||||
switch(selection_type)
|
||||
if("range")
|
||||
for(var/turf/target in range(usr,range))
|
||||
if(!(target in range(usr,inner_radius)))
|
||||
targets += target
|
||||
if("view")
|
||||
for(var/turf/target in view(usr,range))
|
||||
if(!(target in view(usr,inner_radius)))
|
||||
targets += target
|
||||
|
||||
if(!targets.len) //doesn't waste the spell
|
||||
revert_cast()
|
||||
return
|
||||
|
||||
perform(targets)
|
||||
|
||||
return
|
||||
63
code/datums/spells/area_teleport.dm
Normal file
63
code/datums/spells/area_teleport.dm
Normal file
@@ -0,0 +1,63 @@
|
||||
/obj/spell/targeted/area_teleport
|
||||
name = "Area teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
|
||||
var/randomise_selection = 0 //if it lets the usr choose the teleport loc or picks it from the list
|
||||
var/invocation_area = 1 //if the invocation appends the selected area
|
||||
|
||||
/obj/spell/targeted/area_teleport/perform(list/targets)
|
||||
var/thearea = before_cast(targets)
|
||||
if(!thearea)
|
||||
revert_cast()
|
||||
return
|
||||
invocation(thearea)
|
||||
spawn(0)
|
||||
if(charge_type == "recharge")
|
||||
start_recharge()
|
||||
cast(targets,thearea)
|
||||
after_cast(targets)
|
||||
|
||||
/obj/spell/targeted/area_teleport/before_cast(list/targets)
|
||||
var/A = null
|
||||
|
||||
if(!randomise_selection)
|
||||
A = input("Area to teleport to", "Teleport", A) in teleportlocs
|
||||
else
|
||||
A = pick(teleportlocs)
|
||||
|
||||
var/area/thearea = teleportlocs[A]
|
||||
|
||||
return thearea
|
||||
|
||||
/obj/spell/targeted/area_teleport/cast(list/targets,area/thearea)
|
||||
for(var/mob/target in targets)
|
||||
var/list/L = list()
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
if(!T.density)
|
||||
var/clear = 1
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
clear = 0
|
||||
break
|
||||
if(clear)
|
||||
L+=T
|
||||
|
||||
target.loc = pick(L)
|
||||
|
||||
return
|
||||
|
||||
/obj/spell/targeted/area_teleport/invocation(area/chosenarea = null)
|
||||
if(!invocation_area || !chosenarea)
|
||||
..()
|
||||
else
|
||||
switch(invocation_type)
|
||||
if("shout")
|
||||
usr.say("[invocation] [uppertext(chosenarea.name)]")
|
||||
if(usr.gender=="male")
|
||||
playsound(usr.loc, pick('vs_chant_conj_hm.wav','vs_chant_conj_lm.wav','vs_chant_ench_hm.wav','vs_chant_ench_lm.wav','vs_chant_evoc_hm.wav','vs_chant_evoc_lm.wav','vs_chant_illu_hm.wav','vs_chant_illu_lm.wav','vs_chant_necr_hm.wav','vs_chant_necr_lm.wav'), 100, 1)
|
||||
else
|
||||
playsound(usr.loc, pick('vs_chant_conj_hf.wav','vs_chant_conj_lf.wav','vs_chant_ench_hf.wav','vs_chant_ench_lf.wav','vs_chant_evoc_hf.wav','vs_chant_evoc_lf.wav','vs_chant_illu_hf.wav','vs_chant_illu_lf.wav','vs_chant_necr_hf.wav','vs_chant_necr_lf.wav'), 100, 1)
|
||||
if("whisper")
|
||||
usr.whisper("[invocation] [uppertext(chosenarea.name)]")
|
||||
|
||||
return
|
||||
@@ -1,53 +0,0 @@
|
||||
/obj/spell/blink
|
||||
name = "Blink"
|
||||
desc = "This spell randomly teleports you a short distance."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 20
|
||||
clothes_req = 1
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1 //can affect only the user by default, but with var editing can be a teleport other spell
|
||||
var/outer_teleport_radius = 6 //the radius of the area in which it picks turfs to teleport to
|
||||
var/inner_teleport_radius = 0 //so with var fuckery you can have it teleport in a ring, not in a circle
|
||||
var/smoke_spread = 1 //if set to 0, no smoke spreads when teleporting
|
||||
|
||||
/obj/spell/blink/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
var/mob/M
|
||||
|
||||
if(range>=0)
|
||||
M = input("Choose whom to blink", "ABRAKADABRA") as mob in view(usr,range)
|
||||
else
|
||||
M = usr
|
||||
|
||||
if(!M)
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
var/list/turfs = new/list()
|
||||
for(var/turf/T in orange(M,outer_teleport_radius))
|
||||
if(T in orange(M,inner_teleport_radius)) continue
|
||||
if(istype(T,/turf/space)) continue
|
||||
if(T.density) continue
|
||||
if(T.x>world.maxx-outer_teleport_radius || T.x<outer_teleport_radius) continue //putting them at the edge is dumb
|
||||
if(T.y>world.maxy-outer_teleport_radius || T.y<outer_teleport_radius) continue
|
||||
turfs += T
|
||||
if(!turfs.len)
|
||||
var/list/turfs_to_pick_from = list()
|
||||
for(var/turf/T in orange(M,outer_teleport_radius))
|
||||
if(!(T in orange(M,inner_teleport_radius)))
|
||||
turfs_to_pick_from += T
|
||||
turfs += pick(/turf in turfs_to_pick_from)
|
||||
if(smoke_spread)
|
||||
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
|
||||
smoke.set_up(10, 0, M.loc)
|
||||
smoke.start()
|
||||
var/turf/picked = pick(turfs)
|
||||
if(!isturf(picked)) return
|
||||
M.loc = picked
|
||||
@@ -1,3 +1,14 @@
|
||||
/obj/spell/aoe_turf/conjure
|
||||
name = "Conjure"
|
||||
desc = "This spell conjures objs of the specified types in range."
|
||||
|
||||
var/list/summon_type = list() //determines what exactly will be summoned
|
||||
var/summon_lifespan = 0 // 0=permanent, any other time in deciseconds
|
||||
var/summon_amt = 1 //amount of objects summoned
|
||||
var/summon_ignore_density = 0 //if set to 1, adds dense tiles to possible spawn places
|
||||
var/summon_ignore_prev_spawn_points = 0 //if set to 1, each new object is summoned on a new spawn point
|
||||
|
||||
/*
|
||||
/obj/spell/conjure
|
||||
name = "Summon Bigger Carp"
|
||||
desc = "This spell conjures an elite carp."
|
||||
@@ -13,31 +24,23 @@
|
||||
var/summon_amt = 1 //amount of objects summoned
|
||||
var/summon_ignore_density = 0 //if set to 1, adds dense tiles to possible spawn places
|
||||
var/summon_ignore_prev_spawn_points = 0 //if set to 1, each new object is summoned on a new spawn point
|
||||
*/
|
||||
/obj/spell/aoe_turf/conjure/cast(list/targets)
|
||||
|
||||
/obj/spell/conjure/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
var/list/possible_spawn_points = list()
|
||||
|
||||
for(var/turf/T in oview(usr,range))
|
||||
if(!T.density || summon_ignore_density)
|
||||
possible_spawn_points += T
|
||||
for(var/turf/T in targets)
|
||||
if(T.density && !summon_ignore_density)
|
||||
targets -= T
|
||||
|
||||
for(var/i=0,i<summon_amt,i++)
|
||||
if(!possible_spawn_points.len)
|
||||
if(!targets.len)
|
||||
break
|
||||
var/summoned_object_type = text2path(pick(summon_type))
|
||||
var/spawn_place = pick(possible_spawn_points)
|
||||
var/spawn_place = pick(targets)
|
||||
if(summon_ignore_prev_spawn_points)
|
||||
possible_spawn_points -= spawn_place
|
||||
targets -= spawn_place
|
||||
var/summoned_object = new summoned_object_type(spawn_place)
|
||||
if(summon_duration)
|
||||
spawn(summon_duration)
|
||||
if(summon_lifespan)
|
||||
spawn(summon_lifespan)
|
||||
if(summoned_object)
|
||||
del(summoned_object)
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/obj/spell/disable_tech
|
||||
name = "Disable Tech"
|
||||
desc = "This spell disables all weapons, cameras and most other technology in range."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "NEC CANTIO"
|
||||
invocation_type = "shout"
|
||||
var/emp_heavy_radius = 5
|
||||
var/emp_light_radius = 7
|
||||
|
||||
/obj/spell/disable_tech/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
empulse(usr.loc, src.emp_heavy_radius, src.emp_light_radius)
|
||||
return
|
||||
@@ -1,72 +0,0 @@
|
||||
/obj/spell/disintegrate
|
||||
name = "Disintegrate"
|
||||
desc = "This spell instantly kills somebody adjacent to you with the vilest of magick."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 600
|
||||
clothes_req = 1
|
||||
invocation = "EI NATH"
|
||||
invocation_type = "shout"
|
||||
range = 1
|
||||
var/sparks_spread = 1 //if set to 0, no sparks spread when disintegrating
|
||||
var/kill_type = "disintegrate" //"disintegrate" leaves a pile of ash and bones (remains), "gib" gibs, "kill" adds damage_amount of damage_type
|
||||
var/damage_amount = 2000 //only used if kill_type = "damage"
|
||||
var/damage_type = "brute" //can be "brute", "fire", "toxin" or "oxygen"
|
||||
|
||||
/obj/spell/disintegrate/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
var/mob/living/M = input("Choose whom to [kill_type]", "ABRAKADABRA") as mob in oview(usr,range)
|
||||
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
if(sparks_spread)
|
||||
var/datum/effects/system/spark_spread/s = new /datum/effects/system/spark_spread
|
||||
s.set_up(4, 1, M)
|
||||
s.start()
|
||||
|
||||
switch(kill_type)
|
||||
if("disintegrate")
|
||||
M.dust()
|
||||
if("gib")
|
||||
M.gib()
|
||||
if("kill")
|
||||
if (damage_amount>0)
|
||||
M.take_overall_damage(abs(damage_amount),abs(damage_amount))
|
||||
M.toxloss+=abs(damage_amount)
|
||||
M.oxyloss+=abs(damage_amount)
|
||||
else
|
||||
M.heal_overall_damage(abs(damage_amount),abs(damage_amount))
|
||||
M.toxloss+=abs(damage_amount)
|
||||
M.oxyloss+=abs(damage_amount)
|
||||
/*
|
||||
for(var/i=0,i<abs(damage_amount),i++)
|
||||
sleep(0) //to avoid troubles with instantly applying lots of damage, it seems to be buggy
|
||||
switch(damage_type)
|
||||
if("brute")
|
||||
if(damage_amount>0)
|
||||
M.bruteloss++
|
||||
else
|
||||
M.bruteloss--
|
||||
if("toxin")
|
||||
if(damage_amount>0)
|
||||
M.toxloss++
|
||||
else
|
||||
M.toxloss--
|
||||
if("oxygen")
|
||||
if(damage_amount>0)
|
||||
M.oxyloss++
|
||||
else
|
||||
M.oxyloss--
|
||||
if("fire")
|
||||
if(damage_amount>0)
|
||||
M.fireloss++
|
||||
else
|
||||
M.fireloss--
|
||||
*/
|
||||
13
code/datums/spells/emplosion.dm
Normal file
13
code/datums/spells/emplosion.dm
Normal file
@@ -0,0 +1,13 @@
|
||||
/obj/spell/targeted/emplosion
|
||||
name = "Emplosion"
|
||||
desc = "This spell emplodes an area."
|
||||
|
||||
var/emp_heavy = 2
|
||||
var/emp_light = 3
|
||||
|
||||
/obj/spell/targeted/emplosion/cast(list/targets)
|
||||
|
||||
for(var/mob/target in targets)
|
||||
empulse(target.loc, emp_heavy, emp_light)
|
||||
|
||||
return
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/spell/ethereal_jaunt
|
||||
/obj/spell/targeted/ethereal_jaunt
|
||||
name = "Ethereal Jaunt"
|
||||
desc = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls."
|
||||
|
||||
@@ -7,58 +7,44 @@
|
||||
clothes_req = 1
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1 //can affect only the user by default, but with var editing can be an invis other spell
|
||||
range = -1
|
||||
include_usr = 1
|
||||
|
||||
var/jaunt_duration = 50 //in deciseconds
|
||||
|
||||
/obj/spell/ethereal_jaunt/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
var/mob/M
|
||||
|
||||
if(range>=0)
|
||||
M = input("Choose whom to jaunt", "ABRAKADABRA") as mob in view(usr,range)
|
||||
else
|
||||
M = usr
|
||||
|
||||
if(!M)
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
spawn(0)
|
||||
var/mobloc = get_turf(M.loc)
|
||||
var/obj/dummy/spell_jaunt/holder = new /obj/dummy/spell_jaunt( mobloc )
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( mobloc )
|
||||
animation.name = "water"
|
||||
animation.density = 0
|
||||
animation.anchored = 1
|
||||
animation.icon = 'mob.dmi'
|
||||
animation.icon_state = "liquify"
|
||||
animation.layer = 5
|
||||
animation.master = holder
|
||||
flick("liquify",animation)
|
||||
M.loc = holder
|
||||
M.client.eye = holder
|
||||
var/datum/effects/system/steam_spread/steam = new /datum/effects/system/steam_spread()
|
||||
steam.set_up(10, 0, mobloc)
|
||||
steam.start()
|
||||
sleep(jaunt_duration)
|
||||
mobloc = get_turf(M.loc)
|
||||
animation.loc = mobloc
|
||||
steam.location = mobloc
|
||||
steam.start()
|
||||
M.canmove = 0
|
||||
sleep(20)
|
||||
flick("reappear",animation)
|
||||
sleep(5)
|
||||
M.loc = mobloc
|
||||
M.canmove = 1
|
||||
M.client.eye = M
|
||||
del(animation)
|
||||
del(holder)
|
||||
/obj/spell/targeted/ethereal_jaunt/cast(list/targets) //magnets, so mostly hardcoded
|
||||
for(var/mob/target in targets)
|
||||
spawn(0)
|
||||
var/mobloc = get_turf(target.loc)
|
||||
var/obj/dummy/spell_jaunt/holder = new /obj/dummy/spell_jaunt( mobloc )
|
||||
var/atom/movable/overlay/animation = new /atom/movable/overlay( mobloc )
|
||||
animation.name = "water"
|
||||
animation.density = 0
|
||||
animation.anchored = 1
|
||||
animation.icon = 'mob.dmi'
|
||||
animation.icon_state = "liquify"
|
||||
animation.layer = 5
|
||||
animation.master = holder
|
||||
flick("liquify",animation)
|
||||
target.loc = holder
|
||||
target.client.eye = holder
|
||||
var/datum/effects/system/steam_spread/steam = new /datum/effects/system/steam_spread()
|
||||
steam.set_up(10, 0, mobloc)
|
||||
steam.start()
|
||||
sleep(jaunt_duration)
|
||||
mobloc = get_turf(target.loc)
|
||||
animation.loc = mobloc
|
||||
steam.location = mobloc
|
||||
steam.start()
|
||||
target.canmove = 0
|
||||
sleep(20)
|
||||
flick("reappear",animation)
|
||||
sleep(5)
|
||||
target.loc = mobloc
|
||||
target.canmove = 1
|
||||
target.client.eye = target
|
||||
del(animation)
|
||||
del(holder)
|
||||
|
||||
/obj/dummy/spell_jaunt
|
||||
name = "water"
|
||||
|
||||
15
code/datums/spells/explosion.dm
Normal file
15
code/datums/spells/explosion.dm
Normal file
@@ -0,0 +1,15 @@
|
||||
/obj/spell/targeted/explosion
|
||||
name = "Explosion"
|
||||
desc = "This spell explodes an area."
|
||||
|
||||
var/ex_severe = 1
|
||||
var/ex_heavy = 2
|
||||
var/ex_light = 3
|
||||
var/ex_flash = 4
|
||||
|
||||
/obj/spell/targeted/explosion/cast(list/targets)
|
||||
|
||||
for(var/mob/target in targets)
|
||||
explosion(target.loc,ex_severe,ex_heavy,ex_light,ex_flash)
|
||||
|
||||
return
|
||||
@@ -1,48 +0,0 @@
|
||||
/obj/spell/fireball
|
||||
name = "Fireball"
|
||||
desc = "This spell fires a fireball at a target and does not require wizard garb."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 200
|
||||
clothes_req = 0
|
||||
invocation = "ONI SOMA"
|
||||
invocation_type = "shout"
|
||||
var/radius_devastation = -1
|
||||
var/radius_heavy = -1
|
||||
var/radius_light = 2
|
||||
var/radius_flash = 2
|
||||
var/bruteloss = 20 // apparently fireball deals damage in addition to the explosion
|
||||
var/fireloss = 25 // huh
|
||||
var/lifetime = 200 // in deciseconds
|
||||
|
||||
/obj/spell/fireball/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
var/mob/M = input("Choose whom to fireball", "ABRAKADABRA") as mob in oview(usr,range)
|
||||
|
||||
if(!M)
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
var/obj/overlay/A = new /obj/overlay( usr.loc )
|
||||
A.icon_state = "fireball"
|
||||
A.icon = 'wizard.dmi'
|
||||
A.name = "a fireball"
|
||||
A.anchored = 0
|
||||
A.density = 0
|
||||
var/i
|
||||
for(i=0, i<lifetime, i++)
|
||||
step_to(A,M,0)
|
||||
if(get_dist(A,M) <= 1)
|
||||
if(istype(M,/mob/living))
|
||||
M:take_organ_damage(bruteloss,fireloss)
|
||||
explosion(M.loc, radius_devastation, radius_heavy, radius_light, radius_flash)
|
||||
del(A)
|
||||
return
|
||||
sleep(1)
|
||||
del(A)
|
||||
return
|
||||
@@ -1,32 +0,0 @@
|
||||
/obj/spell/forcewall
|
||||
name = "Forcewall"
|
||||
desc = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
invocation = "TARCOL MINTI ZHERI"
|
||||
invocation_type = "whisper"
|
||||
range = 0 //default creates only a 1x1 forcewall in the user's tile
|
||||
var/wall_lifespan = 300 //in deciseconds
|
||||
var/wall_visibility = 1 //if 0, the created wall(s) is(are) invisible
|
||||
|
||||
/obj/spell/forcewall/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
var/list/forcefields = list()
|
||||
|
||||
for(var/turf/T in range(usr,range))
|
||||
forcefields += new /obj/forcefield(T)
|
||||
|
||||
spawn (wall_lifespan)
|
||||
for(var/obj/forcefield/F in forcefields)
|
||||
del(F)
|
||||
del(forcefields)
|
||||
|
||||
return
|
||||
34
code/datums/spells/genetic.dm
Normal file
34
code/datums/spells/genetic.dm
Normal file
@@ -0,0 +1,34 @@
|
||||
/obj/spell/targeted/genetic
|
||||
name = "Genetic"
|
||||
desc = "This spell inflicts a set of mutations and disabilities upon the target."
|
||||
|
||||
var/disabilities = 0 //bits
|
||||
var/mutations = 0 //bits
|
||||
var/duration = 100 //deciseconds
|
||||
/*
|
||||
Disabilities
|
||||
1st bit - ?
|
||||
2nd bit - ?
|
||||
3rd bit - ?
|
||||
4th bit - ?
|
||||
5th bit - ?
|
||||
6th bit - ?
|
||||
Mutations
|
||||
1st bit - portals
|
||||
2nd bit - cold resist
|
||||
3rd bit - xray
|
||||
4th bit - hulk
|
||||
5th bit - clown
|
||||
6th bit - fat
|
||||
*/
|
||||
|
||||
/obj/spell/targeted/genetic/cast(list/targets)
|
||||
|
||||
for(var/mob/target in targets)
|
||||
target.mutations |= mutations
|
||||
target.disabilities |= disabilities
|
||||
spawn(duration)
|
||||
target.mutations &= ~mutations
|
||||
target.disabilities &= ~disabilities
|
||||
|
||||
return
|
||||
44
code/datums/spells/inflict_handler.dm
Normal file
44
code/datums/spells/inflict_handler.dm
Normal file
@@ -0,0 +1,44 @@
|
||||
/obj/spell/targeted/inflict_handler
|
||||
name = "Inflict Handler"
|
||||
desc = "This spell destroys/damages/heals and/or weakens/stuns the target."
|
||||
|
||||
var/amt_weaken = 0
|
||||
var/amt_paralysis = 0 //stun
|
||||
|
||||
//set to negatives for healing
|
||||
var/amt_dam_fire = 0
|
||||
var/amt_dam_brute = 0
|
||||
var/amt_dam_oxy = 0
|
||||
var/amt_dam_tox = 0
|
||||
|
||||
var/destroys = "none" //can be "none", "gib" or "disintegrate"
|
||||
|
||||
/obj/spell/targeted/inflict_handler/cast(list/targets)
|
||||
|
||||
for(var/mob/living/target in targets)
|
||||
switch(destroys)
|
||||
if("gib")
|
||||
target.gib()
|
||||
if("disintegrate")
|
||||
target.dust()
|
||||
|
||||
if(!target)
|
||||
continue
|
||||
//damage
|
||||
if(amt_dam_brute > 0)
|
||||
if(amt_dam_fire > 0)
|
||||
target.take_overall_damage(amt_dam_brute,amt_dam_fire)
|
||||
else if (amt_dam_fire < 0)
|
||||
target.take_overall_damage(amt_dam_brute,0)
|
||||
target.heal_overall_damage(0,amt_dam_fire)
|
||||
else if(amt_dam_brute < 0)
|
||||
if(amt_dam_fire > 0)
|
||||
target.take_overall_damage(0,amt_dam_fire)
|
||||
target.heal_overall_damage(amt_dam_brute,0)
|
||||
else if (amt_dam_fire < 0)
|
||||
target.heal_overall_damage(amt_dam_brute,amt_dam_fire)
|
||||
target.toxloss += amt_dam_tox
|
||||
target.oxyloss += amt_dam_oxy
|
||||
//disabling
|
||||
target.weakened += amt_weaken
|
||||
target.paralysis += amt_paralysis
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/spell/knock
|
||||
/obj/spell/aoe_turf/knock
|
||||
name = "Knock"
|
||||
desc = "This spell opens nearby doors and does not require wizard garb."
|
||||
|
||||
@@ -9,16 +9,11 @@
|
||||
invocation_type = "whisper"
|
||||
range = 3
|
||||
|
||||
/obj/spell/knock/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
for(var/obj/machinery/door/G in oview(usr,range))
|
||||
spawn(1)
|
||||
G:locked = 0
|
||||
G.open()
|
||||
/obj/spell/aoe_turf/knock/cast(list/targets)
|
||||
for(var/turf/T in targets)
|
||||
for(var/obj/machinery/door/door in T.contents)
|
||||
spawn(1)
|
||||
if(istype(door,/obj/machinery/door/airlock))
|
||||
door:locked = 0
|
||||
door.open()
|
||||
return
|
||||
@@ -1,57 +0,0 @@
|
||||
/obj/spell/magic_missile
|
||||
name = "Magic Missile"
|
||||
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 100
|
||||
clothes_req = 1
|
||||
invocation = "FORTI GY AMA"
|
||||
invocation_type = "shout"
|
||||
range = 7
|
||||
var/max_targets = 0 //max targets for the spell. set to 0 for no limit
|
||||
var/missile_lifespan = 20 //in deciseconds * missile_step_delay
|
||||
var/missile_step_delay = 5 //lower = faster missile
|
||||
var/missile_weaken_amt = 5 //the amount by which the missile weakens the target it hits
|
||||
var/missile_damage = 10 //the amount of fireloss each missile deals
|
||||
|
||||
/obj/spell/magic_missile/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
var/targets = 0
|
||||
for (var/mob/living/M as mob in oview(usr,range))
|
||||
if(max_targets)
|
||||
if(targets >= max_targets)
|
||||
break
|
||||
spawn(0)
|
||||
var/obj/overlay/A = new /obj/overlay( usr.loc )
|
||||
A.icon_state = "magicm"
|
||||
A.icon = 'wizard.dmi'
|
||||
A.name = "a magic missile"
|
||||
A.anchored = 0
|
||||
A.density = 0
|
||||
A.layer = 4
|
||||
var/i
|
||||
for(i=0, i<missile_lifespan, i++)
|
||||
var/obj/overlay/B = new /obj/overlay( A.loc )
|
||||
B.icon_state = "magicmd"
|
||||
B.icon = 'wizard.dmi'
|
||||
B.name = "trail"
|
||||
B.anchored = 1
|
||||
B.density = 0
|
||||
B.layer = 3
|
||||
spawn(5)
|
||||
del(B)
|
||||
step_to(A,M,0)
|
||||
if (get_dist(A,M) == 0)
|
||||
M.weakened += missile_weaken_amt
|
||||
M.take_organ_damage(0, missile_damage)
|
||||
del(A)
|
||||
return
|
||||
sleep(missile_step_delay)
|
||||
del(A)
|
||||
targets++
|
||||
@@ -1,4 +1,4 @@
|
||||
/obj/spell/mind_transfer
|
||||
/obj/spell/targeted/mind_transfer
|
||||
name = "Mind Transfer"
|
||||
desc = "This spell allows the user to switch bodies with a target."
|
||||
|
||||
@@ -17,13 +17,16 @@
|
||||
var/paralysis_amount_caster = 20 //how much the caster is paralysed for after the spell
|
||||
var/paralysis_amount_victim = 20 //how much the victim is paralysed for after the spell
|
||||
|
||||
/obj/spell/mind_transfer/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
/obj/spell/targeted/mind_transfer/cast(list/targets) //magnets, so mostly hardcoded
|
||||
if(!targets.len)
|
||||
usr << "No mind found"
|
||||
return
|
||||
|
||||
var/mob/target = input("Choose whom to transfer your mind to", "ABRAKADABRA") as mob in oview(usr,range)
|
||||
if(targets.len > 1)
|
||||
usr << "Too many minds! You're not a hive damnit!"
|
||||
return
|
||||
|
||||
var/mob/target = targets[1]
|
||||
|
||||
if(!target.client || !target.mind)
|
||||
usr << "They appear to be brain-dead."
|
||||
@@ -41,8 +44,6 @@
|
||||
usr << "You didn't study necromancy back at the Space Wizard Federation academy."
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
var/mob/victim = target //mostly copypastaed, I have little idea how this works
|
||||
var/mob/caster = usr
|
||||
//losing spells
|
||||
@@ -51,14 +52,14 @@
|
||||
for(var/i=1,i<=spell_loss_amount,i++)
|
||||
var/spell_loss_chance = base_spell_loss_chance
|
||||
var/list/checked_spells = usr.spell_list
|
||||
checked_spells -= src //MT can't be lost
|
||||
checked_spells -= src //MT can't be lost //doesn't work
|
||||
|
||||
for(var/j=1,j<=checked_spells.len,j++)
|
||||
if(prob(spell_loss_chance))
|
||||
if(checked_spells.len)
|
||||
usr.spell_list -= pick(checked_spells)
|
||||
spawn(msg_wait)
|
||||
caster << "The mind transfer has robbed you of a spell."
|
||||
victim << "The mind transfer has robbed you of a spell."
|
||||
break
|
||||
else
|
||||
spell_loss_chance += spell_loss_chance_modifier
|
||||
@@ -96,6 +97,6 @@
|
||||
victim.paralysis += paralysis_amount_victim
|
||||
|
||||
spawn(msg_wait)
|
||||
victim << "Your body doesn't feel like itself."
|
||||
caster << "Your body doesn't feel like itself."
|
||||
|
||||
del(temp_ghost)
|
||||
@@ -1,50 +0,0 @@
|
||||
/obj/spell/mutate
|
||||
name = "Mutate"
|
||||
desc = "This spell causes you to turn into a hulk and gain telekinesis for a short while."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "BIRUZ BENNAR"
|
||||
invocation_type = "shout"
|
||||
message = "\blue You feel strong! Your mind expands!"
|
||||
range = -1 //can affect only the user by default, but with var editing can be a mutate other spell
|
||||
var/mutate_duration = 300 //in deciseconds
|
||||
var/list/mutation_types = list("hulk","tk") //right now understands only "hulk", "tk", "cold resist", "xray" and "clown"
|
||||
|
||||
/obj/spell/mutate/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
var/mob/M
|
||||
|
||||
if(range>=0)
|
||||
M = input("Choose whom to mutate", "ABRAKADABRA") as mob in view(usr,range)
|
||||
else
|
||||
M = usr
|
||||
|
||||
if(!M)
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
M << text("[message]")
|
||||
var/mutation = 0
|
||||
for(var/MT in mutation_types)
|
||||
switch(MT)
|
||||
if("tk")
|
||||
mutation |= 1
|
||||
if("cold resist")
|
||||
mutation |= 2
|
||||
if("xray")
|
||||
mutation |= 4
|
||||
if("hulk")
|
||||
mutation |= 8
|
||||
if("clown")
|
||||
mutation |= 16
|
||||
M.mutations |= mutation
|
||||
spawn (mutate_duration)
|
||||
M.mutations &= ~mutation
|
||||
return
|
||||
75
code/datums/spells/projectile.dm
Normal file
75
code/datums/spells/projectile.dm
Normal file
@@ -0,0 +1,75 @@
|
||||
/obj/spell/targeted/projectile
|
||||
name = "Projectile"
|
||||
desc = "This spell summons projectiles which try to hit the targets."
|
||||
|
||||
var/proj_icon = 'projectiles.dmi'
|
||||
var/proj_icon_state = "spell"
|
||||
var/proj_name = "a spell projectile"
|
||||
|
||||
var/proj_trail = 0 //if it leaves a trail
|
||||
var/proj_trail_lifespan = 0 //deciseconds
|
||||
var/proj_trail_icon = 'wizard.dmi'
|
||||
var/proj_trail_icon_state = "trail"
|
||||
|
||||
var/proj_type = "/obj/spell/targeted" //IMPORTANT use only subtypes of this
|
||||
|
||||
var/proj_lingering = 0 //if it lingers or disappears upon hitting an obstacle
|
||||
var/proj_homing = 1 //if it follows the target
|
||||
var/proj_insubstantial = 0 //if it can pass through dense objects or not
|
||||
var/proj_trigger_range = 1 //the range from target at which the projectile triggers cast(target)
|
||||
|
||||
var/proj_lifespan = 15 //in deciseconds * proj_step_delay
|
||||
var/proj_step_delay = 1 //lower = faster
|
||||
|
||||
/obj/spell/targeted/projectile/cast(list/targets)
|
||||
|
||||
for(var/mob/target in targets)
|
||||
spawn(0)
|
||||
var/projectile_type = text2path(proj_type)
|
||||
var/obj/spell/targeted/projectile = new projectile_type(usr)
|
||||
projectile.icon = proj_icon
|
||||
projectile.icon_state = proj_icon_state
|
||||
projectile.dir = get_dir(target,projectile)
|
||||
projectile.name = proj_name
|
||||
|
||||
var/current_loc = usr.loc
|
||||
|
||||
for(var/i = 0,i < proj_lifespan,i++)
|
||||
if(!projectile)
|
||||
break
|
||||
|
||||
if(proj_homing)
|
||||
if(proj_insubstantial)
|
||||
projectile.loc = get_step_to(projectile,target)
|
||||
else
|
||||
step_to(projectile,target)
|
||||
else
|
||||
if(proj_insubstantial)
|
||||
projectile.loc = get_step(projectile,dir)
|
||||
else
|
||||
step(projectile,dir)
|
||||
|
||||
if(!proj_lingering && projectile.loc == current_loc) //if it didn't move since last time
|
||||
del(projectile)
|
||||
break
|
||||
|
||||
if(proj_trail && projectile)
|
||||
spawn(0)
|
||||
if(projectile)
|
||||
var/obj/overlay/trail = new /obj/overlay(projectile.loc)
|
||||
trail.icon = proj_trail_icon
|
||||
trail.icon_state = proj_trail_icon_state
|
||||
trail.density = 0
|
||||
spawn(proj_trail_lifespan)
|
||||
del(trail)
|
||||
|
||||
if(projectile.loc in range(target.loc,proj_trigger_range))
|
||||
projectile.perform(list(target))
|
||||
break
|
||||
|
||||
current_loc = projectile.loc
|
||||
|
||||
sleep(proj_step_delay)
|
||||
|
||||
if(projectile)
|
||||
del(projectile)
|
||||
@@ -1,23 +0,0 @@
|
||||
/obj/spell/smoke
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1 //originates from the user and I don't give a shit atm
|
||||
var/smoke_amount = 10 //above 10 gets reduced to 10 anyway by the set_up proc
|
||||
|
||||
/obj/spell/smoke/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
var/datum/effects/system/bad_smoke_spread/smoke = new /datum/effects/system/bad_smoke_spread()
|
||||
smoke.set_up(smoke_amount, 0, usr.loc)
|
||||
smoke.start()
|
||||
@@ -1,64 +0,0 @@
|
||||
/obj/spell/teleport
|
||||
name = "Teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 1
|
||||
invocation = "SCYAR NILA"
|
||||
invocation_type = "none" //hardcoded into the spell due to its specifics
|
||||
range = -1 //can affect only the user by default, but with var editing can be a teleport other spell
|
||||
var/smoke_spread = 1 //if set to 0, no smoke spreads when teleporting
|
||||
|
||||
/obj/spell/teleport/Click()
|
||||
..()
|
||||
|
||||
if(!cast_check())
|
||||
return
|
||||
|
||||
var/mob/M
|
||||
|
||||
if(range>=0)
|
||||
M = input("Choose whom to teleport", "ABRAKADABRA") as mob in view(usr,range)
|
||||
else
|
||||
M = usr
|
||||
|
||||
if(!M)
|
||||
return
|
||||
|
||||
invocation()
|
||||
|
||||
var/A
|
||||
|
||||
A = input("Area to jump to", "BOOYEA", A) in teleportlocs
|
||||
|
||||
var/area/thearea = teleportlocs[A]
|
||||
|
||||
usr.say("[invocation] [uppertext(A)]")
|
||||
if(usr.gender=="male")
|
||||
playsound(usr.loc, pick('vs_chant_conj_hm.wav','vs_chant_conj_lm.wav','vs_chant_ench_hm.wav','vs_chant_ench_lm.wav','vs_chant_evoc_hm.wav','vs_chant_evoc_lm.wav','vs_chant_illu_hm.wav','vs_chant_illu_lm.wav','vs_chant_necr_hm.wav','vs_chant_necr_lm.wav'), 100, 1)
|
||||
else
|
||||
playsound(usr.loc, pick('vs_chant_conj_hf.wav','vs_chant_conj_lf.wav','vs_chant_ench_hf.wav','vs_chant_ench_lf.wav','vs_chant_evoc_hf.wav','vs_chant_evoc_lf.wav','vs_chant_illu_hf.wav','vs_chant_illu_lf.wav','vs_chant_necr_hf.wav','vs_chant_necr_lf.wav'), 100, 1)
|
||||
|
||||
var/datum/effects/system/harmless_smoke_spread/smoke = new /datum/effects/system/harmless_smoke_spread()
|
||||
|
||||
if(smoke_spread)
|
||||
smoke.set_up(5, 0, usr.loc)
|
||||
smoke.attach(usr)
|
||||
smoke.start()
|
||||
|
||||
var/list/L = list()
|
||||
for(var/turf/T in get_area_turfs(thearea.type))
|
||||
if(!T.density)
|
||||
var/clear = 1
|
||||
for(var/obj/O in T)
|
||||
if(O.density)
|
||||
clear = 0
|
||||
break
|
||||
if(clear)
|
||||
L+=T
|
||||
|
||||
M.loc = pick(L)
|
||||
|
||||
if(smoke_spread)
|
||||
smoke.start()
|
||||
34
code/datums/spells/turf_teleport.dm
Normal file
34
code/datums/spells/turf_teleport.dm
Normal file
@@ -0,0 +1,34 @@
|
||||
/obj/spell/targeted/turf_teleport
|
||||
name = "Turf Teleport"
|
||||
desc = "This spell teleports the target to the turf in range."
|
||||
|
||||
var/inner_tele_radius = 1
|
||||
var/outer_tele_radius = 2
|
||||
|
||||
var/include_space = 0 //whether it includes space tiles in possible teleport locations
|
||||
var/include_dense = 0 //whether it includes dense tiles in possible teleport locations
|
||||
|
||||
/obj/spell/targeted/turf_teleport/cast(list/targets)
|
||||
for(var/mob/target in targets)
|
||||
var/list/turfs = new/list()
|
||||
for(var/turf/T in range(target,outer_tele_radius))
|
||||
if(T in range(target,inner_tele_radius)) continue
|
||||
if(istype(T,/turf/space) && !include_space) continue
|
||||
if(T.density && !include_dense) continue
|
||||
if(T.x>world.maxx-outer_tele_radius || T.x<outer_tele_radius) continue //putting them at the edge is dumb
|
||||
if(T.y>world.maxy-outer_tele_radius || T.y<outer_tele_radius) continue
|
||||
turfs += T
|
||||
|
||||
if(!turfs.len)
|
||||
var/list/turfs_to_pick_from = list()
|
||||
for(var/turf/T in orange(target,outer_tele_radius))
|
||||
if(!(T in orange(target,inner_tele_radius)))
|
||||
turfs_to_pick_from += T
|
||||
turfs += pick(/turf in turfs_to_pick_from)
|
||||
|
||||
var/turf/picked = pick(turfs)
|
||||
|
||||
if(!picked || !isturf(picked))
|
||||
return
|
||||
|
||||
target.loc = picked
|
||||
183
code/datums/spells/wizard.dm
Normal file
183
code/datums/spells/wizard.dm
Normal file
@@ -0,0 +1,183 @@
|
||||
/obj/spell/targeted/projectile/fireball
|
||||
name = "Fireball"
|
||||
desc = "This spell fires a fireball at a target and does not require wizard garb."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 200
|
||||
clothes_req = 0
|
||||
invocation = "ONI SOMA"
|
||||
invocation_type = "shout"
|
||||
|
||||
proj_icon_state = "fireball"
|
||||
proj_name = "a fireball"
|
||||
proj_lingering = 1
|
||||
proj_type = "/obj/spell/targeted/explosion/fireball"
|
||||
|
||||
/obj/spell/targeted/explosion/fireball
|
||||
ex_severe = -1
|
||||
ex_heavy = -1
|
||||
ex_light = 3
|
||||
ex_flash = 5
|
||||
|
||||
/obj/spell/targeted/projectile/magic_missile
|
||||
name = "Magic Missile"
|
||||
desc = "This spell fires several, slow moving, magic projectiles at nearby targets."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 100
|
||||
clothes_req = 1
|
||||
invocation = "FORTI GY AMA"
|
||||
invocation_type = "shout"
|
||||
range = 7
|
||||
|
||||
max_targets = 0
|
||||
|
||||
proj_icon_state = "magicm"
|
||||
proj_name = "a magic missile"
|
||||
proj_lingering = 1
|
||||
proj_type = "/obj/spell/targeted/inflict_handler/magic_missile"
|
||||
|
||||
proj_lifespan = 20
|
||||
proj_step_delay = 5
|
||||
|
||||
proj_trail = 1
|
||||
proj_trail_lifespan = 5
|
||||
proj_trail_icon_state = "magicmd"
|
||||
|
||||
/obj/spell/targeted/inflict_handler/magic_missile
|
||||
amt_weaken = 5
|
||||
amt_dam_fire = 10
|
||||
|
||||
/obj/spell/targeted/genetic/blind //doesn't work properly
|
||||
name = "Blind"
|
||||
desc = "This spell temporarily blinds a single person and does not require wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 300
|
||||
clothes_req = 0
|
||||
invocation = "STI KALY"
|
||||
invocation_type = "whisper"
|
||||
message = "\blue Your eyes cry out in pain!"
|
||||
|
||||
disabilities = 1
|
||||
duration = 300
|
||||
|
||||
/obj/spell/targeted/genetic/mutate
|
||||
name = "Mutate"
|
||||
desc = "This spell causes you to turn into a hulk and gain telekinesis for a short while."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "BIRUZ BENNAR"
|
||||
invocation_type = "shout"
|
||||
message = "\blue You feel strong! Your mind expands!"
|
||||
range = -1
|
||||
include_usr = 1
|
||||
|
||||
mutations = 9
|
||||
duration = 300
|
||||
|
||||
/obj/spell/targeted/inflict_handler/disintegrate
|
||||
name = "Disintegrate"
|
||||
desc = "This spell instantly kills somebody adjacent to you with the vilest of magick."
|
||||
|
||||
school = "evocation"
|
||||
charge_max = 600
|
||||
clothes_req = 1
|
||||
invocation = "EI NATH"
|
||||
invocation_type = "shout"
|
||||
range = 1
|
||||
|
||||
destroys = "disintegrate"
|
||||
|
||||
sparks_spread = 1
|
||||
sparks_amt = 4
|
||||
|
||||
/obj/spell/targeted/smoke
|
||||
name = "Smoke"
|
||||
desc = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120
|
||||
clothes_req = 0
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_usr = 1
|
||||
|
||||
smoke_spread = 2
|
||||
smoke_amt = 10
|
||||
|
||||
/obj/spell/targeted/emplosion/disable_tech
|
||||
name = "Disable Tech"
|
||||
desc = "This spell disables all weapons, cameras and most other technology in range."
|
||||
charge_max = 400
|
||||
clothes_req = 1
|
||||
invocation = "NEC CANTIO"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_usr = 1
|
||||
|
||||
emp_heavy = 5
|
||||
emp_light = 7
|
||||
|
||||
/obj/spell/targeted/turf_teleport/blink
|
||||
name = "Blink"
|
||||
desc = "This spell randomly teleports you a short distance."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 20
|
||||
clothes_req = 1
|
||||
invocation = "none"
|
||||
invocation_type = "none"
|
||||
range = -1
|
||||
include_usr = 1
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 10
|
||||
|
||||
inner_tele_radius = 0
|
||||
outer_tele_radius = 6
|
||||
|
||||
/obj/spell/targeted/area_teleport/teleport
|
||||
name = "Teleport"
|
||||
desc = "This spell teleports you to a type of area of your selection."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 600
|
||||
clothes_req = 1
|
||||
invocation = "SCYAR NILA"
|
||||
invocation_type = "shout"
|
||||
range = -1
|
||||
include_usr = 1
|
||||
|
||||
smoke_spread = 1
|
||||
smoke_amt = 5
|
||||
|
||||
/obj/spell/aoe_turf/conjure/forcewall
|
||||
name = "Forcewall"
|
||||
desc = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb."
|
||||
|
||||
school = "transmutation"
|
||||
charge_max = 100
|
||||
clothes_req = 0
|
||||
invocation = "TARCOL MINTI ZHERI"
|
||||
invocation_type = "whisper"
|
||||
range = 0
|
||||
|
||||
summon_type = list("/obj/forcefield")
|
||||
summon_lifespan = 300
|
||||
|
||||
/obj/spell/aoe_turf/conjure/carp
|
||||
name = "Summon Bigger Carp"
|
||||
desc = "This spell conjures an elite carp."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 1200
|
||||
clothes_req = 1
|
||||
invocation = "NOUK FHUNMM SACP RISSKA"
|
||||
invocation_type = "shout"
|
||||
range = 1
|
||||
|
||||
summon_type = list("/obj/livestock/spesscarp/elite")
|
||||
@@ -175,7 +175,7 @@
|
||||
wizard_mob.verbs += /client/proc/jaunt
|
||||
wizard_mob.mind.special_verbs += /client/proc/jaunt
|
||||
else
|
||||
wizard_mob.spell_list += new /obj/spell/ethereal_jaunt(usr)
|
||||
wizard_mob.spell_list += new /obj/spell/targeted/ethereal_jaunt(usr)
|
||||
|
||||
//So zards properly get their items when they are admin-made.
|
||||
del(wizard_mob.wear_suit)
|
||||
@@ -394,43 +394,43 @@
|
||||
if(!already_knows)
|
||||
switch(href_list["spell_choice"])
|
||||
if ("1")
|
||||
usr.spell_list += new /obj/spell/magic_missile(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/projectile/magic_missile(usr)
|
||||
src.temp = "This spell fires several, slow moving, magic projectiles at nearby targets. If they hit a target, it is paralyzed and takes minor damage."
|
||||
if ("2")
|
||||
usr.spell_list += new /obj/spell/fireball(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/projectile/fireball(usr)
|
||||
src.temp = "This spell fires a fireball at a target and does not require wizard garb. Be careful not to fire it at people that are standing next to you."
|
||||
if ("3")
|
||||
usr.spell_list += new /obj/spell/disintegrate(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/inflict_handler/disintegrate(usr)
|
||||
src.temp = "This spell instantly kills somebody adjacent to you with the vilest of magick. It has a long cooldown."
|
||||
if ("4")
|
||||
usr.spell_list += new /obj/spell/disable_tech(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/emplosion/disable_tech(usr)
|
||||
src.temp = "This spell disables all weapons, cameras and most other technology in range."
|
||||
if ("5")
|
||||
usr.spell_list += new /obj/spell/smoke(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/smoke(usr)
|
||||
src.temp = "This spell spawns a cloud of choking smoke at your location and does not require wizard garb."
|
||||
if ("6")
|
||||
usr.spell_list += new /obj/spell/blind(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/genetic/blind(usr)
|
||||
src.temp = "This spell temporarly blinds a single person and does not require wizard garb."
|
||||
if ("7")
|
||||
usr.spell_list += new /obj/spell/mind_transfer(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/mind_transfer(usr)
|
||||
src.temp = "This spell allows the user to switch bodies with a target. Careful to not lose your memory in the process."
|
||||
if ("8")
|
||||
usr.spell_list += new /obj/spell/forcewall(usr)
|
||||
usr.spell_list += new /obj/spell/aoe_turf/conjure/forcewall(usr)
|
||||
src.temp = "This spell creates an unbreakable wall that lasts for 30 seconds and does not need wizard garb."
|
||||
if ("9")
|
||||
usr.spell_list += new /obj/spell/blink(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/turf_teleport/blink(usr)
|
||||
src.temp = "This spell randomly teleports you a short distance. Useful for evasion or getting into areas if you have patience."
|
||||
if ("10")
|
||||
usr.spell_list += new /obj/spell/teleport(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/area_teleport/teleport(usr)
|
||||
src.temp = "This spell teleports you to a type of area of your selection. Very useful if you are in danger, but has a decent cooldown, and is unpredictable."
|
||||
if ("11")
|
||||
usr.spell_list += new /obj/spell/mutate(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/genetic/mutate(usr)
|
||||
src.temp = "This spell causes you to turn into a hulk and gain telekinesis for a short while."
|
||||
if ("12")
|
||||
usr.spell_list += new /obj/spell/ethereal_jaunt(usr)
|
||||
usr.spell_list += new /obj/spell/targeted/ethereal_jaunt(usr)
|
||||
src.temp = "This spell creates your ethereal form, temporarily making you invisible and able to pass through walls."
|
||||
if ("13")
|
||||
usr.spell_list += new /obj/spell/knock(usr)
|
||||
usr.spell_list += new /obj/spell/aoe_turf/knock(usr)
|
||||
src.temp = "This spell opens nearby doors and does not require wizard garb."
|
||||
if (href_list["spell_choice"] == "14")
|
||||
var/area/wizard_station/A = locate()
|
||||
|
||||
@@ -476,7 +476,7 @@
|
||||
src.laws = new /datum/ai_laws/syndicate_override
|
||||
var/time = time2text(world.realtime,"hh:mm:ss")
|
||||
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [src.name]([src.key])")
|
||||
set_zeroth_law("Only [usr] is a syndicate operative.")
|
||||
set_zeroth_law("Only [user.name] and people he designates as being such are syndicate agents.")
|
||||
src << "\red ALERT: Foreign software detected."
|
||||
sleep(5)
|
||||
src << "\red Initiating diagnostics..."
|
||||
|
||||
Reference in New Issue
Block a user