//////////////////////////////////////Globals with important values////////////////////////////////////////
scope FireRun initializer Init
globals
private constant integer DummyID = 'h000' // The Rawcode of teh dummy
private constant integer Spell = 'A000' // Your FieryRun Spell, must add a Buff (look line below)
private constant integer Buff = 'B000' // The Buff the unit has while its "burning" and the spell is active
private constant integer PassiveEffect1 = 'A001' // Effect the Flames got, in this case its an armour decreasing aura
private constant integer PassiveEffect2 = 'A002' // Another Effect the Flames got , in this case its Phoenixfire to deal damage
private constant real CreationRange = 80.00 // Distance between Fire dummys / Minrange the unit has to move till another dummy is created
private constant real TimerPeriod = 0.1 // The interval in which checks are made
private constant real MaxDistance = 800 // The Maximum range which can be moved in each interval which will cause flames to be created (mention the Creationrange and Max movementspeed of 522
private constant real DelayedRemoval = 1.5 // Delay between the death and the removal of the dummy unit (to show death animation)
private timer t = CreateTimer() // Do not modify
endglobals
private constant function Lasts takes integer level returns real
return level + 3.0
// How Long each Flame will last
endfunction
private constant function SpellDuration takes integer level returns real
return 4.0 + 4.0 * level
// Spell Duration, shoul be the same duration of the buff
endfunction
private function RunCondition takes nothing returns boolean
return GetSpellAbilityId() == Spell
//The condition if the spell is casted
endfunction
////////////////////////////////Main script// Do not edit unless you understand it////////////////////////////////
private function CreateFlame takes integer level, unit u, real x, real y, real angle returns nothing
// Simply creating flames
// Yes i know it uses TSA ...but due the duration is not really low and has not an insanely importance i decided to use waits after i got several bugs before which drove me crazy
local unit flame = CreateUnit(GetOwningPlayer(u),DummyID,x,y,bj_RADTODEG * angle)
call UnitAddAbility(flame,PassiveEffect1)
call SetUnitAbilityLevel(flame,PassiveEffect1,level)
call UnitAddAbility(flame,PassiveEffect2)
call SetUnitAbilityLevel(flame,PassiveEffect2,level)
call TriggerSleepAction(Lasts(level))
call KillUnit(flame)
call TriggerSleepAction(DelayedRemoval)
call RemoveUnit(flame)
set flame = null
return
endfunction
private function callback takes nothing returns nothing
local integer i = 0
// looping through all structs
loop
exitwhen i >= F.Index
call F.Data[i].move()
set i = i+1
endloop
if F.Data[F.Index-1].Index != 0 then
call TimerStart(t, TimerPeriod, true, function callback)
endif
endfunction
struct F
static integer Index = 0
static F array Data
unit u // Caster
integer in = 0 // Index of the struct
integer dur = 0 // Duration left
real lx = 0 // Last x coordinated where a flame was created
real ly = 0 // Last y coordinated where a flame was created
integer level // Level of the spell
static method create takes unit u, integer level returns F
// Spell is cast and this sets most revelant values
// Does not create the flames
local F d = F.allocate()
set F.Data[F.Index] = d
set d.dur = R2I(SpellDuration(level) / TimerPeriod)
set d.in = F.Index
set d.u = u
set d.level = level
set d.Index = F.Index + 1
set d.lx = GetUnitX(u)
set d.ly = GetUnitY(u)
if d.Data[d.Index-1].Index == 1 then
call TimerStart(t, TimerPeriod, true, function callback)
endif
return d
endmethod
method move takes nothing returns nothing
local integer ii = 0
local real x = GetUnitX(this.u)
local real y = GetUnitY(this.u)
local real d
local real a
//Checking if the duration is over and destroying the struct then
set this.dur = this.dur - 1
if this.dur <= 0 or GetWidgetLife(this.u) <= 0.405 or GetUnitAbilityLevel(this.u,Buff) == 0 then
set this.u = null
set ii = this.in
call F.destroy(this)
set F.Index = F.Index - 1
set F.Data[ii] = F.Data[F.Index]
set F.Data[ii].in = ii
return
endif
//Checking for distanced and creating the flames
set a = Atan2(y - this.ly, x - this.lx)
set d = SquareRoot((x-this.lx)*(x-this.lx) + (y-this.ly)*(y-this.ly))
if d > CreationRange then
if d < MaxDistance then
set ii = 0
loop
exitwhen ii == 1
set this.lx = this.lx + CreationRange * Cos(a)
set this.ly = this.ly + CreationRange * Sin(a)
call CreateFlame.execute(this.level,this.u,this.lx,this.ly,a)
set d = d - CreationRange
if d < CreationRange then
set ii = 1
endif
endloop
else
set this.lx = x
set this.ly = y
endif
endif
endmethod
endstruct
private function Actions takes nothing returns nothing
// Starting the Spell
// If you want a modification that its targeted and the Targeted unit starts burning just change the GetTriggerUnit() to the unit you want
call F.create(GetTriggerUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Spell))
endfunction
//===========================================================================0
private function Init takes nothing returns nothing
local trigger tr = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(tr,EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition( tr, Condition( function RunCondition ) )
call TriggerAddAction( tr, function Actions )
endfunction
endscope