From 6819c67068be533c2a051cd01b7b77904d5a2dcd Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sun, 27 Sep 2026 08:38:59 -0500 Subject: [PATCH] fix(pets): place the taming minigame where live did Issue 547. The minigame put the player a guessed distance from wherever the pet had wandered to, in the direction of the player, which often left bricks off screen or the whole minigame over a drop. In the 2014 live captures the positions are the same for every try at the same pet: the pet's destination is where it spawned, and the player is teleported exactly 12 units along the direction the pet spawned facing, turned to face the pet. This matches the spawner in the level file for the Pet Ranch cat (spawned facing -43.4 degrees, player placed at spawn + (-8.24, 8.73) facing 136.6 degrees) and holds for the doberman, buffalo, triceratops, rabbit and the script spawned panda. The pet is now put back on that spot and the player placed that way; the heights come from the navmesh when there is one. Co-Authored-By: Claude Opus 5.5 --- dGame/dComponents/PetComponent.cpp | 46 +++++++++++------------------- dGame/dComponents/PetComponent.h | 5 ++++ 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/dGame/dComponents/PetComponent.cpp b/dGame/dComponents/PetComponent.cpp index 63a045b1f..0a8671c96 100644 --- a/dGame/dComponents/PetComponent.cpp +++ b/dGame/dComponents/PetComponent.cpp @@ -175,43 +175,30 @@ void PetComponent::OnUse(Entity* originator) { return; } - const auto petPosition = m_Parent->GetPosition(); - - const auto originatorPosition = originator->GetPosition(); - - m_Parent->SetRotation(QuatUtils::LookAt(petPosition, originatorPosition)); - - float interactionDistance = m_Parent->GetVar(u"interaction_distance"); - if (interactionDistance <= 0) { - interactionDistance = 15; + // Where live put the minigame (2014 captures, the same for every try at a pet): the pet goes back to where it + // spawned, facing the way it spawned, and the player is teleported 12 units in front of it, facing the pet. + if (m_StartPosition == NiPoint3Constant::ZERO) { + m_StartPosition = m_Parent->GetPosition(); + m_StartRotation = m_Parent->GetRotation(); } - auto position = originatorPosition; + constexpr float TAMING_PLAYER_DISTANCE = 12.0f; - NiPoint3 forward = QuatUtils::Forward(QuatUtils::LookAt(m_Parent->GetPosition(), originator->GetPosition())); + auto petPosition = m_StartPosition; + auto forward = QuatUtils::Forward(m_StartRotation); forward.y = 0; + forward = forward.SquaredLength() > 0.0f ? forward.Unitize() : NiPoint3Constant::UNIT_Z; + auto position = petPosition + forward * TAMING_PLAYER_DISTANCE; if (dpWorld::IsLoaded()) { - NiPoint3 attempt = petPosition + forward * interactionDistance; - - NiPoint3 nearestPoint = dpWorld::GetNavMesh()->NearestPoint(attempt); - - while (std::abs(nearestPoint.y - petPosition.y) > 4 && interactionDistance > 10) { - const NiPoint3 forward = QuatUtils::Forward(m_Parent->GetRotation()); - - attempt = originatorPosition + forward * interactionDistance; - - nearestPoint = dpWorld::GetNavMesh()->NearestPoint(attempt); - - interactionDistance -= 0.5f; - } - - position = nearestPoint; - } else { - position = petPosition + forward * interactionDistance; + petPosition.y = dpWorld::GetNavMesh()->GetHeightAtPoint(petPosition); + position.y = dpWorld::GetNavMesh()->GetHeightAtPoint(position); } - auto rotation = QuatUtils::LookAt(position, petPosition); + const auto rotation = QuatUtils::AxisAngle(NiPoint3Constant::UNIT_Y, glm::pi()) * m_StartRotation; + + m_Parent->SetPosition(petPosition); + m_Parent->SetRotation(m_StartRotation); { GameMessages::NotifyPetTamingMinigame msg; @@ -265,6 +252,7 @@ void PetComponent::OnUse(Entity* originator) { void PetComponent::Update(float deltaTime) { if (m_StartPosition == NiPoint3Constant::ZERO) { m_StartPosition = m_Parent->GetPosition(); + m_StartRotation = m_Parent->GetRotation(); } if (m_Owner == LWOOBJID_EMPTY) { diff --git a/dGame/dComponents/PetComponent.h b/dGame/dComponents/PetComponent.h index d18e3a9f0..8fe34c4f1 100644 --- a/dGame/dComponents/PetComponent.h +++ b/dGame/dComponents/PetComponent.h @@ -378,6 +378,11 @@ private: */ NiPoint3 m_StartPosition; + /** + * The rotation that this pet was spawned with + */ + NiQuaternion m_StartRotation{ QuatUtils::IDENTITY }; + /** * The movement AI component that is related to this pet, required to move it around */