library Spell initializer init requires TimerUtils,GroupUtils
globals
private integer SpellId ='A000'
private real SpellAoe =400
private real SpellSpeed =0.1
private real SpellDur =4
private real array SpellDamage
private string SpellSfx ="Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl"
private player TempPlayer
endglobals
private function GetSpellDamage takes integer level returns real
return I2R(level)*50
endfunction
struct Spell
unit u
real x
real y
real tik
integer level
method stop takes nothing returns nothing
set.u=null
call.destroy()
endmethod
method Effect takes nothing returns nothing
local real x
local real y
local real r=GetRandomReal(0,SpellAoe)
set x=.x+r*Cos(r*bj_DEGTORAD)
set y=.y+r*Sin(r*bj_DEGTORAD)
call DestroyEffect(AddSpecialEffect(SpellSfx,x,y))
endmethod
static method Check takes nothing returns boolean
local boolean b=true
local unit u=GetFilterUnit()
set b=b and GetWidgetLife(u)>.405
set b=b and IsUnitType(u,UNIT_TYPE_STRUCTURE)==false
set b=b and IsUnitEnemy(u,TempPlayer)
set u=null
return b
endmethod
method Damage takes nothing returns nothing
local group g=NewGroup()
local unit u
set TempPlayer=GetOwningPlayer(.u)
call GroupEnumUnitsInArea(g,.x,.y,SpellAoe,Condition(function thistype.Check))
loop
set u=FirstOfGroup(g)
exitwhen u==null
call UnitDamageTarget(.u,u,GetSpellDamage(.level),true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,null)
call GroupRemoveUnit(g,u)
set u=null
endloop
call ReleaseGroup(g)
set TempPlayer=null
set g=null
set u=null
endmethod
static method Loop takes nothing returns nothing
local timer ti=GetExpiredTimer()
local thistype this=GetTimerData(ti)
set.tik=.tik-1
if.tik<=0then
call ReleaseTimer(ti)
call.stop()
else
call.Effect()
call.Damage()
endif
set ti=null
endmethod
static method Create takes unit u,real x,real y returns thistype
local thistype this=thistype.allocate()
local timer ti=NewTimer()
set.u=u
set.x=x
set.y=y
set.level=GetUnitAbilityLevel(.u,SpellId)
set.tik=SpellDur/SpellSpeed
call SetTimerData(ti,this)
call TimerStart(ti,SpellSpeed,true,function thistype.Loop)
set ti=null
return this
endmethod
endstruct
private function Cd takes nothing returns boolean
if GetSpellAbilityId()==SpellId then
call Spell.Create(GetSpellAbilityUnit(),GetSpellTargetX(),GetSpellTargetY())
endif
return false
endfunction
private function init takes nothing returns nothing
local integer i=0
local trigger t=CreateTrigger()
loop
if GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING then
call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
endif
set i=i+1
exitwhen i==bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t,function Cd)
set t=null
endfunction
endlibrary