mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-09 00:08:01 +00:00
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:
@@ -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_
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user