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:
Kudlaty
2009-08-20 02:24:53 +02:00
parent fc3717d7e3
commit 33a1d8dc6c
10 changed files with 408 additions and 275 deletions
+28 -12
View File
@@ -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;
}
+3 -1
View File
@@ -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;
+29 -138
View File
@@ -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();
}