scope Armageddon initializer Init
globals
private constant integer ABILITY_ID = 'A003'
private constant real AREA_OF_EFFECT = 600
private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
private constant real DAMAGE = 30
private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_FIRE
private constant integer DUMMY_ID = 'h001'
private constant real DURATION = 8
private constant string EFFECT = "Abilities\\Spells\\Demon\\RainOfFire\\RainOfFireTarget.mdl"
private constant real IMPACT_DELAY = 1
private constant real RADIUS = 80
private constant real TIMEOUT = 0.15
private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
endglobals
globals
private player ENUM_PLAYER
private boolexpr FILTER
private group GROUP
private hashtable TABLE
endglobals
private function Targets_Allowed takes nothing returns boolean
local unit filterUnit = GetFilterUnit( )
if GetUnitState( filterUnit, UNIT_STATE_LIFE ) > 0.405 and IsUnitEnemy( filterUnit, ENUM_PLAYER ) and not IsUnitType( filterUnit, UNIT_TYPE_FLYING ) then
set filterUnit = null
return true
endif
set filterUnit = null
return false
endfunction
private function Damage_Loop takes nothing returns nothing
local timer t = GetExpiredTimer( )
local integer parentKey = GetHandleId(t)
local unit target
set ENUM_PLAYER = LoadPlayerHandle( TABLE, parentKey, StringHash( "id" ) )
set bj_lastCreatedUnit = CreateUnit( ENUM_PLAYER, DUMMY_ID, 0, -256, 0 )
call GroupEnumUnitsInRange( GROUP, LoadReal( TABLE, parentKey, StringHash( "x" ) ), LoadReal( TABLE, parentKey, StringHash( "y" ) ), RADIUS, FILTER )
loop
set target = FirstOfGroup( GROUP )
exitwhen target == null
call UnitDamageTarget( bj_lastCreatedUnit, target, DAMAGE, false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE )
call GroupRemoveUnit( GROUP, target )
endloop
call DestroyTimer( t )
set t = null
set target = null
call RemoveUnit( bj_lastCreatedUnit )
call FlushChildHashtable( TABLE, parentKey )
endfunction
private function Damage takes unit caster returns nothing
local timer t = CreateTimer( )
local integer parentKey = GetHandleId( t )
local real offset = GetRandomReal( 100, AREA_OF_EFFECT )
local real angle = GetRandomReal( 0, 360 ) * bj_PI / 180
local real x = GetUnitX( caster ) + offset * Cos( angle )
local real y = GetUnitY( caster ) + offset * Sin( angle )
call DestroyEffect( AddSpecialEffect( EFFECT, x, y ) )
call SavePlayerHandle( TABLE, parentKey, StringHash( "id" ), GetOwningPlayer( caster ) )
call SaveReal( TABLE, parentKey, StringHash( "x" ), x )
call SaveReal( TABLE, parentKey, StringHash( "y" ), y )
call TimerStart( t, IMPACT_DELAY, false, function Damage_Loop )
set t = null
endfunction
private function Loop takes nothing returns nothing
local timer t = GetExpiredTimer( )
local integer parentKey = GetHandleId( t )
local unit caster = LoadUnitHandle( TABLE, parentKey, StringHash( "caster" ) )
local real duration = LoadReal( TABLE, parentKey, StringHash( "duration" ) ) - TIMEOUT
if GetWidgetLife( caster ) > 0.405 and duration > 0 then
call Damage( caster )
call SaveReal( TABLE, parentKey, StringHash( "duration" ), duration )
else
call PauseTimer( t )
call DestroyTimer( t )
call FlushChildHashtable( TABLE, parentKey )
endif
set t = null
set caster = null
endfunction
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == ABILITY_ID and DURATION > 0
endfunction
private function Actions takes nothing returns nothing
local timer t = CreateTimer( )
local integer parentKey = GetHandleId( t )
local unit caster = GetTriggerUnit( )
call SaveUnitHandle( TABLE, parentKey, StringHash( "caster" ), caster )
call SavePlayerHandle( TABLE, parentKey, StringHash( "id" ), GetOwningPlayer( caster ) )
call SaveReal( TABLE, parentKey, StringHash( "duration" ), DURATION )
call TimerStart( t, TIMEOUT, true, function Loop )
set t = null
set caster = null
endfunction
private constant function True takes nothing returns boolean
return true
endfunction
private function Init takes nothing returns nothing
local trigger trg = CreateTrigger( )
local boolexpr filter = Filter( function True )
set bj_forLoopAIndex = 0
loop
call TriggerRegisterPlayerUnitEvent( trg, Player( bj_forLoopAIndex ), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
set bj_forLoopAIndex = bj_forLoopAIndex + 1
exitwhen bj_forLoopAIndex == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition( trg, Condition( function Conditions ) )
call TriggerAddAction( trg, function Actions )
// globals
set FILTER = Condition( function Targets_Allowed )
set GROUP = CreateGroup( )
set TABLE = InitHashtable( )
// endglobals
// preload
call Preload( EFFECT )
call PreloadStart( )
// endpreload
set trg = null
call DestroyBoolExpr( filter )
set filter = null
endfunction
endscope