aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/Unit
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2018-04-06 18:09:55 +0200
committerGitHub <noreply@github.com>2018-04-06 18:09:55 +0200
commit2a84562dc85516f432bb1e5de9add23c28b26ce4 (patch)
tree2b7414c164370c5144586beb76946db41061fad7 /src/server/game/Entities/Unit
parent9f03743d2d803cba553b2f95a87b106bf5e3f672 (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.cpp59
-rw-r--r--src/server/game/Entities/Unit/Unit.h13
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;