diff options
| author | Treeston <treeston.mmoc@gmail.com> | 2018-04-06 18:09:55 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-06 18:09:55 +0200 |
| commit | 2a84562dc85516f432bb1e5de9add23c28b26ce4 (patch) | |
| tree | 2b7414c164370c5144586beb76946db41061fad7 /src/server/game/Entities/Unit | |
| parent | 9f03743d2d803cba553b2f95a87b106bf5e3f672 (diff) | |
Core/Movement: Replace old TargetedMovementGenerator into ChaseMovementGenerator and FollowMovementGenerator, full rewrite for both.
- Chase to angle is now functional. Pets use this to chase behind the target. Closes #19925.
- Chase to arbitrary range interval works. Not used anywhere, but you can technically make hunter-like mobs.
- Pets now follow the hunter cleanly and without stutter stepping. Also fix some other things. Closes #8924.
Diffstat (limited to 'src/server/game/Entities/Unit')
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 59 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 13 |
2 files changed, 40 insertions, 32 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 0b31a125cd8..b5d04826d85 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -17,6 +17,7 @@ */ #include "Unit.h" +#include "AbstractFollower.h" #include "Battlefield.h" #include "BattlefieldMgr.h" #include "Battleground.h" @@ -538,14 +539,14 @@ bool Unit::IsWithinCombatRange(Unit const* obj, float dist2compare) const return distsq < maxdist * maxdist; } -bool Unit::IsWithinMeleeRange(Unit const* obj) const +bool Unit::IsWithinMeleeRangeAt(Position const& pos, Unit const* obj) const { if (!obj || !IsInMap(obj) || !InSamePhase(obj)) return false; - float dx = GetPositionX() - obj->GetPositionX(); - float dy = GetPositionY() - obj->GetPositionY(); - float dz = GetPositionZ() - obj->GetPositionZ(); + float dx = pos.GetPositionX() - obj->GetPositionX(); + float dy = pos.GetPositionY() - obj->GetPositionY(); + float dz = pos.GetPositionZ() - obj->GetPositionZ(); float distsq = dx*dx + dy*dy + dz*dz; float maxdist = GetMeleeRange(obj); @@ -8509,25 +8510,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype) { // Set creature speed rate if (GetTypeId() == TYPEID_UNIT) - { - Unit* pOwner = GetCharmerOrOwner(); - if ((IsPet() || IsGuardian()) && !IsInCombat() && pOwner) // Must check for owner or crash on "Tame Beast" - { - // For every yard over 5, increase speed by 0.01 - // to help prevent pet from lagging behind and despawning - float dist = GetDistance(pOwner); - float base_rate = 1.00f; // base speed is 100% of owner speed - - if (dist < 5) - dist = 5; - - float mult = base_rate + ((dist - 5) * 0.01f); - - speed *= pOwner->GetSpeedRate(mtype) * mult; // pets derive speed from owner when not in combat - } - else - speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached - } + speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached // Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need /// @todo possible affect only on MOVE_RUN @@ -8551,11 +8534,27 @@ void Unit::UpdateSpeed(UnitMoveType mtype) break; } - // for creature case, we check explicit if mob searched for assistance - if (GetTypeId() == TYPEID_UNIT) + if (Creature* creature = ToCreature()) { - if (ToCreature()->HasSearchedAssistance()) + // for creature case, we check explicit if mob searched for assistance + if (creature->HasSearchedAssistance()) speed *= 0.66f; // best guessed value, so this will be 33% reduction. Based off initial speed, mob can then "run", "walk fast" or "walk". + + if (creature->HasUnitTypeMask(UNIT_MASK_MINION) && !creature->IsInCombat()) + { + MovementGenerator* top = creature->GetMotionMaster()->top(); + if (top && top->GetMovementGeneratorType() == FOLLOW_MOTION_TYPE) + { + Unit* followed = ASSERT_NOTNULL(dynamic_cast<AbstractFollower*>(top))->GetTarget(); + if (followed && followed->GetGUID() == GetOwnerGUID() && !followed->IsInCombat()) + { + float ownerSpeed = followed->GetSpeedRate(mtype); + if (speed < ownerSpeed || creature->IsWithinDist3d(followed, 10.0f)) + speed = ownerSpeed; + speed *= std::min(std::max(1.0f, 0.75f + (GetDistance(followed) - PET_FOLLOW_DIST) * 0.05f), 1.3f); + } + } + } } // Apply strongest slow aura mod to speed @@ -8656,6 +8655,12 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate) } } +void Unit::RemoveAllFollowers() +{ + while (!m_followingMe.empty()) + (*m_followingMe.begin())->SetTarget(nullptr); +} + bool Unit::IsGhouled() const { return HasAura(SPELL_DK_RAISE_ALLY); @@ -9437,6 +9442,8 @@ void Unit::RemoveFromWorld() RemoveAreaAurasDueToLeaveWorld(); + RemoveAllFollowers(); + if (IsCharmed()) RemoveCharmedBy(nullptr); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index f01c476292a..1a910ba48b3 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -20,8 +20,6 @@ #define __UNIT_H #include "Object.h" -#include "FollowerReference.h" -#include "FollowerRefManager.h" #include "CombatManager.h" #include "OptionalFwd.h" #include "SpellAuraDefines.h" @@ -61,6 +59,7 @@ enum InventorySlot NULL_SLOT = 255 }; +struct AbstractFollower; struct FactionTemplateEntry; struct LiquidData; struct LiquidTypeEntry; @@ -789,7 +788,8 @@ class TC_GAME_API Unit : public WorldObject virtual void SetCanDualWield(bool value) { m_canDualWield = value; } float GetCombatReach() const override { return m_floatValues[UNIT_FIELD_COMBATREACH]; } bool IsWithinCombatRange(Unit const* obj, float dist2compare) const; - bool IsWithinMeleeRange(Unit const* obj) const; + bool IsWithinMeleeRange(Unit const* obj) const { return IsWithinMeleeRangeAt(GetPosition(), obj); } + bool IsWithinMeleeRangeAt(Position const& pos, Unit const* obj) const; float GetMeleeRange(Unit const* target) const; virtual SpellSchoolMask GetMeleeDamageSchoolMask(WeaponAttackType attackType = BASE_ATTACK, uint8 damageIndex = 0) const = 0; uint32 m_extraAttacks; @@ -1526,8 +1526,9 @@ class TC_GAME_API Unit : public WorldObject float CalculateSpellpowerCoefficientLevelPenalty(SpellInfo const* spellInfo) const; - void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); } - void removeFollower(FollowerReference* /*pRef*/) { /* nothing to do yet */ } + void FollowerAdded(AbstractFollower* f) { m_followingMe.insert(f); } + void FollowerRemoved(AbstractFollower* f) { m_followingMe.erase(f); } + void RemoveAllFollowers(); MotionMaster* GetMotionMaster() { return i_motionMaster; } MotionMaster const* GetMotionMaster() const { return i_motionMaster; } @@ -1781,7 +1782,7 @@ class TC_GAME_API Unit : public WorldObject friend class ThreatManager; ThreatManager m_threatManager; - FollowerRefManager m_FollowingRefManager; + std::unordered_set<AbstractFollower*> m_followingMe; Unit* m_comboTarget; int8 m_comboPoints; |
