scope SpellTemplate initializer Init
private keyword Data
globals
private constant real TIMER_INTERVAL = 0.03
private constant real DIST = 32 // value of the distance cut every timer interval high value means high speed
private constant integer ABIL_ID = 'A000' //change this to the rawcode of your spell
private constant integer UNIT_ID = 'e000' // rawcode of the dummy (Missile) unit
//Other constant globals here...
private Data array data
private integer index = 0
private timer tim
// Other changable globals here...
endglobals
private function Execute takes nothing returns nothing
local integer i = 0
local Data d
local location missilePoint
local location stepPoint
// Other local variables here...
loop
exitwhen i >= index
set d = data[i]
set missilePoint = GetUnitLoc(d.missile)
if DistanceBetweenPoints(missilePoint, d.CastPoint) < DIST * 0.5 then
call d.destroy()
call CreateNova(d.caster,GetLocationX(d.CastPoint),GetLocationY(d.CastPoint))
else
set stepPoint = PolarProjectionBJ(missilePoint, DIST, AngleBetweenPoints(missilePoint, d.CastPoint))
call SetUnitPositionLoc(d.missile, stepPoint)
call RemoveLocation(stepPoint)
endif
call RemoveLocation(missilePoint)
set i = i + 1
endloop
//Any leak cleaning code here...
endfunction
private struct Data
//Declare struct members here...
unit caster
unit missile
integer ID
location CastPoint
static method create takes unit caster, location target returns Data //make sure you change this based on what data you need
local Data d = Data.allocate()
local real face
//Other create code here...
set data[index] = d
set d.ID = index
set d.CastPoint = target
set d.caster = caster
set face = AngleBetweenPoints(GetUnitLoc(d.caster),d.CastPoint)
set d.missile = CreateUnit(GetOwningPlayer(d.caster), UNIT_ID, GetUnitX(d.caster), GetUnitY(d.caster), face)
call SetUnitPosition(d.missile, GetUnitX(d.caster), GetUnitY(d.caster))
if index == 0 then
call TimerStart(tim, TIMER_INTERVAL, true, function Execute)
endif
set index = index + 1
return d
endmethod
method onDestroy takes nothing returns nothing
set index = index-1
set data[this.ID] = data[index]
set data[this.ID].ID = this.ID
if index==0 then
call PauseTimer(tim)
endif
//Other destroy code here (such as leak cleaning, removing units etc)...
call KillUnit(this.missile)
endmethod
endstruct
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABIL_ID
endfunction
private function Actions takes nothing returns nothing
call Data.create(GetTriggerUnit(), GetSpellTargetLoc()) //make sure you change this based on what data your spell needs
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddAction(t, function Actions)
call TriggerAddCondition(t, Condition(function Conditions))
set tim = CreateTimer()
//Other initializations things here...
//Preload the dummy units to reduce lagg on first cast
call RemoveUnit(CreateUnit(Player(12),'e000',0.,0.,0.))
call RemoveUnit(CreateUnit(Player(12),'e001',0.,0.,0.))
endfunction
endscope