• 🏆 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!

Terrain Walkability

Status
Not open for further replies.
Level 17
Joined
Feb 11, 2011
Messages
1,860
Hello guys,

I'm looking for a way to detect whether a point is walkable or not. I have this system:

JASS:
library TerrainPathability initializer Init

//******************************************************************************
//* BY: Rising_Dusk
//* 
//* This script can be used to detect the type of pathing at a specific point.
//* It is valuable to do it this way because the IsTerrainPathable is very
//* counterintuitive and returns in odd ways and aren't always as you would
//* expect. This library, however, facilitates detecting those things reliably
//* and easily.
//* 
//******************************************************************************
//* 
//*    > function IsTerrainDeepWater    takes real x, real y returns boolean
//*    > function IsTerrainShallowWater takes real x, real y returns boolean
//*    > function IsTerrainLand         takes real x, real y returns boolean
//*    > function IsTerrainPlatform     takes real x, real y returns boolean
//*    > function IsTerrainWalkable     takes real x, real y returns boolean
//* 
//* These functions return true if the given point is of the type specified
//* in the function's name and false if it is not. For the IsTerrainWalkable
//* function, the MAX_RANGE constant below is the maximum deviation range from
//* the supplied coordinates that will still return true.
//* 
//* The IsTerrainPlatform works for any preplaced walkable destructable. It will
//* return true over bridges, destructable ramps, elevators, and invisible
//* platforms. Walkable destructables created at runtime do not create the same
//* pathing hole as preplaced ones do, so this will return false for them. All
//* other functions except IsTerrainWalkable return false for platforms, because
//* the platform itself erases their pathing when the map is saved.
//* 
//* After calling IsTerrainWalkable(x, y), the following two global variables
//* gain meaning. They return the X and Y coordinates of the nearest walkable
//* point to the specified coordinates. These will only deviate from the
//* IsTerrainWalkable function arguments if the function returned false.
//* 
//* Variables that can be used from the library:
//*     [real]    TerrainPathability_X
//*     [real]    TerrainPathability_Y
//* 

    globals
        private constant real    MAX_RANGE     = 10.
        private constant integer DUMMY_ITEM_ID = 'wolg'
    endglobals

    globals    
        private item       Item   = null
        private rect       Find   = null
        private item array Hid
        private integer    HidMax = 0
        public  real       X      = 0.
        public  real       Y      = 0.
    endglobals

    function IsTerrainDeepWater takes real x, real y returns boolean
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
    endfunction
    
    function IsTerrainShallowWater takes real x, real y returns boolean
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
    endfunction
    
    function IsTerrainLand takes real x, real y returns boolean
        return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
    endfunction
    
    function IsTerrainPlatform takes real x, real y returns boolean
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_BUILDABILITY)
    endfunction

    private function HideItem takes nothing returns nothing
        if IsItemVisible(GetEnumItem()) then
            set Hid[HidMax] = GetEnumItem()
            call SetItemVisible(Hid[HidMax], false)
            set HidMax = HidMax + 1
        endif
    endfunction
    
    function IsTerrainWalkable takes real x, real y returns boolean
        //Hide any items in the area to avoid conflicts with our item
        call MoveRectTo(Find, x, y)
        call EnumItemsInRect(Find ,null, function HideItem)
        //Try to move the test item and get its coords
        call SetItemPosition(Item, x, y) //Unhides the item
        set X = GetItemX(Item)
        set Y = GetItemY(Item)
        static if LIBRARY_IsTerrainWalkable then
            //This is for compatibility with the IsTerrainWalkable library
            set IsTerrainWalkable_X = X
            set IsTerrainWalkable_Y = Y
        endif
        call SetItemVisible(Item, false)//Hide it again
        //Unhide any items hidden at the start
        loop
            exitwhen HidMax <= 0
            set HidMax = HidMax - 1
            call SetItemVisible(Hid[HidMax], true)
            set Hid[HidMax] = null
        endloop
        //Return walkability
        return (X-x)*(X-x)+(Y-y)*(Y-y) <= MAX_RANGE*MAX_RANGE and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
    endfunction

    private function Init takes nothing returns nothing
        set Find = Rect(0., 0., 128., 128.)
        set Item = CreateItem(DUMMY_ITEM_ID, 0, 0)
        call SetItemVisible(Item, false)
    endfunction
    
endlibrary
However, it doesn't work for pathing blockers or doodads (such as trees). Can anyone advise me on a way that works? Or am I missing something?

Thanks,

Mr_Bean
 
Level 24
Joined
Jul 9, 2009
Messages
4,097
  • Unwalkable
  • Events
    • Unit - A unit Is issued an order targeting a point
  • Conditions
    • (Terrain type at (Target point of issued order)) Equal to Your Terrain
  • Actions
    • Unit - Order (Triggering unit) to Stop
This should work just as well as any vJass code.
 
Level 17
Joined
Feb 11, 2011
Messages
1,860
Strange. Please try this test map and let me know what the output is. For me it is "Walkable" where it should be "Not walkable". It tests a point that is basically on the tree (you can see by the aura effect created at the point).
 

Attachments

  • test.w3x
    16.8 KB · Views: 65
Status
Not open for further replies.
Top