From 64c0fde3d835386e2839291fe521c0870a15f75f Mon Sep 17 00:00:00 2001 From: Jelle Meeus Date: Sun, 13 Jul 2025 10:24:11 +0200 Subject: [PATCH] faerlina --- src/naxx40Scripts/boss_faerlina_40.cpp | 187 ++++++------------------- 1 file changed, 45 insertions(+), 142 deletions(-) diff --git a/src/naxx40Scripts/boss_faerlina_40.cpp b/src/naxx40Scripts/boss_faerlina_40.cpp index ad433ac..a911ff7 100644 --- a/src/naxx40Scripts/boss_faerlina_40.cpp +++ b/src/naxx40Scripts/boss_faerlina_40.cpp @@ -15,7 +15,7 @@ * with this program. If not, see . */ -#include "ScriptMgr.h" +#include "CreatureScript.h" #include "ScriptedCreature.h" #include "SpellInfo.h" #include "naxxramas.h" @@ -36,30 +36,19 @@ enum Spells SPELL_POISON_BOLT_VOLLEY = 28796, SPELL_RAIN_OF_FIRE = 28794, SPELL_FRENZY = 28798, - SPELL_WIDOWS_EMBRACE = 28732 + SPELL_WIDOWS_EMBRACE = 28732, + SPELL_MINION_WIDOWS_EMBRACE = 54097 }; -enum SpellValues : int32 +enum Groups { - POISON_BOLT_VOLLEY_BP0 = 1224, - POISON_BOLT_VOLLEY_BP1 = 416, - RAIN_OF_FIRE_BP0 = 1849, - FRENZY_BP0 = 149, - FRENZY_BP1 = 74, - FRENZY_BP2 = 49 -}; - -enum Events -{ - EVENT_POISON_BOLT = 1, - EVENT_RAIN_OF_FIRE = 2, - EVENT_FRENZY = 3 + GROUP_FRENZY = 1 }; enum Misc { - NPC_NAXXRAMAS_WORSHIPPER = 351081, - NPC_NAXXRAMAS_FOLLOWER = 351080 + // NPC_NAXXRAMAS_WORSHIPPER = 16506, + // NPC_NAXXRAMAS_FOLLOWER = 16505 }; class boss_faerlina_40 : public CreatureScript @@ -74,16 +63,7 @@ public: struct boss_faerlina_40AI : public BossAI { - boss_faerlina_40AI(Creature* c) : BossAI(c, BOSS_FAERLINA), summons(me) - { - pInstance = me->GetInstanceScript(); - sayGreet = false; - } - - InstanceScript* pInstance; - EventMap events; - SummonList summons; - bool sayGreet; + boss_faerlina_40AI(Creature* c) : BossAI(c, BOSS_FAERLINA), _introDone(false) { } void SummonHelpers() { @@ -91,28 +71,18 @@ public: me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3344.3f, -3618.31f, 261.08f, 4.69494f); me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3356.71f, -3620.05f, 261.08f, 4.57276f); me->SummonCreature(NPC_NAXXRAMAS_WORSHIPPER, 3350.26f, -3619.11f, 261.08f, 4.67748f); - me->SummonCreature(NPC_NAXXRAMAS_FOLLOWER, 3347.49f, -3617.59f, 261.0f, 4.49f); - me->SummonCreature(NPC_NAXXRAMAS_FOLLOWER, 3359.64f, -3619.16f, 261.0f, 4.56f); - } - - void JustSummoned(Creature* cr) override - { - summons.Summon(cr); + // if (Is25ManRaid()) + { + me->SummonCreature(NPC_NAXXRAMAS_FOLLOWER, 3347.49f, -3617.59f, 261.0f, 4.49f); + me->SummonCreature(NPC_NAXXRAMAS_FOLLOWER, 3359.64f, -3619.16f, 261.0f, 4.56f); + } } void Reset() override { BossAI::Reset(); - events.Reset(); summons.DespawnAll(); SummonHelpers(); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_FAERLINA_WEB))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } } void JustEngagedWith(Unit* who) override @@ -121,122 +91,54 @@ public: me->CallForHelp(VISIBLE_RANGE); summons.DoZoneInCombat(); Talk(SAY_AGGRO); - events.ScheduleEvent(EVENT_POISON_BOLT, urand(7000, 12000)); - events.ScheduleEvent(EVENT_RAIN_OF_FIRE, urand(8000, 12000)); - events.ScheduleEvent(EVENT_FRENZY, urand(60000, 80000), 1); - events.SetPhase(1); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_FAERLINA_WEB))) + + ScheduleTimedEvent(7s, 15s, [&]{ + if (!me->HasAura(SPELL_WIDOWS_EMBRACE)) + DoCastVictim(SPELL_POISON_BOLT_VOLLEY); + }, 7s, 15s); + + ScheduleTimedEvent(8s, 18s, [&] { + DoCastRandomTarget(SPELL_RAIN_OF_FIRE); + }, 8s, 18s); + + scheduler.Schedule(60s, 80s, GROUP_FRENZY, [this](TaskContext context) { + if (!me->HasAura(SPELL_WIDOWS_EMBRACE)) { - go->SetGoState(GO_STATE_READY); + Talk(SAY_FRENZY); + Talk(EMOTE_FRENZY); + DoCastSelf(SPELL_FRENZY, true); + context.Repeat(1min); } - } + else + context.Repeat(30s); + }); } void MoveInLineOfSight(Unit* who) override { - if (!sayGreet && who->GetTypeId() == TYPEID_PLAYER) + if (!_introDone && who->IsPlayer()) { Talk(SAY_GREET); - sayGreet = true; + _introDone = true; } ScriptedAI::MoveInLineOfSight(who); } void KilledUnit(Unit* who) override { - if (who->GetTypeId() != TYPEID_PLAYER) + if (!who->IsPlayer()) return; if (!urand(0, 3)) - { Talk(SAY_SLAY); - } - if (pInstance) - { - pInstance->SetData(DATA_IMMORTAL_FAIL, 0); - } + + instance->StorePersistentData(PERSISTENT_DATA_IMMORTAL_FAIL, 1); } void JustDied(Unit* killer) override { BossAI::JustDied(killer); Talk(SAY_DEATH); - if (pInstance) - { - if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_FAERLINA_WEB))) - { - go->SetGoState(GO_STATE_ACTIVE); - } - } - } - - void UpdateAI(uint32 diff) override - { - if (!me->IsInCombat() && sayGreet) - { - for (SummonList::iterator itr = summons.begin(); itr != summons.end(); ++itr) - { - if (pInstance) - { - if (Creature* cr = pInstance->instance->GetCreature(*itr)) - { - if (cr->IsInCombat()) - DoZoneInCombat(); - } - } - } - } - - if (!UpdateVictim()) - return; - - events.Update(diff); - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - switch (events.ExecuteEvent()) - { - case EVENT_POISON_BOLT: - if (!me->HasAura(SPELL_WIDOWS_EMBRACE)) - { - CustomSpellValues values; - int32 bp0 = POISON_BOLT_VOLLEY_BP0; - int32 bp1 = POISON_BOLT_VOLLEY_BP1; - values.AddSpellMod(SPELLVALUE_MAX_TARGETS, 10); - values.AddSpellMod(SPELLVALUE_BASE_POINT0, bp0); - values.AddSpellMod(SPELLVALUE_BASE_POINT1, bp1); - me->CastCustomSpell(SPELL_POISON_BOLT_VOLLEY, values, me, TRIGGERED_NONE, nullptr, nullptr, ObjectGuid::Empty); - } - events.RepeatEvent(urand(7000, 12000)); - break; - case EVENT_RAIN_OF_FIRE: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - { - int32 bp0 = RAIN_OF_FIRE_BP0; - me->CastCustomSpell(target, SPELL_RAIN_OF_FIRE, &bp0, 0, 0, false, nullptr, nullptr, ObjectGuid::Empty); - } - events.RepeatEvent(urand(8000, 12000)); - break; - case EVENT_FRENZY: - if (!me->HasAura(SPELL_FRENZY)) - { - Talk(SAY_FRENZY); - Talk(EMOTE_FRENZY); - int32 bp0 = FRENZY_BP0; - int32 bp1 = FRENZY_BP1; - int32 bp2 = FRENZY_BP2; - me->CastCustomSpell(me, SPELL_FRENZY, &bp0, &bp1, &bp2, true, nullptr, nullptr, ObjectGuid::Empty); - events.RepeatEvent(60000); - } - else - { - events.RepeatEvent(30000); - } - break; - } - DoMeleeAttackIfReady(); } void SpellHit(Unit* caster, SpellInfo const* spell) override @@ -246,17 +148,18 @@ public: Talk(EMOTE_WIDOWS_EMBRACE); // %s is affected by Widow's Embrace! if (me->HasAura(SPELL_FRENZY)) { - events.RescheduleEvent(EVENT_FRENZY, 60000); // You must sacrifice the worshiper AFTER she enrages if you want to stop her for the full 60 seconds. + scheduler.RescheduleGroup(GROUP_FRENZY, 1min); // You must sacrifice the worshiper AFTER she enrages if you want to stop her for the full 60 seconds. me->RemoveAurasDueToSpell(SPELL_FRENZY); - pInstance->SetData(DATA_FRENZY_REMOVED, 0); // achievement + instance->SetData(DATA_FRENZY_REMOVED, 0); // achievement } - else - { - events.RescheduleEvent(EVENT_FRENZY, 30000); // If you sacrifice the Worshiper before the enrage, it will merely delay the enrage for 30 seconds. - } - Unit::Kill(caster, caster); + else + scheduler.RescheduleGroup(GROUP_FRENZY, 30s); // If you sacrifice the Worshiper before the enrage, it will merely delay the enrage for 30 seconds. + caster->KillSelf(); } } + + private: + bool _introDone; }; };