refactor(Scripts/SunwellPlateau): Modernize Eredar Twins script (#20516)

This commit is contained in:
Andrew
2024-11-11 06:09:08 -03:00
committed by GitHub
parent 09352d8b91
commit 519daf9cc7
@@ -70,29 +70,20 @@ enum Spells
enum Misc enum Misc
{ {
ACTION_SISTER_DIED = 1, ACTION_SISTER_DIED = 1,
GROUP_SPECIAL_ABILITY = 1
EVENT_SPELL_SHADOW_BLADES = 1,
EVENT_SPELL_SHADOW_NOVA = 2,
EVENT_SPELL_CONFOUNDING_BLOW = 3,
EVENT_SHADOW_IMAGE = 4,
EVENT_SPELL_ENRAGE = 5,
EVENT_SPELL_CONFLAGRATION = 6,
EVENT_SPELL_BLAZE = 7,
EVENT_SPELL_PYROGENICS = 8,
EVENT_SPELL_FLAME_SEAR = 9
}; };
struct boss_sacrolash : public BossAI struct boss_sacrolash : public BossAI
{ {
boss_sacrolash(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS) {} boss_sacrolash(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS), _isSisterDead(false) {}
bool sisterDied;
void Reset() override void Reset() override
{ {
me->CastSpell(me, SPELL_SHADOWFORM, true); DoCastSelf(SPELL_SHADOWFORM, true);
sisterDied = false; _isSisterDead = false;
BossAI::Reset(); BossAI::Reset();
me->SetLootMode(0); me->SetLootMode(0);
me->m_Events.KillAllEvents(false);
} }
void DoAction(int32 param) override void DoAction(int32 param) override
@@ -100,20 +91,24 @@ struct boss_sacrolash : public BossAI
if (param == ACTION_SISTER_DIED) if (param == ACTION_SISTER_DIED)
{ {
me->ResetLootMode(); me->ResetLootMode();
sisterDied = true; _isSisterDead = true;
Talk(YELL_SISTER_ALYTHESS_DEAD); Talk(YELL_SISTER_ALYTHESS_DEAD);
me->CastSpell(me, SPELL_EMPOWER, true); me->CastSpell(me, SPELL_EMPOWER, true);
uint32 timer = events.GetNextEventTime(EVENT_SPELL_SHADOW_NOVA); scheduler.CancelGroup(GROUP_SPECIAL_ABILITY);
events.CancelEvent(EVENT_SPELL_SHADOW_NOVA); ScheduleTimedEvent(20s, [&] {
events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, timer - events.GetTimer()); Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f);
if (!target)
target = me->GetVictim();
me->CastSpell(target, SPELL_CONFLAGRATION, false);
}, 30s, 35s);
} }
} }
void EnterEvadeMode(EvadeReason why) override void EnterEvadeMode(EvadeReason why) override
{ {
BossAI::EnterEvadeMode(why); BossAI::EnterEvadeMode(why);
if (Creature* alythess = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GRAND_WARLOCK_ALYTHESS))) if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS))
{ {
if (!alythess->IsAlive()) if (!alythess->IsAlive())
alythess->Respawn(true); alythess->Respawn(true);
@@ -125,15 +120,36 @@ struct boss_sacrolash : public BossAI
void JustEngagedWith(Unit* who) override void JustEngagedWith(Unit* who) override
{ {
BossAI::JustEngagedWith(who); BossAI::JustEngagedWith(who);
if (Creature* alythess = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GRAND_WARLOCK_ALYTHESS))) if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS))
if (alythess->IsAlive() && !alythess->IsInCombat()) if (alythess->IsAlive() && !alythess->IsInCombat())
alythess->AI()->AttackStart(who); alythess->AI()->AttackStart(who);
events.ScheduleEvent(EVENT_SPELL_SHADOW_BLADES, 10000); me->m_Events.AddEventAtOffset([&] {
events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, 36000); Talk(YELL_BERSERK);
events.ScheduleEvent(EVENT_SPELL_CONFOUNDING_BLOW, 25000); DoCastSelf(SPELL_ENRAGE, true);
events.ScheduleEvent(EVENT_SHADOW_IMAGE, 20000); }, 6min);
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 360000);
ScheduleTimedEvent(10s, [&] {
DoCastSelf(SPELL_SHADOW_BLADES);
}, 10s);
ScheduleTimedEvent(25s, [&] {
DoCastVictim(SPELL_CONFOUNDING_BLOW);
}, 20s, 25s);
ScheduleTimedEvent(20s, [&] {
me->SummonCreature(NPC_SHADOW_IMAGE, me->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 12000);
}, 6s);
scheduler.Schedule(36s, GROUP_SPECIAL_ABILITY, [this](TaskContext context) {
Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f);
if (!target)
target = me->GetVictim();
Talk(EMOTE_SHADOW_NOVA, target);
Talk(YELL_SHADOW_NOVA);
DoCast(target, SPELL_SHADOW_NOVA);
context.Repeat(30s, 35s);
});
} }
void KilledUnit(Unit* victim) override void KilledUnit(Unit* victim) override
@@ -144,15 +160,14 @@ struct boss_sacrolash : public BossAI
void JustDied(Unit* /*killer*/) override void JustDied(Unit* /*killer*/) override
{ {
events.Reset();
summons.DespawnAll(); summons.DespawnAll();
if (sisterDied) if (_isSisterDead)
{ {
Talk(YELL_SAC_DEAD); Talk(YELL_SAC_DEAD);
instance->SetBossState(DATA_EREDAR_TWINS, DONE); instance->SetBossState(DATA_EREDAR_TWINS, DONE);
} }
else if (Creature* alythess = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_GRAND_WARLOCK_ALYTHESS))) else if (Creature* alythess = instance->GetCreature(DATA_ALYTHESS))
alythess->AI()->DoAction(ACTION_SISTER_DIED); alythess->AI()->DoAction(ACTION_SISTER_DIED);
} }
@@ -166,70 +181,21 @@ struct boss_sacrolash : public BossAI
} }
} }
void UpdateAI(uint32 diff) override private:
{ bool _isSisterDead;
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_ENRAGE:
Talk(YELL_ENRAGE);
me->CastSpell(me, SPELL_ENRAGE, true);
break;
case EVENT_SPELL_CONFOUNDING_BLOW:
me->CastSpell(me->GetVictim(), SPELL_CONFOUNDING_BLOW, false);
events.ScheduleEvent(EVENT_SPELL_CONFOUNDING_BLOW, urand(20000, 25000));
break;
case EVENT_SPELL_SHADOW_BLADES:
me->CastSpell(me, SPELL_SHADOW_BLADES, false);
events.ScheduleEvent(EVENT_SPELL_SHADOW_BLADES, 10000);
break;
case EVENT_SPELL_SHADOW_NOVA:
{
Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f);
if (!target)
target = me->GetVictim();
Talk(EMOTE_SHADOW_NOVA, target);
Talk(YELL_SHADOW_NOVA);
me->CastSpell(target, SPELL_SHADOW_NOVA, false);
events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, urand(30000, 35000));
break;
}
case EVENT_SHADOW_IMAGE:
me->SummonCreature(NPC_SHADOW_IMAGE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 12000);
events.ScheduleEvent(EVENT_SHADOW_IMAGE, 6000);
break;
case EVENT_SPELL_CONFLAGRATION:
{
Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f);
if (!target)
target = me->GetVictim();
me->CastSpell(target, SPELL_CONFLAGRATION, false);
events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, urand(30000, 35000));
break;
}
}
DoMeleeAttackIfReady();
}
}; };
struct boss_alythess : public BossAI struct boss_alythess : public BossAI
{ {
boss_alythess(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS) { } boss_alythess(Creature* creature) : BossAI(creature, DATA_EREDAR_TWINS), _isSisterDead(false) { }
bool sisterDied;
void Reset() override void Reset() override
{ {
me->CastSpell(me, SPELL_FIREFORM, true); DoCastSelf(SPELL_FIREFORM, true);
sisterDied = false; _isSisterDead = false;
BossAI::Reset(); BossAI::Reset();
me->SetLootMode(0); me->SetLootMode(0);
me->m_Events.KillAllEvents(false);
} }
void DoAction(int32 param) override void DoAction(int32 param) override
@@ -237,40 +203,65 @@ struct boss_alythess : public BossAI
if (param == ACTION_SISTER_DIED) if (param == ACTION_SISTER_DIED)
{ {
me->ResetLootMode(); me->ResetLootMode();
sisterDied = true; _isSisterDead = true;
Talk(YELL_SISTER_SACROLASH_DEAD); Talk(YELL_SISTER_SACROLASH_DEAD);
me->CastSpell(me, SPELL_EMPOWER, true); me->CastSpell(me, SPELL_EMPOWER, true);
uint32 timer = events.GetNextEventTime(EVENT_SPELL_CONFLAGRATION); scheduler.CancelGroup(GROUP_SPECIAL_ABILITY);
events.CancelEvent(EVENT_SPELL_CONFLAGRATION); ScheduleTimedEvent(20s, [&] {
events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, timer - events.GetTimer()); Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f);
if (!target)
target = me->GetVictim();
DoCast(target, SPELL_SHADOW_NOVA);
}, 30s, 35s);
} }
} }
void EnterEvadeMode(EvadeReason why) override void EnterEvadeMode(EvadeReason why) override
{ {
BossAI::EnterEvadeMode(why); BossAI::EnterEvadeMode(why);
if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH))) if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
{ {
if (!scorlash->IsAlive()) if (!sacrolash->IsAlive())
scorlash->Respawn(true); sacrolash->Respawn(true);
else if (!scorlash->IsInEvadeMode()) else if (!sacrolash->IsInEvadeMode())
scorlash->AI()->EnterEvadeMode(why); sacrolash->AI()->EnterEvadeMode(why);
} }
} }
void JustEngagedWith(Unit* who) override void JustEngagedWith(Unit* who) override
{ {
BossAI::JustEngagedWith(who); BossAI::JustEngagedWith(who);
if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH))) if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
if (scorlash->IsAlive() && !scorlash->IsInCombat()) if (sacrolash->IsAlive() && !sacrolash->IsInCombat())
scorlash->AI()->AttackStart(who); sacrolash->AI()->AttackStart(who);
events.ScheduleEvent(EVENT_SPELL_BLAZE, 100); me->m_Events.AddEventAtOffset([&] {
events.ScheduleEvent(EVENT_SPELL_PYROGENICS, 15000); Talk(YELL_BERSERK);
events.ScheduleEvent(EVENT_SPELL_FLAME_SEAR, 20000); DoCastSelf(SPELL_ENRAGE, true);
events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, 30000); }, 6min);
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 360000);
ScheduleTimedEvent(1s, [&] {
DoCastVictim(SPELL_BLAZE);
}, 3800ms);
ScheduleTimedEvent(15s, [&] {
DoCastSelf(SPELL_PYROGENICS);
}, 15s);
ScheduleTimedEvent(20s, [&] {
me->CastCustomSpell(SPELL_FLAME_SEAR, SPELLVALUE_MAX_TARGETS, 5, me, TRIGGERED_NONE);
}, 15s);
scheduler.Schedule(20s, GROUP_SPECIAL_ABILITY, [this](TaskContext context) {
Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f);
if (!target)
target = me->GetVictim();
Talk(EMOTE_CONFLAGRATION, target);
Talk(YELL_CANFLAGRATION);
DoCast(target, SPELL_CONFLAGRATION);
context.Repeat(30s, 35s);
});
} }
void KilledUnit(Unit* victim) override void KilledUnit(Unit* victim) override
@@ -281,111 +272,46 @@ struct boss_alythess : public BossAI
void JustDied(Unit* /*killer*/) override void JustDied(Unit* /*killer*/) override
{ {
events.Reset();
summons.DespawnAll(); summons.DespawnAll();
if (sisterDied) if (_isSisterDead)
{ {
Talk(YELL_SAC_DEAD); Talk(YELL_SAC_DEAD);
instance->SetBossState(DATA_EREDAR_TWINS, DONE); instance->SetBossState(DATA_EREDAR_TWINS, DONE);
} }
else if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH))) else if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
scorlash->AI()->DoAction(ACTION_SISTER_DIED); sacrolash->AI()->DoAction(ACTION_SISTER_DIED);
} }
void UpdateAI(uint32 diff) override private:
{ bool _isSisterDead;
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_ENRAGE:
Talk(YELL_BERSERK);
me->CastSpell(me, SPELL_ENRAGE, true);
break;
case EVENT_SPELL_PYROGENICS:
me->CastSpell(me, SPELL_PYROGENICS, false);
events.ScheduleEvent(EVENT_SPELL_PYROGENICS, 15000);
break;
case EVENT_SPELL_FLAME_SEAR:
me->CastCustomSpell(SPELL_FLAME_SEAR, SPELLVALUE_MAX_TARGETS, 5, me, TRIGGERED_NONE);
events.ScheduleEvent(EVENT_SPELL_FLAME_SEAR, 15000);
break;
case EVENT_SPELL_BLAZE:
me->CastSpell(me->GetVictim(), SPELL_BLAZE, false);
events.ScheduleEvent(EVENT_SPELL_BLAZE, 3800);
break;
case EVENT_SPELL_SHADOW_NOVA:
{
Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f);
if (!target)
target = me->GetVictim();
me->CastSpell(target, SPELL_SHADOW_NOVA, false);
events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, urand(30000, 35000));
break;
}
case EVENT_SPELL_CONFLAGRATION:
{
Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 1, 100.0f);
if (!target)
target = me->GetVictim();
Talk(EMOTE_CONFLAGRATION, target);
Talk(YELL_CANFLAGRATION);
me->CastSpell(target, SPELL_CONFLAGRATION, false);
events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, urand(30000, 35000));
break;
}
}
DoMeleeAttackIfReady();
}
}; };
class spell_eredar_twins_apply_dark_touched : public SpellScript class spell_eredar_twins_apply_touch : public SpellScript
{ {
PrepareSpellScript(spell_eredar_twins_apply_dark_touched); PrepareSpellScript(spell_eredar_twins_apply_touch);
public:
spell_eredar_twins_apply_touch(uint32 touchSpell) : SpellScript(), _touchSpell(touchSpell) { }
bool Validate(SpellInfo const* /*spellInfo*/) override bool Validate(SpellInfo const* /*spellInfo*/) override
{ {
return ValidateSpellInfo({ SPELL_DARK_TOUCHED }); return ValidateSpellInfo({ _touchSpell });
} }
void HandleApplyTouch() void HandleApplyTouch()
{ {
if (Player* target = GetHitPlayer()) if (Player* target = GetHitPlayer())
target->CastSpell(target, SPELL_DARK_TOUCHED, true); target->CastSpell(target, _touchSpell, true);
} }
void Register() override void Register() override
{ {
AfterHit += SpellHitFn(spell_eredar_twins_apply_dark_touched::HandleApplyTouch); AfterHit += SpellHitFn(spell_eredar_twins_apply_touch::HandleApplyTouch);
}
};
class spell_eredar_twins_apply_flame_touched : public SpellScript
{
PrepareSpellScript(spell_eredar_twins_apply_flame_touched);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_FLAME_TOUCHED });
} }
void HandleApplyTouch() private:
{ uint32 _touchSpell;
if (Player* target = GetHitPlayer())
target->CastSpell(target, SPELL_FLAME_TOUCHED, true);
}
void Register() override
{
AfterHit += SpellHitFn(spell_eredar_twins_apply_flame_touched::HandleApplyTouch);
}
}; };
class spell_eredar_twins_handle_touch : public SpellScript class spell_eredar_twins_handle_touch : public SpellScript
@@ -474,8 +400,8 @@ void AddSC_boss_eredar_twins()
{ {
RegisterSunwellPlateauCreatureAI(boss_sacrolash); RegisterSunwellPlateauCreatureAI(boss_sacrolash);
RegisterSunwellPlateauCreatureAI(boss_alythess); RegisterSunwellPlateauCreatureAI(boss_alythess);
RegisterSpellScript(spell_eredar_twins_apply_dark_touched); RegisterSpellScriptWithArgs(spell_eredar_twins_apply_touch, "spell_eredar_twins_apply_dark_touched", SPELL_DARK_TOUCHED);
RegisterSpellScript(spell_eredar_twins_apply_flame_touched); RegisterSpellScriptWithArgs(spell_eredar_twins_apply_touch, "spell_eredar_twins_apply_flame_touched", SPELL_FLAME_TOUCHED);
RegisterSpellScript(spell_eredar_twins_handle_touch); RegisterSpellScript(spell_eredar_twins_handle_touch);
RegisterSpellScript(spell_eredar_twins_blaze); RegisterSpellScript(spell_eredar_twins_blaze);
new at_sunwell_eredar_twins(); new at_sunwell_eredar_twins();