Ok, since you lifted the flag, here we go:
Originally Posted by
Blaster_89
This pointer points to a structure containing tile numbers. These tile numbers change as the player moves, effectively removing any necessities for centralizing memory locations and heavily reducing the amount of WinAPI calls necessary to find the same information.
This structure that you are saying is the tiles array index. Why? As in the beginning vanitas proved, TibiaClient stores map in a 3D array where [z][y][x] = [0..7][0..13][0..17].
If you do a nested loop in the array you've found, i.e.,
Code:
for z = 0, 7 do
for y = 0, 13 do
for x = 0, 17 do
you'll face only 2 behaviors, your tile will match at [7 - Self.Z, 6, 8] when Self.Z <= 7 and [2, 6, 8] otherwise.
So, to get your own tile is a O(1) operation
And is really suggestive that we stands Y = 6, X = 8... because it's really center of the X, Y coordinates. What I founded to be odd when coding it, was the fact that if
we match ourself at [2, 6, 8] if Self.Z > 7. So what happens when Self.Z > 13 and we want tiles at Z = 15?
ex:
Suppose Self.Z = 14 and we want Z = 15.
if we match ourself at [2, 6, 8], the logic says Z = 15 is at [1, Y, X], and what is stored at 0? Simple. Nothing (it means tiles at [0, Y, X] will have 0 as count of items). I checked on Thais, there is a hidden city at Z = 15.
Arises at least 3 functions to be coded:
- Get Self Tile
- Get Tile on x, y, z
- Get All Tiles in a single function
The first is really easy, because it is only:
tile = read(mapStart + read(indexArray[7 - Self.Z, 6, 8]) * mapStep) if Self.Z <= 7 or read(mapStart + read(indexArray[2, 6, 8]) * mapStep) otherwise
Lasts 2 is just matter of writing a nice way to offset things and I'll paste directly from my bot here (don't worry, I'll explain first):
In the following, my Tile constructor is "Tile(int index, int x, int y, int z)" or "Tile(int index, Location)", Addresses.TILE_INDEX_INT is the array you Blaster_89 found and Addresses.TILE_INDEX_INT[z, y, x] is the index of tile at x, y, z and Addresses.MAP_INT[,] is the structure buffer as int[,] array, better saying Addresses.MAP_INT[i, ] is i-th tile in Tibia memory
Get Tile on x, y, z:
Code:
Tile OnLocation(int x, int y, int z)
{
if (z < 0 || z > 15)
return null;
Location self = Self.Location;
Location desired = new Location(x, y, z);
Utils.Update(UpdateStruct.Tiles); // It updates 2 arrays, tiles array and array that Blaster_89 found
int start, end, aux;
if (self.Z <= 7)
{
start = 7;
end = -1;
}
else if (self.Z <= 13)
{
start = self.Z + 2;
end = self.Z - 3;
}
else if (self.Z == 14)
{
start = self.Z + 1;
end = self.Z - 3;
}
else
{
start = self.Z;
end = self.Z - 3;
}
aux = self.Z - z;
x -= aux + (self.X - 8);
y -= aux + (self.Y - 6);
z = start - z;
if (x < 0 || x >= 18 || y < 0 || y >= 14 || z < 0)
return null;
return new Tile(Addresses.TILE_INDEX_INT[z, y, x], desired);
}
Get All Tiles
Code:
List<Tile> All()
{
List<Tile> tiles = new List<Tile>();
int z, y, x, aux, start, end;
Location self = Self.Location;
Utils.Update(UpdateStruct.Tiles); // It updates 2 arrays, tiles array and array that Blaster_89 found
if (self.Z <= 7)
{
start = 7;
end = -1;
}
else if (self.Z <= 13)
{
start = self.Z + 2;
end = self.Z - 3;
}
else if (self.Z == 14)
{
start = self.Z + 1;
end = self.Z - 3;
}
else
{
start = self.Z;
end = self.Z - 3;
}
for (z = start; z > end; z--)
{
aux = self.Z - z;
for (y = aux; y < 14 + aux; y++)
for (x = aux; x < 18 + aux; x++)
if (Addresses.MAP_INT[Addresses.TILE_INDEX_INT[start - z, y - aux, x - aux], Addresses.TILE_COUNT_ON_STACK_INT] > 0) // if tile has > 0 items, ok
tiles.Add(new Tile(Addresses.TILE_INDEX_INT[start - z, y - aux, x - aux], self.X - 8 + x, self.Y - 6 + y, z));
}
return tiles;
}
Probably there is some mistake hidden, but well , that's the life.
A bit of offtopic: If you or someone want to look for new structures, recently I found the structure that Tibia stores effects and missiles to draw the screen. So, last offset of Tile structure is the index of this new array I've found.
Ok ok, I'll keep quiet because you Blaster_89 is releasing my secrets!!! Haha, I'm glad someone got it.
EDIT: I almost forget to mention that:
when Self.Z <= 7, you have all tiles above you available, i.e, level 0 - 7.
when Self.Z > 7, you have
Self.Z - 2, Self.Z - 1, Self.Z, Self.Z + 1, Self.Z + 2 levels availables