Merge [SD2]
r1346 Convert script for quest 2078 to use followerAI r1347 Use spell to summon friends instead of manual summon in script for quest 1249. r1348 Extend followerAI function SetFollowComplete with argument to simplify implementation of end events in scripts. r1349 Convert script related to quest 1560 to use followerAI r1350 Apply SD2 code style to one instance and boss script - skip r1351 Add basic support for quest 4491. r1352 Add basic support for quest 5321 r1353 Adjust way to complete quest, for script related to quest 938 --HG-- branch : trunk
This commit is contained in:
@@ -25,7 +25,8 @@ FollowerAI::FollowerAI(Creature* pCreature) : ScriptedAI(pCreature),
|
||||
m_uiUpdateFollowTimer(2500),
|
||||
m_bIsFollowing(false),
|
||||
m_bIsReturnToLeader(false),
|
||||
m_bIsFollowComplete(false)
|
||||
m_bIsFollowComplete(false),
|
||||
m_bIsEndEvent(false)
|
||||
{}
|
||||
|
||||
void FollowerAI::AttackStart(Unit* pWho)
|
||||
@@ -120,6 +121,7 @@ void FollowerAI::JustRespawned()
|
||||
m_bIsFollowing = false;
|
||||
m_bIsReturnToLeader = false;
|
||||
m_bIsFollowComplete = false;
|
||||
m_bIsEndEvent = false;
|
||||
|
||||
if (!IsCombatMovement())
|
||||
SetCombatMovement(true);
|
||||
@@ -139,7 +141,7 @@ void FollowerAI::EnterEvadeMode()
|
||||
|
||||
if (m_bIsFollowing)
|
||||
{
|
||||
debug_log("SD2: FollowerAI left combat, returning to CombatStartPosition.");
|
||||
debug_log("TSCR: FollowerAI left combat, returning to CombatStartPosition.");
|
||||
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
{
|
||||
@@ -163,9 +165,9 @@ void FollowerAI::UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
if (m_uiUpdateFollowTimer < uiDiff)
|
||||
{
|
||||
if (m_bIsFollowComplete)
|
||||
if (m_bIsFollowComplete && !m_bIsEndEvent)
|
||||
{
|
||||
debug_log("SD2: FollowerAI is set completed, despawns.");
|
||||
debug_log("TSCR: FollowerAI is set completed, despawns.");
|
||||
m_creature->ForcedDespawn();
|
||||
return;
|
||||
}
|
||||
@@ -176,7 +178,7 @@ void FollowerAI::UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
if (m_bIsReturnToLeader)
|
||||
{
|
||||
debug_log("SD2: FollowerAI is returning to leader.");
|
||||
debug_log("TSCR: FollowerAI is returning to leader.");
|
||||
m_creature->GetMotionMaster()->MoveFollow(pPlayer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
m_bIsReturnToLeader = false;
|
||||
return;
|
||||
@@ -204,7 +206,7 @@ void FollowerAI::UpdateAI(const uint32 uiDiff)
|
||||
|
||||
if (bIsMaxRangeExceeded)
|
||||
{
|
||||
debug_log("SD2: FollowerAI failed because player/group was to far away or not found");
|
||||
debug_log("TSCR: FollowerAI failed because player/group was to far away or not found");
|
||||
m_creature->ForcedDespawn();
|
||||
return;
|
||||
}
|
||||
@@ -244,13 +246,13 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
{
|
||||
debug_log("SD2: FollowerAI attempt to StartFollow while in combat.");
|
||||
debug_log("TSCR: FollowerAI attempt to StartFollow while in combat.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_bIsFollowing)
|
||||
{
|
||||
error_log("SD2: FollowerAI attempt to StartFollow while already following.");
|
||||
error_log("TSCR: FollowerAI attempt to StartFollow while already following.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -266,7 +268,7 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const
|
||||
{
|
||||
m_creature->GetMotionMaster()->Clear();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
debug_log("SD2: FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle.");
|
||||
debug_log("TSCR: FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle.");
|
||||
}
|
||||
|
||||
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
@@ -275,7 +277,7 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const
|
||||
|
||||
m_bIsFollowing = true;
|
||||
|
||||
debug_log("SD2: FollowerAI start follow %s (GUID %u)", pLeader->GetName(), m_uiLeaderGUID);
|
||||
debug_log("TSCR: FollowerAI start follow %s (GUID %u)", pLeader->GetName(), m_uiLeaderGUID);
|
||||
}
|
||||
|
||||
Player* FollowerAI::GetLeaderForFollower()
|
||||
@@ -294,7 +296,7 @@ Player* FollowerAI::GetLeaderForFollower()
|
||||
|
||||
if (pMember && pMember->isAlive() && m_creature->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE))
|
||||
{
|
||||
debug_log("SD2: FollowerAI GetLeader changed and returned new leader.");
|
||||
debug_log("TSCR: FollowerAI GetLeader changed and returned new leader.");
|
||||
m_uiLeaderGUID = pMember->GetGUID();
|
||||
return pMember;
|
||||
break;
|
||||
@@ -304,6 +306,20 @@ Player* FollowerAI::GetLeaderForFollower()
|
||||
}
|
||||
}
|
||||
|
||||
debug_log("SD2: FollowerAI GetLeader can not find suitable leader.");
|
||||
debug_log("TSCR: FollowerAI GetLeader can not find suitable leader.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FollowerAI::SetFollowComplete(bool bWithEndEvent)
|
||||
{
|
||||
if (m_creature->hasUnitState(UNIT_STAT_FOLLOW))
|
||||
{
|
||||
m_creature->clearUnitState(UNIT_STAT_FOLLOW);
|
||||
|
||||
m_creature->GetMotionMaster()->MovementExpired();
|
||||
m_creature->GetMotionMaster()->MoveIdle();
|
||||
}
|
||||
|
||||
m_bIsEndEvent = bWithEndEvent;
|
||||
m_bIsFollowComplete = true;
|
||||
}
|
||||
|
||||
@@ -31,8 +31,9 @@ class TRINITY_DLL_DECL FollowerAI : public ScriptedAI
|
||||
void StartFollow(Player* pPlayer, uint32 uiFactionForFollower = 0, const Quest* pQuest = NULL);
|
||||
|
||||
protected:
|
||||
void SetFollowComplete() { m_bIsFollowComplete = true; }
|
||||
void SetFollowComplete(bool bWithEndEvent = false);
|
||||
bool IsFollowComplete() { return m_bIsFollowComplete; }
|
||||
bool IsEndEventInProgress() { return m_bIsEndEvent; }
|
||||
|
||||
Player* GetLeaderForFollower();
|
||||
|
||||
@@ -43,6 +44,7 @@ class TRINITY_DLL_DECL FollowerAI : public ScriptedAI
|
||||
bool m_bIsFollowing;
|
||||
bool m_bIsReturnToLeader;
|
||||
bool m_bIsFollowComplete;
|
||||
bool m_bIsEndEvent;
|
||||
|
||||
const Quest* m_pQuestForFollow; //normally we have a quest
|
||||
};
|
||||
|
||||
@@ -38,6 +38,7 @@ enum
|
||||
QUEST_MISSING_DIPLO_PT11 = 1249,
|
||||
FACTION_ENEMY = 168,
|
||||
SPELL_STEALTH = 1785,
|
||||
SPELL_CALL_FRIENDS = 16457, //summons 1x friend
|
||||
NPC_SLIMS_FRIEND = 4971,
|
||||
NPC_TAPOKE_SLIM_JAHN = 4962
|
||||
};
|
||||
@@ -74,9 +75,9 @@ struct TRINITY_DLL_DECL npc_tapoke_slim_jahnAI : public npc_escortAI
|
||||
|
||||
if (IsBeingEscorted && !m_bFriendSummoned && pPlayer)
|
||||
{
|
||||
m_creature->SummonCreature(NPC_SLIMS_FRIEND, 0.0f, 0.0f, 0.0f, 3.10f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
m_creature->SummonCreature(NPC_SLIMS_FRIEND, 0.0f, 0.0f, 0.0f, 2.35f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
m_creature->SummonCreature(NPC_SLIMS_FRIEND, 0.0f, 0.0f, 0.0f, 2.02f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
for(uint8 i = 0; i < 3; ++i)
|
||||
m_creature->CastSpell(m_creature, SPELL_CALL_FRIENDS, true);
|
||||
|
||||
m_bFriendSummoned = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,17 +17,98 @@
|
||||
/* ScriptData
|
||||
SDName: Darkshore
|
||||
SD%Complete: 100
|
||||
SDComment: Quest support: 731, 2078
|
||||
SDComment: Quest support: 731, 2078, 5321
|
||||
SDCategory: Darkshore
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_kerlonian
|
||||
npc_prospector_remtravel
|
||||
npc_threshwackonator
|
||||
EndContentData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "escort_ai.h"
|
||||
#include "follower_ai.h"
|
||||
|
||||
/*####
|
||||
# npc_kerlonian
|
||||
####*/
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_KER_START = -1000434,
|
||||
|
||||
EMOTE_KER_SLEEP_1 = -1000435,
|
||||
EMOTE_KER_SLEEP_2 = -1000436,
|
||||
EMOTE_KER_SLEEP_3 = -1000437,
|
||||
|
||||
SAY_KER_SLEEP_1 = -1000438,
|
||||
SAY_KER_SLEEP_2 = -1000439,
|
||||
SAY_KER_SLEEP_3 = -1000440,
|
||||
SAY_KER_SLEEP_4 = -1000441,
|
||||
|
||||
SAY_KER_ALERT_1 = -1000442,
|
||||
SAY_KER_ALERT_2 = -1000443,
|
||||
|
||||
SAY_KER_END = -1000444,
|
||||
|
||||
SPELL_AWAKEN = 17536,
|
||||
QUEST_SLEEPER_AWAKENED = 5321,
|
||||
NPC_LILADRIS = 11219, //attackers entries unknown
|
||||
FACTION_KER_ESCORTEE = 113
|
||||
};
|
||||
|
||||
//TODO: make concept similar as "ringo" -escort. Find a way to run the scripted attacks, _if_ player are choosing road.
|
||||
struct TRINITY_DLL_DECL npc_kerlonianAI : public FollowerAI
|
||||
{
|
||||
npc_kerlonianAI(Creature* pCreature) : FollowerAI(pCreature) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *pWho)
|
||||
{
|
||||
FollowerAI::MoveInLineOfSight(pWho);
|
||||
|
||||
if (!m_creature->getVictim() && !IsFollowComplete() && pWho->GetEntry() == NPC_LILADRIS)
|
||||
{
|
||||
if (m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE*2))
|
||||
{
|
||||
if (Player* pPlayer = GetLeaderForFollower())
|
||||
{
|
||||
if (pPlayer->GetQuestStatus(QUEST_SLEEPER_AWAKENED) == QUEST_STATUS_INCOMPLETE)
|
||||
pPlayer->GroupEventHappens(QUEST_SLEEPER_AWAKENED, m_creature);
|
||||
|
||||
DoScriptText(SAY_KER_END, m_creature);
|
||||
}
|
||||
|
||||
SetFollowComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_kerlonian(Creature* pCreature)
|
||||
{
|
||||
return new npc_kerlonianAI(pCreature);
|
||||
}
|
||||
|
||||
bool QuestAccept_npc_kerlonian(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
|
||||
{
|
||||
if (pQuest->GetQuestId() == QUEST_SLEEPER_AWAKENED)
|
||||
{
|
||||
if (npc_kerlonianAI* pKerlonianAI = CAST_AI(npc_kerlonianAI, pCreature->AI()))
|
||||
{
|
||||
pCreature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
DoScriptText(SAY_KER_START, pCreature);
|
||||
pKerlonianAI->StartFollow(pPlayer, FACTION_KER_ESCORTEE, pQuest);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*####
|
||||
# npc_prospector_remtravel
|
||||
@@ -171,124 +252,34 @@ enum
|
||||
|
||||
#define GOSSIP_ITEM_INSERT_KEY "[PH] Insert key"
|
||||
|
||||
struct TRINITY_DLL_DECL npc_threshwackonatorAI : public ScriptedAI
|
||||
struct TRINITY_DLL_DECL npc_threshwackonatorAI : public FollowerAI
|
||||
{
|
||||
npc_threshwackonatorAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
npc_threshwackonatorAI(Creature* pCreature) : FollowerAI(pCreature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void MoveInLineOfSight(Unit* pWho)
|
||||
{
|
||||
Faction = pCreature->getFaction();
|
||||
NpcFlags = pCreature->GetUInt32Value(UNIT_NPC_FLAGS);
|
||||
PlayerGUID = 0;
|
||||
}
|
||||
FollowerAI::MoveInLineOfSight(pWho);
|
||||
|
||||
uint64 PlayerGUID;
|
||||
uint32 Faction;
|
||||
uint32 NpcFlags;
|
||||
uint32 CheckPlayerTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
CheckPlayerTimer = 2500;
|
||||
|
||||
if (!PlayerGUID)
|
||||
if (!m_creature->getVictim() && !IsFollowComplete() && pWho->GetEntry() == NPC_GELKAK)
|
||||
{
|
||||
me->setFaction(Faction);
|
||||
me->SetUInt32Value(UNIT_NPC_FLAGS, NpcFlags);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetEntry() == NPC_GELKAK)
|
||||
{
|
||||
if (PlayerGUID && me->IsWithinDistInMap(who, 10.0f))
|
||||
if (m_creature->IsWithinDistInMap(pWho, 10.0f))
|
||||
{
|
||||
DoScriptText(SAY_AT_CLOSE, who);
|
||||
DoScriptText(SAY_AT_CLOSE, pWho);
|
||||
DoAtEnd();
|
||||
}
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->DeleteThreatList();
|
||||
me->CombatStop(true);
|
||||
me->LoadCreaturesAddon();
|
||||
|
||||
if (me->isAlive())
|
||||
{
|
||||
if (Player* pPlayer = Unit::GetPlayer(PlayerGUID))
|
||||
me->GetMotionMaster()->MoveFollow(pPlayer, PET_FOLLOW_DIST, m_creature->GetFollowAngle());
|
||||
else
|
||||
{
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
}
|
||||
|
||||
me->SetLootRecipient(NULL);
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void DoStart(uint64 Starter)
|
||||
{
|
||||
PlayerGUID = Starter;
|
||||
me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
|
||||
if (Player* pPlayer = Unit::GetPlayer(PlayerGUID))
|
||||
me->GetMotionMaster()->MoveFollow(pPlayer, PET_FOLLOW_DIST, m_creature->GetFollowAngle());
|
||||
|
||||
DoScriptText(EMOTE_START, me);
|
||||
}
|
||||
|
||||
void DoAtEnd()
|
||||
{
|
||||
me->setFaction(FACTION_HOSTILE);
|
||||
|
||||
if (Player* pHolder = Unit::GetPlayer(PlayerGUID))
|
||||
if (Player* pHolder = GetLeaderForFollower())
|
||||
me->AI()->AttackStart(pHolder);
|
||||
|
||||
PlayerGUID = 0;
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller)
|
||||
{
|
||||
if (PlayerGUID)
|
||||
{
|
||||
PlayerGUID = 0;
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (PlayerGUID)
|
||||
{
|
||||
if (!me->isInCombat())
|
||||
{
|
||||
if (CheckPlayerTimer < diff)
|
||||
{
|
||||
CheckPlayerTimer = 5000;
|
||||
|
||||
Player* pPlayer = Unit::GetPlayer(PlayerGUID);
|
||||
|
||||
if (pPlayer && !pPlayer->isAlive())
|
||||
{
|
||||
PlayerGUID = 0;
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
}else CheckPlayerTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
SetFollowComplete();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -310,8 +301,13 @@ bool GossipSelect_npc_threshwackonator(Player* pPlayer, Creature* pCreature, uin
|
||||
{
|
||||
if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
|
||||
{
|
||||
CAST_AI(npc_threshwackonatorAI, pCreature->AI())->DoStart(pPlayer->GetGUID());
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
|
||||
if (npc_threshwackonatorAI* pThreshAI = CAST_AI(npc_threshwackonatorAI, pCreature->AI()))
|
||||
{
|
||||
DoScriptText(EMOTE_START, pCreature);
|
||||
pThreshAI->StartFollow(pPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -321,6 +317,12 @@ void AddSC_darkshore()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "npc_kerlonian";
|
||||
newscript->GetAI = &GetAI_npc_kerlonian;
|
||||
newscript->pQuestAccept = &QuestAccept_npc_kerlonian;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "npc_prospector_remtravel";
|
||||
newscript->GetAI = &GetAI_npc_prospector_remtravel;
|
||||
|
||||
@@ -33,6 +33,7 @@ EndContentData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "escort_ai.h"
|
||||
#include "follower_ai.h"
|
||||
|
||||
/*######
|
||||
## mob_aquementas
|
||||
@@ -455,18 +456,11 @@ enum
|
||||
|
||||
const float m_afToWaterLoc[] = {-7032.664551, -4906.199219, -1.606446};
|
||||
|
||||
//Script not fully complete, need to change faction.
|
||||
struct MANGOS_DLL_DECL npc_toogaAI : public ScriptedAI
|
||||
struct TRINITY_DLL_DECL npc_toogaAI : public FollowerAI
|
||||
{
|
||||
npc_toogaAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_uiNpcFlags = pCreature->GetUInt32Value(UNIT_NPC_FLAGS);
|
||||
m_uiPlayerGUID = 0;
|
||||
}
|
||||
npc_toogaAI(Creature* pCreature) : FollowerAI(pCreature) { }
|
||||
|
||||
uint64 m_uiPlayerGUID;
|
||||
uint32 m_uiNpcFlags;
|
||||
uint32 m_uiCheckPlayerTimer;
|
||||
uint32 m_uiCheckSpeechTimer;
|
||||
uint32 m_uiPostEventTimer;
|
||||
uint32 m_uiPhasePostEvent;
|
||||
|
||||
@@ -474,8 +468,8 @@ struct MANGOS_DLL_DECL npc_toogaAI : public ScriptedAI
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_uiCheckPlayerTimer = 2500;
|
||||
m_uiPostEventTimer = 5000;
|
||||
m_uiCheckSpeechTimer = 2500;
|
||||
m_uiPostEventTimer = 1000;
|
||||
m_uiPhasePostEvent = 0;
|
||||
|
||||
pTorta = NULL;
|
||||
@@ -483,135 +477,41 @@ struct MANGOS_DLL_DECL npc_toogaAI : public ScriptedAI
|
||||
|
||||
void MoveInLineOfSight(Unit *pWho)
|
||||
{
|
||||
if (pWho->GetEntry() == NPC_TORTA)
|
||||
FollowerAI::MoveInLineOfSight(pWho);
|
||||
|
||||
if (!m_creature->getVictim() && !IsFollowComplete() && !IsEndEventInProgress() && pWho->GetEntry() == NPC_TORTA)
|
||||
{
|
||||
if (m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE))
|
||||
{
|
||||
if (!pTorta && CanDoComplete())
|
||||
if (Player* pPlayer = GetLeaderForFollower())
|
||||
{
|
||||
pTorta = pWho;
|
||||
m_uiPhasePostEvent = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void 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 EnterEvadeMode()
|
||||
{
|
||||
m_creature->RemoveAllAuras();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop(true);
|
||||
m_creature->LoadCreaturesAddon();
|
||||
|
||||
if (m_creature->isAlive())
|
||||
{
|
||||
if (Unit* pUnit = Unit::GetUnit(*m_creature, m_uiPlayerGUID))
|
||||
{
|
||||
//for later development, it appear this kind return to combatStart, then resume to MoveFollow
|
||||
m_creature->GetMotionMaster()->MoveFollow(pUnit, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_creature->hasUnitState(UNIT_STAT_FOLLOW))
|
||||
m_creature->clearUnitState(UNIT_STAT_FOLLOW);
|
||||
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
}
|
||||
|
||||
m_creature->SetLootRecipient(NULL);
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void JustRespawned()
|
||||
{
|
||||
me->RestoreFaction();
|
||||
|
||||
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, m_creature->GetCreatureInfo()->npcflag);
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void DoStart(Player* pPlayer)
|
||||
{
|
||||
m_uiPlayerGUID = pPlayer->GetGUID();
|
||||
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
|
||||
m_creature->setFaction(FACTION_TOOG_ESCORTEE);
|
||||
|
||||
m_creature->GetMotionMaster()->MoveFollow(pPlayer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
|
||||
}
|
||||
|
||||
bool CanDoComplete()
|
||||
{
|
||||
if (Player* pPlayer = (Player*)Unit::GetUnit(*m_creature, m_uiPlayerGUID))
|
||||
{
|
||||
if (pPlayer->GetQuestStatus(QUEST_TOOGA) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
uint16 uiQuestLogSlot = pPlayer->FindQuestSlot(QUEST_TOOGA);
|
||||
|
||||
if (uiQuestLogSlot < MAX_QUEST_LOG_SIZE)
|
||||
{
|
||||
if (pPlayer->GetQuestSlotState(uiQuestLogSlot) != QUEST_STATE_FAIL)
|
||||
{
|
||||
if (pPlayer->GetQuestStatus(QUEST_TOOGA) == QUEST_STATUS_INCOMPLETE)
|
||||
pPlayer->GroupEventHappens(QUEST_TOOGA, m_creature);
|
||||
m_creature->GetMotionMaster()->MovementExpired();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
pTorta = pWho;
|
||||
SetFollowComplete(true);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MovementInform(uint32 uiMoveType, uint32 uiPointId)
|
||||
void MovementInform(uint32 uiMotionType, uint32 uiPointId)
|
||||
{
|
||||
if (uiMoveType != POINT_MOTION_TYPE || !m_uiPlayerGUID)
|
||||
FollowerAI::MovementInform(uiMotionType, uiPointId);
|
||||
|
||||
if (uiMotionType != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (uiPointId == POINT_ID_TO_WATER)
|
||||
m_creature->ForcedDespawn();
|
||||
SetFollowComplete();
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller)
|
||||
{
|
||||
if (Player* pPlayer = Unit::GetPlayer(m_uiPlayerGUID))
|
||||
{
|
||||
if (pPlayer->GetQuestStatus(QUEST_TOOGA) == QUEST_STATUS_INCOMPLETE)
|
||||
pPlayer->FailQuest(QUEST_TOOGA);
|
||||
}
|
||||
|
||||
m_uiPlayerGUID = 0;
|
||||
m_creature->GetMotionMaster()->MovementExpired();
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff)
|
||||
void UpdateFollowerAI(const uint32 uiDiff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
//we are doing the post-event, or...
|
||||
if (m_uiPhasePostEvent)
|
||||
if (IsEndEventInProgress())
|
||||
{
|
||||
if (m_uiPostEventTimer < uiDiff)
|
||||
{
|
||||
@@ -619,8 +519,8 @@ struct MANGOS_DLL_DECL npc_toogaAI : public ScriptedAI
|
||||
|
||||
if (!pTorta || !pTorta->isAlive())
|
||||
{
|
||||
//something happened, so just despawn (what can go wrong?)
|
||||
m_creature->ForcedDespawn();
|
||||
//something happened, so just complete
|
||||
SetFollowComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -643,7 +543,6 @@ struct MANGOS_DLL_DECL npc_toogaAI : public ScriptedAI
|
||||
break;
|
||||
case 6:
|
||||
DoScriptText(SAY_TORT_POST_6, pTorta);
|
||||
m_creature->GetMotionMaster()->MovementExpired();
|
||||
m_creature->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, m_afToWaterLoc[0], m_afToWaterLoc[1], m_afToWaterLoc[2]);
|
||||
break;
|
||||
}
|
||||
@@ -653,29 +552,21 @@ struct MANGOS_DLL_DECL npc_toogaAI : public ScriptedAI
|
||||
else
|
||||
m_uiPostEventTimer -= uiDiff;
|
||||
}
|
||||
//...we are doing regular player check
|
||||
else if (m_uiPlayerGUID)
|
||||
//...we are doing regular speech check
|
||||
else if (!IsFollowComplete())
|
||||
{
|
||||
if (m_uiCheckPlayerTimer < uiDiff)
|
||||
if (m_uiCheckSpeechTimer < uiDiff)
|
||||
{
|
||||
m_uiCheckPlayerTimer = 5000;
|
||||
m_uiCheckSpeechTimer = 5000;
|
||||
|
||||
switch(rand()%50)
|
||||
{
|
||||
case 10: DoScriptText(SAY_TOOG_THIRST, m_creature); break;
|
||||
case 25: DoScriptText(SAY_TOOG_WORRIED, m_creature); break;
|
||||
}
|
||||
|
||||
Unit* pUnit = Unit::GetUnit(*m_creature, m_uiPlayerGUID);
|
||||
|
||||
if (pUnit && !pUnit->isAlive())
|
||||
{
|
||||
m_uiPlayerGUID = 0;
|
||||
m_creature->ForcedDespawn();
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiCheckPlayerTimer -= uiDiff;
|
||||
m_uiCheckSpeechTimer -= uiDiff;
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -695,7 +586,7 @@ bool QuestAccept_npc_tooga(Player* pPlayer, Creature* pCreature, const Quest* pQ
|
||||
if (pQuest->GetQuestId() == QUEST_TOOGA)
|
||||
{
|
||||
if (npc_toogaAI* pToogaAI = CAST_AI(npc_toogaAI, pCreature->AI()))
|
||||
pToogaAI->DoStart(pPlayer);
|
||||
pToogaAI->StartFollow(pPlayer, FACTION_TOOG_ESCORTEE, pQuest);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -68,19 +68,10 @@ struct TRINITY_DLL_DECL npc_mistAI : public FollowerAI
|
||||
if (Player* pPlayer = GetLeaderForFollower())
|
||||
{
|
||||
if (pPlayer->GetQuestStatus(QUEST_MIST) == QUEST_STATUS_INCOMPLETE)
|
||||
{
|
||||
uint16 uiQuestLogSlot = pPlayer->FindQuestSlot(QUEST_MIST);
|
||||
|
||||
if (uiQuestLogSlot < MAX_QUEST_LOG_SIZE)
|
||||
{
|
||||
//This will be wrong, need to check all group members (if any) for state before event
|
||||
if (pPlayer->GetQuestSlotState(uiQuestLogSlot) != QUEST_STATE_FAIL)
|
||||
pPlayer->AreaExploredOrEventHappens(QUEST_MIST);
|
||||
}
|
||||
}
|
||||
pPlayer->GroupEventHappens(QUEST_MIST, m_creature);
|
||||
}
|
||||
|
||||
//The follow is over (and for later development to indicate a post event can now run)
|
||||
//The follow is over (and for later development, run off to the woods before really end)
|
||||
SetFollowComplete();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,16 +17,18 @@
|
||||
/* ScriptData
|
||||
SDName: Ungoro Crater
|
||||
SD%Complete: 100
|
||||
SDComment: Support for Quest: 4245
|
||||
SDComment: Support for Quest: 4245, 4491
|
||||
SDCategory: Ungoro Crater
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_a-me
|
||||
npc_ringo
|
||||
EndContentData */
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "escort_ai.h"
|
||||
#include "follower_ai.h"
|
||||
|
||||
#define SAY_READY -1000200
|
||||
#define SAY_AGGRO1 -1000201
|
||||
@@ -132,6 +134,163 @@ CreatureAI* GetAI_npc_ame(Creature* pCreature)
|
||||
return new npc_ameAI(pCreature);
|
||||
}
|
||||
|
||||
/*####
|
||||
# npc_ringo
|
||||
####*/
|
||||
|
||||
enum
|
||||
{
|
||||
SAY_RIN_START_1 = -1000416,
|
||||
SAY_RIN_START_2 = -1000417,
|
||||
|
||||
SAY_FAINT_1 = -1000418,
|
||||
SAY_FAINT_2 = -1000419,
|
||||
SAY_FAINT_3 = -1000420,
|
||||
SAY_FAINT_4 = -1000421,
|
||||
|
||||
SAY_WAKE_1 = -1000422,
|
||||
SAY_WAKE_2 = -1000423,
|
||||
SAY_WAKE_3 = -1000424,
|
||||
SAY_WAKE_4 = -1000425,
|
||||
|
||||
SAY_RIN_END_1 = -1000426,
|
||||
SAY_SPR_END_2 = -1000427,
|
||||
SAY_RIN_END_3 = -1000428,
|
||||
EMOTE_RIN_END_4 = -1000429,
|
||||
EMOTE_RIN_END_5 = -1000430,
|
||||
SAY_RIN_END_6 = -1000431,
|
||||
SAY_SPR_END_7 = -1000432,
|
||||
EMOTE_RIN_END_8 = -1000433,
|
||||
|
||||
SPELL_REVIVE_RINGO = 15591,
|
||||
QUEST_A_LITTLE_HELP = 4491,
|
||||
NPC_SPRAGGLE = 9997,
|
||||
FACTION_ESCORTEE = 113
|
||||
};
|
||||
|
||||
//Script not fully complete. Need more development of followerAI to accomplish misc tasks.
|
||||
struct TRINITY_DLL_DECL npc_ringoAI : public FollowerAI
|
||||
{
|
||||
npc_ringoAI(Creature* pCreature) : FollowerAI(pCreature) { }
|
||||
|
||||
uint32 m_uiEndEventProgress;
|
||||
uint32 m_uiEndEventTimer;
|
||||
|
||||
Unit* pSpraggle;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_uiEndEventProgress = 0;
|
||||
m_uiEndEventTimer = 1000;
|
||||
pSpraggle = NULL;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *pWho)
|
||||
{
|
||||
FollowerAI::MoveInLineOfSight(pWho);
|
||||
|
||||
if (!m_creature->getVictim() && !IsFollowComplete() && pWho->GetEntry() == NPC_SPRAGGLE)
|
||||
{
|
||||
if (m_creature->IsWithinDistInMap(pWho, INTERACTION_DISTANCE))
|
||||
{
|
||||
if (Player* pPlayer = GetLeaderForFollower())
|
||||
{
|
||||
if (pPlayer->GetQuestStatus(QUEST_A_LITTLE_HELP) == QUEST_STATUS_INCOMPLETE)
|
||||
pPlayer->GroupEventHappens(QUEST_A_LITTLE_HELP, m_creature);
|
||||
}
|
||||
|
||||
pSpraggle = pWho;
|
||||
SetFollowComplete(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateFollowerAI(const uint32 uiDiff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
if (IsEndEventInProgress())
|
||||
{
|
||||
if (m_uiEndEventTimer < uiDiff)
|
||||
{
|
||||
if (!pSpraggle || !pSpraggle->isAlive())
|
||||
{
|
||||
m_uiEndEventTimer = 1000;
|
||||
SetFollowComplete();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(m_uiEndEventProgress)
|
||||
{
|
||||
case 1:
|
||||
DoScriptText(SAY_RIN_END_1, m_creature);
|
||||
m_uiEndEventTimer = 3000;
|
||||
break;
|
||||
case 2:
|
||||
DoScriptText(SAY_SPR_END_2, pSpraggle);
|
||||
m_uiEndEventTimer = 5000;
|
||||
break;
|
||||
case 3:
|
||||
DoScriptText(SAY_RIN_END_3, m_creature);
|
||||
m_uiEndEventTimer = 1000;
|
||||
break;
|
||||
case 4:
|
||||
DoScriptText(EMOTE_RIN_END_4, m_creature);
|
||||
m_uiEndEventTimer = 9000;
|
||||
break;
|
||||
case 5:
|
||||
DoScriptText(EMOTE_RIN_END_5, m_creature);
|
||||
m_uiEndEventTimer = 1000;
|
||||
break;
|
||||
case 6:
|
||||
DoScriptText(SAY_RIN_END_6, m_creature);
|
||||
m_uiEndEventTimer = 3000;
|
||||
break;
|
||||
case 7:
|
||||
DoScriptText(SAY_SPR_END_7, pSpraggle);
|
||||
m_uiEndEventTimer = 10000;
|
||||
break;
|
||||
case 8:
|
||||
DoScriptText(EMOTE_RIN_END_8, m_creature);
|
||||
m_uiEndEventTimer = 5000;
|
||||
break;
|
||||
case 9:
|
||||
SetFollowComplete();
|
||||
break;
|
||||
}
|
||||
|
||||
++m_uiEndEventProgress;
|
||||
}
|
||||
else
|
||||
m_uiEndEventTimer -= uiDiff;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_npc_ringo(Creature* pCreature)
|
||||
{
|
||||
return new npc_ringoAI(pCreature);
|
||||
}
|
||||
|
||||
bool QuestAccept_npc_ringo(Player* pPlayer, Creature* pCreature, const Quest* pQuest)
|
||||
{
|
||||
if (pQuest->GetQuestId() == QUEST_A_LITTLE_HELP)
|
||||
{
|
||||
if (npc_ringoAI* pRingoAI = CAST_AI(npc_ringoAI, pCreature->AI()))
|
||||
{
|
||||
pCreature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
pRingoAI->StartFollow(pPlayer, FACTION_ESCORTEE, pQuest);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSC_ungoro_crater()
|
||||
{
|
||||
Script *newscript;
|
||||
@@ -141,5 +300,11 @@ void AddSC_ungoro_crater()
|
||||
newscript->GetAI = &GetAI_npc_ame;
|
||||
newscript->pQuestAccept = &QuestAccept_npc_ame;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "npc_ringo";
|
||||
newscript->GetAI = &GetAI_npc_ringo;
|
||||
newscript->pQuestAccept = &QuestAccept_npc_ringo;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user