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

TimeTrackerSmall i_leashExtensionTimer
 
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 = {})
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:63
Optional< ChaseAngle > const _angle
Definition: TargetedMovementGenerator.h:69
bool i_recalculateTravel
Definition: TargetedMovementGenerator.h:65
TimeTrackerSmall i_recheckDistance
Definition: TargetedMovementGenerator.h:64
Optional< ChaseRange > const _range
Definition: TargetedMovementGenerator.h:68
TimeTrackerSmall i_leashExtensionTimer
Definition: TargetedMovementGenerator.h:62

◆ ~ChaseMovementGenerator()

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

Member Function Documentation

◆ DoFinalize()

template<class T >
template void ChaseMovementGenerator< T >::DoFinalize ( T *  )
307{
308 owner->ClearUnitState(UNIT_STATE_CHASE | UNIT_STATE_CHASE_MOVE);
309 if (Creature* cOwner = owner->ToCreature())
310 {
311 cOwner->SetCannotReachTarget();
312 }
313}
@ UNIT_STATE_CHASE
Definition: UnitDefines.h:154
@ UNIT_STATE_CHASE_MOVE
Definition: UnitDefines.h:174
Definition: Creature.h:46
Creature * ToCreature()
Definition: Object.h:202

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

◆ DoInitialize() [1/3]

void ChaseMovementGenerator< Creature >::DoInitialize ( Creature owner)
297{
298 i_path = nullptr;
299 _lastTargetPosition.reset();
301 owner->SetWalk(false);
303}
void Reset(int32 interval)
Definition: Timer.h:249
bool SetWalk(bool enable) override
Enable or disable the creature's walk mode by removing: MOVEMENTFLAG_WALKING. Infom also the client.
Definition: Creature.cpp:3178
void AddUnitState(uint32 f)
Definition: Unit.h:672
Optional< Position > _lastTargetPosition
Definition: TargetedMovementGenerator.h:67

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

◆ DoInitialize() [2/3]

void ChaseMovementGenerator< Player >::DoInitialize ( Player owner)
288{
289 i_path = nullptr;
290 _lastTargetPosition.reset();
291 owner->StopMoving();
293}
void StopMoving()
Definition: Unit.cpp:16606

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 *  )
317{
318 DoInitialize(owner);
319}

◆ DoUpdate()

template<class T >
template bool ChaseMovementGenerator< T >::DoUpdate ( T *  ,
uint32   
)
67{
68 if (!i_target.isValid() || !i_target->IsInWorld() || !owner->IsInMap(i_target.getTarget()))
69 return false;
70
71 if (!owner || !owner->IsAlive())
72 return false;
73
74 Creature* cOwner = owner->ToCreature();
75
76 // the owner might be unable to move (rooted or casting), or we have lost the target, pause movement
77 if (owner->HasUnitState(UNIT_STATE_NOT_MOVE) || HasLostTarget(owner) || (cOwner && cOwner->IsMovementPreventedByCasting()))
78 {
79 owner->StopMoving();
80 _lastTargetPosition.reset();
81 if (cOwner)
82 {
84 cOwner->SetCannotReachTarget();
85 }
86 return true;
87 }
88
89 bool forceDest =
90 //(cOwner && (cOwner->isWorldBoss() || cOwner->IsDungeonBoss())) || // force for all bosses, even not in instances
91 (i_target->IsPlayer() && i_target->ToPlayer()->IsGameMaster()) || // for .npc follow
92 (owner->CanFly())
93 ; // closes "bool forceDest", that way it is more appropriate, so we can comment out crap whenever we need to
94
95 Unit* target = i_target.getTarget();
96
97 bool mutualChase = IsMutualChase(owner, target);
98 bool const mutualTarget = target->GetVictim() == owner;
99 float const chaseRange = GetChaseRange(owner, target);
100 float const meleeRange = owner->GetMeleeRange(target);
101 float const minTarget = (_range ? _range->MinTolerance : 0.0f) + chaseRange;
102 float const maxRange = _range ? _range->MaxRange + chaseRange : meleeRange; // melee range already includes hitboxes
103 float const maxTarget = _range ? _range->MaxTolerance + chaseRange : CONTACT_DISTANCE + chaseRange;
104
105 Optional<ChaseAngle> angle = mutualChase ? Optional<ChaseAngle>() : _angle;
106
107 // Prevent almost infinite spinning of mutual targets.
108 if (angle && !mutualChase && _mutualChase && mutualTarget && chaseRange < meleeRange)
109 {
110 angle = Optional<ChaseAngle>();
111 mutualChase = true;
112 }
113
114 // Prevent almost infinite spinning for pets with mutualTarget
115 // _mutualChase is false for previous check
116 if (angle && !mutualChase && !_mutualChase && mutualTarget && chaseRange < meleeRange && cOwner && cOwner->IsPet())
117 {
118 angle = Optional<ChaseAngle>();
119 mutualChase = true;
120 }
121
122 // periodically check if we're already in the expected range...
123 i_recheckDistance.Update(time_diff);
125 {
126 i_recheckDistance.Reset(400); // Sniffed value
127
128 if (i_recalculateTravel && PositionOkay(owner, target, _movingTowards ? maxTarget : Optional<float>(), angle))
129 {
130 if ((owner->HasUnitState(UNIT_STATE_CHASE_MOVE) && !target->isMoving() && !mutualChase) || _range)
131 {
132 i_recalculateTravel = false;
133 i_path = nullptr;
134 if (cOwner)
135 cOwner->SetCannotReachTarget();
136 owner->StopMoving();
137 owner->SetInFront(target);
138 MovementInform(owner);
139 return true;
140 }
141 }
142 }
143
144 // if we're done moving, we want to clean up
145 if (owner->HasUnitState(UNIT_STATE_CHASE_MOVE) && owner->movespline->Finalized())
146 {
147 i_recalculateTravel = false;
148 i_path = nullptr;
149 if (cOwner)
150 cOwner->SetCannotReachTarget();
151 owner->ClearUnitState(UNIT_STATE_CHASE_MOVE);
152 owner->SetInFront(target);
153 MovementInform(owner);
154 }
155
156 if (owner->movespline->Finalized())
157 { // Mobs should chase you infinitely if you stop and wait every few seconds.
158 i_leashExtensionTimer.Update(time_diff);
160 {
162 if (cOwner)
163 cOwner->UpdateLeashExtensionTime();
164 }
165 }
166 else if (i_recalculateTravel)
168
169 // if the target moved, we have to consider whether to adjust
170 if (!_lastTargetPosition || target->GetPosition() != _lastTargetPosition.value() || mutualChase != _mutualChase || !owner->IsWithinLOSInMap(target))
171 {
173 _mutualChase = mutualChase;
174 if (owner->HasUnitState(UNIT_STATE_CHASE_MOVE) || !PositionOkay(owner, target, maxTarget, angle))
175 {
176 // can we get to the target?
177 if (cOwner && !target->isInAccessiblePlaceFor(cOwner))
178 {
179 cOwner->SetCannotReachTarget(target->GetGUID());
180 cOwner->StopMoving();
181 i_path = nullptr;
182 return true;
183 }
184
185 // figure out which way we want to move
186 float x, y, z;
187 target->GetPosition(x, y, z);
188 bool withinRange = owner->IsInDist(target, maxRange);
189 bool withinLOS = owner->IsWithinLOS(x, y, z);
190 bool moveToward = !(withinRange && withinLOS);
191
192 // make a new path if we have to...
193 if (!i_path || moveToward != _movingTowards)
194 i_path = std::make_unique<PathGenerator>(owner);
195 else
196 i_path->Clear();
197
198 // Predict chase destination to keep up with chase target
199 float additionalRange = 0;
200 bool predictDestination = !mutualChase && target->isMoving();
201 if (predictDestination)
202 {
203 UnitMoveType moveType = MOVE_RUN;
204 if (target->CanFly())
206 else
207 {
208 if (target->IsWalking())
209 moveType = MOVE_WALK;
210 else
212 }
213 float speed = target->GetSpeed(moveType) * 0.5f;
214 additionalRange = owner->GetExactDistSq(target) < G3D::square(speed) ? 0 : speed;
215 }
216
217 bool shortenPath;
218
219 // if we want to move toward the target and there's no fixed angle...
220 if (moveToward && !angle)
221 {
222 // ...we'll pathfind to the center, then shorten the path
223 shortenPath = true;
224 }
225 else
226 {
227 // otherwise, we fall back to nearpoint finding
228 target->GetNearPoint(owner, x, y, z, (moveToward ? maxTarget : minTarget) - chaseRange - additionalRange, 0, angle ? target->ToAbsoluteAngle(angle->RelativeAngle) : target->GetAngle(owner));
229 shortenPath = false;
230 }
231
232 if (owner->IsHovering())
233 owner->UpdateAllowedPositionZ(x, y, z);
234
235 bool success = i_path->CalculatePath(x, y, z, forceDest);
236 if (!success || i_path->GetPathType() & PATHFIND_NOPATH)
237 {
238 if (cOwner)
239 {
240 cOwner->SetCannotReachTarget(target->GetGUID());
241 }
242
243 owner->StopMoving();
244 return true;
245 }
246
247 if (shortenPath)
248 i_path->ShortenPathUntilDist(G3D::Vector3(x, y, z), maxTarget);
249
250 if (cOwner)
251 {
252 cOwner->SetCannotReachTarget();
253 }
254
255 bool walk = false;
256 if (cOwner && !cOwner->IsPet())
257 {
258 switch (cOwner->GetMovementTemplate().GetChase())
259 {
260 case CreatureChaseMovementType::CanWalk:
261 walk = owner->IsWalking();
262 break;
263 case CreatureChaseMovementType::AlwaysWalk:
264 walk = true;
265 break;
266 default:
267 break;
268 }
269 }
270
271 owner->AddUnitState(UNIT_STATE_CHASE_MOVE);
272 i_recalculateTravel = true;
273
274 Movement::MoveSplineInit init(owner);
275 init.MovebyPath(i_path->GetPath());
276 init.SetFacing(target);
277 init.SetWalk(walk);
278 init.Launch();
279 }
280 }
281
282 return true;
283}
@ PATHFIND_NOPATH
Definition: PathGenerator.h:51
float GetChaseRange(Unit const *owner, Unit const *target)
Definition: TargetedMovementGenerator.cpp:35
static bool IsMutualChase(Unit *owner, Unit *target)
Definition: TargetedMovementGenerator.cpp:27
@ MOVEMENTFLAG_BACKWARD
Definition: UnitDefines.h:345
@ UNIT_STATE_NOT_MOVE
Definition: UnitDefines.h:197
UnitMoveType
Definition: UnitDefines.h:327
@ MOVE_FLIGHT
Definition: UnitDefines.h:334
@ MOVE_FLIGHT_BACK
Definition: UnitDefines.h:335
@ MOVE_RUN
Definition: UnitDefines.h:329
@ MOVE_RUN_BACK
Definition: UnitDefines.h:330
@ MOVE_WALK
Definition: UnitDefines.h:328
#define CONTACT_DISTANCE
Definition: ObjectDefines.h:23
TO * getTarget() const
Definition: Reference.h:95
bool isValid() const
Definition: Reference.h:79
void Update(int32 diff)
Definition: Timer.h:239
bool Passed() const
Definition: Timer.h:244
void SetCannotReachTarget(ObjectGuid const &target=ObjectGuid::Empty)
Definition: Creature.cpp:3647
void UpdateLeashExtensionTime()
Definition: Creature.cpp:3700
CreatureMovementData const & GetMovementTemplate() const
Definition: Creature.cpp:2975
bool IsMovementPreventedByCasting() const override
Definition: Creature.cpp:3625
CreatureChaseMovementType GetChase() const
Definition: CreatureData.h:153
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:109
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:2626
float ToAbsoluteAngle(float relAngle) const
Definition: Position.h:203
void GetPosition(float &x, float &y) const
Definition: Position.h:122
float GetAngle(const Position *pos) const
Definition: Position.cpp:77
Definition: Unit.h:630
float GetSpeed(UnitMoveType mtype) const
Definition: Unit.cpp:14378
virtual bool CanFly() const =0
bool IsPet() const
Definition: Unit.h:710
bool isInAccessiblePlaceFor(Creature const *c) const
Definition: Unit.cpp:4175
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:1613
bool isMoving() const
Definition: Unit.h:1696
Unit * GetVictim() const
Definition: Unit.h:789
bool IsWalking() const
Definition: Unit.h:1695
FollowerReference i_target
Definition: TargetedMovementGenerator.h:34
bool _mutualChase
Definition: TargetedMovementGenerator.h:71
bool PositionOkay(T *owner, Unit *target, Optional< float > maxDistance, Optional< ChaseAngle > angle)
Definition: TargetedMovementGenerator.cpp:47
void MovementInform(T *)
Definition: TargetedMovementGenerator.cpp:322
bool HasLostTarget(Unit *unit) const
Definition: TargetedMovementGenerator.h:59
bool _movingTowards
Definition: TargetedMovementGenerator.h:70
Definition: MoveSplineInit.h:71

References AlwaysWalk, Unit::CanFly(), CanWalk, CONTACT_DISTANCE, Position::GetAngle(), CreatureMovementData::GetChase(), GetChaseRange(), Object::GetGUID(), Creature::GetMovementTemplate(), WorldObject::GetNearPoint(), Position::GetPosition(), Unit::GetSpeed(), Unit::GetVictim(), Unit::HasUnitMovementFlag(), Unit::isInAccessiblePlaceFor(), Creature::IsMovementPreventedByCasting(), Unit::isMoving(), IsMutualChase(), Unit::IsPet(), Unit::IsWalking(), Movement::MoveSplineInit::Launch(), MOVE_FLIGHT, MOVE_FLIGHT_BACK, MOVE_RUN, MOVE_RUN_BACK, MOVE_WALK, Movement::MoveSplineInit::MovebyPath(), MOVEMENTFLAG_BACKWARD, PATHFIND_NOPATH, Creature::SetCannotReachTarget(), Movement::MoveSplineInit::SetFacing(), Movement::MoveSplineInit::SetWalk(), Unit::StopMoving(), Position::ToAbsoluteAngle(), Object::ToCreature(), UNIT_STATE_CHASE_MOVE, UNIT_STATE_NOT_MOVE, and Creature::UpdateLeashExtensionTime().

◆ 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 * GetTarget() const
Definition: TargetedMovementGenerator.h:56

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

◆ MovementInform()

template<class T >
template void ChaseMovementGenerator< T >::MovementInform ( T *  )
323{
324 if (!owner->IsCreature())
325 return;
326
327 // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
328 if (CreatureAI* AI = owner->ToCreature()->AI())
329 AI->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter());
330}
Definition: CreatureAI.h:71
LowType GetCounter() const
Definition: ObjectGuid.h:145

References CHASE_MOTION_TYPE.

◆ PositionOkay()

template<class T >
bool ChaseMovementGenerator< T >::PositionOkay ( T *  owner,
Unit target,
Optional< float >  maxDistance,
Optional< ChaseAngle angle 
)
48{
49 float const distSq = owner->GetExactDistSq(target);
50
51 // Distance between owner(chaser) and target is greater than the allowed distance.
52 if (maxDistance && distSq > G3D::square(*maxDistance))
53 return false;
54
55 // owner's relative angle to its target is not within boundaries
56 if (angle && !angle->IsAngleOkay(target->GetRelativeAngle(owner)))
57 return false;
58
59 // owner cannot see its target
60 if (!owner->IsWithinLOSInMap(target))
61 return false;
62 return true;
63}
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_leashExtensionTimer

template<class T >
TimeTrackerSmall ChaseMovementGenerator< T >::i_leashExtensionTimer
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