#define SHAPE_SQUARE 1
#define SHAPE_CIRCLE 2
spell
var/mob/caster // Owner of the spell.
proc
GetCaster()
return caster
GetCasterGroup()
return caster.group
effect
var
spell/master
atom/effecter
icon
icon_state
layer = MOB_LAYER + 1
icon/overlay
New(atom/a, spell/s)
effecter = a
master = s
spawn()
Damage()
Del()
effecter.overlays -= overlay
proc
AddOverlay()
overlay = new(icon, icon_state)
overlays.layer = layer
effecter.overlays += overlay
Damage()
// For now, this is just a template proc.
AddOverlay()
area_of_effect
var
name
atom/center
radius = 5 // By default, it has a radius of
// five tiles.
shape = SHAPE_CIRCLE // The shape of the area of
// effect, which, by
// default, takes the
// shape of a circle.
list
targets[0]
effects[0]
target_type = /mob // Attack any mob. This can
// also be a list.
spell/effect/effect // The effect to use.
time = 100 // Ten second spell.
New(atom/loc, mob/m)
owner = m
center = loc
GetTargets()
DoEffect()
spawn(time)
// When the effect is finished, delete the
// spell.
del src
Del()
for(var/spell/effect/e in effects)
// Cleaning up the effects.
del e
proc
AffectedBySpell(atom/a)
// Default action for this is that no one
// in the caster's group is affected by the
// spell, as well as the caster themself.
return !((a == GetCaster()) || (a in GetCasterGroup())
InRange(atom/a, v)
if((shape == SHAPE_CIRCLE) && (get_dist(center, a) < radius))
return 1
return a in (v || view(center, radius)
GetTargets()
var/list/t = view(center, radius)
for(var/atom/movable/a in t)
// Presumably, you'll only want to
// attack mobs, but this will allow for
// attacking mobs and objs. If you want
// to, for some reason, attack turfs or
// objs, you'll have to edit this proc.
if(istype(target_type, /list) ? !(a.type in target_type) : !istype(a, target_type))
// If a isn't of the target type
// being attacked, keep going.
continue
if(!InRange(a, t))
// If the target is not in range,
// continue.
continue
if(!AffectedBySpell(t))
// If t is not affected by the spell,
// continue.
continue
targets += a // Add the target to the
// targets list.
DoEffect()
for(var/atom/a in targets)
effects += new effect(a, src)
Here is an example implementation, for a circle-of-fire move:
mob/verb/CircleOfFire()
// Create a new circle-of-fire spell, with src as the
// caster, centered at the caster's location.
new /spell/area_of_effect/circle_of_fire(src, loc)
spell
area_of_effect/circle_of_fire
name = "Circle of Fire"
radius = 8
target_type = list(/mob, /obj) // Will burn objs
// as well.
time = 50 // Only a five second spell.
effect = /spell/effects/fire
AffectedBySpell(atom/a)
// This spell will hurt everyoneo but the
// caster.
return a != GetCaster()
effects/fire
icon = 'Effect Icons.dmi'
icon_state = "fire"
Damage()
// And here is where Damage() is used.
while(1)
// This will keep looping so long as
// src exists.
sleep(3) // Do damage every three ticks.
if(master.InRange(effecter))
// As long as the person being attacked
// by the spell is in range of the
// circle, keep doing a random amount
// of damage between 5 and 10 to them.
effecter.Damage(rand(5, 10))
That's incredibly over complicated and partially pointless.