diff options
Diffstat (limited to 'src/tools')
44 files changed, 968 insertions, 492 deletions
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index 9efea7aaec..03fa926fd4 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -140,7 +140,8 @@ foreach(TOOL_NAME ${TOOLS_BUILD_LIST}) mpq zlib Recast - g3dlib) + g3dlib + fkYAML) endif() unset(TOOL_PUBLIC_INCLUDES) @@ -170,4 +171,8 @@ foreach(TOOL_NAME ${TOOLS_BUILD_LIST}) elseif (WIN32) install(TARGETS ${TOOL_PROJECT_NAME} DESTINATION "${CMAKE_INSTALL_PREFIX}") endif() + + if (${TOOL_PROJECT_NAME} STREQUAL "mmaps_generator") + install(FILES ${SOURCE_TOOL_PATH}/mmaps-config.yaml DESTINATION bin) + endif() endforeach() diff --git a/src/tools/dbimport/Main.cpp b/src/tools/dbimport/Main.cpp index 87371f62a3..06b3ce6658 100644 --- a/src/tools/dbimport/Main.cpp +++ b/src/tools/dbimport/Main.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 @@ -109,8 +109,8 @@ bool StartDB() DatabaseLoader loader = modules.empty() ? DatabaseLoader("dbimport") : - (modules == "all") ? DatabaseLoader("dbimport", DatabaseLoader::DATABASE_NONE, AC_MODULES_LIST) : - DatabaseLoader("dbimport", DatabaseLoader::DATABASE_NONE, modules); + (modules == "all") ? DatabaseLoader("dbimport", DatabaseLoader::DATABASE_MASK_ALL, AC_MODULES_LIST) : + DatabaseLoader("dbimport", DatabaseLoader::DATABASE_MASK_ALL, modules); loader .AddDatabase(LoginDatabase, "Login") @@ -140,7 +140,8 @@ variables_map GetConsoleArguments(int argc, char** argv, fs::path& configFile) ("help,h", "print usage message") ("version,v", "print version build info") ("dry-run,d", "Dry run") - ("config,c", value<fs::path>(&configFile)->default_value(fs::path(sConfigMgr->GetConfigPath() + std::string(_ACORE_DB_IMPORT_CONFIG))), "use <arg> as configuration file"); + ("config,c", value<fs::path>(&configFile)->default_value(fs::path(sConfigMgr->GetConfigPath() + std::string(_ACORE_DB_IMPORT_CONFIG))), "use <arg> as configuration file") + ("config-policy", value<std::string>()->value_name("policy"), "override config severity policy (e.g. default=skip,critical_option=fatal)"); variables_map variablesMap; diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index 4396ed47f7..4fef9164e7 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp index 7717080c82..7a3c524182 100644 --- a/src/tools/map_extractor/adt.cpp +++ b/src/tools/map_extractor/adt.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h index 01917e66f9..4cbbb20a07 100644 --- a/src/tools/map_extractor/adt.h +++ b/src/tools/map_extractor/adt.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/dbcfile.cpp b/src/tools/map_extractor/dbcfile.cpp index 589511666d..ecec134aea 100644 --- a/src/tools/map_extractor/dbcfile.cpp +++ b/src/tools/map_extractor/dbcfile.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/dbcfile.h b/src/tools/map_extractor/dbcfile.h index 5fd5365938..0fb6298fc1 100644 --- a/src/tools/map_extractor/dbcfile.h +++ b/src/tools/map_extractor/dbcfile.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp index 8434fa641c..67cf659142 100644 --- a/src/tools/map_extractor/loadlib.cpp +++ b/src/tools/map_extractor/loadlib.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/loadlib/loadlib.h b/src/tools/map_extractor/loadlib/loadlib.h index 68fd5ea00b..6a34ea62f8 100644 --- a/src/tools/map_extractor/loadlib/loadlib.h +++ b/src/tools/map_extractor/loadlib/loadlib.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/mpq_libmpq.cpp b/src/tools/map_extractor/mpq_libmpq.cpp index 5b70a933ad..f9101027ea 100644 --- a/src/tools/map_extractor/mpq_libmpq.cpp +++ b/src/tools/map_extractor/mpq_libmpq.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/mpq_libmpq04.h b/src/tools/map_extractor/mpq_libmpq04.h index dece851e9e..6576111390 100644 --- a/src/tools/map_extractor/mpq_libmpq04.h +++ b/src/tools/map_extractor/mpq_libmpq04.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/wdt.cpp b/src/tools/map_extractor/wdt.cpp index 5ff0ddc299..ef10704a3d 100644 --- a/src/tools/map_extractor/wdt.cpp +++ b/src/tools/map_extractor/wdt.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/map_extractor/wdt.h b/src/tools/map_extractor/wdt.h index 3272959207..8ce1003646 100644 --- a/src/tools/map_extractor/wdt.h +++ b/src/tools/map_extractor/wdt.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/mmaps_generator/Config.cpp b/src/tools/mmaps_generator/Config.cpp new file mode 100644 index 0000000000..dabdb0f0d3 --- /dev/null +++ b/src/tools/mmaps_generator/Config.cpp @@ -0,0 +1,276 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#include "Config.h" +#include <filesystem> +#include <fkYAML/node.hpp> +#include "PathCommon.h" +#include "TerrainBuilder.h" + +namespace MMAP +{ + float ComputeBaseUnitDim(int vertexPerMapEdge) + { + return GRID_SIZE / static_cast<float>(vertexPerMapEdge); + } + + std::pair<uint32, uint32> MakeTileKey(uint32 x, uint32 y) + { + return {x, y}; + } + + bool isCurrentDirectory(const std::string& pathStr) { + try { + const std::filesystem::path givenPath = std::filesystem::canonical(std::filesystem::absolute(pathStr)); + const std::filesystem::path currentPath = std::filesystem::canonical(std::filesystem::current_path()); + return givenPath == currentPath; + } catch (const std::filesystem::filesystem_error& e) { + std::cerr << "Filesystem error: " << e.what() << "\n"; + return false; + } + } + + MmapTileRecastConfig ResolvedMeshConfig::toMMAPTileRecastConfig() const { + MmapTileRecastConfig config; + config.walkableSlopeAngle = walkableSlopeAngle; + config.walkableHeight = walkableHeight; + config.walkableClimb = walkableClimb; + config.walkableRadius = walkableRadius; + config.maxSimplificationError = maxSimplificationError; + config.cellSizeHorizontal = cellSizeHorizontal; + config.cellSizeVertical = cellSizeVertical; + config.baseUnitDim = baseUnitDim; + config.vertexPerMapEdge = vertexPerMapEdge; + config.vertexPerTileEdge = vertexPerTileEdge; + config.tilesPerMapEdge = tilesPerMapEdge; + return config; + } + + std::optional<Config> Config::FromFile(std::string_view configFile) { + Config config; + if (!config.LoadConfig(configFile)) + return std::nullopt; + + return config; + } + + Config::Config() + { + } + + ResolvedMeshConfig Config::GetConfigForTile(uint32 mapID, uint32 tileX, uint32 tileY) const + { + const MapOverride* mapOverride = nullptr; + const TileOverride* tileOverride = nullptr; + + // Lookup map and tile overrides + if (auto mapIt = _maps.find(mapID); mapIt != _maps.end()) + { + mapOverride = &mapIt->second; + + auto tileIt = mapOverride->tileOverrides.find(MakeTileKey(tileY, tileX)); + if (tileIt != mapOverride->tileOverrides.end()) + tileOverride = &tileIt->second; + } + + // Helper lambdas to resolve values in order: tile -> map -> global + auto resolveFloat = [&](auto TileField, auto MapField, float GlobalValue) -> float { + if (tileOverride && TileField(tileOverride)) return *TileField(tileOverride); + if (mapOverride && MapField(mapOverride)) return *MapField(mapOverride); + return GlobalValue; + }; + + auto resolveInt = [&](auto TileField, auto MapField, int GlobalValue) -> int { + if (tileOverride && TileField(tileOverride)) return *TileField(tileOverride); + if (mapOverride && MapField(mapOverride)) return *MapField(mapOverride); + return GlobalValue; + }; + + // Resolve vertex settings + int vertexPerMap = resolveInt( + [](const TileOverride*) { return std::optional<int>{}; }, + [](const MapOverride* m) { return m->vertexPerMapEdge; }, + _global.vertexPerMapEdge + ); + + int vertexPerTile = resolveInt( + [](const TileOverride*) { return std::optional<int>{}; }, + [](const MapOverride* m) { return m->vertexPerTileEdge; }, + _global.vertexPerTileEdge + ); + + ResolvedMeshConfig config; + config.walkableSlopeAngle = resolveFloat( + [](const TileOverride* t) { return t->walkableSlopeAngle; }, + [](const MapOverride* m) { return m->walkableSlopeAngle; }, + _global.walkableSlopeAngle + ); + + config.walkableRadius = resolveInt( + [](const TileOverride* t) { return t->walkableRadius; }, + [](const MapOverride* m) { return m->walkableRadius; }, + _global.walkableRadius + ); + + config.walkableHeight = resolveInt( + [](const TileOverride* t) { return t->walkableHeight; }, + [](const MapOverride* m) { return m->walkableHeight; }, + _global.walkableHeight + ); + + config.walkableClimb = resolveInt( + [](const TileOverride* t) { return t->walkableClimb; }, + [](const MapOverride* m) { return m->walkableClimb; }, + _global.walkableClimb + ); + + config.vertexPerMapEdge = vertexPerMap; + config.vertexPerTileEdge = vertexPerTile; + config.baseUnitDim = ComputeBaseUnitDim(vertexPerMap); + config.tilesPerMapEdge = vertexPerMap / vertexPerTile; + config.maxSimplificationError = _global.maxSimplificationError; + config.cellSizeHorizontal = config.baseUnitDim; + config.cellSizeVertical = config.baseUnitDim; + + if (mapOverride && mapOverride->cellSizeHorizontal.has_value()) + config.cellSizeHorizontal = *mapOverride->cellSizeHorizontal; + + if (mapOverride && mapOverride->cellSizeVertical.has_value()) + config.cellSizeVertical = *mapOverride->cellSizeVertical; + + return config; + } + + bool Config::LoadConfig(std::string_view configFile) { + FILE* f = std::fopen(configFile.data(), "r"); + if (!f) + return false; + + fkyaml::node root = fkyaml::node::deserialize(f); + std::fclose(f); + + if (!root.contains("mmapsConfig")) + return false; + + fkyaml::node mmapsNode = root["mmapsConfig"]; + + auto tryFloat = [](const fkyaml::node& n, const char* key, float& out) + { + if (n.contains(key)) out = n[key].get_value<float>(); + }; + auto tryInt = [](const fkyaml::node& n, const char* key, int& out) + { + if (n.contains(key)) out = n[key].get_value<int>(); + }; + auto tryBoolean = [](const fkyaml::node& n, const char* key, bool& out) + { + if (n.contains(key)) out = n[key].get_value<bool>(); + }; + auto tryString = [](const fkyaml::node& n, const char* key, std::string& out) + { + if (n.contains(key)) out = n[key].get_value<std::string>(); + }; + + tryBoolean(mmapsNode, "skipLiquid", _skipLiquid); + tryBoolean(mmapsNode, "skipContinents", _skipContinents); + tryBoolean(mmapsNode, "skipJunkMaps", _skipJunkMaps); + tryBoolean(mmapsNode, "skipBattlegrounds", _skipBattlegrounds); + tryBoolean(mmapsNode, "debugOutput", _debugOutput); + + std::string dataDirPath; + tryString(mmapsNode, "dataDir", dataDirPath); + _dataDir = dataDirPath; + + mmapsNode = mmapsNode["meshSettings"]; + + // Global config + tryFloat(mmapsNode, "walkableSlopeAngle", _global.walkableSlopeAngle); + tryInt(mmapsNode, "walkableHeight", _global.walkableHeight); + tryInt(mmapsNode, "walkableClimb", _global.walkableClimb); + tryInt(mmapsNode, "walkableRadius", _global.walkableRadius); + tryInt(mmapsNode, "vertexPerMapEdge", _global.vertexPerMapEdge); + tryInt(mmapsNode, "vertexPerTileEdge", _global.vertexPerTileEdge); + tryFloat(mmapsNode, "maxSimplificationError", _global.maxSimplificationError); + + // Map overrides + if (mmapsNode.contains("mapsOverrides")) + { + fkyaml::node maps = mmapsNode["mapsOverrides"]; + for (auto const& mapEntry : maps.as_map()) + { + uint32 mapId = std::stoi(mapEntry.first.as_str()); + + MapOverride override; + fkyaml::node mapNode = mapEntry.second; + + if (mapNode.contains("walkableSlopeAngle")) + override.walkableSlopeAngle = mapNode["walkableSlopeAngle"].get_value<float>(); + if (mapNode.contains("walkableRadius")) + override.walkableRadius = mapNode["walkableRadius"].get_value<int>(); + if (mapNode.contains("walkableHeight")) + override.walkableHeight = mapNode["walkableHeight"].get_value<int>(); + if (mapNode.contains("walkableClimb")) + override.walkableClimb = mapNode["walkableClimb"].get_value<int>(); + if (mapNode.contains("vertexPerMapEdge")) + override.vertexPerMapEdge = mapNode["vertexPerMapEdge"].get_value<int>(); + if (mapNode.contains("cellSizeHorizontal")) + override.cellSizeHorizontal = mapNode["cellSizeHorizontal"].get_value<float>(); + if (mapNode.contains("cellSizeVertical")) + override.cellSizeVertical = mapNode["cellSizeVertical"].get_value<float>(); + + // Tile overrides + if (mapNode.contains("tilesOverrides")) + { + fkyaml::node tiles = mapNode["tilesOverrides"]; + for (auto const& tileEntry : tiles.as_map()) + { + std::string key = tileEntry.first.as_str(); + fkyaml::node tileNode = tileEntry.second; + + size_t comma = key.find(','); + if (comma == std::string::npos) + continue; + + uint32 tileX = static_cast<uint32>(std::stoi(key.substr(0, comma))); + uint32 tileY = static_cast<uint32>(std::stoi(key.substr(comma + 1))); + + TileOverride tileOverride; + if (tileNode.contains("walkableSlopeAngle")) + tileOverride.walkableSlopeAngle = tileNode["walkableSlopeAngle"].get_value<float>(); + if (tileNode.contains("walkableRadius")) + tileOverride.walkableRadius = tileNode["walkableRadius"].get_value<int>(); + if (tileNode.contains("walkableHeight")) + tileOverride.walkableHeight = tileNode["walkableHeight"].get_value<int>(); + if (tileNode.contains("walkableClimb")) + tileOverride.walkableClimb = tileNode["walkableClimb"].get_value<int>(); + + override.tileOverrides[{tileX, tileY}] = std::move(tileOverride); + } + } + + _maps[mapId] = std::move(override); + } + } + + // Resolve data dir path. Maybe we need to use an executable path instead of the current dir. + if (isCurrentDirectory(_dataDir.string()) && !std::filesystem::exists(MapsPath())) + if (auto execPath = std::filesystem::path(executableDirectoryPath()); std::filesystem::exists(execPath/ "maps")) + _dataDir = execPath; + + return true; + } +} diff --git a/src/tools/mmaps_generator/Config.h b/src/tools/mmaps_generator/Config.h new file mode 100644 index 0000000000..c97fa79998 --- /dev/null +++ b/src/tools/mmaps_generator/Config.h @@ -0,0 +1,159 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#ifndef CONFIG_H +#define CONFIG_H + +#include <filesystem> +#include <optional> +#include <string> +#include <string_view> +#include <unordered_map> +#include <boost/program_options/options_description.hpp> +#include "Define.h" +#include "MapDefines.h" + +namespace std +{ + template <> + struct hash<std::pair<uint32_t, uint32_t>> + { + std::size_t operator()(const std::pair<uint32_t, uint32_t>& p) const noexcept + { + return std::hash<uint64_t>()((static_cast<uint64_t>(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<Config> 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<float> walkableSlopeAngle; + std::optional<int> walkableRadius; + std::optional<int> walkableHeight; + std::optional<int> walkableClimb; + }; + + struct MapOverride { + std::optional<float> walkableSlopeAngle; + std::optional<int> walkableRadius; + std::optional<int> walkableHeight; + std::optional<int> walkableClimb; + std::optional<int> vertexPerMapEdge; + std::optional<int> 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<float> 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<float> cellSizeVertical; + + std::unordered_map<std::pair<uint32, uint32>, 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<uint32, MapOverride> _maps; + + bool _skipLiquid; + bool _skipContinents; + bool _skipJunkMaps; + bool _skipBattlegrounds; + bool _debugOutput; + + std::filesystem::path _dataDir; + }; +} + +#endif //CONFIG_H diff --git a/src/tools/mmaps_generator/Info/readme.txt b/src/tools/mmaps_generator/Info/readme.txt index 7e1a1ece6f..c0702d50c4 100644 --- a/src/tools/mmaps_generator/Info/readme.txt +++ b/src/tools/mmaps_generator/Info/readme.txt @@ -1,5 +1,8 @@ Generator command line args +--config [file.*] The path the yaml config file + Default: "mmaps-config.yaml" + --threads [#] Max number of threads used by the generator Default: 3 @@ -11,39 +14,6 @@ Generator command line args --silent [] Make us script friendly. Do not wait for user input on error or completion. ---bigBaseUnit [true|false] Generate tile/map using bigger basic unit. - Use this option only if you have unexpected gaps. - - false: use normal metrics (default) - ---maxAngle [#] Max walkable inclination angle - - float between 45 and 90 degrees (default 60) - ---skipLiquid [true|false] extract liquid data for maps - - false: include liquid data (default) - ---skipContinents [true|false] continents are maps 0 (Eastern Kingdoms), - 1 (Kalimdor), 530 (Outlands), 571 (Northrend) - - false: build continents (default) - ---skipJunkMaps [true|false] junk maps include some unused - maps, transport maps, and some other - - true: skip junk maps (default) - ---skipBattlegrounds [true|false] does not include PVP arenas - - false: skip battlegrounds (default) - ---debugOutput [true|false] create debugging files for use with RecastDemo - if you are only creating mmaps for use with Moongose, - you don't want debugging files - - false: don't create debugging files (default) - --tile [#,#] Build the specified tile seperate number with a comma ',' must specify a map number (see below) @@ -58,9 +28,6 @@ examples: movement_extractor builds maps using the default settings (see above for defaults) -movement_extractor --skipContinents true -builds the default maps, except continents - movement_extractor 0 builds all tiles of map 0 diff --git a/src/tools/mmaps_generator/IntermediateValues.cpp b/src/tools/mmaps_generator/IntermediateValues.cpp index 12b478979e..584d14c021 100644 --- a/src/tools/mmaps_generator/IntermediateValues.cpp +++ b/src/tools/mmaps_generator/IntermediateValues.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 @@ -16,6 +16,8 @@ */ #include "IntermediateValues.h" +#include <string> +#include "StringFormat.h" namespace MMAP { @@ -28,15 +30,15 @@ namespace MMAP rcFreePolyMeshDetail(polyMeshDetail); } - void IntermediateValues::writeIV(uint32 mapID, uint32 tileX, uint32 tileY) + void IntermediateValues::writeIV(const std::string& dataPath, uint32 mapID, uint32 tileX, uint32 tileY) { - char fileName[255]; + char fileName[512]; char tileString[25]; sprintf(tileString, "[%02u,%02u]: ", tileX, tileY); printf("%sWriting debug output... \r", tileString); - std::string name("meshes/%03u%02i%02i."); + std::string name(dataPath+"/meshes/%03u%02i%02i."); #define DEBUG_WRITE(fileExtension,data) \ do { \ @@ -198,16 +200,19 @@ namespace MMAP fwrite(mesh->meshes, sizeof(int), mesh->nmeshes * 4, file); } - void IntermediateValues::generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData) + void IntermediateValues::generateObjFile(const std::string& dataPath, uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData) { - char objFileName[255]; - sprintf(objFileName, "meshes/map%03u%02u%02u.obj", mapID, tileY, tileX); + std::string objFileName = Acore::StringFormat( + "{}/meshes/map{:03}{:02}{:02}.obj", + dataPath, + mapID, tileY, tileX + ); - FILE* objFile = fopen(objFileName, "wb"); + FILE* objFile = fopen(objFileName.c_str(), "wb"); if (!objFile) { char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", objFileName); + sprintf(message, "Failed to open %s for writing!\n", objFileName.c_str()); perror(message); return; } @@ -237,13 +242,17 @@ namespace MMAP sprintf(tileString, "[%02u,%02u]: ", tileY, tileX); printf("%sWriting debug output... \r", tileString); - sprintf(objFileName, "meshes/%03u.map", mapID); + objFileName = Acore::StringFormat( + "{}/meshes/{:03}.map", + dataPath, + mapID + ); - objFile = fopen(objFileName, "wb"); + objFile = fopen(objFileName.c_str(), "wb"); if (!objFile) { char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", objFileName); + sprintf(message, "Failed to open %s for writing!\n", objFileName.c_str()); perror(message); return; } @@ -252,12 +261,17 @@ namespace MMAP fwrite(&b, sizeof(char), 1, objFile); fclose(objFile); - sprintf(objFileName, "meshes/%03u%02u%02u.mesh", mapID, tileY, tileX); - objFile = fopen(objFileName, "wb"); + objFileName = Acore::StringFormat( + "{}/meshes/{:03}{:02}{:02}.mesh", + dataPath, + mapID, tileY, tileX + ); + + objFile = fopen(objFileName.c_str(), "wb"); if (!objFile) { char message[1024]; - sprintf(message, "Failed to open %s for writing!\n", objFileName); + sprintf(message, "Failed to open %s for writing!\n", objFileName.c_str()); perror(message); return; } diff --git a/src/tools/mmaps_generator/IntermediateValues.h b/src/tools/mmaps_generator/IntermediateValues.h index 971cf9000a..2894e5b58e 100644 --- a/src/tools/mmaps_generator/IntermediateValues.h +++ b/src/tools/mmaps_generator/IntermediateValues.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 @@ -35,7 +35,7 @@ namespace MMAP IntermediateValues() {} ~IntermediateValues(); - void writeIV(uint32 mapID, uint32 tileX, uint32 tileY); + void writeIV(const std::string& dataPath, uint32 mapID, uint32 tileX, uint32 tileY); void debugWrite(FILE* file, const rcHeightfield* mesh); void debugWrite(FILE* file, const rcCompactHeightfield* chf); @@ -43,7 +43,7 @@ namespace MMAP void debugWrite(FILE* file, const rcPolyMesh* mesh); void debugWrite(FILE* file, const rcPolyMeshDetail* mesh); - void generateObjFile(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData); + void generateObjFile(const std::string& dataPath, uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData); }; } #endif diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 407cdb103c..45c71367b7 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 @@ -16,28 +16,28 @@ */ #include "MapBuilder.h" +#include <DetourCommon.h> +#include <DetourNavMesh.h> +#include <DetourNavMeshBuilder.h> #include "IntermediateValues.h" #include "MapDefines.h" #include "MapTree.h" +#include "MMapMgr.h" #include "ModelInstance.h" #include "PathCommon.h" #include "StringFormat.h" #include "VMapMgr2.h" -#include <DetourCommon.h> -#include <DetourNavMesh.h> -#include <DetourNavMeshBuilder.h> namespace MMAP { - TileBuilder::TileBuilder(MapBuilder* mapBuilder, bool skipLiquid, bool bigBaseUnit, bool debugOutput) : - m_bigBaseUnit(bigBaseUnit), + TileBuilder::TileBuilder(MapBuilder* mapBuilder, bool skipLiquid, bool debugOutput) : m_debugOutput(debugOutput), m_mapBuilder(mapBuilder), m_terrainBuilder(nullptr), m_workerThread(&TileBuilder::WorkerThread, this), m_rcContext(nullptr) { - m_terrainBuilder = new TerrainBuilder(skipLiquid); + m_terrainBuilder = new TerrainBuilder(m_mapBuilder->getConfig().DataDirPath(), skipLiquid); m_rcContext = new rcContext(false); } @@ -55,26 +55,22 @@ namespace MMAP m_workerThread.join(); } - MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid, - bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, - bool debugOutput, bool bigBaseUnit, int mapid, const char* offMeshFilePath, unsigned int threads) : - - m_debugOutput (debugOutput), + MapBuilder::MapBuilder(Config* config, int mapid, const char* offMeshFilePath, unsigned int threads) : + m_config (config), + m_debugOutput (config->IsDebugOutputEnabled()), m_offMeshFilePath (offMeshFilePath), m_threads (threads), - m_skipContinents (skipContinents), - m_skipJunkMaps (skipJunkMaps), - m_skipBattlegrounds (skipBattlegrounds), - m_skipLiquid (skipLiquid), - m_maxWalkableAngle (maxWalkableAngle), - m_bigBaseUnit (bigBaseUnit), + m_skipContinents (config->ShouldSkipContinents()), + m_skipJunkMaps (config->ShouldSkipJunkMaps()), + m_skipBattlegrounds (config->ShouldSkipBattlegrounds()), + m_skipLiquid (config->ShouldSkipLiquid()), m_mapid (mapid), m_totalTiles (0u), m_totalTilesProcessed(0u), _cancelationToken (false) { - m_terrainBuilder = new TerrainBuilder(skipLiquid); + m_terrainBuilder = new TerrainBuilder(config->DataDirPath(), config->ShouldSkipLiquid()); m_rcContext = new rcContext(false); @@ -105,7 +101,7 @@ namespace MMAP char filter[12]; printf("Discovering maps... "); - getDirContents(files, "maps"); + getDirContents(files, m_config->MapsPath()); for (auto & file : files) { mapID = uint32(atoi(file.substr(0, file.size() - 8).c_str())); @@ -117,7 +113,7 @@ namespace MMAP } files.clear(); - getDirContents(files, "vmaps", "*.vmtree"); + getDirContents(files, m_config->VMapsPath(), "*.vmtree"); for (auto & file : files) { mapID = uint32(atoi(file.substr(0, file.size() - 7).c_str())); @@ -138,7 +134,7 @@ namespace MMAP sprintf(filter, "%03u*.vmtile", mapID); files.clear(); - getDirContents(files, "vmaps", filter); + getDirContents(files, m_config->VMapsPath(), filter); for (auto & file : files) { fsize = file.size(); @@ -153,7 +149,7 @@ namespace MMAP sprintf(filter, "%03u*", mapID); files.clear(); - getDirContents(files, "maps", filter); + getDirContents(files, m_config->MapsPath(), filter); for (auto & file : files) { fsize = file.size(); @@ -209,7 +205,7 @@ namespace MMAP for (unsigned int i = 0; i < m_threads; ++i) { - m_tileBuilders.push_back(new TileBuilder(this, m_skipLiquid, m_bigBaseUnit, m_debugOutput)); + m_tileBuilders.push_back(new TileBuilder(this, m_skipLiquid, m_debugOutput)); } if (mapID) @@ -367,7 +363,7 @@ namespace MMAP getTileBounds(tileX, tileY, data.solidVerts.getCArray(), data.solidVerts.size() / 3, bmin, bmax); // build navmesh tile - TileBuilder tileBuilder = TileBuilder(this, m_skipLiquid, m_bigBaseUnit, m_debugOutput); + TileBuilder tileBuilder = TileBuilder(this, m_skipLiquid, m_debugOutput); tileBuilder.buildMoveMapTile(mapId, tileX, tileY, data, bmin, bmax, navMesh); fclose(file); } @@ -385,7 +381,7 @@ namespace MMAP /// @todo: delete the old tile as the user clearly wants to rebuild it - TileBuilder tileBuilder = TileBuilder(this, m_skipLiquid, m_bigBaseUnit, m_debugOutput); + TileBuilder tileBuilder = TileBuilder(this, m_skipLiquid, m_debugOutput); tileBuilder.buildTile(mapID, tileX, tileY, navMesh); dtFreeNavMesh(navMesh); @@ -567,15 +563,18 @@ namespace MMAP return; } - char fileName[25]; - sprintf(fileName, "mmaps/%03u.mmap", mapID); + const std::string fileName = Acore::StringFormat( + MAP_FILE_NAME_FORMAT, + m_config->DataDirPath(), + mapID + ); - FILE* file = fopen(fileName, "wb"); + FILE* file = fopen(fileName.c_str(), "wb"); if (!file) { dtFreeNavMesh(navMesh); char message[1024]; - sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName); + sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName.c_str()); perror(message); return; } @@ -608,16 +607,17 @@ namespace MMAP int lTriCount = meshData.liquidTris.size() / 3; uint8* lTriFlags = meshData.liquidType.getCArray(); - const TileConfig tileConfig = TileConfig(m_bigBaseUnit); - int TILES_PER_MAP = tileConfig.TILES_PER_MAP; - float BASE_UNIT_DIM = tileConfig.BASE_UNIT_DIM; - rcConfig config = m_mapBuilder->GetMapSpecificConfig(mapID, bmin, bmax, tileConfig); + ResolvedMeshConfig cfg = m_mapBuilder->getConfig().GetConfigForTile(mapID, tileX, tileY); + int tilesPerMap = cfg.tilesPerMapEdge; + float baseUnitDim = cfg.baseUnitDim; + + rcConfig config = m_mapBuilder->getRecastConfig(cfg, bmin, bmax); // this sets the dimensions of the heightfield - should maybe happen before border padding rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); // allocate subregions : tiles - Tile* tiles = new Tile[TILES_PER_MAP * TILES_PER_MAP]; + Tile* tiles = new Tile[tilesPerMap * tilesPerMap]; // Initialize per tile config. rcConfig tileCfg = config; @@ -625,15 +625,16 @@ namespace MMAP tileCfg.height = config.tileSize + config.borderSize * 2; // merge per tile poly and detail meshes - rcPolyMesh** pmmerge = new rcPolyMesh*[TILES_PER_MAP * TILES_PER_MAP]; - rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[TILES_PER_MAP * TILES_PER_MAP]; + rcPolyMesh** pmmerge = new rcPolyMesh*[tilesPerMap * tilesPerMap]; + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[tilesPerMap * tilesPerMap]; int nmerge = 0; + // build all tiles - for (int y = 0; y < TILES_PER_MAP; ++y) + for (int y = 0; y < tilesPerMap; ++y) { - for (int x = 0; x < TILES_PER_MAP; ++x) + for (int x = 0; x < tilesPerMap; ++x) { - Tile& tile = tiles[x + y * TILES_PER_MAP]; + Tile& tile = tiles[x + y * tilesPerMap]; // Calculate the per tile bounding box. tileCfg.bmin[0] = config.bmin[0] + x * float(config.tileSize * config.cs); @@ -790,9 +791,9 @@ namespace MMAP params.offMeshConAreas = meshData.offMeshConnectionsAreas.getCArray(); params.offMeshConFlags = meshData.offMeshConnectionsFlags.getCArray(); - params.walkableHeight = BASE_UNIT_DIM * config.walkableHeight; // agent height - params.walkableRadius = BASE_UNIT_DIM * config.walkableRadius; // agent radius - params.walkableClimb = BASE_UNIT_DIM * config.walkableClimb; // keep less that walkableHeight (aka agent height)! + params.walkableHeight = baseUnitDim * config.walkableHeight; // agent height + params.walkableRadius = baseUnitDim * config.walkableRadius; // agent radius + params.walkableClimb = baseUnitDim * config.walkableClimb; // keep less that walkableHeight (aka agent height)! params.tileX = (((bmin[0] + bmax[0]) / 2) - navMesh->getParams()->orig[0]) / GRID_SIZE; params.tileY = (((bmin[2] + bmax[2]) / 2) - navMesh->getParams()->orig[2]) / GRID_SIZE; rcVcopy(params.bmin, bmin); @@ -861,13 +862,17 @@ namespace MMAP } // file output - char fileName[255]; - sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); - FILE* file = fopen(fileName, "wb"); + const std::string fileName = Acore::StringFormat( + TILE_FILE_NAME_FORMAT, + m_mapBuilder->getConfig().DataDirPath(), + mapID, tileY, tileX + ); + + FILE* file = fopen(fileName.c_str(), "wb"); if (!file) { char message[1024]; - sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName); + sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName.c_str()); perror(message); navMesh->removeTile(tileRef, nullptr, nullptr); break; @@ -879,6 +884,7 @@ namespace MMAP MmapTileHeader header; header.usesLiquids = m_terrainBuilder->usesLiquids(); header.size = uint32(navDataSize); + header.recastConfig = cfg.toMMAPTileRecastConfig(); fwrite(&header, sizeof(MmapTileHeader), 1, file); // write data @@ -899,8 +905,8 @@ namespace MMAP v[2] += (unsigned short)config.borderSize; } - iv.generateObjFile(mapID, tileX, tileY, meshData); - iv.writeIV(mapID, tileX, tileY); + iv.generateObjFile(m_mapBuilder->getConfig().DataDirPath(), mapID, tileX, tileY, meshData); + iv.writeIV(m_mapBuilder->getConfig().DataDirPath(), mapID, tileX, tileY); } } @@ -1028,9 +1034,13 @@ namespace MMAP /**************************************************************************/ bool TileBuilder::shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) const { - char fileName[255]; - sprintf(fileName, "mmaps/%03u%02i%02i.mmtile", mapID, tileY, tileX); - FILE* file = fopen(fileName, "rb"); + const std::string fileName = Acore::StringFormat( + TILE_FILE_NAME_FORMAT, + m_mapBuilder->getConfig().DataDirPath(), + mapID, tileY, tileX + ); + + FILE* file = fopen(fileName.c_str(), "rb"); if (!file) return false; @@ -1046,10 +1056,11 @@ namespace MMAP if (header.mmapVersion != MMAP_VERSION) return false; - return true; + const auto desiredRecastConfig = m_mapBuilder->getConfig().GetConfigForTile(mapID, tileX, tileY).toMMAPTileRecastConfig(); + return header.recastConfig == desiredRecastConfig; } - rcConfig MapBuilder::GetMapSpecificConfig(uint32 mapID, float bmin[3], float bmax[3], const TileConfig &tileConfig) const + rcConfig MapBuilder::getRecastConfig(const ResolvedMeshConfig &cfg, float bmin[3], float bmax[3]) const { rcConfig config; memset(&config, 0, sizeof(rcConfig)); @@ -1058,39 +1069,20 @@ namespace MMAP rcVcopy(config.bmax, bmax); config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; - config.cs = tileConfig.BASE_UNIT_DIM; - config.ch = tileConfig.BASE_UNIT_DIM; - config.walkableSlopeAngle = m_maxWalkableAngle; - config.tileSize = tileConfig.VERTEX_PER_TILE; - config.walkableRadius = m_bigBaseUnit ? 1 : 2; - config.borderSize = config.walkableRadius + 3; - config.maxEdgeLen = tileConfig.VERTEX_PER_TILE + 1; // anything bigger than tileSize - config.walkableHeight = m_bigBaseUnit ? 3 : 6; - // a value >= 3|6 allows npcs to walk over some fences - // a value >= 4|8 allows npcs to walk over all fences - config.walkableClimb = m_bigBaseUnit ? 3 : 6; + config.cs = cfg.cellSizeHorizontal; + config.ch = cfg.cellSizeVertical; + config.walkableSlopeAngle = cfg.walkableSlopeAngle; + config.tileSize = cfg.vertexPerTileEdge; + config.walkableRadius = cfg.walkableRadius; + config.borderSize = cfg.walkableRadius + 3; + config.maxEdgeLen = cfg.vertexPerTileEdge + 1; // anything bigger than tileSize + config.walkableHeight = cfg.walkableHeight; + config.walkableClimb = cfg.walkableClimb; config.minRegionArea = rcSqr(60); config.mergeRegionArea = rcSqr(50); - config.maxSimplificationError = 1.8f; // eliminates most jagged edges (tiny polygons) + config.maxSimplificationError = cfg.maxSimplificationError; // eliminates most jagged edges (tiny polygons) config.detailSampleDist = config.cs * 16; config.detailSampleMaxError = config.ch * 1; - - switch (mapID) - { - // Blade's Edge Arena - case 562: - // This allows to walk on the ropes to the pillars - config.walkableRadius = 0; - break; - // Blackfathom Deeps - case 48: - // Reduce the chance to have underground levels - config.ch *= 2; - break; - default: - break; - } - return config; } diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h index 19ef1ef59f..313c88c525 100644 --- a/src/tools/mmaps_generator/MapBuilder.h +++ b/src/tools/mmaps_generator/MapBuilder.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 @@ -24,6 +24,7 @@ #include <thread> #include <vector> +#include "Config.h" #include "Optional.h" #include "TerrainBuilder.h" @@ -71,27 +72,6 @@ namespace MMAP rcPolyMeshDetail* dmesh{nullptr}; }; - struct TileConfig - { - TileConfig(bool bigBaseUnit) - { - // these are WORLD UNIT based metrics - // this are basic unit dimentions - // value have to divide GRID_SIZE(533.3333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc ) - BASE_UNIT_DIM = bigBaseUnit ? 0.5333333f : 0.2666666f; - - // All are in UNIT metrics! - VERTEX_PER_MAP = int(GRID_SIZE / BASE_UNIT_DIM + 0.5f); - VERTEX_PER_TILE = bigBaseUnit ? 40 : 80; // must divide VERTEX_PER_MAP - TILES_PER_MAP = VERTEX_PER_MAP / VERTEX_PER_TILE; - } - - float BASE_UNIT_DIM; - int VERTEX_PER_MAP; - int VERTEX_PER_TILE; - int TILES_PER_MAP; - }; - struct TileInfo { TileInfo() : m_mapId(uint32(-1)), m_tileX(), m_tileY(), m_navMeshParams() {} @@ -109,7 +89,6 @@ namespace MMAP public: TileBuilder(MapBuilder* mapBuilder, bool skipLiquid, - bool bigBaseUnit, bool debugOutput); TileBuilder(TileBuilder&&) = default; @@ -131,7 +110,6 @@ namespace MMAP bool shouldSkipTile(uint32 mapID, uint32 tileX, uint32 tileY) const; private: - bool m_bigBaseUnit; bool m_debugOutput; MapBuilder* m_mapBuilder; @@ -145,13 +123,7 @@ namespace MMAP { friend class TileBuilder; public: - MapBuilder(float maxWalkableAngle, - bool skipLiquid, - bool skipContinents, - bool skipJunkMaps, - bool skipBattlegrounds, - bool debugOutput, - bool bigBaseUnit, + MapBuilder(Config* config, int mapid, char const* offMeshFilePath, unsigned int threads); @@ -166,6 +138,7 @@ namespace MMAP // builds list of maps, then builds all of mmap tiles (based on the skip settings) void buildMaps(Optional<uint32> mapID); + const Config& getConfig() const { return *m_config; } private: // builds all mmap tiles for the specified map id (ignores skip settings) void buildMap(uint32 mapID); @@ -184,7 +157,7 @@ namespace MMAP bool isTransportMap(uint32 mapID) const; bool isContinentMap(uint32 mapID) const; - rcConfig GetMapSpecificConfig(uint32 mapID, float bmin[3], float bmax[3], const TileConfig &tileConfig) const; + rcConfig getRecastConfig(const ResolvedMeshConfig &cfg, float bmin[3], float bmax[3]) const; uint32 percentageDone(uint32 totalTiles, uint32 totalTilesDone) const; uint32 currentPercentageDone() const; @@ -201,10 +174,10 @@ namespace MMAP bool m_skipBattlegrounds; bool m_skipLiquid; - float m_maxWalkableAngle; - bool m_bigBaseUnit; int32 m_mapid; + Config* m_config; + std::atomic<uint32> m_totalTiles; std::atomic<uint32> m_totalTilesProcessed; diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 866dffb688..6dc6dd608e 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 @@ -20,6 +20,7 @@ #include <string> #include <vector> +#include <boost/dll/runtime_symbol_info.hpp> #ifndef _WIN32 #include <cstddef> @@ -35,6 +36,11 @@ namespace MMAP { + inline std::string executableDirectoryPath() + { + return boost::dll::program_location().parent_path().string(); + } + inline bool matchWildcardFilter(const char* filter, const char* str) { if (!filter || !str) diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 03fece6462..b7fa572c16 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -1,20 +1,21 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 <http://www.gnu.org/licenses/>. */ +#include "Config.h" #include "MapBuilder.h" #include "PathCommon.h" #include "Timer.h" @@ -23,37 +24,34 @@ using namespace MMAP; -bool checkDirectories(bool debugOutput) +bool checkDirectories(const std::string &dataDirPath, bool debugOutput) { std::vector<std::string> dirFiles; - if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) + if (getDirContents(dirFiles, (std::filesystem::path(dataDirPath) / "maps").string()) == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) { printf("'maps' directory is empty or does not exist\n"); return false; } dirFiles.clear(); - if (getDirContents(dirFiles, "vmaps", "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) + if (getDirContents(dirFiles, (std::filesystem::path(dataDirPath) / "vmaps").string(), "*.vmtree") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) { printf("'vmaps' directory is empty or does not exist\n"); return false; } dirFiles.clear(); - if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) + if (getDirContents(dirFiles, (std::filesystem::path(dataDirPath) / "mmaps").string()) == LISTFILE_DIRECTORY_NOT_FOUND) { - return boost::filesystem::create_directory("mmaps"); + return boost::filesystem::create_directory((std::filesystem::path(dataDirPath) / "mmaps").string()); } dirFiles.clear(); - if (debugOutput) + if (debugOutput && getDirContents(dirFiles, (std::filesystem::path(dataDirPath) / "meshes").string()) == LISTFILE_DIRECTORY_NOT_FOUND) { - if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND) - { - printf("'meshes' directory does not exist (no place to put debugOutput files)\n"); - return false; - } + printf("'meshes' directory does not exist creating...\n"); + return boost::filesystem::create_directory((std::filesystem::path(dataDirPath) / "meshes").string()); } return true; @@ -63,32 +61,24 @@ bool handleArgs(int argc, char** argv, int& mapnum, int& tileX, int& tileY, - float& maxAngle, - bool& skipLiquid, - bool& skipContinents, - bool& skipJunkMaps, - bool& skipBattlegrounds, - bool& debugOutput, + std::string& configFilePath, bool& silent, - bool& bigBaseUnit, char*& offMeshInputPath, char*& file, unsigned int& threads) { + bool hasCustomConfigPath = false; char* param = nullptr; for (int i = 1; i < argc; ++i) { - if (strcmp(argv[i], "--maxAngle") == 0) + if (strcmp(argv[i], "--config") == 0) { param = argv[++i]; if (!param) return false; - float maxangle = atof(param); - if (maxangle <= 90.f && maxangle >= 45.f) - maxAngle = maxangle; - else - printf("invalid option for '--maxAngle', using default\n"); + hasCustomConfigPath = true; + configFilePath = param; } else if (strcmp(argv[i], "--threads") == 0) { @@ -126,88 +116,10 @@ bool handleArgs(int argc, char** argv, return false; } } - else if (strcmp(argv[i], "--skipLiquid") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipLiquid = true; - else if (strcmp(param, "false") == 0) - skipLiquid = false; - else - printf("invalid option for '--skipLiquid', using default\n"); - } - else if (strcmp(argv[i], "--skipContinents") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipContinents = true; - else if (strcmp(param, "false") == 0) - skipContinents = false; - else - printf("invalid option for '--skipContinents', using default\n"); - } - else if (strcmp(argv[i], "--skipJunkMaps") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipJunkMaps = true; - else if (strcmp(param, "false") == 0) - skipJunkMaps = false; - else - printf("invalid option for '--skipJunkMaps', using default\n"); - } - else if (strcmp(argv[i], "--skipBattlegrounds") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - skipBattlegrounds = true; - else if (strcmp(param, "false") == 0) - skipBattlegrounds = false; - else - printf("invalid option for '--skipBattlegrounds', using default\n"); - } - else if (strcmp(argv[i], "--debugOutput") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - debugOutput = true; - else if (strcmp(param, "false") == 0) - debugOutput = false; - else - printf("invalid option for '--debugOutput', using default true\n"); - } else if (strcmp(argv[i], "--silent") == 0) { silent = true; } - else if (strcmp(argv[i], "--bigBaseUnit") == 0) - { - param = argv[++i]; - if (!param) - return false; - - if (strcmp(param, "true") == 0) - bigBaseUnit = true; - else if (strcmp(param, "false") == 0) - bigBaseUnit = false; - else - printf("invalid option for '--bigBaseUnit', using default false\n"); - } else if (strcmp(argv[i], "--offMeshInput") == 0) { param = argv[++i]; @@ -229,6 +141,23 @@ bool handleArgs(int argc, char** argv, } } + if (!hasCustomConfigPath) + { + FILE* f = fopen(configFilePath.c_str(), "r"); + if (!f) + { + auto execRelPath = std::filesystem::path(executableDirectoryPath())/configFilePath; + f = fopen(execRelPath.string().c_str(), "r"); + if (!f) + { + printf("Failed to load configuration. Ensure that 'mmaps-config.yaml' exists in the current directory or specify its path using the --config option.'\n"); + return false; + } + configFilePath = execRelPath.string(); + } + fclose(f); + } + return true; } @@ -244,42 +173,36 @@ int main(int argc, char** argv) unsigned int threads = std::thread::hardware_concurrency(); int mapnum = -1; int tileX = -1, tileY = -1; - float maxAngle = 60.0f; - bool skipLiquid = false, - skipContinents = false, - skipJunkMaps = true, - skipBattlegrounds = false, - debugOutput = false, - silent = false, - bigBaseUnit = false; + bool silent = false; char* offMeshInputPath = nullptr; char* file = nullptr; - + std::string configFilePath = "mmaps-config.yaml"; bool validParam = handleArgs(argc, argv, mapnum, - tileX, tileY, maxAngle, - skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, - debugOutput, silent, bigBaseUnit, offMeshInputPath, file, threads); + tileX, tileY, configFilePath, silent, offMeshInputPath, file, threads); if (!validParam) return silent ? -1 : finish("You have specified invalid parameters", -1); - if (mapnum == -1 && debugOutput) + auto config = Config::FromFile(configFilePath); + if (!config) + return silent ? -1 : finish("Failed to load configuration. Ensure that 'mmaps-config.yaml' exists in the current directory or specify its path using the --config option.", -1); + + if (mapnum == -1 && config->IsDebugOutputEnabled()) { if (silent) return -2; - printf("You have specifed debug output, but didn't specify a map to generate.\n"); + printf("You have specified debug output, but didn't specify a map to generate.\n"); printf("This will generate debug output for ALL maps.\n"); printf("Are you sure you want to continue? (y/n) "); if (getchar() != 'y') return 0; } - if (!checkDirectories(debugOutput)) + if (!checkDirectories(config->DataDirPath(), config->IsDebugOutputEnabled())) return silent ? -3 : finish("Press ENTER to close...", -3); - MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, - skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath, threads); + MapBuilder builder(&config.value(), mapnum, offMeshInputPath, threads); uint32 start = getMSTime(); if (file) diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index 2faee49d94..6fb539b0fc 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 @@ -25,6 +25,8 @@ #include <vector> #include <map> +#include "StringFormat.h" + // ****************************************** // Map file format defines // ****************************************** @@ -80,10 +82,17 @@ struct map_liquidHeader namespace MMAP { + static char const* const MAP_FILE_NAME_FORMAT = "{}/{:03}{:02}{:02}.map"; uint32 const MAP_VERSION_MAGIC = 9; - TerrainBuilder::TerrainBuilder(bool skipLiquid) : m_skipLiquid (skipLiquid) { } + TerrainBuilder::TerrainBuilder(const std::string &dataDirPath, bool skipLiquid) : + m_skipLiquid (skipLiquid), + m_mapsPath((std::filesystem::path(dataDirPath) / "maps").string()), + m_vmapsPath((std::filesystem::path(dataDirPath) / "vmaps").string()) + { + } + TerrainBuilder::~TerrainBuilder() = default; /**************************************************************************/ @@ -134,10 +143,13 @@ namespace MMAP /**************************************************************************/ bool TerrainBuilder::loadMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData, Spot portion) { - char mapFileName[255]; - sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); + const std::string mapFileName = Acore::StringFormat( + MAP_FILE_NAME_FORMAT, + m_mapsPath, + mapID, tileY, tileX + ); - FILE* mapFile = fopen(mapFileName, "rb"); + FILE* mapFile = fopen(mapFileName.c_str(), "rb"); if (!mapFile) return false; @@ -146,7 +158,7 @@ namespace MMAP fheader.versionMagic != MAP_VERSION_MAGIC) { fclose(mapFile); - printf("%s is the wrong version, please extract new .map files\n", mapFileName); + printf("%s is the wrong version, please extract new .map files\n", mapFileName.c_str()); return false; } @@ -665,7 +677,7 @@ namespace MMAP bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData& meshData) { IVMapMgr* vmapMgr = new VMapMgr2(); - int result = vmapMgr->loadMap("vmaps", mapID, tileX, tileY); + int result = vmapMgr->loadMap(m_vmapsPath.c_str(), mapID, tileX, tileY); bool retval = false; do diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h index 23cdbc4710..63c21fe081 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.h +++ b/src/tools/mmaps_generator/TerrainBuilder.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 @@ -76,7 +76,7 @@ namespace MMAP class TerrainBuilder { public: - TerrainBuilder(bool skipLiquid); + TerrainBuilder(const std::string &mapsPath, bool skipLiquid); ~TerrainBuilder(); TerrainBuilder(const TerrainBuilder& tb) = delete; @@ -121,6 +121,9 @@ namespace MMAP /// Get the liquid type for a specific position uint8 getLiquidType(int square, const uint8 liquid_type[16][16]); + + std::string m_mapsPath; + std::string m_vmapsPath; }; } diff --git a/src/tools/mmaps_generator/mmaps-config.yaml b/src/tools/mmaps_generator/mmaps-config.yaml new file mode 100644 index 0000000000..2a0aba1fc9 --- /dev/null +++ b/src/tools/mmaps_generator/mmaps-config.yaml @@ -0,0 +1,145 @@ +mmapsConfig: + skipLiquid: false + skipContinents: false + skipJunkMaps: true + skipBattlegrounds: false + + # Path to the directory containing navigation data files. + # This directory should contain the "maps" and "vmaps" folders, + # and is also where the "mmaps" folder will be created or located. + dataDir: "./" + + meshSettings: + # Here we have global config for recast navigation. + # It's possible to override these data on map or tile level (see mapsOverrides). + + # Maximum slope angle (in degrees) NPCs can walk on. + # Surfaces steeper than this will be considered unwalkable. + walkableSlopeAngle: 60 + + # --- Cell Size Calculation --- + # Many parameters below are defined in "cell units". + # In RecastDemo, you often work with world units instead of cell units. + # By default, these cell units are converted to world units using the formula: + # + # cellSize = MMAP::GRID_SIZE / (verticesPerMapEdge - 1) + # + # Where: + # MMAP::GRID_SIZE = 533.3333f (the size of one map tile in world units) + # verticesPerMapEdge = number of vertices along one edge of the full map grid + # + # Example: + # If verticesPerMapEdge = 2000, then: + # cellSize ≈ 533.3333 / (2000 - 1) ≈ 0.2667 world units per cell + # + # To convert a value from cell units to world units (e.g., walkableClimb), + # multiply by cellSize. For example, a walkableClimb of 6 corresponds to: + # 6 * 0.2667 ≈ 1.6 world units + + # Minimum ceiling height (in cell units) NPCs need to pass under an obstacle. + # Controls how much vertical clearance is required. + # To convert to world units, multiply by cellSize (see "Cell Size Calculation"). + walkableHeight: 6 + + # Maximum height difference (in cell units) NPCs can step up or down. + # Higher values allow walking over fences, ledges, or steps. + # To convert to world units, multiply by cellSize (see "Cell Size Calculation"). + # + # Vanilla WotLK uses 6, which allows creatures to "jump" over fences. + # Classic WotLK uses 4, which forces creatures to walk around fences. + walkableClimb: 6 + + # Minimum distance (in cell units) around walkable surfaces. + # Helps prevent NPCs from clipping into walls and narrow gaps. + # To convert to world units, multiply by cellSize (see "Cell Size Calculation"). + walkableRadius: 2 + + # Number of vertices along one edge of the entire map's navmesh grid. + # Higher values increase mesh resolution but also CPU/memory usage. + verticesPerMapEdge: 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. + verticesPerTileEdge: 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. + maxSimplificationError: 1.8 + + # You can override any global parameter for a specific map by specifying its map ID. + # Inside each map override, you can also override parameters per individual tile, + # identified by a string "tileX,tileY" (coordinates). + # + # Overrides cascade: global settings → map overrides → tile overrides. + # For example: + # + # mapsOverrides: + # "0": # Map ID 0 overrides + # walkableRadius: 5 # Override global climb height for entire map 0 + # + # tilesOverrides: + # "50,70": # Tile at coordinates (50,70) on map 0 + # walkableSlopeAngle: 70 # Override slope angle locally just here + # walkableClimb: 4 # Also override climb height for this tile only + # + # "51,71": + # walkableClimb: 3 # Override climb height for tile (51,71) + # + # "48,32": + # walkableClimb: 1 # Even smaller climb for tile (48,32) + # + # "1": # Map ID 1 overrides example + # walkableHeight: 8 # Increase clearance for whole map 1 + # + # tilesOverrides: + # "100,100": + # maxSimplificationError: 2.5 # Looser mesh simplification for this tile only + # + # "101,101": + # walkableRadius: 1 # Smaller NPC radius here for tight corridors + # + # This approach allows very fine-grained control of navigation mesh parameters + # on a per-map and per-tile basis, optimizing pathfinding quality and performance. + # + # All parameters defined globally are eligible for override. + # Just specify the parameter name and new value in the override section. + mapsOverrides: + "562": # Blade's Edge Arena + walkableRadius: 0 # This allows walking on the ropes to the pillars + + "48": # Blackfathom Deeps + cellSizeVertical: 0.5334 # ch*2 = 0.2667 * 2 ≈ 0.5334. Reduce the chance to have underground levels. + + "529": # Arathi Basin + tilesOverrides: + "30,29": # Lumber Mill + # Make sure that Fear will not drop players rom cliff - + # https://github.com/azerothcore/azerothcore-wotlk/pull/22462#issuecomment-3067024680 + walkableSlopeAngle: 45 + + # debugOutput generates debug files in the `meshes` directory for use with RecastDemo. + # This is useful for inspecting and debugging mmap generation visually. + # + # My workflow: + # 1. Install RecastDemo. I'm building it from the source of this fork: https://github.com/jackpoz/recastnavigation + # 2. In-game, move your character to the area you want to debug. + # 3. Type `.mmap loc` in chat. This will output: + # - The current tile file name (e.g., `04832.mmtile`) + # - The Recast config values used to generate that tile + # 4. Enable `debugOutput` and regenerate mmaps (preferably just the tile from step 3). + # - To regenerate only one tile, delete it from the `mmaps` folder. + # 5. After generation, you will find debug files in the `meshes` folder, including an OBJ file (e.g., `map0004832.obj`) + # 6. Copy these debug files to the `Meshes` folder used by RecastDemo. + # - RecastDemo expects this folder to be in the same directory as its executable. + # 7. In RecastDemo: + # - Click "Input Mesh" and select the `.obj` file + # - Choose "Solo Mesh" in the Sample selector + # 8. (Optional) Reuse the Recast config values from step 3: + # - `cellSizeHorizontal` → "Cell Size" + # - `walkableSlopeAngle` → "Max Slope" + # - `walkableClimb` → "Max Climb" + # - and so on + # 9. Scroll to the bottom of RecastDemo UI and press "Build" to generate the navigation mesh + debugOutput: false diff --git a/src/tools/vmap4_assembler/VMapAssembler.cpp b/src/tools/vmap4_assembler/VMapAssembler.cpp index fbe5fadb59..a0a6981ea6 100644 --- a/src/tools/vmap4_assembler/VMapAssembler.cpp +++ b/src/tools/vmap4_assembler/VMapAssembler.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp index 6db292bc86..98513c93dc 100644 --- a/src/tools/vmap4_extractor/adtfile.cpp +++ b/src/tools/vmap4_extractor/adtfile.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/adtfile.h b/src/tools/vmap4_extractor/adtfile.h index 201806f3a3..7ddd412d71 100644 --- a/src/tools/vmap4_extractor/adtfile.h +++ b/src/tools/vmap4_extractor/adtfile.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/dbcfile.cpp b/src/tools/vmap4_extractor/dbcfile.cpp index 3e6351b141..561d86265f 100644 --- a/src/tools/vmap4_extractor/dbcfile.cpp +++ b/src/tools/vmap4_extractor/dbcfile.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/dbcfile.h b/src/tools/vmap4_extractor/dbcfile.h index ad7a4bb703..49535cff9b 100644 --- a/src/tools/vmap4_extractor/dbcfile.h +++ b/src/tools/vmap4_extractor/dbcfile.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/gameobject_extract.cpp b/src/tools/vmap4_extractor/gameobject_extract.cpp index fd7160e783..b1470497e9 100644 --- a/src/tools/vmap4_extractor/gameobject_extract.cpp +++ b/src/tools/vmap4_extractor/gameobject_extract.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/loadlib/loadlib.h b/src/tools/vmap4_extractor/loadlib/loadlib.h index 83222d83af..037f15e633 100644 --- a/src/tools/vmap4_extractor/loadlib/loadlib.h +++ b/src/tools/vmap4_extractor/loadlib/loadlib.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp index d2912f0f37..ed006fbad2 100644 --- a/src/tools/vmap4_extractor/model.cpp +++ b/src/tools/vmap4_extractor/model.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/model.h b/src/tools/vmap4_extractor/model.h index 021d1dedba..6eb1c5ea94 100644 --- a/src/tools/vmap4_extractor/model.h +++ b/src/tools/vmap4_extractor/model.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/modelheaders.h b/src/tools/vmap4_extractor/modelheaders.h index b6230fee3f..8a46311628 100644 --- a/src/tools/vmap4_extractor/modelheaders.h +++ b/src/tools/vmap4_extractor/modelheaders.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/mpq_libmpq.cpp b/src/tools/vmap4_extractor/mpq_libmpq.cpp index 2e5e4eb2b7..d699c78294 100644 --- a/src/tools/vmap4_extractor/mpq_libmpq.cpp +++ b/src/tools/vmap4_extractor/mpq_libmpq.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/mpq_libmpq04.h b/src/tools/vmap4_extractor/mpq_libmpq04.h index 5b6c81ce3b..605ca54a8a 100644 --- a/src/tools/vmap4_extractor/mpq_libmpq04.h +++ b/src/tools/vmap4_extractor/mpq_libmpq04.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/vec3d.h b/src/tools/vmap4_extractor/vec3d.h index 25a042fc2e..fb07d0d473 100644 --- a/src/tools/vmap4_extractor/vec3d.h +++ b/src/tools/vmap4_extractor/vec3d.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 3acd698727..3b6e5a5be4 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/vmapexport.h b/src/tools/vmap4_extractor/vmapexport.h index 4f51ae165f..bf0872bfa9 100644 --- a/src/tools/vmap4_extractor/vmapexport.h +++ b/src/tools/vmap4_extractor/vmapexport.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp index 1a52342408..59955d1571 100644 --- a/src/tools/vmap4_extractor/wdtfile.cpp +++ b/src/tools/vmap4_extractor/wdtfile.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h index e2a6a61dfe..f534a60c88 100644 --- a/src/tools/vmap4_extractor/wdtfile.h +++ b/src/tools/vmap4_extractor/wdtfile.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index 70164930b7..0a25367949 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h index 8967a87a4a..dc44331e32 100644 --- a/src/tools/vmap4_extractor/wmo.h +++ b/src/tools/vmap4_extractor/wmo.h @@ -1,14 +1,14 @@ /* * 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 Affero General Public License as published by the - * Free Software Foundation; either version 3 of the License, or (at your - * option) any later version. + * 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 Affero General Public License for + * 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 |
