Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
MMapManager.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "MMapManager.h"
7#include "Log.h"
8#include "DBCStores.h"
9#include "MMapFactory.h"
10
11namespace MMAP
12{
13 // ######################## MMapManager ########################
15 {
16 for (MMapDataSet::iterator i = loadedMMaps.begin(); i != loadedMMaps.end(); ++i)
17 delete i->second;
18
19 // by now we should not have maps loaded
20 // if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost!
21 }
22
24 {
25 // we already have this map loaded?
26 if (loadedMMaps.find(mapId) != loadedMMaps.end())
27 return true;
28
29 // load and init dtNavMesh - read parameters from file
30 uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%04i.mmap") + 1;
31 char* fileName = new char[pathLen];
32 snprintf(fileName, pathLen, (sWorld->GetDataPath() + "mmaps/%04i.mmap").c_str(), mapId);
33
34 FILE* file = fopen(fileName, "rb");
35 if (!file)
36 {
37 SF_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName);
38 delete[] fileName;
39 return false;
40 }
41
42 dtNavMeshParams params;
43 int count = fread(&params, sizeof(dtNavMeshParams), 1, file);
44 fclose(file);
45 if (count != 1)
46 {
47 SF_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName);
48 delete[] fileName;
49 return false;
50 }
51
52 dtNavMesh* mesh = dtAllocNavMesh();
53 ASSERT(mesh);
54 if (dtStatusFailed(mesh->init(&params)))
55 {
56 dtFreeNavMesh(mesh);
57 SF_LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %04u from file %s", mapId, fileName);
58 delete[] fileName;
59 return false;
60 }
61
62 delete[] fileName;
63
64 SF_LOG_INFO("maps", "MMAP:loadMapData: Loaded %04i.mmap", mapId);
65
66 // store inside our map list
67 MMapData* mmap_data = new MMapData(mesh, mapId);
68
69 loadedMMaps.insert(std::pair<uint32, MMapData*>(mapId, mmap_data));
70 return true;
71 }
72
74 {
75 return uint32(x << 16 | y);
76 }
77
78 bool MMapManager::loadMap(const std::string& /*basePath*/, uint32 mapId, int32 x, int32 y)
79 {
80 // make sure the mmap is loaded and ready to load tiles
81 if (!loadMapData(mapId))
82 return false;
83
84 // get this mmap data
85 MMapData* mmap = loadedMMaps[mapId];
86 ASSERT(mmap->navMesh);
87
88 // check if we already have this tile loaded
89 uint32 packedGridPos = packTileID(x, y);
90 if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end())
91 return false;
92
93 // load this tile :: mmaps/MMMM_XX_YY.mmtile
94 uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%04i_%02i_%02i.mmtile") + 1;
95 char* fileName = new char[pathLen];
96
97 snprintf(fileName, pathLen, (sWorld->GetDataPath() + "mmaps/%04i_%02i_%02i.mmtile").c_str(), mapId, x, y);
98
99 FILE* file = fopen(fileName, "rb");
100 if (!file)
101 {
102 SF_LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '%s'", fileName);
103 delete[] fileName;
104 return false;
105 }
106 delete[] fileName;
107
108 // read header
109 MmapTileHeader fileHeader;
110 if (fread(&fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || fileHeader.mmapMagic != MMAP_MAGIC)
111 {
112 SF_LOG_ERROR("maps", "MMAP:loadMap: Bad header in mmap %04u_%02i_%02i.mmtile", mapId, x, y);
113 fclose(file);
114 return false;
115 }
116
117 if (fileHeader.mmapVersion != MMAP_VERSION)
118 {
119 SF_LOG_ERROR("maps", "MMAP:loadMap: %04u_%02i_%02i.mmtile was built with generator v%f, expected v%f",
120 mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION);
121 fclose(file);
122 return false;
123 }
124
125 unsigned char* data = (unsigned char*)dtAlloc(fileHeader.size, DT_ALLOC_PERM);
126 ASSERT(data);
127
128 size_t result = fread(data, fileHeader.size, 1, file);
129 if (!result)
130 {
131 SF_LOG_ERROR("maps", "MMAP:loadMap: Bad header or data in mmap %04u_%02i_%02i.mmtile", mapId, x, y);
132 fclose(file);
133 return false;
134 }
135
136 fclose(file);
137
138 dtMeshHeader* header = (dtMeshHeader*)data;
139 dtTileRef tileRef = 0;
140
141 // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
142 if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, 0/*DT_TILE_FREE_DATA*/, 0, &tileRef)))
143 {
144 mmap->loadedTileRefs.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
145 ++loadedTiles;
146 SF_LOG_INFO("maps", "MMAP:loadMap: Loaded mmtile %04i[%02i, %02i] into %04i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y);
147
148 LoadPhaseTiles(mapId, x, y);
149
150 return true;
151 }
152 else
153 {
154 SF_LOG_ERROR("maps", "MMAP:loadMap: Could not load %04u_%02i_%02i.mmtile into navmesh", mapId, x, y);
155 dtFree(data);
156 return false;
157 }
158
159 return false;
160 }
161
163 {
164 // load this tile :: mmaps/MMMM_XX_YY.mmtile
165 uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%04i_%02i_%02i.mmtile") + 1;
166 char* fileName = new char[pathLen];
167
168 snprintf(fileName, pathLen, (sWorld->GetDataPath() + "mmaps/%04i_%02i_%02i.mmtile").c_str(), mapId, x, y);
169
170 FILE* file = fopen(fileName, "rb");
171 if (!file)
172 {
173 // Not all tiles have phased versions, don't flood this msg
174 //SF_LOG_DEBUG("phase", "MMAP:LoadTile: Could not open mmtile file '%s'", fileName);
175 delete[] fileName;
176 return NULL;
177 }
178 delete[] fileName;
179
180 PhasedTile* pTile = new PhasedTile();
181
182 // read header
183 if (fread(&pTile->fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || pTile->fileHeader.mmapMagic != MMAP_MAGIC)
184 {
185 SF_LOG_ERROR("phase", "MMAP:LoadTile: Bad header in mmap %04u_%02i_%02i.mmtile", mapId, x, y);
186 delete pTile;
187 fclose(file);
188 return NULL;
189 }
190
191 if (pTile->fileHeader.mmapVersion != MMAP_VERSION)
192 {
193 SF_LOG_ERROR("phase", "MMAP:LoadTile: %04u_%02i_%02i.mmtile was built with generator v%f, expected v%f",
194 mapId, x, y, pTile->fileHeader.mmapVersion, MMAP_VERSION);
195 delete pTile;
196 fclose(file);
197 return NULL;
198 }
199
200 pTile->data = (unsigned char*)dtAlloc(pTile->fileHeader.size, DT_ALLOC_PERM);
201 ASSERT(pTile->data);
202
203 size_t result = fread(pTile->data, pTile->fileHeader.size, 1, file);
204 if (!result)
205 {
206 SF_LOG_ERROR("phase", "MMAP:LoadTile: Bad header or data in mmap %04u_%02i_%02i.mmtile", mapId, x, y);
207 delete pTile;
208 fclose(file);
209 return NULL;
210 }
211
212 fclose(file);
213
214 return pTile;
215 }
216
218 {
219 SF_LOG_DEBUG("phase", "MMAP:LoadPhaseTiles: Loading phased mmtiles for map %u, x: %i, y: %i", mapId, x, y);
220
221 uint32 packedGridPos = packTileID(x, y);
222
223 for (uint32 i = 0; i < sMapStore.GetNumRows(); ++i)
224 {
225 if (const MapEntry * const map = sMapStore.LookupEntry(i))
226 {
227 if (map->rootPhaseMap == mapId)
228 {
229 PhasedTile* data = LoadTile(map->MapID, x, y);
230 // only a few tiles have terrain swaps, do not write error for them
231 if (data)
232 {
233 SF_LOG_DEBUG("phase", "MMAP:LoadPhaseTiles: Loaded phased %04u_%02i_%02i.mmtile for root phase map %u", map->MapID, x, y, mapId);
234 _phaseTiles[map->MapID][packedGridPos] = data;
235 }
236 }
237 }
238 }
239 }
240
242 {
243 SF_LOG_DEBUG("phase", "MMAP:UnloadPhaseTile: Unloading phased mmtile for map %u, x: %i, y: %i", mapId, x, y);
244
245 uint32 packedGridPos = packTileID(x, y);
246
247 const MapEntry* const map = sMapStore.LookupEntry(mapId); // map existence already checked when loading
248 uint32 rootMapId = map->rootPhaseMap;
249
250 if (_phaseTiles[mapId][packedGridPos])
251 {
252 SF_LOG_DEBUG("phase", "MMAP:UnloadPhaseTile: Unloaded phased %04u_%02i_%02i.mmtile for root phase map %u", mapId, x, y, rootMapId);
253 delete _phaseTiles[mapId][packedGridPos]->data;
254 delete _phaseTiles[mapId][packedGridPos];
255 _phaseTiles[mapId].erase(packedGridPos);
256 }
257 }
258
260 {
261 // check if we have this map loaded
262 if (loadedMMaps.find(mapId) == loadedMMaps.end())
263 {
264 // file may not exist, therefore not loaded
265 SF_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. %04u_%02i_%02i.mmtile", mapId, x, y);
266 return false;
267 }
268
269 MMapData* mmap = loadedMMaps[mapId];
270
271 // check if we have this tile loaded
272 uint32 packedGridPos = packTileID(x, y);
273 if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end())
274 {
275 // file may not exist, therefore not loaded
276 SF_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %04u_%02i_%02i.mmtile", mapId, x, y);
277 return false;
278 }
279
280 dtTileRef tileRef = mmap->loadedTileRefs[packedGridPos];
281
282 // unload, and mark as non loaded
283 if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, NULL, NULL)))
284 {
285 // this is technically a memory leak
286 // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
287 // we cannot recover from this error - assert out
288 SF_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %04u_%02i_%02i.mmtile from navmesh", mapId, x, y);
289 ASSERT(false);
290 }
291 else
292 {
293 mmap->loadedTileRefs.erase(packedGridPos);
294 --loadedTiles;
295 SF_LOG_INFO("maps", "MMAP:unloadMap: Unloaded mmtile %04i[%02i, %02i] from %04i", mapId, x, y, mapId);
296
297 UnloadPhaseTile(mapId, x, y);
298 return true;
299 }
300
301 return false;
302 }
303
305 {
306 if (loadedMMaps.find(mapId) == loadedMMaps.end())
307 {
308 // file may not exist, therefore not loaded
309 SF_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %04u", mapId);
310 return false;
311 }
312
313 // unload all tiles from given map
314 MMapData* mmap = loadedMMaps[mapId];
315 for (MMapTileSet::iterator i = mmap->loadedTileRefs.begin(); i != mmap->loadedTileRefs.end(); ++i)
316 {
317 uint32 x = (i->first >> 16);
318 uint32 y = (i->first & 0x0000FFFF);
319 if (dtStatusFailed(mmap->navMesh->removeTile(i->second, NULL, NULL)))
320 SF_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %04u_%02i_%02i.mmtile from navmesh", mapId, x, y);
321 else
322 {
323 UnloadPhaseTile(mapId, x, y);
324 --loadedTiles;
325 SF_LOG_INFO("maps", "MMAP:unloadMap: Unloaded mmtile %04i[%02i, %02i] from %04i", mapId, x, y, mapId);
326 }
327 }
328
329 delete mmap;
330 loadedMMaps.erase(mapId);
331 SF_LOG_INFO("maps", "MMAP:unloadMap: Unloaded %04i.mmap", mapId);
332
333 return true;
334 }
335
337 {
338 // check if we have this map loaded
339 if (loadedMMaps.find(mapId) == loadedMMaps.end())
340 {
341 // file may not exist, therefore not loaded
342 SF_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %04u", mapId);
343 return false;
344 }
345
346 MMapData* mmap = loadedMMaps[mapId];
347 if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
348 {
349 SF_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %04u instanceId %u", mapId, instanceId);
350 return false;
351 }
352
353 dtNavMeshQuery* query = mmap->navMeshQueries[instanceId];
354
355 dtFreeNavMeshQuery(query);
356 mmap->navMeshQueries.erase(instanceId);
357 SF_LOG_INFO("maps", "MMAP:unloadMapInstance: Unloaded mapId %04u instanceId %u", mapId, instanceId);
358
359 return true;
360 }
361
362 dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId, TerrainSet swaps)
363 {
364 if (loadedMMaps.find(mapId) == loadedMMaps.end())
365 return NULL;
366
367 return loadedMMaps[mapId]->GetNavMesh(swaps);
368 }
369
370 dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId, TerrainSet swaps)
371 {
372 if (loadedMMaps.find(mapId) == loadedMMaps.end())
373 return NULL;
374
375 MMapData* mmap = loadedMMaps[mapId];
376 if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end())
377 {
378 // allocate mesh query
379 dtNavMeshQuery* query = dtAllocNavMeshQuery();
380 ASSERT(query);
381 if (dtStatusFailed(query->init(mmap->GetNavMesh(swaps), 1024)))
382 {
383 dtFreeNavMeshQuery(query);
384 SF_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId);
385 return NULL;
386 }
387
388 SF_LOG_INFO("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId);
389 mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query));
390 }
391
392 return mmap->navMeshQueries[instanceId];
393 }
394
396 {
397 for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i)
398 dtFreeNavMeshQuery(i->second);
399
400 dtFreeNavMesh(navMesh);
401
402 for (PhaseTileContainer::iterator i = _baseTiles.begin(); i != _baseTiles.end(); ++i)
403 {
404 delete (*i).second->data;
405 delete (*i).second;
406 }
407 }
408
409 void MMapData::RemoveSwap(PhasedTile* ptile, uint32 swap, uint32 packedXY)
410 {
411 uint32 x = (packedXY >> 16);
412 uint32 y = (packedXY & 0x0000FFFF);
413
414 if (loadedPhasedTiles[swap].find(packedXY) == loadedPhasedTiles[swap].end())
415 {
416 SF_LOG_DEBUG("phase", "MMapData::RemoveSwap: mmtile %04u[%02i, %02i] unload skipped, due to not loaded", swap, x, y);
417 return;
418 }
419 dtMeshHeader* header = (dtMeshHeader*)ptile->data;
420
421 // remove old tile
422 if (dtStatusFailed(navMesh->removeTile(loadedTileRefs[packedXY], NULL, NULL)))
423 SF_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not unload phased %04u_%02i_%02i.mmtile from navmesh", swap, x, y);
424 else
425 {
426 SF_LOG_DEBUG("phase", "MMapData::RemoveSwap: Unloaded phased %04u_%02i_%02i.mmtile from navmesh", swap, x, y);
427
428 // restore base tile
429 if (dtStatusSucceed(navMesh->addTile(_baseTiles[packedXY]->data, _baseTiles[packedXY]->dataSize, 0, 0, &loadedTileRefs[packedXY])))
430 {
431 SF_LOG_DEBUG("phase", "MMapData::RemoveSwap: Loaded base mmtile %04u[%02i, %02i] into %04i[%02i, %02i]", _mapId, x, y, _mapId, header->x, header->y);
432 }
433 else
434 SF_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not load base %04u_%02i_%02i.mmtile to navmesh", _mapId, x, y);
435 }
436
437 loadedPhasedTiles[swap].erase(packedXY);
438
439 if (loadedPhasedTiles[swap].empty())
440 {
441 _activeSwaps.erase(swap);
442 SF_LOG_DEBUG("phase", "MMapData::RemoveSwap: Fully removed swap %u from map %u", swap, _mapId);
443 }
444 }
445
446 void MMapData::AddSwap(PhasedTile* ptile, uint32 swap, uint32 packedXY)
447 {
448 uint32 x = (packedXY >> 16);
449 uint32 y = (packedXY & 0x0000FFFF);
450
451 if (loadedTileRefs.find(packedXY) == loadedTileRefs.end())
452 {
453 SF_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %04u[%02i, %02i] load skipped, due to not loaded base tile on map %u", swap, x, y, _mapId);
454 return;
455 }
456 if (loadedPhasedTiles[swap].find(packedXY) != loadedPhasedTiles[swap].end())
457 {
458 SF_LOG_DEBUG("phase", "MMapData::AddSwap: WARNING! phased mmtile %04u[%02i, %02i] load skipped, due to already loaded on map %u", swap, x, y, _mapId);
459 return;
460 }
461
462
463 dtMeshHeader* header = (dtMeshHeader*)ptile->data;
464
465 const dtMeshTile* oldTile = navMesh->getTileByRef(loadedTileRefs[packedXY]);
466 if (!oldTile)
467 {
468 SF_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %04u[%02i, %02i] load skipped, due to not loaded base tile ref on map %u", swap, x, y, _mapId);
469 return;
470 }
471
472 uint32 old_x = oldTile->header->x;
473 uint32 old_y = oldTile->header->y;
474
475 // header xy is based on the swap map's tile set, wich doesn't have all the same tiles as root map, so copy the xy from the orignal header
476 memcpy(ptile->data + 8, (char*)& old_x, 4);
477 memcpy(ptile->data + 12, (char*)& old_y, 4);
478
479 // the removed tile's data
480 PhasedTile* pt = new PhasedTile();
481 // remove old tile
482 if (dtStatusFailed(navMesh->removeTile(loadedTileRefs[packedXY], &pt->data, &pt->dataSize)))
483 SF_LOG_ERROR("phase", "MMapData::AddSwap: Could not unload %04u_%02i_%02i.mmtile from navmesh", _mapId, x, y);
484 else
485 {
486 SF_LOG_DEBUG("phase", "MMapData::AddSwap: Unloaded %04u_%02i_%02i.mmtile from navmesh", _mapId, x, y);
487
488 // store the removed data first time, this is the origonal, non-phased tile
489 if (_baseTiles.find(packedXY) == _baseTiles.end())
490 _baseTiles[packedXY] = pt;
491
492 _activeSwaps.insert(swap);
493 loadedPhasedTiles[swap].insert(packedXY);
494
495 // add new swapped tile
496 if (dtStatusSucceed(navMesh->addTile(ptile->data, ptile->fileHeader.size, 0, 0, &loadedTileRefs[packedXY])))
497 {
498 SF_LOG_DEBUG("phase", "MMapData::AddSwap: Loaded phased mmtile %04u[%02i, %02i] into %04i[%02i, %02i]", swap, x, y, _mapId, header->x, header->y);
499 }
500 else
501 SF_LOG_ERROR("phase", "MMapData::AddSwap: Could not load %04u_%02i_%02i.mmtile to navmesh", swap, x, y);
502 }
503 }
504
506 {
507 for (uint32 swap : _activeSwaps)
508 {
509 if (swaps.find(swap) == swaps.end()) // swap not active
510 {
512 for (PhaseTileContainer::const_iterator itr = ptc.begin(); itr != ptc.end(); ++itr)
513 {
514 RemoveSwap(itr->second, swap, itr->first); // remove swap
515 }
516 }
517 }
518
519 if (!swaps.empty())
520 {
521 // for each of the calling unit's terrain swaps
522 for (uint32 swap : swaps)
523 {
524 // for each of the terrain swap's xy tiles
526 for (PhaseTileContainer::const_iterator itr = ptc.begin(); itr != ptc.end(); ++itr)
527 {
528 if (_activeSwaps.find(swap) == _activeSwaps.end()) // swap not active
529 {
530 AddSwap(itr->second, swap, itr->first); // add swap
531 }
532 }
533 }
534 }
535 return navMesh;
536 }
537}
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
std::int32_t int32
Definition Define.h:73
std::uint32_t uint32
Definition Define.h:77
#define ASSERT
Definition Errors.h:29
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
#define SF_LOG_INFO(filterType__,...)
Definition Log.h:137
#define MMAP_MAGIC
#define MMAP_VERSION
void RemoveSwap(PhasedTile *ptile, uint32 swap, uint32 packedXY)
TerrainSetMap loadedPhasedTiles
Definition MMapManager.h:65
dtNavMesh * GetNavMesh(TerrainSet swaps)
PhaseTileContainer _baseTiles
Definition MMapManager.h:69
dtNavMesh * navMesh
Definition MMapManager.h:63
std::set< uint32 > _activeSwaps
Definition MMapManager.h:70
void AddSwap(PhasedTile *tile, uint32 swap, uint32 packedXY)
NavMeshQuerySet navMeshQueries
Definition MMapManager.h:61
MMapTileSet loadedTileRefs
Definition MMapManager.h:64
static MMapManager * createOrGetMMapManager()
dtNavMeshQuery const * GetNavMeshQuery(uint32 mapId, uint32 instanceId, TerrainSet swaps)
bool unloadMap(uint32 mapId, int32 x, int32 y)
bool loadMap(const std::string &basePath, uint32 mapId, int32 x, int32 y)
dtNavMesh const * GetNavMesh(uint32 mapId, TerrainSet swaps)
void UnloadPhaseTile(uint32 mapId, int32 x, int32 y)
bool loadMapData(uint32 mapId)
PhaseTileMap _phaseTiles
MMapDataSet loadedMMaps
uint32 packTileID(int32 x, int32 y)
void LoadPhaseTiles(uint32 mapId, int32 x, int32 y)
bool unloadMapInstance(uint32 mapId, uint32 instanceId)
PhaseTileContainer GetPhaseTileContainer(uint32 mapId)
PhasedTile * LoadTile(uint32 mapId, int32 x, int32 y)
#define sWorld
Definition World.h:910
std::set< uint32 > TerrainSet
Definition MMapManager.h:25
UNORDERED_MAP< uint32, PhasedTile * > PhaseTileContainer
Definition MMapManager.h:45
unsigned char * data
Definition MMapManager.h:40
MmapTileHeader fileHeader
Definition MMapManager.h:41
int32 rootPhaseMap