• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] [Needs work] FlatFlier

Level 31
Joined
Jul 10, 2007
Messages
6,306
JASS:
library FlatFlier /* v1.0.1.0
*************************************************************************************
*
*   Makes units fly flatly over terrain (realistic) rather than go up and down
*   with terrain.
*
*   -   Flying units will not be able to go over terrain higher than them
*
*   -   Non flying units will stop flying if they touch the ground
*
*   -   Requires the use of SetUnitZ (SetUnitFlyHeight will not work with this)
*   -   The reason for this is because a unit's fly height will continue to raise
*   -   while it climbs terrain higher than it is. There is no way to make SetUnitFlyHeight
*   -   work correctly.
*
*************************************************************************************
*
*   */uses/*
*   
*       */ AutoFly /*       hiveworkshop.com/forums/submissions-414/autofly-unitindexer-version-195563/
*       */ IsUnitMoving /*  hiveworkshop.com/forums/jass-functions-413/system-unit-moving-178341/
*
************************************************************************************
*
*   SETTINGS
*/
    globals
        private constant boolean DO_GROUND_COLLISION = false
    endglobals
    private function OnGroundCollision takes unit u returns nothing
    endfunction
/*
************************************************************************************
*
*   Functions
*
*       function SetUnitZ takes unit u, real v returns nothing
*       function GetUnitZ takes unit u returns real
*
************************************************************************************/
    globals
        private integer array n
        private integer array p
        private real array w
        private real array tz
        private location z = Location(0,0)
        private boolean array f
    endglobals
    private function i takes nothing returns nothing
        local integer u = n[0]
        local unit h
        local real q
        loop
            exitwhen u == 0
            set h = GetUnitById(u)
            call MoveLocation(z, GetUnitX(h), GetUnitY(h))
            set q = GetLocationZ(z)
            set w[u] = w[u]+tz[u]-q
            static if DO_GROUND_COLLISION then
                if (w[u] <= 0) then
                    call OnGroundCollision(h)
                endif
            endif
            call SetUnitFlyHeight(h, w[u], 10000)
            set tz[u] = q
            set u = n[u]
        endloop
        set h = null
    endfunction
    private function a takes nothing returns boolean
        local integer u = GetMovingUnitId()
        if (f[u]) then
            set n[u] = 0
            set p[u] = p[0]
            set n[p[0]] = u
            set p[0] = u
        endif
        return false
    endfunction
    private function r takes nothing returns boolean
        local integer u = GetMovingUnitId()
        if (f[u]) then
            set n[p[u]] = n[u]
            set p[n[u]] = p[u]
        endif
        return false
    endfunction
    private function g takes nothing returns boolean
        local integer u = GetIndexedUnitId()
        local unit h = GetUnitById(u)
        call MoveLocation(z, GetUnitX(h), GetUnitY(h))
        set tz[u] = GetLocationZ(z)
        set w[u] = GetUnitFlyHeight(h)
        set f[u] = w[u] > 0
        set h = null
        return false
    endfunction
    function SetUnitZ takes unit u, real v returns nothing
        local integer c = GetUnitUserData(u)
        call MoveLocation(z, GetUnitX(u), GetUnitY(u))
        set w[c] = v-GetLocationZ(z)
        set f[c] = w[c] > 0
        if (f[c]) then
            call SetUnitFlyHeight(u,w[c],10000)
            if (IsUnitMoving(u)) then
                set n[c] = 0
                set p[c] = p[0]
                set n[p[0]] = c
                set p[0] = c
            endif
        endif
    endfunction
    function GetUnitZ takes unit u returns real
        return w[GetUnitUserData(u)]
    endfunction
    private module Init
        private static method onInit takes nothing returns nothing
            call RegisterUnitIndexEvent(Condition(function g), UnitIndexer.INDEX)
            call TimerStart(CreateTimer(), .03125, true, function i)
            call UnitMoving.MOVE.register(Condition(function a))
            call UnitMoving.STOP.register(Condition(function r))
        endmethod
    endmodule
    private struct Inits extends array
        implement Init
    endstruct
endlibrary
 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
???

how so? in the timer, you don't know if the fly height changed or not because the relative fly height changes as the terrain raises in level.

edit
When I had tried it, I got stuff with like 80 fly height minimum across high level terrain /sad face.

If you know a way to make it so that SetUnitFlyHeight works with this, I'm all ears =D.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
It was not brought about by that at all, it was brought about by my PositionOrigin extension for my Position script.

->AFAIK this still gets goofy if movement type for a unit is fly.

How so? I outputted the fly height's + z terrain to see if it got goofy at all and it outputted a constant number.

I did that because it visually looked wrong to me, but apparently it was working o-o.
 
Level 12
Joined
Mar 28, 2005
Messages
160
the output works fine, the realization, not so much

try it

at least that is my experience

I would observe a constant z height per trigger calculations, yet a very variable real z height (bouncing, as it were)

if it really worked on the flying unit, their height would not change at all, yet they still bounce...

try it on a unit with hover/none movement type instead
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
yet a very variable real z height

You mean the fly height? yea, that would be changing so that it would keep constant. FlyHeight+TerrainHeight = constant though.

if it really worked on the flying unit, their height would not change at all, yet they still bounce...
Only thing I noticed is that they seemed to go lower when the terrain got higher, and higher when the terrain got lower... but relative to terrain, at highest points they were right on the ground (almost) and on lowest points they were back to their original fly height, so I figured it was just weirdness with the camera or something =P.

Not sure what you're on about, but I did test this with helicopters and watched it. I never saw this bouncing that you're talking about.

This has about +-.003 accuracy.
 
Level 12
Joined
Mar 28, 2005
Messages
160
look at this

notice (you can add debug msgs where I change fly height) that triggered z height remains the same, however the projectile "bounces" as it moves (which it shouldn't, given a constant z height)

change the projectile to hover/none movement, and try it again

what I meant by real z height would be the observed z height (in game), as opposed to the triggered z height, or that value returned by GetUnitZ() (which seem to disagree)
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Yea, GetUnitZ returns a constant.

And I know what you meant, i'm just saying that when I tested this, I never saw the bouncing you were talking about. I can test again with some rough terrain rather than some big hills.

edit
bleh ; (

anyways, that just means you use hover units/movement type none if you want flat fliers >.>..

No way to detect none as a flying unit, so i'll just leave it up to the user to decide what to do (taking out the if statement stuff).

edit
updated

edit
still bounces with NONE and Hover... >.>

hrm

edit
doesn't bounce with foot o_O.
 
Top