AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
ChaseMovementGenerator< T > Class Template Reference

#include "TargetedMovementGenerator.h"

Inheritance diagram for ChaseMovementGenerator< T >:
MovementGeneratorMedium< T, ChaseMovementGenerator< T > > TargetedMovementGeneratorBase MovementGenerator

Public Member Functions

 ChaseMovementGenerator (Unit *target, Optional< ChaseRange > range={}, Optional< ChaseAngle > angle={})
 
 ~ChaseMovementGenerator ()
 
MovementGeneratorType GetMovementGeneratorType ()
 
bool DoUpdate (T *, uint32)
 
void DoInitialize (T *)
 
void DoFinalize (T *)
 
void DoReset (T *)
 
void MovementInform (T *)
 
bool PositionOkay (T *owner, Unit *target, Optional< float > maxDistance, Optional< ChaseAngle > angle)
 
void unitSpeedChanged ()
 
UnitGetTarget () const
 
bool EnableWalking () const
 
bool HasLostTarget (Unit *unit) const
 
void DoInitialize (Player *owner)
 
void DoInitialize (Creature *owner)
 
- Public Member Functions inherited from MovementGeneratorMedium< T, ChaseMovementGenerator< T > >
void Initialize (Unit *u) override
 
void Finalize (Unit *u) override
 
void Reset (Unit *u) override
 
bool Update (Unit *u, uint32 time_diff) override
 
- Public Member Functions inherited from MovementGenerator
virtual ~MovementGenerator ()
 
virtual void Initialize (Unit *)=0
 
virtual void Finalize (Unit *)=0
 
virtual void Reset (Unit *)=0
 
virtual bool Update (Unit *, uint32 time_diff)=0
 
virtual MovementGeneratorType GetMovementGeneratorType ()=0
 
virtual uint32 GetSplineId () const
 
virtual void unitSpeedChanged ()
 
virtual void Pause (uint32)
 
virtual void Resume (uint32)
 
virtual bool GetResetPosition (float &, float &, float &)
 
- Public Member Functions inherited from TargetedMovementGeneratorBase
 TargetedMovementGeneratorBase (Unit *target)
 
void stopFollowing ()
 

Private Attributes

std::unique_ptr< PathGeneratori_path
 
TimeTrackerSmall i_recheckDistance
 
bool i_recalculateTravel
 
Optional< Position_lastTargetPosition
 
Optional< ChaseRange > const _range
 
Optional< ChaseAngle > const _angle
 
bool _movingTowards = true
 
bool _mutualChase = true
 

Additional Inherited Members

- Protected Attributes inherited from TargetedMovementGeneratorBase
FollowerReference i_target
 

Detailed Description

template<class T>
class ChaseMovementGenerator< T >

Constructor & Destructor Documentation

◆ ChaseMovementGenerator()

template<class T >
ChaseMovementGenerator< T >::ChaseMovementGenerator ( Unit target,
Optional< ChaseRange range = {},
Optional< ChaseAngle angle = {} 
)
inline
41 {}, Optional<ChaseAngle> angle = {})
42 : TargetedMovementGeneratorBase(target), i_path(nullptr), i_recheckDistance(0), i_recalculateTravel(true), _range(range), _angle(angle) {}
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:24
Definition: TargetedMovementGenerator.h:29
std::unique_ptr< PathGenerator > i_path
Definition: TargetedMovementGenerator.h:62
Optional< ChaseAngle > const _angle
Definition: TargetedMovementGenerator.h:68
bool i_recalculateTravel
Definition: TargetedMovementGenerator.h:64
TimeTrackerSmall i_recheckDistance
Definition: TargetedMovementGenerator.h:63
Optional< ChaseRange > const _range
Definition: TargetedMovementGenerator.h:67

◆ ~ChaseMovementGenerator()

template<class T >
ChaseMovementGenerator< T >::~ChaseMovementGenerator ( )
inline
43{ }

Member Function Documentation

◆ DoFinalize()

template<class T >
template void ChaseMovementGenerator< T >::DoFinalize ( T *  )
266{
267 owner->ClearUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE);
268 if (Creature* cOwner = owner->ToCreature())
269 {
270 cOwner->SetCannotReachTarget();
271 }
272}
@ UNIT_STATE_CHASE
Definition: Unit.h:330
@ UNIT_STATE_CHASE_MOVE
Definition: Unit.h:350
Definition: Creature.h:46
Creature * ToCreature()
Definition: Object.h:197

References Object::ToCreature(), UNIT_STATE_CHASE, and UNIT_STATE_CHASE_MOVE.

◆ DoInitialize() [1/3]

void ChaseMovementGenerator< Creature >::DoInitialize ( Creature owner)
256{
257 i_path = nullptr;
258 _lastTargetPosition.reset();
259 owner->SetWalk(false);
260 owner->StopMoving();
262}
bool SetWalk(bool enable) override
Definition: Creature.cpp:3081
void StopMoving()
Definition: Unit.cpp:16824
void AddUnitState(uint32 f)
Definition: Unit.h:1397
Optional< Position > _lastTargetPosition
Definition: TargetedMovementGenerator.h:66

References Unit::AddUnitState(), Creature::SetWalk(), Unit::StopMoving(), and UNIT_STATE_CHASE.

◆ DoInitialize() [2/3]

void ChaseMovementGenerator< Player >::DoInitialize ( Player owner)
247{
248 i_path = nullptr;
249 _lastTargetPosition.reset();
250 owner->StopMoving();
252}

References Unit::AddUnitState(), Unit::StopMoving(), and UNIT_STATE_CHASE.

◆ DoInitialize() [3/3]

template<class T >
void ChaseMovementGenerator< T >::DoInitialize ( T *  )

◆ DoReset()

template<class T >
template void ChaseMovementGenerator< T >::DoReset ( T *  )
276{
277 DoInitialize(owner);
278}

◆ DoUpdate()

template<class T >
template bool ChaseMovementGenerator< T >::DoUpdate ( T *  ,
uint32   
)
50{
51 if (!i_target.isValid() || !i_target->IsInWorld() || !owner->IsInMap(i_target.getTarget()))
52 return false;
53
54 if (!owner || !owner->IsAlive())
55 return false;
56
57 Creature* cOwner = owner->ToCreature();
58
59 // the owner might be unable to move (rooted or casting), or we have lost the target, pause movement
60 if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || HasLostTarget(owner) || (cOwner && cOwner->IsMovementPreventedByCasting()))
61 {
62 owner->StopMoving();
63 _lastTargetPosition.reset();
64 if (Creature* cOwner2 = owner->ToCreature())
65 {
66 cOwner2->SetCannotReachTarget();
67 }
68
69 return true;
70 }
71
72 bool forceDest =
73 //(cOwner && (cOwner->isWorldBoss() || cOwner->IsDungeonBoss())) || // force for all bosses, even not in instances
74 (i_target->GetTypeId() == TYPEID_PLAYER && i_target->ToPlayer()->IsGameMaster()) || // for .npc follow
75 (owner->CanFly())
76 ; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
77
78 Unit* target = i_target.getTarget();
79
80 bool const mutualChase = IsMutualChase(owner, target);
81 float const hitboxSum = owner->GetCombatReach() + target->GetCombatReach();
82 float const minTarget = (_range ? _range->MinTolerance : 0.0f) + hitboxSum;
83 float const maxRange = _range ? _range->MaxRange + hitboxSum : owner->GetMeleeRange(target); // melee range already includes hitboxes
84 float const maxTarget = _range ? _range->MaxTolerance + hitboxSum : CONTACT_DISTANCE + hitboxSum;
85 Optional<ChaseAngle> angle = mutualChase ? Optional<ChaseAngle>() : _angle;
86
87 i_recheckDistance.Update(time_diff);
89 {
91
92 if (i_recalculateTravel && PositionOkay(owner, target, _movingTowards ? maxTarget : Optional<float>(), angle))
93 {
94 if (Creature* cOwner2 = owner->ToCreature())
95 {
96 cOwner2->SetCannotReachTarget();
97 }
98
99 i_recalculateTravel = false;
100 i_path = nullptr;
101
102 owner->StopMoving();
103 owner->SetInFront(target);
104 MovementInform(owner);
105 return true;
106 }
107 }
108
109 if (owner->HasUnitState(UNIT_STATE_CHASE_MOVE) && owner->movespline->Finalized())
110 {
111 owner->ClearUnitState(UNIT_STATE_CHASE_MOVE);
112 owner->SetInFront(target);
113 MovementInform(owner);
114
115 if (owner->IsWithinMeleeRange(this->i_target.getTarget()))
116 {
117 owner->Attack(this->i_target.getTarget(), true);
118 if (Creature* cOwner2 = owner->ToCreature())
119 {
120 cOwner2->SetCannotReachTarget();
121 }
122 }
123 else if (i_path && i_path->GetPathType() & PATHFIND_INCOMPLETE)
124 {
125 if (Creature* cOwner2 = owner->ToCreature())
126 {
127 cOwner2->SetCannotReachTarget(this->i_target.getTarget()->GetGUID());
128 }
129 }
130
131 i_recalculateTravel = false;
132 i_path = nullptr;
133 }
134
135 if (_lastTargetPosition && i_target->GetPosition() == _lastTargetPosition.value() && mutualChase == _mutualChase)
136 return true;
137
138 _lastTargetPosition = i_target->GetPosition();
139
140 if (PositionOkay(owner, target, maxRange, angle) && !owner->HasUnitState(UNIT_STATE_CHASE_MOVE))
141 {
142 if (Creature* cOwner2 = owner->ToCreature())
143 {
144 cOwner2->SetCannotReachTarget();
145 }
146
147 return true;
148 }
149
150 float tarX, tarY, tarZ;
151 target->GetPosition(tarX, tarY, tarZ);
152
153 bool withinRange = owner->IsInDist(target, maxRange);
154 bool withinLOS = owner->IsWithinLOS(tarX, tarY, tarZ);
155 bool moveToward = !(withinRange && withinLOS);
156
157 _mutualChase = mutualChase;
158
159 if (owner->HasUnitState(UNIT_STATE_CHASE_MOVE))
160 {
161 // can we get to the target?
162 if (cOwner && !target->isInAccessiblePlaceFor(cOwner))
163 {
164 cOwner->SetCannotReachTarget(target->GetGUID());
165 cOwner->StopMoving();
166 i_path = nullptr;
167 return true;
168 }
169 }
170
171 if (!i_path || moveToward != _movingTowards)
172 i_path = std::make_unique<PathGenerator>(owner);
173 else
174 i_path->Clear();
175
176 float x, y, z;
177 bool shortenPath;
178 // if we want to move toward the target and there's no fixed angle...
179 if (moveToward && !angle)
180 {
181 // ...we'll pathfind to the center, then shorten the path
182 target->GetPosition(x, y, z);
183 shortenPath = true;
184 }
185 else
186 {
187 // otherwise, we fall back to nearpoint finding
188 target->GetNearPoint(owner, x, y, z, (moveToward ? maxTarget : minTarget) - hitboxSum, 0, angle ? target->ToAbsoluteAngle(angle->RelativeAngle) : target->GetAngle(owner));
189 shortenPath = false;
190 }
191
192 if (owner->IsHovering())
193 owner->UpdateAllowedPositionZ(x, y, z);
194
195 i_recalculateTravel = true;
196
197 bool success = i_path->CalculatePath(x, y, z, forceDest);
198 if (!success || i_path->GetPathType() & PATHFIND_NOPATH)
199 {
200 if (cOwner)
201 {
202 cOwner->SetCannotReachTarget(target->GetGUID());
203 }
204
205 return true;
206 }
207
208 if (shortenPath)
209 i_path->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), maxTarget);
210
211 if (cOwner)
212 {
213 cOwner->SetCannotReachTarget();
214 }
215
216 bool walk = false;
217 if (cOwner && !cOwner->IsPet())
218 {
219 switch (cOwner->GetMovementTemplate().GetChase())
220 {
221 case CreatureChaseMovementType::CanWalk:
222 if (owner->IsWalking())
223 walk = true;
224 break;
225 case CreatureChaseMovementType::AlwaysWalk:
226 walk = true;
227 break;
228 default:
229 break;
230 }
231 }
232
233 owner->AddUnitState(UNIT_STATE_CHASE_MOVE);
234
235 Movement::MoveSplineInit init(owner);
236 init.MovebyPath(i_path->GetPath());
237 init.SetFacing(target);
238 init.SetWalk(walk);
239 init.Launch();
240
241 return true;
242}
#define CONTACT_DISTANCE
Definition: ObjectDefines.h:23
@ TYPEID_PLAYER
Definition: ObjectGuid.h:38
@ UNIT_STATE_NOT_MOVE
Definition: Unit.h:371
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
@ PATHFIND_INCOMPLETE
Definition: PathGenerator.h:50
static bool IsMutualChase(Unit *owner, Unit *target)
Definition: TargetedMovementGenerator.cpp:27
TO * getTarget() const
Definition: Reference.h:95
bool isValid() const
Definition: Reference.h:79
void Update(int32 diff)
Definition: Timer.h:239
void Reset(int32 interval)
Definition: Timer.h:249
bool Passed() const
Definition: Timer.h:244
void SetCannotReachTarget(ObjectGuid const &target=ObjectGuid::Empty)
Definition: Creature.cpp:3539
CreatureMovementData const & GetMovementTemplate() const
Definition: Creature.cpp:2884
bool IsMovementPreventedByCasting() const override
Definition: Creature.cpp:3517
CreatureChaseMovementType GetChase() const
Definition: CreatureData.h:156
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:106
void GetNearPoint(WorldObject const *searcher, float &x, float &y, float &z, float searcher_size, float distance2d, float absAngle, float controlZ=0, Position const *startPos=nullptr) const
Definition: Object.cpp:2589
float ToAbsoluteAngle(float relAngle) const
Definition: Position.h:203
float GetPositionZ() const
Definition: Position.h:119
float GetPositionX() const
Definition: Position.h:117
void GetPosition(float &x, float &y) const
Definition: Position.h:122
float GetPositionY() const
Definition: Position.h:118
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
Definition: Unit.h:1290
bool IsPet() const
Definition: Unit.h:1413
float GetCombatReach() const override
Definition: Unit.h:1347
bool isInAccessiblePlaceFor(Creature const *c) const
Definition: Unit.cpp:4133
FollowerReference i_target
Definition: TargetedMovementGenerator.h:34
bool _mutualChase
Definition: TargetedMovementGenerator.h:70
bool PositionOkay(T *owner, Unit *target, Optional< float > maxDistance, Optional< ChaseAngle > angle)
Definition: TargetedMovementGenerator.cpp:36
void MovementInform(T *)
Definition: TargetedMovementGenerator.cpp:281
bool HasLostTarget(Unit *unit) const
Definition: TargetedMovementGenerator.h:59
bool _movingTowards
Definition: TargetedMovementGenerator.h:69
Definition: MoveSplineInit.h:71

References AlwaysWalk, CanWalk, CONTACT_DISTANCE, Position::GetAngle(), CreatureMovementData::GetChase(), Unit::GetCombatReach(), Object::GetGUID(), Creature::GetMovementTemplate(), WorldObject::GetNearPoint(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::isInAccessiblePlaceFor(), Creature::IsMovementPreventedByCasting(), IsMutualChase(), Unit::IsPet(), Movement::MoveSplineInit::Launch(), Movement::MoveSplineInit::MovebyPath(), PATHFIND_INCOMPLETE, PATHFIND_NOPATH, Creature::SetCannotReachTarget(), Movement::MoveSplineInit::SetFacing(), Movement::MoveSplineInit::SetWalk(), Unit::StopMoving(), Position::ToAbsoluteAngle(), Object::ToCreature(), TYPEID_PLAYER, UNIT_STATE_CHASE_MOVE, and UNIT_STATE_NOT_MOVE.

◆ EnableWalking()

template<class T >
bool ChaseMovementGenerator< T >::EnableWalking ( ) const
inline
58{ return false; }

◆ GetMovementGeneratorType()

template<class T >
MovementGeneratorType ChaseMovementGenerator< T >::GetMovementGeneratorType ( )
inlinevirtual

Implements MovementGenerator.

45{ return CHASE_MOTION_TYPE; }
@ CHASE_MOTION_TYPE
Definition: MotionMaster.h:43

References CHASE_MOTION_TYPE.

◆ GetTarget()

template<class T >
Unit * ChaseMovementGenerator< T >::GetTarget ( ) const
inline

◆ HasLostTarget()

template<class T >
bool ChaseMovementGenerator< T >::HasLostTarget ( Unit unit) const
inline
59{ return unit->GetVictim() != this->GetTarget(); }
Unit * GetVictim() const
Definition: Unit.h:1386
Unit * GetTarget() const
Definition: TargetedMovementGenerator.h:56

References ChaseMovementGenerator< T >::GetTarget(), and Unit::GetVictim().

◆ MovementInform()

template<class T >
template void ChaseMovementGenerator< T >::MovementInform ( T *  )
282{
283 if (owner->GetTypeId() != TYPEID_UNIT)
284 return;
285
286 // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
287 if (CreatureAI* AI = owner->ToCreature()->AI())
288 AI->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter());
289}
@ TYPEID_UNIT
Definition: ObjectGuid.h:37
Definition: CreatureAI.h:70
LowType GetCounter() const
Definition: ObjectGuid.h:147

References CHASE_MOTION_TYPE, and TYPEID_UNIT.

◆ PositionOkay()

template<class T >
bool ChaseMovementGenerator< T >::PositionOkay ( T *  owner,
Unit target,
Optional< float >  maxDistance,
Optional< ChaseAngle angle 
)
37{
38 float const distSq = owner->GetExactDistSq(target);
39 if (maxDistance && distSq > G3D::square(*maxDistance))
40 return false;
41 if (angle && !angle->IsAngleOkay(target->GetRelativeAngle(owner)))
42 return false;
43 if (!owner->IsWithinLOSInMap(target))
44 return false;
45 return true;
46}
float GetRelativeAngle(const Position *pos) const
Definition: Position.h:197

References Position::GetRelativeAngle().

◆ unitSpeedChanged()

template<class T >
void ChaseMovementGenerator< T >::unitSpeedChanged ( )
inlinevirtual

Member Data Documentation

◆ _angle

template<class T >
Optional<ChaseAngle> const ChaseMovementGenerator< T >::_angle
private

◆ _lastTargetPosition

template<class T >
Optional<Position> ChaseMovementGenerator< T >::_lastTargetPosition
private

◆ _movingTowards

template<class T >
bool ChaseMovementGenerator< T >::_movingTowards = true
private

◆ _mutualChase

template<class T >
bool ChaseMovementGenerator< T >::_mutualChase = true
private

◆ _range

template<class T >
Optional<ChaseRange> const ChaseMovementGenerator< T >::_range
private

◆ i_path

template<class T >
std::unique_ptr<PathGenerator> ChaseMovementGenerator< T >::i_path
private

◆ i_recalculateTravel

template<class T >
bool ChaseMovementGenerator< T >::i_recalculateTravel
private

◆ i_recheckDistance

template<class T >
TimeTrackerSmall ChaseMovementGenerator< T >::i_recheckDistance
private