scope Epicenter initializer Init
globals
private constant real damage = 85.
private constant real SmallDamageRange = 375.
private constant real MediumDamageRange = 488.
private constant real LargeDamageRange = 600.
private constant integer ABILITY_CAST = 'A02Z'
endglobals
private function cond takes nothing returns boolean
return GetSpellAbilityId() == ABILITY_CAST
endfunction
private struct cache
unit caster
integer Index
group g
endstruct
private function TargetFilter takes unit caster, unit target returns boolean
return IsUnitEnemy(target, GetOwningPlayer(caster))
endfunction
private function GetF takes nothing returns boolean
local unit u = GetFilterUnit()
if not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitType(u, UNIT_TYPE_DEAD) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and not IsUnitType(u, UNIT_TYPE_MECHANICAL) then
set u = null
return true
endif
set u = null
return false
endfunction
private function GetDistanceDamage takes unit caster, real X1, real Y1, real X2, real Y2, unit e returns nothing
local unit u = CreateUnit(GetOwningPlayer(caster), Dummy, X1, Y1, bj_UNIT_FACING)
call UnitAddAbility(u, 'A03Z')
call IssueTargetOrder(u, "slow", e)
call UnitApplyTimedLife(u, 'BTLF', 0.2)
if ( DistanceBetweenXY(X1, Y1, X2, Y2) <= SmallDamageRange ) then
call MakeDamageMagic(caster, e, damage + 20.) //105
return
endif
if ( DistanceBetweenXY(X1, Y1, X2, Y2) <= MediumDamageRange ) then
call MakeDamageMagic(caster, e, damage + 10.) //95
return
endif
if ( DistanceBetweenXY(X1, Y1, X2, Y2) <= LargeDamageRange ) then
call MakeDamageMagic(caster, e, damage) //85
return
endif
endfunction
private function Loop takes nothing returns nothing
local cache data = GetTimerData(GetExpiredTimer())
local unit e = null
set data.Index = data.Index - 1
set TempX = GetUnitX(data.caster)
set TempY = GetUnitY(data.caster)
call DestroyEffect(AddSpecialEffect("Epicenter.mdx", TempX, TempY))
call TerrainDeformCrater(TempX, TempY, LargeDamageRange - 40., 28., 500, false)
call GroupEnumUnitsInArea(data.g, TempX, TempY, LargeDamageRange, Condition(function GetF))
loop
set e = FirstOfGroup(data.g)
exitwhen null == e
call GroupRemoveUnit(data.g, e)
if TargetFilter(data.caster, e) == true then
set TempX2 = GetUnitX(e)
set TempY2 = GetUnitY(e)
call GetDistanceDamage(data.caster, TempX, TempY, TempX2, TempY2, e)
endif
endloop
call GroupRefresh(data.g)
if data.Index == 0 then
call ReleaseTimer(GetExpiredTimer())
call ReleaseGroup(data.g)
set e = null
set data.caster = null
call data.destroy()
endif
endfunction
private function f takes nothing returns nothing
local cache data = cache.create()
local unit u = GetTriggerUnit()
local timer t = NewTimer()
set data.g = NewGroup()
set data.Index = (4 + (2 * GetUnitAbilityLevel(u, GetSpellAbilityId()) ) )
set data.caster = u
call SetTimerData(t, data)
call TimerStart(t, 0.3, true, function Loop )
set u = null
set t = null
endfunction
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call AddEvent(t, EVENT_PLAYER_UNIT_SPELL_FINISH )
call TriggerAddCondition(t, Condition( function cond ) )
call TriggerAddAction(t, function f )
endfunction
endscope