• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] [Snippet] TileDefinition

Info

A specific terrain tile is defined by it's terrain type, but also through coordinates.
While there exists a native GetTerrainType(), there is no native to get the geographical data of it.

TileDefinition can give these geographical information about the location of a terrain tile.
It can also provide an unique index for each terrain tile which can be used as reference.

Code
JASS:
library TileDefinition /* v1.2b    By IcemanBo - Credits to WaterKnight
               
   */ requires /*

        */ WorldBounds    /* github.com/nestharus/JASS/blob/master/jass/Systems/WorldBounds/script.j  
               
**
**
**                          Information
**                         _____________
**
**  TileDefinition provides an API to give information about a terrain tile.
**            
**      
**                             API
**                           _______
**
**
**
**      function GetTileCenterCoordinate takes real a returns real
**          Returns the cooridnate for the center of the tile.
**          Works for x- and y coordiantes.
**
**
**      function GetTileMax takes real a returns real
**          Returns the max value, that is still in same terrain tile.
**          Works for x- and y coordiantes.
**                  
**
**      function GetTileMin takes real a returns real
**          Returns the min value, that is still in same terrain tile.
**          Works for x- and y coordiantes.
**
**
**      function AreCoordinatesInSameTile takes real a, real b returns boolean
**          Checks if two coordinates share the same terrain tile.
**          
**          Attention: Only makes sense if both coordinates are of same type. Or x- or y coordinates.
**                     May bring wrong result, if you compare x with y coordinates.
**
**
**      function ArePointsInSameTile takes real x1, real y1, real x2, real y2 returns boolean
**          Checks if two points share the same terrain tile.
**
**
**      funtion GetTileId takes real x, real y returns integer
**          Returns an unique index for tile of given coordinates.
**          Will return "-1" if it's invalid.
**
**      function GetTileCenterXById takes integer id returns real
**
**      function GetTileCenterYById takes integer id returns real
**                  
**      
***********************************************************************************************************/
    
     globals
        private integer WorldTilesX
        private integer WorldTilesY
    endglobals
    
    function GetTileCenterCoordinate takes real a returns real
        if (a >= 0.) then
            return R2I((a/128) + .5)*128.
        else
            return R2I((a/128) - .5)*128.
        endif
    endfunction
    
    function AreCoordinatesInSameTile takes real a, real b returns boolean
        return GetTileCenterCoordinate(a) == GetTileCenterCoordinate(b)
    endfunction
    
    function AreLocationsInSameTile takes real x1, real y1, real x2, real y2 returns boolean
        return AreCoordinatesInSameTile(x1, x2) and AreCoordinatesInSameTile(y1, y2)
    endfunction
    
    function GetTileMin takes real a returns real
        return GetTileCenterCoordinate(a) - 64.
    endfunction
    
    function GetTileMax takes real a returns real
        return GetTileCenterCoordinate(a) + 64.
    endfunction
    
    function GetTileId takes real x, real y returns integer
        local integer xI = R2I(x - WorldBounds.minX + 64) / 128
        local integer yI = R2I(y - WorldBounds.minY + 64) / 128

        if ((xI < 0) or (xI >= WorldTilesX) or (yI < 0) or (yI >= WorldTilesY)) then
            return -1
        endif

        return (yI * WorldTilesX + xI)
    endfunction

    function GetTileCenterXById takes integer id returns real
        if ((id < 0) or (id >= WorldTilesX * WorldTilesY)) then
            return 0.
        endif

        return (WorldBounds.minX + ModuloInteger(id, WorldTilesX) * 128.)
    endfunction

    function GetTileCenterYById takes integer id returns real
        if ((id < 0) or (id >= WorldTilesX * WorldTilesY)) then
            return 0.
        endif

        return (WorldBounds.minY + id / WorldTilesX * 128.)
    endfunction
   
    private module Init
        private static method onInit takes nothing returns nothing
            set WorldTilesX = R2I(WorldBounds.maxX - WorldBounds.minX) / 128 + 1
            set WorldTilesY = R2I(WorldBounds.maxY - WorldBounds.minY) / 128 + 1
        endmethod
    endmodule
   
    private struct TileDefinition extends array
        implement Init
    endstruct
   
endlibrary
 
Last edited:
GetTileCenterCoordinate seems weird, it should support both X and Y, because right now you only return one value, but there are (Map width/height / 64) number of tiles with the same index
You give any X cooridnate as paramter. The x coorinate is in a random tile on map, that is not known.
Call the function GetTileCenterCoordinate and you will get back the X coorinate of the center of the tile.

If you give a y coordinate as paramter, it will return the the center y cooridnate.

It might seem weird, but actually it has nothing to do with coordiantes. It's just a mathematical formula that works for any real the same way. (read the method comment :))
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
  • JASS:
        function GetMax takes real a returns real
        function GetMin takes real a returns real
    Those function names are way too generic.
  • JASS:
            return Location(GetTileCenteCooridnate(x), GetTileCenteCooridnate(y))
    Couldn't be compiled. Personally, I'm disagreed with that function because location is banned in Jass. And this one too:
    JASS:
        function GetTileRect takes real x, real y returns rect
            return Rect(GetMin(x), GetMin(y), GetMax(x), GetMax(y))
        endfunction
    Functions that do cheap jobs are considered as code bloats.
  • JASS:
            if (aCount == 0) then
                return -64.
    Can be removed if you prefer clean coding for no speed loss. But clean coding itself is personal taste.
  • Have tested and get center function was working correctly, I can assume the other functions are working as well.
 

Attachments

  • test.jpg
    test.jpg
    165.9 KB · Views: 196
  • JASS:
        function GetMax takes real a returns real
        function GetMin takes real a returns real
    Those function names are way too generic.
  • JASS:
            return Location(GetTileCenteCooridnate(x), GetTileCenteCooridnate(y))
    Couldn't be compiled. Personally, I'm disagreed with that function because location is banned in Jass. And this one too:
    JASS:
        function GetTileRect takes real x, real y returns rect
            return Rect(GetMin(x), GetMin(y), GetMax(x), GetMax(y))
        endfunction
    Functions that do cheap jobs are considered as code bloats.
  • JASS:
            if (aCount == 0) then
                return -64.
    Can be removed if you prefer clean coding for no speed loss. But clean coding itself is personal taste.
  • Have tested and get center function was working correctly, I can assume the other functions are working as well.
GetMax/GetMin is generic for a function name, but I'm not other names would fit much better. You anyway would need ro read the comments.
Else oportunities: GetMaxReal/GetMaxCoordinate ... Idk, if they are better. Suggestion?

The location function had two typos, thanks. Fixed!

"function GetTileRect is cheap" ... well, I think it might be used in some cases.

Nice test map.^^ And yes, you of course can assume the functions to work correctly! :csmile:
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
JASS:
function GetMax takes real a returns real
The function with that parameter itself is not clearly understandable. If only get max/min x & y are separated stand-alone functions, then I guess you can give much reasonable names. Such as GetTileAreaMaxX/Y.

If you wont change it, I suggest to rename the parameter name from real a to real xy. Don't know if it causes confusion but it looks much more beautiful to me. Actually, GetTileArea|Max/Min|XY is also fine imho.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
JASS:
globals
    real WORLD_MAX_X
    real WORLD_MAX_Y
    real WORLD_MIN_X
    real WORLD_MIN_Y
    
    rect WORLD_RECT

    integer WORLD_TILES_X
    integer WORLD_TILES_Y
endglobals

function GetTileId takes real x, real y returns integer
    local integer xI = R2I(x - WORLD_MIN_X + 64) / 128
    local integer yI = R2I(y - WORLD_MIN_Y + 64) / 128

    if ((xI < 0) or (xI >= WORLD_TILES_X) or (yI < 0) or (yI >= WORLD_TILES_Y)) then
        return -1
    endif

    return (yI * WORLD_TILES_X + xI)
endfunction

function GetTileIdX takes integer id returns real
    if ((id < 0) or (id >= WORLD_TILES_X * WORLD_TILES_Y)) then
        return 0.
    endif

    return (WORLD_MIN_X + ModuloInteger(id, WORLD_TILES_X) * 128)
endfunction

function GetTileIdY takes integer id returns real
    if ((id < 0) or (id >= WORLD_TILES_X * WORLD_TILES_Y)) then
        return 0.
    endif

    return (WORLD_MIN_Y + id / WORLD_TILES_X * 128)
endfunction

function init takes nothing returns nothing
    set WORLD_RECT = GetWorldBounds()

    set WORLD_MIN_X = GetRectMinX(WORLD_RECT)
    set WORLD_MIN_Y = GetRectMinY(WORLD_RECT)
    set WORLD_MAX_X = GetRectMaxX(WORLD_RECT)
    set WORLD_MAX_Y = GetRectMaxY(WORLD_RECT)

    set WORLD_TILES_X = R2I(WORLD_MAX_X - WORLD_MIN_X) / 128 + 1
    set WORLD_TILES_Y = R2I(WORLD_MAX_Y - WORLD_MIN_Y) / 128 + 1
endfunction
 
Last edited:
JASS:
function GetTileId takes real x, real y returns integer
    local integer xI = R2I(x - WORLD_MIN_X) / 128
    local integer yI = R2I(y - WORLD_MIN_Y) / 128

    return (yI * R2I(WORLD_MAX_X - WORLD_MIN_X) / 128 + xI)
endfunction

function GetTileIdX takes integer id returns real
    return (WORLD_MIN_X + ModuloInteger(id, R2I(WORLD_MAX_X - WORLD_MIN_X) / 128) * 128)
endmethod

function GetTileIdY takes integer id returns real
    return (WORLD_MIN_Y + id / (R2I(WORLD_MAX_X - WORLD_MIN_X) / 128) * 128)
endfunction

function init takes nothing returns nothing
    set WORLD_RECT = GetWorldBounds()

    set WORLD_MIN_X = GetRectMinX(WORLD_RECT)
    set WORLD_MIN_Y = GetRectMinY(WORLD_RECT)
    set WORLD_MAX_X = GetRectMaxX(WORLD_RECT)
    set WORLD_MAX_Y = GetRectMaxY(WORLD_RECT)
endfunction
Waterknight, the code would bring wrong results, because of a deviation of 64.
You assume a certain tile to start at 0 and end in 128. That's a mistake.
The tile, located at 0/0 ... it's max is 64, and it's min is -64.

So you need to take in consideration if positive/negative... and then if I compare codes I don't see that the suggested code is really cooler.
 
Level 26
Joined
Aug 18, 2009
Messages
4,097
Waterknight, the code would bring wrong results, because of a deviation of 64.

You are right. Fixed it. Also something else and some security.

So you need to take in consideration if positive/negative...

It's always positive since I take minX/Y as origin.

and then if I compare codes I don't see that the suggested code is really cooler.

What did you compare it to? I meant to suggest it as an addition. The idea is to give each tile/terrain node an identification. Then you can for example store the terrain type changes of a node.
 
The idea is to give each tile/terrain node an identification. Then you can for example store the terrain type changes of a node.
Argh, shizzle vanizle.. I don't know why I haven't realized it when reading the code.
That's a brilliant idea and useful as hell! Thank you much for this code, I will implement it soon and give proper credits.
 
Ain't a terrain tile the size of 128x128? - and terrain tile is what this is about.


If someone can explain me why I would need to change it, go ahead.

Changed the names with this "get", thanks.

I made this maze generator months ago and I used the sizes, 128, 64, and 32. with 128 and 64, there are some spaces left in between the tiles that haven't been filled. 32 was the perfect one.


Also, DSG said about this i guess.
 
I can't say nothing about this what you mean, sorry.

I'm not sure I see the relation between pathing blockers and the purpose of this snippet.

Pathing blockers have 16x16 texture size. Tiles have 32x32. Compare it and it will look like Pathing Blockers are 1/4 of the Tiles.

Actually, we came up because BPower was confused whether a Tile is 32 or 64.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
A tile is 4x4 pathing cells, which is 128x128 pixels.
The smallest pathing cell that can be made is 32x32 and pathing blockers of this size do not exist in the base game.(The smallest doodads are 2x2)

Just make some custom pathing textures in gimp if you think otherwise. You simply can't make smaller than 32x32 pathing maps, because even those are 1 pixel.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
JASS:
    function GetTileCenterCoordinate takes real a returns real
        if (a >= 0) then
            return GetTileMin(a) + 64.
        else
            return GetTileMin(a) - 64.
        endif
    endfunction
--->
JASS:
    function GetTileCenterCoordinate takes real a returns real
        if (a >= 0) then
            return GetTileMin(a) + 64.
        endif
        return GetTileMin(a) - 64.
    endfunction

Same for GetTileMin, GetTileMax and TileDistance

Useful. Approved.
 
I don't know exactly what I changed in the last update, but now I changed the method a bit. (it works now like the way we worked out herem so it should work now)

However I haven't updated the opening post yet until someone tell me if it works correctly. :D

JASS:
library TileDefinition /* v1.2b    By IcemanBo - Credits to WaterKnight
               
   */ requires /*

        */ WorldBounds    /* github.com/nestharus/JASS/blob/master/jass/Systems/WorldBounds/script.j  
               
**
**
**                          Information
**                         _____________
**
**  TileDefinition provides an API to give information about a terrain tile.
**            
**      
**                             API
**                           _______
**
**
**
**      function GetTileCenterCoordinate takes real a returns real
**          Returns the cooridnate for the center of the tile.
**          Works for x- and y coordiantes.
**
**
**      function GetTileMax takes real a returns real
**          Returns the max value, that is still in same terrain tile.
**          Works for x- and y coordiantes.
**                  
**
**      function GetTileMin takes real a returns real
**          Returns the min value, that is still in same terrain tile.
**          Works for x- and y coordiantes.
**
**
**      function AreCoordinatesInSameTile takes real a, real b returns boolean
**          Checks if two coordinates share the same terrain tile.
**          
**          Attention: Only makes sense if both coordinates are of same type. Or x- or y coordinates.
**                     May bring wrong result, if you compare x with y coordinates.
**
**
**      function ArePointsInSameTile takes real x1, real y1, real x2, real y2 returns boolean
**          Checks if two points share the same terrain tile.
**
**
**      funtion GetTileId takes real x, real y returns integer
**          Returns an unique index for tile of given coordinates.
**          Will return "-1" if it's invalid.
**
**      function GetTileCenterXById takes integer id returns real
**
**      function GetTileCenterYById takes integer id returns real
**                  
**      
***********************************************************************************************************/
    
     globals
        private integer WorldTilesX
        private integer WorldTilesY
    endglobals
    
    function GetTileCenterCoordinate takes real a returns real
        if (a >= 0.) then
            return R2I((a/128) + .5)*128.
        else
            return R2I((a/128) - .5)*128.
        endif
    endfunction
    
    function AreCoordinatesInSameTile takes real a, real b returns boolean
        return GetTileCenterCoordinate(a) == GetTileCenterCoordinate(b)
    endfunction
    
    function AreLocationsInSameTile takes real x1, real y1, real x2, real y2 returns boolean
        return AreCoordinatesInSameTile(x1, x2) and AreCoordinatesInsameTile(y1, y2)
    endfunction
    
    function GetTileMin takes real a returns real
        return GetTileCenterCoordinate(a) - 64.
    endfunction
    
    function GetTileMax takes real a returns real
        return GetTileCenterCoordinate(a) + 64.
    endfunction
    
    function GetTileId takes real x, real y returns integer
        local integer xI = R2I(x - WorldBounds.minX + 64) / 128
        local integer yI = R2I(y - WorldBounds.minY + 64) / 128

        if ((xI < 0) or (xI >= WorldTilesX) or (yI < 0) or (yI >= WorldTilesY)) then
            return -1
        endif

        return (yI * WorldTilesX + xI)
    endfunction

    function GetTileCenterXById takes integer id returns real
        if ((id < 0) or (id >= WorldTilesX * WorldTilesY)) then
            return 0.
        endif

        return (WorldBounds.minX + ModuloInteger(id, WorldTilesX) * 128.)
    endfunction

    function GetTileCenterYById takes integer id returns real
        if ((id < 0) or (id >= WorldTilesX * WorldTilesY)) then
            return 0.
        endif

        return (WorldBounds.minY + id / WorldTilesX * 128.)
    endfunction
   
    private module Init
        private static method onInit takes nothing returns nothing
            set WorldTilesX = R2I(WorldBounds.maxX - WorldBounds.minX) / 128 + 1
            set WorldTilesY = R2I(WorldBounds.maxY - WorldBounds.minY) / 128 + 1
        endmethod
    endmodule
   
    private struct TileDefinition extends array
        implement Init
    endstruct
   
endlibrary
 
Top