aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2018-04-22 01:01:48 +0200
committerShauren <shauren.trinity@gmail.com>2019-02-23 22:00:05 +0100
commit7b561373a892c74870a21cf31687df4afd554495 (patch)
tree2161514b5f1d1c8e4fdf2bc57b9c285ae8973d4e /src
parent8d19fcbc469e0b37a323c876a15097fbe848d884 (diff)
Tools/mmaps_generator: Give land priority during area merges over liquids
Closes #21700 (cherry picked from commit edb2b16f546d18bb66f1527dddb6189f617ec1b3)
Diffstat (limited to 'src')
-rw-r--r--src/common/Collision/Maps/MapDefines.h28
-rw-r--r--src/common/Collision/Maps/TileAssembler.cpp8
-rw-r--r--src/common/Collision/Maps/TileAssembler.h3
-rw-r--r--src/server/game/Movement/PathGenerator.cpp9
-rw-r--r--src/server/game/Movement/PathGenerator.h2
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp13
-rw-r--r--src/tools/mmaps_generator/PathCommon.h3
-rw-r--r--src/tools/mmaps_generator/PathGenerator.cpp41
-rw-r--r--src/tools/mmaps_generator/TerrainBuilder.cpp32
9 files changed, 87 insertions, 52 deletions
diff --git a/src/common/Collision/Maps/MapDefines.h b/src/common/Collision/Maps/MapDefines.h
index 5a525280f74..2109fa57e19 100644
--- a/src/common/Collision/Maps/MapDefines.h
+++ b/src/common/Collision/Maps/MapDefines.h
@@ -22,7 +22,7 @@
#include "DetourNavMesh.h"
const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP'
-#define MMAP_VERSION 8
+#define MMAP_VERSION 9
struct MmapTileHeader
{
@@ -46,18 +46,22 @@ static_assert(sizeof(MmapTileHeader) == (sizeof(MmapTileHeader::mmapMagic) +
sizeof(MmapTileHeader::usesLiquids) +
sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields");
-enum NavTerrain
+enum NavArea
{
- NAV_EMPTY = 0x00,
- NAV_GROUND = 0x01,
- NAV_MAGMA = 0x02,
- NAV_SLIME = 0x04,
- NAV_WATER = 0x08,
- NAV_UNUSED1 = 0x10,
- NAV_UNUSED2 = 0x20,
- NAV_UNUSED3 = 0x40,
- NAV_UNUSED4 = 0x80
- // we only have 8 bits
+ NAV_AREA_EMPTY = 0,
+ // areas 1-60 will be used for destructible areas (currently skipped in vmaps, WMO with flag 1)
+ // ground is the highest value to make recast choose ground over water when merging surfaces very close to each other (shallow water would be walkable)
+ NAV_AREA_GROUND = 63,
+ NAV_AREA_WATER = 62,
+ NAV_AREA_MAGMA_SLIME = 61 // don't need to differentiate between them
+};
+
+enum NavTerrainFlag
+{
+ NAV_EMPTY = 0x00,
+ NAV_GROUND = 1 << (63 - NAV_AREA_GROUND),
+ NAV_WATER = 1 << (63 - NAV_AREA_WATER),
+ NAV_MAGMA_SLIME = 1 << (63 - NAV_AREA_MAGMA_SLIME)
};
#endif /* _MAPDEFINES_H */
diff --git a/src/common/Collision/Maps/TileAssembler.cpp b/src/common/Collision/Maps/TileAssembler.cpp
index 37dc0ee55a4..250c40293e1 100644
--- a/src/common/Collision/Maps/TileAssembler.cpp
+++ b/src/common/Collision/Maps/TileAssembler.cpp
@@ -54,7 +54,7 @@ namespace VMAP
//=================================================================
TileAssembler::TileAssembler(const std::string& pSrcDirName, const std::string& pDestDirName)
- : iDestDir(pDestDirName), iSrcDir(pSrcDirName), iFilterMethod(nullptr), iCurrentUniqueNameId(0)
+ : iDestDir(pDestDirName), iSrcDir(pSrcDirName), iCurrentUniqueNameId(0)
{
boost::filesystem::create_directory(iDestDir);
//init();
@@ -236,8 +236,10 @@ namespace VMAP
printf("spawning Map %u\n", mapID);
mapData[mapID] = current = new MapSpawns();
}
- else current = (*map_iter).second;
- current->UniqueEntries.insert(pair<uint32, ModelSpawn>(spawn.ID, spawn));
+ else
+ current = map_iter->second;
+
+ current->UniqueEntries.emplace(spawn.ID, spawn);
current->TileEntries.insert(pair<uint32, uint32>(StaticMapTree::packTileID(tileX, tileY), spawn.ID));
}
bool success = (ferror(dirf) == 0);
diff --git a/src/common/Collision/Maps/TileAssembler.h b/src/common/Collision/Maps/TileAssembler.h
index 772af15450c..72040135a73 100644
--- a/src/common/Collision/Maps/TileAssembler.h
+++ b/src/common/Collision/Maps/TileAssembler.h
@@ -95,7 +95,6 @@ namespace VMAP
private:
std::string iDestDir;
std::string iSrcDir;
- bool (*iFilterMethod)(char *pName);
G3D::Table<std::string, unsigned int > iUniqueNameIds;
unsigned int iCurrentUniqueNameId;
MapData mapData;
@@ -111,8 +110,6 @@ namespace VMAP
void exportGameobjectModels();
bool convertRawFile(const std::string& pModelFilename);
- void setModelNameFilterMethod(bool (*pFilterMethod)(char *pName)) { iFilterMethod = pFilterMethod; }
- std::string getDirEntryNameFromModName(unsigned int pMapId, const std::string& pModPosName);
};
} // VMAP
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 9e9c60f3d92..d133fc2baf0 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -615,12 +615,12 @@ void PathGenerator::CreateFilter()
// creatures don't take environmental damage
if (creature->CanSwim())
- includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim
+ includeFlags |= (NAV_WATER | NAV_MAGMA_SLIME); // swim
}
else // assume Player
{
// perfect support not possible, just stay 'safe'
- includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA | NAV_SLIME);
+ includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA_SLIME);
}
_filter.setIncludeFlags(includeFlags);
@@ -644,7 +644,7 @@ void PathGenerator::UpdateFilter()
}
}
-NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z)
+NavTerrainFlag PathGenerator::GetNavTerrain(float x, float y, float z)
{
LiquidData data;
ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data, _sourceUnit->GetCollisionHeight());
@@ -657,9 +657,8 @@ NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z)
case MAP_LIQUID_TYPE_OCEAN:
return NAV_WATER;
case MAP_LIQUID_TYPE_MAGMA:
- return NAV_MAGMA;
case MAP_LIQUID_TYPE_SLIME:
- return NAV_SLIME;
+ return NAV_MAGMA_SLIME;
default:
return NAV_GROUND;
}
diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h
index 327f0c4696e..cd6d256300e 100644
--- a/src/server/game/Movement/PathGenerator.h
+++ b/src/server/game/Movement/PathGenerator.h
@@ -123,7 +123,7 @@ class TC_GAME_API PathGenerator
void BuildPointPath(float const* startPoint, float const* endPoint);
void BuildShortcut();
- NavTerrain GetNavTerrain(float x, float y, float z);
+ NavTerrainFlag GetNavTerrain(float x, float y, float z);
void CreateFilter();
void UpdateFilter();
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index 200c0b85917..b71199df508 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -590,7 +590,7 @@ namespace MMAP
// mark all walkable tiles, both liquids and solids
unsigned char* triFlags = new unsigned char[tTriCount];
- memset(triFlags, NAV_GROUND, tTriCount*sizeof(unsigned char));
+ memset(triFlags, NAV_AREA_GROUND, tTriCount*sizeof(unsigned char));
rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags);
rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb);
delete[] triFlags;
@@ -696,8 +696,15 @@ namespace MMAP
// set polygons as walkable
// TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off
for (int i = 0; i < iv.polyMesh->npolys; ++i)
- if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA)
- iv.polyMesh->flags[i] = iv.polyMesh->areas[i];
+ {
+ if (uint8 area = iv.polyMesh->areas[i] & RC_WALKABLE_AREA)
+ {
+ if (area >= NAV_AREA_MAGMA_SLIME)
+ iv.polyMesh->flags[i] = 1 << (63 - area);
+ else
+ iv.polyMesh->flags[i] = NAV_GROUND; // TODO: these will be dynamic in future
+ }
+ }
// setup mesh parameters
dtNavMeshCreateParams params;
diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h
index 26fa84c789c..3d34d28a9ed 100644
--- a/src/tools/mmaps_generator/PathCommon.h
+++ b/src/tools/mmaps_generator/PathCommon.h
@@ -25,6 +25,7 @@
#ifndef _WIN32
#include <cstddef>
+ #include <cstring>
#include <dirent.h>
#else
#include <Windows.h>
@@ -106,7 +107,7 @@ namespace MMAP
errno = 0;
if ((dp = readdir(dirp)) != nullptr)
{
- if (matchWildcardFilter(filter.c_str(), dp->d_name))
+ if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0 && matchWildcardFilter(filter.c_str(), dp->d_name))
fileList.push_back(std::string(dp->d_name));
}
else
diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp
index 8f17288e1f9..3f930042bd0 100644
--- a/src/tools/mmaps_generator/PathGenerator.cpp
+++ b/src/tools/mmaps_generator/PathGenerator.cpp
@@ -16,15 +16,27 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <boost/filesystem.hpp>
-
-#include "PathCommon.h"
+#include "Banner.h"
+#include "DBCFileLoader.h"
#include "MapBuilder.h"
+#include "PathCommon.h"
#include "Timer.h"
-#include "Banner.h"
+#include <boost/filesystem.hpp>
+#include <unordered_map>
using namespace MMAP;
+namespace
+{
+ std::unordered_map<uint32, uint8> _liquidTypes;
+}
+
+uint32 GetLiquidFlags(uint32 liquidId)
+{
+ auto itr = _liquidTypes.find(liquidId);
+ return itr != _liquidTypes.end() ? (1 << itr->second) : 0;
+}
+
bool checkDirectories(bool debugOutput)
{
std::vector<std::string> dirFiles;
@@ -239,6 +251,23 @@ int finish(char const* message, int returnValue)
return returnValue;
}
+std::unordered_map<uint32, uint8> LoadLiquid()
+{
+ DBCFileLoader liquidDbc;
+ std::unordered_map<uint32, uint8> liquidData;
+ // format string doesnt matter as long as it has correct length (only used for mapping to structures in worldserver)
+ if (liquidDbc.Load((boost::filesystem::path("dbc") / "LiquidType.dbc").string().c_str(), "nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"))
+ {
+ for (uint32 x = 0; x < liquidDbc.GetNumRows(); ++x)
+ {
+ DBCFileLoader::Record record = liquidDbc.getRecord(x);
+ liquidData[record.getUInt(0)] = record.getUInt(3);
+ }
+ }
+
+ return liquidData;
+}
+
int main(int argc, char** argv)
{
Trinity::Banner::Show("MMAP generator", [](char const* text) { printf("%s\n", text); }, nullptr);
@@ -280,6 +309,10 @@ int main(int argc, char** argv)
if (!checkDirectories(debugOutput))
return silent ? -3 : finish("Press ENTER to close...", -3);
+ _liquidTypes = LoadLiquid();
+ if (_liquidTypes.empty())
+ return silent ? -5 : finish("Failed to load LiquidType.dbc", -5);
+
MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps,
skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath);
diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp
index d86cf2738d2..ae73ffe9271 100644
--- a/src/tools/mmaps_generator/TerrainBuilder.cpp
+++ b/src/tools/mmaps_generator/TerrainBuilder.cpp
@@ -79,6 +79,8 @@ struct map_liquidHeader
#define MAP_LIQUID_TYPE_SLIME 0x08
#define MAP_LIQUID_TYPE_DARK_WATER 0x10
+uint32 GetLiquidFlags(uint32 liquidId);
+
namespace MMAP
{
char const* MAP_VERSION_MAGIC = "v1.9";
@@ -418,11 +420,9 @@ namespace MMAP
useLiquid = false;
}
else if ((liquidType & (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN)) != 0)
- liquidType = NAV_WATER;
- else if (liquidType & MAP_LIQUID_TYPE_MAGMA)
- liquidType = NAV_MAGMA;
- else if (liquidType & MAP_LIQUID_TYPE_SLIME)
- liquidType = NAV_SLIME;
+ liquidType = NAV_AREA_WATER;
+ else if ((liquidType & (MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)) != 0)
+ liquidType = NAV_AREA_MAGMA_SLIME;
else
useLiquid = false;
}
@@ -638,7 +638,7 @@ namespace MMAP
/**************************************************************************/
bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData)
{
- IVMapManager* vmapManager = new VMapManager2();
+ VMapManager2* vmapManager = new VMapManager2();
int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY);
bool retval = false;
@@ -714,22 +714,14 @@ namespace MMAP
vertsY = tilesY + 1;
uint8* flags = liquid->GetFlagsStorage();
float* data = liquid->GetHeightStorage();
- uint8 type = NAV_EMPTY;
+ uint8 type = NAV_AREA_EMPTY;
// convert liquid type to NavTerrain
- switch (liquid->GetType() & 3)
- {
- case 0:
- case 1:
- type = NAV_WATER;
- break;
- case 2:
- type = NAV_MAGMA;
- break;
- case 3:
- type = NAV_SLIME;
- break;
- }
+ uint32 liquidFlags = GetLiquidFlags(liquid->GetType());
+ if ((liquidFlags & (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN)) != 0)
+ type = NAV_AREA_WATER;
+ else if ((liquidFlags & (MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)) != 0)
+ type = NAV_AREA_MAGMA_SLIME;
// indexing is weird...
// after a lot of trial and error, this is what works: