aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Collision/Management/IVMapManager.h3
-rw-r--r--src/common/Collision/Management/VMapManager2.cpp20
-rw-r--r--src/common/Collision/Management/VMapManager2.h2
-rw-r--r--src/common/Collision/Maps/MapTree.cpp72
-rw-r--r--src/common/Collision/Maps/MapTree.h7
5 files changed, 65 insertions, 39 deletions
diff --git a/src/common/Collision/Management/IVMapManager.h b/src/common/Collision/Management/IVMapManager.h
index 3d760082e28..e779878b8e0 100644
--- a/src/common/Collision/Management/IVMapManager.h
+++ b/src/common/Collision/Management/IVMapManager.h
@@ -43,7 +43,8 @@ namespace VMAP
{
Success,
FileNotFound,
- VersionMismatch
+ VersionMismatch,
+ ReadFromFileFailed
};
#define VMAP_INVALID_HEIGHT -100000.0f // for check
diff --git a/src/common/Collision/Management/VMapManager2.cpp b/src/common/Collision/Management/VMapManager2.cpp
index 88494d0a0c7..ed4e5535250 100644
--- a/src/common/Collision/Management/VMapManager2.cpp
+++ b/src/common/Collision/Management/VMapManager2.cpp
@@ -104,14 +104,21 @@ namespace VMAP
int result = VMAP_LOAD_RESULT_IGNORED;
if (isMapLoadingEnabled())
{
- if (loadSingleMap(mapId, basePath, x, y))
+ LoadResult parentLoadResult = loadSingleMap(mapId, basePath, x, y);
+ if (parentLoadResult == LoadResult::Success || parentLoadResult == LoadResult::FileNotFound)
{
- result = VMAP_LOAD_RESULT_OK;
+ if (parentLoadResult == LoadResult::Success)
+ result = VMAP_LOAD_RESULT_OK;
+ // else VMAP_LOAD_RESULT_IGNORED
+
auto childMaps = iChildMapData.find(mapId);
if (childMaps != iChildMapData.end())
for (uint32 childMapId : childMaps->second)
- if (!loadSingleMap(childMapId, basePath, x, y))
+ {
+ LoadResult childLoadResult = loadSingleMap(childMapId, basePath, x, y);
+ if (childLoadResult != LoadResult::Success && childLoadResult != LoadResult::FileNotFound)
result = VMAP_LOAD_RESULT_ERROR;
+ }
}
else
result = VMAP_LOAD_RESULT_ERROR;
@@ -121,7 +128,7 @@ namespace VMAP
}
// load one tile (internal use only)
- bool VMapManager2::loadSingleMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY)
+ LoadResult VMapManager2::loadSingleMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY)
{
auto instanceTree = iInstanceMapTrees.find(mapId);
if (instanceTree == iInstanceMapTrees.end())
@@ -137,10 +144,11 @@ namespace VMAP
{
std::string mapFileName = getMapFileName(mapId);
StaticMapTree* newTree = new StaticMapTree(mapId, basePath);
- if (!newTree->InitMap(mapFileName))
+ LoadResult treeInitResult = newTree->InitMap(mapFileName);
+ if (treeInitResult != LoadResult::Success)
{
delete newTree;
- return false;
+ return treeInitResult;
}
instanceTree->second = newTree;
}
diff --git a/src/common/Collision/Management/VMapManager2.h b/src/common/Collision/Management/VMapManager2.h
index 76253faded4..024c1619a2f 100644
--- a/src/common/Collision/Management/VMapManager2.h
+++ b/src/common/Collision/Management/VMapManager2.h
@@ -102,7 +102,7 @@ namespace VMAP
void InitializeThreadUnsafe(std::unordered_map<uint32, std::vector<uint32>> const& mapData);
int loadMap(char const* pBasePath, unsigned int mapId, int x, int y) override;
- bool loadSingleMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
+ LoadResult loadSingleMap(uint32 mapId, const std::string& basePath, uint32 tileX, uint32 tileY);
void unloadMap(unsigned int mapId, int x, int y) override;
void unloadSingleMap(uint32 mapId, int x, int y);
diff --git a/src/common/Collision/Maps/MapTree.cpp b/src/common/Collision/Maps/MapTree.cpp
index 04f914fb4f1..7249a0cf1a2 100644
--- a/src/common/Collision/Maps/MapTree.cpp
+++ b/src/common/Collision/Maps/MapTree.cpp
@@ -240,6 +240,7 @@ namespace VMAP
TileFileOpenResult result;
result.Name = basePath + getTileFileName(mapID, tileX, tileY);
result.File = fopen(result.Name.c_str(), "rb");
+ result.UsedMapId = mapID;
if (!result.File)
{
int32 parentMapId = vm->getParentMapId(mapID);
@@ -247,6 +248,7 @@ namespace VMAP
{
result.Name = basePath + getTileFileName(parentMapId, tileX, tileY);
result.File = fopen(result.Name.c_str(), "rb");
+ result.UsedMapId = parentMapId;
if (result.File)
break;
@@ -302,44 +304,47 @@ namespace VMAP
//=========================================================
- bool StaticMapTree::InitMap(std::string const& fname)
+ LoadResult StaticMapTree::InitMap(std::string const& fname)
{
TC_LOG_DEBUG("maps", "StaticMapTree::InitMap() : initializing StaticMapTree '%s'", fname.c_str());
- bool success = false;
std::string fullname = iBasePath + fname;
FILE* rf = fopen(fullname.c_str(), "rb");
if (!rf)
- return false;
+ return LoadResult::FileNotFound;
+ LoadResult result = LoadResult::Success;
char chunk[8];
- if (readChunk(rf, chunk, VMAP_MAGIC, 8) &&
+ if (!readChunk(rf, chunk, VMAP_MAGIC, 8))
+ result = LoadResult::VersionMismatch;
+
+ if (result == LoadResult::Success &&
readChunk(rf, chunk, "NODE", 4) &&
iTree.readFromFile(rf))
{
iNTreeValues = iTree.primCount();
iTreeValues = new ModelInstance[iNTreeValues];
- success = true;
+ result = LoadResult::Success;
}
- if (success)
+ if (result == LoadResult::Success)
{
- success = readChunk(rf, chunk, "SIDX", 4);
+ result = readChunk(rf, chunk, "SIDX", 4) ? LoadResult::Success : LoadResult::ReadFromFileFailed;
uint32 spawnIndicesSize = 0;
uint32 spawnId;
- uint32 spawnIndex;
- if (success && fread(&spawnIndicesSize, sizeof(uint32), 1, rf) != 1) success = false;
- for (uint32 i = 0; i < spawnIndicesSize && success; ++i)
+ if (result == LoadResult::Success && fread(&spawnIndicesSize, sizeof(uint32), 1, rf) != 1)
+ result = LoadResult::ReadFromFileFailed;
+ for (uint32 i = 0; i < spawnIndicesSize && result == LoadResult::Success; ++i)
{
- if (fread(&spawnId, sizeof(uint32), 1, rf) == 1 && fread(&spawnIndex, sizeof(uint32), 1, rf) == 1)
- iSpawnIndices[spawnId] = spawnIndex;
+ if (fread(&spawnId, sizeof(uint32), 1, rf) == 1)
+ iSpawnIndices[spawnId] = i;
else
- success = false;
+ result = LoadResult::ReadFromFileFailed;
}
}
fclose(rf);
- return success;
+ return result;
}
//=========================================================
@@ -358,31 +363,31 @@ namespace VMAP
//=========================================================
- bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm)
+ LoadResult StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm)
{
if (!iTreeValues)
{
TC_LOG_ERROR("misc", "StaticMapTree::LoadMapTile() : tree has not been initialized [%u, %u]", tileX, tileY);
- return false;
+ return LoadResult::ReadFromFileFailed;
}
- bool result = true;
+ LoadResult result = LoadResult::FileNotFound;
TileFileOpenResult fileResult = OpenMapTileFile(iBasePath, iMapID, tileX, tileY, vm);
if (fileResult.File)
{
char chunk[8];
+ result = LoadResult::Success;
if (!readChunk(fileResult.File, chunk, VMAP_MAGIC, 8))
- result = false;
+ result = LoadResult::VersionMismatch;
uint32 numSpawns = 0;
- if (result && fread(&numSpawns, sizeof(uint32), 1, fileResult.File) != 1)
- result = false;
- for (uint32 i = 0; i < numSpawns && result; ++i)
+ if (result == LoadResult::Success && fread(&numSpawns, sizeof(uint32), 1, fileResult.File) != 1)
+ result = LoadResult::ReadFromFileFailed;
+ for (uint32 i = 0; i < numSpawns && result == LoadResult::Success; ++i)
{
// read model spawns
ModelSpawn spawn;
- result = ModelSpawn::readFromFile(fileResult.File, spawn);
- if (result)
+ if (ModelSpawn::readFromFile(fileResult.File, spawn))
{
// acquire model instance
WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name, spawn.flags);
@@ -416,8 +421,19 @@ namespace VMAP
#endif
}
}
- else
- result = false;
+ else if (int32(iMapID) == fileResult.UsedMapId)
+ {
+ // unknown parent spawn might appear in because it overlaps multiple tiles
+ // in case the original tile is swapped but its neighbour is now (adding this spawn)
+ // we want to not mark it as loading error and just skip that model
+ TC_LOG_ERROR("maps", "StaticMapTree::LoadMapTile() : invalid tree element (spawn %u) referenced in tile %s by map %u", spawn.ID, fileResult.Name.c_str(), iMapID);
+ result = LoadResult::ReadFromFileFailed;
+ }
+ }
+ else
+ {
+ TC_LOG_ERROR("maps", "StaticMapTree::LoadMapTile() : cannot read model from file (spawn index %u) referenced in tile %s by map %u", i, fileResult.Name.c_str(), iMapID);
+ result = LoadResult::ReadFromFileFailed;
}
}
iLoadedTiles[packTileID(tileX, tileY)] = true;
@@ -465,9 +481,7 @@ namespace VMAP
// update tree
auto spawnIndex = iSpawnIndices.find(spawn.ID);
- if (spawnIndex == iSpawnIndices.end())
- result = false;
- else
+ if (spawnIndex != iSpawnIndices.end())
{
uint32 referencedNode = spawnIndex->second;
if (!iLoadedSpawns.count(referencedNode))
@@ -478,6 +492,8 @@ namespace VMAP
iLoadedSpawns.erase(referencedNode);
}
}
+ else if (int32(iMapID) == fileResult.UsedMapId) // logic documented in StaticMapTree::LoadMapTile
+ result = false;
}
}
fclose(fileResult.File);
diff --git a/src/common/Collision/Maps/MapTree.h b/src/common/Collision/Maps/MapTree.h
index d2012ea7a30..8b96164bd7c 100644
--- a/src/common/Collision/Maps/MapTree.h
+++ b/src/common/Collision/Maps/MapTree.h
@@ -61,8 +61,9 @@ namespace VMAP
struct TileFileOpenResult
{
- FILE* File;
std::string Name;
+ FILE* File;
+ int32 UsedMapId;
};
private:
@@ -84,9 +85,9 @@ namespace VMAP
bool getAreaInfo(G3D::Vector3 &pos, uint32 &flags, int32 &adtId, int32 &rootId, int32 &groupId) const;
bool GetLocationInfo(const G3D::Vector3 &pos, LocationInfo &info) const;
- bool InitMap(std::string const& fname);
+ LoadResult InitMap(std::string const& fname);
void UnloadMap(VMapManager2* vm);
- bool LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
+ LoadResult LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
void UnloadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm);
uint32 numLoadedTiles() const { return uint32(iLoadedTiles.size()); }
void getModelInstances(ModelInstance* &models, uint32 &count);