# [vJASS][Snippet] TileDefinition

#### IcemanBo

Level 37
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:

#### edo494

Level 23
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

#### IcemanBo

Level 37
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 )

#### edo494

Level 23
`function GetTileCenteCooridnate takes real a returns real` we both know whats wrong there

#### edo494

Level 23
and how are his not coordinates not normalized?

#### Kazeon

Hosted Project: EC
Level 33
• 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
165.9 KB · Views: 186

#### edo494

Level 23
Location: its not banned, but its not used where useless

#### IcemanBo

Level 37
• 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!

#### Kazeon

Hosted Project: EC
Level 33
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.

#### WaterKnight

Level 25
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:

#### IcemanBo

Level 37
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.

#### WaterKnight

Level 25
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.

#### IcemanBo

Level 37
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.

#### BPower

Level 19
The smallest size for a tile is 32x32 or am I wrong here?.

TileMax vs GetTileMax is for me like GetWidgetLife vs WidgetLife.

Very useful snippet.

#### Almia

Level 33
The smallest size for a tile is 32x32 or am I wrong here?.

TileMax vs GetTileMax is for me like GetWidgetLife vs WidgetLife.

Very useful snippet.

Yes that should be 32x32(Based on my tests)

#### IcemanBo

Level 37
Ain't a terrain tile the size of 128x128? - and terrain tile is what this is about.

should be 32x32(Based on my tests)
If someone can explain me why I would need to change it, go ahead.

Changed the names with this "get", thanks.

#### Almia

Level 33
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.

#### BPower

Level 19
Offtopic: So the smallest pathing blocker is centerX +-16 // centerY +-16?
I always based my calculation of this value, when I replaced pathing blockers with unwalkable terrain type.

#### Almia

Level 33
Offtopic: So the smallest pathing blocker is centerX +-16 // centerY +-16?
I always based my calculation of this value, when I replaced pathing blockers with unwalkable terrain type.

Yes, you can check that in terrain editor and see how does the Large Pathing Blocker fits in a tile.

#### IcemanBo

Level 37
with 128 and 64, there are some spaces left in between the tiles that haven't been filled

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

#### Almia

Level 33

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.

#### Xonok

Level 21
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.

#### BPower

Level 19
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.

#### IcemanBo

Level 37
Ty, changed it. I also changed style of requirements a bit.
Could someone please check if it compiles, just to get sure?

#### Kazeon

Hosted Project: EC
Level 33
Hey, I don't know why but `GetTileCenterCoordinate` returns wrong value for x-axis? I need to add 128 to correct it. Can you check on this?

#### IcemanBo

Level 37
I have currently problems with my computer. Among some other softwares I can't use the editor.
When having fixed my problems I will test it.

#### IcemanBo

Level 37
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.

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``````

#### Almia

Level 33
I never thought tiles have 64x64 dimensions :V

Is the concept of your "Tile" based on the smallest grid units in the Terrain Editor? where when editing the terrain tile's skin, you are actually editing one of the corners of the tile? (it seems I don't get it :V)

I wonder because Nestharus' Tile works on 32x32 dimensions

Replies
22
Views
4K
[vJASS] TilesInRange
Replies
14
Views
2K
Replies
34
Views
7K
Replies
12
Views
2K
Replies
99
Views
19K