struct kb //knock back
unit u
real angle
real speed
real friction
endstruct
globals
group OB_hit=CreateGroup() //to prevent multiple knockbacks.
endglobals
constant function OB_Id takes nothing returns integer
return 'A0KU'
endfunction
constant function OB_UnitId takes nothing returns integer
return 'hpea'
endfunction
constant function OB_TimerSpeed takes nothing returns real
return 0.035
endfunction
constant function OB_FallSpeed takes nothing returns real
return 1600.00*OB_TimerSpeed() // how fast the bombs fall
endfunction
constant function OB_StartEffectScale takes real level returns real
return 4.00
endfunction
constant function OB_Height takes nothing returns real
return 1200.00 //starting height of the bombs
endfunction
constant function OB_Radius takes real l returns real
return 500.00 //the radius at where the bombs are dropped
endfunction
constant function OB_StartEffect takes nothing returns string
return "Abilities\\Spells\\NightElf\\TrueshotAura\\TrueshotAura.mdl" //the effect that comes whenever the spell is cast
endfunction
constant function OB_DamageRadius takes real l returns real
return 230.00 //radius of the bombs when they explode
endfunction
constant function OB_BombInterval takes real l returns real
return 0.20 //interval between bombs being dropped
endfunction
constant function OB_WaveInterval takes real l returns real
return 1.20 //interval between waves
endfunction
constant function OB_StartInterval takes real l returns real
return 4.00 //waiting time before bombing starts
endfunction
constant function OB_Damage takes real l returns real
return 150*l //damage from each bomb
endfunction
constant function OB_Scale takes real l returns real
return 1.60 //size of the bombs
endfunction
constant function OB_KnockBackSpeed takes real l returns real
return 700.00 //distance knocked back per sec
endfunction
constant function OB_KnockBackFriction takes real l returns real
return 600.00 //knockback decreasing each second
endfunction
constant function OB_Model takes nothing returns string
return "Abilities\\Weapons\\GyroCopter\\GyroCopterMissile.mdl" //bomb model
endfunction
constant function OB_Explosion takes nothing returns string
return "Abilities\\Weapons\\CannonTowerMissile\\CannonTowerMissile.mdl"//explosion model
endfunction
constant function OB_KnockbackEffect takes nothing returns string
return "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" //the effect on units hit
endfunction
constant function OB_Knockback_AP takes nothing returns string
return "origin" //attachment point for knockback effect
endfunction
//==================================================================
function ProjectX takes real x, real dist, real angle returns real
return x+dist*Cos(angle*0.01745)
endfunction
function ProjectY takes real y, real dist, real angle returns real
return y+dist*Sin(angle*0.01745)
endfunction
function GetAngleBetweenPoints takes real x1, real y1, real x2, real y2 returns real
return 57.29582 * Atan2(y2-y1, x2-x1)
endfunction
function TimedWait takes real duration returns nothing
local timer t
local real timeRemaining
if (duration > 0) then
set t = NewTimer()
call TimerStart(t, duration, false, null)
loop
set timeRemaining = TimerGetRemaining(t)
exitwhen timeRemaining <= 0
// If we have a bit of time left, skip past 10% of the remaining
// duration instead of checking every interval, to minimize the
// polling on long waits.
if (timeRemaining > 2.00) then
call TriggerSleepAction(0.1 * timeRemaining)
else
call TriggerSleepAction(0.10)
endif
endloop
call ReleaseTimer(t)
endif
endfunction
function OB_Filter takes nothing returns boolean
return IsUnitType(GetFilterUnit(),UNIT_TYPE_GROUND)
endfunction
function AddSpecialEffectTargetForPlayer takes string path, widget target,string ap , player p returns effect
local string model = ""
if ( GetLocalPlayer() == p ) then
set model = path
endif
return AddSpecialEffectTarget( model, target, ap)
endfunction
function OB_KnockBackfunc takes nothing returns nothing
local timer t=GetExpiredTimer()
local kb k=GetCSData(t)
if k.speed <= 0 then
call GroupRemoveUnit(OB_hit,k.u)
call kb.destroy(k)
call ReleaseTimer(t)
else
call DestroyEffect(AddSpecialEffectTarget(OB_KnockbackEffect(),k.u,OB_Knockback_AP()))
call SetUnitX(k.u,ProjectX(GetUnitX(k.u),k.speed*OB_TimerSpeed(),k.angle))
call SetUnitY(k.u,ProjectY(GetUnitY(k.u),k.speed*OB_TimerSpeed(),k.angle))
set k.speed=k.speed-k.friction*OB_TimerSpeed()
endif
endfunction
function OB_KnockBack takes unit u,real speed,real angle,real friction returns nothing
local timer t=NewTimer()
local kb k=kb.create()
if IsUnitInGroup(u,OB_hit) == false then
set k.u=u
set k.speed=speed
set k.angle=angle
set k.friction=friction
call SetCSData(t,k)
call GroupAddUnit(OB_hit,u)
call TimerStart(t,OB_TimerSpeed(),true,function OB_KnockBackfunc)
endif
endfunction
function OB_Bombs takes nothing returns nothing
local timer t=GetExpiredTimer()
local unit u=I2U(GetCSData(t))
local group g
local integer i=0
local unit eu
local integer l=GetUnitUserData(u)
call SetUnitFlyHeight(u,GetUnitFlyHeight(u)-OB_FallSpeed(),0)
if GetUnitFlyHeight(u) <= 1 then
set g=CreateGroup()
call DestroyEffect(I2Effect(GetCSData(u)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u),GetUnitY(u)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,330),ProjectY(GetUnitY(u),100,330)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,300),ProjectY(GetUnitY(u),100,300)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,240),ProjectY(GetUnitY(u),100,240)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,210),ProjectY(GetUnitY(u),100,210)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,150),ProjectY(GetUnitY(u),100,150)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,120),ProjectY(GetUnitY(u),100,120)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,60),ProjectY(GetUnitY(u),100,60)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,30),ProjectY(GetUnitY(u),100,30)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u),GetUnitY(u)+100))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u),GetUnitY(u)-100))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u)+100,GetUnitY(u)))
call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u)-100,GetUnitY(u)))
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),OB_DamageRadius(0),Condition(function OB_Filter))
loop
set eu=FirstOfGroup(g)
exitwhen eu==null
if GetWidgetLife(eu) > 0.405 then
call UnitDamageTarget(u,eu,OB_Damage(l),false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_DEMOLITION,null)
call OB_KnockBack(eu,OB_KnockBackSpeed(l),GetAngleBetweenPoints(GetUnitX(u),GetUnitY(u),GetUnitX(eu),GetUnitY(eu)),OB_KnockBackFriction(l))
endif
call GroupRemoveUnit(g,eu)
endloop
call ReleaseTimer(t)
call RemoveUnit(u)
call DestroyGroup(g)
set u=null
set g=null
set eu=null
endif
endfunction
function OB_CreateBomb takes player p, integer l, real x, real y returns nothing
local unit u
local timer t=NewTimer()
set u=CreateUnit(p,OB_UnitId(),GetRandomReal(x-OB_Radius(l),x+OB_Radius(l)),GetRandomReal(y-OB_Radius(l),y+OB_Radius(l)),270.00)
call SetUnitFlyHeight(u,OB_Height(),0)
call SetUnitScale(u,OB_Scale(l),OB_Scale(l),OB_Scale(l))
call SetUnitTimeScale(u,0)
call SetCSData(t,H2I(u))
call SetCSData(u,H2I(AddSpecialEffectTarget(OB_Model(),u,"origin")))
call SetUnitUserData(u,l)
call SetUnitAnimationByIndex(u,0)
call UnitAddAbility(u,'Arav')
call UnitRemoveAbility(u,'Arav')
call SetUnitFlyHeight(u,OB_Height(),0)
call TimerStart(t,OB_TimerSpeed(),true,function OB_Bombs)
set u=null
endfunction
function OB_Actions takes nothing returns nothing
local unit cast=GetTriggerUnit()
local integer l=GetUnitAbilityLevel(cast,OB_Id())
local location targ=GetSpellTargetLoc()
local real x=GetLocationX(targ)
local real y=GetLocationY(targ)
local effect e
local unit u=CreateUnit(GetOwningPlayer(cast),OB_UnitId(),x,y,90)
call SetUnitScale(u,OB_StartEffectScale(l),OB_StartEffectScale(l),OB_StartEffectScale(l))
set e=AddSpecialEffectTargetForPlayer(OB_StartEffect(),u,"origin",GetOwningPlayer(cast))
call SetUnitTimeScale(u,0)
call TimedWait(OB_StartInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_WaveInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_WaveInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call TimedWait(OB_BombInterval(l))
call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
call DestroyEffect(e)
call RemoveUnit(u)
call RemoveLocation(targ)
set targ=null
set cast=null
set u=null
set e=null
endfunction
function OB_Conditions takes nothing returns boolean
return GetSpellAbilityId() == OB_Id()
endfunction
//===========================================================================
function InitTrig_Orbital_Bombardment takes nothing returns nothing
set gg_trg_Orbital_Bombardment = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Orbital_Bombardment, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Orbital_Bombardment, Condition( function OB_Conditions ) )
call TriggerAddAction( gg_trg_Orbital_Bombardment, function OB_Actions )
endfunction