mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-09 00:08:01 +00:00
fix(Core/Movement): let melee pets attack targets whose chase point is unpathable (#26726)
This commit is contained in:
@@ -104,15 +104,40 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
|
|||||||
if (owner->IsHovering())
|
if (owner->IsHovering())
|
||||||
owner->UpdateAllowedPositionZ(x, y, z);
|
owner->UpdateAllowedPositionZ(x, y, z);
|
||||||
|
|
||||||
bool success = i_path->CalculatePath(x, y, z, forceDest);
|
auto isPathUsable = [&]()
|
||||||
uint32 pathType = i_path->GetPathType();
|
{
|
||||||
bool pathFailed = !success || (pathType & PATHFIND_NOPATH);
|
uint32 pathType = i_path->GetPathType();
|
||||||
|
if (pathType & PATHFIND_NOPATH)
|
||||||
|
return false;
|
||||||
|
|
||||||
// For pets, treat incomplete paths as failures to avoid clipping through geometry
|
// For pets, treat incomplete paths as failures to avoid clipping through geometry
|
||||||
// Players and Player-controlled units have more erratic movement, skip failure
|
// Players and Player-controlled units have more erratic movement, skip failure
|
||||||
if (cOwner && (cOwner->IsPet() || cOwner->IsControlledByPlayer()) && !GetTarget()->IsCharmedOwnedByPlayerOrPlayer())
|
if (cOwner && (cOwner->IsPet() || cOwner->IsControlledByPlayer())
|
||||||
if (pathType & PATHFIND_INCOMPLETE)
|
&& !GetTarget()->IsCharmedOwnedByPlayerOrPlayer())
|
||||||
pathFailed = true;
|
if (pathType & PATHFIND_INCOMPLETE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool pathFailed = !i_path->CalculatePath(x, y, z, forceDest) || !isPathUsable();
|
||||||
|
|
||||||
|
// Targets with an oversized combat reach can stand entirely over unwalkable space
|
||||||
|
// (e.g. Kologarn) so pathing to their center or to an angled near point (pets chase
|
||||||
|
// to behind the target, which may hang over the void) fails even though the melee
|
||||||
|
// ring covers the navmesh. Retry against the nearest point on the ring, ignoring the
|
||||||
|
// chase angle, via GetNearPoint2D: GetNearPoint's LoS repositioning must be avoided
|
||||||
|
// here, it can rotate the point to the far side of the target.
|
||||||
|
if (pathFailed && (!_range || _range->MaxRange <= CONTACT_DISTANCE)
|
||||||
|
&& !GetTarget()->IsCharmedOwnedByPlayerOrPlayer() && GetTarget()->GetCombatReach() > NOMINAL_MELEE_RANGE)
|
||||||
|
{
|
||||||
|
GetTarget()->GetNearPoint2D(owner, x, y, 0.0f, GetTarget()->GetAngle(owner));
|
||||||
|
z = GetTarget()->GetPositionZ();
|
||||||
|
owner->UpdateAllowedPositionZ(x, y, z);
|
||||||
|
pathFailed = !i_path->CalculatePath(x, y, z, forceDest) || !isPathUsable();
|
||||||
|
// the destination already lies on the melee ring, nothing to cut
|
||||||
|
cutPath = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (pathFailed)
|
if (pathFailed)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user