mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 08:28:32 +01:00
Scripts/VoA: Update remaining scripts to new model (#26372)
Co-authored-by: offl <offl@users.noreply.github.com>
(cherry picked from commit 3ece1ee87c)
This commit is contained in:
@@ -55,134 +55,112 @@ enum Events
|
||||
EVENT_BERSERK = 5, // 300s cd
|
||||
};
|
||||
|
||||
class boss_archavon : public CreatureScript
|
||||
struct boss_archavon : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_archavon() : CreatureScript("boss_archavon") { }
|
||||
boss_archavon(Creature* creature) : BossAI(creature, DATA_ARCHAVON)
|
||||
{
|
||||
}
|
||||
|
||||
struct boss_archavonAI : public BossAI
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ROCK_SHARDS, 15s);
|
||||
events.ScheduleEvent(EVENT_CHOKING_CLOUD, 30s);
|
||||
events.ScheduleEvent(EVENT_STOMP, 45s);
|
||||
events.ScheduleEvent(EVENT_BERSERK, 5min);
|
||||
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
// Below UpdateAI may need review/debug.
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
boss_archavonAI(Creature* creature) : BossAI(creature, DATA_ARCHAVON)
|
||||
switch (eventId)
|
||||
{
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ROCK_SHARDS, 15s);
|
||||
events.ScheduleEvent(EVENT_CHOKING_CLOUD, 30s);
|
||||
events.ScheduleEvent(EVENT_STOMP, 45s);
|
||||
events.ScheduleEvent(EVENT_BERSERK, 5min);
|
||||
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
// Below UpdateAI may need review/debug.
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
case EVENT_ROCK_SHARDS:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
DoCast(target, SPELL_ROCK_SHARDS);
|
||||
events.ScheduleEvent(EVENT_ROCK_SHARDS, 15s);
|
||||
break;
|
||||
case EVENT_CHOKING_CLOUD:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, -10.0f, true))
|
||||
{
|
||||
case EVENT_ROCK_SHARDS:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
DoCast(target, SPELL_ROCK_SHARDS);
|
||||
events.ScheduleEvent(EVENT_ROCK_SHARDS, 15s);
|
||||
break;
|
||||
case EVENT_CHOKING_CLOUD:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, -10.0f, true))
|
||||
{
|
||||
DoCast(target, SPELL_CRUSHING_LEAP, true); //10y~80y, ignore range
|
||||
Talk(EMOTE_LEAP, target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHOKING_CLOUD, 30s);
|
||||
break;
|
||||
case EVENT_STOMP:
|
||||
DoCastVictim(SPELL_STOMP);
|
||||
events.ScheduleEvent(EVENT_IMPALE, 3s);
|
||||
events.ScheduleEvent(EVENT_STOMP, 45s);
|
||||
break;
|
||||
case EVENT_IMPALE:
|
||||
DoCastVictim(SPELL_IMPALE);
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
Talk(EMOTE_BERSERK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
DoCast(target, SPELL_CRUSHING_LEAP, true); //10y~80y, ignore range
|
||||
Talk(EMOTE_LEAP, target);
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
events.ScheduleEvent(EVENT_CHOKING_CLOUD, 30s);
|
||||
break;
|
||||
case EVENT_STOMP:
|
||||
DoCastVictim(SPELL_STOMP);
|
||||
events.ScheduleEvent(EVENT_IMPALE, 3s);
|
||||
events.ScheduleEvent(EVENT_STOMP, 45s);
|
||||
break;
|
||||
case EVENT_IMPALE:
|
||||
DoCastVictim(SPELL_IMPALE);
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
Talk(EMOTE_BERSERK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetVaultOfArchavonAI<boss_archavonAI>(creature);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
// 58941 - Rock Shards
|
||||
class spell_archavon_rock_shards : public SpellScriptLoader
|
||||
class spell_archavon_rock_shards : public SpellScript
|
||||
{
|
||||
public:
|
||||
spell_archavon_rock_shards() : SpellScriptLoader("spell_archavon_rock_shards") { }
|
||||
PrepareSpellScript(spell_archavon_rock_shards);
|
||||
|
||||
class spell_archavon_rock_shards_SpellScript : public SpellScript
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo(
|
||||
{
|
||||
PrepareSpellScript(spell_archavon_rock_shards_SpellScript);
|
||||
SPELL_ROCK_SHARDS_VISUAL_L,
|
||||
SPELL_ROCK_SHARDS_VISUAL_R,
|
||||
SPELL_ROCK_SHARDS_DAMAGE_L,
|
||||
SPELL_ROCK_SHARDS_DAMAGE_R
|
||||
});
|
||||
}
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo(
|
||||
{
|
||||
SPELL_ROCK_SHARDS_VISUAL_L,
|
||||
SPELL_ROCK_SHARDS_VISUAL_R,
|
||||
SPELL_ROCK_SHARDS_DAMAGE_L,
|
||||
SPELL_ROCK_SHARDS_DAMAGE_R
|
||||
});
|
||||
}
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_VISUAL_L, true);
|
||||
caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_VISUAL_R, true);
|
||||
}
|
||||
|
||||
caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_DAMAGE_L, true);
|
||||
caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_DAMAGE_R, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHit += SpellEffectFn(spell_archavon_rock_shards_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
return new spell_archavon_rock_shards_SpellScript();
|
||||
caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_VISUAL_L, true);
|
||||
caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_VISUAL_R, true);
|
||||
}
|
||||
|
||||
caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_DAMAGE_L, true);
|
||||
caster->CastSpell(nullptr, SPELL_ROCK_SHARDS_DAMAGE_R, true);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHit += SpellEffectFn(spell_archavon_rock_shards::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_archavon()
|
||||
{
|
||||
new boss_archavon();
|
||||
new spell_archavon_rock_shards();
|
||||
RegisterVaultOfArchavonCreatureAI(boss_archavon);
|
||||
RegisterSpellScript(spell_archavon_rock_shards);
|
||||
}
|
||||
|
||||
@@ -68,223 +68,195 @@ Position const TempestMinions[MAX_TEMPEST_MINIONS] =
|
||||
{-203.842529f, -297.097015f, 91.745163f, 1.598807f}
|
||||
};
|
||||
|
||||
/*######
|
||||
## Emalon the Storm Watcher
|
||||
######*/
|
||||
class boss_emalon : public CreatureScript
|
||||
struct boss_emalon : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_emalon() : CreatureScript("boss_emalon") { }
|
||||
boss_emalon(Creature* creature) : BossAI(creature, DATA_EMALON)
|
||||
{
|
||||
}
|
||||
|
||||
struct boss_emalonAI : public BossAI
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
|
||||
for (uint8 i = 0; i < MAX_TEMPEST_MINIONS; ++i)
|
||||
me->SummonCreature(NPC_TEMPEST_MINION, TempestMinions[i], TEMPSUMMON_CORPSE_DESPAWN);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
BossAI::JustSummoned(summoned);
|
||||
|
||||
// AttackStart has nullptr-check for victim
|
||||
if (summoned->AI())
|
||||
summoned->AI()->AttackStart(me->GetVictim());
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
if (!summons.empty())
|
||||
{
|
||||
boss_emalonAI(Creature* creature) : BossAI(creature, DATA_EMALON)
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
{
|
||||
Creature* minion = ObjectAccessor::GetCreature(*me, *itr);
|
||||
if (minion && minion->IsAlive() && !minion->GetVictim() && minion->AI())
|
||||
minion->AI()->AttackStart(who);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
|
||||
for (uint8 i = 0; i < MAX_TEMPEST_MINIONS; ++i)
|
||||
me->SummonCreature(NPC_TEMPEST_MINION, TempestMinions[i], TEMPSUMMON_CORPSE_DESPAWN);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
BossAI::JustSummoned(summoned);
|
||||
|
||||
// AttackStart has nullptr-check for victim
|
||||
if (summoned->AI())
|
||||
summoned->AI()->AttackStart(me->GetVictim());
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
if (!summons.empty())
|
||||
{
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
{
|
||||
Creature* minion = ObjectAccessor::GetCreature(*me, *itr);
|
||||
if (minion && minion->IsAlive() && !minion->GetVictim() && minion->AI())
|
||||
minion->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 5s);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40s);
|
||||
events.ScheduleEvent(EVENT_BERSERK, 6min);
|
||||
events.ScheduleEvent(EVENT_OVERCHARGE, 45s);
|
||||
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CHAIN_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
DoCast(target, SPELL_CHAIN_LIGHTNING);
|
||||
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 25s);
|
||||
break;
|
||||
case EVENT_LIGHTNING_NOVA:
|
||||
DoCastAOE(SPELL_LIGHTNING_NOVA);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40s);
|
||||
break;
|
||||
case EVENT_OVERCHARGE:
|
||||
if (!summons.empty())
|
||||
{
|
||||
Creature* minion = ObjectAccessor::GetCreature(*me, Trinity::Containers::SelectRandomContainerElement(summons));
|
||||
if (minion && minion->IsAlive())
|
||||
{
|
||||
minion->CastSpell(me, SPELL_OVERCHARGED, true);
|
||||
minion->SetFullHealth();
|
||||
Talk(EMOTE_OVERCHARGE);
|
||||
events.ScheduleEvent(EVENT_OVERCHARGE, 45s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
Talk(EMOTE_BERSERK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetVaultOfArchavonAI<boss_emalonAI>(creature);
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 5s);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40s);
|
||||
events.ScheduleEvent(EVENT_BERSERK, 6min);
|
||||
events.ScheduleEvent(EVENT_OVERCHARGE, 45s);
|
||||
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CHAIN_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
DoCast(target, SPELL_CHAIN_LIGHTNING);
|
||||
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 25s);
|
||||
break;
|
||||
case EVENT_LIGHTNING_NOVA:
|
||||
DoCastAOE(SPELL_LIGHTNING_NOVA);
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 40s);
|
||||
break;
|
||||
case EVENT_OVERCHARGE:
|
||||
if (!summons.empty())
|
||||
{
|
||||
Creature* minion = ObjectAccessor::GetCreature(*me, Trinity::Containers::SelectRandomContainerElement(summons));
|
||||
if (minion && minion->IsAlive())
|
||||
{
|
||||
minion->CastSpell(me, SPELL_OVERCHARGED, true);
|
||||
minion->SetFullHealth();
|
||||
Talk(EMOTE_OVERCHARGE);
|
||||
events.ScheduleEvent(EVENT_OVERCHARGE, 45s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EVENT_BERSERK:
|
||||
DoCast(me, SPELL_BERSERK);
|
||||
Talk(EMOTE_BERSERK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## Tempest Minion
|
||||
######*/
|
||||
class npc_tempest_minion : public CreatureScript
|
||||
struct npc_tempest_minion : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_tempest_minion() : CreatureScript("npc_tempest_minion") { }
|
||||
npc_tempest_minion(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
struct npc_tempest_minionAI : public ScriptedAI
|
||||
void Initialize()
|
||||
{
|
||||
OverchargedTimer = 0;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* emalon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EMALON)))
|
||||
{
|
||||
npc_tempest_minionAI(Creature* creature) : ScriptedAI(creature)
|
||||
if (emalon->IsAlive())
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
emalon->SummonCreature(NPC_TEMPEST_MINION, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
Talk(EMOTE_MINION_RESPAWN);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
OverchargedTimer = 0;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* emalon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EMALON)))
|
||||
{
|
||||
if (emalon->IsAlive())
|
||||
{
|
||||
emalon->SummonCreature(NPC_TEMPEST_MINION, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
Talk(EMOTE_MINION_RESPAWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
DoZoneInCombat();
|
||||
events.ScheduleEvent(EVENT_SHOCK, 20s);
|
||||
|
||||
if (Creature* pEmalon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EMALON)))
|
||||
{
|
||||
if (!pEmalon->GetVictim() && pEmalon->AI())
|
||||
pEmalon->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (Aura const* overchargedAura = me->GetAura(SPELL_OVERCHARGED))
|
||||
{
|
||||
if (overchargedAura->GetStackAmount() < 10)
|
||||
{
|
||||
if (OverchargedTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_OVERCHARGED);
|
||||
OverchargedTimer = 2000; // ms
|
||||
}
|
||||
else
|
||||
OverchargedTimer -= diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (overchargedAura->GetStackAmount() == 10)
|
||||
{
|
||||
DoCast(me, SPELL_OVERCHARGED_BLAST);
|
||||
me->DespawnOrUnsummon();
|
||||
Talk(EMOTE_MINION_RESPAWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (events.ExecuteEvent() == EVENT_SHOCK)
|
||||
{
|
||||
DoCastVictim(SPELL_SHOCK);
|
||||
events.ScheduleEvent(EVENT_SHOCK, 20s);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
uint32 OverchargedTimer;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetVaultOfArchavonAI<npc_tempest_minionAI>(creature);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
DoZoneInCombat();
|
||||
events.ScheduleEvent(EVENT_SHOCK, 20s);
|
||||
|
||||
if (Creature* pEmalon = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EMALON)))
|
||||
{
|
||||
if (!pEmalon->GetVictim() && pEmalon->AI())
|
||||
pEmalon->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
if (Aura const* overchargedAura = me->GetAura(SPELL_OVERCHARGED))
|
||||
{
|
||||
if (overchargedAura->GetStackAmount() < 10)
|
||||
{
|
||||
if (OverchargedTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_OVERCHARGED);
|
||||
OverchargedTimer = 2000; // ms
|
||||
}
|
||||
else
|
||||
OverchargedTimer -= diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (overchargedAura->GetStackAmount() == 10)
|
||||
{
|
||||
DoCast(me, SPELL_OVERCHARGED_BLAST);
|
||||
me->DespawnOrUnsummon();
|
||||
Talk(EMOTE_MINION_RESPAWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (events.ExecuteEvent() == EVENT_SHOCK)
|
||||
{
|
||||
DoCastVictim(SPELL_SHOCK);
|
||||
events.ScheduleEvent(EVENT_SHOCK, 20s);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
uint32 OverchargedTimer;
|
||||
};
|
||||
|
||||
void AddSC_boss_emalon()
|
||||
{
|
||||
new boss_emalon();
|
||||
new npc_tempest_minion();
|
||||
RegisterVaultOfArchavonCreatureAI(boss_emalon);
|
||||
RegisterVaultOfArchavonCreatureAI(npc_tempest_minion);
|
||||
}
|
||||
|
||||
@@ -43,188 +43,144 @@ enum Spells
|
||||
SPELL_FW_METEOR_FISTS_DAMAGE = 66809
|
||||
};
|
||||
|
||||
class boss_koralon : public CreatureScript
|
||||
struct boss_koralon : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_koralon() : CreatureScript("boss_koralon") { }
|
||||
boss_koralon(Creature* creature) : BossAI(creature, DATA_KORALON)
|
||||
{
|
||||
}
|
||||
|
||||
struct boss_koralonAI : public BossAI
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
DoCast(me, SPELL_BURNING_FURY);
|
||||
|
||||
events.ScheduleEvent(EVENT_BURNING_FURY, 20s); /// @todo check timer
|
||||
events.ScheduleEvent(EVENT_BURNING_BREATH, 15s); // 1st after 15sec, then every 45sec
|
||||
events.ScheduleEvent(EVENT_METEOR_FISTS, 75s); // 1st after 75sec, then every 45sec
|
||||
events.ScheduleEvent(EVENT_FLAME_CINDER, 30s); /// @todo check timer
|
||||
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
boss_koralonAI(Creature* creature) : BossAI(creature, DATA_KORALON)
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BURNING_FURY:
|
||||
DoCast(me, SPELL_BURNING_FURY);
|
||||
events.ScheduleEvent(EVENT_BURNING_FURY, 20s);
|
||||
break;
|
||||
case EVENT_BURNING_BREATH:
|
||||
DoCast(me, SPELL_BURNING_BREATH);
|
||||
events.ScheduleEvent(EVENT_BURNING_BREATH, 45s);
|
||||
break;
|
||||
case EVENT_METEOR_FISTS:
|
||||
DoCast(me, SPELL_METEOR_FISTS);
|
||||
events.ScheduleEvent(EVENT_METEOR_FISTS, 45s);
|
||||
break;
|
||||
case EVENT_FLAME_CINDER:
|
||||
DoCast(me, SPELL_FLAME_CINDER_A);
|
||||
events.ScheduleEvent(EVENT_FLAME_CINDER, 30s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
DoCast(me, SPELL_BURNING_FURY);
|
||||
|
||||
events.ScheduleEvent(EVENT_BURNING_FURY, 20s); /// @todo check timer
|
||||
events.ScheduleEvent(EVENT_BURNING_BREATH, 15s); // 1st after 15sec, then every 45sec
|
||||
events.ScheduleEvent(EVENT_METEOR_FISTS, 75s); // 1st after 75sec, then every 45sec
|
||||
events.ScheduleEvent(EVENT_FLAME_CINDER, 30s); /// @todo check timer
|
||||
|
||||
BossAI::JustEngagedWith(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BURNING_FURY:
|
||||
DoCast(me, SPELL_BURNING_FURY);
|
||||
events.ScheduleEvent(EVENT_BURNING_FURY, 20s);
|
||||
break;
|
||||
case EVENT_BURNING_BREATH:
|
||||
DoCast(me, SPELL_BURNING_BREATH);
|
||||
events.ScheduleEvent(EVENT_BURNING_BREATH, 45s);
|
||||
break;
|
||||
case EVENT_METEOR_FISTS:
|
||||
DoCast(me, SPELL_METEOR_FISTS);
|
||||
events.ScheduleEvent(EVENT_METEOR_FISTS, 45s);
|
||||
break;
|
||||
case EVENT_FLAME_CINDER:
|
||||
DoCast(me, SPELL_FLAME_CINDER_A);
|
||||
events.ScheduleEvent(EVENT_FLAME_CINDER, 30s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetVaultOfArchavonAI<boss_koralonAI>(creature);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_koralon_meteor_fists : public SpellScriptLoader
|
||||
class spell_koralon_meteor_fists : public AuraScript
|
||||
{
|
||||
public:
|
||||
spell_koralon_meteor_fists() : SpellScriptLoader("spell_koralon_meteor_fists") { }
|
||||
PrepareAuraScript(spell_koralon_meteor_fists);
|
||||
|
||||
class spell_koralon_meteor_fists_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_koralon_meteor_fists_AuraScript);
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_METEOR_FISTS_DAMAGE });
|
||||
}
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_METEOR_FISTS_DAMAGE });
|
||||
}
|
||||
void TriggerFists(AuraEffect* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_METEOR_FISTS_DAMAGE, aurEff);
|
||||
}
|
||||
|
||||
void TriggerFists(AuraEffect* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_METEOR_FISTS_DAMAGE, aurEff);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectProc += AuraEffectProcFn(spell_koralon_meteor_fists_AuraScript::TriggerFists, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_koralon_meteor_fists_AuraScript();
|
||||
}
|
||||
void Register() override
|
||||
{
|
||||
OnEffectProc += AuraEffectProcFn(spell_koralon_meteor_fists::TriggerFists, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_koralon_meteor_fists_damage : public SpellScriptLoader
|
||||
class spell_koralon_meteor_fists_damage : public SpellScript
|
||||
{
|
||||
public:
|
||||
spell_koralon_meteor_fists_damage() : SpellScriptLoader("spell_koralon_meteor_fists_damage") { }
|
||||
PrepareSpellScript(spell_koralon_meteor_fists_damage);
|
||||
|
||||
class spell_koralon_meteor_fists_damage_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_koralon_meteor_fists_damage_SpellScript);
|
||||
public:
|
||||
spell_koralon_meteor_fists_damage()
|
||||
{
|
||||
_chainTargets = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
spell_koralon_meteor_fists_damage_SpellScript()
|
||||
{
|
||||
_chainTargets = 0;
|
||||
}
|
||||
private:
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
_chainTargets = uint8(targets.size());
|
||||
}
|
||||
|
||||
private:
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
_chainTargets = uint8(targets.size());
|
||||
}
|
||||
void CalculateSplitDamage()
|
||||
{
|
||||
if (_chainTargets)
|
||||
SetHitDamage(GetHitDamage() / (_chainTargets + 1));
|
||||
}
|
||||
|
||||
void CalculateSplitDamage()
|
||||
{
|
||||
if (_chainTargets)
|
||||
SetHitDamage(GetHitDamage() / (_chainTargets + 1));
|
||||
}
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_koralon_meteor_fists_damage::FilterTargets, EFFECT_0, TARGET_UNIT_TARGET_ENEMY);
|
||||
OnHit += SpellHitFn(spell_koralon_meteor_fists_damage::CalculateSplitDamage);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_koralon_meteor_fists_damage_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_TARGET_ENEMY);
|
||||
OnHit += SpellHitFn(spell_koralon_meteor_fists_damage_SpellScript::CalculateSplitDamage);
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _chainTargets;
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_koralon_meteor_fists_damage_SpellScript();
|
||||
}
|
||||
private:
|
||||
uint8 _chainTargets;
|
||||
};
|
||||
|
||||
class spell_flame_warder_meteor_fists : public SpellScriptLoader
|
||||
class spell_flame_warder_meteor_fists : public AuraScript
|
||||
{
|
||||
public:
|
||||
spell_flame_warder_meteor_fists() : SpellScriptLoader("spell_flame_warder_meteor_fists") { }
|
||||
PrepareAuraScript(spell_flame_warder_meteor_fists);
|
||||
|
||||
class spell_flame_warder_meteor_fists_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_flame_warder_meteor_fists_AuraScript);
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_FW_METEOR_FISTS_DAMAGE });
|
||||
}
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_FW_METEOR_FISTS_DAMAGE });
|
||||
}
|
||||
void TriggerFists(AuraEffect* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_FW_METEOR_FISTS_DAMAGE, aurEff);
|
||||
}
|
||||
|
||||
void TriggerFists(AuraEffect* aurEff, ProcEventInfo& eventInfo)
|
||||
{
|
||||
PreventDefaultAction();
|
||||
GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_FW_METEOR_FISTS_DAMAGE, aurEff);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectProc += AuraEffectProcFn(spell_flame_warder_meteor_fists_AuraScript::TriggerFists, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const override
|
||||
{
|
||||
return new spell_flame_warder_meteor_fists_AuraScript();
|
||||
}
|
||||
void Register() override
|
||||
{
|
||||
OnEffectProc += AuraEffectProcFn(spell_flame_warder_meteor_fists::TriggerFists, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_koralon()
|
||||
{
|
||||
new boss_koralon();
|
||||
new spell_koralon_meteor_fists();
|
||||
new spell_koralon_meteor_fists_damage();
|
||||
new spell_flame_warder_meteor_fists();
|
||||
RegisterVaultOfArchavonCreatureAI(boss_koralon);
|
||||
RegisterSpellScript(spell_koralon_meteor_fists);
|
||||
RegisterSpellScript(spell_koralon_meteor_fists_damage);
|
||||
RegisterSpellScript(spell_flame_warder_meteor_fists);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user