aboutsummaryrefslogtreecommitdiff
path: root/src/bindings/scripts/base
diff options
context:
space:
mode:
authorKudlaty <none@none>2009-08-20 18:50:41 +0200
committerKudlaty <none@none>2009-08-20 18:50:41 +0200
commitf27fc3e939fb62a6468c91ac87e61b2dcdb4cac3 (patch)
tree63c01b915507c76a3c9a7db0feb3d77ae0975d4d /src/bindings/scripts/base
parentc674463df46244762e1de2197604fde54d855c1c (diff)
Merge [SD2]
r1355 Implement use of bitmask states instead of boolean variables in followerAI. Add function SetFollowPaused to temporary disable follow, with true/false argument to toggle the state on/off. Scripts affected are updated accordingly with needed changes. --HG-- branch : trunk
Diffstat (limited to 'src/bindings/scripts/base')
-rw-r--r--src/bindings/scripts/base/follower_ai.cpp92
-rw-r--r--src/bindings/scripts/base/follower_ai.h25
2 files changed, 85 insertions, 32 deletions
diff --git a/src/bindings/scripts/base/follower_ai.cpp b/src/bindings/scripts/base/follower_ai.cpp
index b44b22a31be..9f362cc67af 100644
--- a/src/bindings/scripts/base/follower_ai.cpp
+++ b/src/bindings/scripts/base/follower_ai.cpp
@@ -23,10 +23,7 @@ FollowerAI::FollowerAI(Creature* pCreature) : ScriptedAI(pCreature),
m_uiLeaderGUID(0),
m_pQuestForFollow(NULL),
m_uiUpdateFollowTimer(2500),
- m_bIsFollowing(false),
- m_bIsReturnToLeader(false),
- m_bIsFollowComplete(false),
- m_bIsEndEvent(false)
+ m_uiFollowState(STATE_FOLLOW_NONE)
{}
void FollowerAI::AttackStart(Unit* pWho)
@@ -60,14 +57,21 @@ void FollowerAI::MoveInLineOfSight(Unit* pWho)
//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 &&
+ m_creature->GetCreatureInfo()->type_flags & CREATURE_TYPEFLAGS_UNK13 &&
pWho->getVictim() &&
pWho->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself() &&
m_creature->IsWithinDistInMap(pWho, MAX_PLAYER_DISTANCE) &&
m_creature->IsWithinLOSInMap(pWho))
{
- pWho->RemoveAurasDueToSpell(SPELL_AURA_MOD_STEALTH);
- AttackStart(pWho);
+ if (!m_creature->getVictim())
+ {
+ AttackStart(pWho);
+ }
+ else
+ {
+ pWho->SetInCombatWith(m_creature);
+ m_creature->AddThreat(pWho, 0.0f);
+ }
}
else
{
@@ -91,7 +95,7 @@ void FollowerAI::MoveInLineOfSight(Unit* pWho)
void FollowerAI::JustDied(Unit* pKiller)
{
- if (!m_bIsFollowing || !m_uiLeaderGUID || !m_pQuestForFollow)
+ if (!HasFollowState(STATE_FOLLOW_INPROGRESS) || !m_uiLeaderGUID || !m_pQuestForFollow)
return;
//TODO: need a better check for quests with time limit.
@@ -118,10 +122,7 @@ void FollowerAI::JustDied(Unit* pKiller)
void FollowerAI::JustRespawned()
{
- m_bIsFollowing = false;
- m_bIsReturnToLeader = false;
- m_bIsFollowComplete = false;
- m_bIsEndEvent = false;
+ m_uiFollowState = STATE_FOLLOW_NONE;
if (!IsCombatMovement())
SetCombatMovement(true);
@@ -139,7 +140,7 @@ void FollowerAI::EnterEvadeMode()
m_creature->CombatStop(true);
m_creature->SetLootRecipient(NULL);
- if (m_bIsFollowing)
+ if (HasFollowState(STATE_FOLLOW_INPROGRESS))
{
debug_log("TSCR: FollowerAI left combat, returning to CombatStartPosition.");
@@ -161,11 +162,13 @@ void FollowerAI::EnterEvadeMode()
void FollowerAI::UpdateAI(const uint32 uiDiff)
{
- if (m_bIsFollowing && !m_creature->getVictim())
+ Unit* pUnit = m_creature->getVictim();
+
+ if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !m_creature->getVictim())
{
if (m_uiUpdateFollowTimer < uiDiff)
{
- if (m_bIsFollowComplete && !m_bIsEndEvent)
+ if (HasFollowState(STATE_FOLLOW_COMPLETE) && !HasFollowState(STATE_FOLLOW_POSTEVENT))
{
debug_log("TSCR: FollowerAI is set completed, despawns.");
m_creature->ForcedDespawn();
@@ -176,11 +179,12 @@ void FollowerAI::UpdateAI(const uint32 uiDiff)
if (Player* pPlayer = GetLeaderForFollower())
{
- if (m_bIsReturnToLeader)
+ if (HasFollowState(STATE_FOLLOW_RETURNING))
{
debug_log("TSCR: FollowerAI is returning to leader.");
+
+ RemoveFollowState(STATE_FOLLOW_RETURNING);
m_creature->GetMotionMaster()->MoveFollow(pPlayer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
- m_bIsReturnToLeader = false;
return;
}
@@ -230,13 +234,16 @@ void FollowerAI::UpdateFollowerAI(const uint32 uiDiff)
void FollowerAI::MovementInform(uint32 uiMotionType, uint32 uiPointId)
{
- if (uiMotionType != POINT_MOTION_TYPE || !m_bIsFollowing)
+ if (uiMotionType != POINT_MOTION_TYPE || !HasFollowState(STATE_FOLLOW_INPROGRESS))
return;
if (uiPointId == POINT_COMBAT_START)
{
if (GetLeaderForFollower())
- m_bIsReturnToLeader = true;
+ {
+ if (!HasFollowState(STATE_FOLLOW_PAUSED))
+ AddFollowState(STATE_FOLLOW_RETURNING);
+ }
else
m_creature->ForcedDespawn();
}
@@ -250,7 +257,7 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const
return;
}
- if (m_bIsFollowing)
+ if (HasFollowState(STATE_FOLLOW_INPROGRESS))
{
error_log("TSCR: FollowerAI attempt to StartFollow while already following.");
return;
@@ -273,9 +280,9 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
- m_creature->GetMotionMaster()->MoveFollow(pLeader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ AddFollowState(STATE_FOLLOW_INPROGRESS);
- m_bIsFollowing = true;
+ m_creature->GetMotionMaster()->MoveFollow(pLeader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
debug_log("TSCR: FollowerAI start follow %s (GUID %u)", pLeader->GetName(), m_uiLeaderGUID);
}
@@ -316,10 +323,45 @@ void FollowerAI::SetFollowComplete(bool bWithEndEvent)
{
m_creature->clearUnitState(UNIT_STAT_FOLLOW);
- m_creature->GetMotionMaster()->MovementExpired();
+ m_creature->StopMoving();
+ m_creature->GetMotionMaster()->Clear();
m_creature->GetMotionMaster()->MoveIdle();
}
- m_bIsEndEvent = bWithEndEvent;
- m_bIsFollowComplete = true;
+ if (bWithEndEvent)
+ AddFollowState(STATE_FOLLOW_POSTEVENT);
+ else
+ {
+ if (HasFollowState(STATE_FOLLOW_POSTEVENT))
+ RemoveFollowState(STATE_FOLLOW_POSTEVENT);
+ }
+
+ AddFollowState(STATE_FOLLOW_COMPLETE);
+}
+
+void FollowerAI::SetFollowPaused(bool bPaused)
+{
+ if (!HasFollowState(STATE_FOLLOW_INPROGRESS) || HasFollowState(STATE_FOLLOW_COMPLETE))
+ return;
+
+ if (bPaused)
+ {
+ AddFollowState(STATE_FOLLOW_PAUSED);
+
+ if (m_creature->hasUnitState(UNIT_STAT_FOLLOW))
+ {
+ m_creature->clearUnitState(UNIT_STAT_FOLLOW);
+
+ m_creature->StopMoving();
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MoveIdle();
+ }
+ }
+ else
+ {
+ RemoveFollowState(STATE_FOLLOW_PAUSED);
+
+ if (Player* pLeader = GetLeaderForFollower())
+ m_creature->GetMotionMaster()->MoveFollow(pLeader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
+ }
}
diff --git a/src/bindings/scripts/base/follower_ai.h b/src/bindings/scripts/base/follower_ai.h
index 10ec5c9061e..1513cd4c49c 100644
--- a/src/bindings/scripts/base/follower_ai.h
+++ b/src/bindings/scripts/base/follower_ai.h
@@ -5,6 +5,17 @@
#ifndef SC_FOLLOWERAI_H
#define SC_FOLLOWERAI_H
+enum eFollowState
+{
+ STATE_FOLLOW_NONE = 0x000,
+ STATE_FOLLOW_INPROGRESS = 0x001, //must always have this state for any follow
+ STATE_FOLLOW_RETURNING = 0x002, //when returning to combat start after being in combat
+ STATE_FOLLOW_PAUSED = 0x004, //disables following
+ STATE_FOLLOW_COMPLETE = 0x008, //follow is completed and may end
+ STATE_FOLLOW_PREEVENT = 0x010, //not implemented (allow pre event to run, before follow is initiated)
+ STATE_FOLLOW_POSTEVENT = 0x020 //can be set at complete and allow post event to run
+};
+
class TRINITY_DLL_DECL FollowerAI : public ScriptedAI
{
public:
@@ -30,21 +41,21 @@ class TRINITY_DLL_DECL FollowerAI : public ScriptedAI
void StartFollow(Player* pPlayer, uint32 uiFactionForFollower = 0, const Quest* pQuest = NULL);
+ void SetFollowPaused(bool bPaused); //if special event require follow mode to hold/resume during the follow
+
protected:
+ bool HasFollowState(uint32 uiFollowState) { return (m_uiFollowState & uiFollowState); }
+ void AddFollowState(uint32 uiFollowState) { m_uiFollowState |= uiFollowState; }
+ void RemoveFollowState(uint32 uiFollowState) { m_uiFollowState &= ~uiFollowState; }
+
void SetFollowComplete(bool bWithEndEvent = false);
- bool IsFollowComplete() { return m_bIsFollowComplete; }
- bool IsEndEventInProgress() { return m_bIsEndEvent; }
Player* GetLeaderForFollower();
private:
uint64 m_uiLeaderGUID;
uint32 m_uiUpdateFollowTimer;
-
- bool m_bIsFollowing;
- bool m_bIsReturnToLeader;
- bool m_bIsFollowComplete;
- bool m_bIsEndEvent;
+ uint32 m_uiFollowState;
const Quest* m_pQuestForFollow; //normally we have a quest
};