HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

MakeUnitHover - Timed function is fucked.

10-13-2008, 01:42 PM#1
Vestras
It's really hard to explain the problem, but somehow the two units who I use shifts heights, and then the first one stops in middle air when they are supposed to be put down to the ground... I'll attach the map.

Collapse JASS:
library MakeUnitHover

private keyword Data

globals
    private constant integer ENABLE_FLY='Amrf'
    // The Raven Form ability which enables flying
    private constant real INTERVAL=0.03
    // The timer interval. 0.03 is suggested, less can cause lag
    private constant real DIVIDE=100
    // d.z is divided with this
    private constant real RATE=5000
    // The "time" the unit is about getting from and to the ground/fly height
    private constant real TIME = 2
    // Amount of time required to get from minHeight to maxHeight, based on HEIGHT
    private constant real HEIGHT = 100
    // Will take TIME seconds to go from minHeight to maxHeight, if Abs(maxHeight - minHeight) == HEIGHT
    
// Necessary globals
private Data array D
private integer N=0
private timer T=CreateTimer()
private location l=Location(0,0) // For GetUnitZ()
endglobals

//! WARNING WARNING WARNING WARNING WARNING WARNING WARNING
//! Real Snippet Code! 
//! Don't touch if you don't know what you are doing!
//! WARNING WARNING WARNING WARNING WARNING WARNING WARNING

private struct Data
    unit swayer
    real z
    real max
    real min
    real height
    real durcount
    real counter=0
    real duration=0
    boolean hasReachedMax
    boolean isTimed
endstruct

private function Parabola takes real x,real d,real h returns real
    return 4*h*x*(d-x)/(d*d)
endfunction

private function GetUnitZ takes unit whichUnit returns real
    call MoveLocation(l,GetUnitX(whichUnit),GetUnitY(whichUnit))
    return GetLocationZ(l)+GetUnitFlyHeight(whichUnit)
endfunction

function StopUnitHover takes unit whichUnit returns nothing
    local Data d
    local integer i=N
    loop
        exitwhen i<=0
        set d=D[i]
        if d.swayer==whichUnit then
            if d.swayer==null then
                call BJDebugMsg("|cffff0000MakeUnitSway|r: invalid unit.")
                return
            endif
            set D[i]=D[N]
            set N=N-1
            if N==0 then
                call PauseTimer(T)
            endif
            call SetUnitFlyHeight(whichUnit,d.height,RATE)
            call BJDebugMsg("rofl")
            call d.destroy()
        endif
        set i=i-1
    endloop
endfunction

private function Callback takes nothing returns nothing
    local Data d
    local integer i=N
    local real parab
    local real dif
    local real totalTime
    local real swayHeight
    loop
        exitwhen i==0
        set d=D[i]
        set dif=RAbsBJ(d.max-d.min)/HEIGHT
        set swayHeight=RAbsBJ(d.max-d.min)
        set totalTime=TIME*dif
        set d.counter=d.counter+INTERVAL
        if d.isTimed then
            set d.durcount=d.durcount+INTERVAL
        endif
        if d.durcount>=d.duration and d.isTimed then
            call StopUnitHover(d.swayer)
            call BJDebugMsg("lol")
        endif
        if d.counter>=totalTime then
            set d.counter=0
        endif
        set parab=Parabola(d.counter,totalTime,swayHeight)+d.min
        call SetUnitFlyHeight(d.swayer,parab,0)
        set i=i-1
    endloop
endfunction

function MakeUnitHover takes unit whichUnit, real max, real min returns nothing
    local Data d=Data.create()
    set d.swayer=whichUnit
    set d.height=GetUnitFlyHeight(whichUnit)
    call UnitAddAbility(whichUnit,ENABLE_FLY)
    call SetUnitFlyHeight(whichUnit,min,RATE)
    set d.z=min-1
    call UnitRemoveAbility(whichUnit,ENABLE_FLY)
    set d.max=max
    set d.min=min
    set d.hasReachedMax=false
    set N=N+1
    set D[N]=d
    set d.isTimed=false
    set d.durcount=0
    set d.duration=0
    if N==1 then
        call TimerStart(T,INTERVAL,true,function Callback)
    endif
endfunction

function MakeUnitHoverTimed takes unit whichUnit, real max, real min, real duration returns nothing
    local Data d=Data.create()
    set d.swayer=whichUnit
    set d.height=GetUnitFlyHeight(whichUnit)
    call UnitAddAbility(whichUnit,ENABLE_FLY)
    call SetUnitFlyHeight(whichUnit,min,RATE)
    set d.z=min-1
    call UnitRemoveAbility(whichUnit,ENABLE_FLY)
    set d.max=max
    set d.min=min
    set d.hasReachedMax=false
    set N=N+1
    set D[N]=d
    set d.isTimed=true
    set d.duration=duration
    set d.durcount=0
    if N==1 then
        call TimerStart(T,INTERVAL,true,function Callback)
    endif
endfunction

endlibrary
Attached Files
File type: w3mMakeUnitHover Altered.w3m (19.2 KB)
10-14-2008, 08:21 AM#2
Vestras
Bump.
10-14-2008, 10:19 AM#3
Anitarf
Collapse JASS:
    loop
        exitwhen i==0
        set d=D[i]
        set dif=RAbsBJ(d.max-d.min)/HEIGHT
        set swayHeight=RAbsBJ(d.max-d.min)
        set totalTime=TIME*dif
        set d.counter=d.counter+INTERVAL
        if d.isTimed then
            set d.durcount=d.durcount+INTERVAL
        endif
        if d.durcount>=d.duration and d.isTimed then
            call StopUnitHover(d.swayer)
            call BJDebugMsg("lol")
        endif
        if d.counter>=totalTime then
            set d.counter=0
        endif
        set parab=Parabola(d.counter,totalTime,swayHeight)+d.min
        call SetUnitFlyHeight(d.swayer,parab,0)
        set i=i-1
    endloop