//================= CUSTOM SCRIPT FUNCTIONS =================
function RapidStrike_AddSpecialEffectTimed_Timer takes nothing returns nothing
local timer t = GetExpiredTimer()
local effect e = LoadEffectHandle(udg_RapidStrike_Hash,GetHandleId(t),0)
call DestroyEffect(e)
call FlushChildHashtable(udg_RapidStrike_Hash,GetHandleId(t))
call DestroyTimer(t)
set e = null
set t = null
endfunction
function RapidStrike_AddSpecialEffectTimed takes string modelName, real x, real y, real time returns nothing
local timer t = CreateTimer()
call SaveEffectHandle(udg_RapidStrike_Hash,GetHandleId(t),0,AddSpecialEffect(modelName,x,y))
call TimerStart(t,time,false,function RapidStrike_AddSpecialEffectTimed_Timer)
set t = null
endfunction
function RapidStrike_IsUnitMatching takes unit whichUnit, unit caster returns boolean
return IsUnitEnemy(whichUnit,GetOwningPlayer(caster)) and not IsUnitPaused(whichUnit) and not IsUnitType(whichUnit,UNIT_TYPE_DEAD) and not IsUnitType(whichUnit,UNIT_TYPE_STRUCTURE) and not IsUnitType(whichUnit,UNIT_TYPE_MAGIC_IMMUNE)
endfunction
//================= SPELL CONSTANTS =================
constant function RapidStrike_AbilId takes nothing returns integer
// 'Deadly Strike' ability rawcode.
return 'A000'
endfunction
constant function RapidStrike_DummyId takes nothing returns integer
// Dummy rawcode.
return 'n000'
endfunction
constant function RapidStrike_SoulId takes nothing returns integer
// Soul rawcode.
return 'n001'
endfunction
constant function RapidStrike_DummyAbilId takes nothing returns integer
// Dummy cast ability rawcode.
return 'A001'
endfunction
constant function RapidStrike_EffInt1 takes nothing returns real
// Interval between ray effects spawn.
return .6
endfunction
constant function RapidStrike_EffInt2 takes nothing returns real
// Interval between thunderclap effects spawn.
return .3
endfunction
constant function RapidStrike_EffDist takes nothing returns real
// Offset from hero to effect spawns.
return 250.
endfunction
constant function RapidStrike_MaxHeight takes nothing returns real
// Maximal height that unit reaches when casting.
return 280.
endfunction
constant function RapidStrike_StartAng takes nothing returns real
// Starting angle for spawning the effects.
return 90.
endfunction
constant function RapidStrike_PickRadius takes nothing returns real
// Radius where units'll be picked and tossed up to the sky.
return 340.
endfunction
constant function RapidStrike_SoulHeight takes nothing returns real
// Maximal height that soul reaches when casting.
return 420.
endfunction
constant function RapidStrike_RayEffPath takes nothing returns string
// Black rays effect path.
return "war3mapImported\\unholyStrikeX20c.mdx"
endfunction
constant function RapidStrike_StompEffPath takes nothing returns string
// Stomp effect path.
return "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"
endfunction
constant function RapidStrike_TCEffPath takes nothing returns string
// Thunderclap effect path.
return "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
endfunction
//================= SPELL FUNCTIONS =================
function Trig_RapidStrike_Conditions takes nothing returns boolean
return GetSpellAbilityId() == RapidStrike_AbilId()
endfunction
function Trig_RapidStrike_FlyDown takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit u = LoadUnitHandle(udg_RapidStrike_Hash,id,0)
local unit gu = LoadUnitHandle(udg_RapidStrike_Hash,id,1)
local unit d = CreateUnit(GetOwningPlayer(u),RapidStrike_DummyId(),GetUnitX(u),GetUnitY(u),0.)
call UnitAddAbility(d,RapidStrike_DummyAbilId())
call SetUnitAbilityLevel(d,RapidStrike_DummyAbilId(),GetUnitAbilityLevel(u,RapidStrike_AbilId()))
call IssueTargetOrderById(d,852095,gu)
call UnitApplyTimedLife(d,'BTLF',.75)
call SetUnitFlyHeight(gu,0.,RapidStrike_MaxHeight()/.3)
call FlushChildHashtable(udg_RapidStrike_Hash,id)
call DestroyTimer(t)
set t = null
set u = null
set gu = null
set d = null
endfunction
function Trig_RapidStrike_EffTimer takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit u = LoadUnitHandle(udg_RapidStrike_Hash,id,0)
local unit soul = LoadUnitHandle(udg_RapidStrike_Hash,id,5)
local real ux = GetUnitX(u)
local real uy = GetUnitY(u)
local real a = LoadReal(udg_RapidStrike_Hash,id,4)
local real x = ux + RapidStrike_EffDist() * Cos(a*.0174532)
local real y = uy + RapidStrike_EffDist() * Sin(a*.0174532)
local boolean b = LoadBoolean(udg_RapidStrike_Hash,id,2)
local unit gu
local timer gt
local integer gtid
if not b then
if a >= RapidStrike_StartAng() + 360. then
call SaveBoolean(udg_RapidStrike_Hash,id,2,true)
call SetUnitAnimation(u,"stand")
call DestroyEffect(AddSpecialEffect(RapidStrike_StompEffPath(),ux,uy))
call RemoveUnit(soul)
call SaveReal(udg_RapidStrike_Hash,GetHandleId(t),4,RapidStrike_StartAng())
call TimerStart(t,RapidStrike_EffInt2(),true,function Trig_RapidStrike_EffTimer)
else
if a >= RapidStrike_StartAng() + 180. then
call SetUnitFlyHeight(u,0.,RapidStrike_MaxHeight()/(RapidStrike_EffInt1()*2.))
call SetUnitFlyHeight(soul,0.,RapidStrike_SoulHeight()/(RapidStrike_EffInt1()*2.))
endif
call RapidStrike_AddSpecialEffectTimed(RapidStrike_RayEffPath(),x,y,1.5)
call SaveReal(udg_RapidStrike_Hash,id,4,a+90.)
endif
else
if a >= RapidStrike_StartAng() + 360. then
call SetUnitInvulnerable(u,false)
call PauseUnit(u,false)
call FlushChildHashtable(udg_RapidStrike_Hash,id)
call PauseTimer(t)
call DestroyTimer(t)
else
call SaveEffectHandle(udg_RapidStrike_Hash,id,1,AddSpecialEffect(RapidStrike_TCEffPath(),x,y))
call GroupEnumUnitsInRange(bj_lastCreatedGroup,x,y,RapidStrike_PickRadius(),null)
loop
set gu = FirstOfGroup(bj_lastCreatedGroup)
exitwhen gu == null
if not LoadBoolean(udg_RapidStrike_Hash,id,GetHandleId(gu)) and RapidStrike_IsUnitMatching(gu,u) then
call SaveBoolean(udg_RapidStrike_Hash,id,GetHandleId(gu),true)
if UnitAddAbility(gu,'Arav') then
call UnitRemoveAbility(gu,'Arav')
endif
call SetUnitFlyHeight(gu,RapidStrike_MaxHeight(),RapidStrike_MaxHeight()/.3)
set gt = CreateTimer()
set gtid = GetHandleId(gt)
call SaveUnitHandle(udg_RapidStrike_Hash,gtid,0,u)
call SaveUnitHandle(udg_RapidStrike_Hash,gtid,1,gu)
call TimerStart(gt,.2,false,function Trig_RapidStrike_FlyDown)
set gt = null
endif
call GroupRemoveUnit(bj_lastCreatedGroup,gu)
endloop
call SaveReal(udg_RapidStrike_Hash,id,4,a+90.)
endif
endif
set soul = null
set t = null
set u = null
endfunction
function Trig_RapidStrike_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local timer t = CreateTimer()
local integer id = GetHandleId(t)
local unit soul = CreateUnit(GetOwningPlayer(u),RapidStrike_SoulId(),GetWidgetX(u),GetWidgetY(u),GetUnitFacing(u))
call SetUnitPathing(soul,false)
call SetUnitX(soul,GetWidgetX(u))
call SetUnitY(soul,GetWidgetY(u))
call SetUnitVertexColor(soul,50,100,200,100)
call SaveUnitHandle(udg_RapidStrike_Hash,id,0,u)
call SaveBoolean(udg_RapidStrike_Hash,id,2,false)
call SaveReal(udg_RapidStrike_Hash,id,4,RapidStrike_StartAng())
call SaveUnitHandle(udg_RapidStrike_Hash,id,5,soul)
if UnitAddAbility(u,'Amrf') then
call UnitRemoveAbility(u,'Amrf')
endif
call PauseUnit(u,true)
call SetUnitInvulnerable(u,true)
call SetUnitAnimation(u,"spell channel")
call SetUnitAnimation(soul,"spell channel")
call SetUnitFlyHeight(u,RapidStrike_MaxHeight(),RapidStrike_MaxHeight()/(RapidStrike_EffInt1()*2.))
call SetUnitFlyHeight(soul,RapidStrike_SoulHeight(),RapidStrike_SoulHeight()/(RapidStrike_EffInt1()*2.))
call TimerStart(t,RapidStrike_EffInt1(),true,function Trig_RapidStrike_EffTimer)
set soul = null
set t = null
set u = null
endfunction
//===========================================================================
function InitTrig_DeadlyStrike takes nothing returns nothing
set udg_RapidStrike_Hash = InitHashtable()
set gg_trg_DeadlyStrike = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(gg_trg_DeadlyStrike,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(gg_trg_DeadlyStrike,Condition(function Trig_RapidStrike_Conditions))
call TriggerAddAction(gg_trg_DeadlyStrike,function Trig_RapidStrike_Actions)
endfunction