scope leapOfFaith initializer i
private struct dLeap
integer steps
location last
unit caster
endstruct
globals
private constant integer ciLeap='A058' //Triggering abilitycode
private constant integer iSteps=35 //Total number of repeated timer steps
private constant integer offset=26 //Distance in game units a unit is offset by
private constant integer reducer=2 //Ammount steps is reduced by each time
private constant real zMultiplier=.5 //Multiplier for caster z height; larger is a taller arc
private dLeap array leapDB
private integer dbIndex=-1
private timer time=CreateTimer()
endglobals
private function c takes nothing returns boolean
return GetSpellAbilityId()==ciLeap
endfunction
private function p takes nothing returns nothing
local integer index=0
local dLeap tempDat
local location lOffset
local real z1
local real z2
local effect fx
local integer iGrabbed=dbIndex
loop
exitwhen index>iGrabbed
set tempDat=leapDB[index]
set lOffset=PolarProjectionBJ(GetUnitLoc(tempDat.caster),offset,GetUnitFacing(tempDat.caster))
set z1=I2R(tempDat.steps/5) //z heights being compared
set z2=I2R(tempDat.steps)/5 //Should just use mod...
if z1==z2 then //This works though.
set fx=AddSpecialEffectLoc("Abilities\\Weapons\\GlaiveMissile\\GlaiveMissileTarget.mdl",lOffset)
call DestroyEffect(fx)
endif
set tempDat.steps=tempDat.steps-reducer
call SetUnitFlyHeight(tempDat.caster,GetUnitFlyHeight(tempDat.caster)+zMultiplier*tempDat.steps,0)
call SetUnitPositionLoc(tempDat.caster,lOffset)
if IsTerrainPathable(GetLocationX(lOffset),GetLocationY(lOffset),PATHING_TYPE_FLOATABILITY)==false then
set tempDat.last=lOffset
endif
if tempDat.steps<-1*iSteps then
call SetUnitPathing(tempDat.caster,true)
set leapDB[index]=leapDB[dbIndex]
set dbIndex=dbIndex-1
call SetUnitFlyHeight(tempDat.caster,0,0)
if dbIndex==-1 then
call PauseTimer(time)
endif
if IsTerrainPathable(GetLocationX(lOffset),GetLocationY(lOffset),PATHING_TYPE_FLOATABILITY) then //WHY IS THIS BACKWARDS!?
call SetUnitPositionLoc(tempDat.caster,tempDat.last)
call SetUnitState(tempDat.caster,UNIT_STATE_LIFE,GetUnitState(tempDat.caster,UNIT_STATE_LIFE)/2+1)
endif
call tempDat.destroy()
endif
set index=index+1
endloop
call RemoveLocation(lOffset)
endfunction
private function a takes nothing returns nothing
local dLeap tempDat=dLeap.create()
local unit caster=GetSpellAbilityUnit()
local real rCasterX=GetUnitX(caster)
local real rCasterY=GetUnitY(caster)
call SetSoundPosition(gg_snd_jumpSoundDefendCasterWav,rCasterX,rCasterY,100)
call StartSound(gg_snd_jumpSoundDefendCasterWav)
call UnitAddAbility(caster,'Amrf')
call UnitRemoveAbility(caster,'Amrf')
call SetUnitPathing(caster,false)
set tempDat.steps=iSteps+GetUnitLevel(caster)/2
set tempDat.caster=caster
if dbIndex==-1 then //While negative 1, the stack is empty. An empty stack must be jumpstarted!
call TimerStart(time,.03,true,function p)
endif
set dbIndex=dbIndex+1
set leapDB[dbIndex]=tempDat
endfunction
private function i takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function c))
call TriggerAddAction(t,function a)
endfunction
endscope