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_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.

View File

@@ -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;

View File

@@ -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.