wc3campaigns
WC3C Homepage - www.wc3c.netUser Control Panel (Requires Log-In)Engage in discussions with other users and join contests in the WC3C forums!Read one of our many tutorials, ranging in difficulty from beginner to advanced!Show off your artistic talents in the WC3C Gallery!Download quality models, textures, spells (vJASS/JASS), systems, and scripts!Download maps that have passed through our rigorous approval process!

Go Back   Wc3C.net > Resources > - Submit a resource -
User Name
Password
Register Rules Get Hosted! Chat Pastebin FAQ and Rules Members List Calendar



Reply
 
Thread Tools Search this Thread
Old 11-30-2015, 09:16 PM   #1
iNfraNe
PhD
 
iNfraNe's Avatar


Cinematics Moderator
 
Join Date: Dec 2003
Posts: 2,283

Submissions (7)

iNfraNe is just really nice (266)iNfraNe is just really nice (266)iNfraNe is just really nice (266)iNfraNe is just really nice (266)iNfraNe is just really nice (266)

Approved Map: Mortar Ball

Send a message via MSN to iNfraNe
Default GetUnitZ

Library GetUnitZ, the way to correctly obtain the z of a unit with movement type fly (and also the others). A demo map is included that shows the need for this library. Two lightning effects follow a flying unit. The chain lightning is calculated using the traditional GetLocationZ + GetUnitFlyHeight functions, the drain life with GetUnitZ.
Collapse JASS:
library GetUnitZ
    //******************************************************************************************************
    //                                                                                                      
    //      Library GetUnitZ, the way to correctly obtain the z of a unit with movement type fly.   
    //                                                                                                      
    //      Author: iNfraNe
    //
    //      API:
    //
    //      function GetUnitZ takes unit u returns real
    //          returns the correct absolute z value of a unit, regardless of its movement type. For flying
    //          units, a grid is made and the height which is appended naturally by the game engine
    //          is calculated.
    //
    //      function GetFlyHeightOffset takes real x, real y returns real
    //          calculates the absolute z of the point on the flyheight surface. This is the Z of the terrain
    //          plus the appended height for flying units.
    //
    //      Known issues:
    //
    //      - destructables influence the flyheight of flying units if their Fly-Over Height is set
    //        to anything but 0. Sadly, because their calculations are pathing-map based, it is not
    //        possible to correct for this, and we require users to make sure there are no destructables
    //        with a Fly-Over Height > 0.
    //      - The system will automatically unhide hidden destructables if the function is called on a
    //        nearby flying unit. Users are required to re-hide the destructables they have previously
    //        hidden after a function call to GetUnitNaturalFlyHeight.
    //
    //******************************************************************************************************
    globals
        private constant real RECT_SIZE = 1024. // the rect size at which destructables should be hidden who may alter the grid calculations. Don't change it.
        private location l = Location(0.,0.)
    endglobals
    private struct fh_grid256
        private static hashtable h = InitHashtable()
        private static rect r = null
        private static method hideDests takes nothing returns nothing
            // these destructables are in range of the current gridpoint, but their Z should not influence the terrain, hiding them means that they are ignored in GetLocationZ
            call ShowDestructable(GetEnumDestructable(), false)
        endmethod
        private static method showDests takes nothing returns nothing
            // show the destructables afterwards. CAREFUL: this means that destructables that were hidden initially will be shown!
            call ShowDestructable(GetEnumDestructable(), true)
        endmethod
        private static method calcGridPointZ takes real x, real y returns real
            local real array h
            local real r
            local real r1
            local real r2
            local real z
            // the function assumes that the x and y are on actual gridpoints!
            debug if I2R(R2I(x/128.))*128. != x or 2*(R2I(x/128.)/2) == R2I(x/128.) or I2R(R2I(y/128.))*128. != y or 2*(R2I(y/128.)/2) == R2I(y/128.) then
                call BJDebugMsg("Error in FlyHeightCalculator, non-grid x ("+R2S(x)+") or y ("+R2S(y)+") passed to calcGridPointZ!")
                return 0.
            endif
            // after this function has been run for a given gridpoint, its z is stored, so as to not run the length function anymore.
            if HaveSavedReal(.h,R2I(x),R2I(y)) then
                return LoadReal(.h,R2I(x),R2I(y))
            endif
            if .r == null then
                set .r = Rect(0.,0.,RECT_SIZE,RECT_SIZE)
            endif
            //
            // move the rect and hide the destructables, so that their walkability doesnt influence calculations
            call MoveRectTo(.r,x,y)
            call EnumDestructablesInRect(.r,null, function thistype.hideDests)
            //======================================================== 
            //=            CALCULATE THE TERRAIN HEIGHTS             =
            //========================================================
                // left bottom
                call MoveLocation(l, x-256., y-256.)
                set h[0] = GetLocationZ(l)
                // center bottom
                call MoveLocation(l, x-128., y-256.)
                set h[1] = GetLocationZ(l)
                call MoveLocation(l, x, y-256.)
                set r = GetLocationZ(l)
                if r > h[1] then
                    set h[1] = r
                endif
                call MoveLocation(l, x+128., y-256.)
                set r = GetLocationZ(l)
                if r > h[1] then
                    set h[1] = r
                endif
                // right bottom
                call MoveLocation(l, x+256, y-256.)
                set h[2] = GetLocationZ(l)
                // left center
                call MoveLocation(l, x-256., y-128.)
                set h[3] = GetLocationZ(l)
                call MoveLocation(l, x-256., y)
                set r = GetLocationZ(l)
                if r > h[3] then
                    set h[3] = r
                endif
                call MoveLocation(l, x-256., y+128.)
                set r = GetLocationZ(l)
                if r > h[3] then
                    set h[3] = r
                endif
                // center center
                call MoveLocation(l, x-128., y-128.)
                set h[4] = GetLocationZ(l)
                call MoveLocation(l, x, y-128.)
                set r = GetLocationZ(l)
                if r > h[4] then
                    set h[4] = r
                endif
                call MoveLocation(l, x+128., y-128.)
                set r = GetLocationZ(l)
                if r > h[4] then
                    set h[4] = r
                endif        
                
                call MoveLocation(l, x-128., y)
                set r = GetLocationZ(l)
                if r > h[4] then
                    set h[4] = r
                endif   
                call MoveLocation(l, x, y)
                set r = GetLocationZ(l)
                if r > h[4] then
                    set h[4] = r
                endif
                call MoveLocation(l, x+128., y)
                set r = GetLocationZ(l)
                if r > h[4] then
                    set h[4] = r
                endif              
                
                call MoveLocation(l, x-128., y+128.)
                set r = GetLocationZ(l)
                if r > h[4] then
                    set h[4] = r
                endif   
                call MoveLocation(l, x, y+128.)
                set r = GetLocationZ(l)
                if r > h[4] then
                    set h[4] = r
                endif
                call MoveLocation(l, x+128., y+128.)
                set r = GetLocationZ(l)
                if r > h[4] then
                    set h[4] = r
                endif        
                // right center
                call MoveLocation(l, x+256., y-128.)
                set h[5] = GetLocationZ(l)
                call MoveLocation(l, x+256., y)
                set r = GetLocationZ(l)
                if r > h[5] then
                    set h[5] = r
                endif
                call MoveLocation(l, x+256., y+128.)
                set r = GetLocationZ(l)
                if r > h[5] then
                    set h[5] = r
                endif            
                // top left
                call MoveLocation(l, x-256., y+256.)
                set h[6] = GetLocationZ(l)
                // top center
                call MoveLocation(l, x-128., y+256.)
                set h[7] = GetLocationZ(l)
                call MoveLocation(l, x, y+256.)
                set r = GetLocationZ(l)
                if r > h[7] then
                    set h[7] = r
                endif
                call MoveLocation(l, x+128., y+256.)
                set r = GetLocationZ(l)
                if r > h[7] then
                    set h[7] = r
                endif
                // top right
                call MoveLocation(l, x+256., y+256.)
                set h[8] = GetLocationZ(l)
            //======================================================== 
            //=           CALCULATE THE ADDED Z BY SIDES             =
            //========================================================                
                set z = h[4]
                if h[1]>h[7] then
                    set r1 = h[1]
                else
                    set r1 = h[7]
                endif
                if h[3]>h[5] then
                    set r2 = h[3]
                else
                    set r2 = h[5]
                endif
                if r1 > r2 then
                    // lowest increase first (for some odd reason)
                    if h[3] > z then
                        set r1 = h[3]-z
                    else
                        set r1 = 0.
                    endif
                    if h[5] > z then
                        set r2 = h[5]-z
                    else
                        set r2 = 0.
                    endif
                    set z = z + (r1+r2)/2
                    
                    // then second
                    if h[1] > z then
                        set r1 = h[1]-z
                    else
                        set r1 = 0.
                    endif
                    if h[7] > z then
                        set r2 = h[7]-z
                    else
                        set r2 = 0.
                    endif
                    set z = z + (r1+r2)/2
                else
                    // lowest increase first (for some odd reason)
                    if h[1] > z then
                        set r1 = h[1]-z
                    else
                        set r1 = 0.
                    endif
                    if h[7] > z then
                        set r2 = h[7]-z
                    else
                        set r2 = 0.
                    endif
                    set z = z + (r1+r2)/2
                    // then second
                    if h[3] > z then
                        set r1 = h[3]-z
                    else
                        set r1 = 0.
                    endif
                    if h[5] > z then
                        set r2 = h[5]-z
                    else
                        set r2 = 0.
                    endif
                    set z = z + (r1+r2)/2
                endif
            //======================================================== 
            //=          CALCULATE THE ADDED Z BY CORNERS            =
            //========================================================        
                // left bottom
                if h[1] > h[3] then
                    if h[1] > h[4] then
                        set r = h[1]
                    else
                        set r = h[4]
                    endif
                else
                    if h[3] > h[4] then
                        set r = h[3]
                    else
                        set r = h[4]
                    endif
                endif
                if h[0] > r then
                    set z = z + ((h[0]-r)/4)
                endif
                // right bottom
                if h[1] > h[5] then
                    if h[1] > h[4] then
                        set r = h[1]
                    else
                        set r = h[4]
                    endif
                else
                    if h[5] > h[4] then
                        set r = h[5]
                    else
                        set r = h[4]
                    endif
                endif
                if h[2] > r then
                    set z = z + ((h[2]-r)/4)
                endif
                // left top
                if h[3] > h[7] then
                    if h[3] > h[4] then
                        set r = h[3]
                    else
                        set r = h[4]
                    endif
                else
                    if h[7] > h[4] then
                        set r = h[7]
                    else
                        set r = h[4]
                    endif
                endif
                if h[6] > r then
                    set z = z + ((h[6]-r)/4)
                endif
                // right top
                if h[5] > h[7] then
                    if h[5] > h[4] then
                        set r = h[5]
                    else
                        set r = h[4]
                    endif
                else
                    if h[7] > h[4] then
                        set r = h[7]
                    else
                        set r = h[4]
                    endif
                endif
                if h[8] > r then
                    set z = z + ((h[8]-r)/4)
                endif

            // show the surrounding destructables. Take into account that previously hidden destructables will also be shown.
            call EnumDestructablesInRect(.r,null, function thistype.showDests)
            //debug call CreateDestructableZ('B000', x, y, z, 0,1.,0)
            // save the real to the hashtable (later, only a read from the table is required to get the gridZ)            
            call SaveReal(.h,R2I(x),R2I(y),z)
            return z
        endmethod
        static method getGridZ takes real x, real y returns real
            local real minX = I2R(R2I((x+128.*RSignBJ(x))/256.))*256.-128.
            local real minY = I2R(R2I((y+128.*RSignBJ(y))/256.))*256.-128.
            local real maxX = minX+256.
            local real maxY = minY+256.
            local real dx = x-minX
            local real dy = y-minY
            local real dz1 = dx/256.*.calcGridPointZ(maxX,minY)+(1-dx/256.)*.calcGridPointZ(minX,minY) //if the calculation has been done for the point, it equals to a hastable call
            local real dz2 = dx/256.*.calcGridPointZ(maxX,maxY)+(1-dx/256.)*.calcGridPointZ(minX,maxY)
            return dy/256.*dz2+(1-dy/256.)*dz1
        endmethod
    endstruct
    function GetUnitZ takes unit u returns real
        if IsUnitType(u, UNIT_TYPE_FLYING) then
            return fh_grid256.getGridZ(GetUnitX(u),GetUnitY(u))+GetUnitFlyHeight(u)
        else
            call MoveLocation(l, GetUnitX(u), GetUnitY(u))
            return GetLocationZ(l)+GetUnitFlyHeight(u)
        endif
        return 0.
    endfunction
    function GetFlyHeightOffset takes real x, real y returns real
        return fh_grid256.getGridZ(x,y)
    endfunction
endlibrary
Attached Files
File Type: w3x GetUnitZDemo.w3x (24.2 KB, 11 views)
__________________
Ever so slightly active.
Table:
Past Projects:
The Spirit of Vengeance (Cinematic, Blizzard contest winner)
Elimination Tournament
Mortar Ball

Last edited by iNfraNe : 12-02-2015 at 09:06 AM.
iNfraNe is offline   Reply With Quote
Sponsored Links - Login to hide this ad!
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off


All times are GMT. The time now is 04:24 PM.


Affiliates
The Hubb The JASS Vault Clan WEnW Campaign Creations Clan CBS GamesModding Flixreel Videos

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services