From cd3151df40aaa32e6e363d9d6c9cc36f83c69507 Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Mon, 25 Jul 2022 12:12:08 -0300 Subject: [PATCH] fix(Scripts/RuinsOfAhnQiraj): Implement Rajaxx waves (#12513) --- .../rev_1658621389874483000.sql | 76 +++++++++ src/server/game/AI/CreatureAI.cpp | 4 + .../game/Entities/Creature/CreatureGroups.cpp | 37 +++++ .../game/Entities/Creature/CreatureGroups.h | 3 + src/server/game/Maps/ZoneScript.h | 1 + .../Kalimdor/RuinsOfAhnQiraj/boss_rajaxx.cpp | 20 +-- .../instance_ruins_of_ahnqiraj.cpp | 148 +++++++++++++++++- .../RuinsOfAhnQiraj/ruins_of_ahnqiraj.h | 23 ++- 8 files changed, 288 insertions(+), 24 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1658621389874483000.sql diff --git a/data/sql/updates/pending_db_world/rev_1658621389874483000.sql b/data/sql/updates/pending_db_world/rev_1658621389874483000.sql new file mode 100644 index 000000000..6b06fcfc7 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1658621389874483000.sql @@ -0,0 +1,76 @@ +-- Captain Qeez +DELETE FROM `creature_formations` WHERE `leaderGUID` = 144676; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(144676, 144676, 0, 0, 11, 0, 0), +(144676, 144611, 0, 0, 11, 0, 0), +(144676, 144656, 0, 0, 11, 0, 0), +(144676, 144653, 0, 0, 11, 0, 0), +(144676, 144655, 0, 0, 11, 0, 0), +(144676, 144610, 0, 0, 11, 0, 0), +(144676, 144654, 0, 0, 11, 0, 0); + +-- Tubid +DELETE FROM `creature_formations` WHERE `leaderGUID` = 144677; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(144677, 144677, 0, 0, 11, 0, 0), +(144677, 144658, 0, 0, 11, 0, 0), +(144677, 144616, 0, 0, 11, 0, 0), +(144677, 144617, 0, 0, 11, 0, 0), +(144677, 144619, 0, 0, 11, 0, 0), +(144677, 144660, 0, 0, 11, 0, 0), +(144677, 144659, 0, 0, 11, 0, 0); + +-- Drenn +DELETE FROM `creature_formations` WHERE `leaderGUID` = 144674; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(144674, 144674, 0, 0, 11, 0, 0), +(144674, 144618, 0, 0, 11, 0, 0), +(144674, 144657, 0, 0, 11, 0, 0), +(144674, 144614, 0, 0, 11, 0, 0), +(144674, 144613, 0, 0, 11, 0, 0), +(144674, 144612, 0, 0, 11, 0, 0), +(144674, 144615, 0, 0, 11, 0, 0); + +-- Yeggeth +DELETE FROM `creature_formations` WHERE `leaderGUID` = 144652; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(144652, 144652, 0, 0, 11, 0, 0), +(144652, 144664, 0, 0, 11, 0, 0), +(144652, 144622, 0, 0, 11, 0, 0), +(144652, 144624, 0, 0, 11, 0, 0), +(144652, 144663, 0, 0, 11, 0, 0), +(144652, 144621, 0, 0, 11, 0, 0), +(144652, 144620, 0, 0, 11, 0, 0); + +-- Xurrem +DELETE FROM `creature_formations` WHERE `leaderGUID` = 144675; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(144675, 144675, 0, 0, 11, 0, 0), +(144675, 144625, 0, 0, 11, 0, 0), +(144675, 144623, 0, 0, 11, 0, 0), +(144675, 144665, 0, 0, 11, 0, 0), +(144675, 144626, 0, 0, 11, 0, 0), +(144675, 144662, 0, 0, 11, 0, 0), +(144675, 144661, 0, 0, 11, 0, 0); + +-- Pakkon +DELETE FROM `creature_formations` WHERE `leaderGUID` = 144673; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(144673, 144673, 0, 0, 11, 0, 0), +(144673, 144669, 0, 0, 11, 0, 0), +(144673, 144630, 0, 0, 11, 0, 0), +(144673, 144670, 0, 0, 11, 0, 0), +(144673, 144631, 0, 0, 11, 0, 0), +(144673, 144672, 0, 0, 11, 0, 0), +(144673, 144671, 0, 0, 11, 0, 0); + +-- Zerram +DELETE FROM `creature_formations` WHERE `leaderGUID` = 144651; +INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES +(144651, 144651, 0, 0, 11, 0, 0), +(144651, 144668, 0, 0, 11, 0, 0), +(144651, 144629, 0, 0, 11, 0, 0), +(144651, 144667, 0, 0, 11, 0, 0), +(144651, 144628, 0, 0, 11, 0, 0), +(144651, 144666, 0, 0, 11, 0, 0), +(144651, 144627, 0, 0, 11, 0, 0); diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index e310de645..14048b6f3 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -27,6 +27,7 @@ #include "Vehicle.h" #include "ScriptMgr.h" #include "Language.h" +#include "ZoneScript.h" class PhasedRespawn : public BasicEvent { @@ -308,6 +309,9 @@ bool CreatureAI::_EnterEvadeMode(EvadeReason /*why*/) me->SetLastDamagedTime(0); me->SetCannotReachTarget(); + if (ZoneScript* zoneScript = me->GetZoneScript() ? me->GetZoneScript() : (ZoneScript*)me->GetInstanceScript()) + zoneScript->OnCreatureEvade(me); + if (me->IsInEvadeMode()) { return false; diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index 030134f26..a181c571a 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -381,3 +381,40 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z, bool run) } } } + +void CreatureGroup::RespawnFormation(bool force) +{ + for (auto const& itr : m_members) + { + if (itr.first && !itr.first->IsAlive()) + { + itr.first->Respawn(force); + } + } +} + +bool CreatureGroup::IsFormationInCombat() +{ + for (auto const& itr : m_members) + { + if (itr.first && itr.first->IsInCombat()) + { + return true; + } + } + + return false; +} + +bool CreatureGroup::IsAnyMemberAlive() +{ + for (auto const& itr : m_members) + { + if (itr.first && itr.first->IsAlive()) + { + return true; + } + } + + return false; +} diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index 9a4db6736..9fe3398f5 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -109,6 +109,9 @@ public: void LeaderMoveTo(float x, float y, float z, bool run); void MemberEngagingTarget(Creature* member, Unit* target); void MemberEvaded(Creature* member); + void RespawnFormation(bool force = false); + [[nodiscard]] bool IsFormationInCombat(); + [[nodiscard]] bool IsAnyMemberAlive(); private: Creature* m_leader; //Important do not forget sometimes to work with pointers instead synonims :D:D diff --git a/src/server/game/Maps/ZoneScript.h b/src/server/game/Maps/ZoneScript.h index 7a52ba113..ae795f6aa 100644 --- a/src/server/game/Maps/ZoneScript.h +++ b/src/server/game/Maps/ZoneScript.h @@ -39,6 +39,7 @@ public: virtual void OnGameObjectRemove(GameObject*) { } virtual void OnUnitDeath(Unit*) { } + virtual void OnCreatureEvade(Creature*) { } //All-purpose data storage 64 bit virtual ObjectGuid GetGuidData(uint32 /*DataId*/) const { return ObjectGuid::Empty; } diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_rajaxx.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_rajaxx.cpp index d9587d28e..2c648dfb0 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_rajaxx.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/boss_rajaxx.cpp @@ -22,16 +22,6 @@ enum Yells { - // The time of our retribution is at hand! Let darkness reign in the hearts of our enemies! Sound: 8645 Emote: 35 - SAY_ANDOROV_INTRO = 0, // Before for the first wave - SAY_ANDOROV_ATTACK = 1, // Beginning the event - - SAY_WAVE3 = 0, - SAY_WAVE4 = 1, - SAY_WAVE5 = 2, - SAY_WAVE6 = 3, - SAY_WAVE7 = 4, - SAY_INTRO = 5, SAY_UNK1 = 6, SAY_UNK2 = 7, SAY_UNK3 = 8, @@ -63,27 +53,25 @@ public: struct boss_rajaxxAI : public BossAI { - boss_rajaxxAI(Creature* creature) : BossAI(creature, DATA_RAJAXX) - { - } + boss_rajaxxAI(Creature* creature) : BossAI(creature, DATA_RAJAXX) { } void Reset() override { _Reset(); enraged = false; - events.ScheduleEvent(EVENT_DISARM, 10000); - events.ScheduleEvent(EVENT_THUNDERCRASH, 12000); } void JustDied(Unit* /*killer*/) override { - //SAY_DEATH + Talk(SAY_DEATH); _JustDied(); } void EnterCombat(Unit* /*victim*/) override { _EnterCombat(); + events.ScheduleEvent(EVENT_DISARM, 10000); + events.ScheduleEvent(EVENT_THUNDERCRASH, 12000); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp index d651cfde6..a84522ab0 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/instance_ruins_of_ahnqiraj.cpp @@ -15,14 +15,46 @@ * with this program. If not, see . */ +#include "CreatureGroups.h" #include "InstanceScript.h" #include "ScriptMgr.h" +#include "TaskScheduler.h" #include "ruins_of_ahnqiraj.h" ObjectData const creatureData[] = { - { NPC_OSSIRIAN, DATA_OSSIRIAN }, - { NPC_KURINNAXX, DATA_KURINNAXX } + { NPC_KURINNAXX, DATA_KURINNAXX }, + { NPC_RAJAXX, DATA_RAJAXX }, + { NPC_OSSIRIAN, DATA_OSSIRIAN }, + { NPC_QUUEZ, DATA_QUUEZ }, + { NPC_TUUBID, DATA_TUUBID }, + { NPC_DRENN, DATA_DRENN }, + { NPC_XURREM, DATA_XURREM }, + { NPC_YEGGETH, DATA_YEGGETH }, + { NPC_PAKKON, DATA_PAKKON }, + { NPC_ZERRAN, DATA_ZERRAN }, +}; + +enum RajaxxText +{ + SAY_WAVE3 = 0, + SAY_WAVE4 = 1, + SAY_WAVE5 = 2, + SAY_WAVE6 = 3, + SAY_WAVE7 = 4, + SAY_ENGAGE = 5 +}; + +std::array RajaxxWavesData[] = +{ + { DATA_QUUEZ, 0 }, + { DATA_TUUBID, 0 }, + { DATA_DRENN, SAY_WAVE3 }, + { DATA_XURREM, SAY_WAVE4 }, + { DATA_YEGGETH, SAY_WAVE5 }, + { DATA_PAKKON, SAY_WAVE6 }, + { DATA_ZERRAN, SAY_WAVE7 }, + { DATA_RAJAXX, SAY_ENGAGE } }; class instance_ruins_of_ahnqiraj : public InstanceMapScript @@ -36,6 +68,7 @@ public: { SetBossNumber(NUM_ENCOUNTER); LoadObjectData(creatureData, nullptr); + _rajaxWaveCounter = 0; } void OnCreatureCreate(Creature* creature) override @@ -65,12 +98,73 @@ public: } } - bool SetBossState(uint32 bossId, EncounterState state) override + void OnCreatureEvade(Creature* creature) override { - if (!InstanceScript::SetBossState(bossId, state)) - return false; + if (CreatureGroup* formation = creature->GetFormation()) + { + if (Creature* leader = formation->GetLeader()) + { + switch (leader->GetEntry()) + { + case NPC_QUUEZ: + case NPC_TUUBID: + case NPC_DRENN: + case NPC_XURREM: + case NPC_YEGGETH: + case NPC_PAKKON: + case NPC_ZERRAN: + if (!formation->IsFormationInCombat()) + { + ResetRajaxxWaves(); + } + break; + default: + break; + } + } + } + else if (creature->GetEntry() == NPC_RAJAXX) + { + ResetRajaxxWaves(); + } + } - return true; + void OnUnitDeath(Unit* unit) override + { + if (Creature* creature = unit->ToCreature()) + { + if (CreatureGroup* formation = creature->GetFormation()) + { + if (Creature* leader = formation->GetLeader()) + { + switch (leader->GetEntry()) + { + case NPC_QUUEZ: + case NPC_TUUBID: + case NPC_DRENN: + case NPC_XURREM: + case NPC_YEGGETH: + case NPC_PAKKON: + case NPC_ZERRAN: + _scheduler.CancelAll(); + _scheduler.Schedule(1s, [this, formation](TaskContext /*context*/) { + if (!formation->IsAnyMemberAlive()) + { + CallNextRajaxxLeader(); + } + }); + break; + default: + break; + } + } + } + } + } + + void Update(uint32 diff) override + { + _scheduler.Update(diff); } void SetGuidData(uint32 type, ObjectGuid data) override @@ -145,6 +239,46 @@ public: OUT_LOAD_INST_DATA_COMPLETE; } + void CallNextRajaxxLeader() + { + ++_rajaxWaveCounter; + + if (Creature* nextLeader = GetCreature(RajaxxWavesData[_rajaxWaveCounter].at(0))) + { + if (_rajaxWaveCounter >= 2) + { + if (Creature* rajaxx = GetCreature(DATA_RAJAXX)) + { + rajaxx->AI()->Talk(RajaxxWavesData[_rajaxWaveCounter].at(1)); + } + } + + if (nextLeader->IsAlive()) + { + nextLeader->SetInCombatWithZone(); + } + else + { + CallNextRajaxxLeader(); + } + } + } + + void ResetRajaxxWaves() + { + _rajaxWaveCounter = 0; + for (auto const& data : RajaxxWavesData) + { + if (Creature* creature = GetCreature(data.at(0))) + { + if (CreatureGroup* group = creature->GetFormation()) + { + group->RespawnFormation(true); + } + } + } + } + private: ObjectGuid _kurinnaxxGUID; ObjectGuid _rajaxxGUID; @@ -153,6 +287,8 @@ public: ObjectGuid _ayamissGUID; ObjectGuid _ossirianGUID; ObjectGuid _paralyzedGUID; + uint32 _rajaxWaveCounter; + TaskScheduler _scheduler; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h index 458966ffe..522b70c78 100644 --- a/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h +++ b/src/server/scripts/Kalimdor/RuinsOfAhnQiraj/ruins_of_ahnqiraj.h @@ -32,7 +32,17 @@ enum DataTypes DATA_OSSIRIAN = 5, NUM_ENCOUNTER = 6, - DATA_PARALYZED = 7 + DATA_PARALYZED = 7, + + DATA_QUUEZ = 8, + DATA_TUUBID = 9, + DATA_DRENN = 10, + DATA_XURREM = 11, + DATA_YEGGETH = 12, + DATA_PAKKON = 13, + DATA_ZERRAN = 14, + + DATA_ENGAGED_FORMATION = 1 }; enum Creatures @@ -52,7 +62,16 @@ enum Creatures NPC_BURU_EGG = 15514, NPC_LARVA = 15555, NPC_SWARMER = 15546, - NPC_HORNET = 15934 + NPC_HORNET = 15934, + + // Rajaxx + NPC_QUUEZ = 15391, + NPC_TUUBID = 15392, + NPC_DRENN = 15389, + NPC_XURREM = 15390, + NPC_YEGGETH = 15386, + NPC_PAKKON = 15388, + NPC_ZERRAN = 15385 }; enum GameObjects