From 53c03515a724ce9fcfb51ae2a04aaee815a85206 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Wed, 30 Sep 2026 07:46:20 -0500 Subject: [PATCH] feat(ai): pets stop at the walls their group can't cross Pets are walked by the server's MovementAI like enemies, but only enemies' paths were cut at movement blockers, so pets walked through the Nimbus Station pet ranch's "PR - Pet Blocker" walls. Their collision group (3) is the one the pet blocker's group (18) touches in the client's collision filter, so a pet's path now stops at them (and at navmesh carvers), whether wandering or following its owner; a pet left behind still warps to its owner. Co-Authored-By: Claude Opus 5.5 --- dGame/dComponents/MovementAIComponent.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dGame/dComponents/MovementAIComponent.cpp b/dGame/dComponents/MovementAIComponent.cpp index e56d42757..ca392dacb 100644 --- a/dGame/dComponents/MovementAIComponent.cpp +++ b/dGame/dComponents/MovementAIComponent.cpp @@ -464,8 +464,11 @@ void MovementAIComponent::SetDestination(const NiPoint3 destination) { // The path is walked without collision, so an enemy's stops at walls it can't cross (navmesh carvers, enemy only // blockers); with nothing left to walk it stays where it is. A patrol along its level path is left as designed. + // Pets are walked here too, and their group (3) is the one the pet ranch's "PR - Pet Blocker" (group 18) touches: + // the client's filter lets pets collide with it and players through. const bool patrolling = m_Path && m_BaseCombatAI && m_BaseCombatAI->GetState() == AiState::idle; - if (m_BaseCombatAI && !patrolling) { + const bool isPet = m_Parent->HasComponent(eReplicaComponentType::PET); + if ((m_BaseCombatAI && !patrolling) || isPet) { computedPath = dpWorld::ClampPath(m_Parent->GetPosition(), std::move(computedPath), static_cast(m_Parent->GetCollisionGroup())); if (computedPath.empty()) computedPath.push_back(m_Parent->GetPosition()); }