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);
}
#define RegisterBlackTempleCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackTempleAI)
#endif // BLACK_TEMPLE_H_

View File

@@ -90,541 +90,477 @@ enum Misc
EVENT_AKAMA_SCENE7 = 36
};
class boss_shade_of_akama : public CreatureScript
struct boss_shade_of_akama : public BossAI
{
public:
boss_shade_of_akama() : CreatureScript("boss_shade_of_akama") { }
struct boss_shade_of_akamaAI : public BossAI
boss_shade_of_akama(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA), summonsChanneler(me), summonsGenerator(me)
{
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 summonsGenerator;
EventMap events2;
SummonList summonsChanneler;
SummonList summonsGenerator;
EventMap events2;
void ChannelersAction(int32 action)
{
for (SummonList::const_iterator i = summonsChanneler.begin(); i != summonsChanneler.end(); ++i)
if (Creature* summon = ObjectAccessor::GetCreature(*me, *i))
void ChannelersAction(int32 action)
{
for (SummonList::const_iterator i = summonsChanneler.begin(); i != summonsChanneler.end(); ++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);
}
else if (action == ACTION_START_ENCOUNTER)
{
summon->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
}
else if (action == ACTION_KILL_CHANNELERS)
{
Unit::Kill(me, summon);
}
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);
}
}
}
void Reset() override
{
BossAI::Reset();
me->SetReactState(REACT_PASSIVE);
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetImmuneToAll(true);
me->SetWalk(true);
}
void Reset() override
{
BossAI::Reset();
me->SetReactState(REACT_PASSIVE);
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetImmuneToAll(true);
me->SetWalk(true);
}
void EnterEvadeMode(EvadeReason why) override
{
BossAI::EnterEvadeMode(why);
summonsGenerator.DoAction(ACTION_DESPAWN_ALL);
events2.ScheduleEvent(EVENT_SHADE_RESET_ENCOUNTER, 20000);
me->SetVisible(false);
ChannelersAction(ACTION_KILL_CHANNELERS);
}
void EnterEvadeMode(EvadeReason why) override
{
BossAI::EnterEvadeMode(why);
summonsGenerator.DoAction(ACTION_DESPAWN_ALL);
events2.ScheduleEvent(EVENT_SHADE_RESET_ENCOUNTER, 20000);
me->SetVisible(false);
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);
summonsGenerator.DoAction(ACTION_DESPAWN_ALL);
summonsChanneler.DespawnAll();
me->CastSpell(me, SPELL_SHADE_OF_AKAMA_TRIGGER, true);
akama->SetHomePosition(*akama);
akama->AI()->DoAction(ACTION_SHADE_DIED);
}
}
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)))
{
akama->SetHomePosition(*akama);
akama->AI()->DoAction(ACTION_SHADE_DIED);
}
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;
}
void JustEngagedWith(Unit* who) override
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
BossAI::JustEngagedWith(who);
}
void DoAction(int32 param) override
{
if (param == ACTION_START_ENCOUNTER)
case EVENT_SHADE_CHECK_DISTANCE:
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
{
summonsGenerator.DoAction(ACTION_START_ENCOUNTER);
ChannelersAction(ACTION_START_ENCOUNTER);
events.ScheduleEvent(EVENT_SHADE_CHECK_DISTANCE, 1000);
int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED);
if (slow > -100)
{
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);
}
}
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)))
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;
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 (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
if (me->IsWithinMeleeRange(me->GetVictim()))
{
case EVENT_SHADE_CHECK_DISTANCE:
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
{
int32 slow = me->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_DECREASE_SPEED);
if (slow > -100)
{
me->SetWalk(true);
me->GetMotionMaster()->MovePoint(POINT_START, 510.0f, 400.7993f, 112.7837f);
}
}
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;
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;
}
DoMeleeAttackIfReady();
events.ScheduleEvent(EVENT_SHADE_CHECK_DISTANCE, 1000);
break;
}
bool CheckEvadeIfOutOfCombatArea() const override
{
return !SelectTargetFromPlayerList(120.0f);
}
};
DoMeleeAttackIfReady();
}
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() : CreatureScript("npc_akama_shade") { }
struct npc_akamaAI : public ScriptedAI
npc_akama_shade(Creature* creature) : ScriptedAI(creature), summons(me)
{
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;
EventMap events;
EventMap events2;
SummonList summons;
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
me->CastSpell(me, SPELL_STEALTH, true);
events.Reset();
events2.Reset();
}
void Reset() override
{
if (instance->GetBossState(DATA_SHADE_OF_AKAMA) == DONE)
{
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
return;
}
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
me->CastSpell(me, SPELL_STEALTH, true);
events.Reset();
events2.Reset();
}
void MovementInform(uint32 type, uint32 point) override
{
if (type != POINT_MOTION_TYPE || point != POINT_CHANNEL_SOUL)
return;
me->SetFacingTo(0.0f);
events2.ScheduleEvent(EVENT_AKAMA_SCENE1, 1000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE2, 16500);
events2.ScheduleEvent(EVENT_AKAMA_SCENE3, 17500);
events2.ScheduleEvent(EVENT_AKAMA_SCENE4, 27000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE5, 37000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE6, 51000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE7, 56000);
}
void DoAction(int32 param) override
{
if (param == ACTION_SHADE_DIED)
events2.ScheduleEvent(EVENT_AKAMA_SCENE0, 1000);
}
void JustDied(Unit* /*killer*/) override
void MovementInform(uint32 type, uint32 point) override
{
if (type != POINT_MOTION_TYPE || point != POINT_CHANNEL_SOUL)
return;
me->SetFacingTo(0.0f);
events2.ScheduleEvent(EVENT_AKAMA_SCENE1, 1000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE2, 16500);
events2.ScheduleEvent(EVENT_AKAMA_SCENE3, 17500);
events2.ScheduleEvent(EVENT_AKAMA_SCENE4, 27000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE5, 37000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE6, 51000);
events2.ScheduleEvent(EVENT_AKAMA_SCENE7, 56000);
}
void DoAction(int32 param) override
{
if (param == ACTION_SHADE_DIED)
events2.ScheduleEvent(EVENT_AKAMA_SCENE0, 1000);
}
void JustDied(Unit* /*killer*/) override
{
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:
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)))
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:
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)))
{
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;
shade->AI()->AttackStart(me);
shade->GetMotionMaster()->Clear();
shade->AI()->DoAction(ACTION_START_ENCOUNTER);
}
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_CHAIN_LIGHTNING:
me->CastSpell(me->GetVictim(), SPELL_CHAIN_LIGHTNING, false);
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, urand(10000, 15000));
break;
case EVENT_SPELL_DESTRUCTIVE_POISON:
me->CastSpell(me, SPELL_DESTRUCTIVE_POISON, false);
events.ScheduleEvent(EVENT_SPELL_DESTRUCTIVE_POISON, urand(4000, 5000));
break;
}
DoMeleeAttackIfReady();
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;
}
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)
{
CloseGossipMenuFor(player);
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
events2.ScheduleEvent(EVENT_AKAMA_START_ENCOUNTER, 0);
}
case EVENT_SPELL_CHAIN_LIGHTNING:
me->CastSpell(me->GetVictim(), SPELL_CHAIN_LIGHTNING, false);
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, urand(10000, 15000));
break;
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);
}
}
};
// ########################################################
// Creature Generator Akama
// ########################################################
class npc_creature_generator_akama : public CreatureScript
struct npc_creature_generator_akama : public NullCreatureAI
{
public:
npc_creature_generator_akama() : CreatureScript("npc_creature_generator_akama") { }
struct npc_creature_generator_akamaAI : public NullCreatureAI
npc_creature_generator_akama(Creature* creature) : NullCreatureAI(creature), summons(me)
{
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();
summons.DespawnAll();
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_ASHTONGUE_SORCERER)
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
{
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 (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
{
if ((*itr)->IsAlive() || (*itr)->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
if (summon->GetEntry() != NPC_ASHTONGUE_SORCERER)
continue;
summon->InterruptNonMeleeSpells(false);
summon->GetMotionMaster()->Clear();
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);
}
}
void SummonedCreatureDies(Creature* summon, Unit*) override
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)
{
summon->DespawnOrUnsummon(10000);
summons.Despawn(summon);
events.ScheduleEvent(EVENT_SUMMON_WAVE_B, 5000);
events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_DEFENDER, 20000);
events.ScheduleEvent(EVENT_SUMMON_ASHTONGUE_SORCERER, 35000);
}
}
void DoAction(int32 param) 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
void UpdateAI(uint32 diff) 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:
spell_shade_of_akama_shade_soul_channel() : SpellScriptLoader("spell_shade_of_akama_shade_soul_channel") { }
PrepareSpellScript(spell_shade_of_akama_akama_soul_expel);
class spell_shade_of_akama_shade_soul_channel_AuraScript : public AuraScript
void SetDest(SpellDestination& dest)
{
PrepareAuraScript(spell_shade_of_akama_shade_soul_channel_AuraScript)
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_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();
// Adjust effect summon position
Position const offset = { 0.0f, 0.0f, 25.0f, 0.0f };
dest.RelocateOffset(offset);
}
};
class spell_shade_of_akama_akama_soul_expel : public SpellScriptLoader
{
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
void Register() override
{
PrepareSpellScript(spell_shade_of_akama_akama_soul_expel_SpellScript);
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();
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_shade_of_akama_akama_soul_expel::SetDest, EFFECT_0, TARGET_DEST_CASTER_RADIUS);
}
};
void AddSC_boss_shade_of_akama()
{
new boss_shade_of_akama();
new npc_akama_shade();
new npc_creature_generator_akama();
new spell_shade_of_akama_shade_soul_channel();
new spell_shade_of_akama_akama_soul_expel();
RegisterBlackTempleCreatureAI(boss_shade_of_akama);
RegisterBlackTempleCreatureAI(npc_akama_shade);
RegisterBlackTempleCreatureAI(npc_creature_generator_akama);
RegisterSpellScript(spell_shade_of_akama_shade_soul_channel);
RegisterSpellScript(spell_shade_of_akama_akama_soul_expel);
}

View File

@@ -46,164 +46,141 @@ enum Supremus
EVENT_GROUP_ABILITIES = 1
};
class boss_supremus : public CreatureScript
struct boss_supremus : public BossAI
{
public:
boss_supremus() : CreatureScript("boss_supremus") { }
boss_supremus(Creature* creature) : BossAI(creature, DATA_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();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
SchedulePhase(false);
events.ScheduleEvent(EVENT_SPELL_BERSERK, 900000);
events.ScheduleEvent(EVENT_SPELL_MOLTEN_FLAMES, 4000);
}
void SchedulePhase(bool run)
{
events.CancelEventGroup(EVENT_GROUP_ABILITIES);
events.ScheduleEvent(EVENT_SWITCH_PHASE, 60000);
DoResetThreatList();
if (!run)
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))
{
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);
DoResetThreatList();
me->AddThreat(target, 5000000.0f);
Talk(EMOTE_NEW_TARGET);
}
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);
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);
Talk(EMOTE_PUNCH_GROUND);
me->CastSpell(me->GetVictim(), SPELL_CHARGE, true);
events.ScheduleEvent(EVENT_CHECK_DIST, 5000, EVENT_GROUP_ABILITIES);
break;
}
}
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_SUPREMUS_PUNCH_STALKER)
events.ScheduleEvent(EVENT_CHECK_DIST, 1, EVENT_GROUP_ABILITIES);
break;
case EVENT_SPELL_VOLCANIC_ERUPTION:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
{
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);
me->CastSpell(target, SPELL_VOLCANIC_ERUPTION, true);
Talk(EMOTE_GROUND_CRACK);
}
else
summon->CastSpell(summon, SPELL_VOLCANIC_ERUPTION_TRIGGER, true);
events.ScheduleEvent(EVENT_SPELL_VOLCANIC_ERUPTION, urand(10000, 18000), EVENT_GROUP_ABILITIES);
break;
}
void SummonedCreatureDespawn(Creature* summon) override
{
summons.Despawn(summon);
}
DoMeleeAttackIfReady();
}
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;
}
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;
}
};
bool CheckEvadeIfOutOfCombatArea() const override
{
return me->GetPositionX() < 565 || me->GetPositionX() > 865 || me->GetPositionY() < 545 || me->GetPositionY() > 1000;
}
};
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() : CreatureScript("boss_teron_gorefiend") { }
boss_teron_gorefiend(Creature* creature) : BossAI(creature, DATA_TERON_GOREFIEND), intro(false) { }
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();
me->CastSpell(me, SPELL_SHADOW_OF_DEATH_REMOVE, true);
Talk(SAY_SLAY);
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())
return;
if (id == SET_DATA_INTRO && !intro)
case EVENT_SPELL_INCINERATE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
intro = true;
Talk(SAY_INTRO);
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;
}
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 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;
}
};
DoMeleeAttackIfReady();
}
};
class spell_teron_gorefiend_shadow_of_death : public SpellScriptLoader
class spell_teron_gorefiend_shadow_of_death : public AuraScript
{
public:
spell_teron_gorefiend_shadow_of_death() : SpellScriptLoader("spell_teron_gorefiend_shadow_of_death") { }
PrepareAuraScript(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*/)
{
PreventDefaultAction();
}
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::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*/)
{
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:
spell_teron_gorefiend_spirit_lance() : SpellScriptLoader("spell_teron_gorefiend_spirit_lance") { }
PrepareAuraScript(spell_teron_gorefiend_shadowy_construct);
class spell_teron_gorefiend_spirit_lance_AuraScript : public AuraScript
bool Load() override
{
PrepareAuraScript(spell_teron_gorefiend_spirit_lance_AuraScript);
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();
return GetUnitOwner()->GetTypeId() == TYPEID_UNIT;
}
};
class spell_teron_gorefiend_spiritual_vengeance : public SpellScriptLoader
{
public:
spell_teron_gorefiend_spiritual_vengeance() : SpellScriptLoader("spell_teron_gorefiend_spiritual_vengeance") { }
class spell_teron_gorefiend_spiritual_vengeance_AuraScript : public AuraScript
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
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*/)
{
Unit::Kill(nullptr, GetTarget());
}
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);
}
void Register() override
{
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();
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_BRIEF_STUN, true);
}
};
class spell_teron_gorefiend_shadowy_construct : public SpellScriptLoader
{
public:
spell_teron_gorefiend_shadowy_construct() : SpellScriptLoader("spell_teron_gorefiend_shadowy_construct") { }
class spell_teron_gorefiend_shadowy_construct_AuraScript : public AuraScript
void Register() override
{
PrepareAuraScript(spell_teron_gorefiend_shadowy_construct_AuraScript)
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();
AfterEffectApply += AuraEffectApplyFn(spell_teron_gorefiend_shadowy_construct::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
void AddSC_boss_teron_gorefiend()
{
new boss_teron_gorefiend();
new spell_teron_gorefiend_shadow_of_death();
new spell_teron_gorefiend_spirit_lance();
new spell_teron_gorefiend_spiritual_vengeance();
new spell_teron_gorefiend_shadowy_construct();
RegisterBlackTempleCreatureAI(boss_teron_gorefiend);
RegisterSpellScript(spell_teron_gorefiend_shadow_of_death);
RegisterSpellScript(spell_teron_gorefiend_spirit_lance);
RegisterSpellScript(spell_teron_gorefiend_spiritual_vengeance);
RegisterSpellScript(spell_teron_gorefiend_shadowy_construct);
}

View File

@@ -50,158 +50,118 @@ enum Events
EVENT_KILL_SPEAK = 6
};
class boss_najentus : public CreatureScript
struct boss_najentus : public BossAI
{
public:
boss_najentus() : CreatureScript("boss_najentus") { }
boss_najentus(Creature* creature) : BossAI(creature, DATA_HIGH_WARLORD_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
{
BossAI::Reset();
}
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.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);
events.ScheduleEvent(EVENT_KILL_SPEAK, 5000);
me->CastSpell(target, SPELL_IMPALING_SPINE, false);
target->CastSpell(target, SPELL_SUMMON_IMPALING_SPINE, true);
Talk(SAY_NEEDLE);
}
}
void JustDied(Unit* killer) override
{
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_SPELL_SPINE, 20000);
return;
case EVENT_YELL:
Talk(SAY_SPECIAL);
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);
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_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();
DoMeleeAttackIfReady();
}
};
class spell_najentus_hurl_spine : public SpellScriptLoader
class spell_najentus_needle_spine : public SpellScript
{
public:
spell_najentus_hurl_spine() : SpellScriptLoader("spell_najentus_hurl_spine") { }
PrepareSpellScript(spell_najentus_needle_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*/)
{
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
void Register() 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()
{
new boss_najentus();
new spell_najentus_needle_spine();
new spell_najentus_hurl_spine();
RegisterBlackTempleCreatureAI(boss_najentus);
RegisterSpellScript(spell_najentus_needle_spine);
RegisterSpellScript(spell_najentus_hurl_spine);
}