mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-17 02:50:29 +00:00
fix(Scripts/BlackTemple): Rewrite Shade of Akama (#18601)
* init * akama only generators left * Update boss_shade_of_akama.cpp * Update boss_shade_of_akama.cpp * warnign * OMFG * akama generators * more for generators * done * codestyle * warnings * illidan fix Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update rev_1711048056647652400.sql Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * a Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update instance_black_temple.cpp Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update rev_1711048056647652400.sql Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * avoid collecting trash Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update boss_illidan.cpp Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * Update boss_shade_of_akama.cpp Co-Authored-By: 天鹿 <18535853+pklloveyou@users.noreply.github.com> * crashfix? * takes too long to despawn * maybe * clear lists --------- Co-authored-by: 天鹿 <18535853+pklloveyou@users.noreply.github.com>
This commit is contained in:
@@ -40,17 +40,27 @@ enum DataTypes
|
||||
DATA_RELIQUARY_OF_SOULS = 5,
|
||||
DATA_MOTHER_SHAHRAZ = 6,
|
||||
DATA_ILLIDARI_COUNCIL = 7,
|
||||
DATA_AKAMA_FINISHED = 8,
|
||||
DATA_AKAMA_ILLIDAN = 8,
|
||||
DATA_ILLIDAN_STORMRAGE = 9,
|
||||
MAX_ENCOUNTERS = 10
|
||||
MAX_ENCOUNTERS = 10,
|
||||
|
||||
DATA_AKAMA_SHADE = 11,
|
||||
DATA_GATHIOS_THE_SHATTERER = 12,
|
||||
DATA_HIGH_NETHERMANCER_ZEREVOR = 13,
|
||||
DATA_LADY_MALANDE = 14,
|
||||
DATA_VERAS_DARKSHADOW = 15
|
||||
};
|
||||
|
||||
enum CreatureIds
|
||||
{
|
||||
NPC_HIGH_WARLORD_NAJENTUS = 22887,
|
||||
NPC_SUPREMUS = 22898,
|
||||
NPC_SHADE_OF_AKAMA = 22841,
|
||||
NPC_AKAMA_SHADE = 23191,
|
||||
NPC_STORM_FURY = 22848,
|
||||
NPC_ASHTONGUE_CHANNELER = 23421,
|
||||
NPC_CREATURE_GENERATOR_AKAMA = 23210,
|
||||
NPC_TERON_GOREFIEND = 22871,
|
||||
NPC_GURTOGG_BLOODBOIL = 22948,
|
||||
NPC_VENGEFUL_SPIRIT = 23109,
|
||||
NPC_SHADOWY_CONSTRUCT = 23111,
|
||||
NPC_ANGERED_SOUL_FRAGMENT = 23398,
|
||||
@@ -58,17 +68,26 @@ enum CreatureIds
|
||||
NPC_SUFFERING_SOUL_FRAGMENT = 23399,
|
||||
NPC_RELIQUARY_OF_THE_LOST = 22856,
|
||||
NPC_ENSLAVED_SOUL = 23469,
|
||||
NPC_MOTHER_SHAHRAZ = 22947,
|
||||
NPC_GATHIOS_THE_SHATTERER = 22949,
|
||||
NPC_HIGH_NETHERMANCER_ZEREVOR = 22950,
|
||||
NPC_LADY_MALANDE = 22951,
|
||||
NPC_VERAS_DARKSHADOW = 22952,
|
||||
NPC_ILLIDARI_COUNCIL = 23426,
|
||||
NPC_AKAMA = 23089,
|
||||
NPC_AKAMA_ILLIDAN = 23089,
|
||||
NPC_ILLIDAN_STORMRAGE = 22917,
|
||||
NPC_PARASITIC_SHADOWFIEND = 23498,
|
||||
NPC_BLADE_OF_AZZINOTH = 22996,
|
||||
NPC_FLAME_OF_AZZINOTH = 22997,
|
||||
|
||||
NPC_ASHTONGUE_BATTLELORD = 22844,
|
||||
NPC_ASHTONGUE_MYSTIC = 22845,
|
||||
NPC_ASHTONGUE_STORMCALLER = 22846,
|
||||
NPC_ASHTONGUE_PRIMALIST = 22847,
|
||||
NPC_ASHTONGUE_FERAL_SPIRIT = 22849,
|
||||
NPC_ASHTONGUE_STALKER = 23374,
|
||||
NPC_STORM_FURY = 22848,
|
||||
|
||||
NPC_DRAGON_TURTLE = 22885
|
||||
};
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ enum Says
|
||||
SAY_AKAMA_ILLIDAN1 = 4,
|
||||
SAY_AKAMA_ILLIDAN2 = 5,
|
||||
SAY_AKAMA_ILLIDAN3 = 6,
|
||||
SAY_AKAMA_COUNCIL_1 = 9,
|
||||
SAY_AKAMA_COUNCIL_2 = 10,
|
||||
|
||||
SAY_MAIEV_SHADOWSONG_TAUNT = 0,
|
||||
SAY_MAIEV_SHADOWSONG_ILLIDAN1 = 1,
|
||||
@@ -117,6 +119,7 @@ enum Spells
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACTION_ILLIDARI_COUNCIL_DONE = 0,
|
||||
ACTION_FIGHT_MINIONS = 1,
|
||||
ACTION_RETURN_BLADE = 2,
|
||||
ACTION_ILLIDAN_CAGED = 3,
|
||||
@@ -133,7 +136,9 @@ enum Misc
|
||||
NPC_ILLIDAN_DB_TARGET = 23070,
|
||||
NPC_MAIEV_SHADOWSONG = 23197,
|
||||
|
||||
GO_CAGE_TRAP = 185916
|
||||
GO_CAGE_TRAP = 185916,
|
||||
|
||||
PATH_AKAMA_ILLIDARI_COUNCIL_1 = 230891
|
||||
};
|
||||
|
||||
enum Events
|
||||
@@ -237,13 +242,13 @@ public:
|
||||
{
|
||||
BossAI::EnterEvadeMode(why);
|
||||
|
||||
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA)))
|
||||
if (Creature* akama = instance->GetCreature(NPC_AKAMA_ILLIDAN))
|
||||
akama->AI()->EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
bool CanAIAttack(Unit const* target) const override
|
||||
{
|
||||
return target->GetEntry() != NPC_AKAMA && target->GetEntry() != NPC_MAIEV_SHADOWSONG;
|
||||
return target->GetEntry() != NPC_AKAMA_ILLIDAN && target->GetEntry() != NPC_MAIEV_SHADOWSONG;
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
@@ -408,7 +413,7 @@ public:
|
||||
switch (events2.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SUMMON_MINIONS2:
|
||||
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA)))
|
||||
if (Creature* akama = instance->GetCreature(NPC_AKAMA_ILLIDAN))
|
||||
akama->AI()->DoAction(ACTION_FIGHT_MINIONS);
|
||||
break;
|
||||
case EVENT_PHASE_2_EYE_BEAM_START:
|
||||
@@ -445,7 +450,7 @@ public:
|
||||
maiev->AI()->Talk(SAY_MAIEV_SHADOWSONG_ILLIDAN3);
|
||||
}
|
||||
|
||||
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA)))
|
||||
if (Creature* akama = instance->GetCreature(NPC_AKAMA_ILLIDAN))
|
||||
{
|
||||
akama->AI()->DoAction(ACTION_ILLIDAN_DEAD);
|
||||
akama->SetTarget(me->GetGUID());
|
||||
@@ -754,6 +759,8 @@ enum Akama
|
||||
EVENT_AKAMA_HEALTH = 102
|
||||
};
|
||||
|
||||
Position AkamaTeleport = { 609.772f, 308.456f, 271.826f, 6.1972566f };
|
||||
|
||||
class npc_akama_illidan : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -764,7 +771,7 @@ public:
|
||||
npc_akama_illidanAI(Creature* creature) : npc_escortAI(creature), summons(me)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
if (instance->GetBossState(DATA_AKAMA_FINISHED) == DONE)
|
||||
if (instance->GetBossState(DATA_AKAMA_ILLIDAN) == DONE)
|
||||
{
|
||||
me->GetMap()->LoadGrid(751.664f, 238.933f);
|
||||
me->SetHomePosition(751.664f, 238.933f, 353.106f, 2.18f);
|
||||
@@ -789,6 +796,12 @@ public:
|
||||
summons.DespawnAll();
|
||||
me->CombatStop(true);
|
||||
}
|
||||
else if (param == ACTION_ILLIDARI_COUNCIL_DONE)
|
||||
{
|
||||
me->NearTeleportTo(AkamaTeleport);
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
me->GetMotionMaster()->MovePath(PATH_AKAMA_ILLIDARI_COUNCIL_1, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
@@ -796,7 +809,6 @@ public:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
me->setActive(false);
|
||||
me->SetVisible(instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE && instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != DONE);
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
}
|
||||
@@ -807,7 +819,7 @@ public:
|
||||
me->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
|
||||
me->setActive(true);
|
||||
|
||||
if (instance->GetBossState(DATA_AKAMA_FINISHED) != DONE)
|
||||
if (instance->GetBossState(DATA_AKAMA_ILLIDAN) != DONE)
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
Start(false, true);
|
||||
@@ -830,6 +842,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void PathEndReached(uint32 pathId) override
|
||||
{
|
||||
if (pathId == PATH_AKAMA_ILLIDARI_COUNCIL_1)
|
||||
{
|
||||
ScheduleUniqueTimedEvent(200ms, [&]
|
||||
{
|
||||
Talk(SAY_AKAMA_COUNCIL_1);
|
||||
}, 1);
|
||||
ScheduleUniqueTimedEvent(7800ms, [&]
|
||||
{
|
||||
Talk(SAY_AKAMA_COUNCIL_2);
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
}, 2);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
@@ -878,6 +906,7 @@ public:
|
||||
|
||||
void UpdateEscortAI(uint32 diff) override
|
||||
{
|
||||
scheduler.Update(diff);
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
@@ -913,8 +942,8 @@ public:
|
||||
udalo->CastSpell(udalo, SPELL_AKAMA_DOOR_OPEN, false);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_9:
|
||||
instance->SetBossState(DATA_AKAMA_FINISHED, NOT_STARTED);
|
||||
instance->SetBossState(DATA_AKAMA_FINISHED, DONE);
|
||||
instance->SetBossState(DATA_AKAMA_ILLIDAN, NOT_STARTED);
|
||||
instance->SetBossState(DATA_AKAMA_ILLIDAN, DONE);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_10:
|
||||
Talk(SAY_AKAMA_BEWARE);
|
||||
@@ -923,40 +952,40 @@ public:
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_20:
|
||||
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE)))
|
||||
if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE))
|
||||
illidan->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_21:
|
||||
me->SetFacingTo(M_PI);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_22:
|
||||
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE)))
|
||||
if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE))
|
||||
illidan->AI()->Talk(SAY_ILLIDAN_AKAMA1);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_23:
|
||||
Talk(SAY_AKAMA_ILLIDAN1);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_24:
|
||||
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE)))
|
||||
if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE))
|
||||
illidan->AI()->Talk(SAY_ILLIDAN_AKAMA2);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_25:
|
||||
Talk(SAY_AKAMA_ILLIDAN2);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_26:
|
||||
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE)))
|
||||
if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE))
|
||||
illidan->AI()->Talk(SAY_ILLIDAN_AKAMA3);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_27:
|
||||
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE)))
|
||||
if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE))
|
||||
illidan->LoadEquipment(1, true);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_28:
|
||||
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE)))
|
||||
if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE))
|
||||
illidan->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
|
||||
break;
|
||||
case EVENT_AKAMA_SCENE_29:
|
||||
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDAN_STORMRAGE)))
|
||||
if (Creature* illidan = instance->GetCreature(DATA_ILLIDAN_STORMRAGE))
|
||||
{
|
||||
illidan->SetImmuneToAll(false);
|
||||
illidan->SetInCombatWithZone();
|
||||
|
||||
@@ -25,30 +25,43 @@ enum Says
|
||||
SAY_BROKEN_FREE_0 = 0,
|
||||
SAY_BROKEN_FREE_1 = 1,
|
||||
SAY_BROKEN_FREE_2 = 2,
|
||||
SAY_LOW_HEALTH = 3,
|
||||
SAY_DEATH = 4,
|
||||
|
||||
SAY_BROKEN_S1 = 0,
|
||||
SAY_BROKEN_S2 = 1
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Akama
|
||||
SPELL_STEALTH = 34189,
|
||||
SPELL_AKAMA_SOUL_CHANNEL = 40447,
|
||||
SPELL_SHADE_SOUL_CHANNEL = 40401,
|
||||
SPELL_CHAIN_LIGHTNING = 39945,
|
||||
SPELL_DESTRUCTIVE_POISON = 40874,
|
||||
SPELL_SHADE_OF_AKAMA_TRIGGER = 40955,
|
||||
SPELL_AKAMA_SOUL_RETRIEVE = 40902,
|
||||
SPELL_CHAIN_LIGHTNING = 39945,
|
||||
SPELL_AKAMA_SOUL_CHANNEL = 40447,
|
||||
SPELL_FIXATE = 40607,
|
||||
SPELL_AKAMA_SOUL_RETRIEVE = 40902, // epilogue
|
||||
SPELL_AKAMA_SOUL_EXPEL_CHANNEL = 40927, // epilogue
|
||||
|
||||
SPELL_ASHTONGUE_WAVE_B = 42035,
|
||||
SPELL_SUMMON_ASHTONGUE_SORCERER = 40476,
|
||||
SPELL_SUMMON_ASHTONGUE_DEFENDER = 40474
|
||||
// Shade & Channelers
|
||||
SPELL_SHADE_SOUL_CHANNEL = 40401,
|
||||
SPELL_THREAT = 41602,
|
||||
SPELL_SHADE_OF_AKAMA_TRIGGER = 40955,
|
||||
|
||||
// Summons
|
||||
SPELL_ASHTONGUE_WAVE_A = 42073, // unused
|
||||
SPELL_ASHTONGUE_WAVE_B = 42035,
|
||||
SPELL_SUMMON_ASHTONGUE_SORCERER = 40476,
|
||||
SPELL_SUMMON_ASHTONGUE_DEFENDER = 40474
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_ASHTONGUE_CHANNELER = 23421,
|
||||
NPC_CREATURE_GENERATOR_AKAMA = 23210,
|
||||
NPC_ASHTONGUE_SORCERER = 23215,
|
||||
NPC_ASHTONGUE_DEFENDER = 23216,
|
||||
NPC_ASHTONGUE_ELEMENTAL = 23523,
|
||||
NPC_ASHTONGUE_ROGUE = 23318,
|
||||
NPC_ASHTONGUE_SPIRITBIND = 23524,
|
||||
NPC_ASHTONGUE_BROKEN = 23319
|
||||
};
|
||||
|
||||
@@ -56,220 +69,137 @@ enum Misc
|
||||
{
|
||||
SUMMON_GROUP_BROKENS = 1,
|
||||
|
||||
POINT_START = 0,
|
||||
POINT_CHANNEL_SOUL = 1,
|
||||
POINT_ENGAGE = 0,
|
||||
POINT_OUTRO = 1,
|
||||
|
||||
ACTION_AKAMA_DIED = 1,
|
||||
ACTION_START_ENCOUNTER = 2,
|
||||
ACTION_STOP_SPAWNING = 3,
|
||||
ACTION_DESPAWN_ALL = 4,
|
||||
ACTION_CHANNELERS_START_CHANNEL = 5,
|
||||
ACTION_KILL_CHANNELERS = 6,
|
||||
ACTION_NO_SORCERERS = 7,
|
||||
ACTION_SHADE_DIED = 8,
|
||||
ACTION_GENERATOR_START = 1,
|
||||
ACTION_GENERATOR_STOP = 2,
|
||||
ACTION_GENERATOR_DESPAWN_ALL = 3,
|
||||
|
||||
EVENT_AKAMA_START_ENCOUNTER = 1,
|
||||
EVENT_AKAMA_START_CHANNEL = 2,
|
||||
EVENT_SPELL_CHAIN_LIGHTNING = 4,
|
||||
EVENT_SPELL_DESTRUCTIVE_POISON = 5,
|
||||
COUNTER_SPAWNS_MAX = 20, // Max number of spawns for each generator, number chosen at random
|
||||
|
||||
EVENT_SHADE_CHECK_DISTANCE = 10,
|
||||
EVENT_SHADE_RESET_ENCOUNTER = 11,
|
||||
EVENT_SHADE_GATHER_NPCS = 12,
|
||||
ACTION_AKAMA_START_OUTRO = 1,
|
||||
|
||||
EVENT_SUMMON_WAVE_B = 20,
|
||||
EVENT_SUMMON_ASHTONGUE_SORCERER = 21,
|
||||
EVENT_SUMMON_ASHTONGUE_DEFENDER = 22,
|
||||
|
||||
EVENT_AKAMA_SCENE0 = 29,
|
||||
EVENT_AKAMA_SCENE1 = 30,
|
||||
EVENT_AKAMA_SCENE2 = 31,
|
||||
EVENT_AKAMA_SCENE3 = 32,
|
||||
EVENT_AKAMA_SCENE4 = 33,
|
||||
EVENT_AKAMA_SCENE5 = 34,
|
||||
EVENT_AKAMA_SCENE6 = 35,
|
||||
EVENT_AKAMA_SCENE7 = 36
|
||||
FACTION_DEFAULT = 1820,
|
||||
FACTION_ENGAGE = 1868
|
||||
};
|
||||
|
||||
Position AkamaEngage = { 517.4877f, 400.79926f, 112.77704f };
|
||||
Position AkamaOutro = { 469.0867f, 401.0793f, 118.52704f, 0.087266460061073303f };
|
||||
Position ShadeEngage = { 512.48773f, 400.8283f, 112.77704f };
|
||||
|
||||
struct boss_shade_of_akama : public BossAI
|
||||
{
|
||||
boss_shade_of_akama(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA), summonsChanneler(me), summonsGenerator(me)
|
||||
{
|
||||
events2.ScheduleEvent(EVENT_SHADE_GATHER_NPCS, 1000);
|
||||
}
|
||||
boss_shade_of_akama(Creature* creature) : BossAI(creature, DATA_SHADE_OF_AKAMA) { }
|
||||
|
||||
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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::list<Creature*> channelers;
|
||||
std::list<Creature*> generators;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
channelers.clear();
|
||||
generators.clear();
|
||||
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetImmuneToAll(true);
|
||||
me->SetWalk(true);
|
||||
me->SetReactState(REACT_DEFENSIVE);
|
||||
BossAI::Reset();
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason why) override
|
||||
{
|
||||
for (Creature* generator : generators)
|
||||
generator->AI()->DoAction(ACTION_GENERATOR_DESPAWN_ALL);
|
||||
|
||||
for (Creature* channeler : channelers)
|
||||
channeler->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
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
|
||||
{
|
||||
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)))
|
||||
|
||||
for (Creature* generator : generators)
|
||||
generator->AI()->DoAction(ACTION_GENERATOR_DESPAWN_ALL);
|
||||
|
||||
if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE))
|
||||
akama->AI()->DoAction(ACTION_AKAMA_START_OUTRO);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == SPELL_AKAMA_SOUL_CHANNEL)
|
||||
{
|
||||
akama->SetHomePosition(*akama);
|
||||
akama->AI()->DoAction(ACTION_SHADE_DIED);
|
||||
instance->SetBossState(DATA_SHADE_OF_AKAMA, IN_PROGRESS);
|
||||
|
||||
me->GetCreatureListWithEntryInGrid(channelers, NPC_ASHTONGUE_CHANNELER, 40.0f);
|
||||
me->GetCreatureListWithEntryInGrid(generators, NPC_CREATURE_GENERATOR_AKAMA, 100.0f);
|
||||
|
||||
for (Creature* channeler : channelers)
|
||||
channeler->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
for (Creature* generator : generators)
|
||||
generator->AI()->DoAction(ACTION_GENERATOR_START);
|
||||
|
||||
ScheduleTimedEvent(1200ms, [&]
|
||||
{
|
||||
if (me->GetSpeed(MOVE_WALK) > 0.01f)
|
||||
{
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MovePoint(POINT_ENGAGE, ShadeEngage);
|
||||
}
|
||||
}, 1200ms);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
void MovementInform(uint32 type, uint32 point) override
|
||||
{
|
||||
if (param == ACTION_START_ENCOUNTER)
|
||||
if (type == POINT_MOTION_TYPE && point == POINT_ENGAGE)
|
||||
{
|
||||
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);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveAurasDueToSpell(SPELL_AKAMA_SOUL_CHANNEL);
|
||||
scheduler.CancelAll();
|
||||
|
||||
for (Creature* generator : generators)
|
||||
generator->AI()->DoAction(ACTION_GENERATOR_STOP);
|
||||
|
||||
if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE))
|
||||
{
|
||||
akama->SetReactState(REACT_AGGRESSIVE);
|
||||
akama->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||
DoCast(akama, SPELL_THREAT, true);
|
||||
me->AddThreat(akama, 900000.0f);
|
||||
akama->AI()->DoCast(me, SPELL_FIXATE, true);
|
||||
AttackStart(akama);
|
||||
}
|
||||
|
||||
ScheduleTimedEvent(3500ms, [&]
|
||||
{
|
||||
if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE))
|
||||
me->AddThreat(akama, 900000.0f);
|
||||
}, 3500ms);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
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;
|
||||
}
|
||||
scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const override
|
||||
{
|
||||
return !SelectTargetFromPlayerList(120.0f);
|
||||
}
|
||||
};
|
||||
|
||||
struct npc_akama_shade : public ScriptedAI
|
||||
{
|
||||
npc_akama_shade(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
npc_akama_shade(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
EventMap events2;
|
||||
SummonList summons;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -279,244 +209,262 @@ struct npc_akama_shade : public ScriptedAI
|
||||
return;
|
||||
}
|
||||
|
||||
me->SetFaction(FACTION_DEFAULT);
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
me->CastSpell(me, SPELL_STEALTH, true);
|
||||
events.Reset();
|
||||
events2.Reset();
|
||||
DoCastSelf(SPELL_STEALTH, true);
|
||||
me->SetWalk(true);
|
||||
scheduler.CancelAll();
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE || point != POINT_CHANNEL_SOUL)
|
||||
return;
|
||||
if (type == POINT_MOTION_TYPE)
|
||||
{
|
||||
switch (point)
|
||||
{
|
||||
case POINT_ENGAGE:
|
||||
me->SetHomePosition(me->GetPosition());
|
||||
me->SetFaction(FACTION_ENGAGE);
|
||||
DoCast(me, SPELL_AKAMA_SOUL_CHANNEL, true);
|
||||
break;
|
||||
case POINT_OUTRO:
|
||||
DoCastSelf(SPELL_AKAMA_SOUL_RETRIEVE, true);
|
||||
ScheduleUniqueTimedEvent(15600ms, [&]
|
||||
{
|
||||
Talk(SAY_BROKEN_FREE_0);
|
||||
me->SummonCreatureGroup(SUMMON_GROUP_BROKENS);
|
||||
}, 1);
|
||||
ScheduleUniqueTimedEvent(26550ms, [&]
|
||||
{
|
||||
Talk(SAY_BROKEN_FREE_1);
|
||||
}, 2);
|
||||
ScheduleUniqueTimedEvent(37500ms, [&]
|
||||
{
|
||||
Talk(SAY_BROKEN_FREE_2);
|
||||
}, 3);
|
||||
ScheduleUniqueTimedEvent(52000ms, [&]
|
||||
{
|
||||
std::list<Creature*> brokens;
|
||||
me->GetCreatureListWithEntryInGrid(brokens, NPC_ASHTONGUE_BROKEN, 40.0f);
|
||||
if (Creature* broken = GetClosestCreatureWithEntry(me, NPC_ASHTONGUE_BROKEN, 40.0f))
|
||||
broken->AI()->Talk(SAY_BROKEN_S1);
|
||||
|
||||
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);
|
||||
for (Creature* broken : brokens)
|
||||
{
|
||||
broken->SetStandState(UNIT_STAND_STATE_KNEEL);
|
||||
broken->SetFaction(FACTION_DEFAULT);
|
||||
broken->AI()->Talk(SAY_BROKEN_S2, 4800ms);
|
||||
}
|
||||
}, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_SHADE_DIED)
|
||||
events2.ScheduleEvent(EVENT_AKAMA_SCENE0, 1000);
|
||||
if (param == ACTION_AKAMA_START_OUTRO)
|
||||
{
|
||||
me->SetWalk(false);
|
||||
me->GetMotionMaster()->MovePoint(POINT_OUTRO, AkamaOutro);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
// In Retail they seem to me like they should move in formations of 3 to set points, this is simpler for now
|
||||
ScriptedAI::JustSummoned(summon);
|
||||
float x, y, z;
|
||||
me->GetNearPoint(summon, x, y, z, 25.f, 0, me->GetAngle(summon));
|
||||
summon->SetWalk(true);
|
||||
summon->GetMotionMaster()->MovePoint(POINT_OUTRO, x, y, z);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override { }
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* shade = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SHADE_OF_AKAMA)))
|
||||
shade->AI()->DoAction(ACTION_AKAMA_DIED);
|
||||
if (Creature* shade = instance->GetCreature(DATA_SHADE_OF_AKAMA))
|
||||
{
|
||||
shade->SetHomePosition(shade->GetHomePosition());
|
||||
shade->AI()->EnterEvadeMode();
|
||||
}
|
||||
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 2000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DESTRUCTIVE_POISON, 5000);
|
||||
ScheduleTimedEvent(2s, [&]
|
||||
{
|
||||
DoCastVictim(SPELL_CHAIN_LIGHTNING);
|
||||
}, 10s, 15s);
|
||||
ScheduleTimedEvent(5s, [&]
|
||||
{
|
||||
DoCastVictim(SPELL_DESTRUCTIVE_POISON);
|
||||
}, 4s, 15s);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/) 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);
|
||||
CloseGossipMenuFor(player);
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
me->RemoveAurasDueToSpell(SPELL_STEALTH);
|
||||
me->GetMotionMaster()->MovePoint(POINT_ENGAGE, AkamaEngage);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
scheduler.Update(diff);
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void sGossipSelect(Player* player, uint32 /*sender*/, uint32 action) override
|
||||
{
|
||||
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
|
||||
struct npc_creature_generator_akama : public ScriptedAI
|
||||
{
|
||||
npc_creature_generator_akama(Creature* creature) : NullCreatureAI(creature), summons(me)
|
||||
npc_creature_generator_akama(Creature* creature) : ScriptedAI(creature), summons(me)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint8 spawnCounter = 0;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
scheduler.CancelAll();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (summon->GetEntry() == NPC_ASHTONGUE_SORCERER)
|
||||
spawnCounter++;
|
||||
ScriptedAI::JustSummoned(summon);
|
||||
|
||||
switch (summon->GetEntry())
|
||||
{
|
||||
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)
|
||||
case NPC_ASHTONGUE_SORCERER:
|
||||
if (Creature* shade = instance->GetCreature(DATA_SHADE_OF_AKAMA))
|
||||
{
|
||||
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;
|
||||
float x, y, z;
|
||||
shade->GetNearPoint(shade, x, y, z, 20.f, 0, shade->GetAngle(summon));
|
||||
summon->GetMotionMaster()->MovePoint(POINT_ENGAGE, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
summon->SetInCombatWithZone();
|
||||
if (Unit* akama = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_AKAMA_SHADE)))
|
||||
{
|
||||
summon->AddThreat(akama, 500.0f);
|
||||
summon->AI()->AttackStart(akama);
|
||||
break;
|
||||
default:
|
||||
summon->SetInCombatWithZone();
|
||||
if (Creature* akama = instance->GetCreature(DATA_AKAMA_SHADE))
|
||||
summon->AI()->AttackStart(akama);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit*) override
|
||||
{
|
||||
spawnCounter--;
|
||||
summon->DespawnOrUnsummon(10000);
|
||||
summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param == ACTION_STOP_SPAWNING || param == ACTION_DESPAWN_ALL)
|
||||
switch (param)
|
||||
{
|
||||
events.Reset();
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
case ACTION_GENERATOR_STOP:
|
||||
scheduler.CancelAll();
|
||||
break;
|
||||
case ACTION_GENERATOR_START:
|
||||
if (me->GetPositionY() > 400.0f) // Right Side
|
||||
{
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||
ScheduleTimedEvent(10s, [&]
|
||||
{
|
||||
if (summon->GetEntry() != NPC_ASHTONGUE_SORCERER)
|
||||
continue;
|
||||
summon->InterruptNonMeleeSpells(false);
|
||||
summon->GetMotionMaster()->Clear();
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
if (spawnCounter <= COUNTER_SPAWNS_MAX)
|
||||
DoCastSelf(SPELL_ASHTONGUE_WAVE_B);
|
||||
}, 50s, 60s);
|
||||
|
||||
ScheduleTimedEvent(2s, 5s, [&]
|
||||
{
|
||||
if (spawnCounter <= COUNTER_SPAWNS_MAX)
|
||||
DoCastSelf(SPELL_SUMMON_ASHTONGUE_DEFENDER);
|
||||
}, 30s, 40s);
|
||||
}
|
||||
}
|
||||
if (param == ACTION_DESPAWN_ALL)
|
||||
|
||||
if (me->GetPositionY() < 400.0f) // Left Side
|
||||
{
|
||||
ScheduleTimedEvent(3s, [&]
|
||||
{
|
||||
if (spawnCounter <= COUNTER_SPAWNS_MAX)
|
||||
DoCastSelf(SPELL_ASHTONGUE_WAVE_B);
|
||||
}, 50s, 60s);
|
||||
|
||||
ScheduleTimedEvent(2s, 5s, [&]
|
||||
{
|
||||
if (spawnCounter <= COUNTER_SPAWNS_MAX)
|
||||
DoCastSelf(SPELL_SUMMON_ASHTONGUE_SORCERER);
|
||||
}, 30s, 35s);
|
||||
}
|
||||
break;
|
||||
case ACTION_GENERATOR_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);
|
||||
scheduler.CancelAll();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
InstanceScript* instance;
|
||||
};
|
||||
|
||||
struct npc_ashtongue_sorcerer : public NullCreatureAI
|
||||
{
|
||||
npc_ashtongue_sorcerer(Creature* creature) : NullCreatureAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && point == POINT_ENGAGE)
|
||||
me->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL, true);
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
};
|
||||
|
||||
struct npc_ashtongue_channeler : public NullCreatureAI
|
||||
{
|
||||
npc_ashtongue_channeler(Creature* creature) : NullCreatureAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
scheduler.Schedule(3600ms, [this](TaskContext context)
|
||||
{
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING))
|
||||
me->CastSpell(me, SPELL_SHADE_SOUL_CHANNEL, true);
|
||||
|
||||
context.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
scheduler.Update(diff);
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
TaskScheduler scheduler;
|
||||
};
|
||||
|
||||
class spell_shade_of_akama_shade_soul_channel : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_shade_of_akama_shade_soul_channel);
|
||||
@@ -562,6 +510,8 @@ void AddSC_boss_shade_of_akama()
|
||||
RegisterBlackTempleCreatureAI(boss_shade_of_akama);
|
||||
RegisterBlackTempleCreatureAI(npc_akama_shade);
|
||||
RegisterBlackTempleCreatureAI(npc_creature_generator_akama);
|
||||
RegisterBlackTempleCreatureAI(npc_ashtongue_channeler);
|
||||
RegisterBlackTempleCreatureAI(npc_ashtongue_sorcerer);
|
||||
RegisterSpellScript(spell_shade_of_akama_shade_soul_channel);
|
||||
RegisterSpellScript(spell_shade_of_akama_akama_soul_expel);
|
||||
}
|
||||
|
||||
@@ -152,15 +152,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ObjectGuid councilGUIDs[4];
|
||||
|
||||
void Reset() override
|
||||
void EnterEvadeMode(EvadeReason why)
|
||||
{
|
||||
BossAI::Reset();
|
||||
Creature* member = nullptr;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
if ((member = ObjectAccessor::GetCreature(*me, councilGUIDs[i])))
|
||||
for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i)
|
||||
if (Creature* member = instance->GetCreature(i))
|
||||
member->AI()->EnterEvadeMode();
|
||||
|
||||
BossAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
void AttackStart(Unit*) override { }
|
||||
@@ -171,15 +169,11 @@ public:
|
||||
if (!me->isActiveObject() && param == ACTION_START_ENCOUNTER)
|
||||
{
|
||||
me->setActive(true);
|
||||
councilGUIDs[0] = instance->GetGuidData(NPC_GATHIOS_THE_SHATTERER);
|
||||
councilGUIDs[1] = instance->GetGuidData(NPC_HIGH_NETHERMANCER_ZEREVOR);
|
||||
councilGUIDs[2] = instance->GetGuidData(NPC_LADY_MALANDE);
|
||||
councilGUIDs[3] = instance->GetGuidData(NPC_VERAS_DARKSHADOW);
|
||||
|
||||
bool spoken = false;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i)
|
||||
{
|
||||
if (Creature* member = ObjectAccessor::GetCreature(*me, councilGUIDs[i]))
|
||||
if (Creature* member = instance->GetCreature(i))
|
||||
{
|
||||
if (!spoken && (roll_chance_i(33) || i == 3))
|
||||
{
|
||||
@@ -193,17 +187,15 @@ public:
|
||||
}
|
||||
else if (param == ACTION_ENRAGE)
|
||||
{
|
||||
Creature* member = nullptr;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
if ((member = ObjectAccessor::GetCreature(*me, councilGUIDs[i])))
|
||||
for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i)
|
||||
if (Creature* member = instance->GetCreature(i))
|
||||
member->AI()->DoAction(ACTION_ENRAGE);
|
||||
}
|
||||
else if (param == ACTION_END_ENCOUNTER)
|
||||
{
|
||||
me->setActive(false);
|
||||
Creature* member = nullptr;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
if ((member = ObjectAccessor::GetCreature(*me, councilGUIDs[i])))
|
||||
for (uint8 i = DATA_GATHIOS_THE_SHATTERER; i <= DATA_VERAS_DARKSHADOW; ++i)
|
||||
if (Creature* member = instance->GetCreature(i))
|
||||
if (member->IsAlive())
|
||||
Unit::Kill(me, member);
|
||||
me->KillSelf();
|
||||
@@ -217,7 +209,7 @@ public:
|
||||
|
||||
if (!SelectTargetFromPlayerList(115.0f))
|
||||
{
|
||||
EnterEvadeMode();
|
||||
EnterEvadeMode(EVADE_REASON_NO_HOSTILES);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -268,13 +260,13 @@ struct boss_illidari_council_memberAI : public ScriptedAI
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
Talk(SAY_COUNCIL_DEATH);
|
||||
if (Creature* council = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDARI_COUNCIL)))
|
||||
if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL))
|
||||
council->GetAI()->DoAction(ACTION_END_ENCOUNTER);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
if (Creature* council = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDARI_COUNCIL)))
|
||||
if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL))
|
||||
council->GetAI()->DoAction(ACTION_START_ENCOUNTER);
|
||||
}
|
||||
};
|
||||
@@ -296,14 +288,14 @@ public:
|
||||
Creature* SelectCouncilMember()
|
||||
{
|
||||
if (roll_chance_i(50))
|
||||
return ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_LADY_MALANDE));
|
||||
return instance->GetCreature(DATA_LADY_MALANDE);
|
||||
|
||||
if (roll_chance_i(20))
|
||||
if (Creature* veras = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_VERAS_DARKSHADOW)))
|
||||
if (Creature* veras = instance->GetCreature(DATA_VERAS_DARKSHADOW))
|
||||
if (!veras->HasAura(SPELL_VANISH))
|
||||
return veras;
|
||||
|
||||
return ObjectAccessor::GetCreature(*me, instance->GetGuidData(RAND(NPC_GATHIOS_THE_SHATTERER, NPC_HIGH_NETHERMANCER_ZEREVOR)));
|
||||
return instance->GetCreature(RAND(DATA_GATHIOS_THE_SHATTERER, DATA_HIGH_NETHERMANCER_ZEREVOR));
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
@@ -555,7 +547,7 @@ public:
|
||||
break;
|
||||
case EVENT_SPELL_ENRAGE:
|
||||
DoResetThreatList();
|
||||
if (Creature* council = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ILLIDARI_COUNCIL)))
|
||||
if (Creature* council = instance->GetCreature(DATA_ILLIDARI_COUNCIL))
|
||||
council->GetAI()->DoAction(ACTION_ENRAGE);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -36,12 +36,37 @@ DoorData const doorData[] =
|
||||
{ GO_MOTHER_SHAHRAZ_DOOR, DATA_MOTHER_SHAHRAZ, DOOR_TYPE_PASSAGE },
|
||||
{ GO_COUNCIL_DOOR_1, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM },
|
||||
{ GO_COUNCIL_DOOR_2, DATA_ILLIDARI_COUNCIL, DOOR_TYPE_ROOM },
|
||||
{ GO_ILLIDAN_GATE, DATA_AKAMA_FINISHED, DOOR_TYPE_PASSAGE },
|
||||
{ GO_ILLIDAN_GATE, DATA_AKAMA_ILLIDAN, DOOR_TYPE_PASSAGE },
|
||||
{ GO_ILLIDAN_DOOR_L, DATA_ILLIDAN_STORMRAGE, DOOR_TYPE_ROOM },
|
||||
{ GO_ILLIDAN_DOOR_R, DATA_ILLIDAN_STORMRAGE, DOOR_TYPE_ROOM },
|
||||
{ 0, 0, DOOR_TYPE_ROOM }
|
||||
};
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_HIGH_WARLORD_NAJENTUS, DATA_HIGH_WARLORD_NAJENTUS },
|
||||
{ NPC_SUPREMUS, DATA_SUPREMUS },
|
||||
{ NPC_SHADE_OF_AKAMA, DATA_SHADE_OF_AKAMA },
|
||||
{ NPC_AKAMA_SHADE, DATA_AKAMA_SHADE },
|
||||
{ NPC_TERON_GOREFIEND, DATA_TERON_GOREFIEND },
|
||||
{ NPC_GURTOGG_BLOODBOIL, DATA_GURTOGG_BLOODBOIL },
|
||||
{ NPC_RELIQUARY_OF_THE_LOST, DATA_RELIQUARY_OF_SOULS },
|
||||
{ NPC_MOTHER_SHAHRAZ, DATA_MOTHER_SHAHRAZ },
|
||||
{ NPC_ILLIDARI_COUNCIL, DATA_ILLIDARI_COUNCIL },
|
||||
{ NPC_GATHIOS_THE_SHATTERER, DATA_GATHIOS_THE_SHATTERER },
|
||||
{ NPC_HIGH_NETHERMANCER_ZEREVOR, DATA_HIGH_NETHERMANCER_ZEREVOR },
|
||||
{ NPC_LADY_MALANDE, DATA_LADY_MALANDE },
|
||||
{ NPC_VERAS_DARKSHADOW, DATA_VERAS_DARKSHADOW },
|
||||
{ NPC_AKAMA_ILLIDAN, DATA_AKAMA_ILLIDAN },
|
||||
{ NPC_ILLIDAN_STORMRAGE, DATA_ILLIDAN_STORMRAGE },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
ObjectData const objectData[] =
|
||||
{
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
BossBoundaryData const boundaries =
|
||||
{
|
||||
{ DATA_HIGH_WARLORD_NAJENTUS, new RectangleBoundary(394.0f, 479.4f, 707.8f, 859.1f) },
|
||||
@@ -70,6 +95,7 @@ public:
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadDoorData(doorData);
|
||||
LoadBossBoundaries(boundaries);
|
||||
LoadObjectData(creatureData, objectData);
|
||||
|
||||
ashtongueGUIDs.clear();
|
||||
}
|
||||
@@ -78,52 +104,19 @@ public:
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_SHADE_OF_AKAMA:
|
||||
ShadeOfAkamaGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_AKAMA_SHADE:
|
||||
AkamaShadeGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_TERON_GOREFIEND:
|
||||
TeronGorefiendGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_RELIQUARY_OF_THE_LOST:
|
||||
ReliquaryGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_GATHIOS_THE_SHATTERER:
|
||||
GathiosTheShattererGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_HIGH_NETHERMANCER_ZEREVOR:
|
||||
HighNethermancerZerevorGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_LADY_MALANDE:
|
||||
LadyMalandeGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VERAS_DARKSHADOW:
|
||||
VerasDarkshadowGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_ILLIDARI_COUNCIL:
|
||||
IllidariCouncilGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_AKAMA:
|
||||
AkamaGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_ILLIDAN_STORMRAGE:
|
||||
IllidanStormrageGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VENGEFUL_SPIRIT:
|
||||
case NPC_SHADOWY_CONSTRUCT:
|
||||
if (Creature* teron = instance->GetCreature(TeronGorefiendGUID))
|
||||
if (Creature* teron = GetCreature(DATA_TERON_GOREFIEND))
|
||||
teron->AI()->JustSummoned(creature);
|
||||
break;
|
||||
case NPC_ENSLAVED_SOUL:
|
||||
if (Creature* reliquary = instance->GetCreature(ReliquaryGUID))
|
||||
if (Creature* reliquary = GetCreature(DATA_RELIQUARY_OF_SOULS))
|
||||
reliquary->AI()->JustSummoned(creature);
|
||||
break;
|
||||
case NPC_PARASITIC_SHADOWFIEND:
|
||||
case NPC_BLADE_OF_AZZINOTH:
|
||||
case NPC_FLAME_OF_AZZINOTH:
|
||||
if (Creature* illidan = instance->GetCreature(IllidanStormrageGUID))
|
||||
if (Creature* illidan = GetCreature(DATA_ILLIDAN_STORMRAGE))
|
||||
illidan->AI()->JustSummoned(creature);
|
||||
break;
|
||||
case NPC_ANGERED_SOUL_FRAGMENT:
|
||||
@@ -131,85 +124,38 @@ public:
|
||||
case NPC_SUFFERING_SOUL_FRAGMENT:
|
||||
creature->SetCorpseDelay(5);
|
||||
break;
|
||||
case NPC_ASHTONGUE_BATTLELORD:
|
||||
case NPC_ASHTONGUE_MYSTIC:
|
||||
case NPC_ASHTONGUE_STORMCALLER:
|
||||
case NPC_ASHTONGUE_PRIMALIST:
|
||||
case NPC_ASHTONGUE_FERAL_SPIRIT:
|
||||
case NPC_ASHTONGUE_STALKER:
|
||||
case NPC_STORM_FURY:
|
||||
if (GetBossState(DATA_SHADE_OF_AKAMA) == DONE)
|
||||
creature->SetFaction(FACTION_ASHTONGUE_DEATHSWORN);
|
||||
else
|
||||
ashtongueGUIDs.insert(creature->GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (creature->GetName().find("Ashtongue") != std::string::npos || creature->GetEntry() == NPC_STORM_FURY)
|
||||
{
|
||||
ashtongueGUIDs.push_back(creature->GetGUID());
|
||||
if (GetBossState(DATA_SHADE_OF_AKAMA) == DONE)
|
||||
creature->SetFaction(FACTION_ASHTONGUE_DEATHSWORN);
|
||||
}
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
// If created after Illidari Council is done, then skip Akama's event. Used for crashes/reset
|
||||
if (go->GetEntry() == GO_ILLIDAN_GATE)
|
||||
{
|
||||
case GO_NAJENTUS_GATE:
|
||||
case GO_SUPREMUS_GATE:
|
||||
case GO_SHADE_OF_AKAMA_DOOR:
|
||||
case GO_TERON_DOOR_1:
|
||||
case GO_TERON_DOOR_2:
|
||||
case GO_GURTOGG_DOOR:
|
||||
case GO_TEMPLE_DOOR:
|
||||
case GO_MOTHER_SHAHRAZ_DOOR:
|
||||
case GO_COUNCIL_DOOR_1:
|
||||
case GO_COUNCIL_DOOR_2:
|
||||
case GO_ILLIDAN_GATE:
|
||||
case GO_ILLIDAN_DOOR_R:
|
||||
case GO_ILLIDAN_DOOR_L:
|
||||
AddDoor(go);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_NAJENTUS_GATE:
|
||||
case GO_SUPREMUS_GATE:
|
||||
case GO_SHADE_OF_AKAMA_DOOR:
|
||||
case GO_TERON_DOOR_1:
|
||||
case GO_TERON_DOOR_2:
|
||||
case GO_GURTOGG_DOOR:
|
||||
case GO_TEMPLE_DOOR:
|
||||
case GO_MOTHER_SHAHRAZ_DOOR:
|
||||
case GO_COUNCIL_DOOR_1:
|
||||
case GO_COUNCIL_DOOR_2:
|
||||
case GO_ILLIDAN_GATE:
|
||||
case GO_ILLIDAN_DOOR_R:
|
||||
case GO_ILLIDAN_DOOR_L:
|
||||
RemoveDoor(go);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 type) const override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case NPC_SHADE_OF_AKAMA:
|
||||
return ShadeOfAkamaGUID;
|
||||
case NPC_AKAMA_SHADE:
|
||||
return AkamaShadeGUID;
|
||||
case NPC_GATHIOS_THE_SHATTERER:
|
||||
return GathiosTheShattererGUID;
|
||||
case NPC_HIGH_NETHERMANCER_ZEREVOR:
|
||||
return HighNethermancerZerevorGUID;
|
||||
case NPC_LADY_MALANDE:
|
||||
return LadyMalandeGUID;
|
||||
case NPC_VERAS_DARKSHADOW:
|
||||
return VerasDarkshadowGUID;
|
||||
case NPC_ILLIDARI_COUNCIL:
|
||||
return IllidariCouncilGUID;
|
||||
case NPC_AKAMA:
|
||||
return AkamaGUID;
|
||||
case NPC_ILLIDAN_STORMRAGE:
|
||||
return IllidanStormrageGUID;
|
||||
if (GetBossState(DATA_ILLIDARI_COUNCIL) == DONE)
|
||||
{
|
||||
SetBossState(DATA_AKAMA_ILLIDAN, DONE);
|
||||
HandleGameObject(ObjectGuid::Empty, true, go);
|
||||
}
|
||||
}
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
InstanceScript::OnGameObjectCreate(go);
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 type, EncounterState state) override
|
||||
@@ -225,26 +171,15 @@ public:
|
||||
}
|
||||
else if (type == DATA_ILLIDARI_COUNCIL && state == DONE)
|
||||
{
|
||||
if (Creature* akama = instance->GetCreature(AkamaGUID))
|
||||
akama->SetVisible(true);
|
||||
if (Creature* akama = GetCreature(DATA_AKAMA_ILLIDAN))
|
||||
akama->AI()->DoAction(0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
ObjectGuid ShadeOfAkamaGUID;
|
||||
ObjectGuid AkamaShadeGUID;
|
||||
ObjectGuid TeronGorefiendGUID;
|
||||
ObjectGuid ReliquaryGUID;
|
||||
GuidList ashtongueGUIDs;
|
||||
ObjectGuid GathiosTheShattererGUID;
|
||||
ObjectGuid HighNethermancerZerevorGUID;
|
||||
ObjectGuid LadyMalandeGUID;
|
||||
ObjectGuid VerasDarkshadowGUID;
|
||||
ObjectGuid IllidariCouncilGUID;
|
||||
ObjectGuid AkamaGUID;
|
||||
ObjectGuid IllidanStormrageGUID;
|
||||
GuidSet ashtongueGUIDs;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
|
||||
Reference in New Issue
Block a user