From db7d754f3fdd96aa4221920eb6a504e77f3002e1 Mon Sep 17 00:00:00 2001 From: Kargatum Date: Fri, 7 May 2021 02:16:44 +0700 Subject: [PATCH] feat(Core/Common): delete lib game-interface inherited (#5333) Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> --- src/common/CMakeLists.txt | 2 - src/common/Collision/DynamicTree.cpp | 16 +- .../Collision/Management/IMMAPManager.h | 2 +- .../Collision/Management/IVMapManager.h | 3 +- .../Collision/Management/MMapFactory.cpp | 9 +- src/common/Collision/Management/MMapFactory.h | 4 +- .../Collision/Management/MMapManager.cpp | 175 ++++++++---------- src/common/Collision/Management/MMapManager.h | 21 +-- .../Collision/Management/VMapFactory.cpp | 9 +- src/common/Collision/Management/VMapFactory.h | 10 +- .../Collision/Management/VMapManager2.cpp | 105 +++++++---- .../Collision/Management/VMapManager2.h | 24 ++- src/common/Collision/Maps/MapDefines.h | 53 ++++++ src/common/Collision/Maps/MapTree.cpp | 6 + src/common/Collision/Maps/TileAssembler.cpp | 2 +- .../Collision/Models/GameObjectModel.cpp | 65 +++---- src/common/Collision/Models/GameObjectModel.h | 58 +++--- src/common/Collision/Models/ModelInstance.h | 6 +- src/common/Collision/Models/WorldModel.cpp | 19 ++ src/common/Collision/Models/WorldModel.h | 14 +- src/common/Collision/VMapTools.h | 4 +- src/common/PrecompiledHeaders/commonPCH.h | 2 - src/common/Utilities/Util.cpp | 3 +- src/server/game/Conditions/DisableMgr.cpp | 33 +++- src/server/game/Conditions/DisableMgr.h | 12 +- .../game/Entities/Creature/CreatureGroups.h | 4 +- .../game/Entities/GameObject/GameObject.cpp | 30 ++- .../game/Entities/GameObject/GameObject.h | 1 + .../game/Entities/Transport/Transport.cpp | 4 +- src/server/game/Entities/Unit/Unit.cpp | 3 +- src/server/game/Grids/GridDefines.h | 6 +- src/server/game/Handlers/PetHandler.cpp | 3 +- src/server/game/Maps/Map.cpp | 6 +- .../HomeMovementGenerator.cpp | 5 +- .../MovementGenerators/PathGenerator.cpp | 2 +- .../MovementGenerators/PathGenerator.h | 1 + .../game/Spells/Auras/SpellAuraEffects.cpp | 3 +- src/server/game/Spells/Spell.cpp | 8 +- src/server/game/World/World.cpp | 20 +- src/server/shared/SharedDefines.h | 38 ---- src/tools/mesh_extractor/Utils.h | 4 +- src/tools/mmaps_generator/MapBuilder.cpp | 33 +--- src/tools/mmaps_generator/PathCommon.h | 14 -- src/tools/mmaps_generator/TerrainBuilder.cpp | 3 +- src/tools/mmaps_generator/VMapExtensions.cpp | 58 ------ 45 files changed, 428 insertions(+), 475 deletions(-) create mode 100644 src/common/Collision/Maps/MapDefines.h delete mode 100644 src/tools/mmaps_generator/VMapExtensions.cpp diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index d06edcaf3..ebd34fe98 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -49,8 +49,6 @@ target_include_directories(common ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(common - PRIVATE - game-interface PUBLIC acore-core-interface ace diff --git a/src/common/Collision/DynamicTree.cpp b/src/common/Collision/DynamicTree.cpp index c7f8c87d2..2af4d3658 100644 --- a/src/common/Collision/DynamicTree.cpp +++ b/src/common/Collision/DynamicTree.cpp @@ -5,16 +5,12 @@ */ #include "DynamicTree.h" -//#include "QuadTree.h" -//#include "RegularGrid.h" #include "BoundingIntervalHierarchyWrapper.h" - #include "Log.h" #include "RegularGrid.h" #include "Timer.h" #include "GameObjectModel.h" #include "ModelInstance.h" - #include #include #include @@ -23,10 +19,8 @@ using VMAP::ModelInstance; namespace { - int CHECK_TREE_PERIOD = 200; - -} // namespace +} template<> struct HashTrait< GameObjectModel> { @@ -44,15 +38,9 @@ template<> struct BoundsTrait< GameObjectModel> static void getBounds2(const GameObjectModel* g, G3D::AABox& out) { out = g->getBounds();} }; -/* -static bool operator == (const GameObjectModel& mdl, const GameObjectModel& mdl2){ - return &mdl == &mdl2; -} -*/ - typedef RegularGrid2D> ParentTree; -struct DynTreeImpl : public ParentTree/*, public Intersectable*/ +struct DynTreeImpl : public ParentTree { typedef GameObjectModel Model; typedef ParentTree base; diff --git a/src/common/Collision/Management/IMMAPManager.h b/src/common/Collision/Management/IMMAPManager.h index ec05fc0bd..a558ab2c0 100644 --- a/src/common/Collision/Management/IMMAPManager.h +++ b/src/common/Collision/Management/IMMAPManager.h @@ -35,4 +35,4 @@ namespace MMAP }; } -#endif \ No newline at end of file +#endif diff --git a/src/common/Collision/Management/IVMapManager.h b/src/common/Collision/Management/IVMapManager.h index aa5cd6037..7d999c779 100644 --- a/src/common/Collision/Management/IVMapManager.h +++ b/src/common/Collision/Management/IVMapManager.h @@ -18,7 +18,6 @@ This is the minimum interface to the VMapMamager. namespace VMAP { - enum VMAP_LOAD_RESULT { VMAP_LOAD_RESULT_ERROR, @@ -83,6 +82,6 @@ namespace VMAP virtual bool getAreaInfo(unsigned int pMapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const = 0; virtual bool GetLiquidLevel(uint32 pMapId, float x, float y, float z, uint8 ReqLiquidType, float& level, float& floor, uint32& type) const = 0; }; - } + #endif diff --git a/src/common/Collision/Management/MMapFactory.cpp b/src/common/Collision/Management/MMapFactory.cpp index b5ea34a50..78dd941f8 100644 --- a/src/common/Collision/Management/MMapFactory.cpp +++ b/src/common/Collision/Management/MMapFactory.cpp @@ -5,7 +5,6 @@ */ #include "MMapFactory.h" -#include "World.h" #include namespace MMAP @@ -23,12 +22,6 @@ namespace MMAP return g_MMapManager; } - bool MMapFactory::IsPathfindingEnabled(const Map* map) - { - if (!map) return false; - return !forbiddenMaps[map->GetId()] && (sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS) ? true : map->IsBattlegroundOrArena()); - } - void MMapFactory::InitializeDisabledMaps() { memset(&forbiddenMaps, 0, sizeof(forbiddenMaps)); @@ -46,4 +39,4 @@ namespace MMAP g_MMapManager = nullptr; } } -} \ No newline at end of file +} diff --git a/src/common/Collision/Management/MMapFactory.h b/src/common/Collision/Management/MMapFactory.h index 30d440870..b25ccce69 100644 --- a/src/common/Collision/Management/MMapFactory.h +++ b/src/common/Collision/Management/MMapFactory.h @@ -10,8 +10,7 @@ #include "MMapManager.h" #include "DetourAlloc.h" #include "DetourNavMesh.h" -#include "Navigation/DetourExtended.h" -#include "Map.h" +#include "DetourExtended.h" #include namespace MMAP @@ -31,7 +30,6 @@ namespace MMAP public: static MMapManager* createOrGetMMapManager(); static void clear(); - static bool IsPathfindingEnabled(const Map* map); static void InitializeDisabledMaps(); static bool forbiddenMaps[1000]; }; diff --git a/src/common/Collision/Management/MMapManager.cpp b/src/common/Collision/Management/MMapManager.cpp index 1ccb13322..40fa34277 100644 --- a/src/common/Collision/Management/MMapManager.cpp +++ b/src/common/Collision/Management/MMapManager.cpp @@ -4,9 +4,10 @@ * Copyright (C) 2005-2009 MaNGOS */ -#include "Config.h" -#include "MapManager.h" #include "MMapManager.h" +#include "Config.h" +#include "Errors.h" +#include "MapDefines.h" #include "Log.h" #include "StringFormat.h" @@ -25,11 +26,41 @@ namespace MMAP // if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost! } + void MMapManager::InitializeThreadUnsafe(const std::vector& mapIds) + { + // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime + for (const uint32& mapId : mapIds) + loadedMMaps.emplace(mapId, nullptr); + + thread_safe_environment = false; + } + + MMapDataSet::const_iterator MMapManager::GetMMapData(uint32 mapId) const + { + // return the iterator if found or end() if not found/NULL + MMapDataSet::const_iterator itr = loadedMMaps.find(mapId); + if (itr != loadedMMaps.cend() && !itr->second) + itr = loadedMMaps.cend(); + + return itr; + } + bool MMapManager::loadMapData(uint32 mapId) { // we already have this map loaded? - if (loadedMMaps.find(mapId) != loadedMMaps.end()) - return true; + MMapDataSet::iterator itr = loadedMMaps.find(mapId); + if (itr != loadedMMaps.end()) + { + if (itr->second) + return true; + } + else + { + if (thread_safe_environment) + itr = loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)).first; + else + ASSERT(false, "Invalid mapId %u passed to MMapManager after startup in thread unsafe environment", mapId); + } // load and init dtNavMesh - read parameters from file std::string fileName = acore::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetOption("DataDir", ".").c_str(), mapId); @@ -37,18 +68,16 @@ namespace MMAP FILE* file = fopen(fileName.c_str(), "rb"); if (!file) { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName.c_str()); -#endif return false; } dtNavMeshParams params; - int count = fread(¶ms, sizeof(dtNavMeshParams), 1, file); + uint32 count = uint32(fread(¶ms, sizeof(dtNavMeshParams), 1, file)); fclose(file); if (count != 1) { - ;//TC_LOG_DEBUG(LOG_FILTER_MAPS, "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName); + LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName.c_str()); return false; } @@ -61,15 +90,11 @@ namespace MMAP return false; } -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - LOG_DEBUG("server", "MMAP:loadMapData: Loaded %03i.mmap", mapId); -#endif + LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %03i.mmap", mapId); // store inside our map list MMapData* mmap_data = new MMapData(mesh); - mmap_data->mmapLoadedTiles.clear(); - - loadedMMaps.insert(std::pair(mapId, mmap_data)); + itr->second = mmap_data; return true; } @@ -78,22 +103,8 @@ namespace MMAP return uint32(x << 16 | y); } - std::shared_mutex& MMapManager::GetMMapLock(uint32 mapId) - { - Map* map = sMapMgr->FindBaseMap(mapId); - if (!map) - { - LOG_INFO("misc", "ZOMG! MoveMaps: BaseMap not found!"); - return this->MMapLock; - } - - return map->GetMMapLock(); - } - bool MMapManager::loadMap(uint32 mapId, int32 x, int32 y) { - std::unique_lock guard(MMapManagerLock); - // make sure the mmap is loaded and ready to load tiles if (!loadMapData(mapId)) return false; @@ -104,7 +115,7 @@ namespace MMAP // check if we already have this tile loaded uint32 packedGridPos = packTileID(x, y); - if (mmap->mmapLoadedTiles.find(packedGridPos) != mmap->mmapLoadedTiles.end()) + if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end()) { LOG_ERROR("server", "MMAP:loadMap: Asked to load already loaded navmesh tile. %03u%02i%02i.mmtile", mapId, x, y); return false; @@ -151,26 +162,18 @@ namespace MMAP dtTileRef tileRef = 0; - dtStatus stat; - { - std::unique_lock guard(GetMMapLock(mapId)); - stat = mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef); - } - // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed - if (stat == DT_SUCCESS) + if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef))) { - mmap->mmapLoadedTiles.insert(std::pair(packedGridPos, tileRef)); + mmap->loadedTileRefs.insert(std::pair(packedGridPos, tileRef)); ++loadedTiles; -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) dtMeshHeader* header = (dtMeshHeader*)data; - LOG_DEBUG("server", "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, x, y, mapId, header->x, header->y); -#endif + LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %03i[%02i,%02i] into %03i[%02i,%02i]", mapId, x, y, mapId, header->x, header->y); return true; } else { - LOG_ERROR("server", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y); + LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y); dtFree(data); return false; } @@ -180,10 +183,9 @@ namespace MMAP bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y) { - std::unique_lock guard(MMapManagerLock); - // check if we have this map loaded - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::const_iterator itr = GetMMapData(mapId); + if (itr == loadedMMaps.end()) { // file may not exist, therefore not loaded #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) @@ -192,11 +194,11 @@ namespace MMAP return false; } - MMapData* mmap = loadedMMaps[mapId]; + MMapData* mmap = itr->second; // check if we have this tile loaded uint32 packedGridPos = packTileID(x, y); - if (mmap->mmapLoadedTiles.find(packedGridPos) == mmap->mmapLoadedTiles.end()) + if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end()) { // file may not exist, therefore not loaded #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) @@ -205,16 +207,10 @@ namespace MMAP return false; } - dtTileRef tileRef = mmap->mmapLoadedTiles[packedGridPos]; - - dtStatus status; - { - std::unique_lock guard(GetMMapLock(mapId)); - status = mmap->navMesh->removeTile(tileRef, nullptr, nullptr); - } + dtTileRef tileRef = mmap->loadedTileRefs[packedGridPos]; // unload, and mark as non loaded - if (status != DT_SUCCESS) + if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, nullptr, nullptr))) { // this is technically a memory leak // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used @@ -224,11 +220,9 @@ namespace MMAP } else { - mmap->mmapLoadedTiles.erase(packedGridPos); + mmap->loadedTileRefs.erase(packedGridPos); --loadedTiles; -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - LOG_DEBUG("server", "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId); -#endif + LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId); return true; } @@ -237,70 +231,52 @@ namespace MMAP bool MMapManager::unloadMap(uint32 mapId) { - std::unique_lock guard(MMapManagerLock); - - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::iterator itr = loadedMMaps.find(mapId); + if (itr == loadedMMaps.end() || !itr->second) { // file may not exist, therefore not loaded -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %03u", mapId); -#endif return false; } // unload all tiles from given map - MMapData* mmap = loadedMMaps[mapId]; - for (MMapTileSet::iterator i = mmap->mmapLoadedTiles.begin(); i != mmap->mmapLoadedTiles.end(); ++i) + MMapData* mmap = itr->second; + for (auto i : mmap->loadedTileRefs) { - uint32 x = (i->first >> 16); - uint32 y = (i->first & 0x0000FFFF); + uint32 x = (i.first >> 16); + uint32 y = (i.first & 0x0000FFFF); - dtStatus status; - { - std::unique_lock guard(GetMMapLock(mapId)); - status = mmap->navMesh->removeTile(i->second, nullptr, nullptr); - } - - if (status != DT_SUCCESS) + if (dtStatusFailed(mmap->navMesh->removeTile(i.second, nullptr, nullptr))) LOG_ERROR("server", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y); else { --loadedTiles; -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) LOG_DEBUG("server", "MMAP:unloadMap: Unloaded mmtile %03i[%02i,%02i] from %03i", mapId, x, y, mapId); -#endif } } delete mmap; - loadedMMaps.erase(mapId); -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - LOG_DEBUG("server", "MMAP:unloadMap: Unloaded %03i.mmap", mapId); -#endif + itr->second = nullptr; + LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %03i.mmap", mapId); return true; } bool MMapManager::unloadMapInstance(uint32 mapId, uint32 instanceId) { - std::unique_lock guard(MMapManagerLock); - // check if we have this map loaded - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::const_iterator itr = GetMMapData(mapId); + if (itr == loadedMMaps.end()) { // file may not exist, therefore not loaded -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId); -#endif return false; } - MMapData* mmap = loadedMMaps[mapId]; + MMapData* mmap = itr->second; if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId); -#endif return false; } @@ -308,47 +284,44 @@ namespace MMAP dtFreeNavMeshQuery(query); mmap->navMeshQueries.erase(instanceId); -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - LOG_DEBUG("server", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); -#endif + LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); return true; } dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId) { - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::const_iterator itr = GetMMapData(mapId); + if (itr == loadedMMaps.end()) return nullptr; - return loadedMMaps[mapId]->navMesh; + return itr->second->navMesh; } dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId) { - if (loadedMMaps.find(mapId) == loadedMMaps.end()) + MMapDataSet::const_iterator itr = GetMMapData(mapId); + if (itr == loadedMMaps.end()) return nullptr; - MMapData* mmap = loadedMMaps[mapId]; + MMapData* mmap = itr->second; if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) { - // pussywizard: different instances of the same map shouldn't access this simultaneously - std::unique_lock guard(GetMMapLock(mapId)); // check again after acquiring mutex if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) { // allocate mesh query dtNavMeshQuery* query = dtAllocNavMeshQuery(); ASSERT(query); - if (DT_SUCCESS != query->init(mmap->navMesh, 1024)) + + if (dtStatusFailed(query->init(mmap->navMesh, 1024))) { dtFreeNavMeshQuery(query); LOG_ERROR("server", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); return nullptr; } -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - LOG_DEBUG("server", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); -#endif + LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); mmap->navMeshQueries.insert(std::pair(instanceId, query)); } } diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h index d71e35b18..d2ebb3b0d 100644 --- a/src/common/Collision/Management/MMapManager.h +++ b/src/common/Collision/Management/MMapManager.h @@ -34,7 +34,8 @@ namespace MMAP // dummy struct to hold map's mmap data struct MMapData { - MMapData(dtNavMesh* mesh) : navMesh(mesh) {} + MMapData(dtNavMesh* mesh) : navMesh(mesh) { } + ~MMapData() { for (NavMeshQuerySet::iterator i = navMeshQueries.begin(); i != navMeshQueries.end(); ++i) @@ -44,11 +45,10 @@ namespace MMAP dtFreeNavMesh(navMesh); } - dtNavMesh* navMesh; - // we have to use single dtNavMeshQuery for every instance, since those are not thread safe - NavMeshQuerySet navMeshQueries; // instanceId to query - MMapTileSet mmapLoadedTiles; // maps [map grid coords] to [dtTile] + NavMeshQuerySet navMeshQueries; // instanceId to query + dtNavMesh* navMesh; + MMapTileSet loadedTileRefs; // maps [map grid coords] to [dtTile] }; typedef std::unordered_map MMapDataSet; @@ -58,9 +58,10 @@ namespace MMAP class MMapManager { public: - MMapManager() : loadedTiles(0) {} + MMapManager() : loadedTiles(0), thread_safe_environment(true) { } ~MMapManager(); + void InitializeThreadUnsafe(const std::vector& mapIds); bool loadMap(uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId); @@ -73,18 +74,14 @@ namespace MMAP uint32 getLoadedTilesCount() const { return loadedTiles; } uint32 getLoadedMapsCount() const { return loadedMMaps.size(); } - std::shared_mutex& GetMMapLock(uint32 mapId); - std::shared_mutex& GetMMapGeneralLock() { return MMapLock; } // pussywizard: in case a per-map mutex can't be found, should never happen - std::shared_mutex& GetManagerLock() { return MMapManagerLock; } private: bool loadMapData(uint32 mapId); uint32 packTileID(int32 x, int32 y); + MMapDataSet::const_iterator GetMMapData(uint32 mapId) const; MMapDataSet loadedMMaps; uint32 loadedTiles; - - std::shared_mutex MMapManagerLock; - std::shared_mutex MMapLock; // pussywizard: in case a per-map mutex can't be found, should never happen + bool thread_safe_environment; }; } diff --git a/src/common/Collision/Management/VMapFactory.cpp b/src/common/Collision/Management/VMapFactory.cpp index 36d22ac5b..5e9a65eda 100644 --- a/src/common/Collision/Management/VMapFactory.cpp +++ b/src/common/Collision/Management/VMapFactory.cpp @@ -9,14 +9,15 @@ namespace VMAP { - IVMapManager* gVMapManager = nullptr; + VMapManager2* gVMapManager = nullptr; //=============================================== // just return the instance - IVMapManager* VMapFactory::createOrGetVMapManager() + VMapManager2* VMapFactory::createOrGetVMapManager() { - if (gVMapManager == 0) - gVMapManager = new VMapManager2(); // should be taken from config ... Please change if you like :-) + if (!gVMapManager) + gVMapManager = new VMapManager2(); + return gVMapManager; } diff --git a/src/common/Collision/Management/VMapFactory.h b/src/common/Collision/Management/VMapFactory.h index d752ae50c..03fe56976 100644 --- a/src/common/Collision/Management/VMapFactory.h +++ b/src/common/Collision/Management/VMapFactory.h @@ -9,20 +9,16 @@ #include "IVMapManager.h" -/** -This is the access point to the VMapManager. -*/ - +// This is the access point to the VMapManager. namespace VMAP { - //=========================================================== + class VMapManager2; class VMapFactory { public: - static IVMapManager* createOrGetVMapManager(); + static VMapManager2* createOrGetVMapManager(); static void clear(); }; - } #endif diff --git a/src/common/Collision/Management/VMapManager2.cpp b/src/common/Collision/Management/VMapManager2.cpp index 728476286..ff819e133 100644 --- a/src/common/Collision/Management/VMapManager2.cpp +++ b/src/common/Collision/Management/VMapManager2.cpp @@ -15,21 +15,19 @@ * with this program. If not, see . */ -#include -#include -#include -#include #include "VMapManager2.h" #include "MapTree.h" #include "ModelInstance.h" #include "WorldModel.h" -#include -#include -#include "DisableMgr.h" -#include "DBCStores.h" +#include "MapDefines.h" #include "Log.h" #include "VMapDefinitions.h" -#include "GridDefines.h" +#include "Errors.h" +#include +#include +#include +#include +#include using G3D::Vector3; @@ -38,20 +36,32 @@ namespace VMAP VMapManager2::VMapManager2() { GetLiquidFlagsPtr = &GetLiquidFlagsDummy; + IsVMAPDisabledForPtr = &IsVMAPDisabledForDummy; + thread_safe_environment = true; } - VMapManager2::~VMapManager2(void) + VMapManager2::~VMapManager2() { for (InstanceTreeMap::iterator i = iInstanceMapTrees.begin(); i != iInstanceMapTrees.end(); ++i) { delete i->second; } + for (ModelFileMap::iterator i = iLoadedModelFiles.begin(); i != iLoadedModelFiles.end(); ++i) { delete i->second.getModel(); } } + void VMapManager2::InitializeThreadUnsafe(const std::vector& mapIds) + { + // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime + for (const uint32& mapId : mapIds) + iInstanceMapTrees.emplace(mapId, nullptr); + + thread_safe_environment = false; + } + Vector3 VMapManager2::convertPositionToInternalRep(float x, float y, float z) const { Vector3 pos; @@ -63,6 +73,16 @@ namespace VMAP return pos; } + InstanceTreeMap::const_iterator VMapManager2::GetMapTree(uint32 mapId) const + { + // return the iterator if found or end() if not found/NULL + InstanceTreeMap::const_iterator itr = iInstanceMapTrees.find(mapId); + if (itr != iInstanceMapTrees.cend() && !itr->second) + itr = iInstanceMapTrees.cend(); + + return itr; + } + // move to MapTree too? std::string VMapManager2::getMapFileName(unsigned int mapId) { @@ -92,6 +112,15 @@ namespace VMAP { InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); if (instanceTree == iInstanceMapTrees.end()) + { + if (thread_safe_environment) + instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, nullptr)).first; + else + ASSERT(false, "Invalid mapId %u tile [%u, %u] passed to VMapManager2 after startup in thread unsafe environment", + mapId, tileX, tileY); + } + + if (!instanceTree->second) { std::string mapFileName = getMapFileName(mapId); StaticMapTree* newTree = new StaticMapTree(mapId, basePath); @@ -100,7 +129,7 @@ namespace VMAP delete newTree; return false; } - instanceTree = iInstanceMapTrees.insert(InstanceTreeMap::value_type(mapId, newTree)).first; + instanceTree->second = newTree; } return instanceTree->second->LoadMapTile(tileX, tileY, this); @@ -109,13 +138,13 @@ namespace VMAP void VMapManager2::unloadMap(unsigned int mapId) { InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); - if (instanceTree != iInstanceMapTrees.end()) + if (instanceTree != iInstanceMapTrees.end() && instanceTree->second) { instanceTree->second->UnloadMap(this); if (instanceTree->second->numLoadedTiles() == 0) { delete instanceTree->second; - iInstanceMapTrees.erase(mapId); + instanceTree->second = nullptr; } } } @@ -123,25 +152,25 @@ namespace VMAP void VMapManager2::unloadMap(unsigned int mapId, int x, int y) { InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); - if (instanceTree != iInstanceMapTrees.end()) + if (instanceTree != iInstanceMapTrees.end() && instanceTree->second) { instanceTree->second->UnloadMapTile(x, y, this); if (instanceTree->second->numLoadedTiles() == 0) { delete instanceTree->second; - iInstanceMapTrees.erase(mapId); + instanceTree->second = nullptr; } } } bool VMapManager2::isInLineOfSight(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2) { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS) - if (!isLineOfSightCalcEnabled() || DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_LOS)) +#if defined(ENABLE_VMAP_CHECKS) + if (!isLineOfSightCalcEnabled() || IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS)) return true; #endif - InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1); @@ -161,11 +190,11 @@ namespace VMAP */ bool VMapManager2::getObjectHitPos(unsigned int mapId, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist) { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS) - if (isLineOfSightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_LOS)) +#if defined(ENABLE_VMAP_CHECKS) + if (isLineOfSightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LOS)) #endif { - InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1); @@ -193,11 +222,11 @@ namespace VMAP float VMapManager2::getHeight(unsigned int mapId, float x, float y, float z, float maxSearchDist) { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS) - if (isHeightCalcEnabled() && !DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_HEIGHT)) +#if defined(ENABLE_VMAP_CHECKS) + if (isHeightCalcEnabled() && !IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_HEIGHT)) #endif { - InstanceTreeMap::iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos = convertPositionToInternalRep(x, y, z); @@ -214,11 +243,11 @@ namespace VMAP bool VMapManager2::getAreaInfo(unsigned int mapId, float x, float y, float& z, uint32& flags, int32& adtId, int32& rootId, int32& groupId) const { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS) - if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_AREAFLAG)) +#if defined(ENABLE_VMAP_CHECKS) + if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_AREAFLAG)) #endif { - InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { Vector3 pos = convertPositionToInternalRep(x, y, z); @@ -234,11 +263,11 @@ namespace VMAP bool VMapManager2::GetLiquidLevel(uint32 mapId, float x, float y, float z, uint8 reqLiquidType, float& level, float& floor, uint32& type) const { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_VMAP_CHECKS) - if (!DisableMgr::IsDisabledFor(DISABLE_TYPE_VMAP, mapId, nullptr, VMAP_DISABLE_LIQUIDSTATUS)) +#if defined(ENABLE_VMAP_CHECKS) + if (!IsVMAPDisabledForPtr(mapId, VMAP_DISABLE_LIQUIDSTATUS)) #endif { - InstanceTreeMap::const_iterator instanceTree = iInstanceMapTrees.find(mapId); + InstanceTreeMap::const_iterator instanceTree = GetMapTree(mapId); if (instanceTree != iInstanceMapTrees.end()) { LocationInfo info; @@ -262,7 +291,7 @@ namespace VMAP WorldModel* VMapManager2::acquireModelInstance(const std::string& basepath, const std::string& filename) { //! Critical section, thread safe access to iLoadedModelFiles - std::lock_guard guard(LoadedModelFilesLock); + std::lock_guard lock(LoadedModelFilesLock); ModelFileMap::iterator model = iLoadedModelFiles.find(filename); if (model == iLoadedModelFiles.end()) @@ -274,20 +303,19 @@ namespace VMAP delete worldmodel; return nullptr; } -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) LOG_DEBUG("maps", "VMapManager2: loading file '%s%s'", basepath.c_str(), filename.c_str()); -#endif model = iLoadedModelFiles.insert(std::pair(filename, ManagedModel())).first; model->second.setModel(worldmodel); } - //model->second.incRefCount(); + return model->second.getModel(); } void VMapManager2::releaseModelInstance(const std::string& filename) { //! Critical section, thread safe access to iLoadedModelFiles - std::lock_guard guard(LoadedModelFilesLock); + std::lock_guard lock(LoadedModelFilesLock); + ModelFileMap::iterator model = iLoadedModelFiles.find(filename); if (model == iLoadedModelFiles.end()) { @@ -296,9 +324,7 @@ namespace VMAP } if (model->second.decRefCount() == 0) { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) LOG_DEBUG("maps", "VMapManager2: unloading file '%s'", filename.c_str()); -#endif delete model->second.getModel(); iLoadedModelFiles.erase(model); } @@ -309,4 +335,9 @@ namespace VMAP return StaticMapTree::CanLoadMap(std::string(basePath), mapId, x, y); } + void VMapManager2::getInstanceMapTree(InstanceTreeMap& instanceMapTree) + { + instanceMapTree = iInstanceMapTrees; + } + } // namespace VMAP diff --git a/src/common/Collision/Management/VMapManager2.h b/src/common/Collision/Management/VMapManager2.h index 71fcbeaa3..514f03600 100644 --- a/src/common/Collision/Management/VMapManager2.h +++ b/src/common/Collision/Management/VMapManager2.h @@ -19,9 +19,10 @@ #define _VMAPMANAGER2_H #include "IVMapManager.h" -#include "Define.h" +#include "Common.h" #include #include +#include //=========================================================== @@ -65,12 +66,22 @@ namespace VMAP typedef std::unordered_map InstanceTreeMap; typedef std::unordered_map ModelFileMap; + enum DisableTypes + { + VMAP_DISABLE_AREAFLAG = 0x1, + VMAP_DISABLE_HEIGHT = 0x2, + VMAP_DISABLE_LOS = 0x4, + VMAP_DISABLE_LIQUIDSTATUS = 0x8 + }; + class VMapManager2 : public IVMapManager { protected: // Tree to check collision ModelFileMap iLoadedModelFiles; InstanceTreeMap iInstanceMapTrees; + bool thread_safe_environment; + // Mutex for iLoadedModelFiles std::mutex LoadedModelFilesLock; @@ -78,6 +89,9 @@ namespace VMAP /* void _unloadMap(uint32 pMapId, uint32 x, uint32 y); */ static uint32 GetLiquidFlagsDummy(uint32) { return 0; } + static bool IsVMAPDisabledForDummy(uint32 /*entry*/, uint8 /*flags*/) { return false; } + + InstanceTreeMap::const_iterator GetMapTree(uint32 mapId) const; public: // public for debug @@ -87,6 +101,8 @@ namespace VMAP VMapManager2(); ~VMapManager2() override; + void InitializeThreadUnsafe(const std::vector& mapIds); + int loadMap(const char* pBasePath, unsigned int mapId, int x, int y) override; void unloadMap(unsigned int mapId, int x, int y) override; @@ -113,12 +129,14 @@ namespace VMAP return getMapFileName(mapId); } bool existsMap(const char* basePath, unsigned int mapId, int x, int y) override; - public: void getInstanceMapTree(InstanceTreeMap& instanceMapTree); typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType); GetLiquidFlagsFn GetLiquidFlagsPtr; + + typedef bool(*IsVMAPDisabledForFn)(uint32 entry, uint8 flags); + IsVMAPDisabledForFn IsVMAPDisabledForPtr; }; } -#endif \ No newline at end of file +#endif diff --git a/src/common/Collision/Maps/MapDefines.h b/src/common/Collision/Maps/MapDefines.h new file mode 100644 index 000000000..e323dfcde --- /dev/null +++ b/src/common/Collision/Maps/MapDefines.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + * Copyright (C) 2008+ TrinityCore + */ + +#ifndef _MAPDEFINES_H +#define _MAPDEFINES_H + +#include "Define.h" +#include "DetourNavMesh.h" + +#define MAX_NUMBER_OF_GRIDS 64 +#define SIZE_OF_GRIDS 533.3333f + +#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' +#define MMAP_VERSION 11 + +struct MmapTileHeader +{ + uint32 mmapMagic{MMAP_MAGIC}; + uint32 dtVersion; + uint32 mmapVersion{MMAP_VERSION}; + uint32 size{0}; + char usesLiquids{true}; + char padding[3]{}; + + MmapTileHeader() : dtVersion(DT_NAVMESH_VERSION) { } +}; + +// All padding fields must be handled and initialized to ensure mmaps_generator will produce binary-identical *.mmtile files +static_assert(sizeof(MmapTileHeader) == 20, "MmapTileHeader size is not correct, adjust the padding field size"); +static_assert(sizeof(MmapTileHeader) == (sizeof(MmapTileHeader::mmapMagic) + + sizeof(MmapTileHeader::dtVersion) + + sizeof(MmapTileHeader::mmapVersion) + + sizeof(MmapTileHeader::size) + + sizeof(MmapTileHeader::usesLiquids) + + sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields"); + +enum NavTerrain +{ + NAV_EMPTY = 0x00, + NAV_GROUND = 0x01, + NAV_MAGMA = 0x02, + NAV_SLIME = 0x04, + NAV_WATER = 0x08, + NAV_UNUSED1 = 0x10, + NAV_UNUSED2 = 0x20, + NAV_UNUSED3 = 0x40, + NAV_UNUSED4 = 0x80 + // we only have 8 bits +}; + +#endif diff --git a/src/common/Collision/Maps/MapTree.cpp b/src/common/Collision/Maps/MapTree.cpp index 520ad8cc3..38e4f97d2 100644 --- a/src/common/Collision/Maps/MapTree.cpp +++ b/src/common/Collision/Maps/MapTree.cpp @@ -462,4 +462,10 @@ namespace VMAP } iLoadedTiles.erase(tile); } + + void StaticMapTree::getModelInstances(ModelInstance*& models, uint32& count) + { + models = iTreeValues; + count = iNTreeValues; + } } diff --git a/src/common/Collision/Maps/TileAssembler.cpp b/src/common/Collision/Maps/TileAssembler.cpp index dd4f2621e..c4fbed201 100644 --- a/src/common/Collision/Maps/TileAssembler.cpp +++ b/src/common/Collision/Maps/TileAssembler.cpp @@ -8,7 +8,7 @@ #include "MapTree.h" #include "BoundingIntervalHierarchy.h" #include "VMapDefinitions.h" -#include "SharedDefines.h" +#include "MapDefines.h" #include #include #include diff --git a/src/common/Collision/Models/GameObjectModel.cpp b/src/common/Collision/Models/GameObjectModel.cpp index 9a0e294a0..56b91c49d 100644 --- a/src/common/Collision/Models/GameObjectModel.cpp +++ b/src/common/Collision/Models/GameObjectModel.cpp @@ -4,19 +4,13 @@ * Copyright (C) 2005-2009 MaNGOS */ +#include "GameObjectModel.h" #include "VMapFactory.h" #include "VMapManager2.h" #include "VMapDefinitions.h" #include "WorldModel.h" - -#include "GameObjectModel.h" #include "Log.h" -#include "GameObject.h" -#include "Creature.h" -#include "TemporarySummon.h" -#include "Object.h" -#include "DBCStores.h" -#include "World.h" +#include "Timer.h" using G3D::Vector3; using G3D::Ray; @@ -35,16 +29,14 @@ struct GameobjectModelData typedef std::unordered_map ModelList; ModelList model_list; -void LoadGameObjectModelList() +void LoadGameObjectModelList(std::string const& dataPath) { - //#ifndef NO_CORE_FUNCS uint32 oldMSTime = getMSTime(); - //#endif - FILE* model_list_file = fopen((sWorld->GetDataPath() + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb"); + FILE* model_list_file = fopen((dataPath + "vmaps/" + VMAP::GAMEOBJECT_MODELS).c_str(), "rb"); if (!model_list_file) { - LOG_ERROR("server", "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS); + LOG_ERROR("maps", "Unable to open '%s' file.", VMAP::GAMEOBJECT_MODELS); return; } @@ -72,7 +64,8 @@ void LoadGameObjectModelList() || fread(&v1, sizeof(Vector3), 1, model_list_file) != 1 || fread(&v2, sizeof(Vector3), 1, model_list_file) != 1) { - LOG_ERROR("server", "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS); + LOG_ERROR("maps", "File '%s' seems to be corrupted!", VMAP::GAMEOBJECT_MODELS); + fclose(model_list_file); break; } @@ -95,12 +88,12 @@ void LoadGameObjectModelList() GameObjectModel::~GameObjectModel() { if (iModel) - ((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->releaseModelInstance(name); + VMAP::VMapFactory::createOrGetVMapManager()->releaseModelInstance(name); } -bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayInfoEntry& info) +bool GameObjectModel::initialize(std::unique_ptr modelOwner, std::string const& dataPath) { - ModelList::const_iterator it = model_list.find(info.Displayid); + ModelList::const_iterator it = model_list.find(modelOwner->GetDisplayId()); if (it == model_list.end()) return false; @@ -112,24 +105,18 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn return false; } - iModel = ((VMAP::VMapManager2*)VMAP::VMapFactory::createOrGetVMapManager())->acquireModelInstance(sWorld->GetDataPath() + "vmaps/", it->second.name); + iModel = VMAP::VMapFactory::createOrGetVMapManager()->acquireModelInstance(dataPath + "vmaps/", it->second.name); if (!iModel) return false; name = it->second.name; - //flags = VMAP::MOD_M2; - //adtId = 0; - //ID = 0; - iPos = Vector3(go.GetPositionX(), go.GetPositionY(), go.GetPositionZ()); - - // pussywizard: - phasemask = (go.GetGoState() == GO_STATE_READY || go.IsTransport()) ? go.GetPhaseMask() : 0; - - iScale = go.GetFloatValue(OBJECT_FIELD_SCALE_X); + iPos = modelOwner->GetPosition(); + phasemask = modelOwner->GetPhaseMask(); + iScale = modelOwner->GetScale(); iInvScale = 1.f / iScale; - G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(go.GetOrientation(), 0, 0); + G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(modelOwner->GetOrientation(), 0, 0); iInvRot = iRotation.inverse(); // transform bounding box: mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale); @@ -138,27 +125,24 @@ bool GameObjectModel::initialize(const GameObject& go, const GameObjectDisplayIn rotated_bounds.merge(iRotation * mdl_box.corner(i)); iBound = rotated_bounds + iPos; + #ifdef SPAWN_CORNERS // test: for (int i = 0; i < 8; ++i) { Vector3 pos(iBound.corner(i)); - const_cast(go).SummonCreature(1, pos.x, pos.y, pos.z, 0, TEMPSUMMON_MANUAL_DESPAWN); + modelOwner->DebugVisualizeCorner(pos); } #endif - owner = &go; + owner = std::move(modelOwner); return true; } -GameObjectModel* GameObjectModel::Create(const GameObject& go) +GameObjectModel* GameObjectModel::Create(std::unique_ptr modelOwner, std::string const& dataPath) { - const GameObjectDisplayInfoEntry* info = sGameObjectDisplayInfoStore.LookupEntry(go.GetDisplayId()); - if (!info) - return nullptr; - GameObjectModel* mdl = new GameObjectModel(); - if (!mdl->initialize(go, *info)) + if (!mdl->initialize(std::move(modelOwner), dataPath)) { delete mdl; return nullptr; @@ -169,7 +153,7 @@ GameObjectModel* GameObjectModel::Create(const GameObject& go) bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const { - if (!(phasemask & ph_mask) || !owner->isSpawned()) + if (!(phasemask & ph_mask) || !owner->IsSpawned()) return false; float time = ray.intersectionTime(iBound); @@ -199,6 +183,7 @@ bool GameObjectModel::UpdatePosition() return false; G3D::AABox mdl_box(it->second.bound); + // ignore models with no bounds if (mdl_box == G3D::AABox::zero()) { @@ -206,12 +191,14 @@ bool GameObjectModel::UpdatePosition() return false; } - iPos = Vector3(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ()); + iPos = owner->GetPosition(); G3D::Matrix3 iRotation = G3D::Matrix3::fromEulerAnglesZYX(owner->GetOrientation(), 0, 0); iInvRot = iRotation.inverse(); + // transform bounding box: mdl_box = AABox(mdl_box.low() * iScale, mdl_box.high() * iScale); AABox rotated_bounds; + for (int i = 0; i < 8; ++i) rotated_bounds.merge(iRotation * mdl_box.corner(i)); @@ -221,7 +208,7 @@ bool GameObjectModel::UpdatePosition() for (int i = 0; i < 8; ++i) { Vector3 pos(iBound.corner(i)); - owner->SummonCreature(1, pos.x, pos.y, pos.z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000); + owner->DebugVisualizeCorner(pos); } #endif diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h index 6e10df44a..3051ba160 100644 --- a/src/common/Collision/Models/GameObjectModel.h +++ b/src/common/Collision/Models/GameObjectModel.h @@ -7,13 +7,12 @@ #ifndef _GAMEOBJECT_MODEL_H #define _GAMEOBJECT_MODEL_H +#include "Define.h" #include #include #include #include -#include "Define.h" - namespace VMAP { class WorldModel; @@ -22,20 +21,23 @@ namespace VMAP class GameObject; struct GameObjectDisplayInfoEntry; -class GameObjectModel /*, public Intersectable*/ +class GameObjectModelOwnerBase { - uint32 phasemask{0}; - G3D::AABox iBound; - G3D::Matrix3 iInvRot; - G3D::Vector3 iPos; - //G3D::Vector3 iRot; - float iInvScale{0}; - float iScale{0}; - VMAP::WorldModel* iModel; - GameObject const* owner; +public: + virtual ~GameObjectModelOwnerBase() = default; - GameObjectModel() : iModel(nullptr), owner(nullptr) { } - bool initialize(const GameObject& go, const GameObjectDisplayInfoEntry& info); + virtual bool IsSpawned() const = 0; + virtual uint32 GetDisplayId() const = 0; + virtual uint32 GetPhaseMask() const = 0; + virtual G3D::Vector3 GetPosition() const = 0; + virtual float GetOrientation() const = 0; + virtual float GetScale() const = 0; + virtual void DebugVisualizeCorner(G3D::Vector3 const& /*corner*/) const = 0; +}; + +class GameObjectModel +{ + GameObjectModel() : phasemask(0), iInvScale(0), iScale(0), iModel(nullptr) { } public: std::string name; @@ -44,19 +46,33 @@ public: ~GameObjectModel(); - [[nodiscard]] const G3D::Vector3& getPosition() const { return iPos;} + [[nodiscard]] const G3D::Vector3& getPosition() const { return iPos; } - /** Enables\disables collision. */ - void disable() { phasemask = 0;} - void enable(uint32 ph_mask) { phasemask = ph_mask;} + /** Enables\disables collision. */ + void disable() { phasemask = 0; } + void enable(uint32 ph_mask) { phasemask = ph_mask; } - [[nodiscard]] bool isEnabled() const {return phasemask != 0;} + [[nodiscard]] bool isEnabled() const { return phasemask != 0; } bool intersectRay(const G3D::Ray& Ray, float& MaxDist, bool StopAtFirstHit, uint32 ph_mask) const; - static GameObjectModel* Create(const GameObject& go); + static GameObjectModel* Create(std::unique_ptr modelOwner, std::string const& dataPath); bool UpdatePosition(); + +private: + bool initialize(std::unique_ptr modelOwner, std::string const& dataPath); + + uint32 phasemask; + G3D::AABox iBound; + G3D::Matrix3 iInvRot; + G3D::Vector3 iPos; + float iInvScale; + float iScale; + VMAP::WorldModel* iModel; + std::unique_ptr owner; }; -#endif // _GAMEOBJECT_MODEL_H \ No newline at end of file +void LoadGameObjectModelList(std::string const& dataPath); + +#endif // _GAMEOBJECT_MODEL_H diff --git a/src/common/Collision/Models/ModelInstance.h b/src/common/Collision/Models/ModelInstance.h index 43d38566a..1d9a11f72 100644 --- a/src/common/Collision/Models/ModelInstance.h +++ b/src/common/Collision/Models/ModelInstance.h @@ -7,13 +7,12 @@ #ifndef _MODELINSTANCE_H_ #define _MODELINSTANCE_H_ +#include "Define.h" #include #include #include #include -#include "Define.h" - namespace VMAP { class WorldModel; @@ -58,12 +57,11 @@ namespace VMAP void intersectPoint(const G3D::Vector3& p, AreaInfo& info) const; bool GetLocationInfo(const G3D::Vector3& p, LocationInfo& info) const; bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo& info, float& liqHeight) const; + WorldModel* getWorldModel() { return iModel; } protected: G3D::Matrix3 iInvRot; float iInvScale{0.0f}; WorldModel* iModel{nullptr}; - public: - WorldModel* getWorldModel(); }; } // namespace VMAP diff --git a/src/common/Collision/Models/WorldModel.cpp b/src/common/Collision/Models/WorldModel.cpp index e8333e0f6..a65f305b7 100644 --- a/src/common/Collision/Models/WorldModel.cpp +++ b/src/common/Collision/Models/WorldModel.cpp @@ -241,6 +241,13 @@ namespace VMAP return result; } + void WmoLiquid::getPosInfo(uint32& tilesX, uint32& tilesY, G3D::Vector3& corner) const + { + tilesX = iTilesX; + tilesY = iTilesY; + corner = iCorner; + } + // ===================== GroupModel ================================== GroupModel::GroupModel(const GroupModel& other): @@ -401,6 +408,13 @@ namespace VMAP return 0; } + void GroupModel::getMeshData(std::vector& outVertices, std::vector& outTriangles, WmoLiquid*& liquid) + { + outVertices = vertices; + outTriangles = triangles; + liquid = iLiquid; + } + // ===================== WorldModel ================================== void WorldModel::setGroupModels(std::vector& models) @@ -575,4 +589,9 @@ namespace VMAP fclose(rf); return result; } + + void WorldModel::getGroupModels(std::vector& outGroupModels) + { + outGroupModels = groupModels; + } } diff --git a/src/common/Collision/Models/WorldModel.h b/src/common/Collision/Models/WorldModel.h index 88558a03e..75a809c27 100644 --- a/src/common/Collision/Models/WorldModel.h +++ b/src/common/Collision/Models/WorldModel.h @@ -7,13 +7,12 @@ #ifndef _WORLDMODEL_H #define _WORLDMODEL_H +#include "Define.h" +#include "BoundingIntervalHierarchy.h" #include #include #include #include -#include "BoundingIntervalHierarchy.h" - -#include "Define.h" namespace VMAP { @@ -46,6 +45,7 @@ namespace VMAP uint32 GetFileSize(); bool writeToFile(FILE* wf); static bool readFromFile(FILE* rf, WmoLiquid*& liquid); + void getPosInfo(uint32& tilesX, uint32& tilesY, G3D::Vector3& corner) const; private: WmoLiquid() { } uint32 iTilesX{0}; //!< number of tiles in x direction, each @@ -54,8 +54,6 @@ namespace VMAP uint32 iType{0}; //!< liquid type float* iHeight{nullptr}; //!< (tilesX + 1)*(tilesY + 1) height values uint8* iFlags{nullptr}; //!< info if liquid tile is used - public: - void getPosInfo(uint32& tilesX, uint32& tilesY, G3D::Vector3& corner) const; }; /*! holding additional info for WMO group files */ @@ -80,6 +78,7 @@ namespace VMAP [[nodiscard]] const G3D::AABox& GetBound() const { return iBound; } [[nodiscard]] uint32 GetMogpFlags() const { return iMogpFlags; } [[nodiscard]] uint32 GetWmoID() const { return iGroupWMOID; } + void getMeshData(std::vector& outVertices, std::vector& outTriangles, WmoLiquid*& liquid); protected: G3D::AABox iBound; uint32 iMogpFlags{0};// 0x8 outdor; 0x2000 indoor @@ -88,8 +87,6 @@ namespace VMAP std::vector triangles; BIH meshTree; WmoLiquid* iLiquid{nullptr}; - public: - void getMeshData(std::vector& vertices, std::vector& triangles, WmoLiquid*& liquid); }; /*! Holds a model (converted M2 or WMO) in its original coordinate space */ class WorldModel @@ -105,12 +102,11 @@ namespace VMAP bool GetLocationInfo(const G3D::Vector3& p, const G3D::Vector3& down, float& dist, LocationInfo& info) const; bool writeFile(const std::string& filename); bool readFile(const std::string& filename); + void getGroupModels(std::vector& outGroupModels); protected: uint32 RootWMOID{0}; std::vector groupModels; BIH groupTree; - public: - void getGroupModels(std::vector& groupModels); }; } // namespace VMAP diff --git a/src/common/Collision/VMapTools.h b/src/common/Collision/VMapTools.h index d29c4c50e..582694126 100644 --- a/src/common/Collision/VMapTools.h +++ b/src/common/Collision/VMapTools.h @@ -7,11 +7,10 @@ #ifndef _VMAPTOOLS_H #define _VMAPTOOLS_H +#include "Define.h" #include #include -#include "NodeValueAccess.h" - /** The Class is mainly taken from G3D/AABSPTree.h but modified to be able to use our internal data structure. This is an iterator that helps us analysing the BSP-Trees. @@ -40,7 +39,6 @@ namespace VMAP class MyCollisionDetection { - private: public: static bool collisionLocationForMovingPointFixedAABox( const G3D::Vector3& origin, diff --git a/src/common/PrecompiledHeaders/commonPCH.h b/src/common/PrecompiledHeaders/commonPCH.h index d0c15b17f..27707525f 100644 --- a/src/common/PrecompiledHeaders/commonPCH.h +++ b/src/common/PrecompiledHeaders/commonPCH.h @@ -2,7 +2,5 @@ #include "Common.h" #include "Log.h" -#include "DatabaseWorker.h" -#include "SQLOperation.h" #include "Errors.h" #include "TypeList.h" diff --git a/src/common/Utilities/Util.cpp b/src/common/Utilities/Util.cpp index 0aca756ec..d69f8b615 100644 --- a/src/common/Utilities/Util.cpp +++ b/src/common/Utilities/Util.cpp @@ -8,10 +8,9 @@ #include "Common.h" #include "utf8.h" #include "Log.h" -#include "DatabaseWorker.h" -#include "SQLOperation.h" #include "Errors.h" #include "TypeList.h" +#include #include "SFMT.h" #include "Errors.h" // for ASSERT #include diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp index 7aaff1d3e..85b6b3f54 100644 --- a/src/server/game/Conditions/DisableMgr.cpp +++ b/src/server/game/Conditions/DisableMgr.cpp @@ -5,16 +5,16 @@ */ #include "DisableMgr.h" +#include "MMapFactory.h" #include "ObjectMgr.h" #include "OutdoorPvP.h" #include "Player.h" #include "SpellInfo.h" #include "SpellMgr.h" -#include "VMapManager2.h" +#include "World.h" namespace DisableMgr { - namespace { struct DisableData @@ -197,28 +197,28 @@ namespace DisableMgr switch (mapEntry->map_type) { case MAP_COMMON: - if (flags & VMAP_DISABLE_AREAFLAG) + if (flags & VMAP::VMAP_DISABLE_AREAFLAG) LOG_INFO("server", "Areaflag disabled for world map %u.", entry); - if (flags & VMAP_DISABLE_LIQUIDSTATUS) + if (flags & VMAP::VMAP_DISABLE_LIQUIDSTATUS) LOG_INFO("server", "Liquid status disabled for world map %u.", entry); break; case MAP_INSTANCE: case MAP_RAID: - if (flags & VMAP_DISABLE_HEIGHT) + if (flags & VMAP::VMAP_DISABLE_HEIGHT) LOG_INFO("server", "Height disabled for instance map %u.", entry); - if (flags & VMAP_DISABLE_LOS) + if (flags & VMAP::VMAP_DISABLE_LOS) LOG_INFO("server", "LoS disabled for instance map %u.", entry); break; case MAP_BATTLEGROUND: - if (flags & VMAP_DISABLE_HEIGHT) + if (flags & VMAP::VMAP_DISABLE_HEIGHT) LOG_INFO("server", "Height disabled for battleground map %u.", entry); - if (flags & VMAP_DISABLE_LOS) + if (flags & VMAP::VMAP_DISABLE_LOS) LOG_INFO("server", "LoS disabled for battleground map %u.", entry); break; case MAP_ARENA: - if (flags & VMAP_DISABLE_HEIGHT) + if (flags & VMAP::VMAP_DISABLE_HEIGHT) LOG_INFO("server", "Height disabled for arena map %u.", entry); - if (flags & VMAP_DISABLE_LOS) + if (flags & VMAP::VMAP_DISABLE_LOS) LOG_INFO("server", "LoS disabled for arena map %u.", entry); break; default: @@ -360,4 +360,17 @@ namespace DisableMgr return false; } + bool IsVMAPDisabledFor(uint32 entry, uint8 flags) + { + return IsDisabledFor(DISABLE_TYPE_VMAP, entry, nullptr, flags); + } + + bool IsPathfindingEnabled(const Map* map) + { + if (!map) + return false; + + return !MMAP::MMapFactory::forbiddenMaps[map->GetId()] && (sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS) ? true : map->IsBattlegroundOrArena()); + } + } // Namespace diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h index 9770c092f..92c35d8c4 100644 --- a/src/server/game/Conditions/DisableMgr.h +++ b/src/server/game/Conditions/DisableMgr.h @@ -8,6 +8,8 @@ #define ACORE_DISABLEMGR_H #include "Define.h" +#include "Map.h" +#include "VMapManager2.h" class Unit; @@ -38,19 +40,13 @@ enum SpellDisableTypes SPELL_DISABLE_LOS) }; -enum VmapDisableTypes -{ - VMAP_DISABLE_AREAFLAG = 0x1, - VMAP_DISABLE_HEIGHT = 0x2, - VMAP_DISABLE_LOS = 0x4, - VMAP_DISABLE_LIQUIDSTATUS = 0x8, -}; - namespace DisableMgr { void LoadDisables(); bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags = 0); void CheckQuestDisables(); + bool IsVMAPDisabledFor(uint32 entry, uint8 flags); + bool IsPathfindingEnabled(const Map* map); } #endif //ACORE_DISABLEMGR_H diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index c3b17bb7d..19041c6f0 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -21,8 +21,8 @@ struct FormationInfo float follow_dist; float follow_angle; uint8 groupAI; - uint16 point_1; - uint16 point_2; + uint32 point_1; + uint32 point_2; }; typedef std::unordered_map CreatureGroupInfoType; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 22aef69c4..1d3b8c330 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -311,7 +311,7 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u SetDisplayId(goinfo->displayId); if (!m_model) - m_model = GameObjectModel::Create(*this); + m_model = CreateModel(); switch (goinfo->type) { @@ -1961,7 +1961,7 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const if (G3D::fuzzyEq(dist, 0.0f)) return true; - float scale = GetFloatValue(OBJECT_FIELD_SCALE_X); + float scale = GetObjectScale(); float sinB = dx / dist; float cosB = dy / dist; dx = dist * (cosA * cosB + sinA * sinB); @@ -2298,7 +2298,7 @@ void GameObject::UpdateModel() if (GetMap()->ContainsGameObjectModel(*m_model)) GetMap()->RemoveGameObjectModel(*m_model); delete m_model; - m_model = GameObjectModel::Create(*this); + m_model = CreateModel(); if (m_model) GetMap()->InsertGameObjectModel(*m_model); } @@ -2517,4 +2517,26 @@ void GameObject::UpdateModelPosition() } } -std::unordered_map GameObject::gameObjectToEventFlag = {}; +std::unordered_map GameObject::gameObjectToEventFlag = { }; + +class GameObjectModelOwnerImpl : public GameObjectModelOwnerBase +{ +public: + explicit GameObjectModelOwnerImpl(GameObject* owner) : _owner(owner) { } + + bool IsSpawned() const override { return _owner->isSpawned(); } + uint32 GetDisplayId() const override { return _owner->GetDisplayId(); } + uint32 GetPhaseMask() const override { return (_owner->GetGoState() == GO_STATE_READY || _owner->IsTransport()) ? _owner->GetPhaseMask() : 0; } + G3D::Vector3 GetPosition() const override { return G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); } + float GetOrientation() const override { return _owner->GetOrientation(); } + float GetScale() const override { return _owner->GetObjectScale(); } + void DebugVisualizeCorner(G3D::Vector3 const& corner) const override { const_cast(_owner)->SummonCreature(1, corner.x, corner.y, corner.z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000); } + +private: + GameObject* _owner; +}; + +GameObjectModel* GameObject::CreateModel() +{ + return GameObjectModel::Create(std::make_unique(this), sWorld->GetDataPath()); +} diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 6c34692b7..e139f39f8 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -953,6 +953,7 @@ public: protected: bool AIM_Initialize(); + GameObjectModel* CreateModel(); void UpdateModel(); // updates model in case displayId were changed uint32 m_spellId; time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()), diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 1abbe77ec..002906ab2 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -91,7 +91,7 @@ bool MotionTransport::CreateMoTrans(ObjectGuid::LowType guidlow, uint32 entry, u // pussywizard: no PathRotation for MotionTransports SetTransportPathRotation(0.0f, 0.0f, 0.0f, 1.0f); - m_model = GameObjectModel::Create(*this); + m_model = CreateModel(); return true; } @@ -722,7 +722,7 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m SetDisplayId(goinfo->displayId); if (!m_model) - m_model = GameObjectModel::Create(*this); + m_model = CreateModel(); SetGoType(GameobjectTypes(goinfo->type)); SetGoState(go_state); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b28228f01..8dadb516b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -16,6 +16,7 @@ #include "CreatureAI.h" #include "CreatureAIImpl.h" #include "CreatureGroups.h" +#include "DisableMgr.h" #include "DynamicVisibility.h" #include "Formulas.h" #include "GridNotifiersImpl.h" @@ -19518,7 +19519,7 @@ void Unit::PetSpellFail(const SpellInfo* spellInfo, Unit* target, uint32 result) if (!charmInfo || GetTypeId() != TYPEID_UNIT) return; - if ((MMAP::MMapFactory::IsPathfindingEnabled(GetMap()) || result != SPELL_FAILED_LINE_OF_SIGHT) && target) + if ((DisableMgr::IsPathfindingEnabled(GetMap()) || result != SPELL_FAILED_LINE_OF_SIGHT) && target) { if ((result == SPELL_FAILED_LINE_OF_SIGHT || result == SPELL_FAILED_OUT_OF_RANGE) || !ToCreature()->HasReactState(REACT_PASSIVE)) if (Unit* owner = GetOwner()) diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h index deaf07835..1f0b95754 100644 --- a/src/server/game/Grids/GridDefines.h +++ b/src/server/game/Grids/GridDefines.h @@ -9,6 +9,7 @@ #include "Common.h" #include "NGrid.h" +#include "MapDefines.h" #include // Forward class definitions @@ -22,10 +23,7 @@ class ObjectGuid; #define MAX_NUMBER_OF_CELLS 8 -#define MAX_NUMBER_OF_GRIDS 64 - -#define SIZE_OF_GRIDS 533.3333f -#define CENTER_GRID_ID (MAX_NUMBER_OF_GRIDS/2) +#define CENTER_GRID_ID (MAX_NUMBER_OF_GRIDS/2) #define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2) diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 2368a21fc..1ec4644d4 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -7,6 +7,7 @@ #include "Chat.h" #include "Common.h" #include "CreatureAI.h" +#include "DisableMgr.h" #include "Group.h" #include "Log.h" #include "ObjectAccessor.h" @@ -559,7 +560,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint16 spe return; // Not let attack through obstructions - bool checkLos = !MMAP::MMapFactory::IsPathfindingEnabled(pet->GetMap()) || + bool checkLos = !DisableMgr::IsPathfindingEnabled(pet->GetMap()) || (TargetUnit->GetTypeId() == TYPEID_UNIT && (TargetUnit->ToCreature()->isWorldBoss() || TargetUnit->ToCreature()->IsDungeonBoss())); if (checkLos && !pet->IsWithinLOSInMap(TargetUnit)) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 860757206..641f18e2d 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -7,6 +7,7 @@ #include "Battleground.h" #include "CellImpl.h" #include "Chat.h" +#include "DisableMgr.h" #include "DynamicTree.h" #include "Geometry.h" #include "GridNotifiers.h" @@ -24,6 +25,7 @@ #include "Transport.h" #include "Vehicle.h" #include "VMapFactory.h" +#include "VMapManager2.h" #ifdef ELUNA #include "LuaEngine.h" @@ -111,7 +113,7 @@ bool Map::ExistVMap(uint32 mapid, int gx, int gy) void Map::LoadMMap(int gx, int gy) { - if (!MMAP::MMapFactory::IsPathfindingEnabled(this)) // pussywizard + if (!DisableMgr::IsPathfindingEnabled(this)) // pussywizard return; int mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap(GetId(), gx, gy); @@ -138,7 +140,7 @@ void Map::LoadMMap(int gx, int gy) void Map::LoadVMap(int gx, int gy) { // x and y are swapped !! - int vmapLoadResult = VMAP::VMapFactory::createOrGetVMapManager()->loadMap((sWorld->GetDataPath() + "vmaps").c_str(), GetId(), gx, gy); + int vmapLoadResult = VMAP::VMapFactory::createOrGetVMapManager()->loadMap((sWorld->GetDataPath() + "vmaps").c_str(), GetId(), gx, gy); switch (vmapLoadResult) { case VMAP::VMAP_LOAD_RESULT_OK: diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp index 477bad32e..cf0cb8b46 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -4,9 +4,10 @@ * Copyright (C) 2005-2009 MaNGOS */ +#include "HomeMovementGenerator.h" #include "Creature.h" #include "CreatureAI.h" -#include "HomeMovementGenerator.h" +#include "DisableMgr.h" #include "MoveSpline.h" #include "MoveSplineInit.h" #include "WorldPacket.h" @@ -55,7 +56,7 @@ void HomeMovementGenerator::_setTargetLocation(Creature* owner) } owner->UpdateAllowedPositionZ(x, y, z); - init.MoveTo(x, y, z, MMAP::MMapFactory::IsPathfindingEnabled(owner->FindMap()), true); + init.MoveTo(x, y, z, DisableMgr::IsPathfindingEnabled(owner->FindMap()), true); init.SetWalk(false); init.Launch(); diff --git a/src/server/game/Movement/MovementGenerators/PathGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathGenerator.cpp index 861076455..5e5636c59 100644 --- a/src/server/game/Movement/MovementGenerators/PathGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PathGenerator.cpp @@ -24,7 +24,7 @@ PathGenerator::PathGenerator(WorldObject const* owner) : memset(_pathPolyRefs, 0, sizeof(_pathPolyRefs)); uint32 mapId = _source->GetMapId(); - //if (MMAP::MMapFactory::IsPathfindingEnabled(_sourceUnit->FindMap())) + //if (DisableMgr::IsPathfindingEnabled(_sourceUnit->FindMap())) { MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); _navMesh = mmap->GetNavMesh(mapId); diff --git a/src/server/game/Movement/MovementGenerators/PathGenerator.h b/src/server/game/Movement/MovementGenerators/PathGenerator.h index 0386f7df3..9f1d768a0 100644 --- a/src/server/game/Movement/MovementGenerators/PathGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PathGenerator.h @@ -9,6 +9,7 @@ #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" +#include "MapDefines.h" #include "MMapFactory.h" #include "MMapManager.h" #include "MoveSplineInitArgs.h" diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 780296a13..008b59137 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2339,7 +2339,7 @@ void AuraEffect::HandleAuraModScale(AuraApplication const* aurApp, uint8 mode, b Unit* target = aurApp->GetTarget(); - float scale = target->GetFloatValue(OBJECT_FIELD_SCALE_X); + float scale = target->GetObjectScale(); ApplyPercentModFloatVar(scale, float(GetAmount()), apply); target->SetObjectScale(scale); } @@ -2359,7 +2359,6 @@ void AuraEffect::HandleAuraCloneCaster(AuraApplication const* aurApp, uint8 mode // What must be cloned? at least display and scale target->SetDisplayId(caster->GetDisplayId()); - //target->SetObjectScale(caster->GetFloatValue(OBJECT_FIELD_SCALE_X)); // we need retail info about how scaling is handled (aura maybe?) target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_MIRROR_IMAGE); } else diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index feda1c46e..f779cbec3 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5678,7 +5678,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_BAD_TARGETS; // Xinef: Pass only explicit unit target spells // pussywizard: - if (MMAP::MMapFactory::IsPathfindingEnabled(m_caster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget()) + if (DisableMgr::IsPathfindingEnabled(m_caster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget()) { Unit* target = m_targets.GetUnitTarget(); if (!target) @@ -7337,12 +7337,6 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff) const return false; } break; - /*case SPELL_EFFECT_CHARGE: - if (MMAP::MMapFactory::IsPathfindingEnabled(m_caster->FindMap())) - break; - [[fallthrough]]; - */ - case SPELL_EFFECT_SUMMON_RAF_FRIEND: if (m_caster->GetTypeId() != TYPEID_PLAYER || target->GetTypeId() != TYPEID_PLAYER) return false; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 44fb101b3..a05c53411 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1415,8 +1415,6 @@ void World::LoadConfigSettings(bool reload) sScriptMgr->OnAfterConfigLoad(reload); } -extern void LoadGameObjectModelList(); - /// Initialize the World void World::SetInitialWorldSettings() { @@ -1433,10 +1431,9 @@ void World::SetInitialWorldSettings() sScriptMgr->Initialize(); ///- Initialize VMapManager function pointers (to untangle game/collision circular deps) - if (VMAP::VMapManager2* vmmgr2 = dynamic_cast(VMAP::VMapFactory::createOrGetVMapManager())) - { - vmmgr2->GetLiquidFlagsPtr = &GetLiquidFlags; - } + VMAP::VMapManager2* vmmgr2 = VMAP::VMapFactory::createOrGetVMapManager(); + vmmgr2->GetLiquidFlagsPtr = &GetLiquidFlags; + vmmgr2->IsVMAPDisabledForPtr = &DisableMgr::IsVMAPDisabledFor; ///- Initialize config settings LoadConfigSettings(); @@ -1498,6 +1495,15 @@ void World::SetInitialWorldSettings() LoadDBCStores(m_dataPath); DetectDBCLang(); + std::vector mapIds; + for (auto const& map : sMapStore) + mapIds.emplace_back(map->MapID); + + vmmgr2->InitializeThreadUnsafe(mapIds); + + MMAP::MMapManager* mmmgr = MMAP::MMapFactory::createOrGetMMapManager(); + mmmgr->InitializeThreadUnsafe(mapIds); + LOG_INFO("server", "Loading Game Graveyard..."); sGraveyard->LoadGraveyardFromDB(); @@ -1520,7 +1526,7 @@ void World::SetInitialWorldSettings() sSpellMgr->LoadSpellCustomAttr(); LOG_INFO("server", "Loading GameObject models..."); - LoadGameObjectModelList(); + LoadGameObjectModelList(m_dataPath); LOG_INFO("server", "Loading Script Names..."); sObjectMgr->LoadScriptNames(); diff --git a/src/server/shared/SharedDefines.h b/src/server/shared/SharedDefines.h index 4f8bfea5f..fd3bb43ed 100644 --- a/src/server/shared/SharedDefines.h +++ b/src/server/shared/SharedDefines.h @@ -3567,42 +3567,4 @@ enum PartyResult ERR_PARTY_LFG_TELEPORT_IN_COMBAT = 30 }; -#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' -#define MMAP_VERSION 11 - -struct MmapTileHeader -{ - uint32 mmapMagic{MMAP_MAGIC}; - uint32 dtVersion; - uint32 mmapVersion{MMAP_VERSION}; - uint32 size{0}; - char usesLiquids{true}; - char padding[3]{}; - - MmapTileHeader() : dtVersion(DT_NAVMESH_VERSION) { } -}; - -// All padding fields must be handled and initialized to ensure mmaps_generator will produce binary-identical *.mmtile files -static_assert(sizeof(MmapTileHeader) == 20, "MmapTileHeader size is not correct, adjust the padding field size"); -static_assert(sizeof(MmapTileHeader) == (sizeof(MmapTileHeader::mmapMagic) + - sizeof(MmapTileHeader::dtVersion) + - sizeof(MmapTileHeader::mmapVersion) + - sizeof(MmapTileHeader::size) + - sizeof(MmapTileHeader::usesLiquids) + - sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields"); - -enum NavTerrain -{ - NAV_EMPTY = 0x00, - NAV_GROUND = 0x01, - NAV_MAGMA = 0x02, - NAV_SLIME = 0x04, - NAV_WATER = 0x08, - NAV_UNUSED1 = 0x10, - NAV_UNUSED2 = 0x20, - NAV_UNUSED3 = 0x40, - NAV_UNUSED4 = 0x80 - // we only have 8 bits -}; - #endif diff --git a/src/tools/mesh_extractor/Utils.h b/src/tools/mesh_extractor/Utils.h index 872a37f6d..c1dd82547 100644 --- a/src/tools/mesh_extractor/Utils.h +++ b/src/tools/mesh_extractor/Utils.h @@ -6,6 +6,7 @@ #ifndef UTILS_H #define UTILS_H + #include #include #include @@ -337,9 +338,6 @@ public: virtual float Scale() const { return 1.0f; }; }; -#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' -#define MMAP_VERSION 10 - struct MmapTileHeader { uint32 mmapMagic; diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 866b63c96..20a325b4c 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -5,45 +5,14 @@ */ #include "MapBuilder.h" +#include "MapDefines.h" #include "MapTree.h" #include "ModelInstance.h" #include "PathCommon.h" - #include #include #include -#include "DisableMgr.h" - -namespace DisableMgr -{ - bool IsDisabledFor(DisableType /*type*/, uint32 /*entry*/, Unit const* /*unit*/, uint8 /*flags*/ /*= 0*/) { return false; } -} - -#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' -#define MMAP_VERSION 11 - -struct MmapTileHeader -{ - uint32 mmapMagic{MMAP_MAGIC}; - uint32 dtVersion; - uint32 mmapVersion{MMAP_VERSION}; - uint32 size{0}; - char usesLiquids{true}; - char padding[3]{}; - - MmapTileHeader() : dtVersion(DT_NAVMESH_VERSION) {} -}; - -// All padding fields must be handled and initialized to ensure mmaps_generator will produce binary-identical *.mmtile files -static_assert(sizeof(MmapTileHeader) == 20, "MmapTileHeader size is not correct, adjust the padding field size"); -static_assert(sizeof(MmapTileHeader) == (sizeof(MmapTileHeader::mmapMagic) + - sizeof(MmapTileHeader::dtVersion) + - sizeof(MmapTileHeader::mmapVersion) + - sizeof(MmapTileHeader::size) + - sizeof(MmapTileHeader::usesLiquids) + - sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields"); - namespace MMAP { MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 7aae07448..c196cf4ce 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -20,20 +20,6 @@ #include #endif -enum NavTerrain -{ - NAV_EMPTY = 0x00, - NAV_GROUND = 0x01, - NAV_MAGMA = 0x02, - NAV_SLIME = 0x04, - NAV_WATER = 0x08, - NAV_UNUSED1 = 0x10, - NAV_UNUSED2 = 0x20, - NAV_UNUSED3 = 0x40, - NAV_UNUSED4 = 0x80 - // we only have 8 bits -}; - namespace MMAP { inline bool matchWildcardFilter(const char* filter, const char* str) diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 3c56e49c3..aaf33f675 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -5,10 +5,9 @@ */ #include "TerrainBuilder.h" - #include "PathCommon.h" #include "MapBuilder.h" - +#include "MapDefines.h" #include "VMapManager2.h" #include "MapTree.h" #include "ModelInstance.h" diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp deleted file mode 100644 index 29970ae15..000000000 --- a/src/tools/mmaps_generator/VMapExtensions.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-GPL2 - * Copyright (C) 2008-2016 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - */ - -#include -#include "MapTree.h" -#include "VMapManager2.h" -#include "WorldModel.h" -#include "ModelInstance.h" - -namespace VMAP -{ - // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator - // maybe add MapBuilder as friend to all of the below classes would be better? - - // declared in src/common/vmap/MapTree.h - void StaticMapTree::getModelInstances(ModelInstance*& models, uint32& count) - { - models = iTreeValues; - count = iNTreeValues; - } - - // declared in src/common/vmap/VMapManager2.h - void VMapManager2::getInstanceMapTree(InstanceTreeMap& instanceMapTree) - { - instanceMapTree = iInstanceMapTrees; - } - - // declared in src/common/vmap/WorldModel.h - void WorldModel::getGroupModels(std::vector& groupModels) - { - groupModels = this->groupModels; - } - - // declared in src/common/vmap/WorldModel.h - void GroupModel::getMeshData(std::vector& vertices, std::vector& triangles, WmoLiquid*& liquid) - { - vertices = this->vertices; - triangles = this->triangles; - liquid = iLiquid; - } - - // declared in src/common/vmap/ModelInstance.h - WorldModel* ModelInstance::getWorldModel() - { - return iModel; - } - - // declared in src/common/vmap/WorldModel.h - void WmoLiquid::getPosInfo(uint32& tilesX, uint32& tilesY, G3D::Vector3& corner) const - { - tilesX = iTilesX; - tilesY = iTilesY; - corner = iCorner; - } -}