This commit is contained in:
郑佩茹
2022-06-21 13:23:18 -06:00
14 changed files with 211 additions and 264 deletions

View File

@@ -224,9 +224,6 @@ struct rcConfig
/// The maximum slope that is considered walkable. [Limits: 0 <= value < 90] [Units: Degrees] /// The maximum slope that is considered walkable. [Limits: 0 <= value < 90] [Units: Degrees]
float walkableSlopeAngle; float walkableSlopeAngle;
/// The maximum slope that is considered walkable but not steep. It should be lower/equal than walkableSlopeAngle. [Limits: 0 <= value < 90] [Units: Degrees]
float walkableSlopeAngleNotSteep;
/// Minimum floor to 'ceiling' height that will still allow the floor area to /// Minimum floor to 'ceiling' height that will still allow the floor area to
/// be considered walkable. [Limit: >= 3] [Units: vx] /// be considered walkable. [Limit: >= 3] [Units: vx]
int walkableHeight; int walkableHeight;
@@ -813,7 +810,7 @@ bool rcCreateHeightfield(rcContext* ctx, rcHeightfield& hf, int width, int heigh
/// @param[in] nt The number of triangles. /// @param[in] nt The number of triangles.
/// @param[out] areas The triangle area ids. [Length: >= @p nt] /// @param[out] areas The triangle area ids. [Length: >= @p nt]
void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv, void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv,
const int* tris, int nt, unsigned char* areas, unsigned char areaType = RC_WALKABLE_AREA); const int* tris, int nt, unsigned char* areas);
/// Sets the area id of all triangles with a slope greater than or equal to the specified value to #RC_NULL_AREA. /// Sets the area id of all triangles with a slope greater than or equal to the specified value to #RC_NULL_AREA.
/// @ingroup recast /// @ingroup recast

View File

@@ -334,7 +334,7 @@ static void calcTriNormal(const float* v0, const float* v1, const float* v2, flo
void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle,
const float* verts, int nv, const float* verts, int nv,
const int* tris, int nt, const int* tris, int nt,
unsigned char* areas, unsigned char areaType) unsigned char* areas)
{ {
rcIgnoreUnused(ctx); rcIgnoreUnused(ctx);
rcIgnoreUnused(nv); rcIgnoreUnused(nv);
@@ -349,7 +349,7 @@ void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle,
calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm); calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm);
// Check if the face is walkable. // Check if the face is walkable.
if (norm[1] > walkableThr) if (norm[1] > walkableThr)
areas[i] = areaType; areas[i] = RC_WALKABLE_AREA;
} }
} }

View File

@@ -13,7 +13,7 @@
#define SIZE_OF_GRIDS 533.3333f #define SIZE_OF_GRIDS 533.3333f
#define MMAP_MAGIC 0x4d4d4150 // 'MMAP' #define MMAP_MAGIC 0x4d4d4150 // 'MMAP'
#define MMAP_VERSION 14 #define MMAP_VERSION 15
struct MmapTileHeader struct MmapTileHeader
{ {
@@ -36,27 +36,18 @@ static_assert(sizeof(MmapTileHeader) == (sizeof(MmapTileHeader::mmapMagic) +
sizeof(MmapTileHeader::usesLiquids) + sizeof(MmapTileHeader::usesLiquids) +
sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields"); sizeof(MmapTileHeader::padding)), "MmapTileHeader has uninitialized padding fields");
enum NavArea enum NavTerrain
{ {
NAV_AREA_EMPTY = 0, NAV_EMPTY = 0x00,
// areas 1-60 will be used for destructible areas (currently skipped in vmaps, WMO with flag 1) NAV_GROUND = 0x01,
// 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_MAGMA = 0x02,
NAV_AREA_GROUND = 11, NAV_SLIME = 0x04,
NAV_AREA_GROUND_STEEP = 10, NAV_WATER = 0x08,
NAV_AREA_WATER = 9, NAV_UNUSED1 = 0x10,
NAV_AREA_MAGMA_SLIME = 8, // don't need to differentiate between them NAV_UNUSED2 = 0x20,
NAV_AREA_MAX_VALUE = NAV_AREA_GROUND, NAV_UNUSED3 = 0x40,
NAV_AREA_MIN_VALUE = NAV_AREA_MAGMA_SLIME, NAV_UNUSED4 = 0x80
NAV_AREA_ALL_MASK = 0x3F // max allowed value // we only have 8 bits
};
enum NavTerrainFlag
{
NAV_EMPTY = 0x00,
NAV_GROUND = 1 << (NAV_AREA_MAX_VALUE - NAV_AREA_GROUND),
NAV_GROUND_STEEP = 1 << (NAV_AREA_MAX_VALUE - NAV_AREA_GROUND_STEEP),
NAV_WATER = 1 << (NAV_AREA_MAX_VALUE - NAV_AREA_WATER),
NAV_MAGMA_SLIME = 1 << (NAV_AREA_MAX_VALUE - NAV_AREA_MAGMA_SLIME)
}; };
#endif /* _MAPDEFINES_H */ #endif /* _MAPDEFINES_H */

View File

@@ -3595,6 +3595,16 @@ Calculate.Creature.Zone.Area.Data = 0
Calculate.Gameoject.Zone.Area.Data = 0 Calculate.Gameoject.Zone.Area.Data = 0
#
# Group.Raid.LevelRestriction
#
# The Group members need to the same, or higher level than the specified value.
# Minimum level is 10.
# Default: 10
#
Group.Raid.LevelRestriction = 10
# #
# LFG.Location.All # LFG.Location.All
# #

View File

@@ -18,6 +18,7 @@
#include "Group.h" #include "Group.h"
#include "Battleground.h" #include "Battleground.h"
#include "BattlegroundMgr.h" #include "BattlegroundMgr.h"
#include "Config.h"
#include "DatabaseEnv.h" #include "DatabaseEnv.h"
#include "GameTime.h" #include "GameTime.h"
#include "GroupMgr.h" #include "GroupMgr.h"
@@ -278,6 +279,16 @@ void Group::ConvertToLFG(bool restricted /*= true*/)
SendUpdate(); SendUpdate();
} }
bool Group::CheckLevelForRaid()
{
for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
if (player->getLevel() < sConfigMgr->GetOption<int32>("Group.Raid.LevelRestriction", 10))
return true;
return false;
}
void Group::ConvertToRaid() void Group::ConvertToRaid()
{ {
m_groupType = GroupType(m_groupType | GROUPTYPE_RAID); m_groupType = GroupType(m_groupType | GROUPTYPE_RAID);

View File

@@ -245,6 +245,7 @@ public:
uint8 GetMemberGroup(ObjectGuid guid) const; uint8 GetMemberGroup(ObjectGuid guid) const;
void ConvertToLFG(bool restricted = true); void ConvertToLFG(bool restricted = true);
bool CheckLevelForRaid();
void ConvertToRaid(); void ConvertToRaid();
void SetBattlegroundGroup(Battleground* bg); void SetBattlegroundGroup(Battleground* bg);

View File

@@ -621,6 +621,12 @@ void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket& /*recvData*/)
return; return;
/** error handling **/ /** error handling **/
if (group->CheckLevelForRaid())
{
SendPartyResult(PARTY_OP_INVITE, "", ERR_RAID_DISALLOWED_BY_LEVEL);
return;
}
if (!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2 || group->isLFGGroup()) // pussywizard: not allowed for lfg groups, it is either raid from the beginning or not! if (!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2 || group->isLFGGroup()) // pussywizard: not allowed for lfg groups, it is either raid from the beginning or not!
return; return;
/********************/ /********************/

View File

@@ -641,12 +641,12 @@ void PathGenerator::CreateFilter()
// creatures don't take environmental damage // creatures don't take environmental damage
if (creature->CanEnterWater()) if (creature->CanEnterWater())
includeFlags |= (NAV_WATER | NAV_MAGMA_SLIME); includeFlags |= (NAV_WATER | NAV_MAGMA);
} }
else // assume Player else // assume Player
{ {
// perfect support not possible, just stay 'safe' // perfect support not possible, just stay 'safe'
includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA_SLIME); includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA);
} }
_filter.setIncludeFlags(includeFlags); _filter.setIncludeFlags(includeFlags);
@@ -671,17 +671,13 @@ void PathGenerator::UpdateFilter()
_filter.setIncludeFlags(includedFlags); _filter.setIncludeFlags(includedFlags);
} }
if (Creature const* _sourceCreature = _source->ToCreature()) /*if (Creature const* _sourceCreature = _source->ToCreature())
{
if (_sourceCreature->IsInCombat() || _sourceCreature->IsInEvadeMode()) if (_sourceCreature->IsInCombat() || _sourceCreature->IsInEvadeMode())
{ _filter.setIncludeFlags(_filter.getIncludeFlags() | NAV_GROUND_STEEP);*/
_filter.setIncludeFlags(_filter.getIncludeFlags() | NAV_GROUND_STEEP);
}
}
} }
} }
NavTerrainFlag PathGenerator::GetNavTerrain(float x, float y, float z) const NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) const
{ {
LiquidData data; LiquidData data;
LiquidData const& liquidData = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), x, y, z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS); LiquidData const& liquidData = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), x, y, z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS);
@@ -695,7 +691,7 @@ NavTerrainFlag PathGenerator::GetNavTerrain(float x, float y, float z) const
return NAV_WATER; return NAV_WATER;
case MAP_LIQUID_TYPE_MAGMA: case MAP_LIQUID_TYPE_MAGMA:
case MAP_LIQUID_TYPE_SLIME: case MAP_LIQUID_TYPE_SLIME:
return NAV_MAGMA_SLIME; return NAV_MAGMA;
default: default:
return NAV_GROUND; return NAV_GROUND;
} }
@@ -1143,9 +1139,9 @@ bool PathGenerator::IsWaterPath(Movement::PointsArray pathPoints) const
// Check both start and end points, if they're both in water, then we can *safely* let the creature move // Check both start and end points, if they're both in water, then we can *safely* let the creature move
for (uint32 i = 0; i < pathPoints.size(); ++i) for (uint32 i = 0; i < pathPoints.size(); ++i)
{ {
NavTerrainFlag terrain = GetNavTerrain(pathPoints[i].x, pathPoints[i].y, pathPoints[i].z); NavTerrain terrain = GetNavTerrain(pathPoints[i].x, pathPoints[i].y, pathPoints[i].z);
// One of the points is not in the water // One of the points is not in the water
if (terrain != NAV_MAGMA_SLIME && terrain != NAV_WATER) if (terrain != NAV_MAGMA && terrain != NAV_WATER)
{ {
waterPath = false; waterPath = false;
break; break;

View File

@@ -168,7 +168,7 @@ class PathGenerator
void BuildPointPath(float const* startPoint, float const* endPoint); void BuildPointPath(float const* startPoint, float const* endPoint);
void BuildShortcut(); void BuildShortcut();
[[nodiscard]] NavTerrainFlag GetNavTerrain(float x, float y, float z) const; [[nodiscard]] NavTerrain GetNavTerrain(float x, float y, float z) const;
void CreateFilter(); void CreateFilter();
void UpdateFilter(); void UpdateFilter();

View File

@@ -52,7 +52,7 @@ namespace MMAP
m_workerThread.join(); m_workerThread.join();
} }
MapBuilder::MapBuilder(Optional<float> maxWalkableAngle, Optional<float> maxWalkableAngleNotSteep, bool skipLiquid, MapBuilder::MapBuilder(float maxWalkableAngle, bool skipLiquid,
bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds, bool skipContinents, bool skipJunkMaps, bool skipBattlegrounds,
bool debugOutput, bool bigBaseUnit, int mapid, const char* offMeshFilePath, unsigned int threads) : bool debugOutput, bool bigBaseUnit, int mapid, const char* offMeshFilePath, unsigned int threads) :
@@ -64,7 +64,6 @@ namespace MMAP
m_skipBattlegrounds (skipBattlegrounds), m_skipBattlegrounds (skipBattlegrounds),
m_skipLiquid (skipLiquid), m_skipLiquid (skipLiquid),
m_maxWalkableAngle (maxWalkableAngle), m_maxWalkableAngle (maxWalkableAngle),
m_maxWalkableAngleNotSteep (maxWalkableAngleNotSteep),
m_bigBaseUnit (bigBaseUnit), m_bigBaseUnit (bigBaseUnit),
m_mapid (mapid), m_mapid (mapid),
m_totalTiles (0u), m_totalTiles (0u),
@@ -654,16 +653,9 @@ namespace MMAP
// mark all walkable tiles, both liquids and solids // mark all walkable tiles, both liquids and solids
/* we want to have triangles with slope less than walkableSlopeAngleNotSteep (<= 55) to have NAV_AREA_GROUND
* and with slope between walkableSlopeAngleNotSteep and walkableSlopeAngle (55 < .. <= 70) to have NAV_AREA_GROUND_STEEP.
* we achieve this using recast API: memset everything to NAV_AREA_GROUND_STEEP, call rcClearUnwalkableTriangles with 70 so
* any area above that will get RC_NULL_AREA (unwalkable), then call rcMarkWalkableTriangles with 55 to set NAV_AREA_GROUND
* on anything below 55 . Players and idle Creatures can use NAV_AREA_GROUND, while Creatures in combat can use NAV_AREA_GROUND_STEEP.
*/
unsigned char* triFlags = new unsigned char[tTriCount]; unsigned char* triFlags = new unsigned char[tTriCount];
memset(triFlags, NAV_AREA_GROUND_STEEP, tTriCount * sizeof(unsigned char)); memset(triFlags, NAV_GROUND, tTriCount * sizeof(unsigned char));
rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags); rcClearUnwalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngle, tVerts, tVertCount, tTris, tTriCount, triFlags);
rcMarkWalkableTriangles(m_rcContext, tileCfg.walkableSlopeAngleNotSteep, tVerts, tVertCount, tTris, tTriCount, triFlags, NAV_AREA_GROUND);
rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb); rcRasterizeTriangles(m_rcContext, tVerts, tVertCount, tTris, triFlags, tTriCount, *tile.solid, config.walkableClimb);
delete[] triFlags; delete[] triFlags;
@@ -769,15 +761,8 @@ namespace MMAP
// set polygons as walkable // set polygons as walkable
// TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off // TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off
for (int i = 0; i < iv.polyMesh->npolys; ++i) for (int i = 0; i < iv.polyMesh->npolys; ++i)
{ if (iv.polyMesh->areas[i] & RC_WALKABLE_AREA)
if (uint8 area = iv.polyMesh->areas[i] & NAV_AREA_ALL_MASK) iv.polyMesh->flags[i] = iv.polyMesh->areas[i];
{
if (area >= NAV_AREA_MIN_VALUE)
iv.polyMesh->flags[i] = 1 << (NAV_AREA_MAX_VALUE - area);
else
iv.polyMesh->flags[i] = NAV_GROUND; // TODO: these will be dynamic in future
}
}
// setup mesh parameters // setup mesh parameters
dtNavMeshCreateParams params; dtNavMeshCreateParams params;
@@ -1072,10 +1057,7 @@ namespace MMAP
config.maxVertsPerPoly = DT_VERTS_PER_POLYGON; config.maxVertsPerPoly = DT_VERTS_PER_POLYGON;
config.cs = tileConfig.BASE_UNIT_DIM; config.cs = tileConfig.BASE_UNIT_DIM;
config.ch = tileConfig.BASE_UNIT_DIM; config.ch = tileConfig.BASE_UNIT_DIM;
// Keeping these 2 slope angles the same reduces a lot the number of polys. config.walkableSlopeAngle = m_maxWalkableAngle;
// 55 should be the minimum, maybe 70 is ok (keep in mind blink uses mmaps), 85 is too much for players
config.walkableSlopeAngle = m_maxWalkableAngle ? *m_maxWalkableAngle : 55;
config.walkableSlopeAngleNotSteep = m_maxWalkableAngleNotSteep ? *m_maxWalkableAngleNotSteep : 55;
config.tileSize = tileConfig.VERTEX_PER_TILE; config.tileSize = tileConfig.VERTEX_PER_TILE;
config.walkableRadius = m_bigBaseUnit ? 1 : 2; config.walkableRadius = m_bigBaseUnit ? 1 : 2;
config.borderSize = config.walkableRadius + 3; config.borderSize = config.walkableRadius + 3;

View File

@@ -147,8 +147,7 @@ namespace MMAP
{ {
friend class TileBuilder; friend class TileBuilder;
public: public:
MapBuilder(Optional<float> maxWalkableAngle, MapBuilder(float maxWalkableAngle,
Optional<float> maxWalkableAngleNotSteep,
bool skipLiquid, bool skipLiquid,
bool skipContinents, bool skipContinents,
bool skipJunkMaps, bool skipJunkMaps,
@@ -204,8 +203,7 @@ namespace MMAP
bool m_skipBattlegrounds; bool m_skipBattlegrounds;
bool m_skipLiquid; bool m_skipLiquid;
Optional<float> m_maxWalkableAngle; float m_maxWalkableAngle;
Optional<float> m_maxWalkableAngleNotSteep;
bool m_bigBaseUnit; bool m_bigBaseUnit;
int32 m_mapid; int32 m_mapid;

View File

@@ -105,7 +105,7 @@ namespace MMAP
errno = 0; errno = 0;
if ((dp = readdir(dirp)) != nullptr) if ((dp = readdir(dirp)) != nullptr)
{ {
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0 && matchWildcardFilter(filter.c_str(), dp->d_name)) if (matchWildcardFilter(filter.c_str(), dp->d_name))
fileList.emplace_back(dp->d_name); fileList.emplace_back(dp->d_name);
} }
else else

View File

@@ -17,26 +17,12 @@
#include "MapBuilder.h" #include "MapBuilder.h"
#include "PathCommon.h" #include "PathCommon.h"
#include "Timer.h"
#include "DBCFileLoader.h"
#include "PathCommon.h"
#include "Util.h" #include "Util.h"
#include "Timer.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <unordered_map>
using namespace MMAP; 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) bool checkDirectories(bool debugOutput)
{ {
std::vector<std::string> dirFiles; std::vector<std::string> dirFiles;
@@ -77,8 +63,7 @@ bool handleArgs(int argc, char** argv,
int& mapnum, int& mapnum,
int& tileX, int& tileX,
int& tileY, int& tileY,
Optional<float>& maxAngle, float& maxAngle,
Optional<float>& maxAngleNotSteep,
bool& skipLiquid, bool& skipLiquid,
bool& skipContinents, bool& skipContinents,
bool& skipJunkMaps, bool& skipJunkMaps,
@@ -100,23 +85,11 @@ bool handleArgs(int argc, char** argv,
return false; return false;
float maxangle = atof(param); float maxangle = atof(param);
if (maxangle <= 90.f && maxangle >= 0.f) if (maxangle <= 90.f && maxangle >= 45.f)
maxAngle = maxangle; maxAngle = maxangle;
else else
printf("invalid option for '--maxAngle', using default\n"); printf("invalid option for '--maxAngle', using default\n");
} }
else if (strcmp(argv[i], "--maxAngleNotSteep") == 0)
{
param = argv[++i];
if (!param)
return false;
float maxangle = atof(param);
if (maxangle <= 90.f && maxangle >= 0.f)
maxAngleNotSteep = maxangle;
else
printf("invalid option for '--maxAngleNotSteep', using default\n");
}
else if (strcmp(argv[i], "--threads") == 0) else if (strcmp(argv[i], "--threads") == 0)
{ {
param = argv[++i]; param = argv[++i];
@@ -266,29 +239,12 @@ int finish(const char* message, int returnValue)
return 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) int main(int argc, char** argv)
{ {
unsigned int threads = std::thread::hardware_concurrency(); unsigned int threads = std::thread::hardware_concurrency();
int mapnum = -1; int mapnum = -1;
int tileX = -1, tileY = -1; int tileX = -1, tileY = -1;
Optional<float> maxAngle, maxAngleNotSteep; float maxAngle = 60.0f;
bool skipLiquid = false, bool skipLiquid = false,
skipContinents = false, skipContinents = false,
skipJunkMaps = true, skipJunkMaps = true,
@@ -300,7 +256,7 @@ int main(int argc, char** argv)
char* file = nullptr; char* file = nullptr;
bool validParam = handleArgs(argc, argv, mapnum, bool validParam = handleArgs(argc, argv, mapnum,
tileX, tileY, maxAngle, maxAngleNotSteep, tileX, tileY, maxAngle,
skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds,
debugOutput, silent, bigBaseUnit, offMeshInputPath, file, threads); debugOutput, silent, bigBaseUnit, offMeshInputPath, file, threads);
@@ -322,13 +278,7 @@ int main(int argc, char** argv)
if (!checkDirectories(debugOutput)) if (!checkDirectories(debugOutput))
return silent ? -3 : finish("Press ENTER to close...", -3); return silent ? -3 : finish("Press ENTER to close...", -3);
_liquidTypes = LoadLiquid(); MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps,
if (_liquidTypes.empty())
{
return silent ? -5 : finish("Failed to load LiquidType.dbc", -5);
}
MapBuilder builder(maxAngle, maxAngleNotSteep, skipLiquid, skipContinents, skipJunkMaps,
skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath, threads); skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath, threads);
uint32 start = getMSTime(); uint32 start = getMSTime();

View File

@@ -77,8 +77,6 @@ struct map_liquidHeader
#define MAP_LIQUID_TYPE_SLIME 0x08 #define MAP_LIQUID_TYPE_SLIME 0x08
#define MAP_LIQUID_TYPE_DARK_WATER 0x10 #define MAP_LIQUID_TYPE_DARK_WATER 0x10
uint32 GetLiquidFlags(uint32 liquidId);
namespace MMAP namespace MMAP
{ {
@@ -414,23 +412,27 @@ namespace MMAP
else else
{ {
liquidType = getLiquidType(i, liquid_flags); liquidType = getLiquidType(i, liquid_flags);
if (liquidType & MAP_LIQUID_TYPE_DARK_WATER) switch (liquidType)
{ {
// players should not be here, so logically neither should creatures default:
useTerrain = false; useLiquid = false;
useLiquid = false; break;
} case MAP_LIQUID_TYPE_WATER:
else if ((liquidType & (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN)) != 0) case MAP_LIQUID_TYPE_OCEAN:
{ // merge different types of water
liquidType = NAV_AREA_WATER; liquidType = NAV_WATER;
} break;
else if ((liquidType & (MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)) != 0) case MAP_LIQUID_TYPE_MAGMA:
{ liquidType = NAV_MAGMA;
liquidType = NAV_AREA_MAGMA_SLIME; break;
} case MAP_LIQUID_TYPE_SLIME:
else liquidType = NAV_SLIME;
{ break;
useLiquid = false; case MAP_LIQUID_TYPE_DARK_WATER:
// players should not be here, so logically neither should creatures
useTerrain = false;
useLiquid = false;
break;
} }
} }
@@ -733,17 +735,20 @@ namespace MMAP
vertsY = tilesY + 1; vertsY = tilesY + 1;
uint8* flags = liquid->GetFlagsStorage(); uint8* flags = liquid->GetFlagsStorage();
float* data = liquid->GetHeightStorage(); float* data = liquid->GetHeightStorage();
uint8 type = NAV_AREA_EMPTY; uint8 type = NAV_EMPTY;
// convert liquid type to NavTerrain switch (liquid->GetType() & 3)
uint32 liquidFlags = GetLiquidFlags(liquid->GetType());
if ((liquidFlags & (MAP_LIQUID_TYPE_WATER | MAP_LIQUID_TYPE_OCEAN)) != 0)
{ {
type = NAV_AREA_WATER; case 0:
} case 1:
else if ((liquidFlags & (MAP_LIQUID_TYPE_MAGMA | MAP_LIQUID_TYPE_SLIME)) != 0) type = NAV_WATER;
{ break;
type = NAV_AREA_MAGMA_SLIME; case 2:
type = NAV_MAGMA;
break;
case 3:
type = NAV_SLIME;
break;
} }
// indexing is weird... // indexing is weird...