fix(Core/FleeingMovementGenerator): Prevent fear movement from causing characters to fall through the ground (#22451)

This commit is contained in:
Anton Popovichenko
2025-07-11 16:44:44 +02:00
committed by GitHub
parent 1c3cbd3d9e
commit 628f6255c4
3 changed files with 24 additions and 2 deletions

View File

@@ -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_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_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_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. // Returns true of status is success.

View File

@@ -137,9 +137,12 @@ void FleeingMovementGenerator<T>::SetTargetLocation(T* owner)
_path->Clear(); _path->Clear();
} }
if (owner->IsPlayer())
_path->SetSlopeCheck(true);
_path->SetPathLengthLimit(30.0f); _path->SetPathLengthLimit(30.0f);
bool result = _path->CalculatePath(destination.GetPositionX(), destination.GetPositionY(), destination.GetPositionZ()); 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); _timer.Reset(100);
return; return;

View File

@@ -564,6 +564,22 @@ void PathGenerator::BuildPointPath(const float* startPoint, const float* endPoin
} }
else if (pointCount < 2 || dtStatusFailed(dtResult)) 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 // only happens if pass bad data to findStraightPath or navmesh is broken
// single point paths can be generated here // single point paths can be generated here
/// @todo check the exact cases /// @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)) 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. // Handle end of path and off-mesh links when close enough.