From 9c6514847fa9d772be340148a8ab854155f9f430 Mon Sep 17 00:00:00 2001 From: Giacomo Pozzoni Date: Thu, 20 Feb 2020 21:34:33 +0100 Subject: [PATCH] Core/PathGenerator: Fix path generator returning shortcuts when start and end are on the same polygon (#24083) * Core/PathGenerator: Fix path generator returning shortcuts when start and end are on the same polygon Second try of handling paths on same poly in a better way than just building a shortcut * Fix movement generators using paths with start/end positions far from mmap polygons * Include flag PATHFIND_FARFROMPOLY even with a normal path if start or end were far away from mmap poly --- .../ConfusedMovementGenerator.cpp | 4 ++- .../FleeingMovementGenerator.cpp | 4 ++- .../RandomMovementGenerator.cpp | 4 ++- src/server/game/Movement/PathGenerator.cpp | 33 +++++++++++++------ src/server/game/Movement/PathGenerator.h | 1 + 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index f789aaf5d2..3e4049942e 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -81,7 +81,9 @@ bool ConfusedMovementGenerator::DoUpdate(T* owner, uint32 diff) _path->SetPathLengthLimit(30.0f); bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()); - if (!result || (_path->GetPathType() & PATHFIND_NOPATH) || (_path->GetPathType() & PATHFIND_SHORTCUT)) + if (!result || (_path->GetPathType() & PATHFIND_NOPATH) + || (_path->GetPathType() & PATHFIND_SHORTCUT) + || (_path->GetPathType() & PATHFIND_FARFROMPOLY)) { _timer.Reset(100); return true; diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp index 050d044a61..7f4b198412 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -126,7 +126,9 @@ void FleeingMovementGenerator::SetTargetLocation(T* owner) _path->SetPathLengthLimit(30.0f); bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()); - if (!result || (_path->GetPathType() & PATHFIND_NOPATH) || (_path->GetPathType() & PATHFIND_SHORTCUT)) + if (!result || (_path->GetPathType() & PATHFIND_NOPATH) + || (_path->GetPathType() & PATHFIND_SHORTCUT) + || (_path->GetPathType() & PATHFIND_FARFROMPOLY)) { _timer.Reset(100); return; diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index 22567141b5..ed851495f8 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -123,7 +123,9 @@ void RandomMovementGenerator::SetRandomLocation(Creature* owner) _path->SetPathLengthLimit(30.0f); bool result = _path->CalculatePath(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ()); - if (!result || (_path->GetPathType() & PATHFIND_NOPATH) || (_path->GetPathType() & PATHFIND_SHORTCUT)) + if (!result || (_path->GetPathType() & PATHFIND_NOPATH) + || (_path->GetPathType() & PATHFIND_SHORTCUT) + || (_path->GetPathType() & PATHFIND_FARFROMPOLY)) { _timer.Reset(100); return; diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 6abc73d396..355879d849 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -227,7 +227,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con if (buildShotrcut) { BuildShortcut(); - _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH); + _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH | PATHFIND_FARFROMPOLY); return; } else @@ -240,7 +240,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con SetActualEndPosition(G3D::Vector3(endPoint[2], endPoint[0], endPoint[1])); } - _type = PATHFIND_INCOMPLETE; + _type = PathType(PATHFIND_INCOMPLETE | PATHFIND_FARFROMPOLY); } } @@ -252,13 +252,12 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con { TC_LOG_DEBUG("maps.mmaps", "++ BuildPolyPath :: (startPoly == endPoly)"); - BuildShortcut(); - _pathPolyRefs[0] = startPoly; _polyLength = 1; - _type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL; - TC_LOG_DEBUG("maps.mmaps", "++ BuildPolyPath :: path type %d", _type); + _type = farFromPoly ? PathType(PATHFIND_INCOMPLETE | PATHFIND_FARFROMPOLY) : PATHFIND_NORMAL; + + BuildPointPath(startPoint, endPoint); return; } @@ -485,6 +484,9 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con else _type = PATHFIND_INCOMPLETE; + if (farFromPoly) + _type = PathType(_type | PATHFIND_FARFROMPOLY); + // generate the point-path out of our up-to-date poly-path BuildPointPath(startPoint, endPoint); } @@ -791,11 +793,22 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo uint32 npolys = polyPathSize; float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE]; - if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos))) - return DT_FAILURE; - if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos))) - return DT_FAILURE; + if (polyPathSize > 1) + { + // Pick the closest poitns on poly border + if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos))) + return DT_FAILURE; + + if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[npolys - 1], endPos, targetPos))) + return DT_FAILURE; + } + else + { + // Case where the path is on the same poly + dtVcopy(iterPos, startPos); + dtVcopy(targetPos, endPos); + } dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos); nsmoothPath++; diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h index 34186a374c..87fdb35a8d 100644 --- a/src/server/game/Movement/PathGenerator.h +++ b/src/server/game/Movement/PathGenerator.h @@ -47,6 +47,7 @@ enum PathType PATHFIND_NOPATH = 0x08, // no valid path at all or error in generating one PATHFIND_NOT_USING_PATH = 0x10, // used when we are either flying/swiming or on map w/o mmaps PATHFIND_SHORT = 0x20, // path is longer or equal to its limited path length + PATHFIND_FARFROMPOLY = 0x40 // start of end positions are far from the mmap poligon }; class TC_GAME_API PathGenerator