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

View File

@@ -70,29 +70,20 @@ enum Spells
enum Misc
{
ACTION_SISTER_DIED = 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
GROUP_SPECIAL_ABILITY = 1
};
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
{
me->CastSpell(me, SPELL_SHADOWFORM, true);
sisterDied = false;
DoCastSelf(SPELL_SHADOWFORM, true);
_isSisterDead = false;
BossAI::Reset();
me->SetLootMode(0);
me->m_Events.KillAllEvents(false);
}
void DoAction(int32 param) override
@@ -100,20 +91,24 @@ struct boss_sacrolash : public BossAI
if (param == ACTION_SISTER_DIED)
{
me->ResetLootMode();
sisterDied = true;
_isSisterDead = true;
Talk(YELL_SISTER_ALYTHESS_DEAD);
me->CastSpell(me, SPELL_EMPOWER, true);
uint32 timer = events.GetNextEventTime(EVENT_SPELL_SHADOW_NOVA);
events.CancelEvent(EVENT_SPELL_SHADOW_NOVA);
events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, timer - events.GetTimer());
scheduler.CancelGroup(GROUP_SPECIAL_ABILITY);
ScheduleTimedEvent(20s, [&] {
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
{
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())
alythess->Respawn(true);
@@ -125,15 +120,36 @@ struct boss_sacrolash : public BossAI
void JustEngagedWith(Unit* who) override
{
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())
alythess->AI()->AttackStart(who);
events.ScheduleEvent(EVENT_SPELL_SHADOW_BLADES, 10000);
events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, 36000);
events.ScheduleEvent(EVENT_SPELL_CONFOUNDING_BLOW, 25000);
events.ScheduleEvent(EVENT_SHADOW_IMAGE, 20000);
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 360000);
me->m_Events.AddEventAtOffset([&] {
Talk(YELL_BERSERK);
DoCastSelf(SPELL_ENRAGE, true);
}, 6min);
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
@@ -144,15 +160,14 @@ struct boss_sacrolash : public BossAI
void JustDied(Unit* /*killer*/) override
{
events.Reset();
summons.DespawnAll();
if (sisterDied)
if (_isSisterDead)
{
Talk(YELL_SAC_DEAD);
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);
}
@@ -166,70 +181,21 @@ struct boss_sacrolash : public BossAI
}
}
void UpdateAI(uint32 diff) override
{
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();
}
private:
bool _isSisterDead;
};
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
{
me->CastSpell(me, SPELL_FIREFORM, true);
sisterDied = false;
DoCastSelf(SPELL_FIREFORM, true);
_isSisterDead = false;
BossAI::Reset();
me->SetLootMode(0);
me->m_Events.KillAllEvents(false);
}
void DoAction(int32 param) override
@@ -237,40 +203,65 @@ struct boss_alythess : public BossAI
if (param == ACTION_SISTER_DIED)
{
me->ResetLootMode();
sisterDied = true;
_isSisterDead = true;
Talk(YELL_SISTER_SACROLASH_DEAD);
me->CastSpell(me, SPELL_EMPOWER, true);
uint32 timer = events.GetNextEventTime(EVENT_SPELL_CONFLAGRATION);
events.CancelEvent(EVENT_SPELL_CONFLAGRATION);
events.ScheduleEvent(EVENT_SPELL_SHADOW_NOVA, timer - events.GetTimer());
scheduler.CancelGroup(GROUP_SPECIAL_ABILITY);
ScheduleTimedEvent(20s, [&] {
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
{
BossAI::EnterEvadeMode(why);
if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH)))
if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
{
if (!scorlash->IsAlive())
scorlash->Respawn(true);
else if (!scorlash->IsInEvadeMode())
scorlash->AI()->EnterEvadeMode(why);
if (!sacrolash->IsAlive())
sacrolash->Respawn(true);
else if (!sacrolash->IsInEvadeMode())
sacrolash->AI()->EnterEvadeMode(why);
}
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH)))
if (scorlash->IsAlive() && !scorlash->IsInCombat())
scorlash->AI()->AttackStart(who);
if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
if (sacrolash->IsAlive() && !sacrolash->IsInCombat())
sacrolash->AI()->AttackStart(who);
events.ScheduleEvent(EVENT_SPELL_BLAZE, 100);
events.ScheduleEvent(EVENT_SPELL_PYROGENICS, 15000);
events.ScheduleEvent(EVENT_SPELL_FLAME_SEAR, 20000);
events.ScheduleEvent(EVENT_SPELL_CONFLAGRATION, 30000);
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 360000);
me->m_Events.AddEventAtOffset([&] {
Talk(YELL_BERSERK);
DoCastSelf(SPELL_ENRAGE, true);
}, 6min);
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
@@ -281,111 +272,46 @@ struct boss_alythess : public BossAI
void JustDied(Unit* /*killer*/) override
{
events.Reset();
summons.DespawnAll();
if (sisterDied)
if (_isSisterDead)
{
Talk(YELL_SAC_DEAD);
instance->SetBossState(DATA_EREDAR_TWINS, DONE);
}
else if (Creature* scorlash = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_SACROLASH)))
scorlash->AI()->DoAction(ACTION_SISTER_DIED);
else if (Creature* sacrolash = instance->GetCreature(DATA_SACROLASH))
sacrolash->AI()->DoAction(ACTION_SISTER_DIED);
}
void UpdateAI(uint32 diff) override
{
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();
}
private:
bool _isSisterDead;
};
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
{
return ValidateSpellInfo({ SPELL_DARK_TOUCHED });
return ValidateSpellInfo({ _touchSpell });
}
void HandleApplyTouch()
{
if (Player* target = GetHitPlayer())
target->CastSpell(target, SPELL_DARK_TOUCHED, true);
target->CastSpell(target, _touchSpell, true);
}
void Register() override
{
AfterHit += SpellHitFn(spell_eredar_twins_apply_dark_touched::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 });
AfterHit += SpellHitFn(spell_eredar_twins_apply_touch::HandleApplyTouch);
}
void HandleApplyTouch()
{
if (Player* target = GetHitPlayer())
target->CastSpell(target, SPELL_FLAME_TOUCHED, true);
}
void Register() override
{
AfterHit += SpellHitFn(spell_eredar_twins_apply_flame_touched::HandleApplyTouch);
}
private:
uint32 _touchSpell;
};
class spell_eredar_twins_handle_touch : public SpellScript
@@ -474,8 +400,8 @@ void AddSC_boss_eredar_twins()
{
RegisterSunwellPlateauCreatureAI(boss_sacrolash);
RegisterSunwellPlateauCreatureAI(boss_alythess);
RegisterSpellScript(spell_eredar_twins_apply_dark_touched);
RegisterSpellScript(spell_eredar_twins_apply_flame_touched);
RegisterSpellScriptWithArgs(spell_eredar_twins_apply_touch, "spell_eredar_twins_apply_dark_touched", SPELL_DARK_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_blaze);
new at_sunwell_eredar_twins();