diff --git a/data/sql/world/base/aq_gate_quest.sql b/data/sql/world/base/aq_gate_quest.sql index 18328c3..0d026cb 100644 --- a/data/sql/world/base/aq_gate_quest.sql +++ b/data/sql/world/base/aq_gate_quest.sql @@ -1,30 +1,23 @@ --- Gate of Ahn'Qiraj -DELETE FROM `gameobject` WHERE `id`=176146; -INSERT INTO `gameobject` (`id`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES (176146, 1, -8133.34, 1525.13, 17.1904, 6.28103, 0.00107995, -0.999999, 600, 100, 1); - --- Ahn'Qiraj Gate Roots -DELETE FROM `gameobject` WHERE `id`=176147; -INSERT INTO `gameobject` (`id`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES (176147, 1, -8133.34, 1525.13, 17.1904, 6.28103, 0.00107995, -0.999999, 600, 100, 1); - --- Ahn'Qiraj Gate Runes -DELETE FROM `gameobject` WHERE `id`=176148; -INSERT INTO `gameobject` (`id`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES (176148, 1, -8133.34, 1525.13, 17.1904, 6.28103, 0.00107995, -0.999999, 600, 100, 1); +DELETE FROM `gameobject` WHERE `id` IN (176146, 176147, 176148); +INSERT INTO `gameobject` (`id`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES +(176146, 1, -8133.34, 1525.13, 17.1904, 6.28103, 0.00107995, -0.999999, 600, 100, 1), -- Gate of Ahn'Qiraj +(176147, 1, -8133.34, 1525.13, 17.1904, 6.28103, 0.00107995, -0.999999, 600, 100, 1), -- Ahn'Qiraj Gate Roots +(176148, 1, -8133.34, 1525.13, 17.1904, 6.28103, 0.00107995, -0.999999, 600, 100, 1); -- Ahn'Qiraj Gate Runes -- Ghost Gate - should not be placed, remove it if it is present -DELETE FROM `gameobject` WHERE `id`=180322; -# INSERT INTO `gameobject` (`id`, `map`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`) VALUES (180322, 1, -8132.76, 1525.19, 6.19048, 6.27739, 0.00289526, -0.999996, 25, 100, 1); +DELETE FROM `gameobject` WHERE `id` = 180322; --- Gate of Ahn'Qiraj -UPDATE `gameobject_template_addon` SET `flags`=4 WHERE `entry`=176146; -UPDATE `gameobject_template` SET `ScriptName`='aq_gate' WHERE `entry`=176148; -UPDATE `gameobject_template` SET `ScriptName`='aq_gate' WHERE `entry`=176147; -UPDATE `gameobject_template` SET `ScriptName`='aq_gate' WHERE `entry`=176146; +-- Ahn'Qiraj Gate, Roots and Runes +UPDATE `gameobject_template_addon` SET `flags` = 4 WHERE `entry` IN (176146, 176147, 176148); +UPDATE `gameobject_template` SET `ScriptName` = 'aq_gate' WHERE `entry` IN (176146, 176147, 176148); --- Ahn'Qiraj Gate Roots -UPDATE `gameobject_template_addon` SET `flags`=4 WHERE `entry`=176147; +-- fix tiny red crystal quest not completing +UPDATE `gameobject_template` SET `ScriptName` = 'gobject_crystalline_tear' WHERE `entry` = 180633; -- was go_crystalline_tear --- Ahn'Qiraj Gate Runes -UPDATE `gameobject_template_addon` SET `flags`=4 WHERE `entry`=176148; +-- add unused crystal to avoid worldserver error due to 'go_crystalline_tear' scrypt no longer being used. +DELETE FROM `gameobject_template` WHERE `entry` = 280633; +INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `size`, `Data1`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES +(280633, 2, 5746, 'Crystalline Tear', 1, 7062, '', 'go_crystalline_tear', 12340); -- Scarab Gong -- See related AC PR: https://github.com/azerothcore/azerothcore-wotlk/pull/12879/files diff --git a/src/vanillaScripts/aq_scripts.cpp b/src/vanillaScripts/aq_scripts.cpp index b4c922a..aec18bb 100644 --- a/src/vanillaScripts/aq_scripts.cpp +++ b/src/vanillaScripts/aq_scripts.cpp @@ -6,6 +6,8 @@ #include "ScriptedGossip.h" #include "WorldSessionMgr.h" +#define EVENT_AREA_RADIUS 65 + enum { QUEST_BANG_A_GONG = 8743, @@ -26,13 +28,240 @@ enum STAGE_RESET = 2 }; +//Cordinates for Spawns +Position const SpawnLocation[] = +{ + {-8085.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8085.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8085.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8080.0f, 1424.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8085.0f, 1422.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + // 2 waves of warriors + {-8082.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1525.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1527.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8082.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8082.0f, 1523.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1521.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1528.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1519.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1526.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8082.0f, 1524.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1522.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1520.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8078.0f, 1518.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + {-8082.0f, 1516.0f, 2.61f, 3.141592f}, //Kaldorei Infantry + + {-8088.0f, 1510.0f, 2.61f, 0.0f}, //Anubisath Conqueror + {-8084.0f, 1520.0f, 2.61f, 0.0f}, //Anubisath Conqueror + {-8088.0f, 1530.0f, 2.61f, 0.0f}, //Anubisath Conqueror + + {-8080.0f, 1513.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8082.0f, 1523.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8085.0f, 1518.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8082.0f, 1516.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8085.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8080.0f, 1528.0f, 2.61f, 0.0f}, //Qiraj Wasp + + {-8082.0f, 1513.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8079.0f, 1523.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8080.0f, 1531.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8079.0f, 1516.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8082.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Wasp + {-8080.0f, 1518.0f, 2.61f, 0.0f}, //Qiraj Wasp + + {-8081.0f, 1514.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8081.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8081.0f, 1526.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8081.0f, 1512.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8082.0f, 1520.0f, 2.61f, 0.0f}, //Qiraj Tank + {-8081.0f, 1528.0f, 2.61f, 0.0f}, //Qiraj Tank + + {-8082.0f, 1513.0f, 2.61f, 3.141592f}, //Anubisath Conqueror + {-8082.0f, 1520.0f, 2.61f, 3.141592f}, //Anubisath Conqueror + {-8082.0f, 1527.0f, 2.61f, 3.141592f}, //Anubisath Conqueror +}; + +enum EternalBoard +{ + QUEST_A_PAWN_ON_THE_ETERNAL_BOARD = 8519, + + C_FANDRAL_STAGHELM = 15382, + C_ARYGOS = 15380, + C_MERITHRA = 15378, + C_CAELESTRASZ = 15379, + + ANACHRONOS_SAY_1 = 0, + ANACHRONOS_SAY_2 = 1, + ANACHRONOS_SAY_3 = 2, + ANACHRONOS_SAY_4 = 3, + ANACHRONOS_SAY_5 = 4, + ANACHRONOS_SAY_6 = 5, + ANACHRONOS_SAY_7 = 6, + ANACHRONOS_SAY_8 = 7, + ANACHRONOS_SAY_9 = 8, + ANACHRONOS_SAY_10 = 9, + ANACHRONOS_EMOTE_1 = 10, + ANACHRONOS_EMOTE_2 = 11, + ANACHRONOS_EMOTE_3 = 12, + + FANDRAL_SAY_1 = 0, + FANDRAL_SAY_2 = 1, + FANDRAL_SAY_3 = 2, + FANDRAL_SAY_4 = 3, + FANDRAL_SAY_5 = 4, + FANDRAL_SAY_6 = 5, + FANDRAL_EMOTE_1 = 6, + FANDRAL_EMOTE_2 = 7, + + CAELESTRASZ_SAY_1 = 0, + CAELESTRASZ_SAY_2 = 1, + CAELESTRASZ_YELL_1 = 2, + + ARYGOS_SAY_1 = 0, + ARYGOS_YELL_1 = 1, + ARYGOS_EMOTE_1 = 2, + + MERITHRA_SAY_1 = 0, + MERITHRA_SAY_2 = 1, + MERITHRA_YELL_1 = 2, + MERITHRA_EMOTE_1 = 3, +}; + +struct QuestCinematic +{ + int32 TextId; + uint32 Creature, Timer; +}; + +static QuestCinematic EventAnim[] = +{ + {ANACHRONOS_SAY_1, 0, 2000}, + {FANDRAL_SAY_1, 1, 4000}, + {MERITHRA_EMOTE_1, 3, 500}, + {MERITHRA_SAY_1, 3, 500}, + {ARYGOS_EMOTE_1, 2, 2000}, + {CAELESTRASZ_SAY_1, 4, 8000}, + {MERITHRA_SAY_2, 3, 6000}, + {0, 3, 2000}, + {MERITHRA_YELL_1, 3, 2500}, + {0, 3, 3000}, //Morph + {0, 3, 4000}, //EmoteLiftoff + {0, 3, 4000}, // spell + {0, 3, 1250}, //fly + {0, 3, 250}, //remove flags + {ARYGOS_SAY_1, 2, 3000}, + {0, 3, 2000}, + {ARYGOS_YELL_1, 2, 3000}, + {0, 3, 3000}, //Morph + {0, 3, 4000}, //EmoteLiftoff + {0, 3, 4000}, // spell + {0, 3, 1000}, //fly + {0, 3, 1000}, //remove flags + {CAELESTRASZ_SAY_2, 4, 5000}, + {0, 3, 3000}, + {CAELESTRASZ_YELL_1, 4, 3000}, + {0, 3, 3000}, //Morph + {0, 3, 4000}, //EmoteLiftoff + {0, 3, 2500}, // spell + {ANACHRONOS_SAY_2, 0, 2000}, + {0, 3, 250}, //fly + {0, 3, 25}, //remove flags + {FANDRAL_SAY_2, 1, 3000}, + {ANACHRONOS_SAY_3, 0, 10000}, //Both run through the armies + {0, 3, 2000}, // Sands will stop + {0, 3, 8000}, // Summon Gate + {ANACHRONOS_SAY_4, 0, 4000}, + {0, 0, 2000}, //spell 1-> Arcane cosmetic (Mobs freeze) + {0, 0, 5000}, //Spell 2-> Arcane long cosmetic (barrier appears) (Barrier -> Glyphs) + {0, 0, 7000}, //BarrieR + {0, 0, 4000}, //Glyphs + {ANACHRONOS_SAY_5, 0, 2000}, + {0, 0, 4000}, // Roots + {FANDRAL_SAY_3, 1, 3000}, //Root Text + {FANDRAL_EMOTE_1, 1, 3000}, //falls knee + {ANACHRONOS_SAY_6, 0, 3000}, + {ANACHRONOS_SAY_7, 0, 3000}, + {ANACHRONOS_SAY_8, 0, 8000}, + {ANACHRONOS_EMOTE_1, 0, 1000}, //Give Scepter + {FANDRAL_SAY_4, 1, 3000}, + {FANDRAL_SAY_5, 1, 3000}, //->Equip hammer~Scepter, throw it at door + {FANDRAL_EMOTE_2, 1, 3000}, //Throw hammer at door. + {ANACHRONOS_SAY_9, 0, 3000}, + {FANDRAL_SAY_6, 1, 3000}, //fandral goes away + {ANACHRONOS_EMOTE_2, 0, 3000}, + {ANACHRONOS_EMOTE_3, 0, 3000}, + {0, 0, 2000}, + {0, 0, 2000}, + {0, 0, 4000}, + {ANACHRONOS_SAY_10, 0, 3000}, + {0, 0, 2000}, + {0, 0, 3000}, + {0, 0, 15000}, + {0, 0, 5000}, + {0, 0, 3500}, + {0, 0, 5000}, + {0, 0, 3500}, + {0, 0, 5000}, + {0, 0, 0} +}; + +struct WaveData +{ + uint8 SpawnCount, UsedSpawnPoint; + uint32 CreatureId, SpawnTimer, YellTimer, DespTimer; + int32 WaveTextId; +}; + +static WaveData WavesInfo[5] = +{ + {30, 0, 15423, 0, 0, 24000, 0}, // Kaldorei Soldier + { 3, 35, 15424, 0, 0, 24000, 0}, // Anubisath Conqueror + {12, 38, 15414, 0, 0, 24000, 0}, // Qiraji Wasps + { 6, 50, 15422, 0, 0, 24000, 0}, // Qiraji Tanks + {15, 15, 15423, 0, 0, 24000, 0} // Kaldorei Soldier +}; + +struct SpawnSpells +{ + uint32 Timer1, Timer2, SpellId; +}; + +static SpawnSpells SpawnCast[4] = +{ + {100000, 2000, 33652}, // Stop Time + {38500, 300000, 28528}, // Poison Cloud + {58000, 300000, 35871}, // Frost Debuff (need correct spell) + {80950, 300000, 42075}, // Fire Explosion (need correct spell however this one looks cool) +}; + class gobject_scarab_gong : public GameObjectScript { private: public: - gobject_scarab_gong() : GameObjectScript("gobject_scarab_gong") - {} + gobject_scarab_gong() : GameObjectScript("gobject_scarab_gong") { } struct gobject_scarab_gongAI : GameObjectAI { @@ -40,13 +269,13 @@ public: uint32 eventStep; uint32 eventStage; - GameObject *go_aq_barrier; - GameObject *go_aq_gate_runes; - GameObject *go_aq_gate_roots; + GameObject* go_aq_barrier; + GameObject* go_aq_gate_runes; + GameObject* go_aq_gate_roots; // Invisible AQ barrier - removed by server during event, but we are allow event to repeat, so we do not place it // GameObject *go_aq_ghost_gate; - explicit gobject_scarab_gongAI(GameObject *object) : GameObjectAI(object) + explicit gobject_scarab_gongAI(GameObject* object) : GameObjectAI(object) { eventTimer = 0; eventStep = 0; @@ -84,10 +313,10 @@ public: Player* target = ObjectAccessor::FindConnectedPlayer(player->GetGUID()); if (!target) { - return false; + return false; } - /* The Scarab Gong can still be seen during the outdoor AQ war. */ + /* The Scarab Gong can still be seen during the outdoor AQ war. */ if (sIndividualProgression->hasPassedProgression(target, PROGRESSION_AQ_WAR)) { return sIndividualProgression->isBeforeProgression(target, PROGRESSION_PRE_AQ); @@ -157,13 +386,12 @@ public: eventStage = STAGE_OPEN_GATES; // Reset to the initial stage for potential future events } - - void OpenGate(Player *player, bool announce) + void OpenGate(Player* player, bool announce) { go_aq_barrier = GetClosestGameObjectWithEntry(me, GO_GATE_OF_AHN_QIRAJ, 150); go_aq_gate_runes = GetClosestGameObjectWithEntry(me, GO_GLYPH_OF_AHN_QIRAJ, 150); go_aq_gate_roots = GetClosestGameObjectWithEntry(me, GO_ROOTS_OF_AHN_QIRAJ, 150); -// go_aq_ghost_gate = GetClosestGameObjectWithEntry(me, GO_AQ_GHOST_GATE, 150); + // go_aq_ghost_gate = GetClosestGameObjectWithEntry(me, GO_AQ_GHOST_GATE, 150); if (!go_aq_barrier || !go_aq_gate_runes || !go_aq_gate_roots) return; @@ -180,17 +408,17 @@ public: } }; - GameObjectAI *GetAI(GameObject *object) const override + GameObjectAI* GetAI(GameObject* object) const override { return new gobject_scarab_gongAI(object); } - bool OnQuestReward(Player *player, GameObject *go, Quest const *quest, uint32 /*opt*/) override + bool OnQuestReward(Player* player, GameObject* go, Quest const* quest, uint32 /*opt*/) override { - if (quest->GetQuestId() != QUEST_BANG_A_GONG) + if ((quest->GetQuestId() != QUEST_BANG_A_GONG) && (player->GetQuestStatus(SIMPLY_BANG_A_GONG) != QUEST_STATUS_REWARDED)) return false; - if (auto *gongAI = dynamic_cast(go->AI())) + if (auto* gongAI = dynamic_cast(go->AI())) gongAI->OpenGate(player, true); return true; @@ -198,9 +426,9 @@ public: bool OnGossipHello(Player* player, GameObject* go) override { - if (player->GetQuestStatus(QUEST_BANG_A_GONG) == QUEST_STATUS_REWARDED) + if ((player->GetQuestStatus(QUEST_BANG_A_GONG) == QUEST_STATUS_REWARDED) || (player->GetQuestStatus(SIMPLY_BANG_A_GONG) == QUEST_STATUS_REWARDED)) { - if (auto *gongAI = dynamic_cast(go->AI())) + if (auto* gongAI = dynamic_cast(go->AI())) gongAI->OpenGate(player, false); } else @@ -226,10 +454,10 @@ public: Player* target = ObjectAccessor::FindConnectedPlayer(player->GetGUID()); if (!target) { - return false; + return false; } - return sIndividualProgression->isBeforeProgression(target, PROGRESSION_PRE_AQ); + return sIndividualProgression->isBeforeProgression(target, PROGRESSION_PRE_AQ); } }; @@ -239,9 +467,644 @@ public: } }; +class npc_anachronos_the_ancient : public CreatureScript +{ +public: + npc_anachronos_the_ancient() : CreatureScript("npc_anachronos_the_ancient") {} + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_anachronos_the_ancientAI(creature); + } + + struct npc_anachronos_the_ancientAI : public ScriptedAI + { + npc_anachronos_the_ancientAI(Creature* creature) : ScriptedAI(creature) {} + + uint32 AnimationTimer; + uint8 AnimationCount; + + ObjectGuid AnachronosQuestTriggerGUID; + ObjectGuid MerithraGUID; + ObjectGuid ArygosGUID; + ObjectGuid CaelestraszGUID; + ObjectGuid FandralGUID; + ObjectGuid PlayerGUID; + bool eventEnd; + + void Reset() override + { + AnimationTimer = 1500; + AnimationCount = 0; + AnachronosQuestTriggerGUID.Clear(); + MerithraGUID.Clear(); + ArygosGUID.Clear(); + CaelestraszGUID.Clear(); + FandralGUID.Clear(); + PlayerGUID.Clear(); + eventEnd = false; + + me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + } + + void HandleAnimation() + { + Player* player = ObjectAccessor::FindConnectedPlayer(PlayerGUID); + + if (!player) + { + return; + } + + Creature* Fandral = player->FindNearestCreature(C_FANDRAL_STAGHELM, 100.0f); + Creature* Arygos = player->FindNearestCreature(C_ARYGOS, 100.0f); + Creature* Caelestrasz = player->FindNearestCreature(C_CAELESTRASZ, 100.0f); + Creature* Merithra = player->FindNearestCreature(C_MERITHRA, 100.0f); + + if (!Fandral || !Arygos || !Caelestrasz || !Merithra) + return; + + AnimationTimer = EventAnim[AnimationCount].Timer; + if (!eventEnd) + { + switch (AnimationCount) + { + case 0: + Talk(ANACHRONOS_SAY_1, Fandral); + break; + case 1: + Fandral->SetTarget(me->GetGUID()); + Fandral->AI()->Talk(FANDRAL_SAY_1, me); + break; + case 2: + Fandral->SetTarget(); + Merithra->AI()->Talk(MERITHRA_EMOTE_1); + break; + case 3: + Merithra->AI()->Talk(MERITHRA_SAY_1); + break; + case 4: + Arygos->AI()->Talk(ARYGOS_EMOTE_1); + break; + case 5: + Caelestrasz->SetTarget(Fandral->GetGUID()); + Caelestrasz->AI()->Talk(CAELESTRASZ_SAY_1); + break; + case 6: + Merithra->AI()->Talk(MERITHRA_SAY_2); + break; + case 7: + Caelestrasz->SetTarget(); + Merithra->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); + break; + case 8: + Merithra->AI()->Talk(MERITHRA_YELL_1); + break; + case 9: + Merithra->CastSpell(Merithra, 25105, true); + break; + case 10: + break; + case 11: + Merithra->CastSpell(Merithra, 24818, false); + break; + case 12: + Merithra->GetMotionMaster()->MovePoint(1, -8100, 1530, 50); + break; + case 13: + break; + case 14: + Arygos->AI()->Talk(ARYGOS_SAY_1); + break; + case 15: + Merithra->SetVisible(false); + Merithra->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 42); + Arygos->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); + break; + case 16: + Arygos->AI()->Talk(ARYGOS_YELL_1); + break; + case 17: + Arygos->CastSpell(Arygos, 25107, true); + break; + case 18: + break; + case 19: + Arygos->CastSpell(Arygos, 50505, false); + break; + case 20: + Arygos->GetMotionMaster()->MovePoint(1, -8100, 1530, 50); + break; + case 21: + break; + case 22: + Caelestrasz->AI()->Talk(CAELESTRASZ_SAY_2, Fandral); + break; + case 23: + Arygos->SetVisible(false); + Arygos->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 10); + Caelestrasz->GetMotionMaster()->MoveCharge(-8065, 1530, 2.61f, 10); + break; + case 24: + Caelestrasz->AI()->Talk(CAELESTRASZ_YELL_1); + break; + case 25: + Caelestrasz->CastSpell(Caelestrasz, 25106, true); + break; + case 26: + break; + case 27: + Caelestrasz->CastSpell(Caelestrasz, 54293, false); + break; + case 28: + Caelestrasz->GetMotionMaster()->MovePoint(1, -8100, 1530, 50); + Talk(ANACHRONOS_SAY_2, Fandral); + break; + case 29: + Fandral->AI()->Talk(FANDRAL_SAY_2); + break; + case 30: + break; + case 31: + Caelestrasz->SetVisible(false); + Caelestrasz->GetMotionMaster()->MoveCharge(-8034.535f, 1535.14f, 2.61f, 42); + Talk(ANACHRONOS_SAY_3, Fandral); + break; + case 32: + Fandral->GetMotionMaster()->MoveCharge(-8108, 1529, 2.77f, 8); + me->GetMotionMaster()->MoveCharge(-8113, 1525, 2.77f, 8); + break;//both run to the gate + case 33: + Talk(ANACHRONOS_SAY_4); + Caelestrasz->GetMotionMaster()->MoveCharge(-8050, 1473, 65, 15); + break; //Text: sands will stop + case 34: + DoCast(player, 23017, true);//Arcane Channeling + break; + case 35: + me->CastSpell(-8088, 1520.43f, 2.67f, 25158, true); + break; + case 36: + DoCast(player, 25159, true); + break; + case 37: + me->SummonGameObject(GO_GATE_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); + break; + case 38: + DoCast(player, 25166, true); + me->SummonGameObject(GO_GLYPH_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); + break; + case 39: + Talk(ANACHRONOS_SAY_5, Fandral); + break; + case 40: + Fandral->CastSpell(me, 25167, true); + break; + case 41: + Fandral->SummonGameObject(GO_ROOTS_OF_AHN_QIRAJ, -8130, 1525, 17.5f, 0, 0, 0, 0, 0, 0); + Fandral->AI()->Talk(FANDRAL_SAY_3); + break; + case 42: + me->CastStop(); + Fandral->AI()->Talk(FANDRAL_EMOTE_1); + break; + case 43: + Fandral->CastStop(); + break; + case 44: + Talk(ANACHRONOS_SAY_6); + break; + case 45: + Talk(ANACHRONOS_SAY_7); + break; + case 46: + Talk(ANACHRONOS_SAY_8); + me->GetMotionMaster()->MoveCharge(-8110, 1527, 2.77f, 4); + break; + case 47: + Talk(ANACHRONOS_EMOTE_1); + break; + case 48: + Fandral->AI()->Talk(FANDRAL_SAY_4, me); + break; + case 49: + Fandral->AI()->Talk(FANDRAL_SAY_5, me); + break; + case 50: + Fandral->AI()->Talk(FANDRAL_EMOTE_2); + Fandral->CastSpell(-8127, 1525, 17.5f, 33806, true); + break; + case 51: + { + std::list constructList; + + me->GetCreatureListWithEntryInGrid(constructList, 15423, 100.0f); + me->GetCreatureListWithEntryInGrid(constructList, 15424, 100.0f); + me->GetCreatureListWithEntryInGrid(constructList, 15414, 100.0f); + me->GetCreatureListWithEntryInGrid(constructList, 15422, 100.0f); + + if (!constructList.empty()) + { + for (std::list::const_iterator itr = constructList.begin(); itr != constructList.end(); ++itr) + { + (*itr)->RemoveFromWorld(); + } + } + + break; + } + case 52: + Fandral->GetMotionMaster()->MoveCharge(-8028.75f, 1538.795f, 2.61f, 4); + Talk(ANACHRONOS_SAY_9); + break; + case 53: + Fandral->AI()->Talk(FANDRAL_SAY_6); + break; + case 54: + Talk(ANACHRONOS_EMOTE_2); + break; + case 55: + //Fandral should not dispear atm. + //Fandral->SetVisible(false); + break; + case 56: + Talk(ANACHRONOS_EMOTE_3); + me->GetMotionMaster()->MoveCharge(-8116, 1522, 3.65f, 4); + break; + case 57: + me->GetMotionMaster()->MoveCharge(-8116.7f, 1527, 3.7f, 4); + break; + case 58: + me->GetMotionMaster()->MoveCharge(-8112.67f, 1529.9f, 2.86f, 4); + break; + case 59: + me->GetMotionMaster()->MoveCharge(-8117.99f, 1532.24f, 3.94f, 4); + break; + case 60: + Talk(ANACHRONOS_SAY_10, player); + me->GetMotionMaster()->MoveCharge(-8113.46f, 1524.16f, 2.89f, 4); + break; + case 61: + me->GetMotionMaster()->MoveCharge(-8057.1f, 1470.32f, 2.61f, 6); + + if (player->IsInRange(me, 0, 20)) + player->GroupEventHappens(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD, me); + break; + case 62: + me->SetDisplayId(15500); + break; + case 63: + me->HandleEmoteCommand(254); + me->SetDisableGravity(true); + break; + case 64: + me->GetMotionMaster()->MoveCharge(-8000, 1400, 150, 9); + me->SetVisible(false); + break; + case 65: + if (Creature* AnachronosQuestTrigger = (ObjectAccessor::GetCreature(*me, AnachronosQuestTriggerGUID))) + { + Talk(ARYGOS_YELL_1); + AnachronosQuestTrigger->AI()->EnterEvadeMode(); + eventEnd = true; + } + break; + } + } + ++AnimationCount; + } + void UpdateAI(uint32 diff) override + { + if (AnimationTimer) + { + if (AnimationTimer <= diff) + HandleAnimation(); + else AnimationTimer -= diff; + } + if (AnimationCount < 65) + me->CombatStop(); + if (AnimationCount == 65 || eventEnd) + EnterEvadeMode(); + } + }; +}; + +class npc_qiraj_war_spawn : public CreatureScript +{ +public: + npc_qiraj_war_spawn() : CreatureScript("npc_qiraj_war_spawn") {} + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_qiraj_war_spawnAI(creature); + } + + struct npc_qiraj_war_spawnAI : public ScriptedAI + { + npc_qiraj_war_spawnAI(Creature* creature) : ScriptedAI(creature) {} + + ObjectGuid MobGUID; + ObjectGuid PlayerGUID; + uint32 SpellTimer1, SpellTimer2, SpellTimer3, SpellTimer4; + bool Timers; + bool hasTarget; + + void Reset() override + { + MobGUID.Clear(); + PlayerGUID.Clear(); + Timers = false; + hasTarget = false; + } + + void JustEngagedWith(Unit* /*who*/) override {} + void JustDied(Unit* /*slayer*/) override; + + void UpdateAI(uint32 diff) override + { + if (!Timers) + { + if (me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) //all but Kaldorei Soldiers + { + SpellTimer1 = SpawnCast[1].Timer1; + SpellTimer2 = SpawnCast[2].Timer1; + SpellTimer3 = SpawnCast[3].Timer1; + } + if (me->GetEntry() == 15423 || me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) + SpellTimer4 = SpawnCast[0].Timer1; + Timers = true; + } + if (me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) + { + if (SpellTimer1 <= diff) + { + DoCast(me, SpawnCast[1].SpellId); + DoCast(me, 24319); + SpellTimer1 = SpawnCast[1].Timer2; + } + else SpellTimer1 -= diff; + if (SpellTimer2 <= diff) + { + DoCast(me, SpawnCast[2].SpellId); + SpellTimer2 = SpawnCast[2].Timer2; + } + else SpellTimer2 -= diff; + if (SpellTimer3 <= diff) + { + DoCast(me, SpawnCast[3].SpellId); + SpellTimer3 = SpawnCast[3].Timer2; + } + else SpellTimer3 -= diff; + } + if (me->GetEntry() == 15423 || me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) + { + if (SpellTimer4 <= diff) + { + me->RemoveAllAttackers(); + me->AttackStop(); + DoCast(me, 15533); + SpellTimer4 = SpawnCast[0].Timer2; + } + else SpellTimer4 -= diff; + } + if (!hasTarget) + { + Unit* target = nullptr; + if (me->GetEntry() == 15424 || me->GetEntry() == 15422 || me->GetEntry() == 15414) + target = me->FindNearestCreature(15423, 20, true); + if (me->GetEntry() == 15423) + { + uint8 tar = urand(0, 2); + + if (tar == 0) + target = me->FindNearestCreature(15422, 20, true); + else if (tar == 1) + target = me->FindNearestCreature(15424, 20, true); + else if (tar == 2) + target = me->FindNearestCreature(15414, 20, true); + } + hasTarget = true; + if (target) + AttackStart(target); + } + if (!(me->FindNearestCreature(15379, 60))) + DoCast(me, 33652); + + if (!UpdateVictim()) + { + hasTarget = false; + return; + } + + DoMeleeAttackIfReady(); + } + }; +}; + +class npc_anachronos_quest_trigger : public CreatureScript +{ +public: + npc_anachronos_quest_trigger() : CreatureScript("npc_anachronos_quest_trigger") {} + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_anachronos_quest_triggerAI(creature); + } + + struct npc_anachronos_quest_triggerAI : public ScriptedAI + { + npc_anachronos_quest_triggerAI(Creature* creature) : ScriptedAI(creature) {} + + ObjectGuid PlayerGUID; + + uint32 WaveTimer; + uint32 AnnounceTimer; + + int8 LiveCount; + uint8 WaveCount; + + bool EventStarted; + bool Announced; + bool Failed; + + void Reset() override + { + PlayerGUID.Clear(); + + WaveTimer = 2000; + AnnounceTimer = 1000; + LiveCount = 0; + WaveCount = 0; + + EventStarted = false; + Announced = false; + Failed = false; + + me->SetVisible(false); + } + + void SummonNextWave() + { + uint8 locIndex = WavesInfo[WaveCount].UsedSpawnPoint; + uint8 count = locIndex + WavesInfo[WaveCount].SpawnCount; + + for (uint8 i = locIndex; i <= count; ++i) + { + uint32 desptimer = WavesInfo[WaveCount].DespTimer; + + if (Creature* spawn = me->SummonCreature(WavesInfo[WaveCount].CreatureId, SpawnLocation[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, desptimer)) + { + if (spawn->GetEntry() == 15423) + spawn->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15427 + rand() % 4); + if (i >= 30) WaveCount = 1; + if (i >= 33) WaveCount = 2; + if (i >= 45) WaveCount = 3; + if (i >= 51) WaveCount = 4; + + if (WaveCount < 5) //1-4 Wave + { + if (npc_qiraj_war_spawn::npc_qiraj_war_spawnAI* spawnAI = CAST_AI(npc_qiraj_war_spawn::npc_qiraj_war_spawnAI, spawn->AI())) + { + spawnAI->MobGUID = me->GetGUID(); + spawnAI->PlayerGUID = PlayerGUID; + } + } + } + } + + WaveTimer = WavesInfo[WaveCount].SpawnTimer; + AnnounceTimer = WavesInfo[WaveCount].YellTimer; + } + + void CheckEventFail() + { + Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID); + if (!player) + return; + + if (Group* EventGroup = player->GetGroup()) + { + uint8 GroupMemberCount = 0; + uint8 FailedMemberCount = 0; + + Group::MemberSlotList const& members = EventGroup->GetMemberSlots(); + + for (Group::member_citerator itr = members.begin(); itr != members.end(); ++itr) + { + Player* groupMember = ObjectAccessor::GetPlayer(*me, itr->guid); + if (!groupMember) + continue; + if (!groupMember->IsWithinDistInMap(me, EVENT_AREA_RADIUS) && groupMember->GetQuestStatus(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) == QUEST_STATUS_INCOMPLETE) + { + groupMember->FailQuest(QUEST_A_PAWN_ON_THE_ETERNAL_BOARD); + ++FailedMemberCount; + } + ++GroupMemberCount; + } + + if (GroupMemberCount == FailedMemberCount || !player->IsWithinDistInMap(me, EVENT_AREA_RADIUS)) + Failed = true; //only so event can restart + } + } + + void LiveCounter() + { + --LiveCount; + if (!LiveCount) + Announced = false; + } + + void UpdateAI(uint32 diff) override + { + if (!PlayerGUID || !EventStarted) + return; + + if (WaveCount < 4) + { + if (!Announced && AnnounceTimer <= diff) + { + Talk(WavesInfo[WaveCount].WaveTextId); + Announced = true; + } + else AnnounceTimer -= diff; + + if (WaveTimer <= diff) + SummonNextWave(); + else WaveTimer -= diff; + } + CheckEventFail(); + if (WaveCount == 4 || Failed) + EnterEvadeMode(); + }; + }; +}; + +class gobject_crystalline_tear : public GameObjectScript +{ +public: + gobject_crystalline_tear() : GameObjectScript("gobject_crystalline_tear") {} + + bool OnQuestAccept(Player* player, GameObject* go, Quest const* quest) override + { + if (quest->GetQuestId() == QUEST_A_PAWN_ON_THE_ETERNAL_BOARD) + { + if (Creature* trigger = go->FindNearestCreature(15454, 100, player)) + { + Unit* Merithra = trigger->SummonCreature(15378, -8034.535f, 1535.14f, 2.61f, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Unit* Caelestrasz = trigger->SummonCreature(15379, -8032.767f, 1533.148f, 2.61f, 1.5f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Unit* Arygos = trigger->SummonCreature(15380, -8034.52f, 1537.843f, 2.61f, 5.7f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + /* Unit* Fandral = */ trigger->SummonCreature(15382, -8028.462f, 1535.843f, 2.61f, 3.141592f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + Creature* Anachronos = trigger->SummonCreature(15381, -8028.75f, 1538.795f, 2.61f, 4, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 220000); + + if (Merithra) + { + Merithra->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE); + Merithra->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Merithra->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15420); + Merithra->SetFaction(FACTION_FRIENDLY); + } + + if (Caelestrasz) + { + Caelestrasz->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE); + Caelestrasz->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Caelestrasz->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15419); + Caelestrasz->SetFaction(FACTION_FRIENDLY); + } + + if (Arygos) + { + Arygos->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE); + Arygos->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); + Arygos->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15418); + Arygos->SetFaction(FACTION_FRIENDLY); + } + + if (Anachronos) + { + if (npc_anachronos_the_ancient::npc_anachronos_the_ancientAI* anachronosAI = CAST_AI(npc_anachronos_the_ancient::npc_anachronos_the_ancientAI, Anachronos->AI())) + anachronosAI->PlayerGUID = player->GetGUID(); + + if (npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI* triggerAI = CAST_AI(npc_anachronos_quest_trigger::npc_anachronos_quest_triggerAI, trigger->AI())) + { + triggerAI->Failed = false; + triggerAI->PlayerGUID = player->GetGUID(); + triggerAI->EventStarted = true; + triggerAI->Announced = true; + } + } + } + } + return true; + } +}; + void AddSC_aq_scripts() { new aq_gate(); new gobject_scarab_gong(); + new gobject_crystalline_tear(); + new npc_anachronos_quest_trigger(); + new npc_anachronos_the_ancient(); + new npc_qiraj_war_spawn(); } -