Calls forth lightning from the abyss, targets enemy units within 600 AoE to follow under the caster command as long as the spell channeled. Also healing friendly allied hero units for 10 hit points per second.
//* Spell Damage
private constant function HEAL_AMOUNT takes integer lvl returns real
return lvl*10.0*INTERVAL
endfunction
//* Spell Area of Effect Radius
private constant function RADIUS takes integer lvl returns real
return lvl*600.
endfunction
//* Configuration End
//*****************************************************************
globals
private integer array UnitData
private boolexpr b
endglobals
//set unit's integer
private function AttachIntegerToUnit takes unit u, integer i returns nothing
set UnitData[GetUnitIndex(u)] = i
endfunction
//get unit's integer
private function GetIntegerFromUnit takes unit u returns integer
return UnitData[GetUnitIndex(u)]
endfunction
//spell filter function
private function Spell_Filter takes nothing returns boolean
return (IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE)==false) and (GetWidgetLife(GetFilterUnit()) > 0.405)
endfunction
//spell struct
private struct data
unit caster
unit dum
unit array missile[LIGHTNING_NUM]
lightning array lg[LIGHTNING_NUM]
real array angle[LIGHTNING_NUM]
effect fx
timer t
group g=CreateGroup()
static method create takes unit c, timer t returns data
local data d=data.allocate()
set d.caster=c
set d.t=t
set d.fx=AddSpecialEffectTarget(CASTER_FX, d.caster,CASTER_ATTCH)
set d.dum=CreateUnit(GetOwningPlayer(d.caster),DUMMY_ID,GetUnitX(d.caster),GetUnitY(d.caster),0)
return d
endmethod
//update victim group
method Update_Group takes nothing returns nothing
local unit s
local group temp=CreateGroup()
local integer lvl=GetUnitAbilityLevel(.caster,SPELL_ID)
loop
set s=FirstOfGroup(temp)
exitwhen s==null
//convert owner
if (IsUnitEnemy(s,GetOwningPlayer(.caster))==true and IsUnitInGroup(s,.g)==false and IsUnitType(s,UNIT_TYPE_HERO)==false) then
call AttachIntegerToUnit(s,GetPlayerId(GetOwningPlayer(s)))
call SetUnitOwner(s,GetOwningPlayer(.caster),true)
call GroupAddUnit(.g,s)
//heal friendly unit
elseif (IsUnitAlly(s,GetOwningPlayer(.caster))==true and s!=.caster and IsUnitType(s,UNIT_TYPE_HERO)==true) then
call SetUnitState(s,UNIT_STATE_LIFE,GetUnitState(s,UNIT_STATE_LIFE)+HEAL_AMOUNT(lvl))
call DestroyEffect(AddSpecialEffectTarget(HEAL_FX, s,TARGT_H_ATTCH))
endif
call GroupRemoveUnit(temp,s)
endloop
call DestroyGroup(temp)
set temp=null
set s=null
endmethod
private method onDestroy takes nothing returns nothing
local integer i=0
local unit s
local integer idx
//revert creeps to original owner
loop
set s=FirstOfGroup(.g)
exitwhen s==null
set idx=GetIntegerFromUnit(s)
call SetUnitOwner(s,Player(idx),true)
call GroupRemoveUnit(.g,s)
endloop
//spell trigger condition
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == SPELL_ID
endfunction
//rotate the lightning
private function Clock takes nothing returns nothing
local timer t = GetExpiredTimer()
local data d=data(GetTimerData(t))
local integer i=0
local real x1
local real y1
local real x2 = GetUnitX(d.dum)
local real y2 = GetUnitY(d.dum)
local real angle
local location l1=GetUnitLoc(d.dum)
local location l2
local integer lvl=GetUnitAbilityLevel(d.caster,SPELL_ID)
if (GetUnitCurrentOrder(d.caster)==OrderId(ORDER_ID)) then
loop
exitwhen i>LIGHTNING_NUM
set x1 = GetUnitX(d.missile[i])
set y1 = GetUnitY(d.missile[i])
//rotate counter clockwise
if CLOCKWISE==false then
set angle=d.angle[i]+ANGLE_INCREMENT
//rotate clockwise
else
set angle=d.angle[i]-ANGLE_INCREMENT
endif
//move lightning
call SetUnitPosition(d.missile[i], x2+RADIUS(lvl)*Cos(angle), y2+RADIUS(lvl)*Sin(angle))
set l2=GetUnitLoc(d.missile[i])
call MoveLightningEx(d.lg[i],true,GetUnitX(d.dum),GetUnitY(d.dum),GetLocationZ(l1)+LIGHTNING_HEIGHT,GetUnitX(d.missile[i]),GetUnitY(d.missile[i]),GetLocationZ(l2))
call DestroyEffect(AddSpecialEffectTarget(GROUND_FX, d.missile[i],"origin"))
set d.angle[i]=angle
call RemoveLocation(l2)
set i=i+1
endloop
else
call d.destroy()
endif
call RemoveLocation(l1)
set l1=null
set l2=null
set t=null
endfunction
//spell trigger actions
private function Actions takes nothing returns nothing
local timer t=NewTimer()
local data d=data.create(GetSpellAbilityUnit(),t)
local integer i=0
local location l1
local location l2
local integer lvl=GetUnitAbilityLevel(d.caster,SPELL_ID)
call SetTimerData(t,integer(d))
//create lightning
set l1=GetUnitLoc(d.dum)
loop
exitwhen i>LIGHTNING_NUM
set d.missile[i]=CreateUnit(GetOwningPlayer(d.caster),DUMMY_ID, PolarProjectionX(GetUnitX(d.caster),RADIUS(lvl), 360/LIGHTNING_NUM*i), PolarProjectionY(GetUnitY(d.caster), RADIUS(lvl), 360/LIGHTNING_NUM*i), 0.00)
set l2=GetUnitLoc(d.missile[i])
set d.lg[i]=AddLightningEx(LIGHTNING_ID,true,GetUnitX(d.dum),GetUnitY(d.dum),GetLocationZ(l1)+LIGHTNING_HEIGHT,GetUnitX(d.missile[i]),GetUnitY(d.missile[i]),GetLocationZ(l2))
set d.angle[i]=bj_DEGTORAD*360/LIGHTNING_NUM*i
call RemoveLocation(l2)
set i=i+1
endloop