TrinityCore
Loading...
Searching...
No Matches
FollowMovementGenerator.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
19#include "Creature.h"
20#include "CreatureAI.h"
21#include "MoveSpline.h"
22#include "MoveSplineInit.h"
23#include "Optional.h"
24#include "PathGenerator.h"
25#include "Pet.h"
26#include "Unit.h"
27#include "Util.h"
28
29static void DoMovementInform(Unit* owner, Unit* target)
30{
31 if (owner->GetTypeId() != TYPEID_UNIT)
32 return;
33
34 if (CreatureAI* AI = owner->ToCreature()->AI())
35 AI->MovementInform(FOLLOW_MOTION_TYPE, target->GetGUID().GetCounter());
36}
37
45
46static bool PositionOkay(Unit* owner, Unit* target, float range, Optional<ChaseAngle> angle = {})
47{
48 if (owner->GetExactDistSq(target) > square(owner->GetCombatReach() + target->GetCombatReach() + range))
49 return false;
50
51 return !angle || angle->IsAngleOkay(target->GetRelativeAngle(owner));
52}
53
64
71
73{
74 // owner might be dead or gone
75 if (!owner || !owner->IsAlive())
76 return false;
77
78 // our target might have gone away
79 Unit* const target = GetTarget();
80 if (!target || !target->IsInWorld())
81 return false;
82
84 {
85 _path = nullptr;
86 owner->StopMoving();
87 _lastTargetPosition.reset();
88 return true;
89 }
90
91 _checkTimer.Update(diff);
92 if (_checkTimer.Passed())
93 {
96 {
98 _path = nullptr;
99 owner->StopMoving();
100 _lastTargetPosition.reset();
101 DoMovementInform(owner, target);
102 return true;
103 }
104 }
105
107 {
109 _path = nullptr;
111 DoMovementInform(owner, target);
112 }
113
114 if (!_lastTargetPosition || _lastTargetPosition->GetExactDistSq(target->GetPosition()) > 0.0f)
115 {
118 {
119 if (!_path)
120 _path = std::make_unique<PathGenerator>(owner);
121
122 float x, y, z;
123
124 // select angle
125 float tAngle;
126 float const curAngle = target->GetRelativeAngle(owner);
127 if (_angle.IsAngleOkay(curAngle))
128 tAngle = curAngle;
129 else
130 {
131 float const diffUpper = Position::NormalizeOrientation(curAngle - _angle.UpperBound());
132 float const diffLower = Position::NormalizeOrientation(_angle.LowerBound() - curAngle);
133 if (diffUpper < diffLower)
134 tAngle = _angle.UpperBound();
135 else
136 tAngle = _angle.LowerBound();
137 }
138
139 target->GetNearPoint(owner, x, y, z, _range, target->ToAbsoluteAngle(tAngle));
140
141 // pets are allowed to "cheat" on pathfinding when following their master
142 bool allowShortcut = false;
143 if (Pet* oPet = owner->ToPet())
144 {
145 if (target->GetGUID() == oPet->GetOwnerGUID())
146 allowShortcut = true;
147 }
148
149 bool success = _path->CalculatePath(x, y, z, allowShortcut);
150 if (!success || (_path->GetPathType() & PATHFIND_NOPATH))
151 {
152 owner->StopMoving();
153 return true;
154 }
155
158
159 Movement::MoveSplineInit init(owner);
160 init.MovebyPath(_path->GetPath());
161 init.SetWalk(target->IsWalking());
162 init.SetFacing(target->GetOrientation());
163 init.Launch();
164 }
165 }
166 return true;
167}
168
175
176void FollowMovementGenerator::Finalize(Unit* owner, bool active, bool/* movementInform*/)
177{
179 if (active)
180 {
182 UpdatePetSpeed(owner);
183 }
184}
185
187{
188 if (Pet* oPet = owner->ToPet())
189 {
190 if (!GetTarget() || GetTarget()->GetGUID() == owner->GetOwnerGUID())
191 {
192 oPet->UpdateSpeed(MOVE_RUN);
193 oPet->UpdateSpeed(MOVE_WALK);
194 oPet->UpdateSpeed(MOVE_SWIM);
195 }
196 }
197}
static bool PositionOkay(Unit *owner, Unit *target, Optional< float > minDistance, Optional< float > maxDistance, Optional< ChaseAngle > angle)
static void DoMovementInform(Unit *owner, Unit *target)
uint32_t uint32
Definition Define.h:133
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:84
static bool PositionOkay(Unit *owner, Unit *target, float range, Optional< ChaseAngle > angle={})
static void DoMovementInform(Unit *owner, Unit *target)
#define FOLLOW_RANGE_TOLERANCE
@ MOTION_PRIORITY_NORMAL
@ FOLLOW_MOTION_TYPE
@ MOVEMENTGENERATOR_FLAG_INITIALIZATION_PENDING
@ MOVEMENTGENERATOR_FLAG_DEACTIVATED
@ MOVEMENTGENERATOR_FLAG_FINALIZED
@ MOVEMENTGENERATOR_FLAG_TRANSITORY
@ MOVEMENTGENERATOR_FLAG_INFORM_ENABLED
@ MOVEMENTGENERATOR_FLAG_INITIALIZED
@ TYPEID_UNIT
Definition ObjectGuid.h:38
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
@ PATHFIND_NOPATH
@ MOVE_SWIM
@ MOVE_RUN
@ MOVE_WALK
@ UNIT_STATE_NOT_MOVE
Definition Unit.h:265
@ UNIT_STATE_FOLLOW
Definition Unit.h:229
@ UNIT_STATE_FOLLOW_MOVE
Definition Unit.h:247
T square(T x)
Definition Util.h:95
CreatureAI * AI() const
Definition Creature.h:154
FollowMovementGenerator(Unit *target, float range, ChaseAngle angle)
bool Update(Unit *, uint32) override
void Finalize(Unit *, bool, bool) override
Optional< Position > _lastTargetPosition
std::unique_ptr< PathGenerator > _path
static constexpr uint32 CHECK_INTERVAL
void AddFlag(uint16 const flag)
bool HasFlag(uint16 const flag) const
void RemoveFlag(uint16 const flag)
void SetWalk(bool enable)
void SetFacing(float angle)
void MovebyPath(PointsArray const &path, int32 pointId=0)
bool Finalized() const
Definition MoveSpline.h:121
LowType GetCounter() const
Definition ObjectGuid.h:156
static Creature * ToCreature(Object *o)
Definition Object.h:186
bool IsInWorld() const
Definition Object.h:73
TypeID GetTypeId() const
Definition Object.h:93
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:78
Definition Pet.h:40
Definition Unit.h:769
void ClearUnitState(uint32 f)
Definition Unit.h:877
virtual bool IsMovementPreventedByCasting() const
Definition Unit.cpp:3123
Pet * ToPet()
Definition Unit.h:1788
Movement::MoveSpline * movespline
Definition Unit.h:1804
ObjectGuid GetOwnerGUID() const override
Definition Unit.h:1241
void StopMoving(bool force=false)
Definition Unit.cpp:10312
bool IsAlive() const
Definition Unit.h:1234
float GetCombatReach() const override
Definition Unit.h:839
void AddUnitState(uint32 f)
Definition Unit.h:875
bool HasUnitState(const uint32 f) const
Definition Unit.h:876
bool IsWalking() const
Definition Unit.h:1219
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float distance2d, float absAngle) const
Definition Object.cpp:3209
Unit * GetTarget() const
float UpperBound() const
float LowerBound() const
bool IsAngleOkay(float relativeAngle) const
float GetRelativeAngle(float x, float y) const
Definition Position.h:139
static float NormalizeOrientation(float o)
Definition Position.cpp:156
float ToAbsoluteAngle(float relAngle) const
Definition Position.h:136
float GetOrientation() const
Definition Position.h:82
void GetPosition(float &x, float &y) const
Definition Position.h:84
float GetExactDistSq(float x, float y, float z) const
Definition Position.h:113
void Update(int32 diff)
Definition Timer.h:121
bool Passed() const
Definition Timer.h:131
void Reset(int32 expiry)
Definition Timer.h:136