library BW requires TimerUtils
globals
private constant integer SPELL_ID = 'A001' //the rawcode of the spell
private constant integer DUMMY_ID = 'h000' //rw of the dummy unit my omnidummy is used in all my spells :)
private constant string AOE_EFFECT = "Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl" //effect that will be created when we cast the spell on the AOE
private constant string AOE2_EFFECT = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl" //another thing used to make this spell cool
private constant damagetype D_TYPE = DAMAGE_TYPE_FIRE //the attack type of the spell
private constant attacktype A_TYPE = ATTACK_TYPE_MAGIC //the damage type of the spell
private constant string RAY_ID1 = "FORK" //The rw of ligthing used for the waves
private constant real RAY_R1 = 0.75 //Red color of the ray
private constant real RAY_G1 = 0.5 //Green color
private constant real RAY_B1 = 0.0 //blue color
private constant real RAY_A1 = 1.0 //Alpha of color 1=no transparency 0=FULL transparency
private constant string RAY_ID2 = "FORK" //The rw of ligthing used for the waves
private constant real RAY_R2 = 1.0 //Red color of the ray
private constant real RAY_G2 = 0.2 //Green color
private constant real RAY_B2 = 0.05 //blue color
private constant real RAY_A2 = 1.0 //Alpha of color 1=no transparency 0=FULL transparency
private constant real Spellaoe = 150 //not sugested to be more than 200 for balance things but whatever
endglobals
private function Range takes integer level returns real
//Real range betwen waves
return 150.
endfunction
private function Waves takes integer level returns real
//Number of waves per level
return level * 2. //3 waves are from default to evade the spell was too long of too short
endfunction
private function Delay takes integer level returns real
//delay in seconds betwen waves CANT be les than 0.1 ¬¬ why not Blizzard?????
//this also affect true sigtht
return 0.1
endfunction
private function Damage takes integer level returns real
//The damage enemies will take
return level * 25.
endfunction
private struct Spell extends array
private static integer instanceCount = 0
private static thistype recycle = 0
private thistype recycleNext
private unit caster
private real facing
private integer level
private integer exit
private lightning l1
private lightning l2
private method destroy takes nothing returns nothing
set this.caster = null
set this.l1 = null
set this.l2 = null
set recycleNext = recycle
set recycle = this
endmethod
private static method periodic takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local real waveX
local real waveY
local real distance
call DestroyLightning(this.l1)
call DestroyLightning(this.l2)
if this.exit == Waves(this.level) + 3 then
call this.destroy()
call ReleaseTimer(GetExpiredTimer())
else
set this.exit = this.exit + 1
set distance = Range(this.level) * (this.exit + 1.50)
set waveX = GetUnitX(this.caster) + distance * Cos(this.facing * bj_DEGTORAD)
set waveY = GetUnitY(this.caster) + distance * Sin(this.facing * bj_DEGTORAD)
set this.l1 = AddLightning(RAY_ID1, true, GetUnitX(this.caster), GetUnitY(this.caster), waveX, waveY)
set this.l2 = AddLightning(RAY_ID2, true, GetUnitX(this.caster), GetUnitY(this.caster), waveX, waveY)
call DestroyEffect(AddSpecialEffect(AOE_EFFECT, waveX, waveY))
call DestroyEffect(AddSpecialEffect(AOE2_EFFECT, waveX, waveY))
call SetLightningColor(this.l1, RAY_R1, RAY_G1, RAY_B1, RAY_A1)
call SetLightningColor(this.l2, RAY_R2, RAY_G2, RAY_B2, RAY_A2)
call UnitDamagePoint(this.caster, Delay(level), Spellaoe, waveX, waveY, Damage(this.level), false, false, A_TYPE, D_TYPE, null)
endif
endmethod
private static method create takes nothing returns thistype
local thistype this
local timer t = NewTimer()
if (recycle == 0) then
set instanceCount = instanceCount + 1
set this = instanceCount
else
set this = recycle
set recycle = recycle.recycleNext
endif
set this.caster = GetTriggerUnit()
set this.facing = GetUnitFacing(this.caster)
set this.level = GetUnitAbilityLevel(this.caster, SPELL_ID)
set this.exit = 0
call SetTimerData(t, this)
call TimerStart(t, Delay(this.level), true, function thistype.periodic)
set t = null
return this
endmethod
private static method condition takes nothing returns boolean
if GetSpellAbilityId() == SPELL_ID then
call thistype.create()
endif
return false
endmethod
private static method onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition(t, Condition(function thistype.condition))
call Preload(AOE_EFFECT)
call Preload(AOE2_EFFECT)
set bj_lastCreatedUnit = CreateUnit(Player(15), DUMMY_ID, 0, 0, 0)
call UnitAddAbility(bj_lastCreatedUnit, SPELL_ID)
call KillUnit(bj_lastCreatedUnit)
endmethod
endstruct
endlibrary