bool StaticMapTree::InitMap(const std::string& fname, VMapManager2* vm) { DEBUG_FILTER_LOG(LOG_FILTER_MAP_LOADING, "Initializing StaticMapTree '%s'", fname.c_str()); bool success = true; std::string fullname = iBasePath + fname; FILE* rf = fopen(fullname.c_str(), "rb"); if (!rf) return false; else { char chunk[8]; // general info if (!readChunk(rf, chunk, VMAP_MAGIC, 8)) success = false; char tiled; if (success && fread(&tiled, sizeof(char), 1, rf) != 1) success = false; iIsTiled = !!tiled; // Nodes if (success && !readChunk(rf, chunk, "NODE", 4)) success = false; if (success) success = iTree.readFromFile(rf); if (success) { iNTreeValues = iTree.primCount(); iTreeValues = new ModelInstance[iNTreeValues]; } if (success && !readChunk(rf, chunk, "GOBJ", 4)) success = false; // global model spawns // only non-tiled maps have them, and if so exactly one (so far at least...) ModelSpawn spawn; #ifdef VMAP_DEBUG DEBUG_LOG("Map isTiled: %u", static_cast<uint32>(iIsTiled)); #endif if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn)) { WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name); DEBUG_FILTER_LOG(LOG_FILTER_MAP_LOADING, "StaticMapTree::InitMap(): loading %s", spawn.name.c_str()); if (model) { model->setModelFlags(spawn.flags); // assume that global model always is the first and only tree value (could be improved...) iTreeValues[0] = ModelInstance(spawn, model); iLoadedSpawns[0] = 1; } else { success = false; ERROR_LOG("StaticMapTree::InitMap() could not acquire WorldModel pointer for '%s'!", spawn.name.c_str()); } } fclose(rf); } return success; }
bool StaticMapTree::LoadMapTile(uint32 tileX, uint32 tileY, VMapManager2* vm) { if (!iIsTiled) { // currently, core creates grids for all maps, whether it has terrain tiles or not // so we need "fake" tile loads to know when we can unload map geometry iLoadedTiles[packTileID(tileX, tileY)] = false; return true; } if (!iTreeValues) { ERROR_LOG("StaticMapTree::LoadMapTile(): Tree has not been initialized! [%u,%u]", tileX, tileY); return false; } bool result = true; std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY); FILE* tf = fopen(tilefile.c_str(), "rb"); if (tf) { char chunk[8]; if (!readChunk(tf, chunk, VMAP_MAGIC, 8)) result = false; uint32 numSpawns; if (result && fread(&numSpawns, sizeof(uint32), 1, tf) != 1) result = false; for (uint32 i = 0; i < numSpawns && result; ++i) { // read model spawns ModelSpawn spawn; result = ModelSpawn::readFromFile(tf, spawn); if (result) { // acquire model instance WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name); if (model) model->setModelFlags(spawn.flags); else ERROR_LOG("StaticMapTree::LoadMapTile() could not acquire WorldModel pointer for '%s'!", spawn.name.c_str()); // update tree uint32 referencedVal; fread(&referencedVal, sizeof(uint32), 1, tf); if (!iLoadedSpawns.count(referencedVal)) { if (referencedVal > iNTreeValues) { ERROR_LOG("invalid tree element! (%u/%u)", referencedVal, iNTreeValues); continue; } iTreeValues[referencedVal] = ModelInstance(spawn, model); iLoadedSpawns[referencedVal] = 1; } else { ++iLoadedSpawns[referencedVal]; #ifdef VMAP_DEBUG if (iTreeValues[referencedVal].ID != spawn.ID) DEBUG_LOG("Error: trying to load wrong spawn in node!"); else if (iTreeValues[referencedVal].name != spawn.name) DEBUG_LOG("Error: name mismatch on GUID=%u", spawn.ID); #endif } } } iLoadedTiles[packTileID(tileX, tileY)] = true; fclose(tf); } else iLoadedTiles[packTileID(tileX, tileY)] = false; return result; }