bool StaticMapTree::InitMap(const std::string &fname, VMapManager2 *vm) { sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : 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 = bool(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 sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : map isTiled: %u", static_cast<uint32>(iIsTiled)); #endif if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn)) { WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name); sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::InitMap() : loading %s", spawn.name.c_str()); if (model) { // 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; sLog->outError( "StaticMapTree::InitMap() : could not acquire WorldModel pointer for '%s'", spawn.name.c_str()); } } fclose(rf); } return success; }
bool MeshRenderComponent::VInit(TiXmlElement* _pData) { Asset = WE_NEW ModelAsset(); LoadAsset(); Instance = WE_NEW ModelInstance(); Instance->asset = Asset; return true; }
bool StaticMapTree::init(const std::string &fname, VMapManager2 *vm) { std::cout << "Initializing StaticMapTree '" << fname << "'\n"; 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 char tiled; if (fread(&tiled, sizeof(char), 1, rf) != 1) success = false; iIsTiled = (bool(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 std::cout << "Map isTiled:" << bool(iIsTiled) << std::endl; #endif if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn)) { WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name); std::cout << "StaticMapTree::init(): loading " << spawn.name << std::endl; if (model) { // assume that global model always is the first and only tree value (could be improved...) iTreeValues[0] = ModelInstance(spawn, model); iLoadedSpawns[spawn.ID] = 1; } else { success = false; std::cout << "error: could not acquire WorldModel pointer!\n"; } } fclose(rf); } return success; }
bool StaticMapTree::InitMap(const std::string &fname, VMapManager2* vm) { VMAP_DEBUG_LOG("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; char chunk[8]; char tiled = '\0'; if (readChunk(rf, chunk, VMAP_MAGIC, 8) && fread(&tiled, sizeof(char), 1, rf) == 1 && readChunk(rf, chunk, "NODE", 4) && iTree.readFromFile(rf)) { iNTreeValues = iTree.primCount(); iTreeValues = new ModelInstance[iNTreeValues]; success = readChunk(rf, chunk, "GOBJ", 4); } iIsTiled = tiled != '\0'; // global model spawns // only non-tiled maps have them, and if so exactly one (so far at least...) ModelSpawn spawn; #ifdef VMAP_DEBUG TC_LOG_DEBUG("maps", "StaticMapTree::InitMap() : map isTiled: %u", static_cast<uint32>(iIsTiled)); #endif if (!iIsTiled && ModelSpawn::readFromFile(rf, spawn)) { WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name); VMAP_DEBUG_LOG("maps", "StaticMapTree::InitMap() : loading %s", spawn.name.c_str()); if (model) { // 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; VMAP_ERROR_LOG("misc", "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) { ERROR_LOG("StaticMapTree::LoadMapTile() could not acquire WorldModel pointer for '%s'!", spawn.name.c_str()); } // update tree uint32 referencedVal; size_t fileRead = fread(&referencedVal, sizeof(uint32), 1, tf); if (!iLoadedSpawns.count(referencedVal) || fileRead <= 0) { #ifdef VMAP_DEBUG if (referencedVal > iNTreeValues) { DEBUG_LOG("invalid tree element! (%u/%u)", referencedVal, iNTreeValues); continue; } #endif 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; }
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) { sLog->outError(LOG_FILTER_GENERAL, "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 = 0; 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) sLog->outError(LOG_FILTER_GENERAL, "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY); // update tree uint32 referencedVal; if (fread(&referencedVal, sizeof(uint32), 1, tf) == 1) { if (!iLoadedSpawns.count(referencedVal)) { #ifdef VMAP_DEBUG if (referencedVal > iNTreeValues) { sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::LoadMapTile() : invalid tree element (%u/%u)", referencedVal, iNTreeValues); continue; } #endif iTreeValues[referencedVal] = ModelInstance(spawn, model); iLoadedSpawns[referencedVal] = 1; } else { ++iLoadedSpawns[referencedVal]; #ifdef VMAP_DEBUG if (iTreeValues[referencedVal].ID != spawn.ID) sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::LoadMapTile() : trying to load wrong spawn in node"); else if (iTreeValues[referencedVal].name != spawn.name) sLog->outDebug(LOG_FILTER_MAPS, "StaticMapTree::LoadMapTile() : name collision on GUID=%u", spawn.ID); #endif } } else result = false; } } iLoadedTiles[packTileID(tileX, tileY)] = true; fclose(tf); } else iLoadedTiles[packTileID(tileX, tileY)] = false; return result; }
MapTile::MapTile(int pX, int pZ, const std::string& pFilename, bool pBigAlpha) { this->modelCount = 0; this->mPositionX = pX; this->mPositionZ = pZ; this->changed = 0; this->xbase = mPositionX * TILESIZE; this->zbase = mPositionZ * TILESIZE; this->mBigAlpha = pBigAlpha; for (int i = 0; i < 16; ++i) { for (int j = 0; j < 16; j++) { mChunks[i][j] = NULL; } } mFilename = pFilename; MPQFile theFile(mFilename); Log << "Opening tile " << mPositionX << ", " << mPositionZ << " (\"" << mFilename << "\") from " << (theFile.isExternal() ? "disk" : "MPQ") << "." << std::endl; // - Parsing the file itself. -------------------------- // We store this data to load it at the end. uint32_t lMCNKOffsets[256]; std::vector<ENTRY_MDDF> lModelInstances; std::vector<ENTRY_MODF> lWMOInstances; uint32_t fourcc; uint32_t size; MHDR Header; // - MVER ---------------------------------------------- uint32_t version; theFile.read(&fourcc, 4); theFile.seekRelative(4); theFile.read(&version, 4); assert(fourcc == 'MVER' && version == 18); // - MHDR ---------------------------------------------- theFile.read(&fourcc, 4); theFile.seekRelative(4); assert(fourcc == 'MHDR'); theFile.read(&Header, sizeof(MHDR)); mFlags = Header.flags; // - MCIN ---------------------------------------------- theFile.seek(Header.mcin + 0x14); theFile.read(&fourcc, 4); theFile.seekRelative(4); assert(fourcc == 'MCIN'); for (int i = 0; i < 256; ++i) { theFile.read(&lMCNKOffsets[i], 4); theFile.seekRelative(0xC); } // - MTEX ---------------------------------------------- theFile.seek(Header.mtex + 0x14); theFile.read(&fourcc, 4); theFile.read(&size, 4); assert(fourcc == 'MTEX'); { char* lCurPos = reinterpret_cast<char*>(theFile.getPointer()); char* lEnd = lCurPos + size; while (lCurPos < lEnd) { mTextureFilenames.push_back(std::string(lCurPos)); lCurPos += strlen(lCurPos) + 1; } } // - MMDX ---------------------------------------------- theFile.seek(Header.mmdx + 0x14); theFile.read(&fourcc, 4); theFile.read(&size, 4); assert(fourcc == 'MMDX'); { char* lCurPos = reinterpret_cast<char*>(theFile.getPointer()); char* lEnd = lCurPos + size; while (lCurPos < lEnd) { mModelFilenames.push_back(std::string(lCurPos)); lCurPos += strlen(lCurPos) + 1; } } // - MWMO ---------------------------------------------- theFile.seek(Header.mwmo + 0x14); theFile.read(&fourcc, 4); theFile.read(&size, 4); assert(fourcc == 'MWMO'); { char* lCurPos = reinterpret_cast<char*>(theFile.getPointer()); char* lEnd = lCurPos + size; while (lCurPos < lEnd) { mWMOFilenames.push_back(std::string(lCurPos)); lCurPos += strlen(lCurPos) + 1; } } // - MDDF ---------------------------------------------- theFile.seek(Header.mddf + 0x14); theFile.read(&fourcc, 4); theFile.read(&size, 4); assert(fourcc == 'MDDF'); ENTRY_MDDF* mddf_ptr = reinterpret_cast<ENTRY_MDDF*>(theFile.getPointer()); for (unsigned int i = 0; i < size / 36; ++i) { lModelInstances.push_back(mddf_ptr[i]); } // - MODF ---------------------------------------------- theFile.seek(Header.modf + 0x14); theFile.read(&fourcc, 4); theFile.read(&size, 4); assert(fourcc == 'MODF'); ENTRY_MODF* modf_ptr = reinterpret_cast<ENTRY_MODF*>(theFile.getPointer()); for (unsigned int i = 0; i < size / 64; ++i) { lWMOInstances.push_back(modf_ptr[i]); } // - MISC ---------------------------------------------- //! \todo Parse all chunks in the new style! // - MH2O ---------------------------------------------- if (Header.mh2o != 0) { theFile.seek(Header.mh2o + 0x14); theFile.read(&fourcc, 4); theFile.read(&size, 4); int ofsW = Header.mh2o + 0x14 + 0x8; assert(fourcc == 'MH2O'); Water = new TileWater(this, xbase, zbase); //has water Water->readFromFile(theFile, ofsW); //reading MH2O data at separated class... } else{ Water = new TileWater(this, xbase, zbase); //empty water tile } // - MFBO ---------------------------------------------- if (mFlags & 1) { theFile.seek(Header.mfbo + 0x14); theFile.read(&fourcc, 4); theFile.read(&size, 4); assert(fourcc == 'MFBO'); int16_t mMaximum[9], mMinimum[9]; theFile.read(mMaximum, sizeof(mMaximum)); theFile.read(mMinimum, sizeof(mMinimum)); static const float xPositions[] = { this->xbase, this->xbase + 266.0f, this->xbase + 533.0f }; static const float yPositions[] = { this->zbase, this->zbase + 266.0f, this->zbase + 533.0f }; for (int y = 0; y < 3; y++) { for (int x = 0; x < 3; x++) { int pos = x + y * 3; mMinimumValues[pos * 3 + 0] = xPositions[x]; mMinimumValues[pos * 3 + 1] = mMinimum[pos]; mMinimumValues[pos * 3 + 2] = yPositions[y]; mMaximumValues[pos * 3 + 0] = xPositions[x]; mMaximumValues[pos * 3 + 1] = mMaximum[pos]; mMaximumValues[pos * 3 + 2] = yPositions[y]; } } } // - MTFX ---------------------------------------------- /* //! \todo Implement this or just use Terrain Cube maps? Log << "MTFX offs: " << Header.mtfx << std::endl; if(Header.mtfx != 0){ Log << "Try to load MTFX" << std::endl; theFile.seek( Header.mtfx + 0x14 ); theFile.read( &fourcc, 4 ); theFile.read( &size, 4 ); assert( fourcc == 'MTFX' ); { char* lCurPos = reinterpret_cast<char*>( theFile.getPointer() ); char* lEnd = lCurPos + size; int tCount = 0; while( lCurPos < lEnd ) { int temp = 0; theFile.read(&temp, 4); Log << "Adding to " << mTextureFilenames[tCount].first << " texture effect: " << temp << std::endl; mTextureFilenames[tCount++].second = temp; lCurPos += 4; } } }*/ // - Done. --------------------------------------------- // - Load textures ------------------------------------- //! \note We no longer pre load textures but the chunks themselves do. // - Load WMOs ----------------------------------------- for (std::vector<ENTRY_MODF>::iterator it = lWMOInstances.begin(); it != lWMOInstances.end(); ++it) { gWorld->mWMOInstances.insert(std::pair<int, WMOInstance>(it->uniqueID, WMOInstance(WMOManager::add(mWMOFilenames[it->nameID]), &(*it)))); } // - Load M2s ------------------------------------------ for (std::vector<ENTRY_MDDF>::iterator it = lModelInstances.begin(); it != lModelInstances.end(); ++it) { gWorld->mModelInstances.insert(std::pair<int, ModelInstance>(it->uniqueID, ModelInstance(ModelManager::add(mModelFilenames[it->nameID]), &(*it)))); } // - Load chunks --------------------------------------- for (int nextChunk = 0; nextChunk < 256; ++nextChunk) { theFile.seek(lMCNKOffsets[nextChunk]); mChunks[nextChunk / 16][nextChunk % 16] = new MapChunk(this, &theFile, mBigAlpha); } theFile.close(); // - Really done. -------------------------------------- LogDebug << "Done loading tile " << mPositionX << "," << mPositionZ << "." << std::endl; }
bool StaticMapTree::loadMap(uint32 tileX, uint32 tileY, VMapManager2 *vm) { if (!iIsTiled) return true; if (!iTreeValues) { std::cout << "Tree has not been initialized!\n"; return false; } bool result = true; std::string tilefile = iBasePath + getTileFileName(iMapID, tileX, tileY); FILE* tf = fopen(tilefile.c_str(), "rb"); if(tf) { while(result) { // read model spawns ModelSpawn spawn; result = ModelSpawn::readFromFile(tf, spawn); if(result) { // acquire model instance WorldModel *model = vm->acquireModelInstance(iBasePath, spawn.name); if(!model) std::cout << "error: could not acquire WorldModel pointer!\n"; // update tree uint32 nNodeVal=0, referencedVal; fread(&nNodeVal, sizeof(uint32), 1, tf); #ifdef VMAP_DEBUG if(nNodeVal != 1) std::cout << "unexpected amount of affected NodeVals! (" << nNodeVal << ")\n"; #endif for (uint32 i=0; i<nNodeVal; ++i) { fread(&referencedVal, sizeof(uint32), 1, tf); if (!iLoadedSpawns.count(spawn.ID)) { #ifdef VMAP_DEBUG if (referencedVal > iNTreeValues) { std::cout << "invalid tree element! (" << referencedVal << "/" << iNTreeValues << ")\n"; continue; } #endif iTreeValues[referencedVal] = ModelInstance(spawn, model); iLoadedSpawns[spawn.ID] = 1; } else { ++iLoadedSpawns[spawn.ID]; #ifdef VMAP_DEBUG if (iTreeValues[referencedVal].ID != spawn.ID) std::cout << "error: trying to load wrong spawn in node!\n"; else if (iTreeValues[referencedVal].name != spawn.name) std::cout << "error: name collision on GUID="<< spawn.ID << "\n"; #endif } } } } iLoadedTiles[packTileID(tileX, tileY)] = true; fclose(tf); } else iLoadedTiles[packTileID(tileX, tileY)] = false; return result; }
bool 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; } bool result = true; TileFileOpenResult fileResult = OpenMapTileFile(iBasePath, iMapID, tileX, tileY, vm); if (fileResult.File) { char chunk[8]; if (!readChunk(fileResult.File, chunk, VMAP_MAGIC, 8)) result = false; uint32 numSpawns = 0; if (result && fread(&numSpawns, sizeof(uint32), 1, fileResult.File) != 1) result = false; for (uint32 i=0; i<numSpawns && result; ++i) { // read model spawns ModelSpawn spawn; result = ModelSpawn::readFromFile(fileResult.File, spawn); if (result) { // acquire model instance WorldModel* model = vm->acquireModelInstance(iBasePath, spawn.name, spawn.flags); if (!model) TC_LOG_ERROR("misc", "StaticMapTree::LoadMapTile() : could not acquire WorldModel pointer [%u, %u]", tileX, tileY); // update tree auto spawnIndex = iSpawnIndices.find(spawn.ID); if (spawnIndex != iSpawnIndices.end()) { uint32 referencedVal = spawnIndex->second; if (!iLoadedSpawns.count(referencedVal)) { if (referencedVal >= iNTreeValues) { TC_LOG_ERROR("maps", "StaticMapTree::LoadMapTile() : invalid tree element (%u/%u) referenced in tile %s", referencedVal, iNTreeValues, fileResult.Name.c_str()); continue; } iTreeValues[referencedVal] = ModelInstance(spawn, model); iLoadedSpawns[referencedVal] = 1; } else { ++iLoadedSpawns[referencedVal]; #ifdef VMAP_DEBUG if (iTreeValues[referencedVal].ID != spawn.ID) TC_LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : trying to load wrong spawn in node"); else if (iTreeValues[referencedVal].name != spawn.name) TC_LOG_DEBUG("maps", "StaticMapTree::LoadMapTile() : name collision on GUID=%u", spawn.ID); #endif } } else result = false; } } iLoadedTiles[packTileID(tileX, tileY)] = true; fclose(fileResult.File); } else iLoadedTiles[packTileID(tileX, tileY)] = false; TC_METRIC_EVENT("map_events", "LoadMapTile", "Map: " + std::to_string(iMapID) + " TileX: " + std::to_string(tileX) + " TileY: " + std::to_string(tileY)); return result; }