Jump math

Status
Not open for further replies.
Level 14
Joined
Jul 26, 2008
Messages
1,008
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:)
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
 
Status
Not open for further replies.
Back
Top