chore(Scripts/BlackTemple): Update Akama, Supremus, Gorefiend and Naj… (#17867)

chore(Scripts/BlackTemple): Update Akama, Supremus, Gorefiend and Najentus to new register method
This commit is contained in:
Andrew
2023-11-26 16:35:16 -03:00
committed by GitHub
parent f440a7479f
commit c9b42d6d6c
5 changed files with 760 additions and 948 deletions

View File

@@ -105,4 +105,6 @@ inline AI* GetBlackTempleAI(T* obj)
return GetInstanceAI<AI>(obj, BlackTempleScriptName); return GetInstanceAI<AI>(obj, BlackTempleScriptName);
} }
#define RegisterBlackTempleCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackTempleAI)
#endif // BLACK_TEMPLE_H_ #endif // BLACK_TEMPLE_H_

View File

@@ -90,541 +90,477 @@ enum Misc
EVENT_AKAMA_SCENE7 = 36 EVENT_AKAMA_SCENE7 = 36
}; };
class boss_shade_of_akama : public CreatureScript struct boss_shade_of_akama : public BossAI
{ {
public: boss_shade_of_akama(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA), summonsChanneler(me), summonsGenerator(me)
boss_shade_of_akama() : CreatureScript("boss_shade_of_akama") { }
struct boss_shade_of_akamaAI : public BossAI
{ {
boss_shade_of_akamaAI(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA), summonsChanneler(me), summonsGenerator(me) events2.ScheduleEvent(EVENT_SHADE_GATHER_NPCS, 1000);
{ }
events2.ScheduleEvent(EVENT_SHADE_GATHER_NPCS, 1000);
}
SummonList summonsChanneler; SummonList summonsChanneler;
SummonList summonsGenerator; SummonList summonsGenerator;
EventMap events2; EventMap events2;
void ChannelersAction(int32 action) void ChannelersAction(int32 action)
{ {
for (SummonList::const_iterator i = summonsChanneler.begin(); i != summonsChanneler.end(); ++i) for (SummonList::const_iterator i = summonsChanneler.begin(); i != summonsChanneler.end(); ++i)
if (Creature* summon = ObjectAccessor::GetCreature(*me, *i)) if (Creature* summon = ObjectAccessor::GetCreature(*me, *i))
{
if (action == ACTION_CHANNELERS_START_CHANNEL)
{ {
if (action == ACTION_CHANNELERS_START_CHANNEL) summon->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL, true);
{ summon->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
summon->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL, true);
summon->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
else if (action == ACTION_START_ENCOUNTER)
{
summon->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
else if (action == ACTION_KILL_CHANNELERS)
{
Unit::Kill(me, summon);
}
} }
} else if (action == ACTION_START_ENCOUNTER)
{
summon->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
else if (action == ACTION_KILL_CHANNELERS)
{
Unit::Kill(me, summon);
}
}
}
void Reset() override void Reset() override
{ {
BossAI::Reset(); BossAI::Reset();
me->SetReactState(REACT_PASSIVE); me->SetReactState(REACT_PASSIVE);
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetImmuneToAll(true); me->SetImmuneToAll(true);
me->SetWalk(true); me->SetWalk(true);
} }
void EnterEvadeMode(EvadeReason why) override void EnterEvadeMode(EvadeReason why) override
{ {
BossAI::EnterEvadeMode(why); BossAI::EnterEvadeMode(why);
summonsGenerator.DoAction(ACTION_DESPAWN_ALL); summonsGenerator.DoAction(ACTION_DESPAWN_ALL);
events2.ScheduleEvent(EVENT_SHADE_RESET_ENCOUNTER, 20000); events2.ScheduleEvent(EVENT_SHADE_RESET_ENCOUNTER, 20000);
me->SetVisible(false); me->SetVisible(false);
ChannelersAction(ACTION_KILL_CHANNELERS); ChannelersAction(ACTION_KILL_CHANNELERS);
} }
void JustDied(Unit* killer) override void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
summonsGenerator.DoAction(ACTION_DESPAWN_ALL);
summonsChanneler.DespawnAll();
me->CastSpell(me, SPELL_SHADE_OF_AKAMA_TRIGGER, true);
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE)))
{ {
BossAI::JustDied(killer); akama->SetHomePosition(*akama);
summonsGenerator.DoAction(ACTION_DESPAWN_ALL); akama->AI()->DoAction(ACTION_SHADE_DIED);
summonsChanneler.DespawnAll(); }
me->CastSpell(me, SPELL_SHADE_OF_AKAMA_TRIGGER, true); }
void DoAction(int32 param) override
{
if (param == ACTION_START_ENCOUNTER)
{
summonsGenerator.DoAction(ACTION_START_ENCOUNTER);
ChannelersAction(ACTION_START_ENCOUNTER);
events.ScheduleEvent(EVENT_SHADE_CHECK_DISTANCE, 1000);
}
else if (param == ACTION_AKAMA_DIED)
{
EnterEvadeMode(EVADE_REASON_OTHER);
}
}
void UpdateAI(uint32 diff) override
{
events2.Update(diff);
switch (events2.ExecuteEvent())
{
case EVENT_SHADE_GATHER_NPCS:
{
std::list<Creature*> ChannelerList;
me->GetCreaturesWithEntryInRange(ChannelerList, 100.0f, NPC_ASHTONGUE_CHANNELER);
for (std::list<Creature*>::const_iterator itr = ChannelerList.begin(); itr != ChannelerList.end(); ++itr)
summonsChanneler.Summon(*itr);
std::list<Creature*> SpawnerList;
me->GetCreaturesWithEntryInRange(SpawnerList, 100.0f, NPC_CREATURE_GENERATOR_AKAMA);
for (std::list<Creature*>::const_iterator itr = SpawnerList.begin(); itr != SpawnerList.end(); ++itr)
summonsGenerator.Summon(*itr);
summonsChanneler.Respawn();
summonsGenerator.Respawn();
ChannelersAction(ACTION_CHANNELERS_START_CHANNEL);
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE))) if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE)))
{ akama->Respawn(true);
akama->SetHomePosition(*akama); break;
akama->AI()->DoAction(ACTION_SHADE_DIED); }
} case EVENT_SHADE_RESET_ENCOUNTER:
me->SetVisible(true);
summonsGenerator.Respawn();
summonsChanneler.Respawn();
ChannelersAction(ACTION_CHANNELERS_START_CHANNEL);
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE)))
akama->Respawn(true);
break;
} }
void JustEngagedWith(Unit* who) override if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{ {
BossAI::JustEngagedWith(who); case EVENT_SHADE_CHECK_DISTANCE:
} if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
void DoAction(int32 param) override
{
if (param == ACTION_START_ENCOUNTER)
{ {
summonsGenerator.DoAction(ACTION_START_ENCOUNTER); int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED);
ChannelersAction(ACTION_START_ENCOUNTER); if (slow > -100)
events.ScheduleEvent(EVENT_SHADE_CHECK_DISTANCE, 1000); {
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_START, 510.0f, 400.7993f, 112.7837f);
}
} }
else if (param == ACTION_AKAMA_DIED) else
{ {
EnterEvadeMode(EVADE_REASON_OTHER); int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED);
} if (slow < -100)
} me->GetMotionMaster()->Clear();
else if (slow == 0)
void UpdateAI(uint32 diff) override {
{ summonsGenerator.DoAction(ACTION_NO_SORCERERS);
events2.Update(diff); me->SetWalk(false);
switch (events2.ExecuteEvent()) }
{
case EVENT_SHADE_GATHER_NPCS:
{
std::list<Creature*> ChannelerList;
me->GetCreaturesWithEntryInRange(ChannelerList, 100.0f, NPC_ASHTONGUE_CHANNELER);
for (std::list<Creature*>::const_iterator itr = ChannelerList.begin(); itr != ChannelerList.end(); ++itr)
summonsChanneler.Summon(*itr);
std::list<Creature*> SpawnerList;
me->GetCreaturesWithEntryInRange(SpawnerList, 100.0f, NPC_CREATURE_GENERATOR_AKAMA);
for (std::list<Creature*>::const_iterator itr = SpawnerList.begin(); itr != SpawnerList.end(); ++itr)
summonsGenerator.Summon(*itr);
summonsChanneler.Respawn();
summonsGenerator.Respawn();
ChannelersAction(ACTION_CHANNELERS_START_CHANNEL);
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE)))
akama->Respawn(true);
break;
}
case EVENT_SHADE_RESET_ENCOUNTER:
me->SetVisible(true);
summonsGenerator.Respawn();
summonsChanneler.Respawn();
ChannelersAction(ACTION_CHANNELERS_START_CHANNEL);
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE)))
akama->Respawn(true);
break;
} }
if (!UpdateVictim()) if (me->IsWithinMeleeRange(me->GetVictim()))
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{ {
case EVENT_SHADE_CHECK_DISTANCE: me->SetReactState(REACT_AGGRESSIVE);
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE) DoResetThreatList();
{ me->GetVictim()->InterruptNonMeleeSpells(false);
int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED); me->AddThreat(me->GetVictim(), 1000000.0f);
if (slow > -100) me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
{ me->SetImmuneToAll(false);
me->SetWalk(true); summonsGenerator.DoAction(ACTION_STOP_SPAWNING);
me->GetMotionMaster()->MovePoint(POINT_START, 510.0f, 400.7993f, 112.7837f); break;
}
}
else
{
int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED);
if (slow < -100)
me->GetMotionMaster()->Clear();
else if (slow == 0)
{
summonsGenerator.DoAction(ACTION_NO_SORCERERS);
me->SetWalk(false);
}
}
if (me->IsWithinMeleeRange(me->GetVictim()))
{
me->SetReactState(REACT_AGGRESSIVE);
DoResetThreatList();
me->GetVictim()->InterruptNonMeleeSpells(false);
me->AddThreat(me->GetVictim(), 1000000.0f);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetImmuneToAll(false);
summonsGenerator.DoAction(ACTION_STOP_SPAWNING);
break;
}
events.ScheduleEvent(EVENT_SHADE_CHECK_DISTANCE, 1000);
break;
} }
events.ScheduleEvent(EVENT_SHADE_CHECK_DISTANCE, 1000);
DoMeleeAttackIfReady(); break;
} }
bool CheckEvadeIfOutOfCombatArea() const override DoMeleeAttackIfReady();
{ }
return !SelectTargetFromPlayerList(120.0f);
}
};
CreatureAI* GetAI(Creature* creature) const override bool CheckEvadeIfOutOfCombatArea() const override
{ {
return GetBlackTempleAI<boss_shade_of_akamaAI>(creature); return !SelectTargetFromPlayerList(120.0f);
} }
}; };
class npc_akama_shade : public CreatureScript struct npc_akama_shade : public ScriptedAI
{ {
public: npc_akama_shade(Creature* creature) : ScriptedAI(creature), summons(me)
npc_akama_shade() : CreatureScript("npc_akama_shade") { }
struct npc_akamaAI : public ScriptedAI
{ {
npc_akamaAI(Creature* creature) : ScriptedAI(creature), summons(me) instance = creature->GetInstanceScript();
}
InstanceScript* instance;
EventMap events;
EventMap events2;
SummonList summons;
void Reset() override
{
if (instance->GetBossState(DATA_SHADE_OF_AKAMA) == DONE)
{ {
instance = creature->GetInstanceScript(); me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
return;
} }
InstanceScript* instance; me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
EventMap events; me->CastSpell(me, SPELL_STEALTH, true);
EventMap events2; events.Reset();
SummonList summons; events2.Reset();
}
void Reset() override void MovementInform(uint32 type, uint32 point) override
{ {
if (instance->GetBossState(DATA_SHADE_OF_AKAMA) == DONE) if (type != POINT_MOTION_TYPE || point != POINT_CHANNEL_SOUL)
{ return;
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
return; me->SetFacingTo(0.0f);
} events2.ScheduleEvent(EVENT_AKAMA_SCENE1, 1000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE2, 16500);
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); events2.ScheduleEvent(EVENT_AKAMA_SCENE3, 17500);
me->CastSpell(me, SPELL_STEALTH, true); events2.ScheduleEvent(EVENT_AKAMA_SCENE4, 27000);
events.Reset(); events2.ScheduleEvent(EVENT_AKAMA_SCENE5, 37000);
events2.Reset(); events2.ScheduleEvent(EVENT_AKAMA_SCENE6, 51000);
} events2.ScheduleEvent(EVENT_AKAMA_SCENE7, 56000);
}
void MovementInform(uint32 type, uint32 point) override
{ void DoAction(int32 param) override
if (type != POINT_MOTION_TYPE || point != POINT_CHANNEL_SOUL) {
return; if (param == ACTION_SHADE_DIED)
events2.ScheduleEvent(EVENT_AKAMA_SCENE0, 1000);
me->SetFacingTo(0.0f); }
events2.ScheduleEvent(EVENT_AKAMA_SCENE1, 1000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE2, 16500); void JustDied(Unit* /*killer*/) override
events2.ScheduleEvent(EVENT_AKAMA_SCENE3, 17500); {
events2.ScheduleEvent(EVENT_AKAMA_SCENE4, 27000); if (Creature* shade = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SHADE_OF_AKAMA)))
events2.ScheduleEvent(EVENT_AKAMA_SCENE5, 37000); shade->AI()->DoAction(ACTION_AKAMA_DIED);
events2.ScheduleEvent(EVENT_AKAMA_SCENE6, 51000); }
events2.ScheduleEvent(EVENT_AKAMA_SCENE7, 56000);
} void JustEngagedWith(Unit* /*who*/) override
{
void DoAction(int32 param) override events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 2000);
{ events.ScheduleEvent(EVENT_SPELL_DESTRUCTIVE_POISON, 5000);
if (param == ACTION_SHADE_DIED) }
events2.ScheduleEvent(EVENT_AKAMA_SCENE0, 1000);
} void JustSummoned(Creature* summon) override
{
void JustDied(Unit* /*killer*/) override float dist = frand(30.0f, 32.0f);
summon->SetWalk(true);
summon->GetMotionMaster()->MovePoint(POINT_START, summon->GetPositionX() + dist * cos(summon->GetOrientation()), summon->GetPositionY() + dist * std::sin(summon->GetOrientation()), summon->GetPositionZ(), false);
summons.Summon(summon);
}
void UpdateAI(uint32 diff) override
{
events2.Update(diff);
switch (events2.ExecuteEvent())
{ {
case EVENT_AKAMA_START_ENCOUNTER:
me->RemoveAura(SPELL_STEALTH);
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_START, 517.4877f, 400.7993f, 112.7837f, false);
events2.ScheduleEvent(EVENT_AKAMA_START_CHANNEL, 11000);
break;
case EVENT_AKAMA_START_CHANNEL:
me->CastSpell(me, SPELL_AKAMA_SOUL_CHANNEL, false);
if (Creature* shade = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SHADE_OF_AKAMA))) if (Creature* shade = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SHADE_OF_AKAMA)))
shade->AI()->DoAction(ACTION_AKAMA_DIED);
}
void JustEngagedWith(Unit* /*who*/) override
{
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 2000);
events.ScheduleEvent(EVENT_SPELL_DESTRUCTIVE_POISON, 5000);
}
void JustSummoned(Creature* summon) override
{
float dist = frand(30.0f, 32.0f);
summon->SetWalk(true);
summon->GetMotionMaster()->MovePoint(POINT_START, summon->GetPositionX() + dist * cos(summon->GetOrientation()), summon->GetPositionY() + dist * std::sin(summon->GetOrientation()), summon->GetPositionZ(), false);
summons.Summon(summon);
}
void UpdateAI(uint32 diff) override
{
events2.Update(diff);
switch (events2.ExecuteEvent())
{ {
case EVENT_AKAMA_START_ENCOUNTER: shade->AI()->AttackStart(me);
me->RemoveAura(SPELL_STEALTH); shade->GetMotionMaster()->Clear();
me->SetWalk(true); shade->AI()->DoAction(ACTION_START_ENCOUNTER);
me->GetMotionMaster()->MovePoint(POINT_START, 517.4877f, 400.7993f, 112.7837f, false);
events2.ScheduleEvent(EVENT_AKAMA_START_CHANNEL, 11000);
break;
case EVENT_AKAMA_START_CHANNEL:
me->CastSpell(me, SPELL_AKAMA_SOUL_CHANNEL, false);
if (Creature* shade = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SHADE_OF_AKAMA)))
{
shade->AI()->AttackStart(me);
shade->GetMotionMaster()->Clear();
shade->AI()->DoAction(ACTION_START_ENCOUNTER);
}
break;
case EVENT_AKAMA_SCENE0:
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_CHANNEL_SOUL, 467.0f, 400.7993f, 118.537f);
break;
case EVENT_AKAMA_SCENE1:
me->CastSpell(me, SPELL_AKAMA_SOUL_RETRIEVE, true);
break;
case EVENT_AKAMA_SCENE2:
Talk(SAY_BROKEN_FREE_0);
break;
case EVENT_AKAMA_SCENE3:
me->SummonCreatureGroup(SUMMON_GROUP_BROKENS);
break;
case EVENT_AKAMA_SCENE4:
Talk(SAY_BROKEN_FREE_1);
break;
case EVENT_AKAMA_SCENE5:
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
if (Creature* broken = ObjectAccessor::GetCreature(*me, *itr))
broken->SetStandState(UNIT_STAND_STATE_KNEEL);
Talk(SAY_BROKEN_FREE_2);
break;
case EVENT_AKAMA_SCENE6:
if (Creature* broken = summons.GetCreatureWithEntry(NPC_ASHTONGUE_BROKEN))
broken->AI()->Talk(SAY_BROKEN_S1);
break;
case EVENT_AKAMA_SCENE7:
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
if (Creature* broken = ObjectAccessor::GetCreature(*me, *itr))
broken->AI()->Talk(SAY_BROKEN_S2);
break;
} }
break;
if (!UpdateVictim()) case EVENT_AKAMA_SCENE0:
return; me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_CHANNEL_SOUL, 467.0f, 400.7993f, 118.537f);
events.Update(diff); break;
if (me->HasUnitState(UNIT_STATE_CASTING)) case EVENT_AKAMA_SCENE1:
return; me->CastSpell(me, SPELL_AKAMA_SOUL_RETRIEVE, true);
break;
switch (events.ExecuteEvent()) case EVENT_AKAMA_SCENE2:
{ Talk(SAY_BROKEN_FREE_0);
case EVENT_SPELL_CHAIN_LIGHTNING: break;
me->CastSpell(me->GetVictim(), SPELL_CHAIN_LIGHTNING, false); case EVENT_AKAMA_SCENE3:
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, urand(10000, 15000)); me->SummonCreatureGroup(SUMMON_GROUP_BROKENS);
break; break;
case EVENT_SPELL_DESTRUCTIVE_POISON: case EVENT_AKAMA_SCENE4:
me->CastSpell(me, SPELL_DESTRUCTIVE_POISON, false); Talk(SAY_BROKEN_FREE_1);
events.ScheduleEvent(EVENT_SPELL_DESTRUCTIVE_POISON, urand(4000, 5000)); break;
break; case EVENT_AKAMA_SCENE5:
} for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
if (Creature* broken = ObjectAccessor::GetCreature(*me, *itr))
DoMeleeAttackIfReady(); broken->SetStandState(UNIT_STAND_STATE_KNEEL);
Talk(SAY_BROKEN_FREE_2);
break;
case EVENT_AKAMA_SCENE6:
if (Creature* broken = summons.GetCreatureWithEntry(NPC_ASHTONGUE_BROKEN))
broken->AI()->Talk(SAY_BROKEN_S1);
break;
case EVENT_AKAMA_SCENE7:
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
if (Creature* broken = ObjectAccessor::GetCreature(*me, *itr))
broken->AI()->Talk(SAY_BROKEN_S2);
break;
} }
void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) override if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{ {
if (action == 0) case EVENT_SPELL_CHAIN_LIGHTNING:
{ me->CastSpell(me->GetVictim(), SPELL_CHAIN_LIGHTNING, false);
CloseGossipMenuFor(player); events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, urand(10000, 15000));
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); break;
events2.ScheduleEvent(EVENT_AKAMA_START_ENCOUNTER, 0); case EVENT_SPELL_DESTRUCTIVE_POISON:
} me->CastSpell(me, SPELL_DESTRUCTIVE_POISON, false);
events.ScheduleEvent(EVENT_SPELL_DESTRUCTIVE_POISON, urand(4000, 5000));
break;
} }
};
CreatureAI* GetAI(Creature* creature) const override DoMeleeAttackIfReady();
}
void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) override
{ {
return GetBlackTempleAI<npc_akamaAI>(creature); if (action == 0)
{
CloseGossipMenuFor(player);
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
events2.ScheduleEvent(EVENT_AKAMA_START_ENCOUNTER, 0);
}
} }
}; };
// ######################################################## struct npc_creature_generator_akama : public NullCreatureAI
// Creature Generator Akama
// ########################################################
class npc_creature_generator_akama : public CreatureScript
{ {
public: npc_creature_generator_akama(Creature* creature) : NullCreatureAI(creature), summons(me)
npc_creature_generator_akama() : CreatureScript("npc_creature_generator_akama") { }
struct npc_creature_generator_akamaAI : public NullCreatureAI
{ {
npc_creature_generator_akamaAI(Creature* creature) : NullCreatureAI(creature), summons(me) instance = creature->GetInstanceScript();
}
void Reset() override
{
events.Reset();
summons.DespawnAll();
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_ASHTONGUE_SORCERER)
{ {
instance = creature->GetInstanceScript(); std::list<Creature*> channelerList;
me->GetCreaturesWithEntryInRange(channelerList, 120.0f, NPC_ASHTONGUE_CHANNELER);
for (std::list<Creature*>::const_iterator itr = channelerList.begin(); itr != channelerList.end(); ++itr)
{
if ((*itr)->IsAlive() || (*itr)->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
continue;
summon->SetInCombatWithZone();
summon->SetReactState(REACT_PASSIVE);
summon->GetMotionMaster()->MovePoint(POINT_START, **itr);
(*itr)->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
return;
}
} }
void Reset() override summon->SetInCombatWithZone();
if (Unit* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE)))
{
summon->AddThreat(akama, 500.0f);
summon->AI()->AttackStart(akama);
}
}
void SummonedCreatureDies(Creature* summon, Unit*) override
{
summon->DespawnOrUnsummon(10000);
summons.Despawn(summon);
}
void DoAction(int32 param) override
{
if (param == ACTION_STOP_SPAWNING || param == ACTION_DESPAWN_ALL)
{ {
events.Reset(); events.Reset();
summons.DespawnAll(); for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_ASHTONGUE_SORCERER)
{ {
std::list<Creature*> channelerList; if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
me->GetCreaturesWithEntryInRange(channelerList, 120.0f, NPC_ASHTONGUE_CHANNELER);
for (std::list<Creature*>::const_iterator itr = channelerList.begin(); itr != channelerList.end(); ++itr)
{ {
if ((*itr)->IsAlive() || (*itr)->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)) if (summon->GetEntry() != NPC_ASHTONGUE_SORCERER)
continue; continue;
summon->InterruptNonMeleeSpells(false);
summon->GetMotionMaster()->Clear();
summon->SetInCombatWithZone(); summon->SetInCombatWithZone();
summon->SetReactState(REACT_PASSIVE);
summon->GetMotionMaster()->MovePoint(POINT_START, **itr);
(*itr)->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
return;
} }
} }
summon->SetInCombatWithZone();
if (Unit* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE)))
{
summon->AddThreat(akama, 500.0f);
summon->AI()->AttackStart(akama);
}
} }
if (param == ACTION_DESPAWN_ALL)
void SummonedCreatureDies(Creature* summon, Unit*) override summons.DespawnAll();
else if (param == ACTION_NO_SORCERERS)
events.CancelEvent(EVENT_SUMMON_ASHTONGUE_SORCERER);
else if (param == ACTION_START_ENCOUNTER)
{ {
summon->DespawnOrUnsummon(10000); events.ScheduleEvent(EVENT_SUMMON_WAVE_B, 5000);
summons.Despawn(summon); events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, 20000);
events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, 35000);
} }
}
void DoAction(int32 param) override void UpdateAI(uint32 diff) override
{
if (param == ACTION_STOP_SPAWNING || param == ACTION_DESPAWN_ALL)
{
events.Reset();
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
{
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
{
if (summon->GetEntry() != NPC_ASHTONGUE_SORCERER)
continue;
summon->InterruptNonMeleeSpells(false);
summon->GetMotionMaster()->Clear();
summon->SetInCombatWithZone();
}
}
}
if (param == ACTION_DESPAWN_ALL)
summons.DespawnAll();
else if (param == ACTION_NO_SORCERERS)
events.CancelEvent(EVENT_SUMMON_ASHTONGUE_SORCERER);
else if (param == ACTION_START_ENCOUNTER)
{
events.ScheduleEvent(EVENT_SUMMON_WAVE_B, 5000);
events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, 20000);
events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, 35000);
}
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_SUMMON_WAVE_B:
me->CastSpell(me, SPELL_ASHTONGUE_WAVE_B, true);
events.ScheduleEvent(EVENT_SUMMON_WAVE_B, 45000);
break;
case EVENT_SUMMON_ASHTONGUE_SORCERER: // left
me->CastSpell(me, SPELL_SUMMON_ASHTONGUE_SORCERER, true);
events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, 45000);
break;
case EVENT_SUMMON_ASHTONGUE_DEFENDER: // right
me->CastSpell(me, SPELL_SUMMON_ASHTONGUE_DEFENDER, true);
events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, 45000);
break;
default:
break;
}
}
private:
EventMap events;
SummonList summons;
InstanceScript* instance;
};
CreatureAI* GetAI(Creature* creature) const override
{ {
return GetBlackTempleAI<npc_creature_generator_akamaAI>(creature); events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_SUMMON_WAVE_B:
me->CastSpell(me, SPELL_ASHTONGUE_WAVE_B, true);
events.ScheduleEvent(EVENT_SUMMON_WAVE_B, 45000);
break;
case EVENT_SUMMON_ASHTONGUE_SORCERER: // left
me->CastSpell(me, SPELL_SUMMON_ASHTONGUE_SORCERER, true);
events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, 45000);
break;
case EVENT_SUMMON_ASHTONGUE_DEFENDER: // right
me->CastSpell(me, SPELL_SUMMON_ASHTONGUE_DEFENDER, true);
events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, 45000);
break;
default:
break;
}
}
private:
EventMap events;
SummonList summons;
InstanceScript* instance;
};
class spell_shade_of_akama_shade_soul_channel : public AuraScript
{
PrepareAuraScript(spell_shade_of_akama_shade_soul_channel);
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* caster = GetCaster())
caster->SetFacingToObject(GetTarget());
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Aura* aura = GetTarget()->GetAura(GetSpellInfo()->Effects[EFFECT_1].TriggerSpell))
aura->ModStackAmount(-1);
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_shade_of_akama_shade_soul_channel::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_shade_of_akama_shade_soul_channel::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
} }
}; };
class spell_shade_of_akama_shade_soul_channel : public SpellScriptLoader class spell_shade_of_akama_akama_soul_expel : public SpellScript
{ {
public: PrepareSpellScript(spell_shade_of_akama_akama_soul_expel);
spell_shade_of_akama_shade_soul_channel() : SpellScriptLoader("spell_shade_of_akama_shade_soul_channel") { }
class spell_shade_of_akama_shade_soul_channel_AuraScript : public AuraScript void SetDest(SpellDestination& dest)
{ {
PrepareAuraScript(spell_shade_of_akama_shade_soul_channel_AuraScript) // Adjust effect summon position
Position const offset = { 0.0f, 0.0f, 25.0f, 0.0f };
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) dest.RelocateOffset(offset);
{
if (Unit* caster = GetCaster())
caster->SetFacingToObject(GetTarget());
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Aura* aura = GetTarget()->GetAura(GetSpellInfo()->Effects[EFFECT_1].TriggerSpell))
aura->ModStackAmount(-1);
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_shade_of_akama_shade_soul_channel_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
AfterEffectRemove += AuraEffectRemoveFn(spell_shade_of_akama_shade_soul_channel_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_shade_of_akama_shade_soul_channel_AuraScript();
} }
};
class spell_shade_of_akama_akama_soul_expel : public SpellScriptLoader void Register() override
{
public:
spell_shade_of_akama_akama_soul_expel() : SpellScriptLoader("spell_shade_of_akama_akama_soul_expel") { }
class spell_shade_of_akama_akama_soul_expel_SpellScript : public SpellScript
{ {
PrepareSpellScript(spell_shade_of_akama_akama_soul_expel_SpellScript); OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_shade_of_akama_akama_soul_expel::SetDest, EFFECT_0, TARGET_DEST_CASTER_RADIUS);
void SetDest(SpellDestination& dest)
{
// Adjust effect summon position
Position const offset = { 0.0f, 0.0f, 25.0f, 0.0f };
dest.RelocateOffset(offset);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_shade_of_akama_akama_soul_expel_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_RADIUS);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_shade_of_akama_akama_soul_expel_SpellScript();
} }
}; };
void AddSC_boss_shade_of_akama() void AddSC_boss_shade_of_akama()
{ {
new boss_shade_of_akama(); RegisterBlackTempleCreatureAI(boss_shade_of_akama);
new npc_akama_shade(); RegisterBlackTempleCreatureAI(npc_akama_shade);
new npc_creature_generator_akama(); RegisterBlackTempleCreatureAI(npc_creature_generator_akama);
new spell_shade_of_akama_shade_soul_channel(); RegisterSpellScript(spell_shade_of_akama_shade_soul_channel);
new spell_shade_of_akama_akama_soul_expel(); RegisterSpellScript(spell_shade_of_akama_akama_soul_expel);
} }

View File

@@ -46,164 +46,141 @@ enum Supremus
EVENT_GROUP_ABILITIES = 1 EVENT_GROUP_ABILITIES = 1
}; };
class boss_supremus : public CreatureScript struct boss_supremus : public BossAI
{ {
public: boss_supremus(Creature* creature) : BossAI(creature, DATA_SUPREMUS) { }
boss_supremus() : CreatureScript("boss_supremus") { }
CreatureAI* GetAI(Creature* creature) const override void JustEngagedWith(Unit* who) override
{ {
return GetBlackTempleAI<boss_supremusAI>(creature); BossAI::JustEngagedWith(who);
SchedulePhase(false);
events.ScheduleEvent(EVENT_SPELL_BERSERK, 900000);
events.ScheduleEvent(EVENT_SPELL_MOLTEN_FLAMES, 4000);
} }
struct boss_supremusAI : public BossAI void SchedulePhase(bool run)
{ {
boss_supremusAI(Creature* creature) : BossAI(creature, DATA_SUPREMUS) events.CancelEventGroup(EVENT_GROUP_ABILITIES);
events.ScheduleEvent(EVENT_SWITCH_PHASE, 60000);
DoResetThreatList();
if (!run)
{ {
events.ScheduleEvent(EVENT_SPELL_HATEFUL_STRIKE, 5000, EVENT_GROUP_ABILITIES);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false);
me->RemoveAurasDueToSpell(SPELL_SNARE_SELF);
}
else
{
events.ScheduleEvent(EVENT_SPELL_VOLCANIC_ERUPTION, 5000, EVENT_GROUP_ABILITIES);
events.ScheduleEvent(EVENT_SWITCH_TARGET, 0, EVENT_GROUP_ABILITIES);
events.ScheduleEvent(EVENT_CHECK_DIST, 0, EVENT_GROUP_ABILITIES);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
me->CastSpell(me, SPELL_SNARE_SELF, true);
}
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_SUPREMUS_PUNCH_STALKER)
{
summon->ToTempSummon()->InitStats(20000);
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true))
summon->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
}
else
summon->CastSpell(summon, SPELL_VOLCANIC_ERUPTION_TRIGGER, true);
}
void SummonedCreatureDespawn(Creature* summon) override
{
summons.Despawn(summon);
}
Unit* FindHatefulStrikeTarget()
{
Unit* target = nullptr;
ThreatContainer::StorageType const& threatlist = me->GetThreatMgr().GetThreatList();
for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i)
{
Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid());
if (unit && me->IsWithinMeleeRange(unit))
if (!target || unit->GetHealth() > target->GetHealth())
target = unit;
} }
void Reset() override return target;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{ {
BossAI::Reset(); case EVENT_SPELL_BERSERK:
} me->CastSpell(me, SPELL_BERSERK, true);
break;
void JustEngagedWith(Unit* who) override case EVENT_SPELL_HATEFUL_STRIKE:
{ if (Unit* target = FindHatefulStrikeTarget())
BossAI::JustEngagedWith(who); me->CastSpell(target, SPELL_HATEFUL_STRIKE, false);
events.ScheduleEvent(EVENT_SPELL_HATEFUL_STRIKE, urand(1500, 3000), EVENT_GROUP_ABILITIES);
SchedulePhase(false); break;
events.ScheduleEvent(EVENT_SPELL_BERSERK, 900000); case EVENT_SPELL_MOLTEN_FLAMES:
events.ScheduleEvent(EVENT_SPELL_MOLTEN_FLAMES, 4000); me->CastSpell(me, SPELL_MOLTEN_PUNCH, false);
} events.ScheduleEvent(EVENT_SPELL_MOLTEN_FLAMES, 20000, EVENT_GROUP_ABILITIES);
break;
void SchedulePhase(bool run) case EVENT_SWITCH_PHASE:
{ SchedulePhase(!me->HasAura(SPELL_SNARE_SELF));
events.CancelEventGroup(EVENT_GROUP_ABILITIES); break;
events.ScheduleEvent(EVENT_SWITCH_PHASE, 60000); case EVENT_SWITCH_TARGET:
DoResetThreatList(); if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
if (!run)
{ {
events.ScheduleEvent(EVENT_SPELL_HATEFUL_STRIKE, 5000, EVENT_GROUP_ABILITIES); DoResetThreatList();
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false); me->AddThreat(target, 5000000.0f);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, false); Talk(EMOTE_NEW_TARGET);
me->RemoveAurasDueToSpell(SPELL_SNARE_SELF);
} }
else events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, EVENT_GROUP_ABILITIES);
break;
case EVENT_CHECK_DIST:
if (me->GetDistance(me->GetVictim()) > 40.0f)
{ {
events.ScheduleEvent(EVENT_SPELL_VOLCANIC_ERUPTION, 5000, EVENT_GROUP_ABILITIES); Talk(EMOTE_PUNCH_GROUND);
events.ScheduleEvent(EVENT_SWITCH_TARGET, 0, EVENT_GROUP_ABILITIES); me->CastSpell(me->GetVictim(), SPELL_CHARGE, true);
events.ScheduleEvent(EVENT_CHECK_DIST, 0, EVENT_GROUP_ABILITIES); events.ScheduleEvent(EVENT_CHECK_DIST, 5000, EVENT_GROUP_ABILITIES);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); break;
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true);
me->CastSpell(me, SPELL_SNARE_SELF, true);
} }
} events.ScheduleEvent(EVENT_CHECK_DIST, 1, EVENT_GROUP_ABILITIES);
break;
void JustDied(Unit* killer) override case EVENT_SPELL_VOLCANIC_ERUPTION:
{ if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
BossAI::JustDied(killer);
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_SUPREMUS_PUNCH_STALKER)
{ {
summon->ToTempSummon()->InitStats(20000); me->CastSpell(target, SPELL_VOLCANIC_ERUPTION, true);
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true)) Talk(EMOTE_GROUND_CRACK);
summon->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f, MOTION_SLOT_CONTROLLED);
} }
else events.ScheduleEvent(EVENT_SPELL_VOLCANIC_ERUPTION, urand(10000, 18000), EVENT_GROUP_ABILITIES);
summon->CastSpell(summon, SPELL_VOLCANIC_ERUPTION_TRIGGER, true); break;
} }
void SummonedCreatureDespawn(Creature* summon) override DoMeleeAttackIfReady();
{ }
summons.Despawn(summon);
}
Unit* FindHatefulStrikeTarget() bool CheckEvadeIfOutOfCombatArea() const override
{ {
Unit* target = nullptr; return me->GetPositionX() < 565 || me->GetPositionX() > 865 || me->GetPositionY() < 545 || me->GetPositionY() > 1000;
ThreatContainer::StorageType const& threatlist = me->GetThreatMgr().GetThreatList(); }
for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i)
{
Unit* unit = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid());
if (unit && me->IsWithinMeleeRange(unit))
if (!target || unit->GetHealth() > target->GetHealth())
target = unit;
}
return target;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_BERSERK:
me->CastSpell(me, SPELL_BERSERK, true);
break;
case EVENT_SPELL_HATEFUL_STRIKE:
if (Unit* target = FindHatefulStrikeTarget())
me->CastSpell(target, SPELL_HATEFUL_STRIKE, false);
events.ScheduleEvent(EVENT_SPELL_HATEFUL_STRIKE, urand(1500, 3000), EVENT_GROUP_ABILITIES);
break;
case EVENT_SPELL_MOLTEN_FLAMES:
me->CastSpell(me, SPELL_MOLTEN_PUNCH, false);
events.ScheduleEvent(EVENT_SPELL_MOLTEN_FLAMES, 20000, EVENT_GROUP_ABILITIES);
break;
case EVENT_SWITCH_PHASE:
SchedulePhase(!me->HasAura(SPELL_SNARE_SELF));
break;
case EVENT_SWITCH_TARGET:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
{
DoResetThreatList();
me->AddThreat(target, 5000000.0f);
Talk(EMOTE_NEW_TARGET);
}
events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, EVENT_GROUP_ABILITIES);
break;
case EVENT_CHECK_DIST:
if (me->GetDistance(me->GetVictim()) > 40.0f)
{
Talk(EMOTE_PUNCH_GROUND);
me->CastSpell(me->GetVictim(), SPELL_CHARGE, true);
events.ScheduleEvent(EVENT_CHECK_DIST, 5000, EVENT_GROUP_ABILITIES);
break;
}
events.ScheduleEvent(EVENT_CHECK_DIST, 1, EVENT_GROUP_ABILITIES);
break;
case EVENT_SPELL_VOLCANIC_ERUPTION:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
{
me->CastSpell(target, SPELL_VOLCANIC_ERUPTION, true);
Talk(EMOTE_GROUND_CRACK);
}
events.ScheduleEvent(EVENT_SPELL_VOLCANIC_ERUPTION, urand(10000, 18000), EVENT_GROUP_ABILITIES);
break;
}
DoMeleeAttackIfReady();
}
bool CheckEvadeIfOutOfCombatArea() const override
{
return me->GetPositionX() < 565 || me->GetPositionX() > 865 || me->GetPositionY() < 545 || me->GetPositionY() > 1000;
}
};
}; };
void AddSC_boss_supremus() void AddSC_boss_supremus()
{ {
new boss_supremus(); RegisterBlackTempleCreatureAI(boss_supremus);
} }

View File

@@ -70,276 +70,213 @@ struct ShadowOfDeathSelector
} }
}; };
class boss_teron_gorefiend : public CreatureScript struct boss_teron_gorefiend : public BossAI
{ {
public: boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND), intro(false) { }
boss_teron_gorefiend() : CreatureScript("boss_teron_gorefiend") { }
CreatureAI* GetAI(Creature* creature) const override bool intro;
void Reset() override
{ {
return GetBlackTempleAI<boss_teron_gorefiendAI>(creature); BossAI::Reset();
me->CastSpell(me, SPELL_SHADOW_OF_DEATH_REMOVE, true);
} }
struct boss_teron_gorefiendAI : public BossAI void SetData(uint32 type, uint32 id) override
{ {
boss_teron_gorefiendAI(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND) if (type || !me->IsAlive())
return;
if (id == SET_DATA_INTRO && !intro)
{ {
intro = false; intro = true;
Talk(SAY_INTRO);
} }
}
bool intro; void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_SPELL_INCINERATE, 24000);
events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 10000);
events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 17000);
events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 20000);
}
void Reset() override void KilledUnit(Unit* /*victim*/) override
{
if (events.GetNextEventTime(EVENT_TALK_KILL) == 0)
{ {
BossAI::Reset(); Talk(SAY_SLAY);
me->CastSpell(me, SPELL_SHADOW_OF_DEATH_REMOVE, true); events.ScheduleEvent(EVENT_TALK_KILL, 6000);
} }
}
void SetData(uint32 type, uint32 id) override void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
}
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
Talk(SAY_DEATH);
me->CastSpell(me, SPELL_SHADOW_OF_DEATH_REMOVE, true);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{ {
if (type || !me->IsAlive()) case EVENT_SPELL_INCINERATE:
return; if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
if (id == SET_DATA_INTRO && !intro)
{ {
intro = true; if (roll_chance_i(50))
Talk(SAY_INTRO); Talk(SAY_INCINERATE);
me->CastSpell(target, SPELL_INCINERATE, false);
} }
events.ScheduleEvent(EVENT_SPELL_INCINERATE, 25000);
break;
case EVENT_SPELL_DOOM_BLOSSOM:
if (roll_chance_i(50))
Talk(SAY_BLOSSOM);
me->CastSpell(me, SPELL_SUMMON_DOOM_BLOSSOM, false);
events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 40000);
break;
case EVENT_SPELL_CRUSHING_SHADOWS:
if (roll_chance_i(20))
Talk(SAY_CRUSHING);
me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me, false);
events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 15000);
break;
case EVENT_SPELL_SHADOW_OF_DEATH:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, ShadowOfDeathSelector()))
me->CastSpell(target, SPELL_SHADOW_OF_DEATH, false);
events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 30000);
break;
} }
void JustEngagedWith(Unit* who) override DoMeleeAttackIfReady();
{ }
BossAI::JustEngagedWith(who);
events.ScheduleEvent(EVENT_SPELL_INCINERATE, 24000);
events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 10000);
events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 17000);
events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 20000);
}
void KilledUnit(Unit* /*victim*/) override
{
if (events.GetNextEventTime(EVENT_TALK_KILL) == 0)
{
Talk(SAY_SLAY);
events.ScheduleEvent(EVENT_TALK_KILL, 6000);
}
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
}
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
Talk(SAY_DEATH);
me->CastSpell(me, SPELL_SHADOW_OF_DEATH_REMOVE, true);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim() )
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_INCINERATE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
if (roll_chance_i(50))
Talk(SAY_INCINERATE);
me->CastSpell(target, SPELL_INCINERATE, false);
}
events.ScheduleEvent(EVENT_SPELL_INCINERATE, 25000);
break;
case EVENT_SPELL_DOOM_BLOSSOM:
if (roll_chance_i(50))
Talk(SAY_BLOSSOM);
me->CastSpell(me, SPELL_SUMMON_DOOM_BLOSSOM, false);
events.ScheduleEvent(EVENT_SPELL_DOOM_BLOSSOM, 40000);
break;
case EVENT_SPELL_CRUSHING_SHADOWS:
if (roll_chance_i(20))
Talk(SAY_CRUSHING);
me->CastCustomSpell(SPELL_CRUSHING_SHADOWS, SPELLVALUE_MAX_TARGETS, 5, me, false);
events.ScheduleEvent(EVENT_SPELL_CRUSHING_SHADOWS, 15000);
break;
case EVENT_SPELL_SHADOW_OF_DEATH:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, ShadowOfDeathSelector()))
me->CastSpell(target, SPELL_SHADOW_OF_DEATH, false);
events.ScheduleEvent(EVENT_SPELL_SHADOW_OF_DEATH, 30000);
break;
}
DoMeleeAttackIfReady();
}
bool CheckEvadeIfOutOfCombatArea() const override
{
return me->GetDistance(me->GetHomePosition()) > 100.0f;
}
};
}; };
class spell_teron_gorefiend_shadow_of_death : public SpellScriptLoader class spell_teron_gorefiend_shadow_of_death : public AuraScript
{ {
public: PrepareAuraScript(spell_teron_gorefiend_shadow_of_death);
spell_teron_gorefiend_shadow_of_death() : SpellScriptLoader("spell_teron_gorefiend_shadow_of_death") { }
class spell_teron_gorefiend_shadow_of_death_AuraScript : public AuraScript void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& /*absorbAmount*/)
{ {
PrepareAuraScript(spell_teron_gorefiend_shadow_of_death_AuraScript) PreventDefaultAction();
}
void Absorb(AuraEffect* /*aurEff*/, DamageInfo& /*dmgInfo*/, uint32& /*absorbAmount*/) void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{ {
PreventDefaultAction(); InstanceScript* instance = GetTarget()->GetInstanceScript();
} if (!GetCaster() || !instance || !instance->IsEncounterInProgress())
return;
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SPIRIT, true);
GetTarget()->CastSpell(GetTarget(), SPELL_POSSESS_SPIRIT_IMMUNE, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SPIRITUAL_VENGEANCE, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SKELETON1, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SKELETON2, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SKELETON3, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SKELETON4, true);
}
void Register() override
{
OnEffectAbsorb += AuraEffectAbsorbFn(spell_teron_gorefiend_shadow_of_death::Absorb, EFFECT_0);
AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_shadow_of_death::HandleEffectRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_teron_gorefiend_spirit_lance : public AuraScript
{
PrepareAuraScript(spell_teron_gorefiend_spirit_lance);
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_2))
amount -= (amount / effect->GetTotalTicks()) * effect->GetTickNumber();
}
void Update(AuraEffect const* /*effect*/)
{
PreventDefaultAction();
if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1))
effect->RecalculateAmount();
}
void Register() override
{
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_teron_gorefiend_spirit_lance::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DECREASE_SPEED);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_teron_gorefiend_spirit_lance::Update, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
class spell_teron_gorefiend_spiritual_vengeance : public AuraScript
{
PrepareAuraScript(spell_teron_gorefiend_spiritual_vengeance);
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
InstanceScript* instance = GetTarget()->GetInstanceScript();
if (!GetCaster() || !instance || !instance->IsEncounterInProgress())
return;
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SPIRIT, true);
GetTarget()->CastSpell(GetTarget(), SPELL_POSSESS_SPIRIT_IMMUNE, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SPIRITUAL_VENGEANCE, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SKELETON1, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SKELETON2, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SKELETON3, true);
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_SKELETON4, true);
}
void Register() override
{
OnEffectAbsorb += AuraEffectAbsorbFn(spell_teron_gorefiend_shadow_of_death_AuraScript::Absorb, EFFECT_0);
AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_shadow_of_death_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{ {
return new spell_teron_gorefiend_shadow_of_death_AuraScript(); Unit::Kill(nullptr, GetTarget());
}
void Register() override
{
AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance::HandleEffectRemove, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL);
} }
}; };
class spell_teron_gorefiend_spirit_lance : public SpellScriptLoader class spell_teron_gorefiend_shadowy_construct : public AuraScript
{ {
public: PrepareAuraScript(spell_teron_gorefiend_shadowy_construct);
spell_teron_gorefiend_spirit_lance() : SpellScriptLoader("spell_teron_gorefiend_spirit_lance") { }
class spell_teron_gorefiend_spirit_lance_AuraScript : public AuraScript bool Load() override
{ {
PrepareAuraScript(spell_teron_gorefiend_spirit_lance_AuraScript); return GetUnitOwner()->GetTypeId() == TYPEID_UNIT;
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
{
if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_2))
amount -= (amount / effect->GetTotalTicks()) * effect->GetTickNumber();
}
void Update(AuraEffect const* /*effect*/)
{
PreventDefaultAction();
if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_1))
effect->RecalculateAmount();
}
void Register() override
{
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_teron_gorefiend_spirit_lance_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DECREASE_SPEED);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_teron_gorefiend_spirit_lance_AuraScript::Update, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_teron_gorefiend_spirit_lance_AuraScript();
} }
};
class spell_teron_gorefiend_spiritual_vengeance : public SpellScriptLoader void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
public:
spell_teron_gorefiend_spiritual_vengeance() : SpellScriptLoader("spell_teron_gorefiend_spiritual_vengeance") { }
class spell_teron_gorefiend_spiritual_vengeance_AuraScript : public AuraScript
{ {
PrepareAuraScript(spell_teron_gorefiend_spiritual_vengeance_AuraScript) GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NORMAL, true);
GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_ALLOW_ID, SPELL_SPIRIT_LANCE, true);
GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_ALLOW_ID, SPELL_SPIRIT_CHAINS, true);
GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_ALLOW_ID, SPELL_SPIRIT_VOLLEY, true);
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) GetUnitOwner()->ToCreature()->SetInCombatWithZone();
{ Map::PlayerList const& playerList = GetUnitOwner()->GetMap()->GetPlayers();
Unit::Kill(nullptr, GetTarget()); for (Map::PlayerList::const_iterator i = playerList.begin(); i != playerList.end(); ++i)
} if (Player* player = i->GetSource())
{
if (GetUnitOwner()->IsValidAttackTarget(player))
GetUnitOwner()->AddThreat(player, 1000000.0f);
}
void Register() override GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_BRIEF_STUN, true);
{
AfterEffectRemove += AuraEffectRemoveFn(spell_teron_gorefiend_spiritual_vengeance_AuraScript::HandleEffectRemove, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_teron_gorefiend_spiritual_vengeance_AuraScript();
} }
};
class spell_teron_gorefiend_shadowy_construct : public SpellScriptLoader void Register() override
{
public:
spell_teron_gorefiend_shadowy_construct() : SpellScriptLoader("spell_teron_gorefiend_shadowy_construct") { }
class spell_teron_gorefiend_shadowy_construct_AuraScript : public AuraScript
{ {
PrepareAuraScript(spell_teron_gorefiend_shadowy_construct_AuraScript) AfterEffectApply += AuraEffectApplyFn(spell_teron_gorefiend_shadowy_construct::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
bool Load() override
{
return GetUnitOwner()->GetTypeId() == TYPEID_UNIT;
}
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NORMAL, true);
GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_ALLOW_ID, SPELL_SPIRIT_LANCE, true);
GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_ALLOW_ID, SPELL_SPIRIT_CHAINS, true);
GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_ALLOW_ID, SPELL_SPIRIT_VOLLEY, true);
GetUnitOwner()->ToCreature()->SetInCombatWithZone();
Map::PlayerList const& playerList = GetUnitOwner()->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator i = playerList.begin(); i != playerList.end(); ++i)
if (Player* player = i->GetSource())
{
if (GetUnitOwner()->IsValidAttackTarget(player))
GetUnitOwner()->AddThreat(player, 1000000.0f);
}
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_BRIEF_STUN, true);
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_teron_gorefiend_shadowy_construct_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_teron_gorefiend_shadowy_construct_AuraScript();
} }
}; };
void AddSC_boss_teron_gorefiend() void AddSC_boss_teron_gorefiend()
{ {
new boss_teron_gorefiend(); RegisterBlackTempleCreatureAI(boss_teron_gorefiend);
new spell_teron_gorefiend_shadow_of_death(); RegisterSpellScript(spell_teron_gorefiend_shadow_of_death);
new spell_teron_gorefiend_spirit_lance(); RegisterSpellScript(spell_teron_gorefiend_spirit_lance);
new spell_teron_gorefiend_spiritual_vengeance(); RegisterSpellScript(spell_teron_gorefiend_spiritual_vengeance);
new spell_teron_gorefiend_shadowy_construct(); RegisterSpellScript(spell_teron_gorefiend_shadowy_construct);
} }

View File

@@ -50,158 +50,118 @@ enum Events
EVENT_KILL_SPEAK = 6 EVENT_KILL_SPEAK = 6
}; };
class boss_najentus : public CreatureScript struct boss_najentus : public BossAI
{ {
public: boss_najentus(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS) { }
boss_najentus() : CreatureScript("boss_najentus") { }
CreatureAI* GetAI(Creature* creature) const override void KilledUnit(Unit* victim) override
{ {
return GetBlackTempleAI<boss_najentusAI>(creature); if (victim->GetTypeId() == TYPEID_PLAYER && events.GetNextEventTime(EVENT_KILL_SPEAK) == 0)
{
Talk(SAY_SLAY);
events.ScheduleEvent(EVENT_KILL_SPEAK, 5000);
}
} }
struct boss_najentusAI : public BossAI void JustDied(Unit* killer) override
{ {
boss_najentusAI(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_NAJENTUS) BossAI::JustDied(killer);
{ Talk(SAY_DEATH);
} }
void Reset() override void JustEngagedWith(Unit* who) override
{ {
BossAI::Reset(); BossAI::JustEngagedWith(who);
} Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SPELL_BERSERK, 480000);
events.ScheduleEvent(EVENT_YELL, urand(25000, 100000));
events.RescheduleEvent(EVENT_SPELL_NEEDLE, 10000);
events.RescheduleEvent(EVENT_SPELL_SPINE, 20001);
events.RescheduleEvent(EVENT_SPELL_SHIELD, 60000);
}
void KilledUnit(Unit* victim) override void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{ {
if (victim->GetTypeId() == TYPEID_PLAYER && events.GetNextEventTime(EVENT_KILL_SPEAK) == 0) case EVENT_SPELL_SHIELD:
me->CastSpell(me, SPELL_TIDAL_SHIELD, false);
events.DelayEvents(10000);
events.ScheduleEvent(EVENT_SPELL_SHIELD, 60000);
break;
case EVENT_SPELL_BERSERK:
Talk(SAY_ENRAGE);
me->CastSpell(me, SPELL_BERSERK, true);
break;
case EVENT_SPELL_NEEDLE:
me->CastCustomSpell(SPELL_NEEDLE_SPINE, SPELLVALUE_MAX_TARGETS, 3, me, false);
events.ScheduleEvent(EVENT_SPELL_NEEDLE, 15000);
break;
case EVENT_SPELL_SPINE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
{ {
Talk(SAY_SLAY); me->CastSpell(target, SPELL_IMPALING_SPINE, false);
events.ScheduleEvent(EVENT_KILL_SPEAK, 5000); target->CastSpell(target, SPELL_SUMMON_IMPALING_SPINE, true);
Talk(SAY_NEEDLE);
} }
} events.ScheduleEvent(EVENT_SPELL_SPINE, 20000);
return;
void JustDied(Unit* killer) override case EVENT_YELL:
{ Talk(SAY_SPECIAL);
BossAI::JustDied(killer);
Talk(SAY_DEATH);
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SPELL_BERSERK, 480000);
events.ScheduleEvent(EVENT_YELL, urand(25000, 100000)); events.ScheduleEvent(EVENT_YELL, urand(25000, 100000));
events.RescheduleEvent(EVENT_SPELL_NEEDLE, 10000); break;
events.RescheduleEvent(EVENT_SPELL_SPINE, 20001);
events.RescheduleEvent(EVENT_SPELL_SHIELD, 60000);
} }
void UpdateAI(uint32 diff) override DoMeleeAttackIfReady();
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_SHIELD:
me->CastSpell(me, SPELL_TIDAL_SHIELD, false);
events.DelayEvents(10000);
events.ScheduleEvent(EVENT_SPELL_SHIELD, 60000);
break;
case EVENT_SPELL_BERSERK:
Talk(SAY_ENRAGE);
me->CastSpell(me, SPELL_BERSERK, true);
break;
case EVENT_SPELL_NEEDLE:
me->CastCustomSpell(SPELL_NEEDLE_SPINE, SPELLVALUE_MAX_TARGETS, 3, me, false);
events.ScheduleEvent(EVENT_SPELL_NEEDLE, 15000);
break;
case EVENT_SPELL_SPINE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
{
me->CastSpell(target, SPELL_IMPALING_SPINE, false);
target->CastSpell(target, SPELL_SUMMON_IMPALING_SPINE, true);
Talk(SAY_NEEDLE);
}
events.ScheduleEvent(EVENT_SPELL_SPINE, 20000);
return;
case EVENT_YELL:
Talk(SAY_SPECIAL);
events.ScheduleEvent(EVENT_YELL, urand(25000, 100000));
break;
}
DoMeleeAttackIfReady();
}
};
};
class spell_najentus_needle_spine : public SpellScriptLoader
{
public:
spell_najentus_needle_spine() : SpellScriptLoader("spell_najentus_needle_spine") { }
class spell_najentus_needle_spine_SpellScript : public SpellScript
{
PrepareSpellScript(spell_najentus_needle_spine_SpellScript);
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
GetCaster()->CastSpell(target, SPELL_NEEDLE_SPINE_DAMAGE, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_najentus_needle_spine_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
{
return new spell_najentus_needle_spine_SpellScript();
} }
}; };
class spell_najentus_hurl_spine : public SpellScriptLoader class spell_najentus_needle_spine : public SpellScript
{ {
public: PrepareSpellScript(spell_najentus_needle_spine);
spell_najentus_hurl_spine() : SpellScriptLoader("spell_najentus_hurl_spine") { }
class spell_najentus_hurl_spine_SpellScript : public SpellScript void HandleDummy(SpellEffIndex /*effIndex*/)
{ {
PrepareSpellScript(spell_najentus_hurl_spine_SpellScript); if (Unit* target = GetHitUnit())
GetCaster()->CastSpell(target, SPELL_NEEDLE_SPINE_DAMAGE, true);
}
void HandleSchoolDamage(SpellEffIndex /*effIndex*/) void Register() override
{
Unit* target = GetHitUnit();
if (target && target->HasAura(SPELL_TIDAL_SHIELD))
{
target->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD);
target->CastSpell(target, SPELL_TIDAL_BURST, true);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_najentus_hurl_spine_SpellScript::HandleSchoolDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
SpellScript* GetSpellScript() const override
{ {
return new spell_najentus_hurl_spine_SpellScript(); OnEffectHitTarget += SpellEffectFn(spell_najentus_needle_spine::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
class spell_najentus_hurl_spine : public SpellScript
{
PrepareSpellScript(spell_najentus_hurl_spine);
void HandleSchoolDamage(SpellEffIndex /*effIndex*/)
{
Unit* target = GetHitUnit();
if (target && target->HasAura(SPELL_TIDAL_SHIELD))
{
target->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD);
target->CastSpell(target, SPELL_TIDAL_BURST, true);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_najentus_hurl_spine::HandleSchoolDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
} }
}; };
void AddSC_boss_najentus() void AddSC_boss_najentus()
{ {
new boss_najentus(); RegisterBlackTempleCreatureAI(boss_najentus);
new spell_najentus_needle_spine(); RegisterSpellScript(spell_najentus_needle_spine);
new spell_najentus_hurl_spine(); RegisterSpellScript(spell_najentus_hurl_spine);
} }