aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp167
1 files changed, 92 insertions, 75 deletions
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index 9e36c07ffa4..3eb44ba0038 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -33,6 +33,23 @@ enum Points
FollowerAI::FollowerAI(Creature* creature) : ScriptedAI(creature), _updateFollowTimer(2500), _followState(STATE_FOLLOW_NONE), _questForFollow(nullptr) { }
+void FollowerAI::MovementInform(uint32 type, uint32 id)
+{
+ if (type != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS))
+ return;
+
+ if (id == POINT_COMBAT_START)
+ {
+ if (GetLeaderForFollower())
+ {
+ if (!HasFollowState(STATE_FOLLOW_PAUSED))
+ AddFollowState(STATE_FOLLOW_RETURNING);
+ }
+ else
+ me->DespawnOrUnsummon();
+ }
+}
+
void FollowerAI::AttackStart(Unit* who)
{
if (!who)
@@ -50,36 +67,6 @@ void FollowerAI::AttackStart(Unit* who)
}
}
-// This part provides assistance to a player that are attacked by who, even if out of normal aggro range
-// It will cause me to attack who that are attacking _any_ player (which has been confirmed may happen also on offi)
-// The flag (type_flag) is unconfirmed, but used here for further research and is a good candidate.
-bool FollowerAI::AssistPlayerInCombatAgainst(Unit* who)
-{
- if (!who || !who->GetVictim())
- return false;
-
- // experimental (unknown) flag not present
- if (!(me->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_CAN_ASSIST))
- return false;
-
- // not a player
- if (!who->EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
- return false;
-
- // never attack friendly
- if (me->IsFriendlyTo(who))
- return false;
-
- // too far away and no free sight?
- if (me->IsWithinDistInMap(who, MAX_PLAYER_DISTANCE) && me->IsWithinLOSInMap(who))
- {
- me->EngageWithTarget(who);
- return true;
- }
-
- return false;
-}
-
void FollowerAI::MoveInLineOfSight(Unit* who)
{
if (me->HasReactState(REACT_AGGRESSIVE) && !me->HasUnitState(UNIT_STATE_STUNNED) && who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me))
@@ -238,23 +225,6 @@ void FollowerAI::UpdateFollowerAI(uint32 /*uiDiff*/)
DoMeleeAttackIfReady();
}
-void FollowerAI::MovementInform(uint32 type, uint32 id)
-{
- if (type != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS))
- return;
-
- if (id == POINT_COMBAT_START)
- {
- if (GetLeaderForFollower())
- {
- if (!HasFollowState(STATE_FOLLOW_PAUSED))
- AddFollowState(STATE_FOLLOW_RETURNING);
- }
- else
- me->DespawnOrUnsummon();
- }
-}
-
void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest const* quest)
{
if (me->IsEngaged())
@@ -293,34 +263,6 @@ void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest co
TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::StartFollow: start follow %s - %s (%s)", player->GetName().c_str(), _leaderGUID.ToString().c_str(), me->GetGUID().ToString().c_str());
}
-Player* FollowerAI::GetLeaderForFollower()
-{
- if (Player* player = ObjectAccessor::GetPlayer(*me, _leaderGUID))
- {
- if (player->IsAlive())
- return player;
- else
- {
- if (Group* group = player->GetGroup())
- {
- for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
- {
- Player* member = groupRef->GetSource();
- if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE) && member->IsAlive())
- {
- TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::GetLeaderForFollower: GetLeader changed and returned new leader. (%s)", me->GetGUID().ToString().c_str());
- _leaderGUID = member->GetGUID();
- return member;
- }
- }
- }
- }
- }
-
- TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::GetLeaderForFollower: GetLeader can not find suitable leader. (%s)", me->GetGUID().ToString().c_str());
- return nullptr;
-}
-
void FollowerAI::SetFollowComplete(bool withEndEvent)
{
if (me->HasUnitState(UNIT_STATE_FOLLOW))
@@ -369,3 +311,78 @@ void FollowerAI::SetFollowPaused(bool paused)
me->GetMotionMaster()->MoveFollow(leader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
}
}
+
+Player* FollowerAI::GetLeaderForFollower()
+{
+ if (Player* player = ObjectAccessor::GetPlayer(*me, _leaderGUID))
+ {
+ if (player->IsAlive())
+ return player;
+ else
+ {
+ if (Group* group = player->GetGroup())
+ {
+ for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
+ {
+ Player* member = groupRef->GetSource();
+ if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE) && member->IsAlive())
+ {
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::GetLeaderForFollower: GetLeader changed and returned new leader. (%s)", me->GetGUID().ToString().c_str());
+ _leaderGUID = member->GetGUID();
+ return member;
+ }
+ }
+ }
+ }
+ }
+
+ TC_LOG_DEBUG("scripts.ai.followerai", "FollowerAI::GetLeaderForFollower: GetLeader can not find suitable leader. (%s)", me->GetGUID().ToString().c_str());
+ return nullptr;
+}
+
+// This part provides assistance to a player that are attacked by who, even if out of normal aggro range
+// It will cause me to attack who that are attacking _any_ player (which has been confirmed may happen also on offi)
+// The flag (type_flag) is unconfirmed, but used here for further research and is a good candidate.
+bool FollowerAI::AssistPlayerInCombatAgainst(Unit* who)
+{
+ if (!who || !who->GetVictim())
+ return false;
+
+ if (me->HasReactState(REACT_PASSIVE))
+ return false;
+
+ // experimental (unknown) flag not present
+ if (!(me->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_CAN_ASSIST))
+ return false;
+
+ // not a player
+ if (!who->EnsureVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
+ return false;
+
+ if (!who->isInAccessiblePlaceFor(me))
+ return false;
+
+ if (!CanAIAttack(who))
+ return false;
+
+ // we cannot attack in evade mode
+ if (me->IsInEvadeMode())
+ return false;
+
+ // or if enemy is in evade mode
+ if (who->GetTypeId() == TYPEID_UNIT && who->ToCreature()->IsInEvadeMode())
+ return false;
+
+ // never attack friendly
+ if (me->IsFriendlyTo(who))
+ return false;
+
+ // too far away and no free sight
+ if (me->IsWithinDistInMap(who, MAX_PLAYER_DISTANCE) && me->IsWithinLOSInMap(who))
+ {
+ me->EngageWithTarget(who);
+ return true;
+ }
+
+ return false;
+}