@@ -23,10 +23,7 @@ FollowerAI::FollowerAI(Creature* pCreature) : ScriptedAI(pCreature),
2323 m_uiLeaderGUID(0 ),
2424 m_pQuestForFollow(NULL ),
2525 m_uiUpdateFollowTimer(2500 ),
26- m_bIsFollowing(false ),
27- m_bIsReturnToLeader(false ),
28- m_bIsFollowComplete(false ),
29- m_bIsEndEvent(false )
26+ m_uiFollowState(STATE_FOLLOW_NONE )
3027{}
3128
3229void FollowerAI::AttackStart (Unit* pWho)
@@ -60,14 +57,21 @@ void FollowerAI::MoveInLineOfSight(Unit* pWho)
6057 // It will cause m_creature to attack pWho that are attacking _any_ player (which has been confirmed may happen also on offi)
6158 // The flag (type_flag) is unconfirmed, but used here for further research and is a good candidate.
6259 if (m_creature->hasUnitState (UNIT_STAT_FOLLOW ) &&
63- m_creature->GetCreatureInfo ()->type_flags & 0x01000 &&
60+ m_creature->GetCreatureInfo ()->type_flags & CREATURE_TYPEFLAGS_UNK13 &&
6461 pWho->getVictim () &&
6562 pWho->getVictim ()->GetCharmerOrOwnerPlayerOrPlayerItself () &&
6663 m_creature->IsWithinDistInMap (pWho, MAX_PLAYER_DISTANCE ) &&
6764 m_creature->IsWithinLOSInMap (pWho))
6865 {
69- pWho->RemoveSpellsCausingAura (SPELL_AURA_MOD_STEALTH );
70- AttackStart (pWho);
66+ if (!m_creature->getVictim ())
67+ {
68+ AttackStart (pWho);
69+ }
70+ else
71+ {
72+ pWho->SetInCombatWith (m_creature);
73+ m_creature->AddThreat (pWho, 0 .0f );
74+ }
7175 }
7276 else
7377 {
@@ -91,7 +95,7 @@ void FollowerAI::MoveInLineOfSight(Unit* pWho)
9195
9296void FollowerAI::JustDied (Unit* pKiller)
9397{
94- if (!m_bIsFollowing || !m_uiLeaderGUID || !m_pQuestForFollow)
98+ if (!HasFollowState ( STATE_FOLLOW_INPROGRESS ) || !m_uiLeaderGUID || !m_pQuestForFollow)
9599 return ;
96100
97101 // TODO: need a better check for quests with time limit.
@@ -118,10 +122,7 @@ void FollowerAI::JustDied(Unit* pKiller)
118122
119123void FollowerAI::JustRespawned ()
120124{
121- m_bIsFollowing = false ;
122- m_bIsReturnToLeader = false ;
123- m_bIsFollowComplete = false ;
124- m_bIsEndEvent = false ;
125+ m_uiFollowState = STATE_FOLLOW_NONE ;
125126
126127 if (!IsCombatMovement ())
127128 SetCombatMovement (true );
@@ -139,7 +140,7 @@ void FollowerAI::EnterEvadeMode()
139140 m_creature->CombatStop (true );
140141 m_creature->SetLootRecipient (NULL );
141142
142- if (m_bIsFollowing )
143+ if (HasFollowState ( STATE_FOLLOW_INPROGRESS ) )
143144 {
144145 debug_log (" SD2: FollowerAI left combat, returning to CombatStartPosition." );
145146
@@ -161,11 +162,13 @@ void FollowerAI::EnterEvadeMode()
161162
162163void FollowerAI::UpdateAI (const uint32 uiDiff)
163164{
164- if (m_bIsFollowing && !m_creature->getVictim ())
165+ Unit* pUnit = m_creature->getVictim ();
166+
167+ if (HasFollowState (STATE_FOLLOW_INPROGRESS ) && !m_creature->getVictim ())
165168 {
166169 if (m_uiUpdateFollowTimer < uiDiff)
167170 {
168- if (m_bIsFollowComplete && !m_bIsEndEvent )
171+ if (HasFollowState ( STATE_FOLLOW_COMPLETE ) && !HasFollowState ( STATE_FOLLOW_POSTEVENT ) )
169172 {
170173 debug_log (" SD2: FollowerAI is set completed, despawns." );
171174 m_creature->ForcedDespawn ();
@@ -176,11 +179,12 @@ void FollowerAI::UpdateAI(const uint32 uiDiff)
176179
177180 if (Player* pPlayer = GetLeaderForFollower ())
178181 {
179- if (m_bIsReturnToLeader )
182+ if (HasFollowState ( STATE_FOLLOW_RETURNING ) )
180183 {
181184 debug_log (" SD2: FollowerAI is returning to leader." );
185+
186+ RemoveFollowState (STATE_FOLLOW_RETURNING );
182187 m_creature->GetMotionMaster ()->MoveFollow (pPlayer, PET_FOLLOW_DIST , PET_FOLLOW_ANGLE );
183- m_bIsReturnToLeader = false ;
184188 return ;
185189 }
186190
@@ -230,13 +234,16 @@ void FollowerAI::UpdateFollowerAI(const uint32 uiDiff)
230234
231235void FollowerAI::MovementInform (uint32 uiMotionType, uint32 uiPointId)
232236{
233- if (uiMotionType != POINT_MOTION_TYPE || !m_bIsFollowing )
237+ if (uiMotionType != POINT_MOTION_TYPE || !HasFollowState ( STATE_FOLLOW_INPROGRESS ) )
234238 return ;
235239
236240 if (uiPointId == POINT_COMBAT_START )
237241 {
238242 if (GetLeaderForFollower ())
239- m_bIsReturnToLeader = true ;
243+ {
244+ if (!HasFollowState (STATE_FOLLOW_PAUSED ))
245+ AddFollowState (STATE_FOLLOW_RETURNING );
246+ }
240247 else
241248 m_creature->ForcedDespawn ();
242249 }
@@ -250,7 +257,7 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const
250257 return ;
251258 }
252259
253- if (m_bIsFollowing )
260+ if (HasFollowState ( STATE_FOLLOW_INPROGRESS ) )
254261 {
255262 error_log (" SD2: FollowerAI attempt to StartFollow while already following." );
256263 return ;
@@ -273,9 +280,9 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const
273280
274281 m_creature->SetUInt32Value (UNIT_NPC_FLAGS , UNIT_NPC_FLAG_NONE );
275282
276- m_creature-> GetMotionMaster ()-> MoveFollow (pLeader, PET_FOLLOW_DIST , PET_FOLLOW_ANGLE );
283+ AddFollowState ( STATE_FOLLOW_INPROGRESS );
277284
278- m_bIsFollowing = true ;
285+ m_creature-> GetMotionMaster ()-> MoveFollow (pLeader, PET_FOLLOW_DIST , PET_FOLLOW_ANGLE ) ;
279286
280287 debug_log (" SD2: FollowerAI start follow %s (GUID %u)" , pLeader->GetName (), m_uiLeaderGUID);
281288}
@@ -316,10 +323,45 @@ void FollowerAI::SetFollowComplete(bool bWithEndEvent)
316323 {
317324 m_creature->clearUnitState (UNIT_STAT_FOLLOW );
318325
319- m_creature->GetMotionMaster ()->MovementExpired ();
326+ m_creature->StopMoving ();
327+ m_creature->GetMotionMaster ()->Clear ();
320328 m_creature->GetMotionMaster ()->MoveIdle ();
321329 }
322330
323- m_bIsEndEvent = bWithEndEvent;
324- m_bIsFollowComplete = true ;
331+ if (bWithEndEvent)
332+ AddFollowState (STATE_FOLLOW_POSTEVENT );
333+ else
334+ {
335+ if (HasFollowState (STATE_FOLLOW_POSTEVENT ))
336+ RemoveFollowState (STATE_FOLLOW_POSTEVENT );
337+ }
338+
339+ AddFollowState (STATE_FOLLOW_COMPLETE );
340+ }
341+
342+ void FollowerAI::SetFollowPaused (bool bPaused)
343+ {
344+ if (!HasFollowState (STATE_FOLLOW_INPROGRESS ) || HasFollowState (STATE_FOLLOW_COMPLETE ))
345+ return ;
346+
347+ if (bPaused)
348+ {
349+ AddFollowState (STATE_FOLLOW_PAUSED );
350+
351+ if (m_creature->hasUnitState (UNIT_STAT_FOLLOW ))
352+ {
353+ m_creature->clearUnitState (UNIT_STAT_FOLLOW );
354+
355+ m_creature->StopMoving ();
356+ m_creature->GetMotionMaster ()->Clear ();
357+ m_creature->GetMotionMaster ()->MoveIdle ();
358+ }
359+ }
360+ else
361+ {
362+ RemoveFollowState (STATE_FOLLOW_PAUSED );
363+
364+ if (Player* pLeader = GetLeaderForFollower ())
365+ m_creature->GetMotionMaster ()->MoveFollow (pLeader, PET_FOLLOW_DIST , PET_FOLLOW_ANGLE );
366+ }
325367}
0 commit comments