summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Popovichenko <walkline.ua@gmail.com>2025-07-11 16:44:44 +0200
committerGitHub <noreply@github.com>2025-07-11 11:44:44 -0300
commit628f6255c49e1ef2123b0f5fb33c3de0a968432e (patch)
tree82eb01f64e332f4792c2bfdd3bf20f0b6d103a21
parent1c3cbd3d9e1d07369be77a049cb95f22c2caf03d (diff)
fix(Core/FleeingMovementGenerator): Prevent fear movement from causing characters to fall through the ground (#22451)
-rw-r--r--deps/recastnavigation/Detour/Include/DetourStatus.h1
-rw-r--r--src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp5
-rw-r--r--src/server/game/Movement/MovementGenerators/PathGenerator.cpp20
3 files changed, 24 insertions, 2 deletions
diff --git a/deps/recastnavigation/Detour/Include/DetourStatus.h b/deps/recastnavigation/Detour/Include/DetourStatus.h
index 8e1bb44b9d..96dcb5b004 100644
--- a/deps/recastnavigation/Detour/Include/DetourStatus.h
+++ b/deps/recastnavigation/Detour/Include/DetourStatus.h
@@ -36,6 +36,7 @@ static const unsigned int DT_BUFFER_TOO_SMALL = 1 << 4; // Result buffer for the
static const unsigned int DT_OUT_OF_NODES = 1 << 5; // Query ran out of nodes during search.
static const unsigned int DT_PARTIAL_RESULT = 1 << 6; // Query did not reach the end location, returning best guess.
static const unsigned int DT_ALREADY_OCCUPIED = 1 << 7; // A tile has already been assigned to the given x,y coordinate
+static const unsigned int DT_SLOPE_TOO_STEEP = 1 << 8; // Surface slope too steep to be walkable.
// Returns true of status is success.
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
index 2547e4ddf3..a4d9867abf 100644
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
@@ -137,9 +137,12 @@ void FleeingMovementGenerator<T>::SetTargetLocation(T* owner)
_path->Clear();
}
+ if (owner->IsPlayer())
+ _path->SetSlopeCheck(true);
+
_path->SetPathLengthLimit(30.0f);
bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ());
- if (!result || (_path->GetPathType() & PathType(PATHFIND_NOPATH | PATHFIND_SHORTCUT | PATHFIND_FARFROMPOLY)))
+ if (!result || (_path->GetPathType() & PathType(PATHFIND_NOPATH | PATHFIND_SHORTCUT | PATHFIND_FARFROMPOLY | PATHFIND_NOT_USING_PATH)))
{
_timer.Reset(100);
return;
diff --git a/src/server/game/Movement/MovementGenerators/PathGenerator.cpp b/src/server/game/Movement/MovementGenerators/PathGenerator.cpp
index 015d3973c7..33bd7ec22a 100644
--- a/src/server/game/Movement/MovementGenerators/PathGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/PathGenerator.cpp
@@ -564,6 +564,22 @@ void PathGenerator::BuildPointPath(const float* startPoint, const float* endPoin
}
else if (pointCount < 2 || dtStatusFailed(dtResult))
{
+ // If its too steep, just return incomplete path.
+ if (pointCount > 0 && dtResult & DT_SLOPE_TOO_STEEP)
+ {
+ _pathPoints.resize(pointCount);
+ for (uint32 i = 0; i < pointCount; ++i)
+ _pathPoints[i] = G3D::Vector3(pathPoints[i * VERTEX_SIZE + 2], pathPoints[i * VERTEX_SIZE], pathPoints[i * VERTEX_SIZE + 1]);
+
+ NormalizePath();
+
+ // first point is always our current location - we need the next one
+ SetActualEndPosition(_pathPoints[pointCount - 1]);
+
+ _type = PathType(_type | PATHFIND_INCOMPLETE);
+ return;
+ }
+
// only happens if pass bad data to findStraightPath or navmesh is broken
// single point paths can be generated here
/// @todo check the exact cases
@@ -884,7 +900,9 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
if (canCheckSlope && !IsSwimmableSegment(iterPos, steerPos) && !IsWalkableClimb(iterPos, steerPos))
{
- return DT_FAILURE;
+ nsmoothPath--;
+ *smoothPathSize = nsmoothPath;
+ return DT_FAILURE | DT_SLOPE_TOO_STEEP;
}
// Handle end of path and off-mesh links when close enough.