diff options
author | Yehonal <yehonal.azeroth@gmail.com> | 2017-12-20 20:48:35 +0100 |
---|---|---|
committer | Yehonal <yehonal.azeroth@gmail.com> | 2017-12-21 00:20:29 +0100 |
commit | 17332304fdf129076d0196010602350d5750c808 (patch) | |
tree | d161f8845df9e5c8ec0b149bd846646c2b112d49 /src/game/AI/ScriptedAI/ScriptedFollowerAI.cpp | |
parent | 0fc4a6a153ca3a09ccb6e1311131b12a59c6cba3 (diff) |
Using TC structure allowing easier patches importing
Diffstat (limited to 'src/game/AI/ScriptedAI/ScriptedFollowerAI.cpp')
-rw-r--r-- | src/game/AI/ScriptedAI/ScriptedFollowerAI.cpp | 381 |
1 files changed, 0 insertions, 381 deletions
diff --git a/src/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/game/AI/ScriptedAI/ScriptedFollowerAI.cpp deleted file mode 100644 index b44ec3ca0f..0000000000 --- a/src/game/AI/ScriptedAI/ScriptedFollowerAI.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-GPL2 - * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> - */ - -/* ScriptData -SDName: FollowerAI -SD%Complete: 50 -SDComment: This AI is under development -SDCategory: Npc -EndScriptData */ - -#include "ScriptedCreature.h" -#include "ScriptedFollowerAI.h" -#include "Group.h" -#include "Player.h" - -const float MAX_PLAYER_DISTANCE = 100.0f; - -enum ePoints -{ - POINT_COMBAT_START = 0xFFFFFF -}; - -FollowerAI::FollowerAI(Creature* creature) : ScriptedAI(creature), - m_uiLeaderGUID(0), - m_uiUpdateFollowTimer(2500), - m_uiFollowState(STATE_FOLLOW_NONE), - m_pQuestForFollow(NULL) -{} - -void FollowerAI::AttackStart(Unit* who) -{ - if (!who) - return; - - if (me->Attack(who, true)) - { - // This is done in Unit::Attack function which wont bug npcs by not adding threat upon combat start... - //me->AddThreat(who, 0.0f); - //me->SetInCombatWith(who); - //who->SetInCombatWith(me); - - if (me->HasUnitState(UNIT_STATE_FOLLOW)) - me->ClearUnitState(UNIT_STATE_FOLLOW); - - if (IsCombatMovementAllowed()) - me->GetMotionMaster()->MoveChase(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::AssistPlayerInCombat(Unit* who) -{ - if (!who || !who->GetVictim()) - return false; - - //experimental (unknown) flag not present - if (!(me->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_AID_PLAYERS)) - return false; - - //not a player - if (!who->GetVictim()->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)) - { - AttackStart(who); - return true; - } - - return false; -} - -void FollowerAI::MoveInLineOfSight(Unit* who) -{ - if (me->GetVictim()) - return; - - if (!me->HasUnitState(UNIT_STATE_STUNNED) && who->isTargetableForAttack(true, me) && who->isInAccessiblePlaceFor(me)) - if (HasFollowState(STATE_FOLLOW_INPROGRESS) && AssistPlayerInCombat(who)) - return; - - if (me->CanStartAttack(who)) - AttackStart(who); -} - -void FollowerAI::JustDied(Unit* /*pKiller*/) -{ - if (!HasFollowState(STATE_FOLLOW_INPROGRESS) || !m_uiLeaderGUID || !m_pQuestForFollow) - return; - - //TODO: need a better check for quests with time limit. - if (Player* player = GetLeaderForFollower()) - { - if (Group* group = player->GetGroup()) - { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) - { - if (Player* member = groupRef->GetSource()) - { - if (member->IsInMap(player) && member->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE) - member->FailQuest(m_pQuestForFollow->GetQuestId()); - } - } - } - else - { - if (player->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE) - player->FailQuest(m_pQuestForFollow->GetQuestId()); - } - } -} - -void FollowerAI::JustRespawned() -{ - m_uiFollowState = STATE_FOLLOW_NONE; - - if (!IsCombatMovementAllowed()) - SetCombatMovement(true); - - if (me->getFaction() != me->GetCreatureTemplate()->faction) - me->setFaction(me->GetCreatureTemplate()->faction); - - Reset(); -} - -void FollowerAI::EnterEvadeMode() -{ - me->RemoveAllAuras(); - me->DeleteThreatList(); - me->CombatStop(true); - me->SetLootRecipient(NULL); - - if (HasFollowState(STATE_FOLLOW_INPROGRESS)) - { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI left combat, returning to CombatStartPosition."); -#endif - - if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) - { - float fPosX, fPosY, fPosZ; - me->GetPosition(fPosX, fPosY, fPosZ); - me->GetMotionMaster()->MovePoint(POINT_COMBAT_START, fPosX, fPosY, fPosZ); - } - } - else - { - if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) - me->GetMotionMaster()->MoveTargetedHome(); - } - - Reset(); -} - -void FollowerAI::UpdateAI(uint32 uiDiff) -{ - if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !me->GetVictim()) - { - if (m_uiUpdateFollowTimer <= uiDiff) - { - if (HasFollowState(STATE_FOLLOW_COMPLETE) && !HasFollowState(STATE_FOLLOW_POSTEVENT)) - { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI is set completed, despawns."); -#endif - me->DespawnOrUnsummon(); - return; - } - - bool bIsMaxRangeExceeded = true; - - if (Player* player = GetLeaderForFollower()) - { - if (HasFollowState(STATE_FOLLOW_RETURNING)) - { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI is returning to leader."); -#endif - - RemoveFollowState(STATE_FOLLOW_RETURNING); - me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - return; - } - - if (Group* group = player->GetGroup()) - { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) - { - Player* member = groupRef->GetSource(); - - if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE)) - { - bIsMaxRangeExceeded = false; - break; - } - } - } - else - { - if (me->IsWithinDistInMap(player, MAX_PLAYER_DISTANCE)) - bIsMaxRangeExceeded = false; - } - } - - if (bIsMaxRangeExceeded) - { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI failed because player/group was to far away or not found"); -#endif - me->DespawnOrUnsummon(); - return; - } - - m_uiUpdateFollowTimer = 1000; - } - else - m_uiUpdateFollowTimer -= uiDiff; - } - - UpdateFollowerAI(uiDiff); -} - -void FollowerAI::UpdateFollowerAI(uint32 /*uiDiff*/) -{ - if (!UpdateVictim()) - return; - - DoMeleeAttackIfReady(); -} - -void FollowerAI::MovementInform(uint32 motionType, uint32 pointId) -{ - if (motionType != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS)) - return; - - if (pointId == POINT_COMBAT_START) - { - if (GetLeaderForFollower()) - { - if (!HasFollowState(STATE_FOLLOW_PAUSED)) - AddFollowState(STATE_FOLLOW_RETURNING); - } - else - me->DespawnOrUnsummon(); - } -} - -void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, const Quest* quest) -{ - if (me->GetVictim()) - { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI attempt to StartFollow while in combat."); -#endif - return; - } - - if (HasFollowState(STATE_FOLLOW_INPROGRESS)) - { - sLog->outError("TSCR: FollowerAI attempt to StartFollow while already following."); - return; - } - - //set variables - m_uiLeaderGUID = player->GetGUID(); - - if (factionForFollower) - me->setFaction(factionForFollower); - - m_pQuestForFollow = quest; - - if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) - { - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveIdle(); -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle."); -#endif - } - - me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); - - AddFollowState(STATE_FOLLOW_INPROGRESS); - - me->GetMotionMaster()->MoveFollow(player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI start follow %s (GUID " UI64FMTD ")", player->GetName().c_str(), m_uiLeaderGUID); -#endif -} - -Player* FollowerAI::GetLeaderForFollower() -{ - if (Player* player = ObjectAccessor::GetPlayer(*me, m_uiLeaderGUID)) - { - if (player->IsAlive()) - return player; - else - { - if (Group* group = player->GetGroup()) - { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) - { - Player* member = groupRef->GetSource(); - - if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE) && member->IsAlive()) - { -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI GetLeader changed and returned new leader."); -#endif - m_uiLeaderGUID = member->GetGUID(); - return member; - } - } - } - } - } - -#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) - sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI GetLeader can not find suitable leader."); -#endif - return NULL; -} - -void FollowerAI::SetFollowComplete(bool bWithEndEvent) -{ - if (me->HasUnitState(UNIT_STATE_FOLLOW)) - { - me->ClearUnitState(UNIT_STATE_FOLLOW); - - me->StopMoving(); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveIdle(); - } - - if (bWithEndEvent) - AddFollowState(STATE_FOLLOW_POSTEVENT); - else - { - if (HasFollowState(STATE_FOLLOW_POSTEVENT)) - RemoveFollowState(STATE_FOLLOW_POSTEVENT); - } - - AddFollowState(STATE_FOLLOW_COMPLETE); -} - -void FollowerAI::SetFollowPaused(bool paused) -{ - if (!HasFollowState(STATE_FOLLOW_INPROGRESS) || HasFollowState(STATE_FOLLOW_COMPLETE)) - return; - - if (paused) - { - AddFollowState(STATE_FOLLOW_PAUSED); - - if (me->HasUnitState(UNIT_STATE_FOLLOW)) - { - me->ClearUnitState(UNIT_STATE_FOLLOW); - - me->StopMoving(); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveIdle(); - } - } - else - { - RemoveFollowState(STATE_FOLLOW_PAUSED); - - if (Player* leader = GetLeaderForFollower()) - me->GetMotionMaster()->MoveFollow(leader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - } -} |