diff options
Diffstat (limited to 'src')
7 files changed, 1158 insertions, 1256 deletions
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp index d0a6cee6b06..e9f65398e38 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp @@ -27,7 +27,7 @@ #include "SpellInfo.h" #include "TemporarySummon.h" -enum Says +enum KaelthasTexts { // Kael'thas Sunstrider SAY_INTRO_1 = 0, @@ -41,7 +41,7 @@ enum Says SAY_DEATH = 8 }; -enum Spells +enum KaelthasSpells { // Kael'thas Sunstrider SPELL_FIREBALL = 44189, @@ -89,7 +89,7 @@ uint32 gravityLapseTeleportSpells[] = #define SPELL_GRAVITY_LAPSE_DAMAGE RAID_MODE<uint32>(49887, 44226) -enum Events +enum KaelthasEvents { // Kael'thas Sunstrider EVENT_TALK_INTRO_1 = 1, @@ -120,7 +120,7 @@ enum Events EVENT_PREPARE_REENGAGE }; -enum Phases +enum KaelthasPhases { PHASE_INTRO = 0, PHASE_ONE = 1, @@ -128,6 +128,7 @@ enum Phases PHASE_OUTRO = 3 }; +// 24664 - Kael'thas Sunstrider struct boss_felblood_kaelthas : public BossAI { boss_felblood_kaelthas(Creature* creature) : BossAI(creature, DATA_KAELTHAS_SUNSTRIDER) @@ -380,6 +381,7 @@ private: bool _firstGravityLapse; }; +// 24674 - Phoenix struct npc_felblood_kaelthas_phoenix : public ScriptedAI { npc_felblood_kaelthas_phoenix(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp index 1747d99f3db..ec0521a4866 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp @@ -51,13 +51,13 @@ static Speech PlayerDeath[]= {9}, }; -enum Yells +enum DelrissaTexts { - SAY_AGGRO = 0, - SAY_DEATH = 10, + SAY_AGGRO = 0, + SAY_DEATH = 10 }; -enum Spells +enum DelrissaSpells { SPELL_DISPEL_MAGIC = 27609, SPELL_FLASH_HEAL = 17843, @@ -65,21 +65,12 @@ enum Spells SPELL_SW_PAIN_HEROIC = 15654, SPELL_SHIELD = 44291, SPELL_RENEW_NORMAL = 44174, - SPELL_RENEW_HEROIC = 46192, - - // Apoko - SPELL_WINDFURY_TOTEM = 27621, - SPELL_WAR_STOMP = 46026, - SPELL_PURGE = 27626, - SPELL_LESSER_HEALING_WAVE = 44256, - SPELL_FROST_SHOCK = 21401, - SPELL_FIRE_NOVA_TOTEM = 44257, - SPELL_EARTHBIND_TOTEM = 15786 + SPELL_RENEW_HEROIC = 46192 }; -enum Misc +enum DelrissaMisc { - MAX_ACTIVE_LACKEY = 4 + MAX_ACTIVE_LACKEY = 4 }; const float fOrientation = 4.98f; @@ -105,247 +96,236 @@ const uint32 m_auiAddEntries[] = 24556, //Zelfan }; -class boss_priestess_delrissa : public CreatureScript +// 24560 - Priestess Delrissa +struct boss_priestess_delrissa : public ScriptedAI { -public: - boss_priestess_delrissa() : CreatureScript("boss_priestess_delrissa") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_priestess_delrissa(Creature* creature) : ScriptedAI(creature) { - return GetMagistersTerraceAI<boss_priestess_delrissaAI>(creature); + Initialize(); + instance = creature->GetInstanceScript(); + LackeyEntryList.clear(); } - struct boss_priestess_delrissaAI : public ScriptedAI + void Initialize() { - boss_priestess_delrissaAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - LackeyEntryList.clear(); - } + PlayersKilled = 0; + + HealTimer = 15000; + RenewTimer = 10000; + ShieldTimer = 2000; + SWPainTimer = 5000; + DispelTimer = 7500; + ResetTimer = 5000; + } - void Initialize() - { - PlayersKilled = 0; + InstanceScript* instance; - HealTimer = 15000; - RenewTimer = 10000; - ShieldTimer = 2000; - SWPainTimer = 5000; - DispelTimer = 7500; - ResetTimer = 5000; - } + std::vector<uint32> LackeyEntryList; + ObjectGuid m_auiLackeyGUID[MAX_ACTIVE_LACKEY]; - InstanceScript* instance; + uint8 PlayersKilled; - std::vector<uint32> LackeyEntryList; - ObjectGuid m_auiLackeyGUID[MAX_ACTIVE_LACKEY]; + uint32 HealTimer; + uint32 RenewTimer; + uint32 ShieldTimer; + uint32 SWPainTimer; + uint32 DispelTimer; + uint32 ResetTimer; - uint8 PlayersKilled; + void Reset() override + { + Initialize(); - uint32 HealTimer; - uint32 RenewTimer; - uint32 ShieldTimer; - uint32 SWPainTimer; - uint32 DispelTimer; - uint32 ResetTimer; + InitializeLackeys(); + } - void Reset() override - { - Initialize(); + //this mean she at some point evaded + void JustReachedHome() override + { + instance->SetBossState(DATA_PRIESTESS_DELRISSA, FAIL); + } - InitializeLackeys(); - } + void JustEngagedWith(Unit* who) override + { + Talk(SAY_AGGRO); - //this mean she at some point evaded - void JustReachedHome() override - { - instance->SetBossState(DATA_PRIESTESS_DELRISSA, FAIL); - } + for (uint8 i = 0; i < MAX_ACTIVE_LACKEY; ++i) + if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[i])) + if (!pAdd->IsEngaged()) + AddThreat(who, 0.0f, pAdd); - void JustEngagedWith(Unit* who) override - { - Talk(SAY_AGGRO); + instance->SetBossState(DATA_PRIESTESS_DELRISSA, IN_PROGRESS); + } - for (uint8 i = 0; i < MAX_ACTIVE_LACKEY; ++i) - if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[i])) - if (!pAdd->IsEngaged()) - AddThreat(who, 0.0f, pAdd); + void InitializeLackeys() + { + //can be called if Creature are dead, so avoid + if (!me->IsAlive()) + return; - instance->SetBossState(DATA_PRIESTESS_DELRISSA, IN_PROGRESS); - } + uint8 j = 0; - void InitializeLackeys() + //it's empty, so first time + if (LackeyEntryList.empty()) { - //can be called if Creature are dead, so avoid - if (!me->IsAlive()) - return; - - uint8 j = 0; - - //it's empty, so first time - if (LackeyEntryList.empty()) - { - //pre-allocate size for speed - LackeyEntryList.resize((sizeof(m_auiAddEntries) / sizeof(uint32))); + //pre-allocate size for speed + LackeyEntryList.resize((sizeof(m_auiAddEntries) / sizeof(uint32))); - //fill vector array with entries from Creature array - for (uint8 i = 0; i < LackeyEntryList.size(); ++i) - LackeyEntryList[i] = m_auiAddEntries[i]; + //fill vector array with entries from Creature array + for (uint8 i = 0; i < LackeyEntryList.size(); ++i) + LackeyEntryList[i] = m_auiAddEntries[i]; - //remove random entries - while (LackeyEntryList.size() > MAX_ACTIVE_LACKEY) - LackeyEntryList.erase(LackeyEntryList.begin() + rand32() % LackeyEntryList.size()); + //remove random entries + while (LackeyEntryList.size() > MAX_ACTIVE_LACKEY) + LackeyEntryList.erase(LackeyEntryList.begin() + rand32() % LackeyEntryList.size()); - //summon all the remaining in vector - for (std::vector<uint32>::const_iterator itr = LackeyEntryList.begin(); itr != LackeyEntryList.end(); ++itr) - { - if (Creature* pAdd = me->SummonCreature((*itr), LackeyLocations[j][0], LackeyLocations[j][1], fZLocation, fOrientation, TEMPSUMMON_CORPSE_DESPAWN)) - m_auiLackeyGUID[j] = pAdd->GetGUID(); + //summon all the remaining in vector + for (std::vector<uint32>::const_iterator itr = LackeyEntryList.begin(); itr != LackeyEntryList.end(); ++itr) + { + if (Creature* pAdd = me->SummonCreature((*itr), LackeyLocations[j][0], LackeyLocations[j][1], fZLocation, fOrientation, TEMPSUMMON_CORPSE_DESPAWN)) + m_auiLackeyGUID[j] = pAdd->GetGUID(); - ++j; - } + ++j; } - else + } + else + { + for (std::vector<uint32>::const_iterator itr = LackeyEntryList.begin(); itr != LackeyEntryList.end(); ++itr) { - for (std::vector<uint32>::const_iterator itr = LackeyEntryList.begin(); itr != LackeyEntryList.end(); ++itr) - { - Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[j]); + Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[j]); - //object already removed, not exist - if (!pAdd) - { - pAdd = me->SummonCreature((*itr), LackeyLocations[j][0], LackeyLocations[j][1], fZLocation, fOrientation, TEMPSUMMON_CORPSE_DESPAWN); - if (pAdd) - m_auiLackeyGUID[j] = pAdd->GetGUID(); - } - ++j; + //object already removed, not exist + if (!pAdd) + { + pAdd = me->SummonCreature((*itr), LackeyLocations[j][0], LackeyLocations[j][1], fZLocation, fOrientation, TEMPSUMMON_CORPSE_DESPAWN); + if (pAdd) + m_auiLackeyGUID[j] = pAdd->GetGUID(); } + ++j; } } + } - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() != TYPEID_PLAYER) - return; + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() != TYPEID_PLAYER) + return; - Talk(PlayerDeath[PlayersKilled].id); + Talk(PlayerDeath[PlayersKilled].id); - if (PlayersKilled < 4) - ++PlayersKilled; - } + if (PlayersKilled < 4) + ++PlayersKilled; + } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); - if (instance->GetData(DATA_DELRISSA_DEATH_COUNT) == MAX_ACTIVE_LACKEY) - instance->SetBossState(DATA_PRIESTESS_DELRISSA, DONE); - else - me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE); - } + if (instance->GetData(DATA_DELRISSA_DEATH_COUNT) == MAX_ACTIVE_LACKEY) + instance->SetBossState(DATA_PRIESTESS_DELRISSA, DONE); + else + me->RemoveDynamicFlag(UNIT_DYNFLAG_LOOTABLE); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) override + if (ResetTimer <= diff) { - if (!UpdateVictim()) + float x, y, z, o; + me->GetHomePosition(x, y, z, o); + if (me->GetPositionZ() >= z+10) + { + EnterEvadeMode(); return; + } + ResetTimer = 5000; + } else ResetTimer -= diff; - if (ResetTimer <= diff) + if (HealTimer <= diff) + { + uint32 health = me->GetHealth(); + Unit* target = me; + for (uint8 i = 0; i < MAX_ACTIVE_LACKEY; ++i) { - float x, y, z, o; - me->GetHomePosition(x, y, z, o); - if (me->GetPositionZ() >= z+10) + if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[i])) { - EnterEvadeMode(); - return; + if (pAdd->IsAlive() && pAdd->GetHealth() < health) + target = pAdd; } - ResetTimer = 5000; - } else ResetTimer -= diff; + } - if (HealTimer <= diff) - { - uint32 health = me->GetHealth(); - Unit* target = me; - for (uint8 i = 0; i < MAX_ACTIVE_LACKEY; ++i) - { - if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[i])) - { - if (pAdd->IsAlive() && pAdd->GetHealth() < health) - target = pAdd; - } - } + DoCast(target, SPELL_FLASH_HEAL); + HealTimer = 15000; + } else HealTimer -= diff; - DoCast(target, SPELL_FLASH_HEAL); - HealTimer = 15000; - } else HealTimer -= diff; + if (RenewTimer <= diff) + { + Unit* target = me; - if (RenewTimer <= diff) - { - Unit* target = me; + if (urand(0, 1)) + if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[rand32() % MAX_ACTIVE_LACKEY])) + if (pAdd->IsAlive()) + target = pAdd; - if (urand(0, 1)) - if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[rand32() % MAX_ACTIVE_LACKEY])) - if (pAdd->IsAlive()) - target = pAdd; + DoCast(target, SPELL_RENEW_NORMAL); + RenewTimer = 5000; + } else RenewTimer -= diff; - DoCast(target, SPELL_RENEW_NORMAL); - RenewTimer = 5000; - } else RenewTimer -= diff; + if (ShieldTimer <= diff) + { + Unit* target = me; - if (ShieldTimer <= diff) - { - Unit* target = me; + if (urand(0, 1)) + if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[rand32() % MAX_ACTIVE_LACKEY])) + if (pAdd->IsAlive() && !pAdd->HasAura(SPELL_SHIELD)) + target = pAdd; - if (urand(0, 1)) - if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[rand32() % MAX_ACTIVE_LACKEY])) - if (pAdd->IsAlive() && !pAdd->HasAura(SPELL_SHIELD)) - target = pAdd; + DoCast(target, SPELL_SHIELD); + ShieldTimer = 7500; + } else ShieldTimer -= diff; - DoCast(target, SPELL_SHIELD); - ShieldTimer = 7500; - } else ShieldTimer -= diff; + if (DispelTimer <= diff) + { + Unit* target = nullptr; - if (DispelTimer <= diff) + if (urand(0, 1)) + target = SelectTarget(SelectTargetMethod::Random, 0, 100, true); + else { - Unit* target = nullptr; - if (urand(0, 1)) - target = SelectTarget(SelectTargetMethod::Random, 0, 100, true); + target = me; else - { - if (urand(0, 1)) - target = me; - else - if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[rand32() % MAX_ACTIVE_LACKEY])) - if (pAdd->IsAlive()) - target = pAdd; - } + if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUID[rand32() % MAX_ACTIVE_LACKEY])) + if (pAdd->IsAlive()) + target = pAdd; + } - if (target) - DoCast(target, SPELL_DISPEL_MAGIC); + if (target) + DoCast(target, SPELL_DISPEL_MAGIC); - DispelTimer = 12000; - } else DispelTimer -= diff; + DispelTimer = 12000; + } else DispelTimer -= diff; - if (SWPainTimer <= diff) - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true)) - DoCast(target, SPELL_SW_PAIN_NORMAL); + if (SWPainTimer <= diff) + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true)) + DoCast(target, SPELL_SW_PAIN_NORMAL); - SWPainTimer = 10000; - } else SWPainTimer -= diff; + SWPainTimer = 10000; + } else SWPainTimer -= diff; - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; -enum HealingPotion +enum LackeySpells { SPELL_HEALING_POTION = 15503 }; -//all 8 possible lackey use this common struct boss_priestess_lackey_commonAI : public ScriptedAI { boss_priestess_lackey_commonAI(Creature* creature) : ScriptedAI(creature) @@ -439,7 +419,7 @@ struct boss_priestess_lackey_commonAI : public ScriptedAI if (Creature* delrissa = instance->GetCreature(DATA_PRIESTESS_DELRISSA)) { for (uint8 i = 0; i < MAX_ACTIVE_LACKEY; ++i) - m_auiLackeyGUIDs[i] = ENSURE_AI(boss_priestess_delrissa::boss_priestess_delrissaAI, delrissa->AI())->m_auiLackeyGUID[i]; + m_auiLackeyGUIDs[i] = ENSURE_AI(boss_priestess_delrissa, delrissa->AI())->m_auiLackeyGUID[i]; } } @@ -469,105 +449,94 @@ enum RogueSpells SPELL_EVISCERATE = 27611 }; -class boss_kagani_nightstrike : public CreatureScript +// 24557 - Kagani Nightstrike (Rogue) +struct boss_kagani_nightstrike : public boss_priestess_lackey_commonAI { -public: - boss_kagani_nightstrike() : CreatureScript("boss_kagani_nightstrike") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_kagani_nightstrike(Creature* creature) : boss_priestess_lackey_commonAI(creature) { - return GetMagistersTerraceAI<boss_kagani_nightstrikeAI>(creature); + Initialize(); } - struct boss_kagani_nightstrikeAI : public boss_priestess_lackey_commonAI + void Initialize() { - //Rogue - boss_kagani_nightstrikeAI(Creature* creature) : boss_priestess_lackey_commonAI(creature) - { - Initialize(); - } - - void Initialize() - { - Gouge_Timer = 5500; - Kick_Timer = 7000; - Vanish_Timer = 2000; - Eviscerate_Timer = 6000; - Wait_Timer = 5000; - InVanish = false; - } + Gouge_Timer = 5500; + Kick_Timer = 7000; + Vanish_Timer = 2000; + Eviscerate_Timer = 6000; + Wait_Timer = 5000; + InVanish = false; + } - uint32 Gouge_Timer; - uint32 Kick_Timer; - uint32 Vanish_Timer; - uint32 Eviscerate_Timer; - uint32 Wait_Timer; - bool InVanish; + uint32 Gouge_Timer; + uint32 Kick_Timer; + uint32 Vanish_Timer; + uint32 Eviscerate_Timer; + uint32 Wait_Timer; + bool InVanish; - void Reset() override - { - Initialize(); - me->SetVisible(true); + void Reset() override + { + Initialize(); + me->SetVisible(true); - boss_priestess_lackey_commonAI::Reset(); - } + boss_priestess_lackey_commonAI::Reset(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - boss_priestess_lackey_commonAI::UpdateAI(diff); + boss_priestess_lackey_commonAI::UpdateAI(diff); - if (Vanish_Timer <= diff) - { - DoCast(me, SPELL_VANISH); + if (Vanish_Timer <= diff) + { + DoCast(me, SPELL_VANISH); - Unit* unit = SelectTarget(SelectTargetMethod::Random, 0); + Unit* unit = SelectTarget(SelectTargetMethod::Random, 0); - ResetThreatList(); + ResetThreatList(); - if (unit) - AddThreat(unit, 1000.0f); + if (unit) + AddThreat(unit, 1000.0f); - InVanish = true; - Vanish_Timer = 30000; - Wait_Timer = 10000; - } else Vanish_Timer -= diff; + InVanish = true; + Vanish_Timer = 30000; + Wait_Timer = 10000; + } else Vanish_Timer -= diff; - if (InVanish) + if (InVanish) + { + if (Wait_Timer <= diff) { - if (Wait_Timer <= diff) - { - DoCastVictim(SPELL_BACKSTAB, true); - DoCastVictim(SPELL_KIDNEY_SHOT, true); - me->SetVisible(true); // ...? Hacklike - InVanish = false; - } else Wait_Timer -= diff; - } + DoCastVictim(SPELL_BACKSTAB, true); + DoCastVictim(SPELL_KIDNEY_SHOT, true); + me->SetVisible(true); // ...? Hacklike + InVanish = false; + } else Wait_Timer -= diff; + } - if (Gouge_Timer <= diff) - { - DoCastVictim(SPELL_GOUGE); - Gouge_Timer = 5500; - } else Gouge_Timer -= diff; + if (Gouge_Timer <= diff) + { + DoCastVictim(SPELL_GOUGE); + Gouge_Timer = 5500; + } else Gouge_Timer -= diff; - if (Kick_Timer <= diff) - { - DoCastVictim(SPELL_KICK); - Kick_Timer = 7000; - } else Kick_Timer -= diff; + if (Kick_Timer <= diff) + { + DoCastVictim(SPELL_KICK); + Kick_Timer = 7000; + } else Kick_Timer -= diff; - if (Eviscerate_Timer <= diff) - { - DoCastVictim(SPELL_EVISCERATE); - Eviscerate_Timer = 4000; - } else Eviscerate_Timer -= diff; + if (Eviscerate_Timer <= diff) + { + DoCastVictim(SPELL_EVISCERATE); + Eviscerate_Timer = 4000; + } else Eviscerate_Timer -= diff; - if (!InVanish) - DoMeleeAttackIfReady(); - } - }; + if (!InVanish) + DoMeleeAttackIfReady(); + } }; enum WarlockSpells @@ -581,161 +550,139 @@ enum WarlockSpells SPELL_SUMMON_IMP = 44163 }; -class boss_ellris_duskhallow : public CreatureScript +// 24558 - Ellrys Duskhallow (Warlock) +struct boss_ellris_duskhallow : public boss_priestess_lackey_commonAI { -public: - boss_ellris_duskhallow() : CreatureScript("boss_ellris_duskhallow") { } + boss_ellris_duskhallow(Creature* creature) : boss_priestess_lackey_commonAI(creature) + { + Initialize(); + } - CreatureAI* GetAI(Creature* creature) const override + void Initialize() { - return GetMagistersTerraceAI<boss_ellris_duskhallowAI>(creature); + Immolate_Timer = 6000; + Shadow_Bolt_Timer = 3000; + Seed_of_Corruption_Timer = 2000; + Curse_of_Agony_Timer = 1000; + Fear_Timer = 10000; } - struct boss_ellris_duskhallowAI : public boss_priestess_lackey_commonAI + uint32 Immolate_Timer; + uint32 Shadow_Bolt_Timer; + uint32 Seed_of_Corruption_Timer; + uint32 Curse_of_Agony_Timer; + uint32 Fear_Timer; + + void Reset() override { - //Warlock - boss_ellris_duskhallowAI(Creature* creature) : boss_priestess_lackey_commonAI(creature) - { - Initialize(); - } + Initialize(); - void Initialize() - { - Immolate_Timer = 6000; - Shadow_Bolt_Timer = 3000; - Seed_of_Corruption_Timer = 2000; - Curse_of_Agony_Timer = 1000; - Fear_Timer = 10000; - } + boss_priestess_lackey_commonAI::Reset(); + } - uint32 Immolate_Timer; - uint32 Shadow_Bolt_Timer; - uint32 Seed_of_Corruption_Timer; - uint32 Curse_of_Agony_Timer; - uint32 Fear_Timer; + void JustEngagedWith(Unit* /*who*/) override + { + DoCast(me, SPELL_SUMMON_IMP); + } - void Reset() override - { - Initialize(); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - boss_priestess_lackey_commonAI::Reset(); - } + boss_priestess_lackey_commonAI::UpdateAI(diff); - void JustEngagedWith(Unit* /*who*/) override + if (Immolate_Timer <= diff) { - DoCast(me, SPELL_SUMMON_IMP); - } + DoCastVictim(SPELL_IMMOLATE); + Immolate_Timer = 6000; + } else Immolate_Timer -= diff; - void UpdateAI(uint32 diff) override + if (Shadow_Bolt_Timer <= diff) { - if (!UpdateVictim()) - return; - - boss_priestess_lackey_commonAI::UpdateAI(diff); - - if (Immolate_Timer <= diff) - { - DoCastVictim(SPELL_IMMOLATE); - Immolate_Timer = 6000; - } else Immolate_Timer -= diff; - - if (Shadow_Bolt_Timer <= diff) - { - DoCastVictim(SPELL_SHADOW_BOLT); - Shadow_Bolt_Timer = 5000; - } else Shadow_Bolt_Timer -= diff; + DoCastVictim(SPELL_SHADOW_BOLT); + Shadow_Bolt_Timer = 5000; + } else Shadow_Bolt_Timer -= diff; - if (Seed_of_Corruption_Timer <= diff) - { - if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) - DoCast(unit, SPELL_SEED_OF_CORRUPTION); + if (Seed_of_Corruption_Timer <= diff) + { + if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) + DoCast(unit, SPELL_SEED_OF_CORRUPTION); - Seed_of_Corruption_Timer = 10000; - } else Seed_of_Corruption_Timer -= diff; + Seed_of_Corruption_Timer = 10000; + } else Seed_of_Corruption_Timer -= diff; - if (Curse_of_Agony_Timer <= diff) - { - if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) - DoCast(unit, SPELL_CURSE_OF_AGONY); + if (Curse_of_Agony_Timer <= diff) + { + if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) + DoCast(unit, SPELL_CURSE_OF_AGONY); - Curse_of_Agony_Timer = 13000; - } else Curse_of_Agony_Timer -= diff; + Curse_of_Agony_Timer = 13000; + } else Curse_of_Agony_Timer -= diff; - if (Fear_Timer <= diff) - { - if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) - DoCast(unit, SPELL_FEAR); + if (Fear_Timer <= diff) + { + if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) + DoCast(unit, SPELL_FEAR); - Fear_Timer = 10000; - } else Fear_Timer -= diff; + Fear_Timer = 10000; + } else Fear_Timer -= diff; - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; -enum KickDown +enum MonkSpells { SPELL_KNOCKDOWN = 11428, SPELL_SNAP_KICK = 46182 }; -class boss_eramas_brightblaze : public CreatureScript +// 24554 - Eramas Brightblaze (Monk) +struct boss_eramas_brightblaze : public boss_priestess_lackey_commonAI { -public: - boss_eramas_brightblaze() : CreatureScript("boss_eramas_brightblaze") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_eramas_brightblaze(Creature* creature) : boss_priestess_lackey_commonAI(creature) { - return GetMagistersTerraceAI<boss_eramas_brightblazeAI>(creature); + Initialize(); } - struct boss_eramas_brightblazeAI : public boss_priestess_lackey_commonAI + void Initialize() { - //Monk - boss_eramas_brightblazeAI(Creature* creature) : boss_priestess_lackey_commonAI(creature) - { - Initialize(); - } - - void Initialize() - { - Knockdown_Timer = 6000; - Snap_Kick_Timer = 4500; - } + Knockdown_Timer = 6000; + Snap_Kick_Timer = 4500; + } - uint32 Knockdown_Timer; - uint32 Snap_Kick_Timer; + uint32 Knockdown_Timer; + uint32 Snap_Kick_Timer; - void Reset() override - { - Initialize(); + void Reset() override + { + Initialize(); - boss_priestess_lackey_commonAI::Reset(); - } + boss_priestess_lackey_commonAI::Reset(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - boss_priestess_lackey_commonAI::UpdateAI(diff); + boss_priestess_lackey_commonAI::UpdateAI(diff); - if (Knockdown_Timer <= diff) - { - DoCastVictim(SPELL_KNOCKDOWN); - Knockdown_Timer = 6000; - } else Knockdown_Timer -= diff; + if (Knockdown_Timer <= diff) + { + DoCastVictim(SPELL_KNOCKDOWN); + Knockdown_Timer = 6000; + } else Knockdown_Timer -= diff; - if (Snap_Kick_Timer <= diff) - { - DoCastVictim(SPELL_SNAP_KICK); - Snap_Kick_Timer = 4500; - } else Snap_Kick_Timer -= diff; + if (Snap_Kick_Timer <= diff) + { + DoCastVictim(SPELL_SNAP_KICK); + Snap_Kick_Timer = 4500; + } else Snap_Kick_Timer -= diff; - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; enum MageSpells @@ -749,126 +696,115 @@ enum MageSpells SPELL_BLINK = 14514 }; -class boss_yazzai : public CreatureScript +// 24561 - Yazzai (Mage) +struct boss_yazzai : public boss_priestess_lackey_commonAI { -public: - boss_yazzai() : CreatureScript("boss_yazzai") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_yazzai(Creature* creature) : boss_priestess_lackey_commonAI(creature) { - return GetMagistersTerraceAI<boss_yazzaiAI>(creature); + Initialize(); } - struct boss_yazzaiAI : public boss_priestess_lackey_commonAI + void Initialize() { - //Mage - boss_yazzaiAI(Creature* creature) : boss_priestess_lackey_commonAI(creature) - { - Initialize(); - } + HasIceBlocked = false; + + Polymorph_Timer = 1000; + Ice_Block_Timer = 20000; + Wait_Timer = 10000; + Blizzard_Timer = 8000; + Ice_Lance_Timer = 12000; + Cone_of_Cold_Timer = 10000; + Frostbolt_Timer = 3000; + Blink_Timer = 8000; + } - void Initialize() - { - HasIceBlocked = false; + bool HasIceBlocked; - Polymorph_Timer = 1000; - Ice_Block_Timer = 20000; - Wait_Timer = 10000; - Blizzard_Timer = 8000; - Ice_Lance_Timer = 12000; - Cone_of_Cold_Timer = 10000; - Frostbolt_Timer = 3000; - Blink_Timer = 8000; - } + uint32 Polymorph_Timer; + uint32 Ice_Block_Timer; + uint32 Wait_Timer; + uint32 Blizzard_Timer; + uint32 Ice_Lance_Timer; + uint32 Cone_of_Cold_Timer; + uint32 Frostbolt_Timer; + uint32 Blink_Timer; - bool HasIceBlocked; + void Reset() override + { + Initialize(); - uint32 Polymorph_Timer; - uint32 Ice_Block_Timer; - uint32 Wait_Timer; - uint32 Blizzard_Timer; - uint32 Ice_Lance_Timer; - uint32 Cone_of_Cold_Timer; - uint32 Frostbolt_Timer; - uint32 Blink_Timer; + boss_priestess_lackey_commonAI::Reset(); + } - void Reset() override - { - Initialize(); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - boss_priestess_lackey_commonAI::Reset(); - } + boss_priestess_lackey_commonAI::UpdateAI(diff); - void UpdateAI(uint32 diff) override + if (Polymorph_Timer <= diff) { - if (!UpdateVictim()) - return; - - boss_priestess_lackey_commonAI::UpdateAI(diff); - - if (Polymorph_Timer <= diff) - { - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - { - DoCast(target, SPELL_POLYMORPH); - Polymorph_Timer = 20000; - } - } else Polymorph_Timer -= diff; - - if (HealthBelowPct(35) && !HasIceBlocked) + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) { - DoCast(me, SPELL_ICE_BLOCK); - HasIceBlocked = true; + DoCast(target, SPELL_POLYMORPH); + Polymorph_Timer = 20000; } + } else Polymorph_Timer -= diff; - if (Blizzard_Timer <= diff) - { - if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) - DoCast(unit, SPELL_BLIZZARD); + if (HealthBelowPct(35) && !HasIceBlocked) + { + DoCast(me, SPELL_ICE_BLOCK); + HasIceBlocked = true; + } - Blizzard_Timer = 8000; - } else Blizzard_Timer -= diff; + if (Blizzard_Timer <= diff) + { + if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) + DoCast(unit, SPELL_BLIZZARD); - if (Ice_Lance_Timer <= diff) - { - DoCastVictim(SPELL_ICE_LANCE); - Ice_Lance_Timer = 12000; - } else Ice_Lance_Timer -= diff; + Blizzard_Timer = 8000; + } else Blizzard_Timer -= diff; - if (Cone_of_Cold_Timer <= diff) - { - DoCastVictim(SPELL_CONE_OF_COLD); - Cone_of_Cold_Timer = 10000; - } else Cone_of_Cold_Timer -= diff; + if (Ice_Lance_Timer <= diff) + { + DoCastVictim(SPELL_ICE_LANCE); + Ice_Lance_Timer = 12000; + } else Ice_Lance_Timer -= diff; - if (Frostbolt_Timer <= diff) - { - DoCastVictim(SPELL_FROSTBOLT); - Frostbolt_Timer = 8000; - } else Frostbolt_Timer -= diff; + if (Cone_of_Cold_Timer <= diff) + { + DoCastVictim(SPELL_CONE_OF_COLD); + Cone_of_Cold_Timer = 10000; + } else Cone_of_Cold_Timer -= diff; - if (Blink_Timer <= diff) + if (Frostbolt_Timer <= diff) + { + DoCastVictim(SPELL_FROSTBOLT); + Frostbolt_Timer = 8000; + } else Frostbolt_Timer -= diff; + + if (Blink_Timer <= diff) + { + bool InMeleeRange = false; + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) { - bool InMeleeRange = false; - for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) + if (pair.second->GetOther(me)->IsWithinMeleeRange(me)) { - if (pair.second->GetOther(me)->IsWithinMeleeRange(me)) - { - InMeleeRange = true; - break; - } + InMeleeRange = true; + break; } + } - //if anybody is in melee range than escape by blink - if (InMeleeRange) - DoCast(me, SPELL_BLINK); + //if anybody is in melee range than escape by blink + if (InMeleeRange) + DoCast(me, SPELL_BLINK); - Blink_Timer = 8000; - } else Blink_Timer -= diff; + Blink_Timer = 8000; + } else Blink_Timer -= diff; - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; enum WarriorSpells @@ -882,115 +818,104 @@ enum WarriorSpells SPELL_MORTAL_STRIKE = 44268 }; -class boss_warlord_salaris : public CreatureScript +// 24559 - Warlord Salaris (Warrior) +struct boss_warlord_salaris : public boss_priestess_lackey_commonAI { -public: - boss_warlord_salaris() : CreatureScript("boss_warlord_salaris") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_warlord_salaris(Creature* creature) : boss_priestess_lackey_commonAI(creature) { - return GetMagistersTerraceAI<boss_warlord_salarisAI>(creature); + Initialize(); } - struct boss_warlord_salarisAI : public boss_priestess_lackey_commonAI + void Initialize() { - //Warrior - boss_warlord_salarisAI(Creature* creature) : boss_priestess_lackey_commonAI(creature) - { - Initialize(); - } - - void Initialize() - { - Intercept_Stun_Timer = 500; - Disarm_Timer = 6000; - Piercing_Howl_Timer = 10000; - Frightening_Shout_Timer = 18000; - Hamstring_Timer = 4500; - Mortal_Strike_Timer = 8000; - } + Intercept_Stun_Timer = 500; + Disarm_Timer = 6000; + Piercing_Howl_Timer = 10000; + Frightening_Shout_Timer = 18000; + Hamstring_Timer = 4500; + Mortal_Strike_Timer = 8000; + } - uint32 Intercept_Stun_Timer; - uint32 Disarm_Timer; - uint32 Piercing_Howl_Timer; - uint32 Frightening_Shout_Timer; - uint32 Hamstring_Timer; - uint32 Mortal_Strike_Timer; + uint32 Intercept_Stun_Timer; + uint32 Disarm_Timer; + uint32 Piercing_Howl_Timer; + uint32 Frightening_Shout_Timer; + uint32 Hamstring_Timer; + uint32 Mortal_Strike_Timer; - void Reset() override - { - Initialize(); + void Reset() override + { + Initialize(); - boss_priestess_lackey_commonAI::Reset(); - } + boss_priestess_lackey_commonAI::Reset(); + } - void JustEngagedWith(Unit* /*who*/) override - { - DoCast(me, SPELL_BATTLE_SHOUT); - } + void JustEngagedWith(Unit* /*who*/) override + { + DoCast(me, SPELL_BATTLE_SHOUT); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - boss_priestess_lackey_commonAI::UpdateAI(diff); + boss_priestess_lackey_commonAI::UpdateAI(diff); - if (Intercept_Stun_Timer <= diff) + if (Intercept_Stun_Timer <= diff) + { + bool InMeleeRange = false; + for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) { - bool InMeleeRange = false; - for (auto const& pair : me->GetCombatManager().GetPvECombatRefs()) + if (pair.second->GetOther(me)->IsWithinMeleeRange(me)) { - if (pair.second->GetOther(me)->IsWithinMeleeRange(me)) - { - InMeleeRange = true; - break; - } + InMeleeRange = true; + break; } + } - //if nobody is in melee range than try to use Intercept - if (!InMeleeRange) - { - if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) - DoCast(unit, SPELL_INTERCEPT_STUN); - } + //if nobody is in melee range than try to use Intercept + if (!InMeleeRange) + { + if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) + DoCast(unit, SPELL_INTERCEPT_STUN); + } - Intercept_Stun_Timer = 10000; - } else Intercept_Stun_Timer -= diff; + Intercept_Stun_Timer = 10000; + } else Intercept_Stun_Timer -= diff; - if (Disarm_Timer <= diff) - { - DoCastVictim(SPELL_DISARM); - Disarm_Timer = 6000; - } else Disarm_Timer -= diff; + if (Disarm_Timer <= diff) + { + DoCastVictim(SPELL_DISARM); + Disarm_Timer = 6000; + } else Disarm_Timer -= diff; - if (Hamstring_Timer <= diff) - { - DoCastVictim(SPELL_HAMSTRING); - Hamstring_Timer = 4500; - } else Hamstring_Timer -= diff; + if (Hamstring_Timer <= diff) + { + DoCastVictim(SPELL_HAMSTRING); + Hamstring_Timer = 4500; + } else Hamstring_Timer -= diff; - if (Mortal_Strike_Timer <= diff) - { - DoCastVictim(SPELL_MORTAL_STRIKE); - Mortal_Strike_Timer = 4500; - } else Mortal_Strike_Timer -= diff; + if (Mortal_Strike_Timer <= diff) + { + DoCastVictim(SPELL_MORTAL_STRIKE); + Mortal_Strike_Timer = 4500; + } else Mortal_Strike_Timer -= diff; - if (Piercing_Howl_Timer <= diff) - { - DoCastVictim(SPELL_PIERCING_HOWL); - Piercing_Howl_Timer = 10000; - } else Piercing_Howl_Timer -= diff; + if (Piercing_Howl_Timer <= diff) + { + DoCastVictim(SPELL_PIERCING_HOWL); + Piercing_Howl_Timer = 10000; + } else Piercing_Howl_Timer -= diff; - if (Frightening_Shout_Timer <= diff) - { - DoCastVictim(SPELL_FRIGHTENING_SHOUT); - Frightening_Shout_Timer = 18000; - } else Frightening_Shout_Timer -= diff; + if (Frightening_Shout_Timer <= diff) + { + DoCastVictim(SPELL_FRIGHTENING_SHOUT); + Frightening_Shout_Timer = 18000; + } else Frightening_Shout_Timer -= diff; - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; enum HunterSpells @@ -1005,207 +930,196 @@ enum HunterSpells NPC_SLIVER = 24552 }; -class boss_garaxxas : public CreatureScript +// 24555 - Garaxxas (Hunter) +struct boss_garaxxas : public boss_priestess_lackey_commonAI { -public: - boss_garaxxas() : CreatureScript("boss_garaxxas") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_garaxxas(Creature* creature) : boss_priestess_lackey_commonAI(creature) { - return GetMagistersTerraceAI<boss_garaxxasAI>(creature); + Initialize(); } - struct boss_garaxxasAI : public boss_priestess_lackey_commonAI + void Initialize() { - //Hunter - boss_garaxxasAI(Creature* creature) : boss_priestess_lackey_commonAI(creature) - { - Initialize(); - } + Aimed_Shot_Timer = 6000; + Shoot_Timer = 2500; + Concussive_Shot_Timer = 8000; + Multi_Shot_Timer = 10000; + Wing_Clip_Timer = 4000; + Freezing_Trap_Timer = 15000; + } - void Initialize() - { - Aimed_Shot_Timer = 6000; - Shoot_Timer = 2500; - Concussive_Shot_Timer = 8000; - Multi_Shot_Timer = 10000; - Wing_Clip_Timer = 4000; - Freezing_Trap_Timer = 15000; - } + ObjectGuid m_uiPetGUID; - ObjectGuid m_uiPetGUID; + uint32 Aimed_Shot_Timer; + uint32 Shoot_Timer; + uint32 Concussive_Shot_Timer; + uint32 Multi_Shot_Timer; + uint32 Wing_Clip_Timer; + uint32 Freezing_Trap_Timer; - uint32 Aimed_Shot_Timer; - uint32 Shoot_Timer; - uint32 Concussive_Shot_Timer; - uint32 Multi_Shot_Timer; - uint32 Wing_Clip_Timer; - uint32 Freezing_Trap_Timer; + void Reset() override + { + Initialize(); - void Reset() override - { - Initialize(); + Unit* pPet = ObjectAccessor::GetUnit(*me, m_uiPetGUID); + if (!pPet) + me->SummonCreature(NPC_SLIVER, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN); - Unit* pPet = ObjectAccessor::GetUnit(*me, m_uiPetGUID); - if (!pPet) - me->SummonCreature(NPC_SLIVER, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN); + boss_priestess_lackey_commonAI::Reset(); + } - boss_priestess_lackey_commonAI::Reset(); - } + void JustSummoned(Creature* summoned) override + { + m_uiPetGUID = summoned->GetGUID(); + } - void JustSummoned(Creature* summoned) override - { - m_uiPetGUID = summoned->GetGUID(); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + boss_priestess_lackey_commonAI::UpdateAI(diff); - boss_priestess_lackey_commonAI::UpdateAI(diff); + if (me->IsWithinDistInMap(me->GetVictim(), ATTACK_DISTANCE)) + { + if (Wing_Clip_Timer <= diff) + { + DoCastVictim(SPELL_WING_CLIP); + Wing_Clip_Timer = 4000; + } else Wing_Clip_Timer -= diff; - if (me->IsWithinDistInMap(me->GetVictim(), ATTACK_DISTANCE)) + if (Freezing_Trap_Timer <= diff) { - if (Wing_Clip_Timer <= diff) - { - DoCastVictim(SPELL_WING_CLIP); - Wing_Clip_Timer = 4000; - } else Wing_Clip_Timer -= diff; + //attempt find go summoned from spell (cast by me) + GameObject* go = me->GetGameObject(SPELL_FREEZING_TRAP); - if (Freezing_Trap_Timer <= diff) + //if we have a go, we need to wait (only one trap at a time) + if (go) + Freezing_Trap_Timer = 2500; + else { - //attempt find go summoned from spell (cast by me) - GameObject* go = me->GetGameObject(SPELL_FREEZING_TRAP); - - //if we have a go, we need to wait (only one trap at a time) - if (go) - Freezing_Trap_Timer = 2500; - else - { - //if go does not exist, then we can cast - DoCastVictim(SPELL_FREEZING_TRAP); - Freezing_Trap_Timer = 15000; - } - } else Freezing_Trap_Timer -= diff; + //if go does not exist, then we can cast + DoCastVictim(SPELL_FREEZING_TRAP); + Freezing_Trap_Timer = 15000; + } + } else Freezing_Trap_Timer -= diff; - DoMeleeAttackIfReady(); - } - else + DoMeleeAttackIfReady(); + } + else + { + if (Concussive_Shot_Timer <= diff) { - if (Concussive_Shot_Timer <= diff) - { - DoCastVictim(SPELL_CONCUSSIVE_SHOT); - Concussive_Shot_Timer = 8000; - } else Concussive_Shot_Timer -= diff; + DoCastVictim(SPELL_CONCUSSIVE_SHOT); + Concussive_Shot_Timer = 8000; + } else Concussive_Shot_Timer -= diff; - if (Multi_Shot_Timer <= diff) - { - DoCastVictim(SPELL_MULTI_SHOT); - Multi_Shot_Timer = 10000; - } else Multi_Shot_Timer -= diff; + if (Multi_Shot_Timer <= diff) + { + DoCastVictim(SPELL_MULTI_SHOT); + Multi_Shot_Timer = 10000; + } else Multi_Shot_Timer -= diff; - if (Aimed_Shot_Timer <= diff) - { - DoCastVictim(SPELL_AIMED_SHOT); - Aimed_Shot_Timer = 6000; - } else Aimed_Shot_Timer -= diff; + if (Aimed_Shot_Timer <= diff) + { + DoCastVictim(SPELL_AIMED_SHOT); + Aimed_Shot_Timer = 6000; + } else Aimed_Shot_Timer -= diff; - if (Shoot_Timer <= diff) - { - DoCastVictim(SPELL_SHOOT); - Shoot_Timer = 2500; - } else Shoot_Timer -= diff; - } + if (Shoot_Timer <= diff) + { + DoCastVictim(SPELL_SHOOT); + Shoot_Timer = 2500; + } else Shoot_Timer -= diff; } - }; + } }; -class boss_apoko : public CreatureScript +enum ShamanSpells { -public: - boss_apoko() : CreatureScript("boss_apoko") { } + SPELL_WINDFURY_TOTEM = 27621, + SPELL_WAR_STOMP = 46026, + SPELL_PURGE = 27626, + SPELL_LESSER_HEALING_WAVE = 44256, + SPELL_FROST_SHOCK = 21401, + SPELL_FIRE_NOVA_TOTEM = 44257, + SPELL_EARTHBIND_TOTEM = 15786 +}; - CreatureAI* GetAI(Creature* creature) const override +// 24553 - Apoko (Shaman) +struct boss_apoko : public boss_priestess_lackey_commonAI +{ + boss_apoko(Creature* creature) : boss_priestess_lackey_commonAI(creature) { - return GetMagistersTerraceAI<boss_apokoAI>(creature); + Initialize(); } - struct boss_apokoAI : public boss_priestess_lackey_commonAI + void Initialize() { - //Shaman - boss_apokoAI(Creature* creature) : boss_priestess_lackey_commonAI(creature) - { - Initialize(); - } - - void Initialize() - { - Totem_Timer = 2000; - Totem_Amount = 1; - War_Stomp_Timer = 10000; - Purge_Timer = 8000; - Healing_Wave_Timer = 5000; - Frost_Shock_Timer = 7000; - } + Totem_Timer = 2000; + Totem_Amount = 1; + War_Stomp_Timer = 10000; + Purge_Timer = 8000; + Healing_Wave_Timer = 5000; + Frost_Shock_Timer = 7000; + } - uint32 Totem_Timer; - uint8 Totem_Amount; - uint32 War_Stomp_Timer; - uint32 Purge_Timer; - uint32 Healing_Wave_Timer; - uint32 Frost_Shock_Timer; + uint32 Totem_Timer; + uint8 Totem_Amount; + uint32 War_Stomp_Timer; + uint32 Purge_Timer; + uint32 Healing_Wave_Timer; + uint32 Frost_Shock_Timer; - void Reset() override - { - Initialize(); + void Reset() override + { + Initialize(); - boss_priestess_lackey_commonAI::Reset(); - } + boss_priestess_lackey_commonAI::Reset(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - boss_priestess_lackey_commonAI::UpdateAI(diff); + boss_priestess_lackey_commonAI::UpdateAI(diff); - if (Totem_Timer <= diff) - { - DoCast(me, RAND(SPELL_WINDFURY_TOTEM, SPELL_FIRE_NOVA_TOTEM, SPELL_EARTHBIND_TOTEM)); - ++Totem_Amount; - Totem_Timer = Totem_Amount*2000; - } else Totem_Timer -= diff; + if (Totem_Timer <= diff) + { + DoCast(me, RAND(SPELL_WINDFURY_TOTEM, SPELL_FIRE_NOVA_TOTEM, SPELL_EARTHBIND_TOTEM)); + ++Totem_Amount; + Totem_Timer = Totem_Amount*2000; + } else Totem_Timer -= diff; - if (War_Stomp_Timer <= diff) - { - DoCast(me, SPELL_WAR_STOMP); - War_Stomp_Timer = 10000; - } else War_Stomp_Timer -= diff; + if (War_Stomp_Timer <= diff) + { + DoCast(me, SPELL_WAR_STOMP); + War_Stomp_Timer = 10000; + } else War_Stomp_Timer -= diff; - if (Purge_Timer <= diff) - { - if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) - DoCast(unit, SPELL_PURGE); + if (Purge_Timer <= diff) + { + if (Unit* unit = SelectTarget(SelectTargetMethod::Random, 0)) + DoCast(unit, SPELL_PURGE); - Purge_Timer = 15000; - } else Purge_Timer -= diff; + Purge_Timer = 15000; + } else Purge_Timer -= diff; - if (Frost_Shock_Timer <= diff) - { - DoCastVictim(SPELL_FROST_SHOCK); - Frost_Shock_Timer = 7000; - } else Frost_Shock_Timer -= diff; + if (Frost_Shock_Timer <= diff) + { + DoCastVictim(SPELL_FROST_SHOCK); + Frost_Shock_Timer = 7000; + } else Frost_Shock_Timer -= diff; - if (Healing_Wave_Timer <= diff) - { - DoCast(me, SPELL_LESSER_HEALING_WAVE); - Healing_Wave_Timer = 5000; - } else Healing_Wave_Timer -= diff; + if (Healing_Wave_Timer <= diff) + { + DoCast(me, SPELL_LESSER_HEALING_WAVE); + Healing_Wave_Timer = 5000; + } else Healing_Wave_Timer -= diff; - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } }; enum EngineerSpells @@ -1218,121 +1132,96 @@ enum EngineerSpells SPELL_SHEEP_EXPLOSION = 44279 }; -class boss_zelfan : public CreatureScript +// 24556 - Zelfan (Engineer) +struct boss_zelfan : public boss_priestess_lackey_commonAI { -public: - boss_zelfan() : CreatureScript("boss_zelfan") { } - - CreatureAI* GetAI(Creature* creature) const override + boss_zelfan(Creature* creature) : boss_priestess_lackey_commonAI(creature) { - return GetMagistersTerraceAI<boss_zelfanAI>(creature); + Initialize(); } - struct boss_zelfanAI : public boss_priestess_lackey_commonAI + void Initialize() { - //Engineer - boss_zelfanAI(Creature* creature) : boss_priestess_lackey_commonAI(creature) - { - Initialize(); - } - - void Initialize() - { - Goblin_Dragon_Gun_Timer = 20000; - Rocket_Launch_Timer = 7000; - Recombobulate_Timer = 4000; - High_Explosive_Sheep_Timer = 10000; - Fel_Iron_Bomb_Timer = 15000; - } + Goblin_Dragon_Gun_Timer = 20000; + Rocket_Launch_Timer = 7000; + Recombobulate_Timer = 4000; + High_Explosive_Sheep_Timer = 10000; + Fel_Iron_Bomb_Timer = 15000; + } - uint32 Goblin_Dragon_Gun_Timer; - uint32 Rocket_Launch_Timer; - uint32 Recombobulate_Timer; - uint32 High_Explosive_Sheep_Timer; - uint32 Fel_Iron_Bomb_Timer; + uint32 Goblin_Dragon_Gun_Timer; + uint32 Rocket_Launch_Timer; + uint32 Recombobulate_Timer; + uint32 High_Explosive_Sheep_Timer; + uint32 Fel_Iron_Bomb_Timer; - void Reset() override - { - Initialize(); + void Reset() override + { + Initialize(); - boss_priestess_lackey_commonAI::Reset(); - } + boss_priestess_lackey_commonAI::Reset(); + } - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - boss_priestess_lackey_commonAI::UpdateAI(diff); + boss_priestess_lackey_commonAI::UpdateAI(diff); - if (Goblin_Dragon_Gun_Timer <= diff) - { - DoCastVictim(SPELL_GOBLIN_DRAGON_GUN); - Goblin_Dragon_Gun_Timer = 10000; - } else Goblin_Dragon_Gun_Timer -= diff; + if (Goblin_Dragon_Gun_Timer <= diff) + { + DoCastVictim(SPELL_GOBLIN_DRAGON_GUN); + Goblin_Dragon_Gun_Timer = 10000; + } else Goblin_Dragon_Gun_Timer -= diff; - if (Rocket_Launch_Timer <= diff) - { - DoCastVictim(SPELL_ROCKET_LAUNCH); - Rocket_Launch_Timer = 9000; - } else Rocket_Launch_Timer -= diff; + if (Rocket_Launch_Timer <= diff) + { + DoCastVictim(SPELL_ROCKET_LAUNCH); + Rocket_Launch_Timer = 9000; + } else Rocket_Launch_Timer -= diff; - if (Fel_Iron_Bomb_Timer <= diff) - { - DoCastVictim(SPELL_FEL_IRON_BOMB); - Fel_Iron_Bomb_Timer = 15000; - } else Fel_Iron_Bomb_Timer -= diff; + if (Fel_Iron_Bomb_Timer <= diff) + { + DoCastVictim(SPELL_FEL_IRON_BOMB); + Fel_Iron_Bomb_Timer = 15000; + } else Fel_Iron_Bomb_Timer -= diff; - if (Recombobulate_Timer <= diff) + if (Recombobulate_Timer <= diff) + { + for (uint8 i = 0; i < MAX_ACTIVE_LACKEY; ++i) { - for (uint8 i = 0; i < MAX_ACTIVE_LACKEY; ++i) + if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUIDs[i])) { - if (Unit* pAdd = ObjectAccessor::GetUnit(*me, m_auiLackeyGUIDs[i])) + if (pAdd->IsPolymorphed()) { - if (pAdd->IsPolymorphed()) - { - DoCast(pAdd, SPELL_RECOMBOBULATE); - break; - } + DoCast(pAdd, SPELL_RECOMBOBULATE); + break; } } - Recombobulate_Timer = 2000; - } else Recombobulate_Timer -= diff; - - if (High_Explosive_Sheep_Timer <= diff) - { - DoCast(me, SPELL_HIGH_EXPLOSIVE_SHEEP); - High_Explosive_Sheep_Timer = 65000; - } else High_Explosive_Sheep_Timer -= diff; - - DoMeleeAttackIfReady(); - } - }; -}; + } + Recombobulate_Timer = 2000; + } else Recombobulate_Timer -= diff; -/* -class npc_high_explosive_sheep : public CreatureScript -{ -public: - npc_high_explosive_sheep() : CreatureScript("npc_high_explosive_sheep") { } + if (High_Explosive_Sheep_Timer <= diff) + { + DoCast(me, SPELL_HIGH_EXPLOSIVE_SHEEP); + High_Explosive_Sheep_Timer = 65000; + } else High_Explosive_Sheep_Timer -= diff; - //CreatureAI* GetAI(Creature* creature) const override - //{ - // return GetMagistersTerraceAI<npc_high_explosive_sheepAI>(creature); - //}; + DoMeleeAttackIfReady(); + } }; -*/ void AddSC_boss_priestess_delrissa() { - new boss_priestess_delrissa(); - new boss_kagani_nightstrike(); - new boss_ellris_duskhallow(); - new boss_eramas_brightblaze(); - new boss_yazzai(); - new boss_warlord_salaris(); - new boss_garaxxas(); - new boss_apoko(); - new boss_zelfan(); - // new npc_high_explosive_sheep(); + RegisterMagistersTerraceCreatureAI(boss_priestess_delrissa); + RegisterMagistersTerraceCreatureAI(boss_kagani_nightstrike); + RegisterMagistersTerraceCreatureAI(boss_ellris_duskhallow); + RegisterMagistersTerraceCreatureAI(boss_eramas_brightblaze); + RegisterMagistersTerraceCreatureAI(boss_yazzai); + RegisterMagistersTerraceCreatureAI(boss_warlord_salaris); + RegisterMagistersTerraceCreatureAI(boss_garaxxas); + RegisterMagistersTerraceCreatureAI(boss_apoko); + RegisterMagistersTerraceCreatureAI(boss_zelfan); } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp index 8cb2c5e0d10..aaaf5d34b85 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp @@ -15,6 +15,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +/* Cystals should really be a DB creature summon group, having them in `creature` like this will cause tons of despawn/respawn bugs */ + #include "ScriptMgr.h" #include "InstanceScript.h" #include "magisters_terrace.h" @@ -22,36 +24,31 @@ #include "ObjectAccessor.h" #include "ScriptedCreature.h" -enum Says +enum SelinTexts { SAY_AGGRO = 0, SAY_ENERGY = 1, SAY_EMPOWERED = 2, - SAY_KILL = 3, + SAY_SLAY = 3, SAY_DEATH = 4, EMOTE_CRYSTAL = 5 }; -enum Spells +enum SelinSpells { - // Crystal effect spells - SPELL_FEL_CRYSTAL_DUMMY = 44329, - SPELL_MANA_RAGE = 44320, // This spell triggers 44321, which changes scale and regens mana Requires an entry in spell_script_target - - // Selin's spells + // Selin SPELL_DRAIN_LIFE = 44294, SPELL_FEL_EXPLOSION = 44314, - SPELL_DRAIN_MANA = 46153 // Heroic only -}; + SPELL_DRAIN_MANA = 46153, // Heroic only -enum Phases -{ - PHASE_NORMAL = 1, - PHASE_DRAIN = 2 + // Crystal + SPELL_FEL_CRYSTAL_DUMMY = 44329, + SPELL_MANA_RAGE = 44320, + SPELL_QUIET_SUICIDE = 3617 }; -enum Events +enum SelinEvents { EVENT_FEL_EXPLOSION = 1, EVENT_DRAIN_CRYSTAL, @@ -60,228 +57,213 @@ enum Events EVENT_EMPOWER }; -enum Misc +enum SelinPhases +{ + PHASE_NORMAL = 1, + PHASE_DRAIN = 2 +}; + +enum SelinMisc { ACTION_SWITCH_PHASE = 1 }; -// @todo crystals should really be a DB creature summon group, having them in `creature` like this will cause tons of despawn/respawn bugs -class boss_selin_fireheart : public CreatureScript +// 24723 - Selin Fireheart +struct boss_selin_fireheart : public BossAI { - public: - boss_selin_fireheart() : CreatureScript("boss_selin_fireheart") { } + boss_selin_fireheart(Creature* creature) : BossAI(creature, DATA_SELIN_FIREHEART), _scheduledEvents(false) { } - struct boss_selin_fireheartAI : public BossAI - { - boss_selin_fireheartAI(Creature* creature) : BossAI(creature, DATA_SELIN_FIREHEART), _scheduledEvents(false) { } + void Reset() override + { + std::list<Creature*> crystals; + me->GetCreatureListWithEntryInGrid(crystals, NPC_FEL_CRYSTAL, 250.0f); - void Reset() override - { - std::list<Creature*> crystals; - me->GetCreatureListWithEntryInGrid(crystals, NPC_FEL_CRYSTAL, 250.0f); + for (Creature* creature : crystals) + creature->Respawn(true); - for (Creature* creature : crystals) - creature->Respawn(true); + _Reset(); + CrystalGUID.Clear(); + _scheduledEvents = false; + } - _Reset(); - CrystalGUID.Clear(); - _scheduledEvents = false; - } - - void DoAction(int32 action) override + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_SWITCH_PHASE: + events.SetPhase(PHASE_NORMAL); + events.ScheduleEvent(EVENT_FEL_EXPLOSION, 2s, 0, PHASE_NORMAL); + AttackStart(me->GetVictim()); + me->GetMotionMaster()->MoveChase(me->GetVictim()); + break; + default: + break; + } + } + + void SelectNearestCrystal() + { + if (Creature* crystal = me->FindNearestCreature(NPC_FEL_CRYSTAL, 250.0f)) + { + Talk(SAY_ENERGY); + Talk(EMOTE_CRYSTAL); + + DoCast(crystal, SPELL_FEL_CRYSTAL_DUMMY); + CrystalGUID = crystal->GetGUID(); + + float x, y, z; + crystal->GetClosePoint(x, y, z, me->GetCombatReach(), CONTACT_DISTANCE); + + events.SetPhase(PHASE_DRAIN); + me->SetWalk(false); + me->GetMotionMaster()->MovePoint(1, x, y, z); + } + } + + void ShatterRemainingCrystals() + { + std::list<Creature*> crystals; + me->GetCreatureListWithEntryInGrid(crystals, NPC_FEL_CRYSTAL, 250.0f); + + for (Creature* crystal : crystals) + crystal->CastSpell(crystal, SPELL_QUIET_SUICIDE, true); + } + + void JustEngagedWith(Unit* who) override + { + Talk(SAY_AGGRO); + BossAI::JustEngagedWith(who); + + events.SetPhase(PHASE_NORMAL); + events.ScheduleEvent(EVENT_FEL_EXPLOSION, 2100ms, 0, PHASE_NORMAL); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } + + void MovementInform(uint32 type, uint32 id) override + { + if (type == POINT_MOTION_TYPE && id == 1) + { + Unit* CrystalChosen = ObjectAccessor::GetUnit(*me, CrystalGUID); + if (CrystalChosen && CrystalChosen->IsAlive()) { - switch (action) - { - case ACTION_SWITCH_PHASE: - events.SetPhase(PHASE_NORMAL); - events.ScheduleEvent(EVENT_FEL_EXPLOSION, 2s, 0, PHASE_NORMAL); - AttackStart(me->GetVictim()); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - break; - default: - break; - } + CrystalChosen->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); + CrystalChosen->CastSpell(me, SPELL_MANA_RAGE, true); + events.ScheduleEvent(EVENT_EMPOWER, 10s, PHASE_DRAIN); } + } + } - void SelectNearestCrystal() - { - if (Creature* crystal = me->FindNearestCreature(NPC_FEL_CRYSTAL, 250.0f)) - { - Talk(SAY_ENERGY); - Talk(EMOTE_CRYSTAL); + void JustDied(Unit* /*killer*/) override + { + Talk(SAY_DEATH); + _JustDied(); - DoCast(crystal, SPELL_FEL_CRYSTAL_DUMMY); - CrystalGUID = crystal->GetGUID(); + ShatterRemainingCrystals(); + } - float x, y, z; - crystal->GetClosePoint(x, y, z, me->GetCombatReach(), CONTACT_DISTANCE); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - events.SetPhase(PHASE_DRAIN); - me->SetWalk(false); - me->GetMotionMaster()->MovePoint(1, x, y, z); - } - } + events.Update(diff); - void ShatterRemainingCrystals() - { - std::list<Creature*> crystals; - me->GetCreatureListWithEntryInGrid(crystals, NPC_FEL_CRYSTAL, 250.0f); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - for (Creature* crystal : crystals) - crystal->KillSelf(); - } - - void JustEngagedWith(Unit* who) override + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - Talk(SAY_AGGRO); - BossAI::JustEngagedWith(who); + case EVENT_FEL_EXPLOSION: + DoCastAOE(SPELL_FEL_EXPLOSION); + events.ScheduleEvent(EVENT_FEL_EXPLOSION, 2s, 0, PHASE_NORMAL); + break; + case EVENT_DRAIN_CRYSTAL: + SelectNearestCrystal(); + _scheduledEvents = false; + break; + case EVENT_DRAIN_MANA: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 45.0f, true)) + DoCast(target, SPELL_DRAIN_MANA); + events.ScheduleEvent(EVENT_DRAIN_MANA, 10s, 0, PHASE_NORMAL); + break; + case EVENT_DRAIN_LIFE: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 20.0f, true)) + DoCast(target, SPELL_DRAIN_LIFE); + events.ScheduleEvent(EVENT_DRAIN_LIFE, 10s, 0, PHASE_NORMAL); + break; + case EVENT_EMPOWER: + { + Talk(SAY_EMPOWERED); - events.SetPhase(PHASE_NORMAL); - events.ScheduleEvent(EVENT_FEL_EXPLOSION, 2100ms, 0, PHASE_NORMAL); - } + Creature* CrystalChosen = ObjectAccessor::GetCreature(*me, CrystalGUID); + if (CrystalChosen && CrystalChosen->IsAlive()) + CrystalChosen->KillSelf(); - void KilledUnit(Unit* victim) override - { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_KILL); - } + CrystalGUID.Clear(); - void MovementInform(uint32 type, uint32 id) override - { - if (type == POINT_MOTION_TYPE && id == 1) - { - Unit* CrystalChosen = ObjectAccessor::GetUnit(*me, CrystalGUID); - if (CrystalChosen && CrystalChosen->IsAlive()) - { - CrystalChosen->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE); - CrystalChosen->CastSpell(me, SPELL_MANA_RAGE, true); - events.ScheduleEvent(EVENT_EMPOWER, 10s, PHASE_DRAIN); - } + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveChase(me->GetVictim()); + break; } + default: + break; } - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); - _JustDied(); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - ShatterRemainingCrystals(); - } - - void UpdateAI(uint32 diff) override + if (me->GetPowerPct(POWER_MANA) < 10.f) + { + if (events.IsInPhase(PHASE_NORMAL) && !_scheduledEvents) { - if (!UpdateVictim()) - return; + _scheduledEvents = true; + Milliseconds timer = randtime(3s, 7s); + events.ScheduleEvent(EVENT_DRAIN_LIFE, timer, 0, PHASE_NORMAL); - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) + if (IsHeroic()) { - switch (eventId) - { - case EVENT_FEL_EXPLOSION: - DoCastAOE(SPELL_FEL_EXPLOSION); - events.ScheduleEvent(EVENT_FEL_EXPLOSION, 2s, 0, PHASE_NORMAL); - break; - case EVENT_DRAIN_CRYSTAL: - SelectNearestCrystal(); - _scheduledEvents = false; - break; - case EVENT_DRAIN_MANA: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 45.0f, true)) - DoCast(target, SPELL_DRAIN_MANA); - events.ScheduleEvent(EVENT_DRAIN_MANA, 10s, 0, PHASE_NORMAL); - break; - case EVENT_DRAIN_LIFE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 20.0f, true)) - DoCast(target, SPELL_DRAIN_LIFE); - events.ScheduleEvent(EVENT_DRAIN_LIFE, 10s, 0, PHASE_NORMAL); - break; - case EVENT_EMPOWER: - { - Talk(SAY_EMPOWERED); - - Creature* CrystalChosen = ObjectAccessor::GetCreature(*me, CrystalGUID); - if (CrystalChosen && CrystalChosen->IsAlive()) - CrystalChosen->KillSelf(); - - CrystalGUID.Clear(); - - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - break; - } - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 10s, 15s, 0, PHASE_NORMAL); + events.ScheduleEvent(EVENT_DRAIN_MANA, timer + 5s, 0, PHASE_NORMAL); } - - if (me->GetPowerPct(POWER_MANA) < 10.f) - { - if (events.IsInPhase(PHASE_NORMAL) && !_scheduledEvents) - { - _scheduledEvents = true; - Milliseconds timer = randtime(3s, 7s); - events.ScheduleEvent(EVENT_DRAIN_LIFE, timer, 0, PHASE_NORMAL); - - if (IsHeroic()) - { - events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 10s, 15s, 0, PHASE_NORMAL); - events.ScheduleEvent(EVENT_DRAIN_MANA, timer + 5s, 0, PHASE_NORMAL); - } - else - events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 20s, 25s, 0, PHASE_NORMAL); - } - } - - DoMeleeAttackIfReady(); + else + events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 20s, 25s, 0, PHASE_NORMAL); } + } - private: - ObjectGuid CrystalGUID; - bool _scheduledEvents; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetMagistersTerraceAI<boss_selin_fireheartAI>(creature); - }; +private: + ObjectGuid CrystalGUID; + bool _scheduledEvents; }; -class npc_fel_crystal : public CreatureScript +// 24722 - Fel Crystal +struct npc_fel_crystal : public ScriptedAI { - public: - npc_fel_crystal() : CreatureScript("npc_fel_crystal") { } - - struct npc_fel_crystalAI : public ScriptedAI - { - npc_fel_crystalAI(Creature* creature) : ScriptedAI(creature) { } - - void JustDied(Unit* /*killer*/) override - { - if (InstanceScript* instance = me->GetInstanceScript()) - { - Creature* selin = instance->GetCreature(DATA_SELIN_FIREHEART); - if (selin && selin->IsAlive()) - selin->AI()->DoAction(ACTION_SWITCH_PHASE); - } - } - }; + npc_fel_crystal(Creature* creature) : ScriptedAI(creature) { } - CreatureAI* GetAI(Creature* creature) const override + void JustDied(Unit* /*killer*/) override + { + if (InstanceScript* instance = me->GetInstanceScript()) { - return GetMagistersTerraceAI<npc_fel_crystalAI>(creature); - }; + Creature* selin = instance->GetCreature(DATA_SELIN_FIREHEART); + if (selin && selin->IsAlive()) + selin->AI()->DoAction(ACTION_SWITCH_PHASE); + } + } }; void AddSC_boss_selin_fireheart() { - new boss_selin_fireheart(); - new npc_fel_crystal(); + RegisterMagistersTerraceCreatureAI(boss_selin_fireheart); + RegisterMagistersTerraceCreatureAI(npc_fel_crystal); } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp index 986c5cffc33..c603a50a26e 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp @@ -15,208 +15,265 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +/* Timers requires to be revisited */ + #include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" #include "magisters_terrace.h" #include "MotionMaster.h" -#include "ScriptedCreature.h" -enum Yells +enum VexallusTexts { SAY_AGGRO = 0, SAY_ENERGY = 1, SAY_OVERLOAD = 2, - SAY_KILL = 3, - EMOTE_DISCHARGE_ENERGY = 4 - - //is this text for real? - //#define SAY_DEATH "What...happen...ed." + SAY_SLAY = 3, + EMOTE_DISCHARGE_ENERGY = 4, + EMOTE_OVERLOAD = 5 }; -enum Spells +enum VexallusSpells { + // Vexallus SPELL_CHAIN_LIGHTNING = 44318, - SPELL_OVERLOAD = 44353, SPELL_ARCANE_SHOCK = 44319, + SPELL_OVERLOAD = 44353, + + SPELL_SUMMON_PURE_ENERGY = 44322, + SPELL_SUMMON_PURE_ENERGY_H_1 = 46154, + SPELL_SUMMON_PURE_ENERGY_H_2 = 46159, + + SPELL_CLEAR_ENERGY_FEEDBACK = 47108, - SPELL_SUMMON_PURE_ENERGY = 44322, // mod scale -10 - H_SPELL_SUMMON_PURE_ENERGY1 = 46154, // mod scale -5 - H_SPELL_SUMMON_PURE_ENERGY2 = 46159 // mod scale -5 + // Pure Energy + SPELL_ENERGY_BOLT_PERIODIC = 46156, + SPELL_PURE_ENERGY_PASSIVE = 44326, + SPELL_TRIGGER_000 = 36294, // Triggers from 44326. NYI. Probably does what we did on creature death + SPELL_ENERGY_FEEDBACK_PERIODIC = 44328, + SPELL_ENERGY_FEEDBACK = 44335, + SPELL_ENERGY_FEEDBACK_SCALE = 44339 }; -enum Events +enum VexallusEvents { - EVENT_ENERGY_BOLT = 1, - EVENT_ENERGY_FEEDBACK, - EVENT_CHAIN_LIGHTNING, - EVENT_OVERLOAD, - EVENT_ARCANE_SHOCK + EVENT_CHAIN_LIGHTNING = 1, + EVENT_ARCANE_SHOCK, + EVENT_OVERLOAD }; -enum Misc +enum VexallusMisc { INTERVAL_MODIFIER = 15, INTERVAL_SWITCH = 6 }; -class boss_vexallus : public CreatureScript +// 24744 - Vexallus +struct boss_vexallus : public BossAI { - public: - boss_vexallus() : CreatureScript("boss_vexallus") { } - - struct boss_vexallusAI : public BossAI + boss_vexallus(Creature* creature) : BossAI(creature, DATA_VEXALLUS), _intervalHealthAmount(1), _enraged(false) { } + + void Reset() override + { + _Reset(); + _intervalHealthAmount = 1; + _enraged = false; + } + + void JustEngagedWith(Unit* who) override + { + Talk(SAY_AGGRO); + BossAI::JustEngagedWith(who); + + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 8s); + events.ScheduleEvent(EVENT_ARCANE_SHOCK, 5s); + } + + void JustSummoned(Creature* summoned) override + { + if (Unit* temp = SelectTarget(SelectTargetMethod::Random, 0)) + summoned->GetMotionMaster()->MoveFollow(temp, 0, 0); + + summons.Summon(summoned); + } + + void DamageTaken(Unit* /*who*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override + { + if (_enraged) + return; + + // 85%, 70%, 55%, 40%, 25% + if (!HealthAbovePct(100 - INTERVAL_MODIFIER * _intervalHealthAmount)) { - boss_vexallusAI(Creature* creature) : BossAI(creature, DATA_VEXALLUS) + // increase amount, unless we're at 10%, then we switch and return + if (_intervalHealthAmount == INTERVAL_SWITCH) { - _intervalHealthAmount = 1; - _enraged = false; + _enraged = true; + events.Reset(); + events.ScheduleEvent(EVENT_OVERLOAD, 1200ms); + Talk(SAY_OVERLOAD); + Talk(EMOTE_OVERLOAD); + return; } + else + ++_intervalHealthAmount; - void Reset() override - { - _Reset(); - _intervalHealthAmount = 1; - _enraged = false; - } + Talk(SAY_ENERGY); + Talk(EMOTE_DISCHARGE_ENERGY); - void KilledUnit(Unit* /*victim*/) override + if (IsHeroic()) { - Talk(SAY_KILL); + DoCastSelf(SPELL_SUMMON_PURE_ENERGY_H_1); + DoCastSelf(SPELL_SUMMON_PURE_ENERGY_H_2); } + else + DoCastSelf(SPELL_SUMMON_PURE_ENERGY); + } + } - void JustEngagedWith(Unit* who) override - { - Talk(SAY_AGGRO); - BossAI::JustEngagedWith(who); + void KilledUnit(Unit* /*victim*/) override + { + Talk(SAY_SLAY); + } - events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 8s); - events.ScheduleEvent(EVENT_ARCANE_SHOCK, 5s); - } + void JustDied(Unit* /*killer*/) override + { + _JustDied(); + DoCastSelf(SPELL_CLEAR_ENERGY_FEEDBACK, true); + } - void JustSummoned(Creature* summoned) override - { - if (Unit* temp = SelectTarget(SelectTargetMethod::Random, 0)) - summoned->GetMotionMaster()->MoveFollow(temp, 0, 0); + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - summons.Summon(summoned); - } + events.Update(diff); - void DamageTaken(Unit* /*who*/, uint32& /*damage*/, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override - { - if (_enraged) - return; - - // 85%, 70%, 55%, 40%, 25% - if (!HealthAbovePct(100 - INTERVAL_MODIFIER * _intervalHealthAmount)) - { - // increase amount, unless we're at 10%, then we switch and return - if (_intervalHealthAmount == INTERVAL_SWITCH) - { - _enraged = true; - events.Reset(); - events.ScheduleEvent(EVENT_OVERLOAD, 1200ms); - return; - } - else - ++_intervalHealthAmount; - - Talk(SAY_ENERGY); - Talk(EMOTE_DISCHARGE_ENERGY); - - if (IsHeroic()) - { - DoCast(me, H_SPELL_SUMMON_PURE_ENERGY1); - DoCast(me, H_SPELL_SUMMON_PURE_ENERGY2); - } - else - DoCast(me, SPELL_SUMMON_PURE_ENERGY); - } - } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void UpdateAI(uint32 diff) override + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_CHAIN_LIGHTNING: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true)) - DoCast(target, SPELL_CHAIN_LIGHTNING); - events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 8s); - break; - case EVENT_ARCANE_SHOCK: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 20.0f, true)) - DoCast(target, SPELL_ARCANE_SHOCK); - events.ScheduleEvent(EVENT_ARCANE_SHOCK, 8s); - break; - case EVENT_OVERLOAD: - DoCastVictim(SPELL_OVERLOAD); - events.ScheduleEvent(EVENT_OVERLOAD, 2s); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); + case EVENT_CHAIN_LIGHTNING: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 0.0f, true)) + DoCast(target, SPELL_CHAIN_LIGHTNING); + events.Repeat(8s); + break; + case EVENT_ARCANE_SHOCK: + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 20.0f, true)) + DoCast(target, SPELL_ARCANE_SHOCK); + events.Repeat(8s); + break; + case EVENT_OVERLOAD: + DoCastSelf(SPELL_OVERLOAD); + events.Repeat(2s); + break; + default: + break; } - private: - uint32 _intervalHealthAmount; - bool _enraged; - }; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } - CreatureAI* GetAI(Creature* creature) const override - { - return GetMagistersTerraceAI<boss_vexallusAI>(creature); - }; + DoMeleeAttackIfReady(); + } + +private: + uint32 _intervalHealthAmount; + bool _enraged; }; -enum NpcPureEnergy +// 24745 - Pure Energy +struct npc_pure_energy : public ScriptedAI { - SPELL_ENERGY_BOLT = 46156, - SPELL_ENERGY_FEEDBACK = 44335, - SPELL_PURE_ENERGY_PASSIVE = 44326 + npc_pure_energy(Creature* creature) : ScriptedAI(creature) + { + me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); + } + + void JustDied(Unit* killer) override + { + // This is not correct as in sniff this spell was used not on killer + if (killer) + DoCast(killer, SPELL_ENERGY_FEEDBACK_PERIODIC, true); + me->RemoveAurasDueToSpell(SPELL_ENERGY_BOLT_PERIODIC); + } }; -class npc_pure_energy : public CreatureScript +// 44328 - Energy Feedback +class spell_vexallus_energy_feedback : public AuraScript { - public: - npc_pure_energy() : CreatureScript("npc_pure_energy") { } + PrepareAuraScript(spell_vexallus_energy_feedback); - struct npc_pure_energyAI : public ScriptedAI - { - npc_pure_energyAI(Creature* creature) : ScriptedAI(creature) - { - me->SetDisplayId(me->GetCreatureTemplate()->Modelid2); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ENERGY_FEEDBACK, SPELL_ENERGY_FEEDBACK_SCALE }); + } - void JustDied(Unit* killer) override - { - if (killer) - killer->CastSpell(killer, SPELL_ENERGY_FEEDBACK, true); - me->RemoveAurasDueToSpell(SPELL_PURE_ENERGY_PASSIVE); - } - }; + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->CastSpell(GetTarget(), SPELL_ENERGY_FEEDBACK, true); + } + + void OnPeriodic(AuraEffect const* aurEff) + { + Creature* caster = GetCaster()->ToCreature(); + if (!caster) + return; - CreatureAI* GetAI(Creature* creature) const override + switch (aurEff->GetTickNumber()) { - return GetMagistersTerraceAI<npc_pure_energyAI>(creature); - }; + case 1: + case 2: + case 3: + case 4: + caster->CastSpell(caster, SPELL_ENERGY_FEEDBACK_SCALE, true); + break; + case 5: + caster->CastSpell(caster, SPELL_ENERGY_FEEDBACK_SCALE, true); + caster->DespawnOrUnsummon(); + break; + default: + break; + } + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_vexallus_energy_feedback::AfterApply, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_vexallus_energy_feedback::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY); + } +}; + +// 47108 - Clear Energy Feedback +class spell_vexallus_clear_energy_feedback : public SpellScript +{ + PrepareSpellScript(spell_vexallus_clear_energy_feedback); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_ENERGY_FEEDBACK }); + } + + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->RemoveAurasDueToSpell(SPELL_ENERGY_FEEDBACK); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_vexallus_clear_energy_feedback::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; void AddSC_boss_vexallus() { - new boss_vexallus(); - new npc_pure_energy(); + RegisterMagistersTerraceCreatureAI(boss_vexallus); + RegisterMagistersTerraceCreatureAI(npc_pure_energy); + RegisterSpellScript(spell_vexallus_energy_feedback); + RegisterSpellScript(spell_vexallus_clear_energy_feedback); } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp index 4311c08efa2..653d92cace4 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp @@ -178,13 +178,7 @@ class instance_magisters_terrace : public InstanceMapScript _events.Update(diff); if (_events.ExecuteEvent() == EVENT_SPAWN_KALECGOS) - { - if (Creature* kalecgos = instance->SummonCreature(NPC_KALECGOS, KalecgosSpawnPos)) - { - kalecgos->GetMotionMaster()->MovePath(PATH_KALECGOS_FLIGHT, false); - kalecgos->AI()->Talk(SAY_KALECGOS_SPAWN); - } - } + instance->SummonCreature(NPC_KALECGOS, KalecgosSpawnPos); } bool SetBossState(uint32 type, EncounterState state) override diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp index d53c63a3acd..f2e62a21aa4 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp @@ -15,103 +15,91 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Magisters_Terrace -SD%Complete: 100 -SDComment: Quest support: 11490(post-event) -SDCategory: Magisters Terrace -EndScriptData */ - -/* ContentData -npc_kalecgos -EndContentData */ +/* + * Kalec for some reason lifts off after landing + * Kalec seems to be spawned after cinematic is finished, not after specific time + */ #include "ScriptMgr.h" #include "magisters_terrace.h" #include "MotionMaster.h" #include "Player.h" #include "ScriptedCreature.h" -#include "ScriptedGossip.h" -/*###### -## npc_kalecgos -######*/ - -enum Spells +enum KalecgosMisc { - SPELL_KALECGOS_TRANSFORM = 44670, - SPELL_TRANSFORM_VISUAL = 24085, + SAY_KALECGOS_SPAWN = 0, + SPELL_CAMERA_SHAKE = 44762, - SPELL_ORB_KILL_CREDIT = 46307 -}; + SPELL_TRANSFORM_VISUAL = 24085, + SPELL_ORB_KILL_CREDIT = 46307, -enum MovementPoints -{ - POINT_ID_PREPARE_LANDING = 6 -}; + PATH_KALECGOS_FLIGHT = 248440, + POINT_ID_PREPARE_LANDING = 6, -enum EventIds -{ - EVENT_KALECGOS_TRANSFORM = 1, - EVENT_KALECGOS_LANDING = 2 + EVENT_KALECGOS_LANDING = 1, + EVENT_KALECGOS_TRANSFORM, + EVENT_KALECGOS_SUMMON }; -class npc_kalecgos : public CreatureScript +Position const KalecgosHumanSpawnPos = { 197.86285f, -272.74414f, -8.651634f, 0.0f }; + +// 24844 - Kalecgos +struct npc_kalecgos : public ScriptedAI { -public: - npc_kalecgos() : CreatureScript("npc_kalecgos") { } + npc_kalecgos(Creature* creature) : ScriptedAI(creature) { } - struct npc_kalecgosAI : public ScriptedAI + void JustAppeared() override { - npc_kalecgosAI(Creature* creature) : ScriptedAI(creature) { } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != WAYPOINT_MOTION_TYPE) - return; + me->GetMotionMaster()->MovePath(PATH_KALECGOS_FLIGHT, false); + Talk(SAY_KALECGOS_SPAWN); + } - if (pointId == POINT_ID_PREPARE_LANDING) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); - me->SetDisableGravity(false); - me->SetHover(false); - events.ScheduleEvent(EVENT_KALECGOS_LANDING, 2s); - } - } + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != WAYPOINT_MOTION_TYPE) + return; - void UpdateAI(uint32 diff) override + if (pointId == POINT_ID_PREPARE_LANDING) { - events.Update(diff); - - switch (events.ExecuteEvent()) - { - case EVENT_KALECGOS_LANDING: - DoCastAOE(SPELL_CAMERA_SHAKE); - me->SetObjectScale(0.6f); - events.ScheduleEvent(EVENT_KALECGOS_TRANSFORM, 1s); - break; - case EVENT_KALECGOS_TRANSFORM: - DoCast(me, SPELL_ORB_KILL_CREDIT, true); - DoCast(me, SPELL_TRANSFORM_VISUAL, false); - DoCast(me, SPELL_KALECGOS_TRANSFORM, false); - me->UpdateEntry(NPC_HUMAN_KALECGOS); - break; - default: - break; - } + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->SetDisableGravity(false); + _events.ScheduleEvent(EVENT_KALECGOS_LANDING, 1s); } + } - private: - EventMap events; - }; - - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetMagistersTerraceAI<npc_kalecgosAI>(creature); + _events.Update(diff); + + switch (_events.ExecuteEvent()) + { + case EVENT_KALECGOS_LANDING: + DoCastSelf(SPELL_CAMERA_SHAKE); + me->SetFacingTo(0.0698132f); + me->SetObjectScale(0.6f); + _events.ScheduleEvent(EVENT_KALECGOS_TRANSFORM, 1s); + break; + case EVENT_KALECGOS_TRANSFORM: + DoCastSelf(SPELL_TRANSFORM_VISUAL); + // This doesn't appear in sniff and credit is rewarded when cinematic is finished + DoCastSelf(SPELL_ORB_KILL_CREDIT); + _events.ScheduleEvent(EVENT_KALECGOS_SUMMON, 1s); + break; + case EVENT_KALECGOS_SUMMON: + me->SummonCreature(NPC_HUMAN_KALECGOS, KalecgosHumanSpawnPos, TEMPSUMMON_MANUAL_DESPAWN); + me->DespawnOrUnsummon(1500ms); + break; + default: + break; + } } + +private: + EventMap _events; }; void AddSC_magisters_terrace() { - new npc_kalecgos(); + RegisterMagistersTerraceCreatureAI(npc_kalecgos); } diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h index 63041a51618..4dfc3b30c1c 100644 --- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h +++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h @@ -51,13 +51,13 @@ enum MTCreatureIds BOSS_PRIESTESS_DELRISSA = 24560, // Encounter related - /*Kael'thas Sunstrider*/ + // Kael'thas Sunstrider NPC_ARCANE_SPHERE = 24708, NPC_FLAME_STRIKE = 24666, NPC_PHOENIX = 24674, NPC_PHOENIX_EGG = 24675, - /*Selin Fireheart*/ + // Selin Fireheart NPC_FEL_CRYSTAL = 24722, // Event related @@ -83,17 +83,7 @@ enum MTGameObjectIds enum MTInstanceEventIds { - EVENT_SPAWN_KALECGOS = 16547 -}; - -enum MTInstanceText -{ - SAY_KALECGOS_SPAWN = 0 -}; - -enum MTMovementData -{ - PATH_KALECGOS_FLIGHT = 248440 + EVENT_SPAWN_KALECGOS = 16547 }; template <class AI, class T> |