fix(Core/Movement): Improve Pet LoS cancellations by using path calculation instead of raycasting (#24330)

This commit is contained in:
Gultask
2026-01-07 23:47:41 -03:00
committed by GitHub
parent 01c4b10b6d
commit a1f5d39370
2 changed files with 14 additions and 16 deletions

View File

@@ -235,17 +235,6 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
if (pet->GetVictim() == TargetUnit && pet->GetCharmInfo()->IsCommandAttack()) if (pet->GetVictim() == TargetUnit && pet->GetCharmInfo()->IsCommandAttack())
return; return;
// Check line of sight either from pet or owner depending if pet is charmed
Unit* seer = pet;
if (Unit* owner = pet->GetOwner())
if (owner->IsPlayer() && owner->ToPlayer()->GetCharm() != pet && owner->ToPlayer()->GetVehicleBase() != pet)
if (sDisableMgr->IsPathfindingEnabled(pet->GetMap()))
seer = owner;
// Fail on LoS
if (seer && !seer->IsWithinLOSInMap(TargetUnit, VMAP::ModelIgnoreFlags::M2))
return;
pet->ClearUnitState(UNIT_STATE_FOLLOW); pet->ClearUnitState(UNIT_STATE_FOLLOW);
// This is true if pet has no target or has target but targets differs. // This is true if pet has no target or has target but targets differs.
if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack())) if (pet->GetVictim() != TargetUnit || (pet->GetVictim() == TargetUnit && !pet->GetCharmInfo()->IsCommandAttack()))
@@ -429,8 +418,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
// This is true if pet has no target or has target but targets differs. // This is true if pet has no target or has target but targets differs.
if (pet->GetVictim() != unit_target) if (pet->GetVictim() != unit_target)
{ {
if (pet->ToCreature()->IsAIEnabled && pet->IsWithinLOSInMap(unit_target, VMAP::ModelIgnoreFlags::M2)) pet->ToCreature()->AI()->AttackStart(unit_target);
pet->ToCreature()->AI()->AttackStart(unit_target);
} }
} }
@@ -511,8 +499,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
charmInfo->SetIsCommandFollow(false); charmInfo->SetIsCommandFollow(false);
charmInfo->SetIsReturning(false); charmInfo->SetIsReturning(false);
if (pet->IsWithinLOSInMap(TargetUnit, VMAP::ModelIgnoreFlags::M2)) pet->ToCreature()->AI()->AttackStart(TargetUnit);
pet->ToCreature()->AI()->AttackStart(TargetUnit);
if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10)) if (pet->IsPet() && pet->ToPet()->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10))
pet->SendPetActionSound(PET_ACTION_SPECIAL_SPELL); pet->SendPetActionSound(PET_ACTION_SPECIAL_SPELL);

View File

@@ -105,11 +105,22 @@ bool ChaseMovementGenerator<T>::DispatchSplineToPosition(T* owner, float x, floa
owner->UpdateAllowedPositionZ(x, y, z); owner->UpdateAllowedPositionZ(x, y, z);
bool success = i_path->CalculatePath(x, y, z, forceDest); bool success = i_path->CalculatePath(x, y, z, forceDest);
if (!success || i_path->GetPathType() & PATHFIND_NOPATH) uint32 pathType = i_path->GetPathType();
bool pathFailed = !success || (pathType & PATHFIND_NOPATH);
// For pets, treat incomplete paths as failures to avoid clipping through geometry
if (cOwner && (cOwner->IsPet() || cOwner->IsControlledByPlayer()))
if (pathType & PATHFIND_INCOMPLETE)
pathFailed = true;
if (pathFailed)
{ {
if (cOwner) if (cOwner)
{ {
cOwner->SetCannotReachTarget(i_target.getTarget()->GetGUID()); cOwner->SetCannotReachTarget(i_target.getTarget()->GetGUID());
if (cOwner->IsPet() || cOwner->IsControlledByPlayer())
cOwner->AttackStop();
} }
owner->StopMoving(); owner->StopMoving();