aboutsummaryrefslogtreecommitdiff
path: root/src/bindings/scripts/base
diff options
context:
space:
mode:
Diffstat (limited to 'src/bindings/scripts/base')
-rw-r--r--src/bindings/scripts/base/escort_ai.cpp (renamed from src/bindings/scripts/base/escortAI.cpp)112
-rw-r--r--src/bindings/scripts/base/escort_ai.h (renamed from src/bindings/scripts/base/escortAI.h)22
-rw-r--r--src/bindings/scripts/base/follower_ai.cpp309
-rw-r--r--src/bindings/scripts/base/follower_ai.h50
-rw-r--r--src/bindings/scripts/base/guard_ai.cpp5
-rw-r--r--src/bindings/scripts/base/guard_ai.h4
6 files changed, 451 insertions, 51 deletions
diff --git a/src/bindings/scripts/base/escortAI.cpp b/src/bindings/scripts/base/escort_ai.cpp
index 2c9b968d281..34b4efcbe60 100644
--- a/src/bindings/scripts/base/escortAI.cpp
+++ b/src/bindings/scripts/base/escort_ai.cpp
@@ -10,7 +10,8 @@ SDCategory: Npc
EndScriptData */
#include "precompiled.h"
-#include "escortAI.h"
+#include "escort_ai.h"
+#include "../system/system.h"
enum
{
@@ -18,7 +19,24 @@ enum
POINT_HOME = 0xFFFFFE
};
-extern std::list<PointMovement> PointMovementList;
+npc_escortAI::npc_escortAI(Creature* pCreature) : ScriptedAI(pCreature),
+ IsBeingEscorted(false),
+ IsOnHold(false),
+ m_uiPlayerGUID(0),
+ MaxPlayerDistance(DEFAULT_MAX_PLAYER_DISTANCE),
+ CanMelee(true),
+ m_uiPlayerCheckTimer(1000),
+ m_uiWPWaitTimer(2500),
+ m_bIsReturning(false),
+ m_bIsActiveAttacker(true),
+ m_bIsRunning(false),
+ DespawnAtEnd(true),
+ DespawnAtFar(true),
+ m_pQuestForEscort(NULL),
+ m_bCanInstantRespawn(false),
+ m_bCanReturnToStart(false),
+ ScriptWP(false)
+{}
void npc_escortAI::AttackStart(Unit* pWho)
{
@@ -45,10 +63,10 @@ void npc_escortAI::MoveInLineOfSight(Unit* pWho)
void npc_escortAI::JustDied(Unit* pKiller)
{
- if (!IsBeingEscorted || !PlayerGUID || !m_pQuestForEscort)
+ if (!IsBeingEscorted || !m_uiPlayerGUID || !m_pQuestForEscort)
return;
- if (Player* pPlayer = Unit::GetPlayer(PlayerGUID))
+ if (Player* pPlayer = GetPlayerForEscort())
{
if (Group* pGroup = pPlayer->GetGroup())
{
@@ -112,6 +130,32 @@ void npc_escortAI::EnterEvadeMode()
Reset();
}
+bool npc_escortAI::IsPlayerOrGroupInRange()
+{
+ if (Player* pPlayer = GetPlayerForEscort())
+ {
+ if (Group* pGroup = pPlayer->GetGroup())
+ {
+ for(GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
+ {
+ Player* pMember = pRef->getSource();
+
+ if (pMember && m_creature->IsWithinDistInMap(pMember, GetMaxPlayerDistance()))
+ {
+ return true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (m_creature->IsWithinDistInMap(pPlayer, GetMaxPlayerDistance()))
+ return true;
+ }
+ }
+ return false;
+}
+
void npc_escortAI::UpdateAI(const uint32 uiDiff)
{
//Waypoint Updating
@@ -160,7 +204,10 @@ void npc_escortAI::UpdateAI(const uint32 uiDiff)
if (!IsOnHold)
{
m_creature->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z);
- debug_log("TSCR: EscortAI Next WP is: %u, %f, %f, %f", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z);
+ debug_log("TSCR: EscortAI start waypoint %u (%f, %f, %f).", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z);
+
+ WaypointStart(CurrentWP->id);
+
m_uiWPWaitTimer = 0;
}
}
@@ -169,35 +216,11 @@ void npc_escortAI::UpdateAI(const uint32 uiDiff)
}
//Check if player or any member of his group is within range
- if (IsBeingEscorted && PlayerGUID && !m_creature->getVictim() && !m_bIsReturning)
+ if (IsBeingEscorted && m_uiPlayerGUID && !m_creature->getVictim() && !m_bIsReturning)
{
if (m_uiPlayerCheckTimer < uiDiff)
{
- bool bIsMaxRangeExceeded = true;
-
- if (Player* pPlayer = Unit::GetPlayer(PlayerGUID))
- {
- if (Group* pGroup = pPlayer->GetGroup())
- {
- for(GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
- {
- Player* pMember = pRef->getSource();
-
- if (pMember && m_creature->IsWithinDistInMap(pMember, GetMaxPlayerDistance()))
- {
- bIsMaxRangeExceeded = false;
- break;
- }
- }
- }
- else
- {
- if (m_creature->IsWithinDistInMap(pPlayer, GetMaxPlayerDistance()))
- bIsMaxRangeExceeded = false;
- }
- }
-
- if (DespawnAtFar && bIsMaxRangeExceeded)
+ if (DespawnAtFar && !IsPlayerOrGroupInRange())
{
debug_log("TSCR: EscortAI failed because player/group was to far away or not found");
@@ -218,6 +241,11 @@ void npc_escortAI::UpdateAI(const uint32 uiDiff)
m_uiPlayerCheckTimer -= uiDiff;
}
+ UpdateEscortAI(uiDiff);
+}
+
+void npc_escortAI::UpdateEscortAI(const uint32 uiDiff)
+{
if (CanMelee && UpdateVictim())
DoMeleeAttackIfReady();
}
@@ -308,17 +336,17 @@ void npc_escortAI::AddWaypoint(uint32 id, float x, float y, float z, uint32 Wait
void npc_escortAI::FillPointMovementListForCreature()
{
- UNORDERED_MAP<uint32, std::vector<PointMovement> >::iterator pPointsEntries = PointMovementMap.find(m_creature->GetEntry());
+ std::vector<ScriptPointMove> const &pPointsEntries = pSystemMgr.GetPointMoveList(m_creature->GetEntry());
- if (pPointsEntries != PointMovementMap.end())
- {
- std::vector<PointMovement>::iterator itr;
+ if (pPointsEntries.empty())
+ return;
- for (itr = pPointsEntries->second.begin(); itr != pPointsEntries->second.end(); ++itr)
- {
- Escort_Waypoint pPoint(itr->m_uiPointId,itr->m_fX,itr->m_fY,itr->m_fZ,itr->m_uiWaitTime);
- WaypointList.push_back(pPoint);
- }
+ std::vector<ScriptPointMove>::const_iterator itr;
+
+ for (itr = pPointsEntries.begin(); itr != pPointsEntries.end(); ++itr)
+ {
+ Escort_Waypoint pPoint(itr->uiPointId, itr->fX, itr->fY, itr->fZ, itr->uiWaitTime);
+ WaypointList.push_back(pPoint);
}
}
@@ -376,7 +404,7 @@ void npc_escortAI::Start(bool bIsActiveAttacker, bool bRun, uint64 uiPlayerGUID,
m_bIsActiveAttacker = bIsActiveAttacker;
m_bIsRunning = bRun;
- PlayerGUID = uiPlayerGUID;
+ m_uiPlayerGUID = uiPlayerGUID;
m_pQuestForEscort = pQuest;
m_bCanInstantRespawn = bInstantRespawn;
@@ -395,7 +423,7 @@ void npc_escortAI::Start(bool bIsActiveAttacker, bool bRun, uint64 uiPlayerGUID,
//disable npcflags
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
- debug_log("TSCR: EscortAI started with %d waypoints. ActiveAttacker = %d, Run = %d, PlayerGUID = %d", WaypointList.size(), m_bIsActiveAttacker, m_bIsRunning, PlayerGUID);
+ debug_log("TSCR: EscortAI started with %d waypoints. ActiveAttacker = %d, Run = %d, PlayerGUID = %d", WaypointList.size(), m_bIsActiveAttacker, m_bIsRunning, m_uiPlayerGUID);
CurrentWP = WaypointList.begin();
diff --git a/src/bindings/scripts/base/escortAI.h b/src/bindings/scripts/base/escort_ai.h
index 8ce82eb370a..60e555dcfd4 100644
--- a/src/bindings/scripts/base/escortAI.h
+++ b/src/bindings/scripts/base/escort_ai.h
@@ -7,8 +7,6 @@
#define DEFAULT_MAX_PLAYER_DISTANCE 50
-extern UNORDERED_MAP<uint32, std::vector<PointMovement> > PointMovementMap;
-
struct Escort_Waypoint
{
Escort_Waypoint(uint32 _id, float _x, float _y, float _z, uint32 _w)
@@ -30,12 +28,12 @@ struct Escort_Waypoint
struct TRINITY_DLL_DECL npc_escortAI : public ScriptedAI
{
public:
- explicit npc_escortAI(Creature* pCreature) : ScriptedAI(pCreature),
- IsBeingEscorted(false), IsOnHold(false), PlayerGUID(0), MaxPlayerDistance(DEFAULT_MAX_PLAYER_DISTANCE), CanMelee(true), m_uiPlayerCheckTimer(1000), m_uiWPWaitTimer(2500), m_bIsReturning(false), m_bIsActiveAttacker(true), m_bIsRunning(false), DespawnAtEnd(true), DespawnAtFar(true), m_pQuestForEscort(NULL), m_bCanInstantRespawn(false), m_bCanReturnToStart(false), ScriptWP(false) {}
+ explicit npc_escortAI(Creature* pCreature);
~npc_escortAI() {}
// Pure Virtual Functions
- virtual void WaypointReached(uint32) = 0;
+ virtual void WaypointReached(uint32 uiPointId) = 0;
+ virtual void WaypointStart(uint32 uiPointId) {}
// CreatureAI functions
void AttackStart(Unit* who);
@@ -50,13 +48,21 @@ struct TRINITY_DLL_DECL npc_escortAI : public ScriptedAI
void EnterEvadeMode();
- void UpdateAI(const uint32);
+ void UpdateAI(const uint32); //the "internal" update, calls UpdateEscortAI()
+ virtual void UpdateEscortAI(const uint32); //used when it's needed to add code in update (abilities, scripted events, etc)
void MovementInform(uint32, uint32);
// EscortAI functions
void AddWaypoint(uint32 id, float x, float y, float z, uint32 WaitTimeMs = 0);
+ bool IsPlayerOrGroupInRange();
+
+ Player* GetPlayerForEscort()
+ {
+ return Unit::GetPlayer(m_uiPlayerGUID);
+ }
+
void FillPointMovementListForCreature();
void Start(bool bIsActiveAttacker = true, bool bRun = false, uint64 uiPlayerGUID = 0, const Quest* pQuest = NULL, bool bInstantRespawn = false, bool bCanLoopPath = false);
@@ -75,15 +81,15 @@ struct TRINITY_DLL_DECL npc_escortAI : public ScriptedAI
bool GetIsBeingEscorted() { return IsBeingEscorted; }//used in EnterEvadeMode override
void SetReturning(bool returning) { m_bIsReturning = returning; }//used in EnterEvadeMode override
void SetCanAttack(bool attack) { m_bIsActiveAttacker = attack; }
- uint64 GetEventStarterGUID() { return PlayerGUID; }
+ uint64 GetEventStarterGUID() { return m_uiPlayerGUID; }
// EscortAI variables
protected:
- uint64 PlayerGUID;
bool IsBeingEscorted;
bool IsOnHold;
private:
+ uint64 m_uiPlayerGUID;
uint32 m_uiWPWaitTimer;
uint32 m_uiPlayerCheckTimer;
float MaxPlayerDistance;
diff --git a/src/bindings/scripts/base/follower_ai.cpp b/src/bindings/scripts/base/follower_ai.cpp
new file mode 100644
index 00000000000..eb847c219db
--- /dev/null
+++ b/src/bindings/scripts/base/follower_ai.cpp
@@ -0,0 +1,309 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+/* ScriptData
+SDName: FollowerAI
+SD%Complete: 50
+SDComment: This AI is under development
+SDCategory: Npc
+EndScriptData */
+
+#include "precompiled.h"
+#include "follower_ai.h"
+
+const float MAX_PLAYER_DISTANCE = 100.0f;
+
+enum
+{
+ POINT_COMBAT_START = 0xFFFFFF
+};
+
+FollowerAI::FollowerAI(Creature* pCreature) : ScriptedAI(pCreature),
+ m_uiLeaderGUID(0),
+ m_pQuestForFollow(NULL),
+ m_uiUpdateFollowTimer(2500),
+ m_bIsFollowing(false),
+ m_bIsReturnToLeader(false),
+ m_bIsFollowComplete(false)
+{}
+
+void FollowerAI::AttackStart(Unit* pWho)
+{
+ if (!pWho)
+ return;
+
+ if (m_creature->Attack(pWho, true))
+ {
+ m_creature->AddThreat(pWho, 0.0f);
+ m_creature->SetInCombatWith(pWho);
+ pWho->SetInCombatWith(m_creature);
+
+ if (m_creature->hasUnitState(UNIT_STAT_FOLLOW))
+ m_creature->clearUnitState(UNIT_STAT_FOLLOW);
+
+ if (IsCombatMovement())
+ m_creature->GetMotionMaster()->MoveChase(pWho);
+ }
+}
+
+void FollowerAI::MoveInLineOfSight(Unit* pWho)
+{
+ if (!m_creature->hasUnitState(UNIT_STAT_STUNNED) && pWho->isTargetableForAttack() &&
+ m_creature->IsHostileTo(pWho) && pWho->isInAccessiblePlaceFor(m_creature))
+ {
+ if (!m_creature->canFly() && m_creature->GetDistanceZ(pWho) > CREATURE_Z_ATTACK_RANGE)
+ return;
+
+ //This part provides assistance to a player that are attacked by pWho, even if out of normal aggro range
+ //It will cause m_creature to attack pWho 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.
+ if (m_creature->hasUnitState(UNIT_STAT_FOLLOW) &&
+ m_creature->GetCreatureInfo()->type_flags & 0x01000 &&
+ pWho->getVictim() &&
+ pWho->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself() &&
+ m_creature->IsWithinDistInMap(pWho, MAX_PLAYER_DISTANCE) &&
+ m_creature->IsWithinLOSInMap(pWho))
+ {
+ pWho->RemoveAurasDueToSpell(SPELL_AURA_MOD_STEALTH);
+ AttackStart(pWho);
+ }
+ else
+ {
+ float attackRadius = m_creature->GetAttackDistance(pWho);
+ if (m_creature->IsWithinDistInMap(pWho, attackRadius) && m_creature->IsWithinLOSInMap(pWho))
+ {
+ if (!m_creature->getVictim())
+ {
+ pWho->RemoveAurasDueToSpell(SPELL_AURA_MOD_STEALTH);
+ AttackStart(pWho);
+ }
+ else if (m_creature->GetMap()->IsDungeon())
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
+ }
+ }
+ }
+}
+
+void FollowerAI::JustDied(Unit* pKiller)
+{
+ if (!m_bIsFollowing || !m_uiLeaderGUID)
+ return;
+
+ //TODO: need a better check for quests with time limit.
+ if (Player* pPlayer = GetLeaderForFollower())
+ {
+ if (Group* pGroup = pPlayer->GetGroup())
+ {
+ for(GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
+ {
+ if (Player* pMember = pRef->getSource())
+ {
+ if (pPlayer->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->FailQuest(m_pQuestForFollow->GetQuestId());
+ }
+ }
+ }
+ else
+ {
+ if (pPlayer->GetQuestStatus(m_pQuestForFollow->GetQuestId()) == QUEST_STATUS_INCOMPLETE)
+ pPlayer->FailQuest(m_pQuestForFollow->GetQuestId());
+ }
+ }
+}
+
+void FollowerAI::JustRespawned()
+{
+ m_bIsFollowing = false;
+ m_bIsReturnToLeader = false;
+ m_bIsFollowComplete = false;
+
+ if (!IsCombatMovement())
+ SetCombatMovement(true);
+
+ if (m_creature->getFaction() != m_creature->GetCreatureInfo()->faction_A)
+ m_creature->setFaction(m_creature->GetCreatureInfo()->faction_A);
+
+ Reset();
+}
+
+void FollowerAI::EnterEvadeMode()
+{
+ m_creature->RemoveAllAuras();
+ m_creature->DeleteThreatList();
+ m_creature->CombatStop(true);
+ m_creature->SetLootRecipient(NULL);
+
+ if (m_bIsFollowing)
+ {
+ debug_log("SD2: FollowerAI left combat, returning to CombatStartPosition.");
+
+ if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ {
+ float fPosX, fPosY, fPosZ;
+ m_creature->GetPosition(fPosX, fPosY, fPosZ);
+ m_creature->GetMotionMaster()->MovePoint(POINT_COMBAT_START, fPosX, fPosY, fPosZ);
+ }
+ }
+ else
+ {
+ if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ m_creature->GetMotionMaster()->MoveTargetedHome();
+ }
+
+ Reset();
+}
+
+void FollowerAI::UpdateAI(const uint32 uiDiff)
+{
+ if (m_bIsFollowing && !m_creature->getVictim())
+ {
+ if (m_uiUpdateFollowTimer < uiDiff)
+ {
+ if (m_bIsFollowComplete)
+ {
+ debug_log("SD2: FollowerAI is set completed, despawns.");
+ m_creature->ForcedDespawn();
+ return;
+ }
+
+ bool bIsMaxRangeExceeded = true;
+
+ if (Player* pPlayer = GetLeaderForFollower())
+ {
+ if (m_bIsReturnToLeader)
+ {
+ debug_log("SD2: FollowerAI is returning to leader.");
+ m_creature->GetMotionMaster()->MoveFollow(pPlayer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ m_bIsReturnToLeader = false;
+ return;
+ }
+
+ if (Group* pGroup = pPlayer->GetGroup())
+ {
+ for(GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
+ {
+ Player* pMember = pRef->getSource();
+
+ if (pMember && m_creature->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE))
+ {
+ bIsMaxRangeExceeded = false;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (m_creature->IsWithinDistInMap(pPlayer, MAX_PLAYER_DISTANCE))
+ bIsMaxRangeExceeded = false;
+ }
+ }
+
+ if (bIsMaxRangeExceeded)
+ {
+ debug_log("SD2: FollowerAI failed because player/group was to far away or not found");
+ m_creature->ForcedDespawn();
+ return;
+ }
+
+ m_uiUpdateFollowTimer = 1000;
+ }
+ else
+ m_uiUpdateFollowTimer -= uiDiff;
+ }
+
+ UpdateFollowerAI(uiDiff);
+}
+
+void FollowerAI::UpdateFollowerAI(const uint32 uiDiff)
+{
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+}
+
+void FollowerAI::MovementInform(uint32 uiMotionType, uint32 uiPointId)
+{
+ if (uiMotionType != POINT_MOTION_TYPE || !m_bIsFollowing)
+ return;
+
+ if (uiPointId == POINT_COMBAT_START)
+ {
+ if (GetLeaderForFollower())
+ m_bIsReturnToLeader = true;
+ else
+ m_creature->ForcedDespawn();
+ }
+}
+
+void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const Quest* pQuest)
+{
+ if (m_creature->getVictim())
+ {
+ debug_log("SD2: FollowerAI attempt to StartFollow while in combat.");
+ return;
+ }
+
+ if (m_bIsFollowing)
+ {
+ error_log("SD2: FollowerAI attempt to StartFollow while already following.");
+ return;
+ }
+
+ //set variables
+ m_uiLeaderGUID = pLeader->GetGUID();
+
+ if (uiFactionForFollower)
+ m_creature->setFaction(uiFactionForFollower);
+
+ m_pQuestForFollow = pQuest;
+
+ if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE)
+ {
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveIdle();
+ debug_log("SD2: FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle.");
+ }
+
+ m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
+
+ m_creature->GetMotionMaster()->MoveFollow(pLeader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+
+ m_bIsFollowing = true;
+
+ debug_log("SD2: FollowerAI start follow %s (GUID %u)", pLeader->GetName(), m_uiLeaderGUID);
+}
+
+Player* FollowerAI::GetLeaderForFollower()
+{
+ if (Player* pLeader = (Player*)Unit::GetUnit(*m_creature, m_uiLeaderGUID))
+ {
+ if (pLeader->isAlive())
+ return pLeader;
+ else
+ {
+ if (Group* pGroup = pLeader->GetGroup())
+ {
+ for(GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
+ {
+ Player* pMember = pRef->getSource();
+
+ if (pMember && pMember->isAlive() && m_creature->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE))
+ {
+ debug_log("SD2: FollowerAI GetLeader changed and returned new leader.");
+ m_uiLeaderGUID = pMember->GetGUID();
+ return pMember;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ debug_log("SD2: FollowerAI GetLeader can not find suitable leader.");
+ return NULL;
+}
diff --git a/src/bindings/scripts/base/follower_ai.h b/src/bindings/scripts/base/follower_ai.h
new file mode 100644
index 00000000000..d62980d4951
--- /dev/null
+++ b/src/bindings/scripts/base/follower_ai.h
@@ -0,0 +1,50 @@
+/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+ * This program is free software licensed under GPL version 2
+ * Please see the included DOCS/LICENSE.TXT for more information */
+
+#ifndef SC_FOLLOWERAI_H
+#define SC_FOLLOWERAI_H
+
+class TRINITY_DLL_DECL FollowerAI : public ScriptedAI
+{
+ public:
+ explicit FollowerAI(Creature* pCreature);
+ ~FollowerAI() {}
+
+ //virtual void WaypointReached(uint32 uiPointId) = 0;
+
+ void MovementInform(uint32 uiMotionType, uint32 uiPointId);
+
+ void AttackStart(Unit*);
+
+ void MoveInLineOfSight(Unit*);
+
+ void EnterEvadeMode();
+
+ void JustDied(Unit*);
+
+ void JustRespawned();
+
+ void UpdateAI(const uint32); //the "internal" update, calls UpdateFollowerAI()
+ virtual void UpdateFollowerAI(const uint32); //used when it's needed to add code in update (abilities, scripted events, etc)
+
+ void StartFollow(Player* pPlayer, uint32 uiFactionForFollower = 0, const Quest* pQuest = NULL);
+
+ protected:
+ void SetFollowComplete() { m_bIsFollowComplete = true; }
+ bool IsFollowComplete() { return m_bIsFollowComplete; }
+
+ Player* GetLeaderForFollower();
+
+ private:
+ uint64 m_uiLeaderGUID;
+ uint32 m_uiUpdateFollowTimer;
+
+ bool m_bIsFollowing;
+ bool m_bIsReturnToLeader;
+ bool m_bIsFollowComplete;
+
+ const Quest* m_pQuestForFollow; //normally we have a quest
+};
+
+#endif
diff --git a/src/bindings/scripts/base/guard_ai.cpp b/src/bindings/scripts/base/guard_ai.cpp
index 7f1daa1e2df..b55eae2dbad 100644
--- a/src/bindings/scripts/base/guard_ai.cpp
+++ b/src/bindings/scripts/base/guard_ai.cpp
@@ -32,6 +32,11 @@ EndScriptData */
#define SAY_GUARD_SIL_AGGRO2 -1070002
#define SAY_GUARD_SIL_AGGRO3 -1070003
+guardAI::guardAI(Creature* pCreature) : ScriptedAI(pCreature),
+ GlobalCooldown(0),
+ BuffTimer(0)
+{}
+
void guardAI::Reset()
{
GlobalCooldown = 0;
diff --git a/src/bindings/scripts/base/guard_ai.h b/src/bindings/scripts/base/guard_ai.h
index 85baa30fb9d..a7fff32e3ab 100644
--- a/src/bindings/scripts/base/guard_ai.h
+++ b/src/bindings/scripts/base/guard_ai.h
@@ -9,7 +9,9 @@
struct TRINITY_DLL_DECL guardAI : public ScriptedAI
{
- guardAI(Creature *c) : ScriptedAI(c) {}
+ public:
+ explicit guardAI(Creature* pCreature);
+ ~guardAI() {}
uint32 GlobalCooldown; //This variable acts like the global cooldown that players have (1.5 seconds)
uint32 BuffTimer; //This variable keeps track of buffs