aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2018-04-06 18:09:55 +0200
committerShauren <shauren.trinity@gmail.com>2021-09-24 23:37:43 +0200
commit14939204955d1a24fe465cdfcbf307daf3ce4f09 (patch)
tree18e2bc2c0fa726bdcea65384c99742805e6d0cdf /src/server/game/Entities
parent27fa6f3e341bb5a52b8c9b37b5a018d40b8e88a5 (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. (cherry picked from commit 2a84562dc85516f432bb1e5de9add23c28b26ce4)
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..413072fc811
--- /dev/null
+++ b/src/server/game/Entities/Object/G3DPosition.hpp
@@ -0,0 +1,29 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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 dfee8719e75..266c6f1e15a 100644
--- a/src/server/game/Entities/Pet/PetDefines.h
+++ b/src/server/game/Entities/Pet/PetDefines.h
@@ -77,6 +77,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 3fb1be9ca38..390d9855ce1 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -16,6 +16,7 @@
*/
#include "Unit.h"
+#include "AbstractFollower.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "Battleground.h"
@@ -559,14 +560,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) || !IsInPhase(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) + GetTotalAuraModifier(SPELL_AURA_MOD_AUTOATTACK_RANGE);
@@ -8020,25 +8021,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
@@ -8073,11 +8056,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
@@ -8170,6 +8169,12 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate)
}
}
+void Unit::RemoveAllFollowers()
+{
+ while (!m_followingMe.empty())
+ (*m_followingMe.begin())->SetTarget(nullptr);
+}
+
void Unit::setDeathState(DeathState s)
{
// Death state needs to be updated before RemoveAllAurasOnDeath() is called, to prevent entering combat
@@ -9076,6 +9081,8 @@ void Unit::RemoveFromWorld()
RemoveAreaAurasDueToLeaveWorld();
+ RemoveAllFollowers();
+
if (!GetCharmerGUID().IsEmpty())
{
TC_LOG_FATAL("entities.unit", "Unit %u has charmer guid when removed from world", GetEntry());
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 161ab077283..25e694d758c 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -19,8 +19,6 @@
#define __UNIT_H
#include "Object.h"
-#include "FollowerReference.h"
-#include "FollowerRefManager.h"
#include "CombatManager.h"
#include "OptionalFwd.h"
#include "SpellAuraDefines.h"
@@ -65,6 +63,7 @@ enum InventorySlot
NULL_SLOT = 255
};
+struct AbstractFollower;
struct FactionTemplateEntry;
struct LiquidData;
struct LiquidTypeEntry;
@@ -793,7 +792,8 @@ class TC_GAME_API Unit : public WorldObject
float GetBoundingRadius() const { return m_unitData->BoundingRadius; }
void SetBoundingRadius(float boundingRadius) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::BoundingRadius), boundingRadius); }
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) const = 0;
bool IsWithinBoundaryRadius(const Unit* obj) const;
@@ -1684,8 +1684,9 @@ class TC_GAME_API Unit : public WorldObject
void SetSpeed(UnitMoveType mtype, float newValue);
void SetSpeedRate(UnitMoveType mtype, float rate);
- 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; }
@@ -1953,7 +1954,7 @@ class TC_GAME_API Unit : public WorldObject
friend class ThreatManager;
ThreatManager m_threatManager;
- FollowerRefManager m_FollowingRefManager;
+ std::unordered_set<AbstractFollower*> m_followingMe;
bool m_cleanupDone; // lock made to not add stuff after cleanup before delete
bool m_duringRemoveFromWorld; // lock made to not add stuff after begining removing from world