fix(MMAP/core/PathGenerator): Try to fix more water creatures (#13705)

Co-authored-by: jackpoz <giacomopoz@gmail.com>
This commit is contained in:
Mickaël Mauger
2023-01-02 22:26:12 +01:00
committed by GitHub
parent aae46cc8af
commit 24fa3ba828
4 changed files with 20 additions and 14 deletions
+1 -1
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 15 #define MMAP_VERSION 16
struct MmapTileHeader struct MmapTileHeader
{ {
+1 -1
View File
@@ -4166,7 +4166,7 @@ bool Unit::isInAccessiblePlaceFor(Creature const* c) const
} }
LiquidStatus liquidStatus = GetLiquidData().Status; LiquidStatus liquidStatus = GetLiquidData().Status;
bool isInWater = (liquidStatus & MAP_LIQUID_STATUS_SWIMMING) != 0; bool isInWater = (liquidStatus & MAP_LIQUID_STATUS_IN_CONTACT) != 0;
// In water or jumping in water // In water or jumping in water
if (isInWater || (liquidStatus == LIQUID_MAP_ABOVE_WATER && (IsFalling() || (ToPlayer() && ToPlayer()->IsFalling())))) if (isInWater || (liquidStatus == LIQUID_MAP_ABOVE_WATER && (IsFalling() || (ToPlayer() && ToPlayer()->IsFalling()))))
@@ -209,25 +209,29 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
// we just need to remove/normalize paths between 2 adjacent points // we just need to remove/normalize paths between 2 adjacent points
if (startFarFromPoly || endFarFromPoly) if (startFarFromPoly || endFarFromPoly)
{ {
bool buildShotrcut = false; bool buildShortcut = false;
bool isUnderWaterStart = _source->GetMap()->IsUnderWater(_source->GetPhaseMask(), startPos.x, startPos.y, startPos.z, _source->GetCollisionHeight()); auto liquidDataStart = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), startPos.x, startPos.y, startPos.z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS);
bool isUnderWaterEnd = _source->GetMap()->IsUnderWater(_source->GetPhaseMask(), endPos.x, endPos.y, endPos.z, _source->GetCollisionHeight()); auto liquidDataEnd = _source->GetMap()->GetLiquidData(_source->GetPhaseMask(), endPos.x, endPos.y, endPos.z, _source->GetCollisionHeight(), MAP_ALL_LIQUIDS);
bool isFarUnderWater = startFarFromPoly ? isUnderWaterStart : isUnderWaterEnd;
bool startUnderWaterEndInWater = liquidDataStart.Status == LIQUID_MAP_UNDER_WATER &&
(liquidDataEnd.Status & MAP_LIQUID_STATUS_IN_CONTACT) != 0;
bool startInWaterEndUnderWater = (liquidDataStart.Status & MAP_LIQUID_STATUS_IN_CONTACT) != 0 &&
liquidDataEnd.Status == LIQUID_MAP_UNDER_WATER;
bool waterPath = startUnderWaterEndInWater || startInWaterEndUnderWater;
Unit const* _sourceUnit = _source->ToUnit(); Unit const* _sourceUnit = _source->ToUnit();
if (_sourceUnit) if (_sourceUnit)
{ {
bool isUnderWater = (_sourceUnit->CanSwim() && isUnderWaterStart && isUnderWaterEnd) || (isFarUnderWater && _useRaycast); bool isWater = (_sourceUnit->CanSwim() && waterPath);
if (isUnderWater || _sourceUnit->CanFly() || (_sourceUnit->IsFalling() && endPos.z < startPos.z)) if (isWater || _sourceUnit->CanFly() || (_sourceUnit->IsFalling() && endPos.z < startPos.z))
{ {
buildShotrcut = true; buildShortcut = true;
} }
} }
if (buildShotrcut) if (buildShortcut)
{ {
BuildShortcut(); BuildShortcut();
_type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
@@ -236,8 +240,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
return; return;
} }
else
if (!isFarUnderWater)
{ {
float closestPoint[VERTEX_SIZE]; float closestPoint[VERTEX_SIZE];
// we may want to use closestPointOnPolyBoundary instead // we may want to use closestPointOnPolyBoundary instead
@@ -679,12 +682,11 @@ void PathGenerator::UpdateFilter()
NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) const NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z) const
{ {
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);
if (liquidData.Status == LIQUID_MAP_NO_WATER) if (liquidData.Status == LIQUID_MAP_NO_WATER)
return NAV_GROUND; return NAV_GROUND;
switch (data.Flags) switch (liquidData.Flags)
{ {
case MAP_LIQUID_TYPE_WATER: case MAP_LIQUID_TYPE_WATER:
case MAP_LIQUID_TYPE_OCEAN: case MAP_LIQUID_TYPE_OCEAN:
@@ -504,6 +504,10 @@ namespace MMAP
minTLevel = h; minTLevel = h;
} }
// terrain under the liquid?
if (minLLevel > maxTLevel)
useTerrain = false;
//liquid under the terrain? //liquid under the terrain?
if (minTLevel > maxLLevel) if (minTLevel > maxLLevel)
useLiquid = false; useLiquid = false;