library MassSleep initializer init
globals
private constant integer SPELL_ID = 'A000'
private constant integer BUFF_ID = 'B000'
private constant integer DUMMY_ID = 'dumX'
private constant integer DUMMY_SPELL_ID = 'A001'
private constant string ORDER = "starfall"
// Don't change \\
private integer T
private constant real L = 0.04
private constant hashtable H = InitHashtable()
endglobals
private function range takes integer level returns real
return 400. + 100. * level
endfunction
private function duration takes integer level returns real
return 7. + 2. * level
endfunction
// Don't change \\
private struct MassSleep
unit caster = null
real r = 0.
real d = 0.
real t = 0.
private static method GroupActions takes nothing returns boolean
local thistype this = T
local unit f = GetFilterUnit()
local unit u
if GetWidgetLife(f) > 0.405 and IsUnitEnemy(f,GetOwningPlayer(.caster)) and IsUnitType(f,UNIT_TYPE_STRUCTURE) == false and IsUnitType(f,UNIT_TYPE_MAGIC_IMMUNE) == false and GetUnitAbilityLevel(f,BUFF_ID) < 1 then
set u = CreateUnit(GetOwningPlayer(.caster),DUMMY_ID,GetUnitX(f),GetUnitY(f),GetUnitFacing(f))
call UnitAddAbility(u,DUMMY_SPELL_ID)
call SetUnitAbilityLevel(u,DUMMY_SPELL_ID,GetUnitAbilityLevel(.caster,SPELL_ID))
call IssueTargetOrder(u,"sleep",f)
endif
set f = null
set u = null
return false
endmethod
private static method GroupEnd takes nothing returns boolean
local thistype this = T
local unit f = GetFilterUnit()
if GetUnitAbilityLevel(f,BUFF_ID) > 0 then
call UnitRemoveAbility(f,BUFF_ID)
endif
set f = null
return false
endmethod
private static method Loop takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer this = LoadInteger(H,GetHandleId(t),0)
local group g = CreateGroup()
if GetUnitCurrentOrder(GetTriggerUnit()) == S2I(ORDER) then
set .t = .t + L
if .t <= .d then
set T = this
call GroupEnumUnitsInRange(g,GetUnitX(.caster),GetUnitY(.caster),.r,Condition(function MassSleep.GroupActions))
else
set T = this
call GroupEnumUnitsInRange(g,GetUnitX(.caster),GetUnitY(.caster),.r,Condition(function MassSleep.GroupEnd))
call PauseTimer(t)
call DestroyTimer(t)
call .destroy()
endif
else
set T = this
call GroupEnumUnitsInRange(g,GetUnitX(.caster),GetUnitY(.caster),.r,Condition(function MassSleep.GroupEnd))
call PauseTimer(t)
call DestroyTimer(t)
call .destroy()
endif
call DestroyGroup(g)
set t = null
endmethod
static method create takes unit caster returns thistype
local thistype this = .allocate()
local timer t = CreateTimer()
local group g = CreateGroup()
set .caster = caster
set .r = range(GetUnitAbilityLevel(.caster,SPELL_ID))
set .d = duration(GetUnitAbilityLevel(.caster,SPELL_ID))
set T = this
call GroupEnumUnitsInRange(g,GetUnitX(.caster),GetUnitY(.caster),.r,Condition(function MassSleep.GroupActions))
call SaveInteger(H,GetHandleId(t),0,this)
call TimerStart(t,L,true,function MassSleep.Loop)
set t = null
call DestroyGroup(g)
return this
endmethod
endstruct
private function cast takes nothing returns boolean
if GetSpellAbilityId() == SPELL_ID then
call MassSleep.create(GetTriggerUnit())
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger t = CreateTrigger()
local integer i = 0
loop
exitwhen i == 15
call TriggerRegisterPlayerUnitEvent(t,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
set i = i + 1
endloop
call TriggerAddCondition(t,Condition(function cast))
set t = null
endfunction
endlibrary