/************************************************************************************************** *
* This spell requires TimerUtils, RegisterPlayerUnitEvent, SpellEffectEvent and IsDestructableTree*
***************************************************************************************************/
scope Kamehameha
globals
private constant integer AID = 'A000' //Set AID = your ability id. To get a spells id go into the objekt editor and press ctrl+d.
private constant real AOE = 200 //How large area around the spell that will take damage.
private constant real OFFSET = 50. //How long infront of the caster the unit will spawn.
private constant integer DUMMY = 'h000' //Set this to the Unit it of your dummy. Press ctrl+d in the objekt editor to find it.
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
private constant real INTERVAL = 0.0312500 //How often the spell will run, this is the same as GUIs Time - Every 0.03 seconds of game time
private constant real DUMMYTIMER = 0.45 //This is for how long the ''line'' will last
private constant boolean DESTROYTREE = true
endglobals
//This is the formula for the damage. You can make your own formula if you want.
private constant function GetDamage takes integer lvl returns real
return 20.*lvl
endfunction
//This is the range of the spell, it will multiply by the speed, check the WARNING below.
private constant function GetRange takes integer lvl returns real
return 200.*lvl
endfunction
//This is how fast the spell will move.
/*********************************************************************
* WARNING!! *
* The speed of the spell changes how long the range of the spell is! *
* If the speed is 20 then is will multiply the range with 2*range. *
**********************************************************************/
private constant function GetSpeed takes integer lvl returns real
return 20. + 0*lvl
endfunction
private function GetTree takes nothing returns nothing
if IsDestructableTree(GetEnumDestructable()) then
call KillTree(GetEnumDestructable())
endif
endfunction
//This checks if a unit is alive so we can deal damage to it or not.
native UnitAlive takes unit id returns boolean
//This is the formula that filters out which units that should take damage.
private function FilterUnits takes unit u, player p returns boolean
return (UnitAlive(u)) and (IsUnitEnemy(u, p)) and (not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE))
endfunction
//DON'T EDIT ANYTHING BELOW
private struct Kamehameha extends array
unit caster
unit dummy
real damage
real angle
player owner
real range
real inRange
real speed
integer lvl
group g
static integer array rn
static integer ic = 0
private static method line takes nothing returns nothing
local timer t = GetExpiredTimer()
local thistype this = GetTimerData(t)
local unit u
local location l = GetUnitLoc(.dummy)
local real x = GetUnitX(.dummy)
local real y = GetUnitY(.dummy)
local unit u2
set .g = CreateGroup()
if UnitAlive(.caster) and .inRange < .range then
//This checks if the DestroyTree globals is true, and if it is then if will destroy all trees withing "aoe" range.
if DESTROYTREE == true then
call EnumDestructablesInCircleBJ( AOE, l, function GetTree)
endif
//Picks all units within "AOE" range and deals damage to them.
call GroupEnumUnitsInRange( .g, x, y, AOE, null)
set u2 = CreateUnit( .owner, DUMMY, x, y, GetUnitFacing(.dummy))
loop
set u = FirstOfGroup(.g)
exitwhen u == null
call GroupRemoveUnit(.g, u)
if FilterUnits(u, .owner) then
call UnitDamageTarget(.caster, u, .damage, false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
endif
endloop
call SetUnitX(.dummy, GetUnitX(.dummy)+.speed*Cos(.angle))
call SetUnitY(.dummy, GetUnitY(.dummy)+.speed*Sin(.angle))
call UnitApplyTimedLife(u2, 'BTLF', DUMMYTIMER)
set u2 = null
set .inRange = .inRange + 10.
else
call ReleaseTimer(t)
call KillUnit(.dummy)
//Deindex the spell
set rn[this] = rn[0]
set rn[0] = this
//Null som of the variables
set caster = null
set owner = null
endif
//Clear the leaks
call RemoveLocation(l)
set l = null
call DestroyGroup(.g)
set u2 = null
set t = null
set u = null
set g = null
endmethod
private static method run takes nothing returns nothing
local thistype this
local integer lvl
local real x = GetUnitX(GetTriggerUnit())
local real y = GetUnitY(GetTriggerUnit())
//Index the spell
set this = rn[0]
if this == 0 then
set ic = ic + 1
set this = ic
else
set rn[0] = rn[this]
endif
set .owner = GetTriggerPlayer()
set .caster = GetTriggerUnit()
set lvl = GetUnitAbilityLevel(.caster, AID)
set .damage = GetDamage(lvl)
set .range = GetRange(lvl)
set .angle = Atan2(GetSpellTargetY()-y,GetSpellTargetX()-x)
set .dummy = CreateUnit(.owner,DUMMY,x + OFFSET*Cos(.angle),y + OFFSET*Sin(.angle),.angle*bj_RADTODEG)
set .inRange = 0
set .speed = GetSpeed(lvl)
call TimerStart(NewTimerEx(this), INTERVAL, true, function thistype.line)
endmethod
private static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent(AID, function thistype.run)
endmethod
endstruct
endscope