- Joined
- Jul 26, 2008
- Messages
- 1,009
I'm trying to create an ability where the unit pops up from a large water spout and is shot in the air, landing shortly after.
(I wanted to find a way to make the unit sink underground just before, but I don't think WC3's engine allows that)
The way I have it set up is with a timer that periodically increases the units fly height at a decreasing value til it hits its apex. It then descends at an increasing rate until it reaches it's default fly height.
I don't know the formula for a smooth Jump animation, and have tried multiple ones. Can someone pass that on to me?
(The unfinished code in question
(I wanted to find a way to make the unit sink underground just before, but I don't think WC3's engine allows that)
The way I have it set up is with a timer that periodically increases the units fly height at a decreasing value til it hits its apex. It then descends at an increasing rate until it reaches it's default fly height.
I don't know the formula for a smooth Jump animation, and have tried multiple ones. Can someone pass that on to me?
(The unfinished code in question
Code:
scope WaterRush initializer Init
globals
private constant integer SPELLID = 'A00M'
private constant real TICK = 0.035
endglobals
struct Data
unit caster
effect fx
real rate = 2
real x
real y
real xdir
real ydir
boolean transported = false
boolean descending = false
static method sinkPeriodic takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
if not .transported then
call SetUnitX(.caster, .x)
call SetUnitY(.caster, .y)
set .transported = true
elseif .transported and GetUnitFlyHeight(.caster) < 450 and not .descending then
set .rate = .rate - 0.5
call SetUnitFlyHeight(.caster, GetUnitFlyHeight(.caster)+(.rate*.rate), 1000)
if IsTerrainWalkable( GetWidgetX(.caster)-1, GetWidgetY(.caster)-1 ) then
call SetUnitX(.caster, GetWidgetX(.caster)-.xdir)
call SetUnitY(.caster, GetWidgetY(.caster)-.ydir)
endif
if GetUnitFlyHeight(.caster) >= 450 then
set .descending = true
endif
elseif .descending and GetUnitFlyHeight(.caster) <= GetUnitDefaultFlyHeight(.caster) then
call ReleaseTimer(GetExpiredTimer())
set .caster = null
call .destroy()
elseif .descending then
set .rate = .rate + 0.5
call SetUnitFlyHeight(.caster, GetUnitFlyHeight(.caster)-(.rate*.rate), 1000)
if IsTerrainWalkable( GetWidgetX(.caster)-1, GetWidgetY(.caster)-1 ) then
call SetUnitX(.caster, GetWidgetX(.caster)-.xdir)
call SetUnitY(.caster, GetWidgetY(.caster)-.ydir)
endif
else
endif
endmethod
static method actions takes nothing returns nothing
local thistype this = thistype.allocate()
if GetSpellAbilityId() == SPELLID then
set .caster = GetTriggerUnit()
set .x = GetSpellTargetX()
set .y = GetSpellTargetY()
set .xdir = GetRandomReal(-2, 2)
set .ydir = GetRandomReal(-2, 2)
if UnitAddAbility(.caster, 'Amrf') then
call UnitRemoveAbility(.caster, 'Amrf')
endif
call SetUnitPathing(.caster,false)
call TimerStart(NewTimerEx(this), TICK, true, function thistype.sinkPeriodic )
endif
endmethod
endstruct
private function Init takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction( t, function Data.actions )
set t = null
endfunction
endscope