This commit is contained in:
Jelle Meeus
2025-07-13 10:24:11 +02:00
parent 1c51dcea1d
commit 64c0fde3d8

View File

@@ -15,7 +15,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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);
// 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 JustSummoned(Creature* cr) override
{
summons.Summon(cr);
}
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)
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))
{
if (GameObject* go = me->GetMap()->GetGameObject(pInstance->GetGuidData(DATA_FAERLINA_WEB)))
{
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);
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;
};
};