diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp index 45ec1dccc..6538947e3 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/MoltenCore/boss_ragnaros.cpp @@ -80,6 +80,7 @@ enum Events EVENT_MIGHT_OF_RAGNAROS, EVENT_LAVA_BURST, EVENT_MAGMA_BLAST, + EVENT_MELEE_SCAN, EVENT_SUBMERGE, EVENT_LAVA_BURST_TRIGGER, @@ -218,29 +219,6 @@ struct boss_ragnaros : public BossAI DoStartNoMovement(target); } - void EnterEvadeMode(EvadeReason why) override - { - if (!me->GetThreatMgr().IsThreatListEmpty()) - { - if (!_processingMagmaBurst) - { - // Boss try to evade, but still got some targets on threat list - it means that none of these targets are in melee range - cast magma blast - _processingMagmaBurst = true; - events.ScheduleEvent(EVENT_MAGMA_BLAST, 4s, PHASE_EMERGED, PHASE_EMERGED); - } - } - else - { - BossAI::EnterEvadeMode(why); - } - } - - bool CanAIAttack(Unit const* victim) const override - { - // Used for Magma Blast handling to force EnterEvadeMode if there are no melee targets - return me->IsWithinMeleeRange(victim); - } - void UpdateAI(uint32 diff) override { if (!extraEvents.Empty()) @@ -307,10 +285,7 @@ struct boss_ragnaros : public BossAI } if (!UpdateVictim()) - { - if (!_processingMagmaBurst) - return; - } + return; events.Update(diff); @@ -348,19 +323,47 @@ struct boss_ragnaros : public BossAI DoCastAOE(SPELL_LAVA_BURST); break; } + case EVENT_MELEE_SCAN: + { + // ReselectVictim() in the threat system already prefers + // in-melee-range targets, so if the current victim is out + // of melee range it means *nobody* is in range. Use that + // as the trigger for the Magma Blast fallback. + if (!IsVictimWithinMeleeRange()) + { + if (!_processingMagmaBurst) + { + _processingMagmaBurst = true; + events.ScheduleEvent(EVENT_MAGMA_BLAST, 4s, PHASE_EMERGED, PHASE_EMERGED); + } + } + else if (_processingMagmaBurst) + { + events.CancelEvent(EVENT_MAGMA_BLAST); + _processingMagmaBurst = false; + } + events.Repeat(500ms); + break; + } case EVENT_MAGMA_BLAST: { _processingMagmaBurst = false; - if (!IsVictimWithinMeleeRange()) + if (IsVictimWithinMeleeRange()) + break; + + if (Unit* victim = me->GetVictim()) { - DoCastRandomTarget(SPELL_MAGMA_BLAST); + DoCast(victim, SPELL_MAGMA_BLAST); if (!_hasYelledMagmaBurst) { Talk(SAY_MAGMABURST); _hasYelledMagmaBurst = true; } + + _processingMagmaBurst = true; + events.ScheduleEvent(EVENT_MAGMA_BLAST, 4s, PHASE_EMERGED, PHASE_EMERGED); } break; @@ -454,12 +457,14 @@ private: events.RescheduleEvent(EVENT_LAVA_BURST, 10s, PHASE_EMERGED, PHASE_EMERGED); events.RescheduleEvent(EVENT_SUBMERGE, 180s, PHASE_EMERGED, PHASE_EMERGED); events.RescheduleEvent(EVENT_MIGHT_OF_RAGNAROS, 11s, PHASE_EMERGED, PHASE_EMERGED); + events.RescheduleEvent(EVENT_MELEE_SCAN, 500ms, PHASE_EMERGED, PHASE_EMERGED); } bool IsVictimWithinMeleeRange() const { return me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()); } + }; constexpr std::array RagnarosLavaBurstSpells = { SPELL_LAVA_BURST_A, SPELL_LAVA_BURST_B, SPELL_LAVA_BURST_C, SPELL_LAVA_BURST_D, SPELL_LAVA_BURST_E, SPELL_LAVA_BURST_F, SPELL_LAVA_BURST_G, SPELL_LAVA_BURST_H };