diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp | 167 |
1 files changed, 94 insertions, 73 deletions
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp index fc29369c28f..e8da81a669f 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp @@ -28,7 +28,7 @@ EndScriptData */ #include "SpellScript.h" #include "halls_of_lightning.h" -enum Yells +enum Texts { SAY_INTRO_1 = 0, SAY_INTRO_2 = 1, @@ -51,6 +51,21 @@ enum Spells SPELL_PULSING_SHOCKWAVE_AURA = 59414 }; +enum Events +{ + EVENT_ARC_LIGHTNING = 1, + EVENT_LIGHTNING_NOVA, + EVENT_RESUME_PULSING_SHOCKWAVE, + EVENT_INTRO_DIALOGUE +}; + +enum Phases +{ + // Phases are used to allow executing the intro event while UpdateVictim() returns false and convenience. + PHASE_INTRO = 1, + PHASE_NORMAL +}; + enum Misc { ACHIEV_TIMELY_DEATH_START_EVENT = 20384 @@ -65,58 +80,41 @@ class boss_loken : public CreatureScript public: boss_loken() : CreatureScript("boss_loken") { } - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_lokenAI>(creature); - } - - struct boss_lokenAI : public ScriptedAI + struct boss_lokenAI : public BossAI { - boss_lokenAI(Creature* creature) : ScriptedAI(creature) + boss_lokenAI(Creature* creature) : BossAI(creature, DATA_LOKEN) { Initialize(); - instance = creature->GetInstanceScript(); + _isIntroDone = false; } void Initialize() { - m_uiArcLightning_Timer = 15000; - m_uiLightningNova_Timer = 20000; - m_uiResumePulsingShockwave_Timer = 1000; - - m_uiHealthAmountModifier = 1; + _healthAmountModifier = 1; } - InstanceScript* instance; - - uint32 m_uiArcLightning_Timer; - uint32 m_uiLightningNova_Timer; - uint32 m_uiResumePulsingShockwave_Timer; - - uint32 m_uiHealthAmountModifier; - void Reset() override { Initialize(); - - instance->SetBossState(DATA_LOKEN, NOT_STARTED); + _Reset(); instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT); } void EnterCombat(Unit* /*who*/) override { + _EnterCombat(); Talk(SAY_AGGRO); - - instance->SetBossState(DATA_LOKEN, IN_PROGRESS); + events.SetPhase(PHASE_NORMAL); + events.ScheduleEvent(EVENT_ARC_LIGHTNING, 15000); + events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 20000); + events.ScheduleEvent(EVENT_RESUME_PULSING_SHOCKWAVE, 1000); instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT); } void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); - - instance->SetBossState(DATA_LOKEN, DONE); - instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PULSING_SHOCKWAVE_AURA); + _JustDied(); } void KilledUnit(Unit* who) override @@ -125,66 +123,89 @@ public: Talk(SAY_SLAY); } - void UpdateAI(uint32 uiDiff) override + void MoveInLineOfSight(Unit* who) override { - //Return since we have no target - if (!UpdateVictim()) - return; - - if (m_uiResumePulsingShockwave_Timer) + if (!_isIntroDone && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 40.0f)) { - if (m_uiResumePulsingShockwave_Timer <= uiDiff) - { - DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true); - me->ClearUnitState(UNIT_STATE_CASTING); // this flag breaks movement - - DoCast(me, SPELL_PULSING_SHOCKWAVE, true); - m_uiResumePulsingShockwave_Timer = 0; - } - else - m_uiResumePulsingShockwave_Timer -= uiDiff; + _isIntroDone = true; + Talk(SAY_INTRO_1); + events.ScheduleEvent(EVENT_INTRO_DIALOGUE, 20000, 0, PHASE_INTRO); } + BossAI::MoveInLineOfSight(who); + } - if (m_uiArcLightning_Timer <= uiDiff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_ARC_LIGHTNING); + void UpdateAI(uint32 diff) override + { + if (events.IsInPhase(PHASE_NORMAL) && !UpdateVictim()) + return; - m_uiArcLightning_Timer = urand(15000, 16000); - } - else - m_uiArcLightning_Timer -= uiDiff; + events.Update(diff); - if (m_uiLightningNova_Timer <= uiDiff) + while (uint32 eventId = events.ExecuteEvent()) { - Talk(SAY_NOVA); - Talk(EMOTE_NOVA); - DoCast(me, SPELL_LIGHTNING_NOVA); - - me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_PULSING_SHOCKWAVE, me)); - m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura - m_uiLightningNova_Timer = urand(20000, 21000); + switch (eventId) + { + case EVENT_ARC_LIGHTNING: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_ARC_LIGHTNING); + events.ScheduleEvent(EVENT_ARC_LIGHTNING, urand(15000, 16000)); + break; + case EVENT_LIGHTNING_NOVA: + Talk(SAY_NOVA); + Talk(EMOTE_NOVA); + DoCastAOE(SPELL_LIGHTNING_NOVA); + me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_PULSING_SHOCKWAVE, me)); + events.ScheduleEvent(EVENT_RESUME_PULSING_SHOCKWAVE, DUNGEON_MODE(5000, 4000)); // Pause Pulsing Shockwave aura + events.ScheduleEvent(EVENT_LIGHTNING_NOVA, urand(20000, 21000)); + break; + case EVENT_RESUME_PULSING_SHOCKWAVE: + DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true); + me->ClearUnitState(UNIT_STATE_CASTING); // This flag breaks movement. + DoCast(me, SPELL_PULSING_SHOCKWAVE, true); + break; + case EVENT_INTRO_DIALOGUE: + Talk(SAY_INTRO_2); + events.SetPhase(PHASE_NORMAL); + break; + default: + break; + } } - else - m_uiLightningNova_Timer -= uiDiff; - // Health check - if (HealthBelowPct(100 - 25 * m_uiHealthAmountModifier)) + DoMeleeAttackIfReady(); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(100 - 25 * _healthAmountModifier, damage)) { - switch (m_uiHealthAmountModifier) + switch (_healthAmountModifier) { - case 1: Talk(SAY_75HEALTH); break; - case 2: Talk(SAY_50HEALTH); break; - case 3: Talk(SAY_25HEALTH); break; + case 1: + Talk(SAY_75HEALTH); + break; + case 2: + Talk(SAY_50HEALTH); + break; + case 3: + Talk(SAY_25HEALTH); + break; + default: + break; } - - ++m_uiHealthAmountModifier; + ++_healthAmountModifier; } - - DoMeleeAttackIfReady(); } + + private: + uint32 _healthAmountModifier; + bool _isIntroDone; }; + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_lokenAI>(creature); + } }; class spell_loken_pulsing_shockwave : public SpellScriptLoader |