From a10c183e99a7c4880420886777e6b3e1c3308965 Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Wed, 14 Jun 2023 23:23:13 +0200 Subject: [PATCH] chore(Scripts/MagtheridonsLair): rework Magtheridon boss script (#16527) * initial commit * remove leftovers * codestyle --- .../MagtheridonsLair/boss_magtheridon.cpp | 246 ++++++++---------- 1 file changed, 109 insertions(+), 137 deletions(-) diff --git a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp index b7ec0db34..077dbd977 100644 --- a/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp @@ -55,27 +55,9 @@ enum Spells SPELL_DEBRIS_DAMAGE = 30631 }; -enum Events +enum Groups { - EVENT_EMOTE1 = 1, - EVENT_EMOTE2 = 2, - EVENT_EMOTE3 = 3, - EVENT_ENTER_COMBAT = 4, - EVENT_RECENTLY_SPOKEN = 5, - - EVENT_CLEAVE = 10, - EVENT_BLAST_NOVA = 11, - EVENT_BLAZE = 12, - EVENT_ENRAGE = 13, - EVENT_QUAKE = 14, - EVENT_CHECK_HEALTH = 15, - EVENT_COLLAPSE_CEIL = 16, - EVENT_COLLAPSE_DAMAGE = 17, - EVENT_DEBRIS = 18, - - EVENT_RANDOM_TAUNT = 30, - EVENT_CHECK_GRASP = 31, - EVENT_CANCEL_GRASP_CHECK = 32 + GROUP_INTERRUPT_CHECK = 0 }; class DealDebrisDamage : public BasicEvent @@ -102,28 +84,69 @@ public: struct boss_magtheridonAI : public BossAI { - boss_magtheridonAI(Creature* creature) : BossAI(creature, TYPE_MAGTHERIDON) { } - - EventMap events2; + boss_magtheridonAI(Creature* creature) : BossAI(creature, TYPE_MAGTHERIDON) + { + scheduler.SetValidator([this] + { + return !me->HasUnitState(UNIT_STATE_CASTING); + }); + } void Reset() override { - events2.Reset(); - events2.ScheduleEvent(EVENT_RANDOM_TAUNT, 90000); _Reset(); + _currentPhase = 0; + _recentlySpoken = false; + scheduler.Schedule(90s, [this](TaskContext context) + { + Talk(SAY_TAUNT); + context.Repeat(90s); + }); me->CastSpell(me, SPELL_SHADOW_CAGE, true); me->SetReactState(REACT_PASSIVE); me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); me->SetImmuneToPC(true); + + ScheduleHealthCheckEvent(30, [&] { + _currentPhase = 1; + Talk(SAY_PHASE3); + me->GetMotionMaster()->Clear(); + scheduler.DelayAll(18s); + scheduler.Schedule(8s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_CAMERA_SHAKE, true); + instance->SetData(DATA_COLLAPSE, GO_STATE_ACTIVE); + }).Schedule(15s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_COLLAPSE_DAMAGE, true); + me->resetAttackTimer(); + me->GetMotionMaster()->MoveChase(me->GetVictim()); + _currentPhase = 0; + scheduler.Schedule(20s, [this](TaskContext context) + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random)) + { + target->CastSpell(target, SPELL_DEBRIS_VISUAL, true, nullptr, nullptr, me->GetGUID()); + me->m_Events.AddEvent(new DealDebrisDamage(*me, target->GetGUID()), me->m_Events.CalculateTime(5000)); + } + context.Repeat(20s); + }); + }); + }); } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* /*victim*/) override { - if (events.GetNextEventTime(EVENT_RECENTLY_SPOKEN) == 0) + if(!_recentlySpoken) { - events.ScheduleEvent(EVENT_RECENTLY_SPOKEN, 5000); Talk(SAY_SLAY); + _recentlySpoken = true; } + + scheduler.Schedule(5s, [this](TaskContext /*context*/) + { + _recentlySpoken = false; + }); } void JustDied(Unit* /*killer*/) override @@ -132,135 +155,84 @@ public: Talk(SAY_DEATH); } - void MoveInLineOfSight(Unit* /*who*/) override { } - void JustEngagedWith(Unit* /*who*/) override { - events2.Reset(); _JustEngagedWith(); - events.ScheduleEvent(EVENT_EMOTE1, 0); - events.ScheduleEvent(EVENT_EMOTE2, 60000); - events.ScheduleEvent(EVENT_EMOTE3, 120000); - events.ScheduleEvent(EVENT_ENTER_COMBAT, 123000); + Talk(SAY_EMOTE_BEGIN); + + scheduler.Schedule(60s, [this](TaskContext /*context*/) + { + Talk(SAY_EMOTE_NEARLY); + }).Schedule(120s, [this](TaskContext /*context*/) + { + Talk(SAY_EMOTE_FREE); + }).Schedule(123s, [this](TaskContext /*context*/) + { + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetImmuneToPC(false); + me->SetReactState(REACT_AGGRESSIVE); + instance->SetData(DATA_ACTIVATE_CUBES, 1); + me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE); + + scheduler.Schedule(9s, [this](TaskContext context) + { + DoCastVictim(SPELL_CLEAVE); + context.Repeat(10s); + }).Schedule(10s, [this](TaskContext context) + { + me->CastCustomSpell(SPELL_BLAZE, SPELLVALUE_MAX_TARGETS, 1); + context.Repeat(30s); + }).Schedule(40s, [this](TaskContext context) + { + me->CastSpell(me, SPELL_QUAKE); //needs fixes with custom spell + scheduler.Schedule(7s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_BLAST_NOVA); + + scheduler.Schedule(50ms, GROUP_INTERRUPT_CHECK, [this](TaskContext context) + { + if (me->GetAuraCount(SPELL_SHADOW_GRASP_VISUAL) == 5) + { + Talk(SAY_BANISH); + me->InterruptNonMeleeSpells(true); + scheduler.CancelGroup(GROUP_INTERRUPT_CHECK); + } + context.Repeat(50ms); + }).Schedule(12s, GROUP_INTERRUPT_CHECK, [this](TaskContext /*context*/) + { + scheduler.CancelGroup(GROUP_INTERRUPT_CHECK); + }); + }); + context.Repeat(50s); + }).Schedule(1320s, [this](TaskContext /*context*/) + { + DoCastSelf(SPELL_BERSERK, true); + }); + }); } void UpdateAI(uint32 diff) override { - events2.Update(diff); - switch (events2.ExecuteEvent()) - { - case EVENT_RANDOM_TAUNT: - Talk(SAY_TAUNT); - events2.ScheduleEvent(EVENT_RANDOM_TAUNT, 90000); - break; - case EVENT_CHECK_GRASP: - if (me->GetAuraCount(SPELL_SHADOW_GRASP_VISUAL) == 5) - { - Talk(SAY_BANISH); - me->InterruptNonMeleeSpells(true); - break; - } - events2.ScheduleEvent(EVENT_CHECK_GRASP, 0); - break; - } - if (!UpdateVictim()) return; - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + scheduler.Update(diff); - switch (events.ExecuteEvent()) + if (_currentPhase != 1) { - case EVENT_EMOTE1: - Talk(SAY_EMOTE_BEGIN); - break; - case EVENT_EMOTE2: - Talk(SAY_EMOTE_NEARLY); - break; - case EVENT_EMOTE3: - Talk(SAY_EMOTE_FREE); - Talk(SAY_FREE); - break; - case EVENT_ENTER_COMBAT: - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetImmuneToPC(false); - me->SetReactState(REACT_AGGRESSIVE); - events.ScheduleEvent(EVENT_CLEAVE, 9000); - events.ScheduleEvent(EVENT_BLAZE, 10000); - events.ScheduleEvent(EVENT_QUAKE, 40000); - events.ScheduleEvent(EVENT_CHECK_HEALTH, 500); - events.ScheduleEvent(EVENT_ENRAGE, 22 * MINUTE * IN_MILLISECONDS); - - instance->SetData(DATA_ACTIVATE_CUBES, 1); - me->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE); - break; - case EVENT_CLEAVE: - me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false); - events.ScheduleEvent(EVENT_CLEAVE, 10000); - break; - case EVENT_BLAST_NOVA: - me->CastSpell(me, SPELL_BLAST_NOVA, false); - events.ScheduleEvent(EVENT_CANCEL_GRASP_CHECK, 12000); - events2.ScheduleEvent(EVENT_CHECK_GRASP, 0); - break; - case EVENT_BLAZE: - me->CastCustomSpell(SPELL_BLAZE, SPELLVALUE_MAX_TARGETS, 1); - events.ScheduleEvent(EVENT_BLAZE, 30000); - break; - case EVENT_ENRAGE: - me->CastSpell(me, SPELL_BERSERK, true); - break; - case EVENT_CANCEL_GRASP_CHECK: - events2.Reset(); - break; - case EVENT_QUAKE: - me->CastSpell(me, SPELL_QUAKE, false); - events.ScheduleEvent(EVENT_BLAST_NOVA, 7000); - events.ScheduleEvent(EVENT_QUAKE, 50000); - break; - case EVENT_CHECK_HEALTH: - if (me->HealthBelowPct(30)) - { - Talk(SAY_PHASE3); - events.SetPhase(1); - events.DelayEvents(18000); - events.ScheduleEvent(EVENT_COLLAPSE_CEIL, 8000); - events.ScheduleEvent(EVENT_COLLAPSE_DAMAGE, 15000); - break; - } - events.ScheduleEvent(EVENT_CHECK_HEALTH, 500); - break; - case EVENT_COLLAPSE_CEIL: - me->CastSpell(me, SPELL_CAMERA_SHAKE, true); - instance->SetData(DATA_COLLAPSE, GO_STATE_ACTIVE); - break; - case EVENT_COLLAPSE_DAMAGE: - me->CastSpell(me, SPELL_COLLAPSE_DAMAGE, true); - me->resetAttackTimer(); - events.SetPhase(0); - events.ScheduleEvent(EVENT_DEBRIS, 20000); - break; - case EVENT_DEBRIS: - if (Unit* target = SelectTarget(SelectTargetMethod::Random)) - { - target->CastSpell(target, SPELL_DEBRIS_VISUAL, true, nullptr, nullptr, me->GetGUID()); - me->m_Events.AddEvent(new DealDebrisDamage(*me, target->GetGUID()), me->m_Events.CalculateTime(5000)); - } - events.ScheduleEvent(EVENT_DEBRIS, 20000); - break; - } - - if (!events.IsInPhase(1)) DoMeleeAttackIfReady(); + } } + private: + bool _recentlySpoken; + uint8 _currentPhase; }; CreatureAI* GetAI(Creature* creature) const override { return GetMagtheridonsLairAI(creature); } + }; class spell_magtheridon_blaze : public SpellScriptLoader