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

PathingLib v1.6

JASS:
library PathingLib
   
    // Object generator
    //! external ObjectMerger w3u hgry hPLF unsf "(PathingLib) FlyChecker"   unam "" umdl ".mdl" ubdg 0 uabi "Aloc" uble 0 ulum 0 upoi 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" ugol 0 uaen "" udea "" umvt "fly" usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
    //! external ObjectMerger w3u hfoo hPLW unsf "(PathingLib) WalkChecker"  unam "" umdl ".mdl" ubdg 0 uabi "Aloc" uble 0 ulum 0 upoi 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" ugol 0 uaen "" udea "" umvt "foot" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
    //! external ObjectMerger w3u hhou hPLB unsf "(PathingLib) BuildChecker" unam "" umdl ".mdl" ubdg 1 uabi "Aloc" upat "" ulum 0 upoi 0 uubs "" uble 0 ushb "" uico "" ugol 0 ufma 0 umxp 0 ubsl "" umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
    //! external ObjectMerger w3u hpea hPLP unsf "(PathingLib) PathChecker"  unam "" umdl ".mdl" ubdg 0 uabi "Aloc" uble 0 ubui "hPLF,hPLW,hPLB" ulum 0 upoi 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" ugol 0 uaen "" udea "" umvt "foot" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
   
    // Configuration
        globals
            private constant integer PATH_CHECKER  = 'hPLP'
            private constant integer FLY_CHECKER   = 'hPLF'
            private constant integer WALK_CHECKER  = 'hPLW'
            private constant integer BUILD_CHECKER = 'hPLB'
            private constant player  DUMMY_PLAYER  = Player(15)
        endglobals
    /*
                    Pathing Library v1.6
                    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
        Description
        ¯¯¯¯¯¯¯¯¯¯¯
            Allows you to detect all pathability types:
            walkablility, flyability, and buildability.
           
            Warning!
            Please keep informed that this system is more sensitive than
            any other walkability checker systems out there, as it also
            detects pathing map generated by normal units as well.
           
        API
        ¯¯¯
            | function IsTerrainFlyable takes real x, real y returns boolean
            | function IsTerrainWalkable takes real x, real y returns boolean
            | function IsTerrainBuildable takes real x, real y returns boolean
                   
        How to import
        ¯¯¯¯¯¯¯¯¯¯¯¯¯
            - Copy Fly, Walk, Build, and Path Checker at object editor (Unit).
            - Make sure Path Checker is able to build Fly, Walk, and Build Checker
              (at object editor>unit>Path Checker>"Techtree - Structures built")
            - Configure this system correctly.
                   
        Link: hiveworkshop.com/forums/spells-569/pathing-type-v1-2-a-263230/
    */
   
    globals
        private unit PathChecker
    endglobals
   
    function IsTerrainFlyable takes real x, real y returns boolean
        return IssueBuildOrderById(PathChecker, FLY_CHECKER, x, y)
    endfunction
   
    function IsTerrainWalkable takes real x, real y returns boolean
        return IssueBuildOrderById(PathChecker, WALK_CHECKER, x, y)
    endfunction
   
    function IsTerrainBuildable takes real x, real y returns boolean
        return IssueBuildOrderById(PathChecker, BUILD_CHECKER, x, y)
    endfunction
   
    private module Init
        private static method onInit takes nothing returns nothing
            call init()
        endmethod
    endmodule
   
    private struct InitStruct extends array
        private static method init takes nothing returns nothing
            set PathChecker = CreateUnit(DUMMY_PLAYER, PATH_CHECKER, 0, 0, 0)
            call UnitRemoveAbility(PathChecker, 'Amov')
            call ShowUnit(PathChecker, false)
            if GetLocalPlayer() == DUMMY_PLAYER then
                call FogEnable(false)
            endif
        endmethod
        implement Init
    endstruct
   
endlibrary

Last update:
- Added object generator

Credits:
- Special thanks to PurgeandFire for his pathability checking method!
- TheHelper.net for a complete pathing color tutorial.

Keywords:
check, terrain, pathing, pathability, walkability, flyability, buildability, color
Contents

PathingLib (Map)

Reviews
11:40, 10th Mar 2015 IcemanBo: The system works very nicely and can be very useful. Good job.

Moderator

M

Moderator

11:40, 10th Mar 2015
IcemanBo: The system works very nicely and can be very useful. Good job.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
description is provided in the jass resource already.

I like the overall description quite a lot actually.

Cant really rate the algorithm, but I guess it works correctly, assuming you tested it.

One last thing to mention is you could mention to copy the units from the map, but that is not really required, since most people will understand that if it says 'h000' and 'n000' than it most likely is implicit, kind of.
 
Level 14
Joined
Dec 29, 2009
Messages
931
The point of the system is to enable you to check not only if the terrain is walkable, but if it's buildable, pathable for air units, etc.
There are also combinations, the 'colors' are results of things being, for example, both walkable AND buildable.

Now I'm not the best with vJASS but I'm basing this off of what I remember when I was working with pathability before, and I had looked up a few resources. :)
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
OMG. I'm so excited to release this update. It's not only much faster due to its new approach (big thanks to PurgeandFire), but it also allows you to check flyability and buildability as well. And it's no longer depending on IsTerrainWalkable library by Vex. It has its own function which is faster than before. Enjoy!!!
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Updated with the following changes:
  • Renamed to "Pathing Library" or in short "PathingLib"
  • Improved documentations
  • Global vision is no longer given to dummy player
  • Improved object editor data:
    • Added locust to dummy units
    • Dummy units are moved to Other-Special category for better look
    • Removed pathing map from Build Checker, improved accuracy, supposedly
  • And some others
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
How sensitive is IsTerrainWalkable? For better understanding the word sensitive is used
to describe a true positive result.

In other words, what is the closest point to an unwalkable point returning IsWalkable?
If I remember correctly the minimum collision size was something like 8.
Let's say (0,0) is not walkable. Will IsTerrainWalkable(1, 0) return true or false?
Or is the closest point (9, 0)?
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I'd drop

function GetTerrainPathingColor takes real x, real y returns integer

and all of your coloring stuff. That stuff isn't necessary ; ). The same can be accomplished with an external lib at no extra cost with more specificity to the problem.


To support vexorian's JassHelper, you should be using a module initializer instead of the regular initializer. By using the regular initializer, a general public resource (at least one I write) can't use this.

I have taken the opportunity to edit the script and give some more specific comments within the script itself.

JASS:
library PathingLib
    
    // Configuration
    
        globals
        
            private constant integer PATH_CHECKER  = 'h000'
            private constant integer FLY_CHECKER   = 'h001'
            private constant integer WALK_CHECKER  = 'h002'
            private constant integer BUILD_CHECKER = 'h003'
            
            private constant player  DUMMY_PLAYER  = Player(15)
            
        endglobals
    
    /*
    
                Pathing Library v1.4
                ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
                        by: Quilnez aka Dalvengyr
        
        
        Description
        ¯¯¯¯¯¯¯¯¯¯¯
            This library allows you to detect all pathability types:
            walkablility, flyability, and buildability.
            
            Warning!
            Please keep informed that this system is more sensitive than
            any other walkability checker systems out there, as it also
            detects pathing map generated by normal units as well.
            
            (You can check your pathing map by pressing 'p' at terrain editor.)
            
            
        API
        ¯¯¯

            // this is difficult to read with the description coming before the function
            // normally the functions are listed with tabbed descriptions. This is common in
            // all forms of professional documentation.
            1. Used for checking certain point's flyability
            
                | function IsTerrainFlyable takes real x, real y returns boolean
                
                
            2. Used for checking certain point's walkability.
            
                | function IsTerrainWalkable takes real x, real y returns boolean
                
                
            3. Used for checking certain point's buildability.
            
                | function IsTerrainBuildable takes real x, real y returns boolean
                    
                    
        How to import
        ¯¯¯¯¯¯¯¯¯¯¯¯¯
            - Copy Fly, Walk, Build, and Path Checker (units) at object editor.
            - Make sure Path Checker is able to build Fly, Walk, and Build Checker
              (at object editor>unit>Path Checker>"Techtree - Structures built")
            - Configure this system (available above).
                    
                    
        Credits
        ¯¯¯¯¯¯¯
            - PurgeandFire for pathability checking method.
            - TheHelper.net for complete pathing types tutorial.
                    
                    
        Link
        ¯¯¯¯
            hiveworkshop.com/forums/spells-569/pathing-type-v1-2-a-263230/
    
    */
    
    globals

        // should be pathChecker
        private unit PathChecker

    endglobals
    
    function IsTerrainFlyable takes real x, real y returns boolean
        return IssueBuildOrderById(PathChecker, FLY_CHECKER, x, y)
    endfunction
    
    function IsTerrainWalkable takes real x, real y returns boolean
        return IssueBuildOrderById(PathChecker, WALK_CHECKER, x, y)
    endfunction
    
    function IsTerrainBuildable takes real x, real y returns boolean
        return IssueBuildOrderById(PathChecker, BUILD_CHECKER, x, y)
    endfunction

    // Init library here if this is ugly -> github.com/nestharus/JASS/blob/master/jass/Systems/Init/script.j
    private module Init
        private static method onInit takes nothing returns nothing
            call init()
        endmethod
    endmodule

    private struct InitStruct extends array
        private static method init takes nothing returns nothing
    
            // should disable whatever Unit Indexing library before creating this unit

            set PathChecker = CreateUnit(DUMMY_PLAYER, PATH_CHECKER, 0, 0, 0)
            call UnitRemoveAbility(PathChecker, 'Amov')
            call ShowUnit(PathChecker, false)

            // is this line necessary? I really don't know.
            if GetLocalPlayer() == DUMMY_PLAYER then
                call FogEnable(false)
            endif
        
        endmethod

        implement Init
    endstruct
    
endlibrary

I also recommend that, if there is a unit indexing library involved, you disable the unit indexer when creating your unit : ).

You might also want to do 3 methods of installation.

Method 1: Copy objects
Method 2: Run object merger script
Method 3: Run installation script (dynamic, see my Lua stuff on github under JASS)



Also, having "cool" bonus functionality is not a good thing : P.


I'm only critiquing this harshly because I think it should be used as the standard pathing library. It's better than mine too : ).

https://github.com/nestharus/JASS/blob/master/jass/Systems/IsPathable/script.j


In order to really be used as a core standard, it needs to have very tight code (minimal features), it needs to work with as many resources as possible (things like module initializers), and it needs to have as many methods of installation as possible for compatibility (by Lua, by inline, by copy).



For now, I personally rate this a 4/5. Let's bring it to a perfect score ^)^.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
while I dont take your opinion out, you are almost like Nazi. "Making it the standard"
a.) You are not really in position to call things standards, we are not coding for you, but for the comunity
b.) nowhere did he say he wants this to become clear standard smashing everything to ground from now on.

Forms of instalation, I dont think copy pasting 2 things from one map to another is really an issue, dont forget LUA doesnt work for everyone

Also on the color, while it is extra stuff, it is still strongly related, therefore I see why it could be in the core of this system instead of new independant resource, mainly because having 50 lines resources that can be inlined into the original thing are just plain annoying and retarded(look at your shitty tables you had here). Modularity is nice thing, but having 10 line resources is just, as I said, plain retarded, mainly because there is no good way to pull scripts from internet into JassHelper, yet
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
while I dont take your opinion out, you are almost like Nazi. "Making it the standard"
Quite inappropriate.

I agree on covering a disable call for a possible unit indexer tool.
Module initializers is (sadly) a must have in every resource, which should be accessible from other resources.

You can do the LUA thing, it's not a must have for only few objects (my opinion).
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
How sensitive is IsTerrainWalkable? For better understanding the word sensitive is used
to describe a true positive result.

In other words, what is the closest point to an unwalkable point returning IsWalkable?
If I remember correctly the minimum collision size was something like 8.
Let's say (0,0) is not walkable. Will IsTerrainWalkable(1, 0) return true or false?
Or is the closest point (9, 0)?

I think this is perfectly precise, theoritically. Since I'm using 0 collision size for every checker unit, but thanks God they are still able to check pathability.

@Nestharus:
Your post is so long to quote.

But I would like to ask you, why you love to separate every little thing? Alright the color feature is just useful in some rare cases but still, it's just some lines of codes, how terrible can it be?

I could fix the initializer thing tho, I never knew the issue behind that method before.

And sorry for the late response, I didn't really check my resources lately.
 

Zwiebelchen

Hosted Project GR
Level 35
Joined
Sep 17, 2009
Messages
7,236
JASS:
private module Init
         private static method onInit takes nothing returns nothing
             call init()
         endmethod
     endmodule
     
     private struct InitStruct extends array
         private static method init takes nothing returns nothing
             set PathChecker = CreateUnit(DUMMY_PLAYER, PATH_CHECKER, 0, 0, 0)
             call UnitRemoveAbility(PathChecker, 'Amov')
             call ShowUnit(PathChecker, false)
             if GetLocalPlayer() == DUMMY_PLAYER then
                 call FogEnable(false)
             endif
         endmethod
         implement Init
     endstruct
What exactly was the issue with the library initializer btw? The new solution seems super convoluted and I don't see the point in it.

Also, any ideas on how to fix the unit sensitivity problem? You lib is the only one I've seen so far that takes destructables into account, but this thing also reacting to units makes it kinda unusable for missile or knockback systems.
 
What exactly was the issue with the library initializer btw? The new solution seems super convoluted and I don't see the point in it.

It is an issue with Vexorian's jasshelper. Picture libraries as a tree where "requires" indicates that the library is a parent. The "root" node in a tree is the one that is all the way at the top (all the children require the root, or they require a library which requires the root).

i.e. if you have a library B that requires A, and library C that requires A, then you'll have a tree that will look something like this:

.. A .
./...\.
B....C

Vexorian's jasshelper evaluates initializers as follows:
  • First execute the root module initializer, and then all its children's module initializers.
  • Second, execute the root struct initializers (private static method onInit) and then all its children's struct initializers.
  • Third, execute the library initializers and all its children's library initializers.
  • Finally, execute the scope initializers and all its children's scope initializers, and then its regular Trig_Init methods (I don't remember the details for this step).

This leads to weird problems when you try to use a library within an initialization function. If the library you require uses a library initializer whereas your child library uses a struct initializer, then your child library's init will run first.

That's why a lot of libraries just use module initializers. They are implemented first, so you're guaranteed to have functionality when someone calls it within their initialization function. It is a minor cost of readability, but eh there isn't any way of knowing how an individual user writes his code, so it is kinda a necessary evil if you wan't your code to work in those cases. :\

The easiest way to fix this would be to update jasshelper. Cohadar did that but he switched the parser and that gave a slew of other issues--so it never really caught on.
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
Also, any ideas on how to fix the unit sensitivity problem? You lib is the only one I've seen so far that takes destructables into account, but this thing also reacting to units makes it kinda unusable for missile or knockback systems.

I kinda forgot to reply. Maybe there is. But perhaps it's not a neat solution:
Before you check a pathing just move all units around the point within.. largest unit collision size in your map, to another point. Using SetUnitX/Y will move normal unit's pathing to the new spot immediately, but not with structure unit's, it will stay. If you do so, I suppose it will work like PnF's pathing checker then. I haven't tested it tho but I'm pretty much sure bout the result ^^

@PnF:
Thanks man for the explanation!
 
Level 9
Joined
May 24, 2016
Messages
298
Could anyone tell me what is that code?

JASS:
    // Object generator
    //! external ObjectMerger w3u hgry hPLF unsf "(PathingLib) FlyChecker"   unam "" umdl ".mdl" ubdg 0 uabi "Aloc" uble 0 ulum 0 upoi 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" ugol 0 uaen "" udea "" umvt "fly" usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
    //! external ObjectMerger w3u hfoo hPLW unsf "(PathingLib) WalkChecker"  unam "" umdl ".mdl" ubdg 0 uabi "Aloc" uble 0 ulum 0 upoi 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" ugol 0 uaen "" udea "" umvt "foot" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
    //! external ObjectMerger w3u hhou hPLB unsf "(PathingLib) BuildChecker" unam "" umdl ".mdl" ubdg 1 uabi "Aloc" upat "" ulum 0 upoi 0 uubs "" uble 0 ushb "" uico "" ugol 0 ufma 0 umxp 0 ubsl "" umxr 0 ussc 0 ushu "" uaen "" udea "" umvt "" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""
    //! external ObjectMerger w3u hpea hPLP unsf "(PathingLib) PathChecker"  unam "" umdl ".mdl" ubdg 0 uabi "Aloc" uble 0 ubui "hPLF,hPLW,hPLB" ulum 0 upoi 0 uico "" umxp 0 umxr 0 ussc 0 ushu "" ugol 0 uaen "" udea "" umvt "foot" ucol 0 usnd "" ufle 0 ufoo 0 uspe 1 uhom 1 urac "unknown" usid 0 usin 0 upgr "" uhot "" utip "" utub ""

Is there a way to use that system without these strings? Since Im using another version of world editor, these things give me the error while trying to save the demo map. (and I dont plan to use another since my map is already hardcoded into another WE version)

1.26 version.
 
Level 39
Joined
Feb 27, 2007
Messages
4,989
There is zero good reason to be on patch 1.26 any more. Please update your game; it's literally free.

This is old code that can no longer run in the modern WE because //! external calls are now deprecated. Those lines create units in the Object Editor. You can do what they do manually by going word-by-word and matching up what that means you should change. Things always come in pairs just like when editing spell data with triggers:
  • ObjectMerger w3u ---> OM is making a unit
  • hgrp hPLF ---> based on unit 'hgrp' it has the new custom rawcode 'hPLF'
  • unsf "(PathingLib) FlyChecker" ---> it has that as a suffix
  • unam "" ---> the field unam (name) has the value "" (empty string)
  • umdl ".mdl" ---> it has a model file of ".mdl"
See how you can walk through the list? You just need to recreate them all yourself as they are specified by the OM calls. Press Ctrl + D while in the Object Editor to see each field by its raw name rather than the verbose names for each field (unam vs "Unit Name").
 
Level 9
Joined
May 24, 2016
Messages
298
There is zero good reason to be on patch 1.26 any more. Please update your game; it's literally free.

This is old code that can no longer run in the modern WE because //! external calls are now deprecated. Those lines create units in the Object Editor. You can do what they do manually by going word-by-word and matching up what that means you should change. Things always come in pairs just like when editing spell data with triggers:
  • ObjectMerger w3u ---> OM is making a unit
  • hgrp hPLF ---> based on unit 'hgrp' it has the new custom rawcode 'hPLF'
  • unsf "(PathingLib) FlyChecker" ---> it has that as a suffix
  • unam "" ---> the field unam (name) has the value "" (empty string)
  • umdl ".mdl" ---> it has a model file of ".mdl"
See how you can walk through the list? You just need to recreate them all yourself as they are specified by the OM calls. Press Ctrl + D while in the Object Editor to see each field by its raw name rather than the verbose names for each field (unam vs "Unit Name").
Oh, I see. Thx you. But since his demo map already has modified object editor with units named FlyChecker; WalkChecker and etc. I suggest I can easily remove those lines from library, copy and paste his units from Object Editor, and that's it, I just copied them and it should work fine?

Pyrogasm is there a way that this system check inside a loop would loop endlessly?
f.e
JASS:
loop
set X = GetRandomReal(GetRectMinX(bj_mapInitialPlayableArea), GetRectMaxX(bj_mapInitialPlayableArea)) 
set Y = GetRandomReal(GetRectMinY(bj_mapInitialPlayableArea), GetRectMaxY(bj_mapInitialPlayableArea))
exitwhen IsTerrainWalkable(X, Y)
endloop
?
 
Last edited:
Top