function CastSpell takes unit caster, unit target, integer spell, integer level, integer order returns nothing
local unit u = CreateUnit(GetOwningPlayer(caster), 'nwad', GetUnitX(target), GetUnitY(target), 0)
call UnitApplyTimedLife(u, 'BTLF', 2)
call UnitAddAbility(u, spell)
call SetUnitAbilityLevel(u, spell, level)
call IssueTargetOrderById(u,order,target)
call ShowUnitHide(u)
set u=null
endfunction
function Jumper takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer id=GetHandleId(t)
local unit u=LoadUnitHandle(udg_MH,id,1)
local real L=LoadReal(udg_MH,id,2)
local integer i=LoadInteger(udg_MH,id,3)+1
local integer n=LoadInteger(udg_MH,id,7)
local real h=LoadReal(udg_MH,id,4)
local real MoveX=LoadReal(udg_MH,id,5)
local real MoveY=LoadReal(udg_MH,id,6)
local real A=MoveX*I2R(i)
local real B=MoveY*I2R(i)
local real x=SquareRoot(A*A+B*B)
local real z
local pathingtype pt=ConvertPathingType(LoadInteger(udg_MH,id,8))
if i>n or GetWidgetLife(u)<=0 then
call UnitRemoveAbility(u,'Avul')
call SetUnitPathing(u,true)
call FlushChildHashtable(udg_MH,id)
call DestroyTimer(t)
call UnitRemoveAbility(u,'B001')
call SetUnitFlyHeight(u,0.,0.)
set t=null
set u=null
return
else
set z=4.*h*x/L*(1.-x/L)
call SaveInteger(udg_MH,id,3,i)
if not IsTerrainPathable(GetUnitX(u)+MoveX,GetUnitY(u)+MoveY,pt) then
call SetUnitX(u,GetUnitX(u)+MoveX)
call SetUnitY(u,GetUnitY(u)+MoveY)
endif
call SetUnitFlyHeight(u,z+GetZ(GetUnitX(u),GetUnitY(u)),0.)
set t=null
set u=null
endif
endfunction
function JumpContinue takes nothing returns nothing
local timer t2=GetExpiredTimer()
local integer id2=GetHandleId(t2)
local unit u=LoadUnitHandle(udg_MH,id2,1)
local timer t=LoadTimerHandle(udg_MH,id2,2)
call DestroyTimer(t2)
set t2=null
call FlushChildHashtable(udg_MH,id2)
call UnitAddAbility(u,'Amrf')
call UnitRemoveAbility(u,'Amrf')
call UnitAddAbility(u,'Avul')
call SetUnitPathing(u,false)
call TimerStart(t,0.03,true,function Jumper)
set t=null
set u=null
endfunction
function Jump takes unit u,real angle,real distance,real distanceZ,real time,integer pt returns nothing
local real X1=GetUnitX(u)
local real Y1=GetUnitY(u)
local real Z1=GetZ(X1,Y1)
local real X2=X1+distance*CosBJ(angle)
local real Y2=Y1+distance*SinBJ(angle)
local real Z2=GetZ(X2,Y2)
local real dZ=(Z1+Z2)/2.
local real L=2.*distance/(1.+SquareRoot(distanceZ/(dZ+distanceZ)))
local integer n=R2I(time/0.03)
local timer t=CreateTimer()
local integer id=GetHandleId(t)
local timer t2=CreateTimer()
local integer id2=GetHandleId(t2)
local real Move=L/I2R(n)
local real MoveX=Move*CosBJ(angle)
local real MoveY=Move*SinBJ(angle)
local real h=distanceZ+dZ
call SaveUnitHandle(udg_MH,id,1,u)
call SaveReal(udg_MH,id,2,L)
call SaveInteger(udg_MH,id,3,0)
call SaveInteger(udg_MH,id,7,n)
call SaveReal(udg_MH,id,4,h)
call SaveReal(udg_MH,id,5,MoveX)
call SaveReal(udg_MH,id,6,MoveY)
call SaveInteger(udg_MH,id,8,pt)
call CastSpell(u,u,'AHtb',1,OrderId("thunderbolt"))
call IssueImmediateOrder(u,"stop")
call SaveUnitHandle(udg_MH,id2,1,u)
call SaveTimerHandle(udg_MH,id2,2,t)
call TimerStart(t2,0.02,false,function JumpContinue)
set t2=null
set t=null
endfunction