diff --git a/deps/recastnavigation/Detour/Include/DetourStatus.h b/deps/recastnavigation/Detour/Include/DetourStatus.h index 8e1bb44b9..96dcb5b00 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 2547e4ddf..a4d9867ab 100644 --- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp @@ -137,9 +137,12 @@ void FleeingMovementGenerator::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 015d3973c..33bd7ec22 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.