diff options
author | Shauren <shauren.trinity@gmail.com> | 2011-02-03 21:59:07 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2011-02-03 21:59:07 +0100 |
commit | 7ea8bad07f64ed5886130fcc8016c0c72a32758e (patch) | |
tree | 7fbd4102dbd5ca30a9aa81df42ba602f749e996d /src | |
parent | 0a5d8711e5294c36d40b779187e1718d3365f5fa (diff) |
Scripts/Molten Core: Huge cleanup in instance script, converted all bosses to use BossAI, cleaned code style
Scripts/Molten Core: Implemented saving boss states to database, now it is possible to continue the instance after core restart
Diffstat (limited to 'src')
12 files changed, 1364 insertions, 1598 deletions
diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_baron_geddon.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_baron_geddon.cpp index 796d7bcadfb..19ce6288c78 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_baron_geddon.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_baron_geddon.cpp @@ -23,98 +23,97 @@ SDComment: SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "molten_core.h" -#define EMOTE_SERVICE -1409000 +#define EMOTE_SERVICE -1409000 -#define SPELL_INFERNO 19695 -#define SPELL_IGNITEMANA 19659 -#define SPELL_LIVINGBOMB 20475 -#define SPELL_ARMAGEDDOM 20479 - -class boss_baron_geddon : public CreatureScript +enum Spells { -public: - boss_baron_geddon() : CreatureScript("boss_baron_geddon") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_baron_geddonAI (pCreature); - } - - struct boss_baron_geddonAI : public ScriptedAI - { - boss_baron_geddonAI(Creature *pCreature) : ScriptedAI(pCreature) - { - m_pInstance = pCreature->GetInstanceScript(); - } - InstanceScript* m_pInstance; - - uint32 Inferno_Timer; - uint32 IgniteMana_Timer; - uint32 LivingBomb_Timer; - - void Reset() - { - Inferno_Timer = 45000; //These times are probably wrong - IgniteMana_Timer = 30000; - LivingBomb_Timer = 35000; - } + SPELL_INFERNO = 19695, + SPELL_IGNITE_MANA = 19659, + SPELL_LIVING_BOMB = 20475, + SPELL_ARMAGEDDON = 20479, +}; - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance) - m_pInstance->SetData(DATA_GEDDON, 0); - } +enum Events +{ + EVENT_INFERNO = 1, + EVENT_IGNITE_MANA = 2, + EVENT_LIVING_BOMB = 3, +}; - void EnterCombat(Unit * /*who*/) - { - } +class boss_baron_geddon : public CreatureScript +{ + public: + boss_baron_geddon() : CreatureScript("boss_baron_geddon") { } - void UpdateAI(const uint32 diff) + struct boss_baron_geddonAI : public BossAI { - if (!UpdateVictim()) - return; - - //If we are <2% hp cast Armageddom - if (!HealthAbovePct(2)) + boss_baron_geddonAI(Creature *pCreature) : BossAI(pCreature, BOSS_BARON_GEDDON) { - me->InterruptNonMeleeSpells(true); - DoCast(me, SPELL_ARMAGEDDOM); - DoScriptText(EMOTE_SERVICE, me); - return; } - //Inferno_Timer - if (Inferno_Timer <= diff) - { - DoCast(me, SPELL_INFERNO); - Inferno_Timer = 45000; - } else Inferno_Timer -= diff; - - //IgniteMana_Timer - if (IgniteMana_Timer <= diff) + void EnterCombat(Unit* victim) { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(pTarget, SPELL_IGNITEMANA); - - IgniteMana_Timer = 30000; - } else IgniteMana_Timer -= diff; + BossAI::EnterCombat(victim); + events.ScheduleEvent(EVENT_INFERNO, 45000); + events.ScheduleEvent(EVENT_IGNITE_MANA, 30000); + events.ScheduleEvent(EVENT_LIVING_BOMB, 35000); + } - //LivingBomb_Timer - if (LivingBomb_Timer <= diff) + void UpdateAI(const uint32 diff) { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(pTarget, SPELL_LIVINGBOMB); - - LivingBomb_Timer = 35000; - } else LivingBomb_Timer -= diff; + if (!UpdateVictim()) + return; + + events.Update(diff); + + // If we are <2% hp cast Armageddon + if (!HealthAbovePct(2)) + { + me->InterruptNonMeleeSpells(true); + DoCast(me, SPELL_ARMAGEDDON); + DoScriptText(EMOTE_SERVICE, me); + return; + } + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_INFERNO: + DoCast(me, SPELL_INFERNO); + events.ScheduleEvent(EVENT_INFERNO, 45000); + break; + case EVENT_IGNITE_MANA: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_IGNITE_MANA)) + DoCast(target, SPELL_IGNITE_MANA); + events.ScheduleEvent(EVENT_IGNITE_MANA, 30000); + break; + case EVENT_LIVING_BOMB: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + DoCast(target, SPELL_LIVING_BOMB); + events.ScheduleEvent(EVENT_LIVING_BOMB, 35000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* pCreature) const + { + return new boss_baron_geddonAI (pCreature); } - }; - }; void AddSC_boss_baron_geddon() diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_garr.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_garr.cpp index 5cddc3348b9..d52c7a4d369 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_garr.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_garr.cpp @@ -23,135 +23,134 @@ SDComment: Adds NYI SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "molten_core.h" -// Garr spells -#define SPELL_ANTIMAGICPULSE 19492 -#define SPELL_MAGMASHACKLES 19496 -#define SPELL_ENRAGE 19516 //Stacking enrage (stacks to 10 times) +enum Spells +{ + // Garr + SPELL_ANTIMAGIC_PULSE = 19492, + SPELL_MAGMA_SHACKLES = 19496, + SPELL_ENRAGE = 19516, + + // Adds + SPELL_ERUPTION = 19497, + SPELL_IMMOLATE = 20294, +}; -//Add spells -#define SPELL_ERUPTION 19497 -#define SPELL_IMMOLATE 20294 +enum Events +{ + EVENT_ANTIMAGIC_PULSE = 1, + EVENT_MAGMA_SHACKLES = 2, +}; class boss_garr : public CreatureScript { -public: - boss_garr() : CreatureScript("boss_garr") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_garrAI (pCreature); - } + public: + boss_garr() : CreatureScript("boss_garr") { } - struct boss_garrAI : public ScriptedAI - { - boss_garrAI(Creature *pCreature) : ScriptedAI(pCreature) + struct boss_garrAI : public BossAI { - m_pInstance = pCreature->GetInstanceScript(); - } - InstanceScript* m_pInstance; - - uint32 AntiMagicPulse_Timer; - uint32 MagmaShackles_Timer; - uint32 CheckAdds_Timer; - uint64 Add[8]; - bool Enraged[8]; - - void Reset() - { - AntiMagicPulse_Timer = 25000; //These times are probably wrong - MagmaShackles_Timer = 15000; - CheckAdds_Timer = 2000; - } - - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance) - m_pInstance->SetData(DATA_GARR, 0); - } - - void EnterCombat(Unit * /*who*/) - { - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + boss_garrAI(Creature* creature) : BossAI(creature, BOSS_GARR) + { + } - //AntiMagicPulse_Timer - if (AntiMagicPulse_Timer <= diff) + void EnterCombat(Unit* victim) { - DoCast(me, SPELL_ANTIMAGICPULSE); - AntiMagicPulse_Timer = 10000 + rand()%5000; - } else AntiMagicPulse_Timer -= diff; + BossAI::EnterCombat(victim); + events.ScheduleEvent(EVENT_ANTIMAGIC_PULSE, 25000); + events.ScheduleEvent(EVENT_MAGMA_SHACKLES, 15000); + } - //MagmaShackles_Timer - if (MagmaShackles_Timer <= diff) + void UpdateAI(const uint32 diff) { - DoCast(me, SPELL_MAGMASHACKLES); - MagmaShackles_Timer = 8000 + rand()%4000; - } else MagmaShackles_Timer -= diff; + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_ANTIMAGIC_PULSE: + DoCast(me, SPELL_ANTIMAGIC_PULSE); + events.ScheduleEvent(EVENT_ANTIMAGIC_PULSE, urand(10000, 15000)); + break; + case EVENT_MAGMA_SHACKLES: + DoCast(me, SPELL_MAGMA_SHACKLES); + events.ScheduleEvent(EVENT_MAGMA_SHACKLES, urand(8000, 12000)); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const + { + return new boss_garrAI(creature); } - }; - }; class mob_firesworn : public CreatureScript { -public: - mob_firesworn() : CreatureScript("mob_firesworn") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new mob_fireswornAI (pCreature); - } - - struct mob_fireswornAI : public ScriptedAI - { - mob_fireswornAI(Creature *c) : ScriptedAI(c) {} - - uint32 Immolate_Timer; - - void Reset() - { - Immolate_Timer = 4000; //These times are probably wrong - } + public: + mob_firesworn() : CreatureScript("mob_firesworn") { } - void EnterCombat(Unit * /*who*/) + struct mob_fireswornAI : public ScriptedAI { - } + mob_fireswornAI(Creature* creature) : ScriptedAI(creature) {} - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + uint32 immolateTimer; - //Immolate_Timer - if (Immolate_Timer <= diff) + void Reset() { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(pTarget, SPELL_IMMOLATE); + immolateTimer = 4000; //These times are probably wrong + } - Immolate_Timer = urand(5000,10000); - } else Immolate_Timer -= diff; + void DamageTaken(Unit* /*attacker*/, uint32& damage) + { + uint32 const health10pct = me->CountPctFromMaxHealth(10); + uint32 health = me->GetHealth(); + if (int32(health) - int32(damage) < int32(health10pct)) + { + damage = 0; + DoCastVictim(SPELL_ERUPTION); + me->DespawnOrUnsummon(); + } + } - //Cast Erruption and let them die - if (!HealthAbovePct(10)) + void UpdateAI(const uint32 diff) { - DoCast(me->getVictim(), SPELL_ERUPTION); - me->setDeathState(JUST_DIED); - me->RemoveCorpse(); + if (!UpdateVictim()) + return; + + if (immolateTimer <= diff) + { + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_IMMOLATE); + immolateTimer = urand(5000, 10000); + } + else + immolateTimer -= diff; + + DoMeleeAttackIfReady(); } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const + { + return new mob_fireswornAI(creature); } - }; - }; diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_gehennas.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_gehennas.cpp index 70b379aa380..bf476b4e3e4 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_gehennas.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_gehennas.cpp @@ -23,84 +23,85 @@ SDComment: Adds MC NYI SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "molten_core.h" -#define SPELL_SHADOWBOLT 19728 -#define SPELL_RAINOFFIRE 19717 -#define SPELL_GEHENNASCURSE 19716 - -class boss_gehennas : public CreatureScript +enum Spells { -public: - boss_gehennas() : CreatureScript("boss_gehennas") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_gehennasAI (pCreature); - } - - struct boss_gehennasAI : public ScriptedAI - { - boss_gehennasAI(Creature *pCreature) : ScriptedAI(pCreature) - { - m_pInstance = pCreature->GetInstanceScript(); - } - InstanceScript* m_pInstance; - - uint32 ShadowBolt_Timer; - uint32 RainOfFire_Timer; - uint32 GehennasCurse_Timer; - - void Reset() - { - ShadowBolt_Timer = 6000; - RainOfFire_Timer = 10000; - GehennasCurse_Timer = 12000; - } + SPELL_GEHENNAS_CURSE = 19716, + SPELL_RAIN_OF_FIRE = 19717, + SPELL_SHADOW_BOLT = 19728, +}; - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance) - m_pInstance->SetData(DATA_GEHENNAS, 0); - } +enum Events +{ + EVENT_GEHENNAS_CURSE = 1, + EVENT_RAIN_OF_FIRE = 2, + EVENT_SHADOW_BOLT = 3, +}; - void EnterCombat(Unit * /*who*/) {} +class boss_gehennas : public CreatureScript +{ + public: + boss_gehennas() : CreatureScript("boss_gehennas") { } - void UpdateAI(const uint32 diff) + struct boss_gehennasAI : public BossAI { - if (!UpdateVictim()) - return; - - //ShadowBolt_Timer - if (ShadowBolt_Timer <= diff) + boss_gehennasAI(Creature* creature) : BossAI(creature, BOSS_GEHENNAS) { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1)) - DoCast(pTarget, SPELL_SHADOWBOLT); + } - ShadowBolt_Timer = 7000; - } else ShadowBolt_Timer -= diff; - - //RainOfFire_Timer - if (RainOfFire_Timer <= diff) + void EnterCombat(Unit* victim) { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pTarget, SPELL_RAINOFFIRE); - - RainOfFire_Timer = urand(4000,12000); - } else RainOfFire_Timer -= diff; + BossAI::EnterCombat(victim); + events.ScheduleEvent(EVENT_GEHENNAS_CURSE, 12000); + events.ScheduleEvent(EVENT_RAIN_OF_FIRE, 10000); + events.ScheduleEvent(EVENT_SHADOW_BOLT, 6000); + } - //GehennasCurse_Timer - if (GehennasCurse_Timer <= diff) + void UpdateAI(const uint32 diff) { - DoCast(me->getVictim(), SPELL_GEHENNASCURSE); - GehennasCurse_Timer = urand(22000,30000); - } else GehennasCurse_Timer -= diff; - - DoMeleeAttackIfReady(); + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_GEHENNAS_CURSE: + DoCastVictim(SPELL_GEHENNAS_CURSE); + events.ScheduleEvent(EVENT_GEHENNAS_CURSE, urand(22000, 30000)); + break; + case EVENT_RAIN_OF_FIRE: + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_RAIN_OF_FIRE); + events.ScheduleEvent(EVENT_RAIN_OF_FIRE, urand(4000, 12000)); + break; + case EVENT_SHADOW_BOLT: + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1)) + DoCast(target, SPELL_SHADOW_BOLT); + events.ScheduleEvent(EVENT_SHADOW_BOLT, 7000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_gehennasAI(creature); } - }; - }; void AddSC_boss_gehennas() diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp index 06170f19a20..a0daf31531c 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_golemagg.cpp @@ -23,11 +23,19 @@ SDComment: Timers need to be confirmed, Golemagg's Trust need to be checked SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "molten_core.h" -enum eEnums +enum Texts { + EMOTE_LOWHP = -1409002, +}; + +enum Spells +{ + // Golemagg SPELL_MAGMASPLASH = 13879, SPELL_PYROBLAST = 20228, SPELL_EARTHQUAKE = 19798, @@ -35,169 +43,145 @@ enum eEnums SPELL_GOLEMAGG_TRUST = 20553, // Core Rager - EMOTE_LOWHP = -1409002, SPELL_MANGLE = 19820 }; -class boss_golemagg : public CreatureScript +enum Events { -public: - boss_golemagg() : CreatureScript("boss_golemagg") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_golemaggAI (pCreature); - } - - struct boss_golemaggAI : public ScriptedAI - { - boss_golemaggAI(Creature* pCreature) : ScriptedAI(pCreature) - { - m_pInstance = pCreature->GetInstanceScript(); - } - - InstanceScript* m_pInstance; - - uint32 m_uiPyroblastTimer; - uint32 m_uiEarthquakeTimer; - uint32 m_uiBuffTimer; - bool m_bEnraged; - - void Reset() - { - m_uiPyroblastTimer = 7*IN_MILLISECONDS; // These timers are probably wrong - m_uiEarthquakeTimer = 3*IN_MILLISECONDS; - m_uiBuffTimer = 2500; - m_bEnraged = false; - - DoCast(me, SPELL_MAGMASPLASH, true); - } + EVENT_PYROBLAST = 1, + EVENT_EARTHQUAKE = 2, +}; - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance) - m_pInstance->SetData(DATA_GOLEMAGG, 0); - } +class boss_golemagg : public CreatureScript +{ + public: + boss_golemagg() : CreatureScript("boss_golemagg") { } - void UpdateAI(const uint32 uiDiff) + struct boss_golemaggAI : public BossAI { - if (!UpdateVictim()) - return; + boss_golemaggAI(Creature* creature) : BossAI(creature, BOSS_GOLEMAGG_THE_INCINERATOR) + { + } - //Pyroblast - if (m_uiPyroblastTimer <= uiDiff) + void Reset() { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) - DoCast(pTarget, SPELL_PYROBLAST); + BossAI::Reset(); + DoCast(me, SPELL_MAGMASPLASH, true); + } - m_uiPyroblastTimer = 7*IN_MILLISECONDS; + void EnterCombat(Unit* victim) + { + BossAI::EnterCombat(victim); + events.ScheduleEvent(EVENT_PYROBLAST, 7000); } - else - m_uiPyroblastTimer -= uiDiff; - // Enrage - if (!m_bEnraged && HealthBelowPct(10)) + void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { - DoCast(me, SPELL_ENRAGE); - m_bEnraged = true; + if (HealthBelowPct(10) || me->HasAura(SPELL_ENRAGE)) + return; + + DoCast(me, SPELL_ENRAGE, true); + events.ScheduleEvent(EVENT_EARTHQUAKE, 3000); } - // Earthquake - if (m_bEnraged) + void UpdateAI(const uint32 diff) { - if (m_uiEarthquakeTimer <= uiDiff) + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { - DoCast(me->getVictim(), SPELL_EARTHQUAKE); - m_uiEarthquakeTimer = 3*IN_MILLISECONDS; + switch (eventId) + { + case EVENT_PYROBLAST: + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(pTarget, SPELL_PYROBLAST); + events.ScheduleEvent(EVENT_PYROBLAST, 7000); + break; + case EVENT_EARTHQUAKE: + DoCastVictim(SPELL_EARTHQUAKE); + events.ScheduleEvent(EVENT_EARTHQUAKE, 3000); + break; + default: + break; + } } - else - m_uiEarthquakeTimer -= uiDiff; - } - /* - // Golemagg's Trust - if (m_uiBuffTimer <= uidiff) - { - DoCast(me, SPELL_GOLEMAGG_TRUST); - m_uiBuffTimer = 2.5*IN_MILLISECONDS; + DoMeleeAttackIfReady(); } - else - m_uiBuffTimer -= uiDiff; - */ + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const + { + return new boss_golemaggAI(creature); } - }; - }; class mob_core_rager : public CreatureScript { -public: - mob_core_rager() : CreatureScript("mob_core_rager") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new mob_core_ragerAI (pCreature); - } + public: + mob_core_rager() : CreatureScript("mob_core_rager") { } - struct mob_core_ragerAI : public ScriptedAI - { - mob_core_ragerAI(Creature *c) : ScriptedAI(c) + struct mob_core_ragerAI : public ScriptedAI { - m_pInstance = c->GetInstanceScript(); - } - - InstanceScript* m_pInstance; - - uint32 m_uiMangleTimer; + mob_core_ragerAI(Creature* creature) : ScriptedAI(creature) + { + instance = creature->GetInstanceScript(); + } - void Reset() - { - m_uiMangleTimer = 7*IN_MILLISECONDS; // These times are probably wrong - } + void Reset() + { + mangleTimer = 7*IN_MILLISECONDS; // These times are probably wrong + } - void DamageTaken(Unit* /*pDoneBy*/, uint32& uiDamage) - { - if (HealthBelowPct(50)) + void DamageTaken(Unit* /*attacker*/, uint32& damage) { - if (m_pInstance) + if (HealthAbovePct(50) || !instance) + return; + + if (Creature* pGolemagg = instance->instance->GetCreature(instance->GetData64(BOSS_GOLEMAGG_THE_INCINERATOR))) { - if (Creature* pGolemagg = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_GOLEMAGG))) + if (pGolemagg->isAlive()) { - if (pGolemagg->isAlive()) - { - DoScriptText(EMOTE_LOWHP, me); - me->SetFullHealth(); - } - else - uiDamage = me->GetHealth(); + me->AddAura(SPELL_GOLEMAGG_TRUST, me); + DoScriptText(EMOTE_LOWHP, me); + me->SetFullHealth(); } } } - } - - void UpdateAI(const uint32 uiDiff) - { - if (!UpdateVictim()) - return; - // Mangle - if (m_uiMangleTimer <= uiDiff) + void UpdateAI(const uint32 diff) { - DoCast(me->getVictim(), SPELL_MANGLE); - m_uiMangleTimer = 10*IN_MILLISECONDS; - } - else - m_uiMangleTimer -= uiDiff; + if (!UpdateVictim()) + return; - DoMeleeAttackIfReady(); - } - }; + // Mangle + if (mangleTimer <= diff) + { + DoCast(me->getVictim(), SPELL_MANGLE); + mangleTimer = 10*IN_MILLISECONDS; + } + else + mangleTimer -= diff; -}; + DoMeleeAttackIfReady(); + } + private: + InstanceScript* instance; + uint32 mangleTimer; + }; + CreatureAI* GetAI(Creature* creature) const + { + return new mob_core_ragerAI(creature); + } +}; void AddSC_boss_golemagg() { diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_lucifron.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_lucifron.cpp index ed6dc98a3b2..54bb5bc7880 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_lucifron.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_lucifron.cpp @@ -23,82 +23,83 @@ SDComment: SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "molten_core.h" -#define SPELL_IMPENDINGDOOM 19702 -#define SPELL_LUCIFRONCURSE 19703 -#define SPELL_SHADOWSHOCK 20603 - -class boss_lucifron : public CreatureScript +enum Spells { -public: - boss_lucifron() : CreatureScript("boss_lucifron") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_lucifronAI (pCreature); - } - - struct boss_lucifronAI : public ScriptedAI - { - boss_lucifronAI(Creature *pCreature) : ScriptedAI(pCreature) - { - m_pInstance = pCreature->GetInstanceScript(); - } - InstanceScript* m_pInstance; - - uint32 ImpendingDoom_Timer; - uint32 LucifronCurse_Timer; - uint32 ShadowShock_Timer; - - void Reset() - { - ImpendingDoom_Timer = 10000; //Initial cast after 10 seconds so the debuffs alternate - LucifronCurse_Timer = 20000; //Initial cast after 20 seconds - ShadowShock_Timer = 6000; //6 seconds - } + SPELL_IMPENDING_DOOM = 19702, + SPELL_LUCIFRON_CURSE = 19703, + SPELL_SHADOW_SHOCK = 20603, +}; - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance) - m_pInstance->SetData(DATA_LUCIFRON, 0); - } +enum Events +{ + EVENT_IMPENDING_DOOM = 1, + EVENT_LUCIFRON_CURSE = 2, + EVENT_SHADOW_SHOCK = 3, +}; - void EnterCombat(Unit * /*who*/) - { - } +class boss_lucifron : public CreatureScript +{ + public: + boss_lucifron() : CreatureScript("boss_lucifron") { } - void UpdateAI(const uint32 diff) + struct boss_lucifronAI : public BossAI { - if (!UpdateVictim()) - return; - - //Impending doom timer - if (ImpendingDoom_Timer <= diff) + boss_lucifronAI(Creature* creature) : BossAI(creature, BOSS_LUCIFRON) { - DoCast(me->getVictim(), SPELL_IMPENDINGDOOM); - ImpendingDoom_Timer = 20000; - } else ImpendingDoom_Timer -= diff; + } - //Lucifron's curse timer - if (LucifronCurse_Timer <= diff) + void EnterCombat(Unit* victim) { - DoCast(me->getVictim(), SPELL_LUCIFRONCURSE); - LucifronCurse_Timer = 15000; - } else LucifronCurse_Timer -= diff; + BossAI::EnterCombat(victim); + events.ScheduleEvent(EVENT_IMPENDING_DOOM, 10000); + events.ScheduleEvent(EVENT_LUCIFRON_CURSE, 20000); + events.ScheduleEvent(EVENT_SHADOW_SHOCK, 6000); + } - //Shadowshock - if (ShadowShock_Timer <= diff) + void UpdateAI(const uint32 diff) { - DoCast(me->getVictim(), SPELL_SHADOWSHOCK); - ShadowShock_Timer = 6000; - } else ShadowShock_Timer -= diff; - - DoMeleeAttackIfReady(); + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_IMPENDING_DOOM: + DoCastVictim(SPELL_IMPENDING_DOOM); + events.ScheduleEvent(EVENT_IMPENDING_DOOM, 20000); + break; + case EVENT_LUCIFRON_CURSE: + DoCastVictim(SPELL_LUCIFRON_CURSE); + events.ScheduleEvent(EVENT_LUCIFRON_CURSE, 15000); + break; + case EVENT_SHADOW_SHOCK: + DoCastVictim(SPELL_SHADOW_SHOCK); + events.ScheduleEvent(EVENT_SHADOW_SHOCK, 6000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_lucifronAI(creature); } - }; - }; void AddSC_boss_lucifron() diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_magmadar.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_magmadar.cpp index db48760c90f..6f17c9e8079 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_magmadar.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_magmadar.cpp @@ -19,95 +19,101 @@ /* ScriptData SDName: Boss_Magmadar SD%Complete: 75 -SDComment: Conflag on ground nyi, fear causes issues without VMAPs +SDComment: Conflag on ground nyi SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "molten_core.h" -#define EMOTE_FRENZY -1409001 - -#define SPELL_FRENZY 19451 -#define SPELL_MAGMASPIT 19449 //This is actually a buff he gives himself -#define SPELL_PANIC 19408 -#define SPELL_LAVABOMB 19411 //This calls a dummy server side effect that isn't implemented yet -#define SPELL_LAVABOMB_ALT 19428 //This is the spell that the lava bomb casts - -class boss_magmadar : public CreatureScript +enum Texts { -public: - boss_magmadar() : CreatureScript("boss_magmadar") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_magmadarAI (pCreature); - } - - struct boss_magmadarAI : public ScriptedAI - { - boss_magmadarAI(Creature *pCreature) : ScriptedAI(pCreature) - { - m_pInstance = pCreature->GetInstanceScript(); - } - InstanceScript* m_pInstance; - - uint32 Frenzy_Timer; - uint32 Panic_Timer; - uint32 Lavabomb_Timer; - - void Reset() - { - Frenzy_Timer = 30000; - Panic_Timer = 20000; - Lavabomb_Timer = 12000; + EMOTE_FRENZY = -1409001, +}; - DoCast(me, SPELL_MAGMASPIT, true); - } +enum Spells +{ + SPELL_FRENZY = 19451, + SPELL_MAGMA_SPIT = 19449, + SPELL_PANIC = 19408, + SPELL_LAVA_BOMB = 19428, +}; - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance) - m_pInstance->SetData(DATA_MAGMADAR, 0); - } +enum Events +{ + EVENT_FRENZY = 1, + EVENT_PANIC = 2, + EVENT_LAVA_BOMB = 3, +}; - void EnterCombat(Unit * /*who*/) - { - } +class boss_magmadar : public CreatureScript +{ + public: + boss_magmadar() : CreatureScript("boss_magmadar") { } - void UpdateAI(const uint32 diff) + struct boss_magmadarAI : public BossAI { - if (!UpdateVictim()) - return; - - //Frenzy_Timer - if (Frenzy_Timer <= diff) + boss_magmadarAI(Creature *pCreature) : BossAI(pCreature, BOSS_MAGMADAR) { - DoScriptText(EMOTE_FRENZY, me); - DoCast(me, SPELL_FRENZY); - Frenzy_Timer = 15000; - } else Frenzy_Timer -= diff; + } - //Panic_Timer - if (Panic_Timer <= diff) + void Reset() { - DoCast(me->getVictim(), SPELL_PANIC); - Panic_Timer = 35000; - } else Panic_Timer -= diff; + BossAI::Reset(); + DoCast(me, SPELL_MAGMA_SPIT, true); + } - //Lavabomb_Timer - if (Lavabomb_Timer <= diff) + void EnterCombat(Unit* victim) { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - DoCast(pTarget, SPELL_LAVABOMB_ALT); - - Lavabomb_Timer = 12000; - } else Lavabomb_Timer -= diff; + BossAI::EnterCombat(victim); + events.ScheduleEvent(EVENT_FRENZY, 30000); + events.ScheduleEvent(EVENT_PANIC, 20000); + events.ScheduleEvent(EVENT_LAVA_BOMB, 12000); + } - DoMeleeAttackIfReady(); + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_FRENZY: + DoScriptText(EMOTE_FRENZY, me); + DoCast(me, SPELL_FRENZY); + events.ScheduleEvent(EVENT_FRENZY, 15000); + break; + case EVENT_PANIC: + DoCastVictim(SPELL_PANIC); + events.ScheduleEvent(EVENT_PANIC, 35000); + break; + case EVENT_LAVA_BOMB: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_LAVA_BOMB)) + DoCast(target, SPELL_LAVA_BOMB); + events.ScheduleEvent(EVENT_LAVA_BOMB, 12000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return new boss_magmadarAI(creature); } - }; - }; void AddSC_boss_magmadar() diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_majordomo_executus.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_majordomo_executus.cpp index 91f1e8b3bab..ffa48d8846b 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_majordomo_executus.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_majordomo_executus.cpp @@ -23,205 +23,194 @@ SDComment: Correct spawning and Event NYI SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" #include "molten_core.h" -#define SAY_AGGRO -1409003 -#define SAY_SPAWN -1409004 -#define SAY_SLAY -1409005 -#define SAY_SPECIAL -1409006 -#define SAY_DEFEAT -1409007 - -#define SAY_SUMMON_MAJ -1409008 -#define SAY_ARRIVAL1_RAG -1409009 -#define SAY_ARRIVAL2_MAJ -1409010 -#define SAY_ARRIVAL3_RAG -1409011 -#define SAY_ARRIVAL5_RAG -1409012 - -#define ENTRY_RAGNAROS 11502 - -#define EMOTE_EMERGE 449 - -#define TELE_TO_RAG_X 829.159f -#define TELE_TO_RAG_Y -815.773f -#define TELE_TO_RAG_Z -228.972f -#define TELE_TO_RAG_O 5.305f - -#define SPELL_MAGIC_REFLECTION 20619 -#define SPELL_DAMAGE_REFLECTION 21075 - -#define SPELL_BLASTWAVE 20229 -#define SPELL_AEGIS 20620 //This is self casted whenever we are below 50% -#define SPELL_TELEPORT 20618 -#define SPELL_SUMMON_RAGNAROS 19774 +enum Texts +{ + SAY_AGGRO = -1409003, + SAY_SPAWN = -1409004, + SAY_SLAY = -1409005, + SAY_SPECIAL = -1409006, + SAY_DEFEAT = -1409007, + + SAY_SUMMON_MAJ = -1409008, + SAY_ARRIVAL1_RAG = -1409009, + SAY_ARRIVAL2_MAJ = -1409010, + SAY_ARRIVAL3_RAG = -1409011, + SAY_ARRIVAL5_RAG = -1409012, +}; -#define ENTRY_FLAMEWALKER_HEALER 11663 -#define ENTRY_FLAMEWALKER_ELITE 11664 +enum Spells +{ + SPELL_MAGIC_REFLECTION = 20619, + SPELL_DAMAGE_REFLECTION = 21075, + SPELL_BLAST_WAVE = 20229, + SPELL_AEGIS_OF_RAGNAROS = 20620, + SPELL_TELEPORT = 20618, + SPELL_SUMMON_RAGNAROS = 19774, +}; #define GOSSIP_HELLO 4995 -#define GOSSIP_SELLECT "Tell me more." +#define GOSSIP_SELECT "Tell me more." -class boss_majordomo : public CreatureScript +enum Events { -public: - boss_majordomo() : CreatureScript("boss_majordomo") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_majordomoAI (pCreature); - } - - bool OnGossipHello(Player* pPlayer, Creature* pCreature) - { - pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELLECT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); - pPlayer->SEND_GOSSIP_MENU(GOSSIP_HELLO, pCreature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* pPlayer, Creature* pCreature, uint32 /*uiSender*/, uint32 /*uiAction*/) - { - //ScriptedInstance* pInstance = pCreature->GetInstanceData(); - - BossAI* pBossAI = CAST_AI(boss_majordomoAI, pCreature->AI()); - - if (/*pInstance && */pBossAI) - { - pPlayer->CLOSE_GOSSIP_MENU(); - CAST_AI(boss_majordomoAI, pCreature->AI())->StartRagsEvent(); - } - return true; - } - - struct boss_majordomoAI : public BossAI - { - boss_majordomoAI(Creature *pCreature) : BossAI(pCreature, BOSS_MAJORDOMO) - { - m_pInstance = pCreature->GetInstanceScript(); - } - InstanceScript* m_pInstance; - - uint32 MagicReflection_Timer; - uint32 DamageReflection_Timer; - uint32 Blastwave_Timer; - uint32 Teleport_Timer; - uint32 Phase_Timer; //for teleport and ragnaros's intro - uint8 Phase; - - void Reset() - { - MagicReflection_Timer = 30000; //Damage reflection first so we alternate - DamageReflection_Timer = 15000; - Blastwave_Timer = 10000; - Teleport_Timer = 20000; - Phase = 0; - } - - void KilledUnit(Unit* /*victim*/) - { - if (rand()%5) - return; + EVENT_MAGIC_REFLECTION = 1, + EVENT_DAMAGE_REFLECTION = 2, + EVENT_BLAST_WAVE = 3, + EVENT_TELEPORT = 4, + + EVENT_OUTRO_1 = 5, + EVENT_OUTRO_2 = 6, + EVENT_OUTRO_3 = 7, +}; - DoScriptText(SAY_SLAY, me); - } +class boss_majordomo : public CreatureScript +{ + public: + boss_majordomo() : CreatureScript("boss_majordomo") { } - void EnterCombat(Unit * /*who*/) + struct boss_majordomoAI : public BossAI { - DoScriptText(SAY_AGGRO, me); - } + boss_majordomoAI(Creature *pCreature) : BossAI(pCreature, BOSS_MAJORDOMO_EXECUTUS) + { + } - void UpdateAI(const uint32 diff) - { - if (Phase == 0) + void KilledUnit(Unit* /*victim*/) { - if (!UpdateVictim()) - return; + if (urand(0, 99) < 25) + DoScriptText(SAY_SLAY, me); + } - if (((!me->FindNearestCreature(ENTRY_FLAMEWALKER_HEALER,100.0f)) && (!me->FindNearestCreature(ENTRY_FLAMEWALKER_ELITE,100.0f))) && (!m_pInstance->GetData(DATA_MAJORDOMOISDEAD))) - { - me->setFaction(35); - me->AI()->EnterEvadeMode(); - DoScriptText(SAY_DEFEAT, me); - //DoCast(SPELL_SUMMON_RAGNAROS); Not working atm ,doing workaround - if (m_pInstance) - m_pInstance->SetData(DATA_MAJORDOMO, DONE); - //m_pInstance->SetBossState(DATA_MAJORDOMO, DONE); - Phase_Timer = 32000; - Phase = 1; - } - - //Cast Ageis if less than 50% hp - if (HealthBelowPct(50)) - DoCast(me, SPELL_AEGIS); - - if (MagicReflection_Timer <= diff) - { - DoCast(me, SPELL_MAGIC_REFLECTION); - MagicReflection_Timer = 30000; - } else MagicReflection_Timer -= diff; + void EnterCombat(Unit* who) + { + BossAI::EnterCombat(who); + DoScriptText(SAY_AGGRO, me); + events.ScheduleEvent(EVENT_MAGIC_REFLECTION, 30000); + events.ScheduleEvent(EVENT_DAMAGE_REFLECTION, 15000); + events.ScheduleEvent(EVENT_BLAST_WAVE, 10000); + events.ScheduleEvent(EVENT_TELEPORT, 20000); + } - if (DamageReflection_Timer <= diff) + void UpdateAI(const uint32 diff) + { + if (instance && instance->GetBossState(BOSS_MAJORDOMO_EXECUTUS) != DONE) { - DoCast(me, SPELL_DAMAGE_REFLECTION); - DamageReflection_Timer = 30000; - } else DamageReflection_Timer -= diff; + if (!UpdateVictim()) + return; - //Blastwave_Timer - if (Blastwave_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_BLASTWAVE); - Blastwave_Timer = 10000; - } else Blastwave_Timer -= diff; + events.Update(diff); - if (Teleport_Timer <= diff) + if (!me->FindNearestCreature(NPC_FLAMEWAKER_HEALER, 100.0f) && !me->FindNearestCreature(NPC_FLAMEWAKER_ELITE, 100.0f)) + { + //instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, me->GetEntry()); + me->setFaction(35); + me->AI()->EnterEvadeMode(); + DoScriptText(SAY_DEFEAT, me); + _JustDied(); + events.ScheduleEvent(EVENT_OUTRO_1, 32000); + return; + } + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + if (HealthBelowPct(50)) + DoCast(me, SPELL_AEGIS_OF_RAGNAROS, true); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_MAGIC_REFLECTION: + DoCast(me, SPELL_MAGIC_REFLECTION); + events.ScheduleEvent(EVENT_MAGIC_REFLECTION, 30000); + break; + case EVENT_DAMAGE_REFLECTION: + DoCast(me, SPELL_DAMAGE_REFLECTION); + events.ScheduleEvent(EVENT_DAMAGE_REFLECTION, 30000); + break; + case EVENT_BLAST_WAVE: + DoCastVictim(SPELL_BLAST_WAVE); + events.ScheduleEvent(EVENT_BLAST_WAVE, 10000); + break; + case EVENT_TELEPORT: + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1)) + DoCast(target, SPELL_TELEPORT); + events.ScheduleEvent(EVENT_TELEPORT, 20000); + break; + default: + break; + } + } + + DoMeleeAttackIfReady(); + } + else { - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1)) - DoCast(pTarget, SPELL_TELEPORT); - Teleport_Timer = 20000; - } else Teleport_Timer -= diff; + events.Update(diff); - DoMeleeAttackIfReady(); - } - else - { - if (Phase == 1) - { - if (Phase_Timer <= diff) + while (uint32 eventId = events.ExecuteEvent()) { - me->NearTeleportTo(TELE_TO_RAG_X, TELE_TO_RAG_Y, TELE_TO_RAG_Z, TELE_TO_RAG_O); - Phase = 2; - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } else Phase_Timer -= diff; + switch (eventId) + { + case EVENT_OUTRO_1: + me->NearTeleportTo(RagnarosTelePos.GetPositionX(), RagnarosTelePos.GetPositionY(), RagnarosTelePos.GetPositionZ(), RagnarosTelePos.GetOrientation()); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + break; + case EVENT_OUTRO_2: + if (instance) + instance->instance->SummonCreature(NPC_RAGNAROS, RagnarosSummonPos); + break; + case EVENT_OUTRO_3: + DoScriptText(SAY_ARRIVAL2_MAJ, me); + break; + default: + break; + } + } } - if (Phase == 3) + } + + void DoAction(const int32 action) + { + if (action == ACTION_START_RAGNAROS) { - if (Phase_Timer <= diff) - { - if (m_pInstance) - m_pInstance->SetData(DATA_RAGNAROS, true); - Phase = 4; - Phase_Timer = 16000; - } else Phase_Timer -= diff; + me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + DoScriptText(SAY_SUMMON_MAJ, me); + events.ScheduleEvent(EVENT_OUTRO_2, 8000); + events.ScheduleEvent(EVENT_OUTRO_3, 24000); } - if (Phase == 4) + else if (action == ACTION_START_RAGNAROS_ALT) { - if (Phase_Timer <= diff) - { - DoScriptText(SAY_ARRIVAL2_MAJ, me); - Phase = 5; - } else Phase_Timer -= diff; + me->setFaction(35); + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } } + }; + + bool OnGossipHello(Player* player, Creature* creature) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1); + player->SEND_GOSSIP_MENU(GOSSIP_HELLO, creature->GetGUID()); + return true; } - void StartRagsEvent() + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 /*uiAction*/) { - me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - Phase = 3; - DoScriptText(SAY_SUMMON_MAJ, me); - Phase_Timer = 8000; + player->CLOSE_GOSSIP_MENU(); + creature->AI()->DoAction(ACTION_START_RAGNAROS); + return true; } - }; + CreatureAI* GetAI(Creature* creature) const + { + return new boss_majordomoAI(creature); + } }; void AddSC_boss_majordomo() diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_ragnaros.cpp index deacf74bf4d..f58269861cd 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_ragnaros.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_ragnaros.cpp @@ -19,414 +19,335 @@ /* ScriptData SDName: Boss_Ragnaros SD%Complete: 95 -SDComment: missing effects in intro (summon, majordomos tele) annd some spells doesnt work correctly +SDComment: some spells doesnt work correctly SDCategory: Molten Core EndScriptData */ #include "ScriptPCH.h" #include "molten_core.h" -#define SAY_REINFORCEMENTS1 -1409013 -#define SAY_REINFORCEMENTS2 -1409014 -#define SAY_HAND -1409015 -#define SAY_WRATH -1409016 -#define SAY_KILL -1409017 -#define SAY_MAGMABURST -1409018 - -#define SPELL_HANDOFRAGNAROS 19780 -#define SPELL_WRATHOFRAGNAROS 20566 -#define SPELL_LAVABURST 21158 - -#define SPELL_MAGMABURST 20565 //Ranged attack - -#define SPELL_SONSOFFLAME_DUMMY 21108 //Server side effect -#define SPELL_RAGSUBMERGE 21107 //Stealth aura -#define SPELL_RAGEMERGE 20568 -#define SPELL_MELTWEAPON 21388 -#define SPELL_ELEMENTALFIRE 20564 -#define SPELL_ERRUPTION 17731 - -#define SAY_SUMMON_MAJ -1409008 //intro -#define SAY_ARRIVAL1_RAG -1409009 -#define SAY_ARRIVAL2_MAJ -1409010 -#define SAY_ARRIVAL3_RAG -1409011 -#define SAY_ARRIVAL5_RAG -1409012 - -#define UNIT_DYNFLAG_ROOTED 8 - -#define ADD_1X 848.740356 -#define ADD_1Y -816.103455 -#define ADD_1Z -229.74327 -#define ADD_1O 2.615287 - -#define ADD_2X 852.560791 -#define ADD_2Y -849.861511 -#define ADD_2Z -228.560974 -#define ADD_2O 2.836073 - -#define ADD_3X 808.710632 -#define ADD_3Y -852.845764 -#define ADD_3Z -227.914963 -#define ADD_3O 0.964207 - -#define ADD_4X 786.597107 -#define ADD_4Y -821.132874 -#define ADD_4Z -226.350128 -#define ADD_4O 0.949377 - -#define ADD_5X 796.219116 -#define ADD_5Y -800.948059 -#define ADD_5Z -226.010361 -#define ADD_5O 0.560603 - -#define ADD_6X 821.602539 -#define ADD_6Y -782.744109 -#define ADD_6Z -226.023575 -#define ADD_6O 6.157440 - -#define ADD_7X 844.924744 -#define ADD_7Y -769.453735 -#define ADD_7Z -225.521698 -#define ADD_7O 4.4539958 - -#define ADD_8X 839.823364 -#define ADD_8Y -810.869385 -#define ADD_8Z -229.683182 -#define ADD_8O 4.693108 +enum Texts +{ + SAY_REINFORCEMENTS1 = -1409013, + SAY_REINFORCEMENTS2 = -1409014, + SAY_HAND = -1409015, + SAY_WRATH = -1409016, + SAY_KILL = -1409017, + SAY_MAGMABURST = -1409018, + SAY_SUMMON_MAJ = -1409008, + SAY_ARRIVAL1_RAG = -1409009, + SAY_ARRIVAL2_MAJ = -1409010, + SAY_ARRIVAL3_RAG = -1409011, + SAY_ARRIVAL5_RAG = -1409012, +}; -class boss_ragnaros : public CreatureScript +enum Spells { -public: - boss_ragnaros() : CreatureScript("boss_ragnaros") { } + SPELL_HAND_OF_RAGNAROS = 19780, + SPELL_WRATH_OF_RAGNAROS = 20566, + SPELL_LAVA_BURST = 21158, + SPELL_MAGMA_BLAST = 20565, // Ranged attack + SPELL_SONS_OF_FLAME_DUMMY = 21108, // Server side effect + SPELL_RAGSUBMERGE = 21107, // Stealth aura + SPELL_RAGEMERGE = 20568, + SPELL_MELT_WEAPON = 21388, + SPELL_ELEMENTAL_FIRE = 20564, + SPELL_ERRUPTION = 17731, +}; - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_ragnarosAI (pCreature); - } +enum Events +{ + EVENT_ERUPTION = 1, + EVENT_WRATH_OF_RAGNAROS = 2, + EVENT_HAND_OF_RAGNAROS = 3, + EVENT_LAVA_BURST = 4, + EVENT_ELEMENTAL_FIRE = 5, + EVENT_MAGMA_BLAST = 6, + EVENT_SUBMERGE = 7, + + EVENT_INTRO_1 = 8, + EVENT_INTRO_2 = 9, + EVENT_INTRO_3 = 10, + EVENT_INTRO_4 = 11, + EVENT_INTRO_5 = 12, +}; - struct boss_ragnarosAI : public BossAI - { - boss_ragnarosAI(Creature *pCreature) : BossAI(pCreature, BOSS_RAGNAROS) - { - Intro_Timer = 0; - Intro = 0; - me->SetReactState(REACT_PASSIVE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - SetCombatMovement(false); - } +class boss_ragnaros : public CreatureScript +{ + public: + boss_ragnaros() : CreatureScript("boss_ragnaros") { } - uint32 WrathOfRagnaros_Timer; - uint32 HandOfRagnaros_Timer; - uint32 LavaBurst_Timer; - uint32 MagmaBurst_Timer; - uint32 ElementalFire_Timer; - uint32 Erruption_Timer; - uint32 Submerge_Timer; - uint32 Attack_Timer; - uint32 Intro_Timer; - uint8 Intro; - - bool HasYelledMagmaBurst; - bool HasSubmergedOnce; - bool WasBanished; - bool HasAura; - - void Reset() + struct boss_ragnarosAI : public BossAI { - WrathOfRagnaros_Timer = 30000; - HandOfRagnaros_Timer = 25000; - LavaBurst_Timer = 10000; - MagmaBurst_Timer = 2000; - Erruption_Timer = 15000; - ElementalFire_Timer = 3000; - Submerge_Timer = 180000; - Attack_Timer = 90000; - HasYelledMagmaBurst = false; - HasSubmergedOnce = false; - WasBanished = false; - - DoCast(me, SPELL_MELTWEAPON, true); - HasAura = true; - - me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED); - } + boss_ragnarosAI(Creature *pCreature) : BossAI(pCreature, BOSS_RAGNAROS) + { + _introState = 0; + me->SetReactState(REACT_PASSIVE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } - void KilledUnit(Unit* /*victim*/) - { - if (rand()%5) - return; + void Reset() + { + BossAI::Reset(); + _emergeTimer = 90000; + _hasYelledMagmaBurst = false; + _hasSubmergedOnce = false; + _isBanished = false; + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + } - DoScriptText(SAY_KILL, me); - } + void EnterCombat(Unit* victim) + { + BossAI::EnterCombat(victim); + events.ScheduleEvent(EVENT_ERUPTION, 15000); + events.ScheduleEvent(EVENT_WRATH_OF_RAGNAROS, 30000); + events.ScheduleEvent(EVENT_HAND_OF_RAGNAROS, 25000); + events.ScheduleEvent(EVENT_LAVA_BURST, 10000); + events.ScheduleEvent(EVENT_ELEMENTAL_FIRE, 3000); + events.ScheduleEvent(EVENT_MAGMA_BLAST, 2000); + events.ScheduleEvent(EVENT_SUBMERGE, 180000); + } - void EnterCombat(Unit * /*who*/) - { - } + void KilledUnit(Unit* /*victim*/) + { + if (urand(0, 99 < 25)) + DoScriptText(SAY_KILL, me); + } - void UpdateAI(const uint32 diff) - { - if (Intro == 1) - { - if (Intro_Timer <= diff) - { - DoScriptText(SAY_ARRIVAL1_RAG, me); - Intro_Timer = 18000; - Intro = 2; - } else Intro_Timer -= diff; - } - else if (Intro == 2) - { - if (Intro_Timer <= diff) - { - DoScriptText(SAY_ARRIVAL3_RAG, me); - Intro_Timer = 19000; - Intro = 3; - } else Intro_Timer -= diff; - } - else if (Intro == 3) - { - if (Intro_Timer <= diff) - { - me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H); - Intro_Timer = 1000; - Intro = 4; - } else Intro_Timer -= diff; - } - else if (Intro == 4) - { - if (Intro_Timer <= diff) - { - DoScriptText(SAY_ARRIVAL5_RAG, me); - if (instance) - if (Creature *pMajordomo = me->GetCreature(*me, instance->GetData64(DATA_MAJORDOMO_GUID))) - me->Kill(pMajordomo); - Intro_Timer = 10000; - Intro = 5; - } else Intro_Timer -= diff; - } - else if (Intro == 5) - { - if (Intro_Timer <= diff) - { - me->SetReactState(REACT_AGGRESSIVE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - Intro = 6; - } else Intro_Timer -= diff; - } - else if (Intro == 6) + void UpdateAI(const uint32 diff) { - if (instance) + if (_introState != 2) { - if (WasBanished && ((Attack_Timer <= diff) || (instance->GetData(DATA_RAG_ELE_COUNTER)) > 8)) + if (!_introState) { - //Become unbanished again - me->SetReactState(REACT_AGGRESSIVE); - me->setFaction(14); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED); me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); - if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - AttackStart(pTarget); - instance->SetData(DATA_RAG_ELE_COUNTER, 0); - - //DoCast(me, SPELL_RAGEMERGE); //"phase spells" didnt worked correctly so Ive commented them and wrote solution witch doesnt need core support - WasBanished = false; - } - else if (WasBanished) - { - Attack_Timer -= diff; - //Do nothing while banished - return; + events.ScheduleEvent(EVENT_INTRO_1, 4000); + events.ScheduleEvent(EVENT_INTRO_2, 23000); + events.ScheduleEvent(EVENT_INTRO_3, 42000); + events.ScheduleEvent(EVENT_INTRO_4, 43000); + events.ScheduleEvent(EVENT_INTRO_5, 53000); + _introState = 1; } - } - - //Return since we have no target - if (!UpdateVictim()) - return; - - //Erruption_Timer - if (LavaBurst_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_ERRUPTION); - Erruption_Timer = urand(20000,45000); - } else Erruption_Timer -= diff; - - //WrathOfRagnaros_Timer - if (WrathOfRagnaros_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_WRATHOFRAGNAROS); - - if (urand(0,1)) - DoScriptText(SAY_WRATH, me); - - WrathOfRagnaros_Timer = 25000; - } else WrathOfRagnaros_Timer -= diff; - - //HandOfRagnaros_Timer - if (HandOfRagnaros_Timer <= diff) - { - DoCast(me, SPELL_HANDOFRAGNAROS); - if (urand(0,1)) - DoScriptText(SAY_HAND, me); + events.Update(diff); - HandOfRagnaros_Timer = 20000; - } else HandOfRagnaros_Timer -= diff; - - //LavaBurst_Timer - if (LavaBurst_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_LAVABURST); - LavaBurst_Timer = 10000; - } else LavaBurst_Timer -= diff; - - //ElementalFire_Timer - if (ElementalFire_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_ELEMENTALFIRE); - ElementalFire_Timer = urand(10000,14000); - } else ElementalFire_Timer -= diff; - - //Submerge_Timer - if (!WasBanished && Submerge_Timer <= diff && instance) - { - //Creature spawning and ragnaros becomming unattackable - //is not very well supported in the core //no it really isnt - //so added normaly spawning and banish workaround and attack again after 90 secs. - - me->AttackStop(); - DoResetThreat(); - me->SetReactState(REACT_PASSIVE); - me->InterruptNonMeleeSpells(false); - //Root self - //DoCast(me, 23973); - me->setFaction(35); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED); - me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE); - instance->SetData(DATA_RAG_ELE_COUNTER, 0); - - if (!HasSubmergedOnce) + while (uint32 eventId = events.ExecuteEvent()) { - DoScriptText(SAY_REINFORCEMENTS1, me); - - // summon 10 elementals - for (uint8 i = 0; i < 9; ++i) + switch (eventId) { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - { - if (Creature* pSummoned = me->SummonCreature(12143,pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(),0.0f,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000)) - pSummoned->AI()->AttackStart(pTarget); - } + case EVENT_INTRO_1: + DoScriptText(SAY_ARRIVAL1_RAG, me); + break; + case EVENT_INTRO_2: + DoScriptText(SAY_ARRIVAL3_RAG, me); + break; + case EVENT_INTRO_3: + me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H); + break; + case EVENT_INTRO_4: + DoScriptText(SAY_ARRIVAL5_RAG, me); + if (instance) + if (Creature* executus = Unit::GetCreature(*me, instance->GetData64(BOSS_MAJORDOMO_EXECUTUS))) + me->Kill(executus); + break; + case EVENT_INTRO_5: + me->SetReactState(REACT_AGGRESSIVE); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + _introState = 2; + break; + default: + break; } - - HasSubmergedOnce = true; - WasBanished = true; - //DoCast(me, SPELL_RAGSUBMERGE); - Attack_Timer = 90000; - } - else + } + else + { + if (instance) { - DoScriptText(SAY_REINFORCEMENTS2, me); - - for (uint8 i = 0; i < 9; ++i) + if (_isBanished && ((_emergeTimer <= diff) || (instance->GetData(DATA_RAGNAROS_ADDS)) > 8)) { - if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM,0)) - { - if (Creature* pSummoned = me->SummonCreature(12143,pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(),0.0f,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000)) - pSummoned->AI()->AttackStart(pTarget); - } + //Become unbanished again + me->SetReactState(REACT_AGGRESSIVE); + me->setFaction(14); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); + me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); + if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + AttackStart(target); + instance->SetData(DATA_RAGNAROS_ADDS, 0); + + //DoCast(me, SPELL_RAGEMERGE); //"phase spells" didnt worked correctly so Ive commented them and wrote solution witch doesnt need core support + _isBanished = false; + } + else if (_isBanished) + { + _emergeTimer -= diff; + //Do nothing while banished + return; } - - WasBanished = true; - //DoCast(me, SPELL_RAGSUBMERGE); - Attack_Timer = 90000; } - Submerge_Timer = 180000; - } else Submerge_Timer -= diff; + //Return since we have no target + if (!UpdateVictim()) + return; - //If we are within range melee the target - if (me->IsWithinMeleeRange(me->getVictim())) - { - //Make sure our attack is ready and we arn't currently casting - if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false)) - { - me->AttackerStateUpdate(me->getVictim()); - me->resetAttackTimer(); - } - } - else - { - //MagmaBurst_Timer - if (MagmaBurst_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_MAGMABURST); + events.Update(diff); - if (!HasYelledMagmaBurst) + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) { - //Say our dialog - DoScriptText(SAY_MAGMABURST, me); - HasYelledMagmaBurst = true; + case EVENT_ERUPTION: + DoCastVictim(SPELL_ERRUPTION); + events.ScheduleEvent(EVENT_ERUPTION, urand(20000, 45000)); + break; + case EVENT_WRATH_OF_RAGNAROS: + DoCastVictim(SPELL_WRATH_OF_RAGNAROS); + if (urand(0, 1)) + DoScriptText(SAY_WRATH, me); + events.ScheduleEvent(EVENT_WRATH_OF_RAGNAROS, 25000); + break; + case EVENT_HAND_OF_RAGNAROS: + DoCast(me, SPELL_HAND_OF_RAGNAROS); + if (urand(0,1)) + DoScriptText(SAY_HAND, me); + events.ScheduleEvent(EVENT_HAND_OF_RAGNAROS, 20000); + break; + case EVENT_LAVA_BURST: + DoCastVictim(SPELL_LAVA_BURST); + events.ScheduleEvent(EVENT_LAVA_BURST, 10000); + break; + case EVENT_ELEMENTAL_FIRE: + DoCastVictim(SPELL_ELEMENTAL_FIRE); + events.ScheduleEvent(EVENT_ELEMENTAL_FIRE, urand(10000, 14000)); + break; + case EVENT_MAGMA_BLAST: + if (me->IsWithinMeleeRange(me->getVictim())) + { + DoCastVictim(SPELL_MAGMA_BLAST); + if (!_hasYelledMagmaBurst) + { + //Say our dialog + DoScriptText(SAY_MAGMABURST, me); + _hasYelledMagmaBurst = true; + } + } + events.ScheduleEvent(EVENT_MAGMA_BLAST, 2500); + break; + case EVENT_SUBMERGE: + { + if (instance && !_isBanished) + { + //Creature spawning and ragnaros becomming unattackable + //is not very well supported in the core //no it really isnt + //so added normaly spawning and banish workaround and attack again after 90 secs. + me->AttackStop(); + DoResetThreat(); + me->SetReactState(REACT_PASSIVE); + me->InterruptNonMeleeSpells(false); + //Root self + //DoCast(me, 23973); + me->setFaction(35); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_SUBMERGED); + me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE); + instance->SetData(DATA_RAGNAROS_ADDS, 0); + + if (!_hasSubmergedOnce) + { + DoScriptText(SAY_REINFORCEMENTS1, me); + + // summon 8 elementals + for (uint8 i = 0; i < 8; ++i) + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + if (Creature* pSummoned = me->SummonCreature(12143, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000)) + pSummoned->AI()->AttackStart(pTarget); + + _hasSubmergedOnce = true; + _isBanished = true; + //DoCast(me, SPELL_RAGSUBMERGE); + _emergeTimer = 90000; + + } + else + { + DoScriptText(SAY_REINFORCEMENTS2, me); + + for (uint8 i = 0; i < 8; ++i) + if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0)) + if (Creature* pSummoned = me->SummonCreature(12143, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,900000)) + pSummoned->AI()->AttackStart(pTarget); + + _isBanished = true; + //DoCast(me, SPELL_RAGSUBMERGE); + _emergeTimer = 90000; + } + } + events.ScheduleEvent(EVENT_SUBMERGE, 180000); + break; + } + default: + break; } + } - MagmaBurst_Timer = 2500; - } else MagmaBurst_Timer -= diff; + DoMeleeAttackIfReady(); } } - else - { - me->HandleEmoteCommand(EMOTE_ONESHOT_EMERGE); - Intro_Timer = 4000; - Intro = 1; - } - } -}; + private: + uint32 _emergeTimer; + uint8 _introState; + bool _hasYelledMagmaBurst; + bool _hasSubmergedOnce; + bool _isBanished; + }; + CreatureAI* GetAI(Creature* pCreature) const + { + return new boss_ragnarosAI(pCreature); + } }; -class mob_SonOfFlame : public CreatureScript +class mob_son_of_flame : public CreatureScript { -public: - mob_SonOfFlame() : CreatureScript("mob_SonOfFlame") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new mob_SonOfFlameAI(pCreature); - } + public: + mob_son_of_flame() : CreatureScript("mob_SonOfFlame") { } - struct mob_SonOfFlameAI : public ScriptedAI //didnt work correctly in EAI for me... - { - mob_SonOfFlameAI(Creature *c) : ScriptedAI(c) + struct mob_son_of_flameAI : public ScriptedAI //didnt work correctly in EAI for me... { - pInstance = me->GetInstanceScript(); - } + mob_son_of_flameAI(Creature *c) : ScriptedAI(c) + { + instance = me->GetInstanceScript(); + } - InstanceScript* pInstance; + void JustDied(Unit * /*victim*/) + { + if (instance) + instance->SetData(DATA_RAGNAROS_ADDS, 1); + } - void JustDied(Unit * /*victim*/) - { - if (pInstance) - pInstance->SetData(DATA_RAG_ELE_COUNTER, 1); - } + void UpdateAI(const uint32 /*diff*/) + { + if (!UpdateVictim()) + return; - void UpdateAI(const uint32 /*diff*/) - { - if (!UpdateVictim()) - return; + DoMeleeAttackIfReady(); + } + + private: + InstanceScript* instance; + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* pCreature) const + { + return new mob_son_of_flameAI(pCreature); } - }; }; - - void AddSC_boss_ragnaros() { new boss_ragnaros(); - new mob_SonOfFlame(); + new mob_son_of_flame(); } diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_shazzrah.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_shazzrah.cpp index c460a9f52a1..8928dca0750 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_shazzrah.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_shazzrah.cpp @@ -23,113 +23,104 @@ SDComment: Teleport NYI SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "molten_core.h" -#define SPELL_ARCANEEXPLOSION 19712 -#define SPELL_SHAZZRAHCURSE 19713 -#define SPELL_DEADENMAGIC 19714 -#define SPELL_COUNTERSPELL 19715 - -class boss_shazzrah : public CreatureScript +enum Spells { -public: - boss_shazzrah() : CreatureScript("boss_shazzrah") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_shazzrahAI (pCreature); - } - - struct boss_shazzrahAI : public ScriptedAI - { - boss_shazzrahAI(Creature *pCreature) : ScriptedAI(pCreature) - { - m_pInstance = pCreature->GetInstanceScript(); - } - - InstanceScript* m_pInstance; - - uint32 ArcaneExplosion_Timer; - uint32 ShazzrahCurse_Timer; - uint32 DeadenMagic_Timer; - uint32 Countspell_Timer; - uint32 Blink_Timer; - - void Reset() - { - ArcaneExplosion_Timer = 6000; //These times are probably wrong - ShazzrahCurse_Timer = 10000; - DeadenMagic_Timer = 24000; - Countspell_Timer = 15000; - Blink_Timer = 30000; - } + SPELL_ARCANE_EXPLOSION = 19712, + SPELL_SHAZZRAH_CURSE = 19713, + SPELL_MAGIC_GROUNDING = 19714, + SPELL_COUNTERSPELL = 19715, +}; - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance) - m_pInstance->SetData(DATA_SHAZZRAH, 0); - } +enum Events +{ + EVENT_ARCANE_EXPLOSION = 1, + EVENT_SHAZZRAH_CURSE = 2, + EVENT_MAGIC_GROUNDING = 3, + EVENT_COUNTERSPELL = 4, + EVENT_BLINK = 5, +}; - void EnterCombat(Unit * /*who*/) - { - } +class boss_shazzrah : public CreatureScript +{ + public: + boss_shazzrah() : CreatureScript("boss_shazzrah") { } - void UpdateAI(const uint32 diff) + struct boss_shazzrahAI : public BossAI { - if (!UpdateVictim()) - return; - - //ArcaneExplosion_Timer - if (ArcaneExplosion_Timer <= diff) + boss_shazzrahAI(Creature* creature) : BossAI(creature, BOSS_SHAZZRAH) { - DoCast(me->getVictim(), SPELL_ARCANEEXPLOSION); - ArcaneExplosion_Timer = 5000 + rand()%4000; - } else ArcaneExplosion_Timer -= diff; + } - //ShazzrahCurse_Timer - if (ShazzrahCurse_Timer <= diff) + void EnterCombat(Unit* target) { - Unit *pTarget = NULL; - pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); - if (pTarget) DoCast(pTarget, SPELL_SHAZZRAHCURSE); - - ShazzrahCurse_Timer = 25000 + rand()%5000; - } else ShazzrahCurse_Timer -= diff; - - //DeadenMagic_Timer - if (DeadenMagic_Timer <= diff) + BossAI::EnterCombat(target); + events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, 6000); + events.ScheduleEvent(EVENT_SHAZZRAH_CURSE, 10000); + events.ScheduleEvent(EVENT_MAGIC_GROUNDING, 24000); + events.ScheduleEvent(EVENT_COUNTERSPELL, 15000); + events.ScheduleEvent(EVENT_BLINK, 30000); + } + + void UpdateAI(const uint32 diff) { - DoCast(me, SPELL_DEADENMAGIC); - DeadenMagic_Timer = 35000; - } else DeadenMagic_Timer -= diff; + if (!UpdateVictim()) + return; - //Countspell_Timer - if (Countspell_Timer <= diff) - { - DoCast(me->getVictim(), SPELL_COUNTERSPELL); - Countspell_Timer = 16000 + rand()%4000; - } else Countspell_Timer -= diff; + events.Update(diff); - //Blink_Timer - if (Blink_Timer <= diff) - { - // Teleporting him to a random gamer and casting Arcane Explosion after that. - // Blink is not working cause of LoS System we need to do this hardcoded. - if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,0, 100, true)) + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { - DoTeleportTo(pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ()); - DoCast(pTarget, SPELL_ARCANEEXPLOSION); - DoResetThreat(); + switch (eventId) + { + case EVENT_ARCANE_EXPLOSION: + DoCastVictim(SPELL_ARCANE_EXPLOSION); + events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(5000, 9000)); + break; + case EVENT_SHAZZRAH_CURSE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -EVENT_SHAZZRAH_CURSE)) + DoCast(target, SPELL_SHAZZRAH_CURSE); + events.ScheduleEvent(EVENT_SHAZZRAH_CURSE, urand(25000, 30000)); + break; + case EVENT_MAGIC_GROUNDING: + DoCast(me, SPELL_MAGIC_GROUNDING); + events.ScheduleEvent(EVENT_MAGIC_GROUNDING, 35000); + break; + case EVENT_COUNTERSPELL: + DoCastVictim(SPELL_COUNTERSPELL); + events.ScheduleEvent(EVENT_COUNTERSPELL, urand(16000, 20000)); + break; + case EVENT_BLINK: + // Teleporting him to a random player and casting Arcane Explosion after that. + // Blink is not working cause of LoS System we need to do this hardcoded. + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true)) + { + DoTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()); + DoCast(target, SPELL_ARCANE_EXPLOSION); + DoResetThreat(); + } + events.ScheduleEvent(EVENT_BLINK, 45000); + break; + default: + break; + } } - Blink_Timer = 45000; - } else Blink_Timer -= diff; + DoMeleeAttackIfReady(); + } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const + { + return new boss_shazzrahAI(creature); } - }; - }; void AddSC_boss_shazzrah() diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/boss_sulfuron_harbinger.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/boss_sulfuron_harbinger.cpp index 0f2c42bc46f..04cc421fae6 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/boss_sulfuron_harbinger.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/boss_sulfuron_harbinger.cpp @@ -23,199 +23,200 @@ SDComment: Adds NYI SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "molten_core.h" -#define SPELL_DARKSTRIKE 19777 -#define SPELL_DEMORALIZINGSHOUT 19778 -#define SPELL_INSPIRE 19779 -#define SPELL_KNOCKDOWN 19780 -#define SPELL_FLAMESPEAR 19781 +enum Spells +{ + // Sulfuron Harbringer + SPELL_DARK_STRIKE = 19777, + SPELL_DEMORALIZING_SHOUT = 19778, + SPELL_INSPIRE = 19779, + SPELL_KNOCKDOWN = 19780, + SPELL_FLAMESPEAR = 19781, + + // Adds + SPELL_HEAL = 19775, + SPELL_SHADOWWORDPAIN = 19776, + SPELL_IMMOLATE = 20294, +}; -//Adds Spells -#define SPELL_HEAL 19775 -#define SPELL_SHADOWWORDPAIN 19776 -#define SPELL_IMMOLATE 20294 +enum Events +{ + EVENT_DARK_STRIKE = 1, + EVENT_DEMORALIZING_SHOUT = 2, + EVENT_INSPIRE = 3, + EVENT_KNOCKDOWN = 4, + EVENT_FLAMESPEAR = 5, + + EVENT_HEAL = 6, + EVENT_SHADOW_WORD_PAIN = 7, + EVENT_IMMOLATE = 8, +}; class boss_sulfuron : public CreatureScript { -public: - boss_sulfuron() : CreatureScript("boss_sulfuron") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_sulfuronAI (pCreature); - } - - struct boss_sulfuronAI : public ScriptedAI - { - boss_sulfuronAI(Creature *pCreature) : ScriptedAI(pCreature) - { - m_pInstance = pCreature->GetInstanceScript(); - } - InstanceScript* m_pInstance; - - uint32 Darkstrike_Timer; - uint32 DemoralizingShout_Timer; - uint32 Inspire_Timer; - uint32 Knockdown_Timer; - uint32 Flamespear_Timer; - - void Reset() - { - Darkstrike_Timer=10000; //These times are probably wrong - DemoralizingShout_Timer = 15000; - Inspire_Timer = 13000; - Knockdown_Timer = 6000; - Flamespear_Timer = 2000; - } - - void JustDied(Unit* /*pKiller*/) - { - if (m_pInstance) - m_pInstance->SetData(DATA_SULFURON, 0); - } - - void EnterCombat(Unit * /*who*/) - { - } + public: + boss_sulfuron() : CreatureScript("boss_sulfuron") { } - void UpdateAI(const uint32 diff) + struct boss_sulfuronAI : public BossAI { - if (!UpdateVictim()) - return; - - //DemoralizingShout_Timer - if (DemoralizingShout_Timer <= diff) + boss_sulfuronAI(Creature* creature) : BossAI(creature, BOSS_SULFURON_HARBINGER) { - DoCast(me->getVictim(), SPELL_DEMORALIZINGSHOUT); - DemoralizingShout_Timer = 15000 + rand()%5000; - } else DemoralizingShout_Timer -= diff; + } - //Inspire_Timer - if (Inspire_Timer <= diff) + void EnterCombat(Unit* victim) { - Creature *pTarget = NULL; - std::list<Creature*> pList = DoFindFriendlyMissingBuff(45.0f,SPELL_INSPIRE); - if (!pList.empty()) - { - std::list<Creature*>::const_iterator i = pList.begin(); - advance(i, (rand()%pList.size())); - pTarget = (*i); - } - - if (pTarget) - DoCast(pTarget, SPELL_INSPIRE); - - DoCast(me, SPELL_INSPIRE); - - Inspire_Timer = 20000 + rand()%6000; - } else Inspire_Timer -= diff; - - //Knockdown_Timer - if (Knockdown_Timer <= diff) + BossAI::EnterCombat(victim); + events.ScheduleEvent(EVENT_DARK_STRIKE, 10000); + events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, 15000); + events.ScheduleEvent(EVENT_INSPIRE, 13000); + events.ScheduleEvent(EVENT_KNOCKDOWN, 6000); + events.ScheduleEvent(EVENT_FLAMESPEAR, 2000); + } + + void UpdateAI(const uint32 diff) { - DoCast(me->getVictim(), SPELL_KNOCKDOWN); - Knockdown_Timer = 12000 + rand()%3000; - } else Knockdown_Timer -= diff; + if (!UpdateVictim()) + return; - //Flamespear_Timer - if (Flamespear_Timer <= diff) - { - Unit *pTarget = NULL; - pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); - if (pTarget) DoCast(pTarget, SPELL_FLAMESPEAR); + events.Update(diff); + + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; - Flamespear_Timer = 12000 + rand()%4000; - } else Flamespear_Timer -= diff; + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_DARK_STRIKE: + DoCast(me, SPELL_DARK_STRIKE); + events.ScheduleEvent(EVENT_DARK_STRIKE, urand(15000, 18000)); + break; + case EVENT_DEMORALIZING_SHOUT: + DoCastVictim(SPELL_DEMORALIZING_SHOUT); + events.ScheduleEvent(EVENT_DEMORALIZING_SHOUT, urand(15000, 20000)); + break; + case EVENT_INSPIRE: + { + Creature* target = NULL; + std::list<Creature*> healers = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE); + if (!healers.empty()) + { + std::list<Creature*>::const_iterator itr = healers.begin(); + std::advance(itr, urand(0, healers.size()-1)); + target = *itr; + } + + if (target) + DoCast(target, SPELL_INSPIRE); + + DoCast(me, SPELL_INSPIRE); + events.ScheduleEvent(EVENT_INSPIRE, urand(20000, 26000)); + break; + } + case EVENT_KNOCKDOWN: + DoCastVictim(SPELL_KNOCKDOWN); + events.ScheduleEvent(EVENT_KNOCKDOWN, urand(12000, 15000)); + break; + case EVENT_FLAMESPEAR: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + DoCast(target, SPELL_FLAMESPEAR); + events.ScheduleEvent(EVENT_FLAMESPEAR, urand(12000, 16000)); + break; + default: + break; + } + } - //DarkStrike_Timer - if (Darkstrike_Timer <= diff) - { - DoCast(me, SPELL_DARKSTRIKE); - Darkstrike_Timer = 15000 + rand()%3000; - } else Darkstrike_Timer -= diff; + DoMeleeAttackIfReady(); + } + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const + { + return new boss_sulfuronAI(creature); } - }; - }; class mob_flamewaker_priest : public CreatureScript { -public: - mob_flamewaker_priest() : CreatureScript("mob_flamewaker_priest") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new mob_flamewaker_priestAI (pCreature); - } + public: + mob_flamewaker_priest() : CreatureScript("mob_flamewaker_priest") { } - struct mob_flamewaker_priestAI : public ScriptedAI - { - mob_flamewaker_priestAI(Creature *c) : ScriptedAI(c) {} - - uint32 Heal_Timer; - uint32 ShadowWordPain_Timer; - uint32 Immolate_Timer; - - void Reset() + struct mob_flamewaker_priestAI : public ScriptedAI { - Heal_Timer = 15000+rand()%15000; - ShadowWordPain_Timer = 2000; - Immolate_Timer = 8000; - } + mob_flamewaker_priestAI(Creature* creature) : ScriptedAI(creature) + { + } - void EnterCombat(Unit * /*who*/) - { - } + void Reset() + { + events.Reset(); + } - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + void JustDied(Unit* /*killer*/) + { + events.Reset(); + } - //Casting Heal to Sulfuron or other Guards. - if (Heal_Timer <= diff) + void EnterCombat(Unit* victim) { - Unit* pUnit = DoSelectLowestHpFriendly(60.0f, 1); - if (!pUnit) - return; + ScriptedAI::EnterCombat(victim); + events.ScheduleEvent(EVENT_HEAL, urand(15000, 30000)); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 2000); + events.ScheduleEvent(EVENT_IMMOLATE, 8000); + } - DoCast(pUnit, SPELL_HEAL); + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; - Heal_Timer = 15000+rand()%5000; - } else Heal_Timer -= diff; + events.Update(diff); - //ShadowWordPain_Timer - if (ShadowWordPain_Timer <= diff) - { - Unit *pTarget = NULL; - pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); - if (pTarget) DoCast(pTarget, SPELL_SHADOWWORDPAIN); + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; - ShadowWordPain_Timer = 18000+rand()%8000; - } else ShadowWordPain_Timer -= diff; + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_HEAL: + if (Unit* target = DoSelectLowestHpFriendly(60.0f, 1)) + DoCast(target, SPELL_HEAL); + events.ScheduleEvent(EVENT_HEAL, urand(15000, 20000)); + break; + case EVENT_SHADOW_WORD_PAIN: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_SHADOWWORDPAIN)) + DoCast(target, SPELL_SHADOWWORDPAIN); + events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(18000, 26000)); + break; + case EVENT_IMMOLATE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_IMMOLATE)) + DoCast(target, SPELL_IMMOLATE); + events.ScheduleEvent(EVENT_IMMOLATE, urand(15000, 25000)); + break; + default: + break; + } + } - //Immolate_Timer - if (Immolate_Timer <= diff) - { - Unit *pTarget = NULL; - pTarget = SelectUnit(SELECT_TARGET_RANDOM,0); - if (pTarget) DoCast(pTarget, SPELL_IMMOLATE); + DoMeleeAttackIfReady(); + } - Immolate_Timer = 15000+rand()%10000; - } else Immolate_Timer -= diff; + private: + EventMap events; + }; - DoMeleeAttackIfReady(); + CreatureAI* GetAI(Creature* creature) const + { + return new mob_flamewaker_priestAI(creature); } - }; - }; - - void AddSC_boss_sulfuron() { new boss_sulfuron(); diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/instance_molten_core.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/instance_molten_core.cpp index fd81e3337f0..e4b6943ffdc 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/instance_molten_core.cpp +++ b/src/server/scripts/EasternKingdoms/MoltenCore/instance_molten_core.cpp @@ -23,351 +23,208 @@ SDComment: Place Holder SDCategory: Molten Core EndScriptData */ -#include "ScriptPCH.h" +#include "ObjectMgr.h" +#include "ScriptMgr.h" +#include "InstanceScript.h" +#include "CreatureAI.h" #include "molten_core.h" -#define MAX_ENCOUNTER 10 - -#define ID_LUCIFRON 12118 -#define ID_MAGMADAR 11982 -#define ID_GEHENNAS 12259 -#define ID_GARR 12057 -#define ID_GEDDON 12056 -#define ID_SHAZZRAH 12264 -#define ID_GOLEMAGG 11988 -#define ID_SULFURON 12098 -#define ID_DOMO 12018 -#define ID_RAGNAROS 11502 -#define ID_FLAMEWAKERPRIEST 11662 -#define ID_FLAMEWAKERHEALER 11663 -#define ID_FLAMEWAKERELITE 11664 - -const Position Pos[10] = +const Position SummonPositions[10] = { - {737.85f,-1145.35f,-120.288f,4.71368f}, - {744.162f,-1151.63f,-119.726f,4.58204f}, - {751.247f,-1152.82f,-119.744f,4.49673f}, - {759.206f,-1155.09f,-120.051f,4.30104f}, - {755.973f,-1152.33f,-120.029f,4.25588f}, - {731.712f,-1147.56f,-120.195f,4.95955f}, - {726.499f,-1149.8f,-120.156f,5.24055f}, - {722.408f,-1152.41f,-120.029f,5.33087f}, - {718.994f,-1156.36f,-119.805f,5.75738f}, - {838.51f,-829.84f,-232.00f,2.00f}, + {737.850f, -1145.35f, -120.288f, 4.71368f}, + {744.162f, -1151.63f, -119.726f, 4.58204f}, + {751.247f, -1152.82f, -119.744f, 4.49673f}, + {759.206f, -1155.09f, -120.051f, 4.30104f}, + {755.973f, -1152.33f, -120.029f, 4.25588f}, + {731.712f, -1147.56f, -120.195f, 4.95955f}, + {726.499f, -1149.80f, -120.156f, 5.24055f}, + {722.408f, -1152.41f, -120.029f, 5.33087f}, + {718.994f, -1156.36f, -119.805f, 5.75738f}, + {838.510f, -829.840f, -232.000f, 2.00000f}, }; class instance_molten_core : public InstanceMapScript { -public: - instance_molten_core() : InstanceMapScript("instance_molten_core", 409) { } - - InstanceScript* GetInstanceScript(InstanceMap* pMap) const - { - return new instance_molten_core_InstanceMapScript (pMap); - } - - struct instance_molten_core_InstanceMapScript : public InstanceScript - { - instance_molten_core_InstanceMapScript(Map* pMap) : InstanceScript(pMap) {Initialize();}; - - uint64 Lucifron, Magmadar, Gehennas, Garr, Geddon, Shazzrah, Sulfuron, Golemagg, Domo, Ragnaros, FlamewakerPriest; - uint64 RuneKoro, RuneZeth, RuneMazj, RuneTheri, RuneBlaz, RuneKress, RuneMohn, m_uiFirelordCacheGUID; - uint8 rag_ele_counter; - - //If all Bosses are dead. - bool IsBossDied[9]; - bool summoned; - - bool rag_summoned; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - - void Initialize() - { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - Lucifron = 0; - Magmadar = 0; - Gehennas = 0; - Garr = 0; - Geddon = 0; - Shazzrah = 0; - Sulfuron = 0; - Golemagg = 0; - Domo = 0; - Ragnaros = 0; - FlamewakerPriest = 0; - - RuneKoro = 0; - RuneZeth = 0; - RuneMazj = 0; - RuneTheri = 0; - RuneBlaz = 0; - RuneKress = 0; - RuneMohn = 0; - - rag_ele_counter = 0; - - m_uiFirelordCacheGUID = 0; - - IsBossDied[0] = false; - IsBossDied[1] = false; - IsBossDied[2] = false; - IsBossDied[3] = false; - IsBossDied[4] = false; - IsBossDied[5] = false; - IsBossDied[6] = false; - IsBossDied[7] = false; - IsBossDied[8] = false; - summoned = false; - rag_summoned = false; - } - - bool IsEncounterInProgress() const - { - return false; - }; - - void OnGameObjectCreate(GameObject* pGo) - { - switch(pGo->GetEntry()) - { - case 176951: //Sulfuron - RuneKoro = pGo->GetGUID(); - break; - case 176952: //Geddon - RuneZeth = pGo->GetGUID(); - break; - case 176953: //Shazzrah - RuneMazj = pGo->GetGUID(); - break; - case 176954: //Golemagg - RuneTheri = pGo->GetGUID(); - break; - case 176955: //Garr - RuneBlaz = pGo->GetGUID(); - break; - case 176956: //Magmadar - RuneKress = pGo->GetGUID(); - break; - case 176957: //Gehennas - RuneMohn = pGo->GetGUID(); - break; - case 179703: - m_uiFirelordCacheGUID = pGo->GetGUID(); //when majordomo event == DONE DoRespawnGameObject(m_uiFirelordCacheGUID,); - break; - } - } + public: + instance_molten_core() : InstanceMapScript("instance_molten_core", 409) { } - void OnCreatureCreate(Creature* pCreature) - { - switch (pCreature->GetEntry()) + struct instance_molten_core_InstanceMapScript : public InstanceScript { - case ID_LUCIFRON: - Lucifron = pCreature->GetGUID(); - break; - - case ID_MAGMADAR: - Magmadar = pCreature->GetGUID(); - break; - - case ID_GEHENNAS: - Gehennas = pCreature->GetGUID(); - break; + instance_molten_core_InstanceMapScript(Map* map) : InstanceScript(map) + { + SetBossNumber(MAX_ENCOUNTER); + _golemaggTheIncineratorGUID = 0; + _majordomoExecutusGUID = 0; + _cacheOfTheFirelordGUID = 0; + _deadBossCount = 0; + _ragnarosAddDeaths = 0; + _summonedExecutus = false; + } - case ID_GARR: - Garr = pCreature->GetGUID(); - break; + void OnCreatureCreate(Creature* creature) + { + switch (creature->GetEntry()) + { + case NPC_GOLEMAGG_THE_INCINERATOR: + _golemaggTheIncineratorGUID = creature->GetGUID(); + break; + case NPC_MAJORDOMO_EXECUTUS: + _majordomoExecutusGUID = creature->GetGUID(); + break; + } + } - case ID_GEDDON: - Geddon = pCreature->GetGUID(); - break; + void OnGameObjectCreate(GameObject* go) + { + switch (go->GetEntry()) + { + case GO_CACHE_OF_THE_FIRELORD: + _cacheOfTheFirelordGUID = go->GetGUID(); + break; + } + } - case ID_SHAZZRAH: - Shazzrah = pCreature->GetGUID(); - break; + void SetData(uint32 type, uint32 data) + { + if (type == DATA_RAGNAROS_ADDS) + { + if (data == 1) + ++_ragnarosAddDeaths; + else if (data == 0) + _ragnarosAddDeaths = 0; + } + } - case ID_SULFURON: - Sulfuron = pCreature->GetGUID(); - break; + uint32 GetData(uint32 type) + { + switch (type) + { + case DATA_RAGNAROS_ADDS: + return _ragnarosAddDeaths; + } - case ID_GOLEMAGG: - Golemagg = pCreature->GetGUID(); - break; + return 0; + } - case ID_DOMO: - Domo = pCreature->GetGUID(); - break; + uint64 GetData64(uint32 type) + { + switch (type) + { + case BOSS_GOLEMAGG_THE_INCINERATOR: + return _golemaggTheIncineratorGUID; + case BOSS_MAJORDOMO_EXECUTUS: + return _majordomoExecutusGUID; + } + + return 0; + } - case ID_RAGNAROS: - Ragnaros = pCreature->GetGUID(); - break; + bool SetBossState(uint32 bossId, EncounterState state) + { + if (!InstanceScript::SetBossState(bossId, state)) + return false; - case ID_FLAMEWAKERPRIEST: - FlamewakerPriest = pCreature->GetGUID(); - break; - } - } + if (state == DONE && bossId < BOSS_MAJORDOMO_EXECUTUS) + if (++_deadBossCount == 8) + SummonMajordomoExecutus(false); - uint64 GetData64 (uint32 identifier) - { - switch(identifier) - { - case DATA_SULFURON: - return Sulfuron; - case DATA_GOLEMAGG: - return Golemagg; - case DATA_MAJORDOMO_GUID: - return Domo; - - case DATA_FLAMEWAKERPRIEST: - return FlamewakerPriest; - } - return 0; - } + if (bossId == BOSS_MAJORDOMO_EXECUTUS && state == DONE) + DoRespawnGameObject(_cacheOfTheFirelordGUID, 7 * DAY); - uint32 GetData(uint32 type) - { - switch(type) - { - case DATA_LUCIFRONISDEAD: - if (IsBossDied[0]) - return 1; - break; - - case DATA_MAGMADARISDEAD: - if (IsBossDied[1]) - return 1; - break; - - case DATA_GEHENNASISDEAD: - if (IsBossDied[2]) - return 1; - break; - - case DATA_GARRISDEAD: - if (IsBossDied[3]) - return 1; - break; - - case DATA_GEDDONISDEAD: - if (IsBossDied[4]) - return 1; - break; - - case DATA_SHAZZRAHISDEAD: - if (IsBossDied[5]) - return 1; - break; - - case DATA_SULFURONISDEAD: - if (IsBossDied[6]) - return 1; - break; - - case DATA_GOLEMAGGISDEAD: - if (IsBossDied[7]) - return 1; - break; - - case DATA_MAJORDOMOISDEAD: - if (IsBossDied[8]) - return 1; - break; - - case DATA_RAG_ELE_COUNTER: - return rag_ele_counter; - break; - } - return 0; - } + return true; + } - /*bool SetBossState(uint32 id, EncounterState state) - { - if (!InstanceData::SetBossState(id, state)) - return false; + void SummonMajordomoExecutus(bool done) + { + if (_summonedExecutus) + return; - if (id == DATA_MAJORDOMO && state == DONE) - { - if (GameObject *pFirelordCache = instance->GetGameObject(m_uiFirelordCacheGUID)){ - pFirelordCache->SetRespawnTime(pFirelordCache->GetRespawnDelay()); + _summonedExecutus = true; + if (!done) + { + instance->SummonCreature(NPC_MAJORDOMO_EXECUTUS, SummonPositions[0]); + instance->SummonCreature(NPC_FLAMEWAKER_HEALER, SummonPositions[1]); + instance->SummonCreature(NPC_FLAMEWAKER_HEALER, SummonPositions[2]); + instance->SummonCreature(NPC_FLAMEWAKER_HEALER, SummonPositions[3]); + instance->SummonCreature(NPC_FLAMEWAKER_HEALER, SummonPositions[4]); + instance->SummonCreature(NPC_FLAMEWAKER_ELITE, SummonPositions[5]); + instance->SummonCreature(NPC_FLAMEWAKER_ELITE, SummonPositions[6]); + instance->SummonCreature(NPC_FLAMEWAKER_ELITE, SummonPositions[7]); + instance->SummonCreature(NPC_FLAMEWAKER_ELITE, SummonPositions[8]); + } + else if (TempSummon* summon = instance->SummonCreature(NPC_MAJORDOMO_EXECUTUS, RagnarosTelePos)) + summon->AI()->DoAction(ACTION_START_RAGNAROS_ALT); } - instance->SummonCreature(ID_RAGNAROS, Pos[9], TEMPSUMMON_CORPSE_DESPAWN); - } - return true; - } */ - void SetData(uint32 type, uint32 data) - { - if (type == DATA_LUCIFRON) - IsBossDied[0] = true; + std::string GetSaveData() + { + OUT_SAVE_INST_DATA; - if (type == DATA_MAGMADAR) - IsBossDied[1] = true; + std::ostringstream saveStream; + saveStream << "M C " << GetBossSaveData(); - if (type == DATA_GEHENNAS) - IsBossDied[2] = true; + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); + } - if (type == DATA_GARR) - IsBossDied[3] = true; + void Load(char const* data) + { + if (!data) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } - if (type == DATA_SHAZZRAH) - IsBossDied[4] = true; + OUT_LOAD_INST_DATA(data); - if (type == DATA_GEDDON) - IsBossDied[5] = true; + char dataHead1, dataHead2; - if (type == DATA_GOLEMAGG) - IsBossDied[6] = true; + std::istringstream loadStream(data); + loadStream >> dataHead1 >> dataHead2; - if (type == DATA_SULFURON) - IsBossDied[7] = true; + if (dataHead1 == 'M' && dataHead2 == 'C') + { + EncounterState states[MAX_ENCOUNTER]; + uint8 executusCounter = 0; - if (type == DATA_RAGNAROS) - { - rag_summoned = true; - instance->SummonCreature(ID_RAGNAROS, Pos[9]); - } + // need 2 loops to check spawning executus/ragnaros + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > TO_BE_DECIDED) + tmpState = NOT_STARTED; + states[i] = EncounterState(tmpState); - if (type == DATA_RAG_ELE_COUNTER) - { - if (data == 1) - ++rag_ele_counter; - else if (data == 0) - rag_ele_counter = 0; - } + if (tmpState == DONE && i < BOSS_MAJORDOMO_EXECUTUS) + ++executusCounter; + } - if (type == DATA_MAJORDOMO) - { - IsBossDied[8] = true; - if (GameObject *pFirelordCache = instance->GetGameObject(m_uiFirelordCacheGUID)) - { - pFirelordCache->SetRespawnTime(pFirelordCache->GetRespawnDelay()); - } - } + if (executusCounter >= 8 && states[BOSS_RAGNAROS] != DONE) + SummonMajordomoExecutus(states[BOSS_MAJORDOMO_EXECUTUS] == DONE); - if (summoned == false) - { + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + SetBossState(i, states[i]); + } + else + OUT_LOAD_INST_DATA_FAIL; - for(int i=0;i<8;i++) - { - if (IsBossDied[i] == false) - return; + OUT_LOAD_INST_DATA_COMPLETE; } - instance->SummonCreature(ID_DOMO, Pos[0]); - instance->SummonCreature(ID_FLAMEWAKERHEALER, Pos[1]); - instance->SummonCreature(ID_FLAMEWAKERHEALER, Pos[2]); - instance->SummonCreature(ID_FLAMEWAKERHEALER, Pos[3]); - instance->SummonCreature(ID_FLAMEWAKERHEALER, Pos[4]); - instance->SummonCreature(ID_FLAMEWAKERELITE, Pos[5]); - instance->SummonCreature(ID_FLAMEWAKERELITE, Pos[6]); - instance->SummonCreature(ID_FLAMEWAKERELITE, Pos[7]); - instance->SummonCreature(ID_FLAMEWAKERELITE, Pos[8]); - summoned = true; + private: + uint64 _golemaggTheIncineratorGUID; + uint64 _majordomoExecutusGUID; + uint64 _cacheOfTheFirelordGUID; + uint8 _deadBossCount; + uint8 _ragnarosAddDeaths; + bool _summonedExecutus; + }; + + InstanceScript* GetInstanceScript(InstanceMap* map) const + { + return new instance_molten_core_InstanceMapScript(map); } - } - }; }; diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/molten_core.h b/src/server/scripts/EasternKingdoms/MoltenCore/molten_core.h index 8a1cc8fab44..7bbae236f52 100644 --- a/src/server/scripts/EasternKingdoms/MoltenCore/molten_core.h +++ b/src/server/scripts/EasternKingdoms/MoltenCore/molten_core.h @@ -19,37 +19,54 @@ #ifndef DEF_MOLTEN_CORE_H #define DEF_MOLTEN_CORE_H -enum eData +enum Encounters { - DATA_FLAMEWAKERPRIEST, - DATA_GARRISDEAD, - DATA_GEDDONISDEAD, - DATA_GEHENNASISDEAD, - DATA_GOLEMAGGISDEAD, - DATA_GOLEMAGG_DEATH, - DATA_LUCIFRONISDEAD, - DATA_MAGMADARISDEAD, - DATA_MAJORDOMOISDEAD, - DATA_SHAZZRAHISDEAD, - DATA_SULFURON, - DATA_SULFURONISDEAD, - DATA_GOLEMAGG, - DATA_LUCIFRON, - DATA_MAGMADAR, - DATA_GEHENNAS, - DATA_GARR, - DATA_SHAZZRAH, - DATA_GEDDON, - DATA_MAJORDOMO, - DATA_MAJORDOMO_GUID, - DATA_RAGNAROS, - DATA_RAG_ELE_COUNTER, + BOSS_LUCIFRON = 0, + BOSS_MAGMADAR = 1, + BOSS_GEHENNAS = 2, + BOSS_GARR = 3, + BOSS_SHAZZRAH = 4, + BOSS_BARON_GEDDON = 5, + BOSS_SULFURON_HARBINGER = 6, + BOSS_GOLEMAGG_THE_INCINERATOR = 7, + BOSS_MAJORDOMO_EXECUTUS = 8, + BOSS_RAGNAROS = 9, + MAX_ENCOUNTER, }; -enum Encounter +enum Actions { - BOSS_MAJORDOMO, - BOSS_RAGNAROS + ACTION_START_RAGNAROS = 0, + ACTION_START_RAGNAROS_ALT = 1, +}; + +Position const RagnarosTelePos = {829.159f, -815.773f, -228.972f, 5.30500f}; +Position const RagnarosSummonPos = {838.510f, -829.840f, -232.000f, 2.00000f}; + +enum Creatures +{ + NPC_LUCIFRON = 12118, + NPC_MAGMADAR = 11982, + NPC_GEHENNAS = 12259, + NPC_GARR = 12057, + NPC_SHAZZRAH = 12264, + NPC_BARON_GEDDON = 12056, + NPC_SULFURON_HARBINGER = 12098, + NPC_GOLEMAGG_THE_INCINERATOR = 11988, + NPC_MAJORDOMO_EXECUTUS = 12018, + NPC_RAGNAROS = 11502, + NPC_FLAMEWAKER_HEALER = 11663, + NPC_FLAMEWAKER_ELITE = 11664, +}; + +enum GameObjects +{ + GO_CACHE_OF_THE_FIRELORD = 179703, +}; + +enum Data +{ + DATA_RAGNAROS_ADDS = 0, }; #endif |