From 0d0ce23bd164861095705101240154677f3cc626 Mon Sep 17 00:00:00 2001 From: killerwife Date: Tue, 14 Jan 2025 14:50:37 +0100 Subject: [PATCH] AQ20: Modernize Rajaxx encounter --- .../eastern_kingdoms/zulaman/zulaman.cpp | 2 +- .../ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp | 197 ++++++++---------- .../ruins_of_ahnqiraj/ruins_of_ahnqiraj.h | 45 ++-- 3 files changed, 111 insertions(+), 133 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/zulaman.cpp b/src/game/AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/zulaman.cpp index 0027421598b..3b725ef622d 100644 --- a/src/game/AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/zulaman.cpp +++ b/src/game/AI/ScriptDevAI/scripts/eastern_kingdoms/zulaman/zulaman.cpp @@ -538,7 +538,7 @@ void instance_zulaman::Load(const char* chrIn) >> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7] >> m_auiEncounter[8] >> m_auiEncounter[9] >> m_auiEncounter[10] >> m_auiEncounter[11]; - // Skip m_auiEncounter[7], to start the time event properly if needed + // Skip m_encounter[7], to start the time event properly if needed for (uint8 i = 0; i < MAX_ENCOUNTER - 1; ++i) { if (m_auiEncounter[i] == IN_PROGRESS) diff --git a/src/game/AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp b/src/game/AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp index 7836214ab78..70b1c707270 100644 --- a/src/game/AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp +++ b/src/game/AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.cpp @@ -24,33 +24,43 @@ EndScriptData */ #include "AI/ScriptDevAI/include/sc_common.h" #include "ruins_of_ahnqiraj.h" -instance_ruins_of_ahnqiraj::instance_ruins_of_ahnqiraj(Map* pMap) : ScriptedInstance(pMap), - m_uiArmyDelayTimer(0), - m_uiCurrentArmyWave(0) +instance_ruins_of_ahnqiraj::instance_ruins_of_ahnqiraj(Map* map) : ScriptedInstance(map), + m_armyDelayTimer(0), + m_currentArmyWave(0) { Initialize(); } void instance_ruins_of_ahnqiraj::Initialize() { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + memset(&m_encounter, 0, sizeof(m_encounter)); } -void instance_ruins_of_ahnqiraj::OnPlayerEnter(Player* /*pPlayer*/) +bool instance_ruins_of_ahnqiraj::IsEncounterInProgress() const +{ + for (uint32 i : m_encounter) + { + if (i == IN_PROGRESS) + return true; + } + return false; +} + +void instance_ruins_of_ahnqiraj::OnPlayerEnter(Player* /*player*/) { // Spawn andorov if necessary - if (m_auiEncounter[TYPE_KURINNAXX] == DONE) + if (GetData(TYPE_KURINNAXX) == DONE) DoSpawnAndorovIfCan(); } -void instance_ruins_of_ahnqiraj::OnCreatureCreate(Creature* pCreature) +void instance_ruins_of_ahnqiraj::OnCreatureCreate(Creature* creature) { - switch (pCreature->GetEntry()) + switch (creature->GetEntry()) { case NPC_OSSIRIAN_TRIGGER: { - GuidVector& vector = m_npcEntryGuidCollection[pCreature->GetEntry()]; - vector.push_back(pCreature->GetObjectGuid()); + GuidVector& vector = m_npcEntryGuidCollection[creature->GetEntry()]; + vector.push_back(creature->GetObjectGuid()); std::sort(vector.begin(), vector.end(), [&](ObjectGuid const& a, ObjectGuid const& b) -> bool { return a.GetCounter() < b.GetCounter(); @@ -68,10 +78,10 @@ void instance_ruins_of_ahnqiraj::OnCreatureCreate(Creature* pCreature) case NPC_CAPTAIN_DRENN: case NPC_CAPTAIN_TUUBID: case NPC_CAPTAIN_QEEZ: - m_npcEntryGuidStore[pCreature->GetEntry()] = pCreature->GetObjectGuid(); + m_npcEntryGuidStore[creature->GetEntry()] = creature->GetObjectGuid(); break; case NPC_KALDOREI_ELITE: - m_lKaldoreiGuidList.push_back(pCreature->GetObjectGuid()); + m_kaldoreiGuidList.push_back(creature->GetObjectGuid()); break; } } @@ -82,9 +92,9 @@ void instance_ruins_of_ahnqiraj::OnObjectCreate(GameObject* go) m_goEntryGuidCollection[go->GetEntry()].push_back(go->GetObjectGuid()); } -void instance_ruins_of_ahnqiraj::OnCreatureEnterCombat(Creature* pCreature) +void instance_ruins_of_ahnqiraj::OnCreatureEnterCombat(Creature* creature) { - switch (pCreature->GetEntry()) + switch (creature->GetEntry()) { case NPC_KURINNAXX: SetData(TYPE_KURINNAXX, IN_PROGRESS); break; case NPC_MOAM: SetData(TYPE_MOAM, IN_PROGRESS); break; @@ -94,9 +104,9 @@ void instance_ruins_of_ahnqiraj::OnCreatureEnterCombat(Creature* pCreature) } } -void instance_ruins_of_ahnqiraj::OnCreatureEvade(Creature* pCreature) +void instance_ruins_of_ahnqiraj::OnCreatureEvade(Creature* creature) { - switch (pCreature->GetEntry()) + switch (creature->GetEntry()) { case NPC_KURINNAXX: SetData(TYPE_KURINNAXX, FAIL); break; case NPC_MOAM: SetData(TYPE_MOAM, FAIL); break; @@ -105,7 +115,7 @@ void instance_ruins_of_ahnqiraj::OnCreatureEvade(Creature* pCreature) case NPC_OSSIRIAN: SetData(TYPE_OSSIRIAN, FAIL); break; case NPC_RAJAXX: // Rajaxx yells on evade - // DoScriptText(SAY_DEAGGRO, pCreature); - unconfirmed + // DoScriptText(SAY_DEAGGRO, creature); - unconfirmed // no break; case NPC_COLONEL_ZERRAN: case NPC_MAJOR_PAKKON: @@ -119,9 +129,9 @@ void instance_ruins_of_ahnqiraj::OnCreatureEvade(Creature* pCreature) } } -void instance_ruins_of_ahnqiraj::OnCreatureDeath(Creature* pCreature) +void instance_ruins_of_ahnqiraj::OnCreatureDeath(Creature* creature) { - switch (pCreature->GetEntry()) + switch (creature->GetEntry()) { case NPC_KURINNAXX: SetData(TYPE_KURINNAXX, DONE); break; case NPC_RAJAXX: SetData(TYPE_RAJAXX, DONE); break; @@ -143,15 +153,7 @@ void instance_ruins_of_ahnqiraj::OnCreatureDeath(Creature* pCreature) if (GetData(TYPE_RAJAXX) != IN_PROGRESS) return; - // Check if the dead creature belongs to the current wave - if (m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].find(pCreature->GetObjectGuid()) != m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].end()) - { - m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].erase(pCreature->GetObjectGuid()); - // If all the soldiers from the current wave are dead, then send the next one - if (m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].empty()) - DoSendNextArmyWave(); - } break; } } @@ -176,25 +178,37 @@ void instance_ruins_of_ahnqiraj::OnCreatureRespawn(Creature* creature) } } -void instance_ruins_of_ahnqiraj::SetData(uint32 uiType, uint32 uiData) +void instance_ruins_of_ahnqiraj::OnCreatureGroupDespawn(CreatureGroup* group, Creature* creature) { - switch (uiType) + // last wave makes rajaxx attack immediately + if (group->GetGroupEntry().StringId == instance->GetMapDataContainer().GetStringId("AQ20_ZERRAN")) + { + if (GetData(TYPE_RAJAXX) != IN_PROGRESS) + return; + + m_armyDelayTimer = 1; + } +} + +void instance_ruins_of_ahnqiraj::SetData(uint32 type, uint32 data) +{ + switch (type) { case TYPE_KURINNAXX: - if (uiData == DONE) + if (data == DONE) { DoSpawnAndorovIfCan(); // Yell after kurinnaxx if (Creature* ossirian = GetSingleCreatureFromStorage(NPC_OSSIRIAN)) DoScriptText(SAY_OSSIRIAN_INTRO, ossirian); // targets kurinnaxx in sniff } - m_auiEncounter[uiType] = uiData; + m_encounter[type] = data; break; case TYPE_RAJAXX: - m_auiEncounter[uiType] = uiData; - if (uiData == IN_PROGRESS) + m_encounter[type] = data; + if (data == IN_PROGRESS) DoSortArmyWaves(); - if (uiData == DONE) + if (data == DONE) { if (Creature* andorov = GetSingleCreatureFromStorage(NPC_GENERAL_ANDOROV)) if (andorov->IsAlive()) @@ -205,7 +219,7 @@ void instance_ruins_of_ahnqiraj::SetData(uint32 uiType, uint32 uiData) case TYPE_BURU: case TYPE_AYAMISS: case TYPE_OSSIRIAN: - if (uiType == FAIL) + if (type == FAIL) { GuidVector crystals; GetGameObjectGuidVectorFromStorage(GO_OSSIRIAN_CRYSTAL, crystals); @@ -219,17 +233,17 @@ void instance_ruins_of_ahnqiraj::SetData(uint32 uiType, uint32 uiData) } m_goEntryGuidCollection[GO_OSSIRIAN_CRYSTAL].resize(1); // keeps first } - m_auiEncounter[uiType] = uiData; + m_encounter[type] = data; break; } - if (uiData == DONE) + if (data == DONE) { OUT_SAVE_INST_DATA; std::ostringstream saveStream; - saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] - << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5]; + saveStream << m_encounter[0] << " " << m_encounter[1] << " " << m_encounter[2] + << " " << m_encounter[3] << " " << m_encounter[4] << " " << m_encounter[5]; m_strInstData = saveStream.str(); @@ -238,10 +252,10 @@ void instance_ruins_of_ahnqiraj::SetData(uint32 uiType, uint32 uiData) } } -uint32 instance_ruins_of_ahnqiraj::GetData(uint32 uiType) const +uint32 instance_ruins_of_ahnqiraj::GetData(uint32 type) const { - if (uiType < MAX_ENCOUNTER) - return m_auiEncounter[uiType]; + if (type < MAX_ENCOUNTER) + return m_encounter[type]; return 0; } @@ -251,12 +265,12 @@ void instance_ruins_of_ahnqiraj::DoSpawnAndorovIfCan() if (GetSingleCreatureFromStorage(NPC_GENERAL_ANDOROV)) return; - Player* pPlayer = GetPlayerInMap(); - if (!pPlayer) + Player* player = GetPlayerInMap(); + if (!player) return; for (const auto& aAndorovSpawnLoc : aAndorovSpawnLocs) - pPlayer->SummonCreature(aAndorovSpawnLoc.m_uiEntry, aAndorovSpawnLoc.m_fX, aAndorovSpawnLoc.m_fY, aAndorovSpawnLoc.m_fZ, aAndorovSpawnLoc.m_fO, TEMPSPAWN_DEAD_DESPAWN, 0); + player->SummonCreature(aAndorovSpawnLoc.m_uiEntry, aAndorovSpawnLoc.m_fX, aAndorovSpawnLoc.m_fY, aAndorovSpawnLoc.m_fZ, aAndorovSpawnLoc.m_fO, TEMPSPAWN_DEAD_DESPAWN, 0); } void instance_ruins_of_ahnqiraj::Load(const char* chrIn) @@ -271,10 +285,10 @@ void instance_ruins_of_ahnqiraj::Load(const char* chrIn) std::istringstream loadStream(chrIn); - loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] - >> m_auiEncounter[3] >> m_auiEncounter[4] >> m_auiEncounter[5]; + loadStream >> m_encounter[0] >> m_encounter[1] >> m_encounter[2] + >> m_encounter[3] >> m_encounter[4] >> m_encounter[5]; - for (uint32& i : m_auiEncounter) + for (uint32& i : m_encounter) { if (i == IN_PROGRESS) i = NOT_STARTED; @@ -283,53 +297,27 @@ void instance_ruins_of_ahnqiraj::Load(const char* chrIn) OUT_LOAD_INST_DATA_COMPLETE; } -void instance_ruins_of_ahnqiraj::Update(uint32 uiDiff) +void instance_ruins_of_ahnqiraj::Update(uint32 diff) { if (GetData(TYPE_RAJAXX) == IN_PROGRESS) { - if (m_uiArmyDelayTimer) + if (m_armyDelayTimer) { - if (m_uiArmyDelayTimer <= uiDiff) + if (m_armyDelayTimer <= diff) { DoSendNextArmyWave(); - m_uiArmyDelayTimer = 2 * MINUTE * IN_MILLISECONDS; + m_armyDelayTimer = 3 * MINUTE * IN_MILLISECONDS; } else - m_uiArmyDelayTimer -= uiDiff; + m_armyDelayTimer -= diff; } } } void instance_ruins_of_ahnqiraj::DoSortArmyWaves() { - CreatureList lCreatureList; - - // Sort the 7 army waves - // We need to use gridsearcher for this, because coords search is too complicated here - for (uint8 i = 0; i < MAX_ARMY_WAVES; ++i) - { - // Clear all the army waves - m_sArmyWavesGuids[i].clear(); - lCreatureList.clear(); - - if (Creature* pTemp = GetSingleCreatureFromStorage(aArmySortingParameters[i].m_uiEntry)) - { - GetCreatureListWithEntryInGrid(lCreatureList, pTemp, NPC_QIRAJI_WARRIOR, aArmySortingParameters[i].m_fSearchDist); - GetCreatureListWithEntryInGrid(lCreatureList, pTemp, NPC_SWARMGUARD_NEEDLER, aArmySortingParameters[i].m_fSearchDist); - - for (CreatureList::const_iterator itr = lCreatureList.begin(); itr != lCreatureList.end(); ++itr) - { - if ((*itr)->IsAlive()) - m_sArmyWavesGuids[i].insert((*itr)->GetObjectGuid()); - } - - if (pTemp->IsAlive()) - m_sArmyWavesGuids[i].insert(pTemp->GetObjectGuid()); - } - } - // send the first wave - m_uiCurrentArmyWave = 0; + m_currentArmyWave = 0; DoSendNextArmyWave(); } @@ -340,64 +328,53 @@ void instance_ruins_of_ahnqiraj::DoSendNextArmyWave() return; // The last wave is General Rajaxx itself - if (m_uiCurrentArmyWave == MAX_ARMY_WAVES) + if (m_currentArmyWave == MAX_ARMY_WAVES) { - if (Creature* pRajaxx = GetSingleCreatureFromStorage(NPC_RAJAXX)) + if (Creature* rajaxx = GetSingleCreatureFromStorage(NPC_RAJAXX)) { - DoScriptText(SAY_INTRO, pRajaxx); - pRajaxx->SetInCombatWithZone(); - pRajaxx->AI()->AttackClosestEnemy(); + DoScriptText(SAY_INTRO, rajaxx); + rajaxx->SetInCombatWithZone(); + rajaxx->AI()->AttackClosestEnemy(); } - m_uiArmyDelayTimer = 0; + m_armyDelayTimer = 0; } else { - // Increase the wave id if some are already dead - while (m_uiCurrentArmyWave < MAX_ARMY_WAVES && m_sArmyWavesGuids[m_uiCurrentArmyWave].empty()) - ++m_uiCurrentArmyWave; - - if (m_uiCurrentArmyWave == MAX_ARMY_WAVES) + if (m_currentArmyWave == MAX_ARMY_WAVES) { script_error_log("Instance Ruins of Ahn'Qiraj: ERROR Something unexpected happened. Please report to SD2 team."); return; } - float fX, fY, fZ; - for (auto itr : m_sArmyWavesGuids[m_uiCurrentArmyWave]) + auto waveInfo = aArmySortingParameters[m_currentArmyWave]; + auto waveMobs = instance->GetCreatures(waveInfo.m_stringId); + if (waveMobs) { - if (Creature* pTemp = instance->GetCreature(itr)) + for (Creature* member : *waveMobs) { - if (!pTemp->IsAlive()) - continue; - - pTemp->SetWalk(false); - pTemp->GetRandomPoint(aAndorovMoveLocs[4].m_fX, aAndorovMoveLocs[4].m_fY, aAndorovMoveLocs[4].m_fZ, 10.0f, fX, fY, fZ); - pTemp->GetMotionMaster()->MovePoint(0, fX, fY, fZ); + member->SetWalk(false); + member->SetInCombatWithZone(); + member->AI()->AttackClosestEnemy(); } } // Yell on each wave (except the first 2) - if (aArmySortingParameters[m_uiCurrentArmyWave].m_uiYellEntry) + if (aArmySortingParameters[m_currentArmyWave].m_uiYellEntry) { if (Creature* pRajaxx = GetSingleCreatureFromStorage(NPC_RAJAXX)) - DoScriptText(aArmySortingParameters[m_uiCurrentArmyWave].m_uiYellEntry, pRajaxx); + DoScriptText(aArmySortingParameters[m_currentArmyWave].m_uiYellEntry, pRajaxx); } // on wowwiki it states that there were 3 min between the waves, but this was reduced in later patches - m_uiArmyDelayTimer = 2 * MINUTE * IN_MILLISECONDS; + m_armyDelayTimer = 3 * MINUTE * IN_MILLISECONDS; } - ++m_uiCurrentArmyWave; -} - -InstanceData* GetInstanceData_instance_ruins_of_ahnqiraj(Map* pMap) -{ - return new instance_ruins_of_ahnqiraj(pMap); + ++m_currentArmyWave; } void AddSC_instance_ruins_of_ahnqiraj() { Script* pNewScript = new Script; pNewScript->Name = "instance_ruins_of_ahnqiraj"; - pNewScript->GetInstanceData = &GetInstanceData_instance_ruins_of_ahnqiraj; + pNewScript->GetInstanceData = &GetNewInstanceScript; pNewScript->RegisterSelf(); } diff --git a/src/game/AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h b/src/game/AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h index cd3706f8a78..d5c58dce262 100644 --- a/src/game/AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h +++ b/src/game/AI/ScriptDevAI/scripts/kalimdor/ruins_of_ahnqiraj/ruins_of_ahnqiraj.h @@ -83,18 +83,18 @@ struct SortingParameters { uint32 m_uiEntry; int32 m_uiYellEntry; - float m_fSearchDist; + std::string m_stringId; }; static const SortingParameters aArmySortingParameters[MAX_ARMY_WAVES] = { - {NPC_CAPTAIN_QEEZ, 0, 20.0f}, - {NPC_CAPTAIN_TUUBID, 0, 22.0f}, - {NPC_CAPTAIN_DRENN, SAY_WAVE3, 22.0f}, - {NPC_CAPTAIN_XURREM, SAY_WAVE4, 22.0f}, - {NPC_MAJOR_YEGGETH, SAY_WAVE5, 20.0f}, - {NPC_MAJOR_PAKKON, SAY_WAVE6, 21.0f}, - {NPC_COLONEL_ZERRAN, SAY_WAVE7, 17.0f}, + {NPC_CAPTAIN_QEEZ, 0, "AQ20_QEEZ"}, + {NPC_CAPTAIN_TUUBID, 0, "AQ20_TUUBID"}, + {NPC_CAPTAIN_DRENN, SAY_WAVE3, "AQ20_DRENN"}, + {NPC_CAPTAIN_XURREM, SAY_WAVE4, "AQ20_XURREM"}, + {NPC_MAJOR_YEGGETH, SAY_WAVE5, "AQ20_YEGGETH"}, + {NPC_MAJOR_PAKKON, SAY_WAVE6, "AQ20_PAKKON"}, + {NPC_COLONEL_ZERRAN, SAY_WAVE7, "AQ20_ZERRAN"}, }; class instance_ruins_of_ahnqiraj : public ScriptedInstance @@ -105,21 +105,23 @@ class instance_ruins_of_ahnqiraj : public ScriptedInstance void Initialize() override; - // bool IsEncounterInProgress() const override; // not active in AQ20 + bool IsEncounterInProgress() const override; // not active in AQ20 - void OnCreatureCreate(Creature* pCreature) override; + void OnCreatureCreate(Creature* creature) override; void OnObjectCreate(GameObject* go) override; - void OnPlayerEnter(Player* pPlayer) override; + void OnPlayerEnter(Player* player) override; - void OnCreatureEnterCombat(Creature* pCreature) override; - void OnCreatureEvade(Creature* pCreature) override; - void OnCreatureDeath(Creature* pCreature) override; + void OnCreatureEnterCombat(Creature* creature) override; + void OnCreatureEvade(Creature* creature) override; + void OnCreatureDeath(Creature* creature) override; void OnCreatureRespawn(Creature* creature) override; - void SetData(uint32 uiType, uint32 uiData) override; - uint32 GetData(uint32 uiType) const override; + void OnCreatureGroupDespawn(CreatureGroup* group, Creature* creature) override; - void GetKaldoreiGuidList(GuidList& lList) const { lList = m_lKaldoreiGuidList; } + void SetData(uint32 type, uint32 data) override; + uint32 GetData(uint32 type) const override; + + void GetKaldoreiGuidList(GuidList& lList) const { lList = m_kaldoreiGuidList; } void Update(const uint32 diff) override; @@ -131,13 +133,12 @@ class instance_ruins_of_ahnqiraj : public ScriptedInstance void DoSortArmyWaves(); void DoSendNextArmyWave(); - uint32 m_auiEncounter[MAX_ENCOUNTER]; + uint32 m_encounter[MAX_ENCOUNTER]; std::string m_strInstData; - GuidList m_lKaldoreiGuidList; - GuidSet m_sArmyWavesGuids[MAX_ARMY_WAVES]; + GuidList m_kaldoreiGuidList; - uint32 m_uiArmyDelayTimer; - uint8 m_uiCurrentArmyWave; + uint32 m_armyDelayTimer; + uint8 m_currentArmyWave; }; #endif