|
|
|
|
| JASS Resources Find JASS code snippets and functions here or write your own and post it on the Submissions sub-forum. |
 |
|
07-10-2011, 02:34 AM
|
#1 (permalink)
|
|
User
Join Date: Jul 2007
Posts: 4,919
|
[Snippet] Is Pathable
Is Point Pathable
Not to be confused with IsTerrainPathable, this script will check to see if a point is currently pathable given a pathing type. For example, it will be able to detect if a building is at that point, unlike IsTerrainPathable, which only checks the terrains pathability (including doodads and what not).
This takes advantage of SetUnitPosition in order to determine whether a point is pathable or not. However, SetUnitPosition may bug in cases where the closest pathable point is at least 1024 units away (in which case the unit is just placed at the original point regardless as to whether it was pathable or not). This avoid that bug with a special algorithm that no other is pathable resource has.
Installation Script
Requires- LUA_GET_VAR_OBJECT
Jass:
//! externalblock extension=lua ObjectMerger $FILENAME$
//! runtextmacro LUA_FILE_HEADER()
//! i dofile("GetVarObject")
//! i local function create(id,pt)
//! i createobject("hwtw", id)
//! i makechange(current, "unsf", "( " .. pt .. " )")
//! i makechange(current, "upat", "PathTextures\\2x2Default.tga")
//! i makechange(current, "ushb", "")
//! i makechange(current, "uubs", "")
//! i makechange(current, "uabr", "0")
//! i makechange(current, "uabt", "")
//! i makechange(current, "ucol", "0")
//! i makechange(current, "usid", "")
//! i makechange(current, "usin", "")
//! i makechange(current, "ubdg", "0")
//! i makechange(current, "usca", ".01")
//! i makechange(current, "uabi", "Avul")
//! i if (pt~="blighted") then
//! i makechange(current, "upap", pt)
//! i else
//! i makechange(current, "upar", pt)
//! i makechange(current, "upap", "")
//! i end
//! i if (pt=="unflyable") then
//! i makechange(current, "umvt", "fly")
//! i elseif (pt=="unamph") then
//! i makechange(current, "umvt", "amph")
//! i elseif (pt=="unfloat") then
//! i makechange(current, "umvt", "float")
//! i else
//! i makechange(current, "umvt", "foot")
//! i end
//! i end
//! i create(getvarobject("hwtw", "units", "UNITS_PATH_" .. "unflyable", true),"unflyable")
//! i create(getvarobject("hwtw", "units", "UNITS_PATH_" .. "unamph", true),"unamph")
//! i create(getvarobject("hwtw", "units", "UNITS_PATH_" .. "unbuildable", true),"unbuildable")
//! i create(getvarobject("hwtw", "units", "UNITS_PATH_" .. "unwalkable", true),"unwalkable")
//! i create(getvarobject("hwtw", "units", "UNITS_PATH_" .. "unfloat", true),"unfloat")
//! i create(getvarobject("hwtw", "units", "UNITS_PATH_" .. "blighted", true),"blighted")
//! i updateobjects()
//! endexternalblock
Script
Jass:
library IsPathable /* v1.0.2.3
*************************************************************************************
*
* The IsTerrainPathable native does not work.
*
* This library will also check if a point is currently pathable. Will even be
* able to detect buildings and large clusters of units (avoids the 1024 warcraft
* limit to pathing)
*
************************************************************************************
*
* */uses/*
*
* */ WorldBounds /* hiveworkshop.com/forums/jass-functions-413/snippet-worldbounds-180494/
* */ optional UnitIndexer /* hiveworkshop.com/forums/jass-resources-412/system-unit-indexer-172090/
*
************************************************************************************
*
* SETTINGS
*/
globals
/*
Enables the 1024 path checking for warcraft 3 (100% accurate path checking)
The 1024 case is a very rare case and may not be present in the map
Only enable this if it is truly needed (major performance hit).
*/
private constant boolean SAFE_PATHING = false
endglobals
/*
************************************************************************************
*
* constant integer PATH_TYPE_AMPHIBIOUS
* constant integer PATH_TYPE_BLIGHT
* constant integer PATH_TYPE_BUILDABILITY
* constant integer PATH_TYPE_FLOATABILITY
* constant integer PATH_TYPE_FLYABILITY
* constant integer PATH_TYPE_WALKABILITY
*
* function IsPathable takes integer x, integer y, integer pathingType returns boolean
* - i.e. call IsPathable(0,0,PATH_TYPE_AMPHIBIOUS)
*
************************************************************************************/
globals
//pathing types
constant integer PATH_TYPE_AMPHIBIOUS=0
constant integer PATH_TYPE_BLIGHT=1
constant integer PATH_TYPE_BUILDABILITY=2
constant integer PATH_TYPE_FLOATABILITY=3
constant integer PATH_TYPE_FLYABILITY=4
constant integer PATH_TYPE_WALKABILITY=5
constant integer UNITS_PATH_unflyable='h!!!'
constant integer UNITS_PATH_unamph='h!!"'
constant integer UNITS_PATH_unbuildable='h!!#'
constant integer UNITS_PATH_unwalkable='h!!$'
constant integer UNITS_PATH_unfloat='h!!%'
constant integer UNITS_PATH_blighted='h!!&'
private pathingtype array pt
private unit array u //unit pathability checkers array
endglobals
function GetPathingUnit takes integer pt returns unit
return u[pt]
endfunction
function IsPathable takes integer x, integer y, integer p returns boolean
local boolean b //was point pathable?
call SetUnitPosition(u[p],x,y) //use SetUnitPosition to determine if point is pathable
set b=GetUnitX(u[p])==x and GetUnitY(u[p])==y //if coordinates are identical, coordinate *may* be
//pathable
static if SAFE_PATHING then
if (b) then
//if the point was found as pathable, it may not be pathable
//units are placed at the original coordinates if the closest pathable point is
//at least 1024 units out
set x=x+32 //go out by 32
call SetUnitPosition(u[p],x,y) //set unit to new position
set b=GetUnitX(u[p])<x //check to see if unit shifted towards original position
//if unit didn't shift towards original position, check second position with another unit
//where all points are not pathable, place a unit at an arbitrary point
//it will stay at that point even though it isn't pathable
/*
* * * *
* * * *
* U * *
* * * *
*/
//shift the unit over by 1 and see if it doesn't shift
//if it did shift, then the original position was pathable
//if it didn't shift, then both positions may or may not be pathable
/*
* * * *
* * * *
* * U *
* * * *
*/
//place a second unit on top of the first unit
//if it didn't shift left, then the first position was not pathable
/*
* * * *
* * * *
* * <-UU *
* * * *
--------------------------
* * * *
* * * *
* U U *
* * * *
*/
//the reason it will shift left is because 64 is only half a square, meaning it
//will still be closest to the first position
//the reason why two units are required
/*
* * * *
* * * *
* *
* * * *
*/
//in this case, both positions are pathable, meaning the unit will not shift
//it would be identical to this case
/*
* * * *
* * * *
* * * *
* * * *
*/
//and the reason for moving right is due to this case
/*
* * * *
* * * *
* * *
* * * *
*/
//in this case, a unit placed on top of the original unit will not shift anywhere
//and nothing is known
if (not b) then
call SetUnitPosition(u[p+6],x-32,y)
set b=GetUnitX(u[p+6])<x
call SetUnitX(u[p+6],WorldBounds.minX)
call SetUnitY(u[p+6],WorldBounds.minY)
endif
endif
endif
call SetUnitX(u[p],WorldBounds.minX)
call SetUnitY(u[p],WorldBounds.minY)
return b
endfunction
private module N
private static method onInit takes nothing returns nothing
local player p=Player(15)
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = false
endif
set pt[PATH_TYPE_FLYABILITY]=PATHING_TYPE_FLYABILITY
set pt[PATH_TYPE_AMPHIBIOUS]=PATHING_TYPE_AMPHIBIOUSPATHING
set pt[PATH_TYPE_BUILDABILITY]=PATHING_TYPE_BUILDABILITY
set pt[PATH_TYPE_WALKABILITY]=PATHING_TYPE_WALKABILITY
set pt[PATH_TYPE_FLOATABILITY]=PATHING_TYPE_FLOATABILITY
set pt[PATH_TYPE_BLIGHT]=PATHING_TYPE_BLIGHTPATHING
set u[PATH_TYPE_FLYABILITY]=CreateUnit(p,UNITS_PATH_unflyable,0,0,0)
set u[PATH_TYPE_AMPHIBIOUS]=CreateUnit(p,UNITS_PATH_unamph,0,0,0)
set u[PATH_TYPE_BUILDABILITY]=CreateUnit(p,UNITS_PATH_unbuildable,0,0,0)
set u[PATH_TYPE_WALKABILITY]=CreateUnit(p,UNITS_PATH_unwalkable,0,0,0)
set u[PATH_TYPE_FLOATABILITY]=CreateUnit(p,UNITS_PATH_unfloat,0,0,0)
set u[PATH_TYPE_BLIGHT]=CreateUnit(p,UNITS_PATH_blighted,0,0,0)
set u[PATH_TYPE_FLYABILITY+6]=CreateUnit(p,UNITS_PATH_unflyable,0,0,0)
set u[PATH_TYPE_AMPHIBIOUS+6]=CreateUnit(p,UNITS_PATH_unamph,0,0,0)
set u[PATH_TYPE_BUILDABILITY+6]=CreateUnit(p,UNITS_PATH_unbuildable,0,0,0)
set u[PATH_TYPE_WALKABILITY+6]=CreateUnit(p,UNITS_PATH_unwalkable,0,0,0)
set u[PATH_TYPE_FLOATABILITY+6]=CreateUnit(p,UNITS_PATH_unfloat,0,0,0)
set u[PATH_TYPE_BLIGHT+6]=CreateUnit(p,UNITS_PATH_blighted,0,0,0)
call SetUnitX(u[PATH_TYPE_FLYABILITY],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_FLYABILITY],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_AMPHIBIOUS],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_AMPHIBIOUS],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_BUILDABILITY],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_BUILDABILITY],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_WALKABILITY],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_WALKABILITY],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_FLOATABILITY],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_FLOATABILITY],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_BLIGHT],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_BLIGHT],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_FLYABILITY+6],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_FLYABILITY+6],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_AMPHIBIOUS+6],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_AMPHIBIOUS+6],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_BUILDABILITY+6],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_BUILDABILITY+6],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_WALKABILITY+6],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_WALKABILITY+6],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_FLOATABILITY+6],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_FLOATABILITY+6],WorldBounds.minY)
call SetUnitX(u[PATH_TYPE_BLIGHT+6],WorldBounds.minX)
call SetUnitY(u[PATH_TYPE_BLIGHT+6],WorldBounds.minY)
call PauseUnit(u[PATH_TYPE_FLYABILITY], true)
call PauseUnit(u[PATH_TYPE_AMPHIBIOUS], true)
call PauseUnit(u[PATH_TYPE_BUILDABILITY], true)
call PauseUnit(u[PATH_TYPE_WALKABILITY], true)
call PauseUnit(u[PATH_TYPE_FLOATABILITY], true)
call PauseUnit(u[PATH_TYPE_BLIGHT], true)
call PauseUnit(u[PATH_TYPE_FLYABILITY + 6], true)
call PauseUnit(u[PATH_TYPE_AMPHIBIOUS + 6], true)
call PauseUnit(u[PATH_TYPE_BUILDABILITY + 6], true)
call PauseUnit(u[PATH_TYPE_WALKABILITY + 6], true)
call PauseUnit(u[PATH_TYPE_FLOATABILITY + 6], true)
call PauseUnit(u[PATH_TYPE_BLIGHT + 6], true)
set p=null
static if LIBRARY_UnitIndexer then
set UnitIndexer.enabled = true
endif
endmethod
endmodule
private struct I extends array
implement N
endstruct
endlibrary
Last edited by Nestharus; 12-22-2012 at 04:08 AM.
|
|
|
07-10-2011, 03:58 AM
|
#2 (permalink)
|
|
ʕ•͡ᴥ•ʔ
Resource & Tutorial Moderator
Join Date: Nov 2006
Posts: 3,556
|
This doesn't seem very fast compared to the item movement check method.
|
|
|
07-10-2011, 05:55 AM
|
#3 (permalink)
|
|
User
Join Date: Jul 2007
Posts: 4,919
|
Uh huh, but it can check for different types of pathability and it avoids a wc3 bug that the item movement check method fails to catch.
read the comments >.>
Jass:
//if the point was found as pathable, it may not be pathable
//units are placed at the original coordinates if the closest pathable point is
//at least 1024 units out
//loop through to see if the coordinates move *away* from the original position
Also keep in mind that an item wouldn't be able to tell if something like water had ship a ship at a point or floating buildings at a point =P.
But yea, due to the wc3 bug, you have to do the loop or you could get invalid results ;\.
Last edited by Nestharus; 07-10-2011 at 07:37 AM.
|
|
|
07-10-2011, 07:41 AM
|
#4 (permalink)
|
|
Keep it simple
Spells, Help Zones & JASS Moderator
Join Date: Sep 2009
Posts: 5,581
|
To know which integer to use, you can spoof GetHandleId as the array indices here. pathingtype only goes 0-7 so fits into an array perfectly.
Jass:
constant pathingtype PATHING_TYPE_ANY = ConvertPathingType(0)
constant pathingtype PATHING_TYPE_WALKABILITY = ConvertPathingType(1)
constant pathingtype PATHING_TYPE_FLYABILITY = ConvertPathingType(2)
constant pathingtype PATHING_TYPE_BUILDABILITY = ConvertPathingType(3)
constant pathingtype PATHING_TYPE_PEONHARVESTPATHING = ConvertPathingType(4)
constant pathingtype PATHING_TYPE_BLIGHTPATHING = ConvertPathingType(5)
constant pathingtype PATHING_TYPE_FLOATABILITY = ConvertPathingType(6)
constant pathingtype PATHING_TYPE_AMPHIBIOUSPATHING = ConvertPathingType(7)
This is more intuitive and allows the user to pass in the pathingtype directly instead of some integer.
__________________
How to post your triggers on the Hive Workshop.
JPAG - Bettering the cause of readable source code.
|
|
|
07-10-2011, 08:03 AM
|
#5 (permalink)
|
|
User
Join Date: Jul 2007
Posts: 4,919
|
Uh huh, but GetHandleId has a ton of overhead.
|
|
|
07-10-2011, 08:24 AM
|
#6 (permalink)
|
|
Keep it simple
Spells, Help Zones & JASS Moderator
Join Date: Sep 2009
Posts: 5,581
|
Let's see some benchmarks just what a "ton of overhead" GetHandleId is.
Here's what I know about it:
1. It was benchmarked faster than H2I.
2. Some natives are almost as fast as array lookups. This is probably one of them.
3. There's no way it has a "ton of overhead".
At most it'd be a 0.5% speed difference with what you have now.
However, it will preserve intuivity with maintaining the same names as already-existing variables, and those variables are even highlighted with syntax.
Reducing the learning curve on a lot of your libraries is definitely a good thing.
This is not a function you want to be calling on high-speed timers anyway. I can't think of a reason to use it.
Nice work on the documentation though.
__________________
How to post your triggers on the Hive Workshop.
JPAG - Bettering the cause of readable source code.
|
|
|
07-10-2011, 02:35 PM
|
#7 (permalink)
|
|
User
Join Date: Jul 2007
Posts: 4,919
|
GetHandleId is actually one of the slower natives :\
|
|
|
07-10-2011, 07:07 PM
|
#8 (permalink)
|
|
Keep it simple
Spells, Help Zones & JASS Moderator
Join Date: Sep 2009
Posts: 5,581
|
Yeah, I'm sure it ranks up there somewhere with
the efficiency of "CreateUnit". Really, GetHandleId
being one of the slow natives is just about as
unlikely as me being able to read your short variable
names.
__________________
How to post your triggers on the Hive Workshop.
JPAG - Bettering the cause of readable source code.
|
|
|
07-10-2011, 07:42 PM
|
#9 (permalink)
|
|
User
Join Date: Jul 2007
Posts: 4,919
|
Final update. This is now the best IsPathable library and the only one that fully works.
edit
60 fps vs 30 fps
Jass:
globals
constant boolean F=true
endglobals
function r takes nothing returns nothing
local integer x=5000
local integer i
loop
static if F then
set i=GetHandleId(PATHING_TYPE_ANY)
else
set i=0
endif
set x=x-1
exitwhen 0==x
endloop
endfunction
struct tester extends array
private static method onInit takes nothing returns nothing
call TimerStart(CreateTimer(),.015625000,true,function r)
endmethod
endstruct
This is the last time I'm benchmarking your bs claims for you. From now on, you bench it yourself before you make them.
You need to get with the program Bribe.
edit
Oh yea, and to give you an idea of how slow GetHandleId is, it tied with the SubString and LoadInteger natives on speed.
GetHandleId is among the slowest of all of the natives... you really don't believe me, but you forget that I've been coding JASS for many years and I know these things..
when GetHandleId was done and benched against H2I, it was barely faster, and H2I was an extremely slow and heavy operation... that just automatically says that GetHandleId is among the slowest of all of the natives.
Again, before you make these suggestions of yours, you need to investigate them yourself and prove that your suggestion is better. I'm only going to investigate them if there is room for doubt.
Because you really don't seem to know any of the native speeds, you keep throwing out these absurd suggestions. You need to do your own research Bribe.
I'm just getting tired of these claims of yours Bribe... and it's especially irritating when you throw these claims that I already know are totally asinine without even testing them and then claim that I'm the dude who doesn't know anything while on your high cloud of air -.-.
Next time you make one of these really stupid claims without any backing expecting me to test it for you even though I already know the outcome, I swear I'm going to 100% ignore you.
Last edited by Nestharus; 07-10-2011 at 08:46 PM.
|
|
|
07-10-2011, 08:50 PM
|
#10 (permalink)
|
|
JESUS MAN
Resource Moderator
Join Date: Dec 2008
Posts: 5,700
|
For Efficiency:
Create a local player in the onInit method, set it to Player(15) and use that :P
|
|
|
07-10-2011, 08:54 PM
|
#11 (permalink)
|
|
User
Join Date: Jul 2007
Posts: 4,919
|
Done, although that hardly matters since it's in onInit and you know it =P
|
|
|
07-10-2011, 09:17 PM
|
#12 (permalink)
|
|
JESUS MAN
Resource Moderator
Join Date: Dec 2008
Posts: 5,700
|
Quote:
|
Oh yea, and to give you an idea of how slow GetHandleId is, it tied with the SubString and LoadInteger natives on speed.
|
If it tied with LoadInteger, then I'm pretty sure handle Ids are stored in an instance of
class hashtable{};
:P
|
|
|
07-10-2011, 09:17 PM
|
#13 (permalink)
|
|
User
Join Date: Jul 2007
Posts: 4,919
|
Well, the handle table is probably a hashtable..
|
|
|
07-11-2011, 07:07 AM
|
#14 (permalink)
|
|
Keep it simple
Spells, Help Zones & JASS Moderator
Join Date: Sep 2009
Posts: 5,581
|
Nestharus, you fully missed the entire point.
I don't know how you got the idea to compare GetHandleId
to "set i = 0".
I said when compared to this whole IsPathable function, it
would add at most a 0.5% speed increase.
Now that you got rid of the loop in that function, I wouldn't
hold the same claim. I'd say maybe 15-20% speed increase
now (because it also involves creating a local), so it'd now
be worth it.
__________________
How to post your triggers on the Hive Workshop.
JPAG - Bettering the cause of readable source code.
|
|
|
07-11-2011, 11:09 AM
|
#15 (permalink)
|
|
cool != useful
Join Date: Apr 2008
Posts: 1,940
|
Maybe there is a failure in this benchmark but i don't see which one :
Jass:
library Test initializer init
globals
private boolean GetHandleIdTest = false
integer array I
endglobals
function F takes nothing returns nothing
local integer i
local integer j = 0
loop
exitwhen j == 6500
set j = j+1
static if GetHandleIdTest then
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
set i = GetHandleId(PATHING_TYPE_WALKABILITY)
else
set i = I[1]
set i = I[1]
set i = I[1]
set i = I[1]
set i = I[1]
set i = I[1]
set i = I[1]
set i = I[1]
set i = I[1]
set i = I[1]
endif
endloop
//call BJDebugMsg("limit op not reached")
endfunction
private function init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerSleepAction(2.)
call BJDebugMsg("test")
set I[1] = 1
call TimerStart(CreateTimer(),0.03,true,function F)
endfunction
endlibrary
Result : about 40 fps for both tests. (without the timer i have 60 fps)
PS : Not revelant but the code i pasted is the "inputwar3map.j" created by Jasshelper, i didn't put so much new lines myself.
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|
|
|
|
|
|
|
All times are GMT. The time now is 12:36 AM.
|