scope Energy initializer Initi
globals
private constant integer SPELL_ID = 'A000'
private constant integer DUMMY_ID = 'h000'
private constant real PERIOD = 0.04 //Timer period
private constant real RADIUS = 450. //Spell radius
private constant string DUMMY_EFFECT = "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl" //The missle effect that appears on the dummy
private constant string HEAL_EFFECT = "Abilities\\Spells\\Human\\Heal\\HealTarget.mdl" //The healing effect that appears on the caster
private group TempGroup = CreateGroup()
private timer T = CreateTimer()
endglobals
private function HEAL takes integer lvl returns real //The ammount healed for each essence
return lvl * 10 + 25.
endfunction
private function DAMAGE takes integer lvl returns real //The ammount of damage dealt to each target
return lvl * 10 + 25.
endfunction
private function Filter takes nothing returns boolean
return (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false) and (GetWidgetLife(GetFilterUnit()) > 0.405)
endfunction
////////////////////////Don't touch anything below unless you know what you're doing///////////////////////////////////////////
private struct data
unit caster
unit dummy
integer lvl
effect sfx
static integer Total = 0
static data array ar
static method Callback takes nothing returns nothing
local data d
local integer i = 0
local real x
local real y
local real angle
loop
exitwhen i >= data.Total
set d = data.ar[i]
set x = GetUnitX(d.dummy)
set y = GetUnitY(d.dummy)
set angle = Atan2(GetUnitY(d.caster) - y,GetUnitX(d.caster) - x)
if SquareRoot((x - GetUnitX(d.caster)) * (x - GetUnitX(d.caster)) + (y - GetUnitY(d.caster)) * (y - GetUnitY(d.caster))) > 30 then
set x = x + 20 * Cos(angle)
set y = y + 20 * Sin(angle)
call SetUnitX(d.dummy, x)
call SetUnitY(d.dummy, y)
call SetUnitFacing(d.dummy, angle * bj_RADTODEG)
else
call DestroyEffect(AddSpecialEffectTarget(HEAL_EFFECT, d.caster, "chest"))
call SetWidgetLife(d.caster, GetWidgetLife(d.caster) + HEAL(d.lvl))
call DestroyEffect(d.sfx)
call RemoveUnit(d.dummy)
call d.destroy()
set data.Total = data.Total - 1
set data.ar[i] = data.ar[data.Total]
set i = i - 1
endif
set i = i + 1
endloop
if data.Total == 0 then
call PauseTimer(T)
endif
endmethod
static method create takes unit caster, unit target returns data
local data d = data.allocate()
set d.caster = caster
set d.dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID, GetUnitX(target), GetUnitY(target), Atan2(GetUnitY(caster) - GetUnitY(target), GetUnitX(caster) - GetUnitX(target)) * bj_RADTODEG)
set d.sfx = AddSpecialEffectTarget(DUMMY_EFFECT, d.dummy, "chest")
set data.ar[data.Total] = d
if data.Total == 0 then
call TimerStart(T, PERIOD, true, function data.Callback)
endif
set data.Total = data.Total + 1
return d
endmethod
endstruct
private function Cond takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
private function Act takes nothing returns nothing
local unit temp
local unit caster = GetTriggerUnit()
call GroupEnumUnitsInRange(TempGroup, GetUnitX(caster), GetUnitY(caster), RADIUS, Condition(function Filter))
loop
set temp = FirstOfGroup(TempGroup)
exitwhen temp == null
if IsUnitEnemy(temp, GetTriggerPlayer()) then
call UnitDamageTarget(caster, temp, DAMAGE(GetUnitAbilityLevel(caster, SPELL_ID)), false, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call data.create(caster, temp)
endif
call GroupRemoveUnit(TempGroup, temp)
endloop
set caster = null
endfunction
private function Initi takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t, Condition(function Cond))
call TriggerAddAction(t, function Act)
endfunction
endscope