aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
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
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')
-rw-r--r--src/server/game/Entities/Object/G3DPosition.hpp29
-rw-r--r--src/server/game/Entities/Pet/PetDefines.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp59
-rw-r--r--src/server/game/Entities/Unit/Unit.h13
4 files changed, 70 insertions, 33 deletions
diff --git a/src/server/game/Entities/Object/G3DPosition.hpp b/src/server/game/Entities/Object/G3DPosition.hpp
new file mode 100644
index 00000000000..bfca424cb19
--- /dev/null
+++ b/src/server/game/Entities/Object/G3DPosition.hpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TRINITY_G3DPOSITION_HPP
+#define TRINITY_G3DPOSITION_HPP
+
+#include "Position.h"
+#include <G3D/Vector3.h>
+#include "Errors.h"
+
+inline G3D::Vector3 PositionToVector3(Position p) { return { p.m_positionX, p.m_positionY, p.m_positionZ }; }
+inline G3D::Vector3 PositionToVector3(Position const* p) { return { ASSERT_NOTNULL(p)->m_positionX, p->m_positionY, p->m_positionZ }; }
+inline Position Vector3ToPosition(G3D::Vector3 v) { return { v.x, v.y, v.z }; }
+
+#endif
diff --git a/src/server/game/Entities/Pet/PetDefines.h b/src/server/game/Entities/Pet/PetDefines.h
index dd359dc6ee4..39475f49d40 100644
--- a/src/server/game/Entities/Pet/PetDefines.h
+++ b/src/server/game/Entities/Pet/PetDefines.h
@@ -75,6 +75,6 @@ enum PetTalk
};
#define PET_FOLLOW_DIST 1.0f
-#define PET_FOLLOW_ANGLE float(M_PI/2)
+#define PET_FOLLOW_ANGLE float(M_PI)
#endif
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;