mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-16 10:30:27 +00:00
refactor(Scripts/MagistersTerrace): Update scripts to new register model (#17725)
This commit is contained in:
@@ -76,259 +76,237 @@ enum Misc
|
||||
CREATURE_ARCANE_SPHERE = 24708
|
||||
};
|
||||
|
||||
class boss_felblood_kaelthas : public CreatureScript
|
||||
struct boss_felblood_kaelthas : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
boss_felblood_kaelthas() : CreatureScript("boss_felblood_kaelthas") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_felblood_kaelthas(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
{
|
||||
return GetMagistersTerraceAI<boss_felblood_kaelthasAI>(creature);
|
||||
instance = creature->GetInstanceScript();
|
||||
introSpeak = false;
|
||||
}
|
||||
|
||||
struct boss_felblood_kaelthasAI : public ScriptedAI
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
EventMap events2;
|
||||
SummonList summons;
|
||||
bool introSpeak;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
boss_felblood_kaelthasAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false);
|
||||
instance->SetBossState(DATA_KAELTHAS, NOT_STARTED);
|
||||
me->SetImmuneToAll(false);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (*itr == summon->GetGUID())
|
||||
return;
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
ScriptedAI::InitializeAI();
|
||||
me->SetImmuneToAll(true);
|
||||
}
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
instance->SetBossState(DATA_KAELTHAS, DONE);
|
||||
|
||||
if (GameObject* orb = instance->GetGameObject(DATA_ESCAPE_ORB))
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
introSpeak = false;
|
||||
orb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
instance->SetBossState(DATA_KAELTHAS, IN_PROGRESS);
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL, 0);
|
||||
events.ScheduleEvent(EVENT_SPELL_PHOENIX, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 22000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_SHOCK_BARRIER, 50000);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!introSpeak && me->IsWithinDistInMap(who, 40.0f) && who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
introSpeak = true;
|
||||
events2.ScheduleEvent(EVENT_INIT_COMBAT, 35000);
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
EventMap events2;
|
||||
SummonList summons;
|
||||
bool introSpeak;
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false);
|
||||
instance->SetBossState(DATA_KAELTHAS, NOT_STARTED);
|
||||
damage = me->GetHealth() - 1;
|
||||
if (me->isRegeneratingHealth())
|
||||
{
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetImmuneToAll(true);
|
||||
me->CombatStop();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
LapseAction(ACTION_REMOVE_FLY);
|
||||
events.Reset();
|
||||
events2.ScheduleEvent(EVENT_FINISH_TALK, 6000);
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LapseAction(uint8 action)
|
||||
{
|
||||
uint8 counter = 0;
|
||||
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr, ++counter)
|
||||
if (Player* player = itr->GetSource())
|
||||
{
|
||||
if (action == ACTION_TELEPORT_PLAYERS)
|
||||
me->CastSpell(player, SPELL_GRAVITY_LAPSE_PLAYER + counter, true);
|
||||
else if (action == ACTION_KNOCKUP)
|
||||
player->CastSpell(player, SPELL_GRAVITY_LAPSE_DOT, true, nullptr, nullptr, me->GetGUID());
|
||||
else if (action == ACTION_ALLOW_FLY)
|
||||
player->CastSpell(player, SPELL_GRAVITY_LAPSE_FLY, true, nullptr, nullptr, me->GetGUID());
|
||||
else if (action == ACTION_REMOVE_FLY)
|
||||
{
|
||||
player->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
|
||||
player->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events2.Update(diff);
|
||||
switch (events2.ExecuteEvent())
|
||||
{
|
||||
case EVENT_INIT_COMBAT:
|
||||
me->SetImmuneToAll(false);
|
||||
if (Unit* target = SelectTargetFromPlayerList(50.0f))
|
||||
AttackStart(target);
|
||||
return;
|
||||
case EVENT_FINISH_TALK:
|
||||
me->KillSelf();
|
||||
return;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (*itr == summon->GetGUID())
|
||||
return;
|
||||
summons.Summon(summon);
|
||||
}
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
ScriptedAI::InitializeAI();
|
||||
me->SetImmuneToAll(true);
|
||||
}
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
void JustDied(Unit*) override
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
instance->SetBossState(DATA_KAELTHAS, DONE);
|
||||
|
||||
if (GameObject* orb = instance->GetGameObject(DATA_ESCAPE_ORB))
|
||||
case EVENT_SPELL_FIREBALL:
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_FIREBALL_N, SPELL_FIREBALL_H), false);
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL, urand(3000, 4500));
|
||||
break;
|
||||
case EVENT_SPELL_FLAMESTRIKE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
|
||||
{
|
||||
orb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
me->CastSpell(target, SPELL_FLAMESTRIKE_SUMMON, true);
|
||||
Talk(SAY_FLAMESTRIKE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
instance->SetBossState(DATA_KAELTHAS, IN_PROGRESS);
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL, 0);
|
||||
events.ScheduleEvent(EVENT_SPELL_PHOENIX, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 22000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_SHOCK_BARRIER, 50000);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!introSpeak && me->IsWithinDistInMap(who, 40.0f) && who->GetTypeId() == TYPEID_PLAYER)
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 25000);
|
||||
break;
|
||||
case EVENT_SPELL_SHOCK_BARRIER:
|
||||
me->CastSpell(me, SPELL_SHOCK_BARRIER, true);
|
||||
me->CastCustomSpell(SPELL_PYROBLAST, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHOCK_BARRIER, 50000);
|
||||
break;
|
||||
case EVENT_SPELL_PHOENIX:
|
||||
Talk(SAY_PHOENIX);
|
||||
me->CastSpell(me, SPELL_PHOENIX, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_PHOENIX, 60000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (HealthBelowPct(50))
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
introSpeak = true;
|
||||
events2.ScheduleEvent(EVENT_INIT_COMBAT, 35000);
|
||||
}
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
|
||||
me->CastSpell(me, SPELL_TELEPORT_CENTER, true);
|
||||
events.Reset();
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
me->StopMoving();
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
|
||||
events.SetPhase(1);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_1_1, 0);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 500);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_1_1:
|
||||
case EVENT_GRAVITY_LAPSE_1_2:
|
||||
Talk(eventId == EVENT_GRAVITY_LAPSE_1_1 ? SAY_GRAVITY_LAPSE : SAY_RECAST_GRAVITY);
|
||||
me->CastSpell(me, SPELL_GRAVITY_LAPSE_INITIAL, false);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_2, 2000);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_2:
|
||||
LapseAction(ACTION_TELEPORT_PLAYERS);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_3, 1000);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_3:
|
||||
LapseAction(ACTION_KNOCKUP);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_4, 1000);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_4:
|
||||
LapseAction(ACTION_ALLOW_FLY);
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
me->CastSpell(me, SPELL_SUMMON_ARCANE_SPHERE, true);
|
||||
|
||||
me->CastSpell(me, SPELL_GRAVITY_LAPSE_CHANNEL, false);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_5, 30000);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_5:
|
||||
LapseAction(ACTION_REMOVE_FLY);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
Talk(SAY_TIRED);
|
||||
me->CastSpell(me, SPELL_POWER_FEEDBACK, false);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_1_2, 10000);
|
||||
break;
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (damage >= me->GetHealth())
|
||||
{
|
||||
damage = me->GetHealth() - 1;
|
||||
if (me->isRegeneratingHealth())
|
||||
{
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetUnitFlag(UNIT_FLAG_DISABLE_MOVE);
|
||||
me->SetImmuneToAll(true);
|
||||
me->CombatStop();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
LapseAction(ACTION_REMOVE_FLY);
|
||||
events.Reset();
|
||||
events2.ScheduleEvent(EVENT_FINISH_TALK, 6000);
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LapseAction(uint8 action)
|
||||
{
|
||||
uint8 counter = 0;
|
||||
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr, ++counter)
|
||||
if (Player* player = itr->GetSource())
|
||||
{
|
||||
if (action == ACTION_TELEPORT_PLAYERS)
|
||||
me->CastSpell(player, SPELL_GRAVITY_LAPSE_PLAYER + counter, true);
|
||||
else if (action == ACTION_KNOCKUP)
|
||||
player->CastSpell(player, SPELL_GRAVITY_LAPSE_DOT, true, nullptr, nullptr, me->GetGUID());
|
||||
else if (action == ACTION_ALLOW_FLY)
|
||||
player->CastSpell(player, SPELL_GRAVITY_LAPSE_FLY, true, nullptr, nullptr, me->GetGUID());
|
||||
else if (action == ACTION_REMOVE_FLY)
|
||||
{
|
||||
player->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
|
||||
player->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events2.Update(diff);
|
||||
switch (events2.ExecuteEvent())
|
||||
{
|
||||
case EVENT_INIT_COMBAT:
|
||||
me->SetImmuneToAll(false);
|
||||
if (Unit* target = SelectTargetFromPlayerList(50.0f))
|
||||
AttackStart(target);
|
||||
return;
|
||||
case EVENT_FINISH_TALK:
|
||||
me->KillSelf();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_FIREBALL:
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_FIREBALL_N, SPELL_FIREBALL_H), false);
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL, urand(3000, 4500));
|
||||
break;
|
||||
case EVENT_SPELL_FLAMESTRIKE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
|
||||
{
|
||||
me->CastSpell(target, SPELL_FLAMESTRIKE_SUMMON, true);
|
||||
Talk(SAY_FLAMESTRIKE);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SPELL_FLAMESTRIKE, 25000);
|
||||
break;
|
||||
case EVENT_SPELL_SHOCK_BARRIER:
|
||||
me->CastSpell(me, SPELL_SHOCK_BARRIER, true);
|
||||
me->CastCustomSpell(SPELL_PYROBLAST, SPELLVALUE_MAX_TARGETS, 1, (Unit*)nullptr, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHOCK_BARRIER, 50000);
|
||||
break;
|
||||
case EVENT_SPELL_PHOENIX:
|
||||
Talk(SAY_PHOENIX);
|
||||
me->CastSpell(me, SPELL_PHOENIX, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_PHOENIX, 60000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (HealthBelowPct(50))
|
||||
{
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
|
||||
me->CastSpell(me, SPELL_TELEPORT_CENTER, true);
|
||||
events.Reset();
|
||||
|
||||
me->StopMoving();
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
|
||||
events.SetPhase(1);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_1_1, 0);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 500);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_1_1:
|
||||
case EVENT_GRAVITY_LAPSE_1_2:
|
||||
Talk(eventId == EVENT_GRAVITY_LAPSE_1_1 ? SAY_GRAVITY_LAPSE : SAY_RECAST_GRAVITY);
|
||||
me->CastSpell(me, SPELL_GRAVITY_LAPSE_INITIAL, false);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_2, 2000);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_2:
|
||||
LapseAction(ACTION_TELEPORT_PLAYERS);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_3, 1000);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_3:
|
||||
LapseAction(ACTION_KNOCKUP);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_4, 1000);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_4:
|
||||
LapseAction(ACTION_ALLOW_FLY);
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
me->CastSpell(me, SPELL_SUMMON_ARCANE_SPHERE, true);
|
||||
|
||||
me->CastSpell(me, SPELL_GRAVITY_LAPSE_CHANNEL, false);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_5, 30000);
|
||||
break;
|
||||
case EVENT_GRAVITY_LAPSE_5:
|
||||
LapseAction(ACTION_REMOVE_FLY);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
Talk(SAY_TIRED);
|
||||
me->CastSpell(me, SPELL_POWER_FEEDBACK, false);
|
||||
events.ScheduleEvent(EVENT_GRAVITY_LAPSE_1_2, 10000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (events.GetPhaseMask() == 0)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
if (events.GetPhaseMask() == 0)
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
class spell_mt_phoenix_burn : public SpellScriptLoader
|
||||
class spell_mt_phoenix_burn : public SpellScript
|
||||
{
|
||||
public:
|
||||
spell_mt_phoenix_burn() : SpellScriptLoader("spell_mt_phoenix_burn") { }
|
||||
PrepareSpellScript(spell_mt_phoenix_burn);
|
||||
|
||||
class spell_mt_phoenix_burn_SpellScript : public SpellScript
|
||||
void HandleAfterCast()
|
||||
{
|
||||
PrepareSpellScript(spell_mt_phoenix_burn_SpellScript);
|
||||
uint32 damage = CalculatePct(GetCaster()->GetMaxHealth(), 5);
|
||||
Unit::DealDamage(GetCaster(), GetCaster(), damage);
|
||||
}
|
||||
|
||||
void HandleAfterCast()
|
||||
{
|
||||
uint32 damage = CalculatePct(GetCaster()->GetMaxHealth(), 5);
|
||||
Unit::DealDamage(GetCaster(), GetCaster(), damage);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterCast += SpellCastFn(spell_mt_phoenix_burn_SpellScript::HandleAfterCast);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
void Register() override
|
||||
{
|
||||
return new spell_mt_phoenix_burn_SpellScript();
|
||||
AfterCast += SpellCastFn(spell_mt_phoenix_burn::HandleAfterCast);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_felblood_kaelthas()
|
||||
{
|
||||
new boss_felblood_kaelthas();
|
||||
new spell_mt_phoenix_burn();
|
||||
RegisterMagistersTerraceCreatureAI(boss_felblood_kaelthas);
|
||||
RegisterSpellScript(spell_mt_phoenix_burn);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,188 +52,177 @@ enum Events
|
||||
EVENT_RESTORE_COMBAT = 6
|
||||
};
|
||||
|
||||
class boss_selin_fireheart : public CreatureScript
|
||||
struct boss_selin_fireheart : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
boss_selin_fireheart() : CreatureScript("boss_selin_fireheart") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_selin_fireheart(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
{
|
||||
return GetMagistersTerraceAI<boss_selin_fireheartAI>(creature);
|
||||
};
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
struct boss_selin_fireheartAI : public ScriptedAI
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
ObjectGuid CrystalGUID;
|
||||
|
||||
bool CanAIAttack(Unit const* who) const override
|
||||
{
|
||||
boss_selin_fireheartAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
return who->GetPositionX() > 216.0f;
|
||||
}
|
||||
|
||||
void SpawnCrystals()
|
||||
{
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 248.053f, 14.592f, 3.74882f, 3.94444f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 225.969f, -20.0775f, -2.9731f, 0.942478f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 226.314f, 20.2183f, -2.98127f, 5.32325f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 247.888f, -14.6252f, 3.80777f, 2.33874f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 263.149f, 0.309245f, 1.32057f, 3.15905f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit*) override
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
if (events.GetPhaseMask() & 0x01)
|
||||
events.ScheduleEvent(EVENT_RESTORE_COMBAT, 0);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
SpawnCrystals();
|
||||
instance->SetBossState(DATA_SELIN_FIREHEART, NOT_STARTED);
|
||||
CrystalGUID.Clear();
|
||||
me->SetPower(POWER_MANA, 0);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SetBossState(DATA_SELIN_FIREHEART, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_LIFE, 2500, 1);
|
||||
events.ScheduleEvent(EVENT_SPELL_FEL_EXPLOSION, 2000);
|
||||
events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 14000);
|
||||
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, 7500, 1);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
instance->SetBossState(DATA_SELIN_FIREHEART, DONE); // Encounter complete!
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void SelectNearestCrystal()
|
||||
{
|
||||
if (summons.empty())
|
||||
return;
|
||||
|
||||
CrystalGUID.Clear();
|
||||
Unit* crystal = nullptr;
|
||||
for (SummonList::const_iterator i = summons.begin(); i != summons.end(); )
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *i++))
|
||||
if (!crystal || me->GetDistanceOrder(summon, crystal, false))
|
||||
crystal = summon;
|
||||
|
||||
if (crystal)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
Talk(SAY_ENERGY);
|
||||
float x, y, z;
|
||||
crystal->GetClosePoint(x, y, z, me->GetObjectSize(), CONTACT_DISTANCE);
|
||||
CrystalGUID = crystal->GetGUID();
|
||||
me->GetMotionMaster()->MovePoint(2, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
ObjectGuid CrystalGUID;
|
||||
|
||||
bool CanAIAttack(Unit const* who) const override
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == 2)
|
||||
{
|
||||
return who->GetPositionX() > 216.0f;
|
||||
}
|
||||
|
||||
void SpawnCrystals()
|
||||
{
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 248.053f, 14.592f, 3.74882f, 3.94444f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 225.969f, -20.0775f, -2.9731f, 0.942478f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 226.314f, 20.2183f, -2.98127f, 5.32325f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 247.888f, -14.6252f, 3.80777f, 2.33874f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
me->SummonCreature(NPC_FEL_CRYSTAL, 263.149f, 0.309245f, 1.32057f, 3.15905f, TEMPSUMMON_CORPSE_DESPAWN);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit*) override
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
if (events.GetPhaseMask() & 0x01)
|
||||
if (Unit* crystal = ObjectAccessor::GetUnit(*me, CrystalGUID))
|
||||
{
|
||||
Talk(EMOTE_CRYSTAL);
|
||||
crystal->ReplaceAllUnitFlags(UNIT_FLAG_NONE);
|
||||
crystal->CastSpell(me, SPELL_MANA_RAGE, true);
|
||||
me->CastSpell(crystal, SPELL_FEL_CRYSTAL_COSMETIC, true);
|
||||
events.SetPhase(1);
|
||||
events.ScheduleEvent(EVENT_EMPOWER, 0, 0, 1);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_RESTORE_COMBAT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
SpawnCrystals();
|
||||
instance->SetBossState(DATA_SELIN_FIREHEART, NOT_STARTED);
|
||||
CrystalGUID.Clear();
|
||||
me->SetPower(POWER_MANA, 0);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SetBossState(DATA_SELIN_FIREHEART, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_LIFE, 2500, 1);
|
||||
case EVENT_SPELL_DRAIN_LIFE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_DRAIN_LIFE_N, SPELL_DRAIN_LIFE_H), false);
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_LIFE, 10000, 1);
|
||||
return;
|
||||
case EVENT_SPELL_DRAIN_MANA:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 40.0f, false)))
|
||||
me->CastSpell(target, SPELL_DRAIN_MANA, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, 10000, 1);
|
||||
return;
|
||||
case EVENT_SPELL_FEL_EXPLOSION:
|
||||
me->RemoveAuraFromStack(SPELL_MANA_RAGE_TRIGGER);
|
||||
me->CastSpell(me, SPELL_FEL_EXPLOSION, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_FEL_EXPLOSION, 2000);
|
||||
events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 14000);
|
||||
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, 7500, 1);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
instance->SetBossState(DATA_SELIN_FIREHEART, DONE); // Encounter complete!
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void SelectNearestCrystal()
|
||||
{
|
||||
if (summons.empty())
|
||||
return;
|
||||
|
||||
CrystalGUID.Clear();
|
||||
Unit* crystal = nullptr;
|
||||
for (SummonList::const_iterator i = summons.begin(); i != summons.end(); )
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *i++))
|
||||
if (!crystal || me->GetDistanceOrder(summon, crystal, false))
|
||||
crystal = summon;
|
||||
|
||||
if (crystal)
|
||||
{
|
||||
Talk(SAY_ENERGY);
|
||||
float x, y, z;
|
||||
crystal->GetClosePoint(x, y, z, me->GetObjectSize(), CONTACT_DISTANCE);
|
||||
CrystalGUID = crystal->GetGUID();
|
||||
me->GetMotionMaster()->MovePoint(2, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == 2)
|
||||
break;
|
||||
case EVENT_DRAIN_CRYSTAL:
|
||||
events.DelayEvents(10001);
|
||||
events.ScheduleEvent(EVENT_EMPOWER, 10000);
|
||||
events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 30000);
|
||||
SelectNearestCrystal();
|
||||
break;
|
||||
case EVENT_EMPOWER:
|
||||
if (me->GetPower(POWER_MANA) == me->GetMaxPower(POWER_MANA))
|
||||
{
|
||||
Talk(SAY_EMPOWERED);
|
||||
if (Unit* crystal = ObjectAccessor::GetUnit(*me, CrystalGUID))
|
||||
{
|
||||
Talk(EMOTE_CRYSTAL);
|
||||
crystal->ReplaceAllUnitFlags(UNIT_FLAG_NONE);
|
||||
crystal->CastSpell(me, SPELL_MANA_RAGE, true);
|
||||
me->CastSpell(crystal, SPELL_FEL_CRYSTAL_COSMETIC, true);
|
||||
events.SetPhase(1);
|
||||
events.ScheduleEvent(EVENT_EMPOWER, 0, 0, 1);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_RESTORE_COMBAT, 0);
|
||||
Unit::Kill(crystal, crystal);
|
||||
events.DelayEvents(10000, 1);
|
||||
events.ScheduleEvent(EVENT_RESTORE_COMBAT, 0);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_EMPOWER, 0, 0, 1);
|
||||
break;
|
||||
case EVENT_RESTORE_COMBAT:
|
||||
events.SetPhase(0);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
break;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_DRAIN_LIFE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_DRAIN_LIFE_N, SPELL_DRAIN_LIFE_H), false);
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_LIFE, 10000, 1);
|
||||
return;
|
||||
case EVENT_SPELL_DRAIN_MANA:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 40.0f, false)))
|
||||
me->CastSpell(target, SPELL_DRAIN_MANA, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_MANA, 10000, 1);
|
||||
return;
|
||||
case EVENT_SPELL_FEL_EXPLOSION:
|
||||
me->RemoveAuraFromStack(SPELL_MANA_RAGE_TRIGGER);
|
||||
me->CastSpell(me, SPELL_FEL_EXPLOSION, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_FEL_EXPLOSION, 2000);
|
||||
break;
|
||||
case EVENT_DRAIN_CRYSTAL:
|
||||
events.DelayEvents(10001);
|
||||
events.ScheduleEvent(EVENT_EMPOWER, 10000);
|
||||
events.ScheduleEvent(EVENT_DRAIN_CRYSTAL, 30000);
|
||||
SelectNearestCrystal();
|
||||
break;
|
||||
case EVENT_EMPOWER:
|
||||
if (me->GetPower(POWER_MANA) == me->GetMaxPower(POWER_MANA))
|
||||
{
|
||||
Talk(SAY_EMPOWERED);
|
||||
if (Unit* crystal = ObjectAccessor::GetUnit(*me, CrystalGUID))
|
||||
Unit::Kill(crystal, crystal);
|
||||
events.DelayEvents(10000, 1);
|
||||
events.ScheduleEvent(EVENT_RESTORE_COMBAT, 0);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_EMPOWER, 0, 0, 1);
|
||||
break;
|
||||
case EVENT_RESTORE_COMBAT:
|
||||
events.SetPhase(0);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_selin_fireheart()
|
||||
{
|
||||
new boss_selin_fireheart();
|
||||
RegisterMagistersTerraceCreatureAI(boss_selin_fireheart);
|
||||
}
|
||||
|
||||
@@ -58,133 +58,122 @@ enum Misc
|
||||
EVENT_HEALTH_CHECK = 3,
|
||||
};
|
||||
|
||||
class boss_vexallus : public CreatureScript
|
||||
struct boss_vexallus : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
boss_vexallus() : CreatureScript("boss_vexallus") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_vexallus(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
{
|
||||
return GetMagistersTerraceAI<boss_vexallusAI>(creature);
|
||||
};
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
struct boss_vexallusAI : public ScriptedAI
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
|
||||
uint8 IntervalHealthAmount;
|
||||
bool Enraged;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
boss_vexallusAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
summons.DespawnAll();
|
||||
IntervalHealthAmount = 1;
|
||||
|
||||
instance->SetBossState(DATA_VEXALLUS, NOT_STARTED);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ENERGY_FEEDBACK);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
instance->SetBossState(DATA_VEXALLUS, DONE);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ENERGY_FEEDBACK);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SetBossState(DATA_VEXALLUS, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 8000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ARCANE_SHOCK, 5000);
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
summon->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f);
|
||||
summon->CastSpell(target, SPELL_ENERGY_FEEDBACK_CHANNEL, false);
|
||||
}
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
void SummonedCreatureDies(Creature* summon, Unit* killer) override
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
summon->DespawnOrUnsummon(1);
|
||||
if (killer)
|
||||
killer->CastSpell(killer, SPELL_ENERGY_FEEDBACK, true, 0, 0, summon->GetGUID());
|
||||
}
|
||||
|
||||
uint8 IntervalHealthAmount;
|
||||
bool Enraged;
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
void Reset() override
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
summons.DespawnAll();
|
||||
IntervalHealthAmount = 1;
|
||||
case EVENT_HEALTH_CHECK:
|
||||
//used for check, when Vexallus cast adds 85%, 70%, 55%, 40%
|
||||
if (!HealthAbovePct(100 - INTERVAL_MODIFIER * IntervalHealthAmount))
|
||||
{
|
||||
if (IntervalHealthAmount++ == INTERVAL_SWITCH)
|
||||
{
|
||||
events.Reset();
|
||||
me->CastSpell(me, SPELL_OVERLOAD, true);
|
||||
return;
|
||||
}
|
||||
|
||||
instance->SetBossState(DATA_VEXALLUS, NOT_STARTED);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ENERGY_FEEDBACK);
|
||||
}
|
||||
Talk(SAY_ENERGY);
|
||||
Talk(EMOTE_DISCHARGE_ENERGY);
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_KILL);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
instance->SetBossState(DATA_VEXALLUS, DONE);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ENERGY_FEEDBACK);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SetBossState(DATA_VEXALLUS, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 8000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ARCANE_SHOCK, 5000);
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
if (IsHeroic())
|
||||
{
|
||||
me->CastSpell(me, SPELL_SUMMON_PURE_ENERGY_H1, false);
|
||||
me->CastSpell(me, SPELL_SUMMON_PURE_ENERGY_H2, false);
|
||||
}
|
||||
else
|
||||
me->CastSpell(me, SPELL_SUMMON_PURE_ENERGY_N, false);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 0);
|
||||
break;
|
||||
case EVENT_SPELL_CHAIN_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
summon->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f);
|
||||
summon->CastSpell(target, SPELL_ENERGY_FEEDBACK_CHANNEL, false);
|
||||
}
|
||||
summons.Summon(summon);
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_CHAIN_LIGHTNING_N, SPELL_CHAIN_LIGHTNING_H), false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 8000);
|
||||
break;
|
||||
case EVENT_SPELL_ARCANE_SHOCK:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 20.0f))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_ARCANE_SHOCK_N, SPELL_ARCANE_SHOCK_H), false);
|
||||
events.ScheduleEvent(EVENT_SPELL_ARCANE_SHOCK, 8000);
|
||||
break;
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit* killer) override
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
summon->DespawnOrUnsummon(1);
|
||||
if (killer)
|
||||
killer->CastSpell(killer, SPELL_ENERGY_FEEDBACK, true, 0, 0, summon->GetGUID());
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_HEALTH_CHECK:
|
||||
//used for check, when Vexallus cast adds 85%, 70%, 55%, 40%
|
||||
if (!HealthAbovePct(100 - INTERVAL_MODIFIER * IntervalHealthAmount))
|
||||
{
|
||||
if (IntervalHealthAmount++ == INTERVAL_SWITCH)
|
||||
{
|
||||
events.Reset();
|
||||
me->CastSpell(me, SPELL_OVERLOAD, true);
|
||||
return;
|
||||
}
|
||||
|
||||
Talk(SAY_ENERGY);
|
||||
Talk(EMOTE_DISCHARGE_ENERGY);
|
||||
|
||||
if (IsHeroic())
|
||||
{
|
||||
me->CastSpell(me, SPELL_SUMMON_PURE_ENERGY_H1, false);
|
||||
me->CastSpell(me, SPELL_SUMMON_PURE_ENERGY_H2, false);
|
||||
}
|
||||
else
|
||||
me->CastSpell(me, SPELL_SUMMON_PURE_ENERGY_N, false);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 0);
|
||||
break;
|
||||
case EVENT_SPELL_CHAIN_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_CHAIN_LIGHTNING_N, SPELL_CHAIN_LIGHTNING_H), false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 8000);
|
||||
break;
|
||||
case EVENT_SPELL_ARCANE_SHOCK:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 20.0f))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_ARCANE_SHOCK_N, SPELL_ARCANE_SHOCK_H), false);
|
||||
events.ScheduleEvent(EVENT_SPELL_ARCANE_SHOCK, 8000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_vexallus()
|
||||
{
|
||||
new boss_vexallus();
|
||||
RegisterMagistersTerraceCreatureAI(boss_vexallus);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user