/* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef CONFIG_H #define CONFIG_H #include #include #include #include #include #include #include "Define.h" #include "MapDefines.h" namespace std { template <> struct hash> { std::size_t operator()(const std::pair& p) const noexcept { return std::hash()((static_cast(p.first) << 32) | p.second); } }; } namespace MMAP { struct ResolvedMeshConfig { float walkableSlopeAngle; int walkableRadius; int walkableHeight; int walkableClimb; int vertexPerMapEdge; int vertexPerTileEdge; int tilesPerMapEdge; float baseUnitDim; float cellSizeHorizontal; float cellSizeVertical; float maxSimplificationError; MmapTileRecastConfig toMMAPTileRecastConfig() const; }; class Config { public: static std::optional FromFile(std::string_view configFile); ~Config() = default; ResolvedMeshConfig GetConfigForTile(uint32 mapID, uint32 tileX, uint32 tileY) const; bool ShouldSkipLiquid() const { return _skipLiquid; } bool ShouldSkipContinents() const { return _skipContinents; } bool ShouldSkipJunkMaps() const { return _skipJunkMaps; } bool ShouldSkipBattlegrounds() const { return _skipBattlegrounds; } bool IsDebugOutputEnabled() const { return _debugOutput; } std::string VMapsPath() const { return (_dataDir / "vmaps").string(); } std::string MapsPath() const { return (_dataDir / "maps").string(); } std::string MMapsPath() const { return (_dataDir / "mmaps").string(); } std::string DataDirPath() const { return _dataDir.string(); } private: explicit Config(); bool LoadConfig(std::string_view configFile); struct TileOverride { std::optional walkableSlopeAngle; std::optional walkableRadius; std::optional walkableHeight; std::optional walkableClimb; }; struct MapOverride { std::optional walkableSlopeAngle; std::optional walkableRadius; std::optional walkableHeight; std::optional walkableClimb; std::optional vertexPerMapEdge; std::optional vertexPerTileEdge; // The width/depth of each cell in the XZ-plane grid used for voxelization. [Units: world units] // A smaller value increases navmesh resolution but also memory and CPU usage. // Default is equal to calculated baseUnitDim. // Recast reference: https://github.com/recastnavigation/recastnavigation/blob/bd98d84c274ee06842bf51a4088ca82ac71f8c2d/Recast/Include/Recast.h#L231 std::optional cellSizeHorizontal; // The height of each cell in the Y-axis used for voxelization. [Units: world units] // Controls how vertical features are represented. Lower values improve accuracy for uneven terrain. // Default is equal to calculated baseUnitDim. // Recast reference: https://github.com/recastnavigation/recastnavigation/blob/bd98d84c274ee06842bf51a4088ca82ac71f8c2d/Recast/Include/Recast.h#L234 std::optional cellSizeVertical; std::unordered_map, TileOverride> tileOverrides; }; struct GlobalConfig { // Maximum slope angle (in degrees) NPCs can walk on. // Surfaces steeper than this will be considered unwalkable. float walkableSlopeAngle = 60.0f; // Minimum distance (in cell units) around walkable surfaces. // Helps prevent NPCs from clipping into walls and narrow gaps. int walkableRadius = 2; // Minimum ceiling height (in cell units) NPCs need to pass under an obstacle. // Controls how much vertical clearance is required. int walkableHeight = 6; // Maximum height difference (in cell units) NPCs can step up or down. // Higher values allow walking over fences, ledges, or steps. int walkableClimb = 6; // Number of vertices along one edge of the entire map's navmesh grid. // Higher values increase mesh resolution but also CPU/memory usage. int vertexPerMapEdge = 2000; // Number of vertices along one edge of each tile chunk. // Must divide (vertexPerMapEdge - 1) evenly for seamless tiles. // A higher vertex count per tile means fewer total tiles, // reducing runtime work to load, unload, and manage tiles. int vertexPerTileEdge = 80; // Tolerance for how much a polygon can deviate from the original geometry when simplified. // Higher values produce simpler (faster) meshes but can reduce accuracy. float maxSimplificationError = 1.8f; }; GlobalConfig _global; std::unordered_map _maps; bool _skipLiquid; bool _skipContinents; bool _skipJunkMaps; bool _skipBattlegrounds; bool _debugOutput; std::filesystem::path _dataDir; }; } #endif //CONFIG_H