From 3d416de89337758a8dbfe81e9ec919c21104e936 Mon Sep 17 00:00:00 2001 From: Stoabrogga <38475780+Stoabrogga@users.noreply.github.com> Date: Tue, 8 Jan 2019 07:36:25 +0100 Subject: [PATCH] Core/Movement: Prevent pet animation stuttering during movement (#1142) * fix vanity pet distance and angle * fix vanity pet distance to player * put size calculation for normal pets into the if-statement for vanity pets * change pet speed algorithm * change distance calculation * another change to the distance calculation; differentiate between player running or flying --- src/server/game/Entities/Unit/Unit.cpp | 37 ++++++++++++++++++- src/server/game/Entities/Unit/Unit.h | 1 + .../TargetedMovementGenerator.cpp | 23 +++++++++++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 1c1e1dd81..513f758a2 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -178,6 +178,7 @@ i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_ThreatManager(this), m_rootTimes = 0; m_state = 0; + m_petCatchUp = false; m_deathState = ALIVE; for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i) @@ -13093,8 +13094,40 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced) Unit* pOwner = GetCharmerOrOwner(); if (pOwner && !IsInCombat() && !IsVehicle() && !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED) && (IsPet() || IsGuardian() || GetGUID() == pOwner->GetCritterGUID() || GetCharmerGUID() == pOwner->GetGUID())) { - if (speed < pOwner->GetSpeedRate(mtype)+0.1f) - speed = pOwner->GetSpeedRate(mtype)+0.1f; // pets derive speed from owner when not in combat + if (pOwner->GetTypeId() != TYPEID_PLAYER) + { + if (speed < pOwner->GetSpeedRate(mtype)+0.1f) + speed = pOwner->GetSpeedRate(mtype)+0.1f; // pets derive speed from owner when not in combat + } + else + { + // special treatment for player pets in order to avoid stuttering + float ownerSpeed = pOwner->GetSpeedRate(mtype); + float distOwner = GetDistance(pOwner); + float minDist = 2.5f; + + if (ToCreature()->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET) + { + // different minimum distance for vanity pets + minDist = 5.0f; + + if (mtype == MOVE_FLIGHT) + mtype = MOVE_RUN; // vanity pets use run speed for flight + } + + float maxDist = ownerSpeed >= 1.0f ? minDist * ownerSpeed * 1.5f : minDist * 1.5f; + + if (distOwner < minDist && m_petCatchUp) + m_petCatchUp = false; + + if (distOwner > maxDist && !m_petCatchUp) + m_petCatchUp = true; + + if (m_petCatchUp) + speed = ownerSpeed * 1.05f; + else + speed = ownerSpeed * 0.95f; + } } else speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index b9e7d6f47..fe217d258 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2561,6 +2561,7 @@ class Unit : public WorldObject bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world uint32 _oldFactionId; ///< faction before charm + bool m_petCatchUp; }; namespace Trinity diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 17a238ce1..b3d97f217 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -98,8 +98,17 @@ void TargetedMovementGeneratorMedium::_setTargetLocation(T* owner, bool ini if ((!initial || (owner->movespline->Finalized() && this->GetMovementGeneratorType() == CHASE_MOTION_TYPE)) && i_target->IsWithinDistInMap(owner, dist) && i_target->IsWithinLOS(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ())) return; - // Xinef: Fix follow angle for hostile units float angle = i_angle; + + if (i_target->GetTypeId() == TYPEID_PLAYER && owner->ToCreature()->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET) + { + // fix distance and angle for vanity pets + dist = 0.3f; + angle = PET_FOLLOW_ANGLE + M_PI * 0.2f; + size = i_target->GetCombatReach() - i_target->GetObjectSize(); + } + + // Xinef: Fix follow angle for hostile units if (angle == 0.0f && owner->GetVictim() && owner->GetVictim()->GetGUID() == i_target->GetGUID()) angle = MapManager::NormalizeOrientation(i_target->GetAngle(owner)-i_target->GetOrientation()); // to at i_offset distance from target and i_angle from target facing @@ -298,6 +307,18 @@ bool TargetedMovementGeneratorMedium::DoUpdate(T* owner, uint32 time_diff) if (i_recalculateTravel) _setTargetLocation(owner, false); } + + Unit* pOwner = owner->GetCharmerOrOwner(); + + if (pOwner && pOwner->GetTypeId() == TYPEID_PLAYER) + { + // Update pet speed for players in order to avoid stuttering + if (pOwner->IsFlying()) + owner->UpdateSpeed(MOVE_FLIGHT, true); + else + owner->UpdateSpeed(MOVE_RUN, true); + } + return true; }