Files
Polaris/code/datums/spell.dm
uporotiy b7db69b6f8 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
2011-04-17 18:49:46 +00:00

259 lines
8.4 KiB
Plaintext

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/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; 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
if(!(src in usr.spell_list))
usr << "\red You shouldn't have this spell! Something's wrong."
return 0
switch(charge_type)
if("recharge")
if(charge_counter < charge_max)
usr << "[name] is still recharging."
return 0
if("charges")
if(!charge_counter)
usr << "[name] has no charges left."
return 0
if(usr.stat && !stat_allowed)
usr << "Not when you're incapacitated."
return 0
if(clothes_req) //clothes check
if(!istype(usr:wear_suit, /obj/item/clothing/suit/wizrobe))
usr << "I don't feel strong enough without my robe."
return 0
if(!istype(usr:shoes, /obj/item/clothing/shoes/sandal))
usr << "I don't feel strong enough without my sandals."
return 0
if(!istype(usr:head, /obj/item/clothing/head/wizard))
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
switch(invocation_type)
if("shout")
usr.say(invocation)
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)
/obj/spell/New()
..()
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