library SpeedChange
globals
private hashtable Table = InitHashtable()
private hashtable SpeedTable = InitHashtable()
constant real MinMoveSpeed = 1.00
endglobals
private function GetActualEndSpeed takes real init, real modif returns real
local real result = init * modif
if result < MinMoveSpeed then
return MinMoveSpeed
endif
return result
endfunction
private function GetActualEndSpeedLinear takes real def, real init, real modif returns real
local real result = init - def*(1-modif)
if result < MinMoveSpeed then
return MinMoveSpeed
endif
return result
endfunction
private function OnExpire2 takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local integer buff_ab = LoadInteger(Table, id, 'babi')
local unit u = LoadUnitHandle(Table, id, 'unit')
local integer id2 = GetHandleId(u)
local real current_speed = LoadReal( SpeedTable , id2 , 0 )
local real speed_change = LoadReal( SpeedTable , id2 , buff_ab )
local integer temp_int = LoadInteger( SpeedTable , id2 , 1 )
call SetUnitMoveSpeed( u , current_speed * speed_change )
call RemoveSavedReal( SpeedTable, id2, buff_ab )
call UnitRemoveAbility( u , buff_ab )
call RemoveSavedHandle(Table, id2, buff_ab)
call FlushChildHashtable(Table, id)
call DestroyTimer(t)
if temp_int == 1 then
call FlushChildHashtable( SpeedTable , id2 )
else
call SaveReal( SpeedTable , id2 , 0 , current_speed * speed_change )
call SaveInteger( SpeedTable , id2 , 1 , temp_int - 1 )
endif
set t = null
set u = null
endfunction
function ChangeUnitSpeed2 takes unit u, real speed_modifier, real duration, boolean linear, integer buff_ability, boolean building_up returns nothing
local timer t = LoadTimerHandle(Table, GetHandleId(u), buff_ability)
local integer id
local integer id2 = GetHandleId(u)
local real time
local real init_speed = LoadReal( SpeedTable, id2, 0 )
local real end_speed
local integer temp_int = LoadInteger( SpeedTable, id2, 1 ) + 1
if init_speed == 0 then
set init_speed = GetUnitDefaultMoveSpeed(u)
endif
if t != null then
set id = GetHandleId(t)
set time = TimerGetRemaining(t) + duration
else
set t = CreateTimer()
set id = GetHandleId(t)
call SaveTimerHandle(Table, id2, buff_ability, t )
set time = duration
endif
if time == duration then
if linear then
set end_speed = GetActualEndSpeedLinear( GetUnitDefaultMoveSpeed(u), init_speed, speed_modifier )
else
set end_speed = GetActualEndSpeed(init_speed, speed_modifier)
endif
call SetUnitMoveSpeed( u , end_speed )
call SaveUnitHandle(Table, id, 'unit', u )
call SaveReal( SpeedTable, id2, 0, end_speed )
call SaveInteger( SpeedTable, id2, 1, temp_int)
call SaveReal( SpeedTable, id2, buff_ability, init_speed / end_speed)
call UnitAddAbility( u , buff_ability )
call SaveInteger(Table, id, 'babi', buff_ability )
endif
if building_up then
call TimerStart( t, time, false, function OnExpire2 )
else
call TimerStart( t, duration, true, function OnExpire2 )
endif
set t = null
set u = null
endfunction
endlibrary
function SF_Fall takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit c = LoadUnitHandle( udg_Table, id, 'unit' )
local player p = GetOwningPlayer(c)
local real x = LoadReal( udg_Table, id, 'casx' )
local real y = LoadReal( udg_Table, id, 'casy' )
local group g = CreateGroup()
local unit u
call GroupEnumUnitsInRange( g, x, y, 500.00, null )
loop
set u = FirstOfGroup(g)
exitwhen u == null
if IsUnitEnemy( u, p ) then
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\NightElf\\Starfall\\StarfallTarget.mdl", u, "origin"))
call UnitDamageTarget( c, u, 2*GetHeroInt(c, true) , true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
call ChangeUnitSpeed2( u, 0.5, 3, true, 'A001', false )
endif
call GroupRemoveUnit(g, u)
endloop
call DestroyGroup(g)
set g = null
set c = null
set p = null
set t = null
endfunction
function Trig_Starfall_Conditions takes nothing returns boolean
local unit u
local real x
local real y
local timer t
local integer id
if GetSpellAbilityId() == 'A000' then // 'A000' is the ID of your starfall
set u = GetTriggerUnit()
set t = CreateTimer()
set x = GetUnitX(u)
set y = GetUnitY(u)
set id = GetHandleId(t)
call SaveUnitHandle( udg_Table, id, 'unit', u )
call SaveReal( udg_Table, id, 'casx', x )
call SaveReal( udg_Table, id, 'casy', y )
call SaveTimerHandle( udg_Table, GetHandleId(u), 'time', t )
call TimerStart( t, 1.5, true, function SF_Fall )
set u = null
set t = null
endif
return false
endfunction
function SF_End takes nothing returns boolean
local unit u
local timer t
if GetSpellAbilityId() == 'A000' then
set u = GetTriggerUnit()
set t = LoadTimerHandle(udg_Table, GetHandleId(u), 'time')
call FlushChildHashtable(udg_Table, GetHandleId(t))
call DestroyTimer(t)
set t = null
call FlushChildHashtable(udg_Table, GetHandleId(u))
set u = null
endif
return false
endfunction
//===========================================================================
function InitTrig_Starfall takes nothing returns nothing
local trigger t = CreateTrigger()
set gg_trg_Starfall = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Starfall, EVENT_PLAYER_UNIT_SPELL_CHANNEL )
call TriggerAddCondition( gg_trg_Starfall, Condition( function Trig_Starfall_Conditions ) )
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_ENDCAST )
call TriggerAddCondition( t, Condition(function SF_End))
set t = null
endfunction