diff options
author | Keader <keader.android@gmail.com> | 2017-10-26 23:10:00 -0300 |
---|---|---|
committer | funjoker <funjoker109@gmail.com> | 2021-01-21 22:30:40 +0100 |
commit | 8a6fdb7a21d43bb61bd27ce7cd57663e957e6689 (patch) | |
tree | 7f42cec97825abbc4ac880f831d927ac4b07416d /src | |
parent | b17a23635d5e1d36cc4f51866e85d11d9442ccbf (diff) |
Scripts/BlackTemple: Updates on Illidan encounter
- Fixed issues related with Parasitic Shadowfiend
- Updated script to new model
- Fixed loop of Parasitic Shadowfiend Summon
- Added a new spell (SPELL_REMOVE_PARASITIC_SHADOWFIEND)
- Fixed illidari elite attacking players
- SPELL_PARASITIC_SHADOWFIEND now is a negative aura
(cherry picked from commit 90f07bd948546595a04d7633eaa95a463f0ce6f9)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 4 | ||||
-rw-r--r-- | src/server/scripts/Outland/BlackTemple/black_temple.h | 5 | ||||
-rw-r--r-- | src/server/scripts/Outland/BlackTemple/boss_illidan.cpp | 3213 |
3 files changed, 1498 insertions, 1724 deletions
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 495c5ab068b..e422abe4690 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -4219,6 +4219,10 @@ bool SpellInfo::_IsPositiveEffect(uint32 effIndex, bool deep) const case 29214: // Wrath of the Plaguebringer case 34700: // Allergic Reaction case 54836: // Wrath of the Plaguebringer + case 61987: // Avenging Wrath Marker + case 61988: // Divine Shield exclude aura + case 41914: // Parasitic Shadowfiend (Illidan) + case 41917: // Parasitic Shadowfiend (Illidan) return false; case 30877: // Tag Murloc case 61716: // Rabbit Costume diff --git a/src/server/scripts/Outland/BlackTemple/black_temple.h b/src/server/scripts/Outland/BlackTemple/black_temple.h index 10be8f5c633..a4a8f6913e9 100644 --- a/src/server/scripts/Outland/BlackTemple/black_temple.h +++ b/src/server/scripts/Outland/BlackTemple/black_temple.h @@ -105,7 +105,8 @@ enum BTCreatureIds NPC_ILLIDARI_ELITE = 23226, NPC_GLAIVE_TARGET = 23448, NPC_GLAIVE_WORLD_TRIGGER = 22515, - NPC_DEMON_FIRE = 23069 + NPC_DEMON_FIRE = 23069, + NPC_PARASITIC_SHADOWFIEND = 23498 }; enum BTGameObjectIds @@ -143,4 +144,6 @@ inline AI* GetBlackTempleAI(T* obj) return GetInstanceAI<AI>(obj, BTScriptName); } +#define RegisterBlackTempleCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetBlackTempleAI) + #endif // BLACK_TEMPLE_H_ diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp index 92a3c12353d..e75bdb65df4 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp @@ -159,6 +159,8 @@ enum IllidanSpells SPELL_DRAW_SOUL = 40904, SPELL_DRAW_SOUL_HEAL = 40903, SPELL_PARASITIC_SHADOWFIEND = 41917, + SPELL_PARASITIC_SHADOWFIEND_2 = 41914, + SPELL_REMOVE_PARASITIC_SHADOWFIEND = 41923, SPELL_AGONIZING_FLAMES = 40932, SPELL_AGONIZING_FLAMES_SELECTOR = 40834, SPELL_FRENZY = 40683, @@ -211,6 +213,7 @@ enum IllidanActions ACTION_FLAME_DEAD, ACTION_FINALIZE_AIR_PHASE, ACTION_START_PHASE_4, + ACTION_RESUME_COMBAT, ACTION_ILLIDAN_CAGED, ACTION_START_OUTRO, ACTION_MAIEV_DOWN_FADE @@ -446,2106 +449,1870 @@ private: Unit const* _me; }; -class boss_illidan_stormrage : public CreatureScript +struct boss_illidan_stormrage : public BossAI { -public: - boss_illidan_stormrage() : CreatureScript("boss_illidan_stormrage") { } + boss_illidan_stormrage(Creature* creature) : BossAI(creature, DATA_ILLIDAN_STORMRAGE), + _minionsCount(0), _flameCount(0), _orientation(0.0f), _pillarIndex(0), _phase(0), _dead(false), _isDemon(false) { } + + void Reset() override + { + _Reset(); + specialEvents.Reset(); + me->SummonCreatureGroup(SUMMON_GROUP); + me->LoadEquipment(1, true); + me->SetSheath(SHEATH_STATE_UNARMED); + me->SetControlled(false, UNIT_STATE_ROOT); + me->SetDisableGravity(false); + _dead = false; + _minionsCount = 0; + _flameCount = 0; + _phase = PHASE_1; + _isDemon = false; + if (instance->GetData(DATA_AKAMA_ILLIDAN_INTRO) && instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE) + if (Creature* akama = instance->GetCreature(DATA_AKAMA)) + akama->AI()->DoAction(ACTION_ACTIVE_AKAMA_INTRO); + } + + void EnterCombat(Unit* /*who*/) override + { + _EnterCombat(); + me->SetCanDualWield(true); + if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_3_SOUND_ID); + specialEvents.ScheduleEvent(EVENT_EVADE_CHECK, Seconds(10)); + specialEvents.ScheduleEvent(EVENT_BERSERK, Minutes(25)); + ScheduleEvents(GROUP_PHASE_1, GROUP_PHASE_1); + events.ScheduleEvent(EVENT_TAUNT, Seconds(30), Seconds(60), GROUP_PHASE_ALL); + } + + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_PARASITIC_SHADOWFIEND) + summons.Summon(summon); + else + BossAI::JustSummoned(summon); + } + + void ChangeOrientation(float orientation) + { + _orientation = orientation; + events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, Milliseconds(1), GROUP_PHASE_ALL); + } + + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_ILLIDAN_KILL); + } + + void ScheduleEvents(uint8 phase, uint8 group) + { + switch (phase) + { + case GROUP_PHASE_1: + events.ScheduleEvent(EVENT_FLAME_CRASH, Seconds(30), group); + events.ScheduleEvent(EVENT_DRAW_SOUL, Seconds(34), group); + events.ScheduleEvent(EVENT_SHEAR, Seconds(10), group); + events.ScheduleEvent(EVENT_PARASITIC_SHADOWFIEND, Seconds(26), group); + break; + case GROUP_PHASE_2: + events.ScheduleEvent(EVENT_FIREBALL, Seconds(1), Seconds(8), group); + events.ScheduleEvent(EVENT_EYE_BLAST, Seconds(1), Seconds(30), group); + if (roll_chance_i(50)) + events.ScheduleEvent(EVENT_DARK_BARRAGE, Seconds(1), Seconds(20), group); + break; + case GROUP_PHASE_3: + ScheduleEvents(GROUP_PHASE_1, group); + events.ScheduleEvent(EVENT_AGONIZING_FLAMES, Seconds(21), group); + events.ScheduleEvent(EVENT_DEMON, Seconds(60), group); + break; + case GROUP_PHASE_DEMON: + events.ScheduleEvent(EVENT_SHADOW_BLAST, Seconds(1), group); + events.ScheduleEvent(EVENT_FLAME_BURST, Seconds(6), group); + events.ScheduleEvent(EVENT_SHADOW_DEMON, Seconds(18), Seconds(30), group); + break; + case GROUP_PHASE_4: + ScheduleEvents(GROUP_PHASE_3, group); + events.ScheduleEvent(EVENT_FRENZY, Seconds(40), group); + break; + default: + break; + } + } + + void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override + { + if (summon->GetEntry() == NPC_ILLIDARI_ELITE) + _minionsCount--; + } - struct boss_illidan_stormrageAI : public BossAI + void EnterEvadeMode(EvadeReason /*why*/) override { - boss_illidan_stormrageAI(Creature* creature) : BossAI(creature, DATA_ILLIDAN_STORMRAGE), - _minionsCount(0), _flameCount(0), _orientation(0.0f), _pillarIndex(0), _phase(0), _dead(false), _isDemon(false) { } + summons.DespawnAll(); + specialEvents.Reset(); + _DespawnAtEvade(); + } - void Reset() override + void DoAction(int32 actionId) override + { + switch (actionId) { - _Reset(); - specialEvents.Reset(); - me->SummonCreatureGroup(SUMMON_GROUP); - me->LoadEquipment(1, true); - me->SetSheath(SHEATH_STATE_UNARMED); - me->SetControlled(false, UNIT_STATE_ROOT); - me->SetDisableGravity(false); - _dead = false; - _minionsCount = 0; - _flameCount = 0; - _phase = PHASE_1; - _isDemon = false; - if (instance->GetData(DATA_AKAMA_ILLIDAN_INTRO) && instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE) + case ACTION_START_ENCOUNTER: + events.SetPhase(PHASE_INTRO); + me->RemoveAurasDueToSpell(SPELL_KNEEL); + events.ScheduleEvent(EVENT_START_INTRO, Seconds(2), GROUP_PHASE_ALL); + events.ScheduleEvent(EVENT_UNCONVINCED, Seconds(24), GROUP_PHASE_ALL); if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_ACTIVE_AKAMA_INTRO); + akama->AI()->DoAction(ACTION_FREE); + break; + case ACTION_INTRO_DONE: + instance->SetData(DATA_AKAMA_ILLIDAN_INTRO, 0); + break; + case ACTION_START_MINIONS: + Talk(SAY_ILLIDAN_MINION); + if (Creature* akama = instance->GetCreature(DATA_AKAMA)) + akama->AI()->DoAction(ACTION_START_MINIONS); + break; + case ACTION_START_MINIONS_WEAVE: + events.ScheduleEvent(EVENT_MINIONS_WEAVE, Milliseconds(1), GROUP_PHASE_ALL); + break; + case ACTION_START_PHASE_2: + { + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); + me->SetDisableGravity(true); + DoPlaySoundToSet(me, ILLIDAN_TAKEOFF_SOUND_ID); + events.ScheduleEvent(EVENT_FLY, Seconds(1), GROUP_PHASE_ALL); + events.CancelEventGroup(GROUP_PHASE_1); + break; + } + case ACTION_FLAME_DEAD: + _flameCount++; + if (_flameCount == 2) + { + _flameCount = 0; + DoAction(ACTION_FINALIZE_AIR_PHASE); + } + break; + case ACTION_FINALIZE_AIR_PHASE: + me->InterruptNonMeleeSpells(false); + me->GetMotionMaster()->Clear(); + events.CancelEventGroup(GROUP_PHASE_2); + _phase = PHASE_3; + events.CancelEvent(EVENT_FLY_TO_RANDOM_PILLAR); + me->GetMotionMaster()->MovePoint(POINT_ILLIDAN_MIDDLE, IllidanMiddlePoint); + break; + case ACTION_START_PHASE_4: + events.CancelEventGroup(GROUP_PHASE_3); + DoCastSelf(SPELL_SHADOW_PRISON, true); + summons.DoAction(ACTION_START_PHASE_4, EntryCheckPredicate(NPC_PARASITIC_SHADOWFIEND)); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + events.ScheduleEvent(EVENT_SHADOW_PRISON_TEXT, Milliseconds(500), GROUP_PHASE_ALL); + break; + case ACTION_ILLIDAN_CAGED: + for (uint32 summonSpell : SummonCageTrapSpells) + DoCastSelf(summonSpell, true); + DoCastSelf(SPELL_CAGE_TRAP, true); + break; + case ACTION_START_OUTRO: + me->AttackStop(); + events.Reset(); + specialEvents.Reset(); + DoCastSelf(SPELL_DEATH, true); + me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + events.ScheduleEvent(EVENT_DEFEATED_TEXT, Seconds(4)); + break; + default: + break; } + } + + void JustDied(Unit* /*killer*/) override + { + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + instance->SetBossState(DATA_ILLIDAN_STORMRAGE, DONE); + events.Reset(); + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) + return; - void EnterCombat(Unit* /*who*/) override + switch (pointId) { - _EnterCombat(); - me->SetCanDualWield(true); - if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_3_SOUND_ID); - specialEvents.ScheduleEvent(EVENT_EVADE_CHECK, Seconds(10)); - specialEvents.ScheduleEvent(EVENT_BERSERK, Minutes(25)); - ScheduleEvents(GROUP_PHASE_1, GROUP_PHASE_1); - events.ScheduleEvent(EVENT_TAUNT, Seconds(30), Seconds(60), GROUP_PHASE_ALL); + case POINT_THROW_GLAIVE: + DoPlaySoundToSet(me, ILLIDAN_WARGLAIVE_SOUND_ID); + events.ScheduleEvent(EVENT_THROW_WARGLAIVE, Seconds(2), GROUP_PHASE_ALL); + events.ScheduleEvent(EVENT_FACE_MIDDLE, Milliseconds(1), GROUP_PHASE_ALL); + break; + case POINT_RANDOM_PILLAR: + { + float orientation = IllidanPhase2Positions[_pillarIndex].GetOrientation(); + ChangeOrientation(orientation); + ScheduleEvents(GROUP_PHASE_2, GROUP_PHASE_2); + break; + } + case POINT_ILLIDAN_MIDDLE: + { + float orientation = IllidanMiddlePoint.GetOrientation(); + ChangeOrientation(orientation); + + std::list<Creature*> triggers; + GetCreatureListWithEntryInGrid(triggers, me, NPC_BLADE_OF_AZZINOTH, 150.0f); + for (Creature* trigger : triggers) + trigger->CastSpell(trigger, SPELL_GLAIVE_RETURNS, true); + + events.ScheduleEvent(EVENT_GLAIVE_EMOTE, Seconds(3), GROUP_PHASE_ALL); + break; + } + default: + break; } + } - void ChangeOrientation(float orientation) + void EnterEvadeModeIfNeeded() + { + Map::PlayerList const& players = me->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) + if (Player* player = i->GetSource()) + if (player->IsAlive() && !player->IsGameMaster() && CheckBoundary(player)) + return; + + EnterEvadeMode(EVADE_REASON_NO_HOSTILES); + } + + void SummonMinions() + { + uint8 needSummon = MAX_MINIONS_NUMBER - _minionsCount; + for (uint8 i = 0; i < needSummon; ++i) { - _orientation = orientation; - events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, Milliseconds(1), GROUP_PHASE_ALL); + _minionsCount++; + me->SummonCreature(NPC_ILLIDARI_ELITE, MinionsSpawnPositions[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 6000); } + } - void KilledUnit(Unit* victim) override + void DamageTaken(Unit* who, uint32 &damage) override + { + + if (damage >= me->GetHealth() && who->GetGUID() != me->GetGUID()) { - if (victim->GetTypeId() == TYPEID_PLAYER) - Talk(SAY_ILLIDAN_KILL); + damage = me->GetHealth() - 1; + if (!_dead) + { + if (_isDemon) + { + events.Reset(); + specialEvents.Reset(); + DoCastSelf(SPELL_DEMON_TRANSFORM_1); + return; + } + _dead = true; + summons.DespawnEntry(NPC_PARASITIC_SHADOWFIEND); + DoCastSelf(SPELL_REMOVE_PARASITIC_SHADOWFIEND, true); + DoAction(ACTION_START_OUTRO); + if (Creature* maiev = instance->GetCreature(DATA_MAIEV)) + maiev->AI()->DoAction(ACTION_START_OUTRO); + } + } + else if (me->HealthBelowPct(90) && _phase < PHASE_MINIONS) + { + _phase = PHASE_MINIONS; + DoAction(ACTION_START_MINIONS); + } + else if (me->HealthBelowPct(65) && _phase < PHASE_2) + { + _phase = PHASE_2; + DoAction(ACTION_START_PHASE_2); + } + else if (me->HealthBelowPct(30) && _phase < PHASE_4) + { + _phase = PHASE_4; + + if (_isDemon) + { + _isDemon = false; + me->SetControlled(false, UNIT_STATE_ROOT); + events.CancelEventGroup(GROUP_PHASE_DEMON); + me->InterruptNonMeleeSpells(false); + DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); + events.ScheduleEvent(EVENT_PHASE_4_DELAYED, Seconds(12), GROUP_PHASE_ALL); + } + else + DoAction(ACTION_START_PHASE_4); } + } - void ScheduleEvents(uint8 phase, uint8 group) + void ExecuteSpecialEvents() + { + while (uint32 eventId = specialEvents.ExecuteEvent()) { - switch (phase) + switch (eventId) { - case GROUP_PHASE_1: - events.ScheduleEvent(EVENT_FLAME_CRASH, Seconds(30), group); - events.ScheduleEvent(EVENT_DRAW_SOUL, Seconds(34), group); - events.ScheduleEvent(EVENT_SHEAR, Seconds(10), group); - events.ScheduleEvent(EVENT_PARASITIC_SHADOWFIEND, Seconds(26), group); - break; - case GROUP_PHASE_2: - events.ScheduleEvent(EVENT_FIREBALL, Seconds(1), Seconds(8), group); - events.ScheduleEvent(EVENT_EYE_BLAST, Seconds(1), Seconds(30), group); - if (roll_chance_i(50)) - events.ScheduleEvent(EVENT_DARK_BARRAGE, Seconds(1), Seconds(20), group); - break; - case GROUP_PHASE_3: - ScheduleEvents(GROUP_PHASE_1, group); - events.ScheduleEvent(EVENT_AGONIZING_FLAMES, Seconds(21), group); - events.ScheduleEvent(EVENT_DEMON, Seconds(60), group); - break; - case GROUP_PHASE_DEMON: - events.ScheduleEvent(EVENT_SHADOW_BLAST, Seconds(1), group); - events.ScheduleEvent(EVENT_FLAME_BURST, Seconds(6), group); - events.ScheduleEvent(EVENT_SHADOW_DEMON, Seconds(18), Seconds(30), group); - break; - case GROUP_PHASE_4: - ScheduleEvents(GROUP_PHASE_3, group); - events.ScheduleEvent(EVENT_FRENZY, Seconds(40), group); + case EVENT_BERSERK: + Talk(SAY_ILLIDAN_ENRAGE); + DoCastSelf(SPELL_BERSERK, true); + break; + case EVENT_CANCEL_DEMON_FORM: + me->InterruptNonMeleeSpells(false); + me->SetControlled(false, UNIT_STATE_ROOT); + events.CancelEventGroup(GROUP_PHASE_DEMON); + DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); + events.ScheduleEvent(EVENT_RESUME_COMBAT_DEMON, Seconds(12), GROUP_PHASE_ALL); + _isDemon = false; + break; + case EVENT_EVADE_CHECK: + EnterEvadeModeIfNeeded(); + specialEvents.Repeat(Seconds(10)); break; default: break; } } + } - void JustSummoned(Creature* summon) override - { - BossAI::JustSummoned(summon); - if (summon->GetEntry() == NPC_ILLIDARI_ELITE) - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - AddThreat(akama, 1000.0f, summon); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) + return; - void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override - { - if (summon->GetEntry() == NPC_ILLIDARI_ELITE) - _minionsCount--; - } + specialEvents.Update(diff); - void EnterEvadeMode(EvadeReason /*why*/) override - { - summons.DespawnAll(); - specialEvents.Reset(); - _DespawnAtEvade(); - } + ExecuteSpecialEvents(); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void DoAction(int32 actionId) override + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) { - switch (actionId) + switch (eventId) { - case ACTION_START_ENCOUNTER: - events.SetPhase(PHASE_INTRO); - me->RemoveAurasDueToSpell(SPELL_KNEEL); - events.ScheduleEvent(EVENT_START_INTRO, Seconds(2), GROUP_PHASE_ALL); - events.ScheduleEvent(EVENT_UNCONVINCED, Seconds(24), GROUP_PHASE_ALL); - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_FREE); + case EVENT_START_INTRO: + Talk(SAY_ILLIDAN_DUPLICITY); break; - case ACTION_INTRO_DONE: - instance->SetData(DATA_AKAMA_ILLIDAN_INTRO, 0); + case EVENT_UNCONVINCED: + Talk(SAY_ILLIDAN_UNCONVINCED); + events.ScheduleEvent(EVENT_PREPARED, Seconds(14), GROUP_PHASE_ALL); break; - case ACTION_START_MINIONS: - Talk(SAY_ILLIDAN_MINION); + case EVENT_PREPARED: + Talk(SAY_ILLIDAN_PREPARED); + me->SetSheath(SHEATH_STATE_MELEE); + events.ScheduleEvent(EVENT_ENCOUNTER_START, Seconds(3), GROUP_PHASE_ALL); + break; + case EVENT_ENCOUNTER_START: + me->SetImmuneToAll(false); + DoZoneInCombat(); if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_START_MINIONS); + akama->AI()->DoAction(ACTION_START_ENCOUNTER); break; - case ACTION_START_MINIONS_WEAVE: - events.ScheduleEvent(EVENT_MINIONS_WEAVE, Milliseconds(1), GROUP_PHASE_ALL); + case EVENT_FLAME_CRASH: + DoCastVictim(SPELL_FLAME_CRASH); + events.Repeat(Seconds(30)); break; - case ACTION_START_PHASE_2: - { - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - me->SetDisableGravity(true); - DoPlaySoundToSet(me, ILLIDAN_TAKEOFF_SOUND_ID); - events.ScheduleEvent(EVENT_FLY, Seconds(1), GROUP_PHASE_ALL); - events.CancelEventGroup(GROUP_PHASE_1); + case EVENT_DRAW_SOUL: + DoCastAOE(SPELL_DRAW_SOUL); + events.Repeat(Seconds(34)); break; - } - case ACTION_FLAME_DEAD: - _flameCount++; - if (_flameCount == 2) - { - _flameCount = 0; - DoAction(ACTION_FINALIZE_AIR_PHASE); - } + case EVENT_SHEAR: + DoCastVictim(SPELL_SHEAR); + events.Repeat(Seconds(12)); break; - case ACTION_FINALIZE_AIR_PHASE: - me->InterruptNonMeleeSpells(false); - me->GetMotionMaster()->Clear(); - events.CancelEventGroup(GROUP_PHASE_2); - _phase = PHASE_3; - events.CancelEvent(EVENT_FLY_TO_RANDOM_PILLAR); - me->GetMotionMaster()->MovePoint(POINT_ILLIDAN_MIDDLE, IllidanMiddlePoint); + case EVENT_PARASITIC_SHADOWFIEND: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) + DoCast(target, SPELL_PARASITIC_SHADOWFIEND); + events.Repeat(Seconds(30)); break; - case ACTION_START_PHASE_4: - events.CancelEventGroup(GROUP_PHASE_3); - DoCastSelf(SPELL_SHADOW_PRISON, true); - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - events.ScheduleEvent(EVENT_SHADOW_PRISON_TEXT, Milliseconds(500), GROUP_PHASE_ALL); + case EVENT_MINIONS_WEAVE: + if (_dead) + return; + SummonMinions(); + events.Repeat(Seconds(30)); break; - case ACTION_ILLIDAN_CAGED: - for (uint32 summonSpell : SummonCageTrapSpells) - DoCastSelf(summonSpell, true); - DoCastSelf(SPELL_CAGE_TRAP, true); + case EVENT_MOVE_TO_WARGLAIVE_POINT: + { + Position pos; + std::list<Creature*> triggers; + GetCreatureListWithEntryInGrid(triggers, me, NPC_GLAIVE_WORLD_TRIGGER, 150.0f); + triggers.remove_if([](WorldObject* unit) + { + return unit->GetPositionZ() < 355.0f || unit->GetPositionZ() > 365.0f; + }); + + if (triggers.empty()) + break; + + triggers.sort(Trinity::ObjectDistanceOrderPred(me)); + pos.Relocate(triggers.front()); + pos.SetOrientation(0.0f); + me->GetMotionMaster()->MovePoint(POINT_THROW_GLAIVE, pos); + if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_HERO_2_SOUND_ID); break; - case ACTION_START_OUTRO: - me->AttackStop(); - events.Reset(); - specialEvents.Reset(); - DoCastSelf(SPELL_DEATH, true); - me->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - events.ScheduleEvent(EVENT_DEFEATED_TEXT, Seconds(4)); + } + case EVENT_THROW_WARGLAIVE: + DoCastAOE(SPELL_THROW_GLAIVE); + events.ScheduleEvent(EVENT_THROW_WARGLAIVE_2, Seconds(1), GROUP_PHASE_ALL); break; - default: + case EVENT_THROW_WARGLAIVE_2: + DoCastAOE(SPELL_THROW_GLAIVE2); + me->SetSheath(SHEATH_STATE_UNARMED); + events.ScheduleEvent(EVENT_FLY_TO_RANDOM_PILLAR, Seconds(2), GROUP_PHASE_ALL); break; - } - } - - void JustDied(Unit* /*killer*/) override - { - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - instance->SetBossState(DATA_ILLIDAN_STORMRAGE, DONE); - events.Reset(); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE) - return; - - switch (pointId) - { - case POINT_THROW_GLAIVE: - DoPlaySoundToSet(me, ILLIDAN_WARGLAIVE_SOUND_ID); - events.ScheduleEvent(EVENT_THROW_WARGLAIVE, Seconds(2), GROUP_PHASE_ALL); - events.ScheduleEvent(EVENT_FACE_MIDDLE, Milliseconds(1), GROUP_PHASE_ALL); + case EVENT_CHANGE_ORIENTATION: + me->SetFacingTo(_orientation); + break; + case EVENT_FLY: + ChangeOrientation(3.137039f); + events.ScheduleEvent(EVENT_MOVE_TO_WARGLAIVE_POINT, Seconds(6), GROUP_PHASE_ALL); break; - case POINT_RANDOM_PILLAR: + case EVENT_FLY_TO_RANDOM_PILLAR: { - float orientation = IllidanPhase2Positions[_pillarIndex].GetOrientation(); - ChangeOrientation(orientation); - ScheduleEvents(GROUP_PHASE_2, GROUP_PHASE_2); + events.CancelEventGroup(GROUP_PHASE_2); + _pillarIndex = urand(0, 3); + me->GetMotionMaster()->MovePoint(POINT_RANDOM_PILLAR, IllidanPhase2Positions[_pillarIndex]); + events.Repeat(Seconds(30)); break; } - case POINT_ILLIDAN_MIDDLE: + case EVENT_FACE_MIDDLE: { - float orientation = IllidanMiddlePoint.GetOrientation(); - ChangeOrientation(orientation); - - std::list<Creature*> triggers; - GetCreatureListWithEntryInGrid(triggers, me, NPC_BLADE_OF_AZZINOTH, 150.0f); - for (Creature* trigger : triggers) - trigger->CastSpell(trigger, SPELL_GLAIVE_RETURNS, true); - - events.ScheduleEvent(EVENT_GLAIVE_EMOTE, Seconds(3), GROUP_PHASE_ALL); + float angle = me->GetAngle(IllidanMiddlePoint); + me->SetFacingTo(angle); break; } - default: - break; - } - } - - void EnterEvadeModeIfNeeded() - { - Map::PlayerList const& players = me->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) - if (Player* player = i->GetSource()) - if (player->IsAlive() && !player->IsGameMaster() && CheckBoundary(player)) - return; - - EnterEvadeMode(EVADE_REASON_NO_HOSTILES); - } - - void SummonMinions() - { - uint8 needSummon = MAX_MINIONS_NUMBER - _minionsCount; - for (uint8 i = 0; i < needSummon; ++i) - { - _minionsCount++; - me->SummonCreature(NPC_ILLIDARI_ELITE, MinionsSpawnPositions[i], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 6000); - } - } - - void DamageTaken(Unit* who, uint32 &damage) override - { - - if (damage >= me->GetHealth() && who->GetGUID() != me->GetGUID()) - { - damage = me->GetHealth() - 1; - if (!_dead) + case EVENT_EYE_BLAST: { - if (_isDemon) + events.CancelEvent(EVENT_DARK_BARRAGE); + Position pos = IllidanDBTargetSpawnPositions[_pillarIndex]; + if (TempSummon* dbTarget = me->SummonCreature(NPC_ILLIDAN_DB_TARGET, pos, TEMPSUMMON_MANUAL_DESPAWN)) { - events.Reset(); - specialEvents.Reset(); - DoCastSelf(SPELL_DEMON_TRANSFORM_1); - return; + Talk(SAY_ILLIDAN_EYE_BLAST); + DoCast(dbTarget, SPELL_EYE_BLAST); + dbTarget->GetMotionMaster()->MovePoint(POINT_DB_TARGET, IllidanDBTargetPoints[_pillarIndex]); } - _dead = true; - DoAction(ACTION_START_OUTRO); - if (Creature* maiev = instance->GetCreature(DATA_MAIEV)) - maiev->AI()->DoAction(ACTION_START_OUTRO); + break; } - } - else if (me->HealthBelowPct(90) && _phase < PHASE_MINIONS) - { - _phase = PHASE_MINIONS; - DoAction(ACTION_START_MINIONS); - } - else if (me->HealthBelowPct(65) && _phase < PHASE_2) - { - _phase = PHASE_2; - DoAction(ACTION_START_PHASE_2); - } - else if (me->HealthBelowPct(30) && _phase < PHASE_4) - { - _phase = PHASE_4; - - if (_isDemon) + case EVENT_DARK_BARRAGE: { - _isDemon = false; - me->SetControlled(false, UNIT_STATE_ROOT); - events.CancelEventGroup(GROUP_PHASE_DEMON); - me->InterruptNonMeleeSpells(false); + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f, true)) + DoCast(target, SPELL_DARK_BARRAGE); + events.RescheduleEvent(EVENT_EYE_BLAST, Seconds(5), GROUP_PHASE_2); + uint32 currentTime = events.GetNextEventTime(EVENT_FLY_TO_RANDOM_PILLAR); + events.RescheduleEvent(EVENT_FLY_TO_RANDOM_PILLAR, Seconds(currentTime) + Seconds(30), GROUP_PHASE_2); + break; + } + case EVENT_FIREBALL: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f, true)) + DoCast(target, SPELL_FIREBALL); + events.Repeat(Seconds(2), Seconds(4)); + break; + case EVENT_GLAIVE_EMOTE: + me->SetDisableGravity(false); + me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); + me->SetSheath(SHEATH_STATE_MELEE); + events.ScheduleEvent(EVENT_RESUME_COMBAT, Seconds(3), GROUP_PHASE_ALL); + break; + case EVENT_RESUME_COMBAT: + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + ScheduleEvents(GROUP_PHASE_3, GROUP_PHASE_3); + if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_UNI_3_SOUND_ID); + break; + case EVENT_AGONIZING_FLAMES: + DoCastSelf(SPELL_AGONIZING_FLAMES_SELECTOR); + events.Repeat(Seconds(53)); + break; + case EVENT_DEMON: + me->SetControlled(true, UNIT_STATE_ROOT); + _isDemon = true; + events.CancelEventGroup(_phase == PHASE_3 ? GROUP_PHASE_3 : GROUP_PHASE_4); + me->LoadEquipment(0, true); DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); - events.ScheduleEvent(EVENT_PHASE_4_DELAYED, Seconds(12), GROUP_PHASE_ALL); + events.ScheduleEvent(EVENT_DEMON_TEXT, Seconds(2), GROUP_PHASE_ALL); + specialEvents.ScheduleEvent(EVENT_CANCEL_DEMON_FORM, Minutes(1) + Seconds(12)); + events.ScheduleEvent(EVENT_SCHEDULE_DEMON_SPELLS, Seconds(15)); + break; + case EVENT_SCHEDULE_DEMON_SPELLS: + ResetThreatList(); + ScheduleEvents(GROUP_PHASE_DEMON, GROUP_PHASE_DEMON); + break; + case EVENT_DEMON_TEXT: + Talk(SAY_ILLIDAN_MORPH); + break; + case EVENT_RESUME_COMBAT_DEMON: + { + uint8 group = _phase == PHASE_3 ? GROUP_PHASE_3 : GROUP_PHASE_4; + ResetThreatList(); + ScheduleEvents(group, group); + me->LoadEquipment(1, true); + break; } - else + case EVENT_FLAME_BURST: + DoCastSelf(SPELL_FLAME_BURST); + events.Repeat(Seconds(22)); + break; + case EVENT_SHADOW_DEMON: + DoCastSelf(SPELL_SUMMON_SHADOWDEMON); + break; + case EVENT_SHADOW_BLAST: + DoCastVictim(SPELL_SHADOW_BLAST); + events.Repeat(Seconds(2)); + break; + case EVENT_PHASE_4_DELAYED: DoAction(ACTION_START_PHASE_4); - } - } - - void ExecuteSpecialEvents() - { - while (uint32 eventId = specialEvents.ExecuteEvent()) - { - switch (eventId) + break; + case EVENT_SHADOW_PRISON_TEXT: + Talk(SAY_ILLIDAN_SHADOW_PRISON); + events.ScheduleEvent(EVENT_SUMMON_MAIEV, Seconds(9), GROUP_PHASE_ALL); + break; + case EVENT_SUMMON_MAIEV: + DoCastSelf(SPELL_SUMMON_MAIEV); + if (Creature* maiev = instance->GetCreature(DATA_MAIEV)) + me->SetFacingToObject(maiev); + events.ScheduleEvent(EVENT_CONFRONT_MAIEV_TEXT, Seconds(9), GROUP_PHASE_ALL); + break; + case EVENT_CONFRONT_MAIEV_TEXT: + Talk(SAY_ILLIDAN_CONFRONT_MAIEV); + events.ScheduleEvent(EVENT_RESUME_COMBAT_PHASE_4, Seconds(13), GROUP_PHASE_ALL); + break; + case EVENT_RESUME_COMBAT_PHASE_4: + me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + ScheduleEvents(GROUP_PHASE_4, GROUP_PHASE_4); + summons.DoAction(ACTION_RESUME_COMBAT, EntryCheckPredicate(NPC_PARASITIC_SHADOWFIEND)); + break; + case EVENT_FRENZY: + DoCastSelf(SPELL_FRENZY); + Talk(SAY_ILLIDAN_FRENZY); + events.Repeat(Seconds(40)); + break; + case EVENT_TAUNT: + Talk(SAY_ILLIDAN_TAUNT); + events.Repeat(Seconds(30), Seconds(60)); + break; + case EVENT_DEFEATED_TEXT: + Talk(SAY_ILLIDAN_DEFEATED); + if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_ARRIVAL_WALK_HERO_1_SOUND_ID); + events.ScheduleEvent(EVENT_QUIET_SUICIDE, Seconds(18)); + break; + case EVENT_QUIET_SUICIDE: { - case EVENT_BERSERK: - Talk(SAY_ILLIDAN_ENRAGE); - DoCastSelf(SPELL_BERSERK, true); - break; - case EVENT_CANCEL_DEMON_FORM: - me->InterruptNonMeleeSpells(false); - me->SetControlled(false, UNIT_STATE_ROOT); - events.CancelEventGroup(GROUP_PHASE_DEMON); - DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); - events.ScheduleEvent(EVENT_RESUME_COMBAT_DEMON, Seconds(12), GROUP_PHASE_ALL); - _isDemon = false; - break; - case EVENT_EVADE_CHECK: - EnterEvadeModeIfNeeded(); - specialEvents.Repeat(Seconds(10)); - break; - default: - break; + DoCastSelf(SPELL_QUIET_SUICIDE, true); + if (Creature* akama = instance->GetCreature(DATA_AKAMA)) + akama->AI()->DoAction(ACTION_START_OUTRO); + ObjectGuid _akamaGUID = instance->GetGuidData(DATA_AKAMA); + ObjectGuid _maievGUID = instance->GetGuidData(DATA_MAIEV); + summons.DespawnIf([_akamaGUID, _maievGUID](ObjectGuid unitGuid) + { + return unitGuid != _akamaGUID && unitGuid != _maievGUID; + }); + break; } + default: + break; } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !events.IsInPhase(PHASE_INTRO)) - return; - - specialEvents.Update(diff); - - ExecuteSpecialEvents(); if (me->HasUnitState(UNIT_STATE_CASTING)) return; + } - events.Update(diff); + DoMeleeAttackIfReady(); + } - while (uint32 eventId = events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_START_INTRO: - Talk(SAY_ILLIDAN_DUPLICITY); - break; - case EVENT_UNCONVINCED: - Talk(SAY_ILLIDAN_UNCONVINCED); - events.ScheduleEvent(EVENT_PREPARED, Seconds(14), GROUP_PHASE_ALL); - break; - case EVENT_PREPARED: - Talk(SAY_ILLIDAN_PREPARED); - me->SetSheath(SHEATH_STATE_MELEE); - events.ScheduleEvent(EVENT_ENCOUNTER_START, Seconds(3), GROUP_PHASE_ALL); - break; - case EVENT_ENCOUNTER_START: - me->SetImmuneToAll(false); - DoZoneInCombat(); - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_START_ENCOUNTER); - break; - case EVENT_FLAME_CRASH: - DoCastVictim(SPELL_FLAME_CRASH); - events.Repeat(Seconds(30)); - break; - case EVENT_DRAW_SOUL: - DoCastAOE(SPELL_DRAW_SOUL); - events.Repeat(Seconds(34)); - break; - case EVENT_SHEAR: - DoCastVictim(SPELL_SHEAR); - events.Repeat(Seconds(12)); - break; - case EVENT_PARASITIC_SHADOWFIEND: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) - DoCast(target, SPELL_PARASITIC_SHADOWFIEND); - events.Repeat(Seconds(30)); - break; - case EVENT_MINIONS_WEAVE: - SummonMinions(); - events.Repeat(Seconds(30)); - break; - case EVENT_MOVE_TO_WARGLAIVE_POINT: - { - Position pos; - std::list<Creature*> triggers; - GetCreatureListWithEntryInGrid(triggers, me, NPC_GLAIVE_WORLD_TRIGGER, 150.0f); - triggers.remove_if([](WorldObject* unit) - { - return unit->GetPositionZ() < 355.0f || unit->GetPositionZ() > 365.0f; - }); +private: + uint8 _minionsCount; + uint8 _flameCount; + float _orientation; + uint8 _pillarIndex; + uint8 _phase; + bool _dead; + bool _isDemon; + EventMap specialEvents; +}; - if (triggers.empty()) - break; +struct npc_akama_illidan : public ScriptedAI +{ + npc_akama_illidan(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), + _orientation(0.0f), _isTeleportToMinions(false) { } - triggers.sort(Trinity::ObjectDistanceOrderPred(me)); - pos.Relocate(triggers.front()); - pos.SetOrientation(0.0f); - me->GetMotionMaster()->MovePoint(POINT_THROW_GLAIVE, pos); - if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_HERO_2_SOUND_ID); - break; - } - case EVENT_THROW_WARGLAIVE: - DoCastAOE(SPELL_THROW_GLAIVE); - events.ScheduleEvent(EVENT_THROW_WARGLAIVE_2, Seconds(1), GROUP_PHASE_ALL); - break; - case EVENT_THROW_WARGLAIVE_2: - DoCastAOE(SPELL_THROW_GLAIVE2); - me->SetSheath(SHEATH_STATE_UNARMED); - events.ScheduleEvent(EVENT_FLY_TO_RANDOM_PILLAR, Seconds(2), GROUP_PHASE_ALL); - break; - case EVENT_CHANGE_ORIENTATION: - me->SetFacingTo(_orientation); - break; - case EVENT_FLY: - ChangeOrientation(3.137039f); - events.ScheduleEvent(EVENT_MOVE_TO_WARGLAIVE_POINT, Seconds(6), GROUP_PHASE_ALL); - break; - case EVENT_FLY_TO_RANDOM_PILLAR: - { - events.CancelEventGroup(GROUP_PHASE_2); - _pillarIndex = urand(0, 3); - me->GetMotionMaster()->MovePoint(POINT_RANDOM_PILLAR, IllidanPhase2Positions[_pillarIndex]); - events.Repeat(Seconds(30)); - break; - } - case EVENT_FACE_MIDDLE: - { - float angle = me->GetAngle(IllidanMiddlePoint); - me->SetFacingTo(angle); - break; - } - case EVENT_EYE_BLAST: - { - events.CancelEvent(EVENT_DARK_BARRAGE); - Position pos = IllidanDBTargetSpawnPositions[_pillarIndex]; - if (TempSummon* dbTarget = me->SummonCreature(NPC_ILLIDAN_DB_TARGET, pos, TEMPSUMMON_MANUAL_DESPAWN)) - { - Talk(SAY_ILLIDAN_EYE_BLAST); - DoCast(dbTarget, SPELL_EYE_BLAST); - dbTarget->GetMotionMaster()->MovePoint(POINT_DB_TARGET, IllidanDBTargetPoints[_pillarIndex]); - } - break; - } - case EVENT_DARK_BARRAGE: - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f, true)) - DoCast(target, SPELL_DARK_BARRAGE); - events.RescheduleEvent(EVENT_EYE_BLAST, Seconds(5), GROUP_PHASE_2); - uint32 currentTime = events.GetNextEventTime(EVENT_FLY_TO_RANDOM_PILLAR); - events.RescheduleEvent(EVENT_FLY_TO_RANDOM_PILLAR, Seconds(currentTime) + Seconds(30), GROUP_PHASE_2); - break; - } - case EVENT_FIREBALL: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 150.0f, true)) - DoCast(target, SPELL_FIREBALL); - events.Repeat(Seconds(2), Seconds(4)); - break; - case EVENT_GLAIVE_EMOTE: - me->SetDisableGravity(false); - me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); - me->SetSheath(SHEATH_STATE_MELEE); - events.ScheduleEvent(EVENT_RESUME_COMBAT, Seconds(3), GROUP_PHASE_ALL); - break; - case EVENT_RESUME_COMBAT: - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_AGGRESSIVE); - ScheduleEvents(GROUP_PHASE_3, GROUP_PHASE_3); - if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_STORM_WALK_UNI_3_SOUND_ID); - break; - case EVENT_AGONIZING_FLAMES: - DoCastSelf(SPELL_AGONIZING_FLAMES_SELECTOR); - events.Repeat(Seconds(53)); - break; - case EVENT_DEMON: - me->SetControlled(true, UNIT_STATE_ROOT); - _isDemon = true; - events.CancelEventGroup(_phase == PHASE_3 ? GROUP_PHASE_3 : GROUP_PHASE_4); - me->LoadEquipment(0, true); - DoCastSelf(SPELL_DEMON_TRANSFORM_1, true); - events.ScheduleEvent(EVENT_DEMON_TEXT, Seconds(2), GROUP_PHASE_ALL); - specialEvents.ScheduleEvent(EVENT_CANCEL_DEMON_FORM, Minutes(1) + Seconds(12)); - events.ScheduleEvent(EVENT_SCHEDULE_DEMON_SPELLS, Seconds(15)); - break; - case EVENT_SCHEDULE_DEMON_SPELLS: - ResetThreatList(); - ScheduleEvents(GROUP_PHASE_DEMON, GROUP_PHASE_DEMON); - break; - case EVENT_DEMON_TEXT: - Talk(SAY_ILLIDAN_MORPH); - break; - case EVENT_RESUME_COMBAT_DEMON: - { - uint8 group = _phase == PHASE_3 ? GROUP_PHASE_3 : GROUP_PHASE_4; - ResetThreatList(); - ScheduleEvents(group, group); - me->LoadEquipment(1, true); - break; - } - case EVENT_FLAME_BURST: - DoCastSelf(SPELL_FLAME_BURST); - events.Repeat(Seconds(22)); - break; - case EVENT_SHADOW_DEMON: - DoCastSelf(SPELL_SUMMON_SHADOWDEMON); - break; - case EVENT_SHADOW_BLAST: - DoCastVictim(SPELL_SHADOW_BLAST); - events.Repeat(Seconds(2)); - break; - case EVENT_PHASE_4_DELAYED: - DoAction(ACTION_START_PHASE_4); - break; - case EVENT_SHADOW_PRISON_TEXT: - Talk(SAY_ILLIDAN_SHADOW_PRISON); - events.ScheduleEvent(EVENT_SUMMON_MAIEV, Seconds(9), GROUP_PHASE_ALL); - break; - case EVENT_SUMMON_MAIEV: - DoCastSelf(SPELL_SUMMON_MAIEV); - if (Creature* maiev = instance->GetCreature(DATA_MAIEV)) - me->SetFacingToObject(maiev); - events.ScheduleEvent(EVENT_CONFRONT_MAIEV_TEXT, Seconds(9), GROUP_PHASE_ALL); - break; - case EVENT_CONFRONT_MAIEV_TEXT: - Talk(SAY_ILLIDAN_CONFRONT_MAIEV); - events.ScheduleEvent(EVENT_RESUME_COMBAT_PHASE_4, Seconds(13), GROUP_PHASE_ALL); - break; - case EVENT_RESUME_COMBAT_PHASE_4: - me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_AGGRESSIVE); - ScheduleEvents(GROUP_PHASE_4, GROUP_PHASE_4); - break; - case EVENT_FRENZY: - DoCastSelf(SPELL_FRENZY); - Talk(SAY_ILLIDAN_FRENZY); - events.Repeat(Seconds(40)); - break; - case EVENT_TAUNT: - Talk(SAY_ILLIDAN_TAUNT); - events.Repeat(Seconds(30), Seconds(60)); - break; - case EVENT_DEFEATED_TEXT: - Talk(SAY_ILLIDAN_DEFEATED); - if (GameObject* musicController = instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_ARRIVAL_WALK_HERO_1_SOUND_ID); - events.ScheduleEvent(EVENT_QUIET_SUICIDE, Seconds(18)); - break; - case EVENT_QUIET_SUICIDE: - { - DoCastSelf(SPELL_QUIET_SUICIDE, true); - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_START_OUTRO); - ObjectGuid _akamaGUID = instance->GetGuidData(DATA_AKAMA); - ObjectGuid _maievGUID = instance->GetGuidData(DATA_MAIEV); - summons.DespawnIf([_akamaGUID, _maievGUID](ObjectGuid unitGuid) - { - return unitGuid != _akamaGUID && unitGuid != _maievGUID; - }); - break; - } - default: - break; - } + void Reset() override + { + _events.Reset(); + _spiritOfUdaloGUID.Clear(); + _spiritOfOlumGUID.Clear(); + _isTeleportToMinions = false; + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } + bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + if (gossipListId == GOSSIP_START_INTRO) + { + _instance->SetData(DATA_AKAMA, AKAMA_FIGHT); + me->GetMotionMaster()->MoveAlongSplineChain(POINT_STAIRS, SPLINE_STAIRS, false); + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->DoAction(ACTION_INTRO_DONE); + CloseGossipMenuFor(player); - DoMeleeAttackIfReady(); } + else if (gossipListId == GOSSIP_START_FIGHT) + { + _events.SetPhase(PHASE_INTRO); + me->GetMotionMaster()->MoveAlongSplineChain(POINT_FACE_ILLIDAN, SPLINE_FACE_ILLIDAN, false); + me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + CloseGossipMenuFor(player); + } + return false; + } - private: - uint8 _minionsCount; - uint8 _flameCount; - float _orientation; - uint8 _pillarIndex; - uint8 _phase; - bool _dead; - bool _isDemon; - EventMap specialEvents; - }; + bool CanAIAttack(Unit const* who) const override + { + if (_events.IsInPhase(PHASE_MINIONS) && who->GetEntry() == NPC_ILLIDAN_STORMRAGE) + return false; + return ScriptedAI::CanAIAttack(who); + } - CreatureAI* GetAI(Creature* creature) const override + uint32 GetData(uint32 /*data*/) const override { - return GetBlackTempleAI<boss_illidan_stormrageAI>(creature); + return _isTeleportToMinions ? 1 : 0; } -}; -class npc_akama : public CreatureScript -{ -public: - npc_akama() : CreatureScript("npc_akama_illidan") { } + void EnterEvadeMode(EvadeReason /*why*/) override { } - struct npc_akamaAI : public ScriptedAI + void JustSummoned(Creature* summon) override { - npc_akamaAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _orientation(0.0f), _isTeleportToMinions(false) { } - - void Reset() override + if (summon->GetEntry() == NPC_SPIRIT_OF_UDALO) { - _events.Reset(); - _spiritOfUdaloGUID.Clear(); - _spiritOfOlumGUID.Clear(); - _isTeleportToMinions = false; + _spiritOfUdaloGUID = summon->GetGUID(); + summon->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); } - - bool GossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + else if (summon->GetEntry() == NPC_SPIRIT_OF_OLUM) { - if (gossipListId == GOSSIP_START_INTRO) - { - _instance->SetData(DATA_AKAMA, AKAMA_FIGHT); - me->GetMotionMaster()->MoveAlongSplineChain(POINT_STAIRS, SPLINE_STAIRS, false); - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->DoAction(ACTION_INTRO_DONE); - CloseGossipMenuFor(player); + _spiritOfOlumGUID = summon->GetGUID(); + summon->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); + } + } - } - else if (gossipListId == GOSSIP_START_FIGHT) - { + void DoAction(int32 actionId) override + { + switch (actionId) + { + case ACTION_ACTIVE_AKAMA_INTRO: _events.SetPhase(PHASE_INTRO); - me->GetMotionMaster()->MoveAlongSplineChain(POINT_FACE_ILLIDAN, SPLINE_FACE_ILLIDAN, false); me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - CloseGossipMenuFor(player); - } - return false; + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_TELEPORT, Seconds(1)); + _events.ScheduleEvent(EVENT_MOVE_TO_ILLIDARI_ROOM, Seconds(1) + Milliseconds(500)); + break; + case ACTION_OPEN_DOOR: + _instance->SetData(ACTION_OPEN_DOOR, 0); + _events.ScheduleEvent(EVENT_AKAMA_THANKS, Seconds(2)); + break; + case ACTION_FREE: + _events.ScheduleEvent(EVENT_FREE, Seconds(14)); + break; + case ACTION_START_ENCOUNTER: + DoZoneInCombat(); + _events.ScheduleEvent(EVENT_HEALING_POTION, Seconds(1)); + break; + case ACTION_START_MINIONS: + _events.ScheduleEvent(EVENT_AKAMA_MINIONS, Seconds(8)); + break; + case ACTION_START_OUTRO: + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + _events.Reset(); + _events.ScheduleEvent(EVENT_AKAMA_MOVE_BACK, Seconds(2)); + break; + default: + break; } + } - bool CanAIAttack(Unit const* who) const override - { - if (_events.IsInPhase(PHASE_MINIONS) && who->GetEntry() == NPC_ILLIDAN_STORMRAGE) - return false; - return ScriptedAI::CanAIAttack(who); - } + void ChangeOrientation(float orientation) + { + _orientation = orientation; + _events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, Milliseconds(1)); + } - uint32 GetData(uint32 /*data*/) const override - { - return _isTeleportToMinions ? 1 : 0; + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE && type != SPLINE_CHAIN_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_ILLIDARI_COUNCIL: + Talk(SAY_AKAMA_FINISH); + me->AddNpcFlag(UNIT_NPC_FLAG_GOSSIP); + break; + case POINT_STAIRS: + ChangeOrientation(6.265732f); + _events.ScheduleEvent(EVENT_AKAMA_SAY_DOOR, Seconds(5)); + break; + case POINT_ILLIDAN_ROOM: + ChangeOrientation(2.129302f); + Talk(SAY_AKAMA_BETRAYER); + me->AddNpcFlag(UNIT_NPC_FLAG_GOSSIP); + break; + case POINT_FACE_ILLIDAN: + ChangeOrientation(3.140537f); + _events.ScheduleEvent(EVENT_START_ILLIDAN, Seconds(2)); + break; + case POINT_TELEPORT: + DoCastSelf(SPELL_AKAMA_TELEPORT); + _events.ScheduleEvent(EVENT_AKAMA_MINIONS_MOVE_2, Milliseconds(500)); + break; + case POINT_MINIONS: + _events.SetPhase(PHASE_MINIONS); + me->SetImmuneToNPC(false); + me->SetReactState(REACT_AGGRESSIVE); + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->DoAction(ACTION_START_MINIONS_WEAVE); + _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(2)); + break; + case POINT_MOVE_BACK: + _events.ScheduleEvent(EVENT_AKAMA_MOVE_TO_ILLIDAN, Milliseconds(1)); + break; + case POINT_ILLIDAN: + _events.ScheduleEvent(EVENT_AKAMA_LIGHT_TEXT, Seconds(1)); + break; + default: + break; } + } - void EnterEvadeMode(EvadeReason /*why*/) override { } + void DamageTaken(Unit* /*who*/, uint32 &damage) override + { + if (damage >= me->GetHealth()) + damage = me->GetHealth() - 1; + } - void JustSummoned(Creature* summon) override - { - if (summon->GetEntry() == NPC_SPIRIT_OF_UDALO) - { - _spiritOfUdaloGUID = summon->GetGUID(); - summon->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - } - else if (summon->GetEntry() == NPC_SPIRIT_OF_OLUM) - { - _spiritOfOlumGUID = summon->GetGUID(); - summon->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - } - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void DoAction(int32 actionId) override + while (uint32 eventId = _events.ExecuteEvent()) { - switch (actionId) + switch (eventId) { - case ACTION_ACTIVE_AKAMA_INTRO: - _events.SetPhase(PHASE_INTRO); - me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP); - _events.SetPhase(PHASE_INTRO); - _events.ScheduleEvent(EVENT_TELEPORT, Seconds(1)); - _events.ScheduleEvent(EVENT_MOVE_TO_ILLIDARI_ROOM, Seconds(1) + Milliseconds(500)); + case EVENT_TELEPORT: + DoCastSelf(SPELL_AKAMA_TELEPORT, true); break; - case ACTION_OPEN_DOOR: - _instance->SetData(ACTION_OPEN_DOOR, 0); - _events.ScheduleEvent(EVENT_AKAMA_THANKS, Seconds(2)); + case EVENT_MOVE_TO_ILLIDARI_ROOM: + me->GetMotionMaster()->MoveAlongSplineChain(POINT_ILLIDARI_COUNCIL, SPLINE_ILLIDARI_COUNCIL, false); break; - case ACTION_FREE: - _events.ScheduleEvent(EVENT_FREE, Seconds(14)); + case EVENT_AKAMA_SAY_DOOR: + Talk(SAY_AKAMA_DOOR); + _events.ScheduleEvent(EVENT_AKAMA_DOOR_FAIL, Seconds(4)); break; - case ACTION_START_ENCOUNTER: - DoZoneInCombat(); - _events.ScheduleEvent(EVENT_HEALING_POTION, Seconds(1)); + case EVENT_AKAMA_DOOR_FAIL: + DoCastSelf(SPELL_AKAMA_DOOR_FAIL); + _events.ScheduleEvent(EVENT_AKAMA_SAY_ALONE, Seconds(10)); + break; + case EVENT_AKAMA_SAY_ALONE: + Talk(SAY_AKAMA_ALONE); + _events.ScheduleEvent(EVENT_SUMMON_SPIRITS, Seconds(7)); + break; + case EVENT_SUMMON_SPIRITS: + me->SummonCreatureGroup(SUMMON_GROUP); + _events.ScheduleEvent(EVENT_SPIRIT_SAY_1, Seconds(1)); + break; + case EVENT_SPIRIT_SAY_1: + if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) + undalo->AI()->Talk(SAY_SPIRIT_ALONE); + _events.ScheduleEvent(EVENT_SPIRIT_SAY_2, Seconds(6)); + break; + case EVENT_SPIRIT_SAY_2: + if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) + olum->AI()->Talk(SAY_SPIRIT_ALONE); + _events.ScheduleEvent(EVENT_AKAMA_DOOR_SUCCESS, Seconds(6)); + break; + case EVENT_AKAMA_DOOR_SUCCESS: + DoCastSelf(SPELL_AKAMA_DOOR_CHANNEL); + if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) + undalo->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL); + if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) + olum->CastSpell((Unit*) nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL); + _events.ScheduleEvent(EVENT_AKAMA_START_SOUND, Seconds(5)); + break; + case EVENT_AKAMA_START_SOUND: + if (GameObject* musicController = _instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) + musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_SOUND_ID); break; - case ACTION_START_MINIONS: - _events.ScheduleEvent(EVENT_AKAMA_MINIONS, Seconds(8)); + case EVENT_AKAMA_THANKS: + Talk(SAY_AKAMA_SALUTE); + _events.ScheduleEvent(EVENT_SPIRIT_SALUTE, Seconds(3)); + _events.ScheduleEvent(EVENT_RUN_FROM_ILLIDAN_ROOM, Seconds(7)); break; - case ACTION_START_OUTRO: + case EVENT_SPIRIT_SALUTE: + if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) + { + undalo->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); + undalo->DespawnOrUnsummon(Seconds(7)); + } + if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) + { + olum->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); + olum->DespawnOrUnsummon(Seconds(7)); + } + break; + case EVENT_RUN_FROM_ILLIDAN_ROOM: + me->GetMotionMaster()->MoveAlongSplineChain(POINT_ILLIDAN_ROOM, SPLINE_ILLIDAN_ROOM, false); + break; + case EVENT_START_ILLIDAN: + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->DoAction(ACTION_START_ENCOUNTER); + break; + case EVENT_FREE: + Talk(SAY_AKAMA_FREE); + _events.ScheduleEvent(EVENT_TIME_HAS_COME, Seconds(18)); + break; + case EVENT_TIME_HAS_COME: + Talk(SAY_AKAMA_TIME_HAS_COME); + _events.ScheduleEvent(EVENT_ROAR, Seconds(2)); + break; + case EVENT_ROAR: + me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + me->SetEmoteState(EMOTE_STATE_READY1H); + break; + case EVENT_CHANGE_ORIENTATION: + me->SetFacingTo(_orientation); + break; + case EVENT_HEALING_POTION: + if (me->HealthBelowPct(20)) + DoCastSelf(SPELL_HEALING_POTION); + _events.Repeat(Seconds(1)); + break; + case EVENT_AKAMA_MINIONS: + Talk(SAY_AKAMA_MINIONS); + _events.ScheduleEvent(EVENT_AKAMA_MINIONS_EMOTE, Seconds(2)); + break; + case EVENT_AKAMA_MINIONS_EMOTE: me->SetReactState(REACT_PASSIVE); me->AttackStop(); - _events.Reset(); - _events.ScheduleEvent(EVENT_AKAMA_MOVE_BACK, Seconds(2)); + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + me->SetImmuneToNPC(true); + _events.ScheduleEvent(EVENT_AKAMA_MINIONS_MOVE, Seconds(4)); break; - default: + case EVENT_AKAMA_MINIONS_MOVE: + _isTeleportToMinions = true; + me->GetMotionMaster()->MoveAlongSplineChain(POINT_TELEPORT, SPLINE_TELEPORT, false); break; - } - } - - void ChangeOrientation(float orientation) - { - _orientation = orientation; - _events.ScheduleEvent(EVENT_CHANGE_ORIENTATION, Milliseconds(1)); - } - - void MovementInform(uint32 type, uint32 pointId) override - { - if (type != POINT_MOTION_TYPE && type != SPLINE_CHAIN_MOTION_TYPE) - return; - - switch (pointId) - { - case POINT_ILLIDARI_COUNCIL: - Talk(SAY_AKAMA_FINISH); - me->AddNpcFlag(UNIT_NPC_FLAG_GOSSIP); - break; - case POINT_STAIRS: - ChangeOrientation(6.265732f); - _events.ScheduleEvent(EVENT_AKAMA_SAY_DOOR, Seconds(5)); - break; - case POINT_ILLIDAN_ROOM: - ChangeOrientation(2.129302f); - Talk(SAY_AKAMA_BETRAYER); - me->AddNpcFlag(UNIT_NPC_FLAG_GOSSIP); - break; - case POINT_FACE_ILLIDAN: - ChangeOrientation(3.140537f); - _events.ScheduleEvent(EVENT_START_ILLIDAN, Seconds(2)); - break; - case POINT_TELEPORT: - DoCastSelf(SPELL_AKAMA_TELEPORT); - _events.ScheduleEvent(EVENT_AKAMA_MINIONS_MOVE_2, Milliseconds(500)); - break; - case POINT_MINIONS: - _events.SetPhase(PHASE_MINIONS); - me->SetImmuneToNPC(false); - me->SetReactState(REACT_AGGRESSIVE); + case EVENT_AKAMA_MINIONS_MOVE_2: + me->GetMotionMaster()->MoveAlongSplineChain(POINT_MINIONS, SPLINE_MINIONS, false); + break; + case EVENT_CHAIN_LIGHTNING: + DoCastVictim(SPELL_CHAIN_LIGHTNING); + _events.Repeat(Seconds(8) + Milliseconds(500)); + break; + case EVENT_AKAMA_MOVE_BACK: + me->GetMotionMaster()->MoveAlongSplineChain(POINT_MOVE_BACK, SPLINE_MOVE_BACK, false); + break; + case EVENT_AKAMA_MOVE_TO_ILLIDAN: if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->DoAction(ACTION_START_MINIONS_WEAVE); - _events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, Seconds(2)); + me->GetMotionMaster()->MoveCloserAndStop(POINT_ILLIDAN, illidan, 5.0f); + break; + case EVENT_AKAMA_LIGHT_TEXT: + Talk(SAY_AKAMA_LIGHT); + _events.ScheduleEvent(EVENT_FINAL_SALUTE, Seconds(4)); break; - case POINT_MOVE_BACK: - _events.ScheduleEvent(EVENT_AKAMA_MOVE_TO_ILLIDAN, Milliseconds(1)); + case EVENT_FINAL_SALUTE: + me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); + _events.ScheduleEvent(EVENT_AKAMA_DESPAWN, Seconds(5)); break; - case POINT_ILLIDAN: - _events.ScheduleEvent(EVENT_AKAMA_LIGHT_TEXT, Seconds(1)); + case EVENT_AKAMA_DESPAWN: + DoCastSelf(SPELL_AKAMA_DESPAWN, true); break; default: break; } - } - - void DamageTaken(Unit* /*who*/, uint32 &damage) override - { - if (damage >= me->GetHealth()) - damage = me->GetHealth() - 1; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) - return; - - _events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_TELEPORT: - DoCastSelf(SPELL_AKAMA_TELEPORT, true); - break; - case EVENT_MOVE_TO_ILLIDARI_ROOM: - me->GetMotionMaster()->MoveAlongSplineChain(POINT_ILLIDARI_COUNCIL, SPLINE_ILLIDARI_COUNCIL, false); - break; - case EVENT_AKAMA_SAY_DOOR: - Talk(SAY_AKAMA_DOOR); - _events.ScheduleEvent(EVENT_AKAMA_DOOR_FAIL, Seconds(4)); - break; - case EVENT_AKAMA_DOOR_FAIL: - DoCastSelf(SPELL_AKAMA_DOOR_FAIL); - _events.ScheduleEvent(EVENT_AKAMA_SAY_ALONE, Seconds(10)); - break; - case EVENT_AKAMA_SAY_ALONE: - Talk(SAY_AKAMA_ALONE); - _events.ScheduleEvent(EVENT_SUMMON_SPIRITS, Seconds(7)); - break; - case EVENT_SUMMON_SPIRITS: - me->SummonCreatureGroup(SUMMON_GROUP); - _events.ScheduleEvent(EVENT_SPIRIT_SAY_1, Seconds(1)); - break; - case EVENT_SPIRIT_SAY_1: - if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) - undalo->AI()->Talk(SAY_SPIRIT_ALONE); - _events.ScheduleEvent(EVENT_SPIRIT_SAY_2, Seconds(6)); - break; - case EVENT_SPIRIT_SAY_2: - if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) - olum->AI()->Talk(SAY_SPIRIT_ALONE); - _events.ScheduleEvent(EVENT_AKAMA_DOOR_SUCCESS, Seconds(6)); - break; - case EVENT_AKAMA_DOOR_SUCCESS: - DoCastSelf(SPELL_AKAMA_DOOR_CHANNEL); - if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) - undalo->CastSpell(nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL); - if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) - olum->CastSpell(nullptr, SPELL_DEATHSWORN_DOOR_CHANNEL); - _events.ScheduleEvent(EVENT_AKAMA_START_SOUND, Seconds(5)); - break; - case EVENT_AKAMA_START_SOUND: - if (GameObject* musicController = _instance->GetGameObject(DATA_ILLIDAN_MUSIC_CONTROLLER)) - musicController->PlayDirectMusic(EVENT_BT_SUMMIT_WALK_SOUND_ID); - break; - case EVENT_AKAMA_THANKS: - Talk(SAY_AKAMA_SALUTE); - _events.ScheduleEvent(EVENT_SPIRIT_SALUTE, Seconds(3)); - _events.ScheduleEvent(EVENT_RUN_FROM_ILLIDAN_ROOM, Seconds(7)); - break; - case EVENT_SPIRIT_SALUTE: - if (Creature* undalo = ObjectAccessor::GetCreature(*me, _spiritOfUdaloGUID)) - { - undalo->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - undalo->DespawnOrUnsummon(Seconds(7)); - } - if (Creature* olum = ObjectAccessor::GetCreature(*me, _spiritOfOlumGUID)) - { - olum->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - olum->DespawnOrUnsummon(Seconds(7)); - } - break; - case EVENT_RUN_FROM_ILLIDAN_ROOM: - me->GetMotionMaster()->MoveAlongSplineChain(POINT_ILLIDAN_ROOM, SPLINE_ILLIDAN_ROOM, false); - break; - case EVENT_START_ILLIDAN: - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->DoAction(ACTION_START_ENCOUNTER); - break; - case EVENT_FREE: - Talk(SAY_AKAMA_FREE); - _events.ScheduleEvent(EVENT_TIME_HAS_COME, Seconds(18)); - break; - case EVENT_TIME_HAS_COME: - Talk(SAY_AKAMA_TIME_HAS_COME); - _events.ScheduleEvent(EVENT_ROAR, Seconds(2)); - break; - case EVENT_ROAR: - me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); - me->SetEmoteState(EMOTE_STATE_READY1H); - break; - case EVENT_CHANGE_ORIENTATION: - me->SetFacingTo(_orientation); - break; - case EVENT_HEALING_POTION: - if (me->HealthBelowPct(20)) - DoCastSelf(SPELL_HEALING_POTION); - _events.Repeat(Seconds(1)); - break; - case EVENT_AKAMA_MINIONS: - Talk(SAY_AKAMA_MINIONS); - _events.ScheduleEvent(EVENT_AKAMA_MINIONS_EMOTE, Seconds(2)); - break; - case EVENT_AKAMA_MINIONS_EMOTE: - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); - me->SetImmuneToNPC(true); - _events.ScheduleEvent(EVENT_AKAMA_MINIONS_MOVE, Seconds(4)); - break; - case EVENT_AKAMA_MINIONS_MOVE: - _isTeleportToMinions = true; - me->GetMotionMaster()->MoveAlongSplineChain(POINT_TELEPORT, SPLINE_TELEPORT, false); - break; - case EVENT_AKAMA_MINIONS_MOVE_2: - me->GetMotionMaster()->MoveAlongSplineChain(POINT_MINIONS, SPLINE_MINIONS, false); - break; - case EVENT_CHAIN_LIGHTNING: - DoCastVictim(SPELL_CHAIN_LIGHTNING); - _events.Repeat(Seconds(8) + Milliseconds(500)); - break; - case EVENT_AKAMA_MOVE_BACK: - me->GetMotionMaster()->MoveAlongSplineChain(POINT_MOVE_BACK, SPLINE_MOVE_BACK, false); - break; - case EVENT_AKAMA_MOVE_TO_ILLIDAN: - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - me->GetMotionMaster()->MoveCloserAndStop(POINT_ILLIDAN, illidan, 5.0f); - break; - case EVENT_AKAMA_LIGHT_TEXT: - Talk(SAY_AKAMA_LIGHT); - _events.ScheduleEvent(EVENT_FINAL_SALUTE, Seconds(4)); - break; - case EVENT_FINAL_SALUTE: - me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); - _events.ScheduleEvent(EVENT_AKAMA_DESPAWN, Seconds(5)); - break; - case EVENT_AKAMA_DESPAWN: - DoCastSelf(SPELL_AKAMA_DESPAWN, true); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } - - DoMeleeAttackIfReady(); } - private: - InstanceScript* _instance; - EventMap _events; - ObjectGuid _spiritOfUdaloGUID; - ObjectGuid _spiritOfOlumGUID; - float _orientation; - bool _isTeleportToMinions; - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_akamaAI>(creature); + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + EventMap _events; + ObjectGuid _spiritOfUdaloGUID; + ObjectGuid _spiritOfOlumGUID; + float _orientation; + bool _isTeleportToMinions; }; -class npc_parasitic_shadowfiend : public CreatureScript +struct npc_parasitic_shadowfiend : public ScriptedAI { -public: - npc_parasitic_shadowfiend() : CreatureScript("npc_parasitic_shadowfiend") { } + npc_parasitic_shadowfiend(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_parasitic_shadowfiendAI : public ScriptedAI + void Reset() override { - npc_parasitic_shadowfiendAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } + if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) + { + me->DespawnOrUnsummon(); + return; + } - void Reset() override + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->JustSummoned(me); + me->SetReactState(REACT_DEFENSIVE); + _scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/) { - if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) - { - me->DespawnOrUnsummon(); - return; - } + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + }); + } - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->JustSummoned(me); - me->SetReactState(REACT_DEFENSIVE); + void DoAction(int32 action) override + { + if (action == ACTION_START_PHASE_4) + { + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + } + else if (action == ACTION_RESUME_COMBAT) _scheduler.Schedule(Seconds(2), [this](TaskContext /*context*/) { me->SetReactState(REACT_AGGRESSIVE); me->SetInCombatWithZone(); }); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + } - _scheduler.Update(diff, [this] - { - DoMeleeAttackIfReady(); - }); - } + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); - private: - InstanceScript* _instance; - TaskScheduler _scheduler; - }; + if (!UpdateVictim()) + return; - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_parasitic_shadowfiendAI>(creature); + DoMeleeAttackIfReady(); } + +private: + InstanceScript* _instance; + TaskScheduler _scheduler; }; -class npc_blade_of_azzinoth : public CreatureScript +struct npc_blade_of_azzinoth : public NullCreatureAI { -public: - npc_blade_of_azzinoth() : CreatureScript("npc_blade_of_azzinoth") { } + npc_blade_of_azzinoth(Creature* creature) : NullCreatureAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_blade_of_azzinothAI : public NullCreatureAI + void Reset() override { - npc_blade_of_azzinothAI(Creature* creature) : NullCreatureAI(creature), _instance(creature->GetInstanceScript()) { } - - void Reset() override - { - if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) - { - me->DespawnOrUnsummon(); - return; - } - - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->JustSummoned(me); - _flameGuid.Clear(); - me->PlayDirectSound(WARGLAIVE_SPAWN_SOUND_ID); - DoCastSelf(SPELL_BIRTH, true); - _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) - { - DoCastSelf(SPELL_SUMMON_TEAR_OF_AZZINOTH); - _scheduler.Schedule(Milliseconds(500), [this](TaskContext /*context*/) - { - if (Creature* flame = ObjectAccessor::GetCreature(*me, _flameGuid)) - DoCast(flame, SPELL_AZZINOTH_CHANNEL); - }); - }); - } - - void JustSummoned(Creature* summon) override + if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) { - if (summon->GetEntry() == NPC_FLAME_OF_AZZINOTH) - _flameGuid = summon->GetGUID(); + me->DespawnOrUnsummon(); + return; } - void UpdateAI(uint32 diff) override + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->JustSummoned(me); + _flameGuid.Clear(); + me->PlayDirectSound(WARGLAIVE_SPAWN_SOUND_ID); + DoCastSelf(SPELL_BIRTH, true); + _scheduler.Schedule(Seconds(3), [this](TaskContext /*context*/) { - _scheduler.Update(diff); - } + DoCastSelf(SPELL_SUMMON_TEAR_OF_AZZINOTH); + _scheduler.Schedule(Milliseconds(500), [this](TaskContext /*context*/) + { + if (Creature* flame = ObjectAccessor::GetCreature(*me, _flameGuid)) + DoCast(flame, SPELL_AZZINOTH_CHANNEL); + }); + }); + } - private: - InstanceScript* _instance; - TaskScheduler _scheduler; - ObjectGuid _flameGuid; - }; + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_FLAME_OF_AZZINOTH) + _flameGuid = summon->GetGUID(); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackTempleAI<npc_blade_of_azzinothAI>(creature); + _scheduler.Update(diff); } + +private: + InstanceScript* _instance; + TaskScheduler _scheduler; + ObjectGuid _flameGuid; }; -class npc_flame_of_azzinoth : public CreatureScript +struct npc_flame_of_azzinoth : public ScriptedAI { -public: - npc_flame_of_azzinoth() : CreatureScript("npc_flame_of_azzinoth") { } + npc_flame_of_azzinoth(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) + { + SetBoundary(_instance->GetBossBoundary(DATA_ILLIDAN_STORMRAGE)); + } - struct npc_flame_of_azzinothAI : public ScriptedAI + void Reset() override { - npc_flame_of_azzinothAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) + if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) { - SetBoundary(_instance->GetBossBoundary(DATA_ILLIDAN_STORMRAGE)); + me->DespawnOrUnsummon(); + return; } - void Reset() override - { - if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) - { - me->DespawnOrUnsummon(); - return; - } + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->JustSummoned(me); + DoCastSelf(SPELL_FLAME_TEAR_OF_AZZINOTH, true); // Idk what this spell should do + me->SetReactState(REACT_PASSIVE); + _events.ScheduleEvent(EVENT_ENGAGE, Seconds(3)); + _events.ScheduleEvent(EVENT_FLAME_BLAST, Seconds(11)); + } - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->JustSummoned(me); - DoCastSelf(SPELL_FLAME_TEAR_OF_AZZINOTH, true); // Idk what this spell should do - me->SetReactState(REACT_PASSIVE); - _events.ScheduleEvent(EVENT_ENGAGE, Seconds(3)); - _events.ScheduleEvent(EVENT_FLAME_BLAST, Seconds(11)); - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - _events.Update(diff); + _events.Update(diff); - while (uint32 eventId = _events.ExecuteEvent()) + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) { - switch (eventId) - { - case EVENT_ENGAGE: - me->SetReactState(REACT_AGGRESSIVE); - me->SetInCombatWithZone(); - _events.ScheduleEvent(EVENT_FLAME_CHARGE, Seconds(5)); - break; - case EVENT_FLAME_CHARGE: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, ChargeTargetSelector(me))) - { - DoCast(target, SPELL_CHARGE); - _events.Repeat(Seconds(5)); - } - else - _events.Repeat(Seconds(1)); - break; - case EVENT_FLAME_BLAST: - DoCastAOE(SPELL_FLAME_BLAST); - _events.Repeat(Seconds(12)); - break; - default: - break; - } - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; + case EVENT_ENGAGE: + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + _events.ScheduleEvent(EVENT_FLAME_CHARGE, Seconds(5)); + break; + case EVENT_FLAME_CHARGE: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, ChargeTargetSelector(me))) + { + DoCast(target, SPELL_CHARGE); + _events.Repeat(Seconds(5)); + } + else + _events.Repeat(Seconds(1)); + break; + case EVENT_FLAME_BLAST: + DoCastAOE(SPELL_FLAME_BLAST); + _events.Repeat(Seconds(12)); + break; + default: + break; } - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) override - { - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->AI()->DoAction(ACTION_FLAME_DEAD); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; } - private: - InstanceScript* _instance; - EventMap _events; - }; + DoMeleeAttackIfReady(); + } - CreatureAI* GetAI(Creature* creature) const override + void JustDied(Unit* /*killer*/) override { - return GetBlackTempleAI<npc_flame_of_azzinothAI>(creature); + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->AI()->DoAction(ACTION_FLAME_DEAD); } + +private: + InstanceScript* _instance; + EventMap _events; }; -class npc_illidan_db_target : public CreatureScript +struct npc_illidan_db_target : public NullCreatureAI { -public: - npc_illidan_db_target() : CreatureScript("npc_illidan_db_target") { } + npc_illidan_db_target(Creature* creature) : NullCreatureAI(creature) { } - struct npc_illidan_db_targetAI : public NullCreatureAI + void Reset() override { - npc_illidan_db_targetAI(Creature* creature) : NullCreatureAI(creature) { } - - void Reset() override - { - DoCastSelf(SPELL_EYE_BLAST_TRIGGER); - } + DoCastSelf(SPELL_EYE_BLAST_TRIGGER); + } - void JustSummoned(Creature* summon) override - { - if (summon->GetEntry() == NPC_DEMON_FIRE) - summon->SetReactState(REACT_PASSIVE); - } + void JustSummoned(Creature* summon) override + { + if (summon->GetEntry() == NPC_DEMON_FIRE) + summon->SetReactState(REACT_PASSIVE); + } - void MovementInform(uint32 type, uint32 pointId) override + void MovementInform(uint32 type, uint32 pointId) override + { + if (type == POINT_MOTION_TYPE && pointId == POINT_DB_TARGET) { - if (type == POINT_MOTION_TYPE && pointId == POINT_DB_TARGET) - { - me->RemoveAurasDueToSpell(SPELL_EYE_BLAST_TRIGGER); - me->RemoveAurasDueToSpell(SPELL_EYE_BLAST); - } + me->RemoveAurasDueToSpell(SPELL_EYE_BLAST_TRIGGER); + me->RemoveAurasDueToSpell(SPELL_EYE_BLAST); } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetBlackTempleAI<npc_illidan_db_targetAI>(creature); } }; -class npc_illidan_shadow_demon : public CreatureScript +struct npc_shadow_demon : public PassiveAI { -public: - npc_illidan_shadow_demon() : CreatureScript("npc_shadow_demon") { } + npc_shadow_demon(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_illidan_shadow_demonAI : public PassiveAI + void Reset() override { - npc_illidan_shadow_demonAI(Creature* creature) : PassiveAI(creature), _instance(creature->GetInstanceScript()) { } - - void Reset() override + if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) { - if (_instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != IN_PROGRESS) - { - me->DespawnOrUnsummon(); - return; - } - - DoCastSelf(SPELL_SHADOW_DEMON_PASSIVE); - DoCastSelf(SPELL_FIND_TARGET); - _scheduler.Schedule(Seconds(1), [this](TaskContext checkTarget) - { - if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) - { - if (!target->IsAlive()) - DoCastSelf(SPELL_FIND_TARGET); - else if (me->IsWithinMeleeRange(target)) - { - me->InterruptNonMeleeSpells(false); - DoCast(target, SPELL_CONSUME_SOUL, true); - } - } - checkTarget.Repeat(); - }); + me->DespawnOrUnsummon(); + return; } - void SetGUID(ObjectGuid guid, int32 /*id*/) override + DoCastSelf(SPELL_SHADOW_DEMON_PASSIVE); + DoCastSelf(SPELL_FIND_TARGET); + _scheduler.Schedule(Seconds(1), [this](TaskContext checkTarget) { - _targetGUID = guid; if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) - me->GetMotionMaster()->MoveChase(target); - } - - void UpdateAI(uint32 diff) override - { - _scheduler.Update(diff); - } + { + if (!target->IsAlive()) + DoCastSelf(SPELL_FIND_TARGET); + else if (me->IsWithinMeleeRange(target)) + { + me->InterruptNonMeleeSpells(false); + DoCast(target, SPELL_CONSUME_SOUL, true); + } + } + checkTarget.Repeat(); + }); + } - private: - InstanceScript* _instance; - TaskScheduler _scheduler; - ObjectGuid _targetGUID; - }; + void SetGUID(ObjectGuid guid, int32 /*id*/) override + { + _targetGUID = guid; + if (Unit* target = ObjectAccessor::GetUnit(*me, _targetGUID)) + me->GetMotionMaster()->MoveChase(target); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackTempleAI<npc_illidan_shadow_demonAI>(creature); + _scheduler.Update(diff); } + +private: + InstanceScript* _instance; + TaskScheduler _scheduler; + ObjectGuid _targetGUID; }; -class npc_maiev : public CreatureScript +struct npc_maiev : public ScriptedAI { -public: - npc_maiev() : CreatureScript("npc_maiev") { } + npc_maiev(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _canDown(true) { } - struct npc_maievAI : public ScriptedAI + void Reset() override { - npc_maievAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _canDown(true) { } + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + me->SetFacingToObject(illidan); + me->SetReactState(REACT_PASSIVE); + _events.SetPhase(PHASE_INTRO); + _events.ScheduleEvent(EVENT_MAIEV_APPEAR, Seconds(1)); + _events.ScheduleEvent(EVENT_MAIEV_EXCLAMATION, Seconds(2)); + _events.ScheduleEvent(EVENT_MAIEV_JUSTICE_TEXT, Seconds(14)); + _events.ScheduleEvent(EVENT_TAUNT, Seconds(20), Seconds(60)); + _canDown = true; + } + + void EnterCombat(Unit* /*who*/) override + { + _events.SetPhase(PHASE_1); + _events.ScheduleEvent(EVENT_CAGE_TRAP, Seconds(30)); + _events.ScheduleEvent(EVENT_SHADOW_STRIKE, Seconds(50)); + _events.ScheduleEvent(EVENT_THROW_DAGGER, Seconds(1)); + } - void Reset() override + void DoAction(int32 actionId) override + { + if (actionId == ACTION_START_OUTRO) { + _events.Reset(); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) me->SetFacingToObject(illidan); - me->SetReactState(REACT_PASSIVE); - _events.SetPhase(PHASE_INTRO); - _events.ScheduleEvent(EVENT_MAIEV_APPEAR, Seconds(1)); - _events.ScheduleEvent(EVENT_MAIEV_EXCLAMATION, Seconds(2)); - _events.ScheduleEvent(EVENT_MAIEV_JUSTICE_TEXT, Seconds(14)); - _events.ScheduleEvent(EVENT_TAUNT, Seconds(20), Seconds(60)); - _canDown = true; + Talk(SAY_MAIEV_SHADOWSONG_FINISHED); + _events.ScheduleEvent(EVENT_MAIEV_OUTRO_TEXT, Seconds(28)); } + else if (actionId == ACTION_MAIEV_DOWN_FADE) + _canDown = true; + } - void EnterCombat(Unit* /*who*/) override + void DamageTaken(Unit* /*who*/, uint32 &damage) override + { + if (damage >= me->GetHealth() && _canDown) { - _events.SetPhase(PHASE_1); - _events.ScheduleEvent(EVENT_CAGE_TRAP, Seconds(30)); - _events.ScheduleEvent(EVENT_SHADOW_STRIKE, Seconds(50)); - _events.ScheduleEvent(EVENT_THROW_DAGGER, Seconds(1)); + damage = me->GetHealth() - 1; + _canDown = false; + DoCastSelf(SPELL_MAIEV_DOWN, true); + Talk(SAY_MAIEV_SHADOWSONG_DOWN, me); } + } - void DoAction(int32 actionId) override - { - if (actionId == ACTION_START_OUTRO) - { - _events.Reset(); - me->SetReactState(REACT_PASSIVE); - me->AttackStop(); - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - me->SetFacingToObject(illidan); - Talk(SAY_MAIEV_SHADOWSONG_FINISHED); - _events.ScheduleEvent(EVENT_MAIEV_OUTRO_TEXT, Seconds(28)); - } - else if (actionId == ACTION_MAIEV_DOWN_FADE) - _canDown = true; - } + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) + return; + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - void DamageTaken(Unit* /*who*/, uint32 &damage) override + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) { - if (damage >= me->GetHealth() && _canDown) + switch (eventId) { - damage = me->GetHealth() - 1; - _canDown = false; - DoCastSelf(SPELL_MAIEV_DOWN, true); - Talk(SAY_MAIEV_SHADOWSONG_DOWN, me); + case EVENT_MAIEV_APPEAR: + Talk(SAY_MAIEV_SHADOWSONG_APPEAR); + break; + case EVENT_MAIEV_EXCLAMATION: + me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); + break; + case EVENT_MAIEV_JUSTICE_TEXT: + Talk(SAY_MAIEV_SHADOWSONG_JUSTICE); + _events.ScheduleEvent(EVENT_MAIEV_YES, Seconds(2)); + break; + case EVENT_MAIEV_YES: + me->HandleEmoteCommand(EMOTE_ONESHOT_YES); + _events.ScheduleEvent(EVENT_MAIEV_ROAR, Seconds(3)); + break; + case EVENT_MAIEV_ROAR: + me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); + _events.ScheduleEvent(EVENT_MAIEV_COMBAT, Seconds(3)); + break; + case EVENT_MAIEV_COMBAT: + me->SetReactState(REACT_AGGRESSIVE); + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + AttackStart(illidan); + break; + case EVENT_CAGE_TRAP: + if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) + illidan->CastSpell(illidan, SPELL_CAGED_TRAP_TELEPORT, true); + DoCastSelf(SPELL_CAGE_TRAP_SUMMON); + Talk(SAY_MAIEV_SHADOWSONG_TRAP); + _events.Repeat(Seconds(30)); + break; + case EVENT_SHADOW_STRIKE: + DoCastVictim(SPELL_SHADOW_STRIKE); + _events.Repeat(Seconds(50)); + break; + case EVENT_THROW_DAGGER: + if (Unit* target = me->GetVictim()) + if (!me->IsWithinMeleeRange(target)) + { + DoCastVictim(SPELL_THROW_DAGGER); + _events.Repeat(Seconds(5)); + break; + } + _events.Repeat(Seconds(1)); + break; + case EVENT_TAUNT: + Talk(SAY_MAIEV_SHADOWSONG_TAUNT); + _events.Repeat(Seconds(30), Seconds(60)); + break; + case EVENT_MAIEV_OUTRO_TEXT: + Talk(SAY_MAIEV_SHADOWSONG_OUTRO); + _events.ScheduleEvent(EVENT_MAIEV_FAREWELL_TEXT, Seconds(11)); + break; + case EVENT_MAIEV_FAREWELL_TEXT: + Talk(SAY_MAIEV_SHADOWSONG_FAREWELL); + _events.ScheduleEvent(EVENT_MAIEV_TELEPORT_DESPAWN, Seconds(3)); + break; + case EVENT_MAIEV_TELEPORT_DESPAWN: + DoCastSelf(SPELL_TELEPORT_VISUAL); + me->DespawnOrUnsummon(Seconds(1)); + break; + default: + break; } - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim() && !_events.IsInPhase(PHASE_INTRO)) - return; if (me->HasUnitState(UNIT_STATE_CASTING)) return; + } - _events.Update(diff); - - while (uint32 eventId = _events.ExecuteEvent()) - { - switch (eventId) - { - case EVENT_MAIEV_APPEAR: - Talk(SAY_MAIEV_SHADOWSONG_APPEAR); - break; - case EVENT_MAIEV_EXCLAMATION: - me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); - break; - case EVENT_MAIEV_JUSTICE_TEXT: - Talk(SAY_MAIEV_SHADOWSONG_JUSTICE); - _events.ScheduleEvent(EVENT_MAIEV_YES, Seconds(2)); - break; - case EVENT_MAIEV_YES: - me->HandleEmoteCommand(EMOTE_ONESHOT_YES); - _events.ScheduleEvent(EVENT_MAIEV_ROAR, Seconds(3)); - break; - case EVENT_MAIEV_ROAR: - me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); - _events.ScheduleEvent(EVENT_MAIEV_COMBAT, Seconds(3)); - break; - case EVENT_MAIEV_COMBAT: - me->SetReactState(REACT_AGGRESSIVE); - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - AttackStart(illidan); - break; - case EVENT_CAGE_TRAP: - if (Creature* illidan = _instance->GetCreature(DATA_ILLIDAN_STORMRAGE)) - illidan->CastSpell(illidan, SPELL_CAGED_TRAP_TELEPORT, true); - DoCastSelf(SPELL_CAGE_TRAP_SUMMON); - Talk(SAY_MAIEV_SHADOWSONG_TRAP); - _events.Repeat(Seconds(30)); - break; - case EVENT_SHADOW_STRIKE: - DoCastVictim(SPELL_SHADOW_STRIKE); - _events.Repeat(Seconds(50)); - break; - case EVENT_THROW_DAGGER: - if (Unit* target = me->GetVictim()) - if (!me->IsWithinMeleeRange(target)) - { - DoCastVictim(SPELL_THROW_DAGGER); - _events.Repeat(Seconds(5)); - break; - } - _events.Repeat(Seconds(1)); - break; - case EVENT_TAUNT: - Talk(SAY_MAIEV_SHADOWSONG_TAUNT); - _events.Repeat(Seconds(30), Seconds(60)); - break; - case EVENT_MAIEV_OUTRO_TEXT: - Talk(SAY_MAIEV_SHADOWSONG_OUTRO); - _events.ScheduleEvent(EVENT_MAIEV_FAREWELL_TEXT, Seconds(11)); - break; - case EVENT_MAIEV_FAREWELL_TEXT: - Talk(SAY_MAIEV_SHADOWSONG_FAREWELL); - _events.ScheduleEvent(EVENT_MAIEV_TELEPORT_DESPAWN, Seconds(3)); - break; - case EVENT_MAIEV_TELEPORT_DESPAWN: - DoCastSelf(SPELL_TELEPORT_VISUAL); - me->DespawnOrUnsummon(Seconds(1)); - break; - default: - break; - } + DoMeleeAttackIfReady(); + } - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - } +private: + EventMap _events; + InstanceScript* _instance; + bool _canDown; +}; - DoMeleeAttackIfReady(); - } +struct npc_cage_trap_trigger : public PassiveAI +{ + npc_cage_trap_trigger(Creature* creature) : PassiveAI(creature) { } - private: - EventMap _events; - InstanceScript* _instance; - bool _canDown; - }; + void Reset() override + { + _scheduler.Schedule(Seconds(1), [this](TaskContext checkTarget) + { + DoCastSelf(SPELL_CAGE_TRAP_PERIODIC); + checkTarget.Repeat(); + }); + } - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetBlackTempleAI<npc_maievAI>(creature); + _scheduler.Update(diff); } + +private: + TaskScheduler _scheduler; }; -class npc_cage_trap_trigger : public CreatureScript +struct npc_illidari_elite : public ScriptedAI { -public: - npc_cage_trap_trigger() : CreatureScript("npc_cage_trap_trigger") { } + npc_illidari_elite(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { } - struct npc_cage_trap_triggerAI : public PassiveAI + void Reset() override { - npc_cage_trap_triggerAI(Creature* creature) : PassiveAI(creature) { } - - void Reset() override - { - _scheduler.Schedule(Seconds(1), [this](TaskContext checkTarget) - { - DoCastSelf(SPELL_CAGE_TRAP_PERIODIC); - checkTarget.Repeat(); - }); - } - - void UpdateAI(uint32 diff) override + if (Creature* akama = _instance->GetCreature(DATA_AKAMA)) { - _scheduler.Update(diff); + AttackStart(akama); + AddThreat(akama, 1000.0f); } + } - private: - TaskScheduler _scheduler; - }; - - CreatureAI* GetAI(Creature* creature) const override + bool CanAIAttack(Unit const* who) const override { - return GetBlackTempleAI<npc_cage_trap_triggerAI>(creature); + if (who->GetEntry() == NPC_AKAMA) + return true; + return false; } + +private: + InstanceScript* _instance; }; // 41077 - Akama Teleport -class spell_illidan_akama_teleport : public SpellScriptLoader +class spell_illidan_akama_teleport : public SpellScript { - public: - spell_illidan_akama_teleport() : SpellScriptLoader("spell_illidan_akama_teleport") { } - - class spell_illidan_akama_teleport_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_akama_teleport_SpellScript); - - void SetDest(SpellDestination& dest) - { - if (Creature* caster = GetCaster()->ToCreature()) - { - uint32 destination = caster->AI()->GetData(DATA_AKAMA_TELEPORT_POSITION); - dest.Relocate(AkamaTeleportPositions[destination]); - } - } + PrepareSpellScript(spell_illidan_akama_teleport); - void Register() override - { - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_illidan_akama_teleport_SpellScript::SetDest, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); - } - }; - - SpellScript* GetSpellScript() const override + void SetDest(SpellDestination& dest) + { + if (Creature* caster = GetCaster()->ToCreature()) { - return new spell_illidan_akama_teleport_SpellScript(); + uint32 destination = caster->AI()->GetData(DATA_AKAMA_TELEPORT_POSITION); + dest.Relocate(AkamaTeleportPositions[destination]); } + } + + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_illidan_akama_teleport::SetDest, EFFECT_0, TARGET_DEST_NEARBY_ENTRY); + } }; // 41268 - Quest - Black Temple - Akama - Door Open -class spell_illidan_akama_door_channel : public SpellScriptLoader +class spell_illidan_akama_door_channel : public AuraScript { - public: - spell_illidan_akama_door_channel() : SpellScriptLoader("spell_illidan_akama_door_channel") { } + PrepareAuraScript(spell_illidan_akama_door_channel); - class spell_illidan_akama_door_channel_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_akama_door_channel_AuraScript); - - bool Validate(SpellInfo const* /*spell*/) override - { - return ValidateSpellInfo({ SPELL_ARCANE_EXPLOSION }); - } - - void OnRemoveDummy(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_ARCANE_EXPLOSION, true); + bool Validate(SpellInfo const* /*spell*/) override + { + return ValidateSpellInfo({ SPELL_ARCANE_EXPLOSION }); + } - if (InstanceScript* instance = target->GetInstanceScript()) - if (Creature* akama = instance->GetCreature(DATA_AKAMA)) - akama->AI()->DoAction(ACTION_OPEN_DOOR); - } + void OnRemoveDummy(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_ARCANE_EXPLOSION, true); - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_akama_door_channel_AuraScript::OnRemoveDummy, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + if (InstanceScript* instance = target->GetInstanceScript()) + if (Creature* akama = instance->GetCreature(DATA_AKAMA)) + akama->AI()->DoAction(ACTION_OPEN_DOOR); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidan_akama_door_channel_AuraScript(); - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_akama_door_channel::OnRemoveDummy, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; // 40904 - Draw Soul -class spell_illidan_draw_soul : public SpellScriptLoader +class spell_illidan_draw_soul : public SpellScript { - public: - spell_illidan_draw_soul() : SpellScriptLoader("spell_illidan_draw_soul") { } - - class spell_illidan_draw_soul_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_draw_soul_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DRAW_SOUL_HEAL }); - } + PrepareSpellScript(spell_illidan_draw_soul); - void HandleScriptEffect(SpellEffIndex effIndex) - { - PreventHitDefaultEffect(effIndex); - GetHitUnit()->CastSpell(GetCaster(), SPELL_DRAW_SOUL_HEAL, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DRAW_SOUL_HEAL }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_draw_soul_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetCaster(), SPELL_DRAW_SOUL_HEAL, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_draw_soul_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_draw_soul::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT); + } }; /* 41917 - Parasitic Shadowfiend 41914 - Parasitic Shadowfiend */ -class spell_illidan_parasitic_shadowfiend : public SpellScriptLoader +class spell_illidan_parasitic_shadowfiend : public AuraScript { - public: - spell_illidan_parasitic_shadowfiend() : SpellScriptLoader("spell_illidan_parasitic_shadowfiend") { } + PrepareAuraScript(spell_illidan_parasitic_shadowfiend); - class spell_illidan_parasitic_shadowfiend_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_parasitic_shadowfiend_AuraScript); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SUMMON_PARASITIC_SHADOWFIENDS }); + } - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_SUMMON_PARASITIC_SHADOWFIENDS }); - } + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode(); + if (removeMode != AURA_REMOVE_BY_EXPIRE && removeMode != AURA_REMOVE_BY_DEATH) + return; - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_SUMMON_PARASITIC_SHADOWFIENDS, true); - } + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_SUMMON_PARASITIC_SHADOWFIENDS, true); + } - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_parasitic_shadowfiend_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); - } - }; + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_parasitic_shadowfiend::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL); + } +}; - AuraScript* GetAuraScript() const override - { - return new spell_illidan_parasitic_shadowfiend_AuraScript(); - } +// 41923 - Remove Parasitic Shadowfiends (SERVERSIDE) +class spell_illidan_remove_parasitic_shadowfiend : public AuraScript +{ + PrepareAuraScript(spell_illidan_remove_parasitic_shadowfiend); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PARASITIC_SHADOWFIEND, SPELL_PARASITIC_SHADOWFIEND_2 }); + } + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveAurasDueToSpell(SPELL_PARASITIC_SHADOWFIEND); + GetTarget()->RemoveAurasDueToSpell(SPELL_PARASITIC_SHADOWFIEND_2); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_illidan_remove_parasitic_shadowfiend::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; /* 39635 - Throw Glaive 39849 - Throw Glaive */ -class spell_illidan_throw_warglaive : public SpellScriptLoader +class spell_illidan_throw_warglaive : public SpellScript { - public: - spell_illidan_throw_warglaive() : SpellScriptLoader("spell_illidan_throw_warglaive") { } - - class spell_illidan_throw_warglaive_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_throw_warglaive_SpellScript); - - void HandleDummy(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - target->m_Events.AddEvent(new SummonWarglaiveEvent(target), target->m_Events.CalculateTime(1000)); - } + PrepareSpellScript(spell_illidan_throw_warglaive); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_throw_warglaive_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + target->m_Events.AddEvent(new SummonWarglaiveEvent(target), target->m_Events.CalculateTime(1000)); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_throw_warglaive_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_throw_warglaive::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 39857 - Tear of Azzinoth Summon Channel -class spell_illidan_tear_of_azzinoth_channel : public SpellScriptLoader +class spell_illidan_tear_of_azzinoth_channel : public AuraScript { - public: - spell_illidan_tear_of_azzinoth_channel() : SpellScriptLoader("spell_illidan_tear_of_azzinoth_channel") { } - - class spell_illidan_tear_of_azzinoth_channel_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_tear_of_azzinoth_channel_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_UNCAGED_WRATH }); - } + PrepareAuraScript(spell_illidan_tear_of_azzinoth_channel); - void OnPeriodic(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - if (Unit* caster = GetCaster()) - { - Unit* target = GetTarget(); - if (caster->GetDistance2d(target) > 25.0f) - { - target->CastSpell(target, SPELL_UNCAGED_WRATH, true); - Remove(); - } - } - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_UNCAGED_WRATH }); + } - void Register() override + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + if (Unit* caster = GetCaster()) + { + Unit* target = GetTarget(); + if (caster->GetDistance2d(target) > 25.0f) { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_tear_of_azzinoth_channel_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + target->CastSpell(target, SPELL_UNCAGED_WRATH, true); + Remove(); } - }; - - AuraScript* GetAuraScript() const override - { - return new spell_illidan_tear_of_azzinoth_channel_AuraScript(); } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_tear_of_azzinoth_channel::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; // 40631 - Flame Blast -class spell_illidan_flame_blast : public SpellScriptLoader +class spell_illidan_flame_blast : public SpellScript { - public: - spell_illidan_flame_blast() : SpellScriptLoader("spell_illidan_flame_blast") { } + PrepareSpellScript(spell_illidan_flame_blast); - class spell_illidan_flame_blast_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_flame_blast_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_BLAZE_SUMMON }); - } - - void HandleBlaze(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - if (target->GetTypeId() == TYPEID_PLAYER) - target->CastSpell(target, SPELL_BLAZE_SUMMON, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_BLAZE_SUMMON }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_flame_blast_SpellScript::HandleBlaze, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); - } - }; + void HandleBlaze(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + if (target->GetTypeId() == TYPEID_PLAYER) + target->CastSpell(target, SPELL_BLAZE_SUMMON, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_flame_blast_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_flame_blast::HandleBlaze, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE); + } }; // 39873 - Glaive Returns -class spell_illidan_return_glaives : public SpellScriptLoader +class spell_illidan_return_glaives : public SpellScript { - public: spell_illidan_return_glaives() : SpellScriptLoader("spell_illidan_return_glaives") { } - - class spell_illidan_return_glaives_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_return_glaives_SpellScript); - - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - GetHitUnit()->SendPlaySpellVisualKit(SPELL_GLAIVE_VISUAL_KIT, 0, 0); - if (Creature* caster = GetCaster()->ToCreature()) - caster->DespawnOrUnsummon(); - } + PrepareSpellScript(spell_illidan_return_glaives); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_return_glaives_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->SendPlaySpellVisualKit(SPELL_GLAIVE_VISUAL_KIT, 0, 0); + if (Creature* caster = GetCaster()->ToCreature()) + caster->DespawnOrUnsummon(); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_return_glaives_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_return_glaives::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 40834 - Agonizing Flames -class spell_illidan_agonizing_flames : public SpellScriptLoader +class spell_illidan_agonizing_flames : public SpellScript { - public: - spell_illidan_agonizing_flames() : SpellScriptLoader("spell_illidan_agonizing_flames") { } - - class spell_illidan_agonizing_flames_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_agonizing_flames_SpellScript); + PrepareSpellScript(spell_illidan_agonizing_flames); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_AGONIZING_FLAMES }); - } - - void FilterTargets(std::list<WorldObject*>& targets) - { - if (targets.empty()) - return; + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_AGONIZING_FLAMES }); + } - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } + void FilterTargets(std::list<WorldObject*>& targets) + { + if (targets.empty()) + return; - void HandleScript(SpellEffIndex /*effIndex*/) - { - GetCaster()->CastSpell(GetHitUnit(), SPELL_AGONIZING_FLAMES, true); - } + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_illidan_agonizing_flames_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_illidan_agonizing_flames_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleScript(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_AGONIZING_FLAMES, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_agonizing_flames_SpellScript(); - } + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_illidan_agonizing_flames::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_illidan_agonizing_flames::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 40511 - Demon Transform 1 -class spell_illidan_demon_transform1 : public SpellScriptLoader +class spell_illidan_demon_transform1 : public AuraScript { - public: - spell_illidan_demon_transform1() : SpellScriptLoader("spell_illidan_demon_transform1") { } - - class spell_illidan_demon_transform1_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_demon_transform1_AuraScript); + PrepareAuraScript(spell_illidan_demon_transform1); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEMON_TRANSFORM_2 }); - } - - void OnPeriodic(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - GetTarget()->CastSpell(GetTarget(), SPELL_DEMON_TRANSFORM_2, true); - Remove(); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DEMON_TRANSFORM_2 }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform1_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + GetTarget()->CastSpell(GetTarget(), SPELL_DEMON_TRANSFORM_2, true); + Remove(); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidan_demon_transform1_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform1::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; + // 40398 - Demon Transform 2 -class spell_illidan_demon_transform2 : public SpellScriptLoader +class spell_illidan_demon_transform2 : public AuraScript { - public: - spell_illidan_demon_transform2() : SpellScriptLoader("spell_illidan_demon_transform2") { } - - class spell_illidan_demon_transform2_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_demon_transform2_AuraScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_DEMON_FORM, SPELL_DEMON_TRANSFORM_3 }); - } - - void OnPeriodic(AuraEffect const* aurEff) - { - PreventDefaultAction(); - Unit* target = GetTarget(); + PrepareAuraScript(spell_illidan_demon_transform2); - if (aurEff->GetTickNumber() == 1) - { - if (target->GetDisplayId() == target->GetNativeDisplayId()) - target->CastSpell(target, SPELL_DEMON_FORM, true); - else - target->RemoveAurasDueToSpell(SPELL_DEMON_FORM); - } - else if (aurEff->GetTickNumber() == 2) - { - target->CastSpell(target, SPELL_DEMON_TRANSFORM_3, true); - if (Aura* aura = GetUnitOwner()->GetAura(SPELL_DEMON_TRANSFORM_3)) - aura->SetDuration(4300); - Remove(); - } - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_DEMON_FORM, SPELL_DEMON_TRANSFORM_3 }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform2_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + void OnPeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + Unit* target = GetTarget(); - AuraScript* GetAuraScript() const override + if (aurEff->GetTickNumber() == 1) + { + if (target->GetDisplayId() == target->GetNativeDisplayId()) + target->CastSpell(target, SPELL_DEMON_FORM, true); + else + target->RemoveAurasDueToSpell(SPELL_DEMON_FORM); + } + else if (aurEff->GetTickNumber() == 2) { - return new spell_illidan_demon_transform2_AuraScript(); + target->CastSpell(target, SPELL_DEMON_TRANSFORM_3, true); + if (Aura* aura = GetUnitOwner()->GetAura(SPELL_DEMON_TRANSFORM_3)) + aura->SetDuration(4300); + Remove(); } + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform2::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; // 41126 - Flame Burst -class spell_illidan_flame_burst : public SpellScriptLoader +class spell_illidan_flame_burst : public SpellScript { - public: - spell_illidan_flame_burst() : SpellScriptLoader("spell_illidan_flame_burst") { } - - class spell_illidan_flame_burst_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_flame_burst_SpellScript); + PrepareSpellScript(spell_illidan_flame_burst); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_FLAME_BURST_EFFECT }); - } - - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - GetHitUnit()->CastSpell(GetHitUnit(), SPELL_FLAME_BURST_EFFECT, true); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FLAME_BURST_EFFECT }); + } - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_flame_burst_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_FLAME_BURST_EFFECT, true); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_flame_burst_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_flame_burst::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 41081 - Find Target -class spell_illidan_find_target : public SpellScriptLoader +class spell_illidan_find_target : public SpellScript { - public: - spell_illidan_find_target() : SpellScriptLoader("spell_illidan_find_target") { } - - class spell_illidan_find_target_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_find_target_SpellScript); - - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_PARALYZE }); - } + PrepareSpellScript(spell_illidan_find_target); - void FilterTargets(std::list<WorldObject*>& targets) - { - targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_PARALYZE)); + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PARALYZE }); + } - if (targets.empty()) - return; + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_PARALYZE)); - WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); - targets.clear(); - targets.push_back(target); - } + if (targets.empty()) + return; - void HandleScript(SpellEffIndex /*effIndex*/) - { - Unit* target = GetHitUnit(); - if (Creature* caster = GetCaster()->ToCreature()) - { - caster->CastSpell(target, SPELL_PARALYZE, true); - caster->AI()->SetGUID(target->GetGUID(), 0); - } - } - - void Register() override - { - OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_illidan_find_target_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); - OnEffectHitTarget += SpellEffectFn(spell_illidan_find_target_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets); + targets.clear(); + targets.push_back(target); + } - SpellScript* GetSpellScript() const override + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* target = GetHitUnit(); + if (Creature* caster = GetCaster()->ToCreature()) { - return new spell_illidan_find_target_SpellScript(); + caster->CastSpell(target, SPELL_PARALYZE, true); + caster->AI()->SetGUID(target->GetGUID(), 0); } + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_illidan_find_target::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY); + OnEffectHitTarget += SpellEffectFn(spell_illidan_find_target::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; // 39908 - Eye Blast -class spell_illidan_eye_blast : public SpellScriptLoader +class spell_illidan_eye_blast : public AuraScript { - public: - spell_illidan_eye_blast() : SpellScriptLoader("spell_illidan_eye_blast") { } - - class spell_illidan_eye_blast_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_eye_blast_AuraScript); - - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - if (Creature* target = GetTarget()->ToCreature()) - target->DespawnOrUnsummon(); - } + PrepareAuraScript(spell_illidan_eye_blast); - void Register() override - { - AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_eye_blast_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); - } - }; + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (Creature* target = GetTarget()->ToCreature()) + target->DespawnOrUnsummon(); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidan_eye_blast_AuraScript(); - } + void Register() override + { + AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_eye_blast::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); + } }; // 40761 - Cage Trap -class spell_illidan_cage_trap : public SpellScriptLoader +class spell_illidan_cage_trap : public SpellScript { - public: - spell_illidan_cage_trap() : SpellScriptLoader("spell_illidan_cage_trap") { } - - class spell_illidan_cage_trap_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_cage_trap_SpellScript); - - void HandleScriptEffect(SpellEffIndex /*effIndex*/) - { - Creature* target = GetHitCreature(); - Creature* caster = GetCaster()->ToCreature(); - - if (!target || !caster) - return; + PrepareSpellScript(spell_illidan_cage_trap); - if (caster->GetDistance2d(target) < 4.0f) - { - target->AI()->DoAction(ACTION_ILLIDAN_CAGED); - caster->DespawnOrUnsummon(); - if (GameObject* trap = target->FindNearestGameObject(GO_ILLIDAN_CAGE_TRAP, 10.0f)) - trap->UseDoorOrButton(); - } - } + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + Creature* target = GetHitCreature(); + Creature* caster = GetCaster()->ToCreature(); - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_cage_trap_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + if (!target || !caster) + return; - SpellScript* GetSpellScript() const override + if (caster->GetDistance2d(target) < 4.0f) { - return new spell_illidan_cage_trap_SpellScript(); + target->AI()->DoAction(ACTION_ILLIDAN_CAGED); + caster->DespawnOrUnsummon(); + if (GameObject* trap = target->FindNearestGameObject(GO_ILLIDAN_CAGE_TRAP, 10.0f)) + trap->UseDoorOrButton(); } + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_cage_trap::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } }; // 40760 - Cage Trap -class spell_illidan_caged : public SpellScriptLoader +class spell_illidan_caged : public AuraScript { - public: - spell_illidan_caged() : SpellScriptLoader("spell_illidan_caged") { } - - class spell_illidan_caged_AuraScript : public AuraScript - { - PrepareAuraScript(spell_illidan_caged_AuraScript); + PrepareAuraScript(spell_illidan_caged); - bool Validate(SpellInfo const* /*spellInfo*/) override - { - return ValidateSpellInfo({ SPELL_CAGED_DEBUFF }); - } - - void OnPeriodic(AuraEffect const* /*aurEff*/) - { - PreventDefaultAction(); - Unit* target = GetTarget(); - target->CastSpell(target, SPELL_CAGED_DEBUFF, true); - Remove(); - } + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_CAGED_DEBUFF }); + } - void Register() override - { - OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_caged_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); - } - }; + void OnPeriodic(AuraEffect const* /*aurEff*/) + { + PreventDefaultAction(); + Unit* target = GetTarget(); + target->CastSpell(target, SPELL_CAGED_DEBUFF, true); + Remove(); + } - AuraScript* GetAuraScript() const override - { - return new spell_illidan_caged_AuraScript(); - } + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_caged::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } }; // 40409 - Maiev Down -class spell_maiev_down : public SpellScriptLoader +class spell_maiev_down : public AuraScript { -public: - spell_maiev_down() : SpellScriptLoader("spell_maiev_down") { } + PrepareAuraScript(spell_maiev_down); - class spell_maiev_down_AuraScript : public AuraScript + bool Load() override { - PrepareAuraScript(spell_maiev_down_AuraScript); - - bool Load() override - { - return GetUnitOwner()->GetTypeId() == TYPEID_UNIT; - } - - void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - } + return GetUnitOwner()->GetTypeId() == TYPEID_UNIT; + } - void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) - { - GetTarget()->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - GetTarget()->GetAI()->DoAction(ACTION_MAIEV_DOWN_FADE); - } + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->AddUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + } - void Register() override - { - OnEffectApply += AuraEffectApplyFn(spell_maiev_down_AuraScript::HandleEffectApply, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); - AfterEffectRemove += AuraEffectRemoveFn(spell_maiev_down_AuraScript::HandleEffectRemove, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); - } - }; + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + GetTarget()->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + GetTarget()->GetAI()->DoAction(ACTION_MAIEV_DOWN_FADE); + } - AuraScript* GetAuraScript() const override + void Register() override { - return new spell_maiev_down_AuraScript(); + OnEffectApply += AuraEffectApplyFn(spell_maiev_down::HandleEffectApply, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_maiev_down::HandleEffectRemove, EFFECT_1, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); } }; // 40693 - Cage Trap -class spell_illidan_cage_teleport : public SpellScriptLoader +class spell_illidan_cage_teleport : public SpellScript { - public: - spell_illidan_cage_teleport() : SpellScriptLoader("spell_illidan_cage_teleport") { } - - class spell_illidan_cage_teleport_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_cage_teleport_SpellScript); - - void SetDest(SpellDestination& dest) - { - Position offset = { 0.0f, 0.0f, GetCaster()->GetPositionZ(), 0.0f }; - dest.RelocateOffset(offset); - } + PrepareSpellScript(spell_illidan_cage_teleport); - void Register() override - { - OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_illidan_cage_teleport_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER_RADIUS); - } - }; + void SetDest(SpellDestination& dest) + { + Position offset = { 0.0f, 0.0f, GetCaster()->GetPositionZ(), 0.0f }; + dest.RelocateOffset(offset); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_cage_teleport_SpellScript(); - } + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_illidan_cage_teleport::SetDest, EFFECT_0, TARGET_DEST_CASTER_RADIUS); + } }; // 41242 - Akama Despawn -class spell_illidan_despawn_akama : public SpellScriptLoader +class spell_illidan_despawn_akama : public SpellScript { - public: - spell_illidan_despawn_akama() : SpellScriptLoader("spell_illidan_despawn_akama") { } - - class spell_illidan_despawn_akama_SpellScript : public SpellScript - { - PrepareSpellScript(spell_illidan_despawn_akama_SpellScript); + PrepareSpellScript(spell_illidan_despawn_akama); - void HandleDummy(SpellEffIndex /*effIndex*/) - { - if (Creature* target = GetHitCreature()) - target->DespawnOrUnsummon(Seconds(1)); - } - - void Register() override - { - OnEffectHitTarget += SpellEffectFn(spell_illidan_despawn_akama_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); - } - }; + void HandleDummy(SpellEffIndex /*effIndex*/) + { + if (Creature* target = GetHitCreature()) + target->DespawnOrUnsummon(Seconds(1)); + } - SpellScript* GetSpellScript() const override - { - return new spell_illidan_despawn_akama_SpellScript(); - } + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_illidan_despawn_akama::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } }; void AddSC_boss_illidan() { - new boss_illidan_stormrage(); - new npc_akama(); - new npc_parasitic_shadowfiend(); - new npc_blade_of_azzinoth(); - new npc_flame_of_azzinoth(); - new npc_illidan_db_target(); - new npc_maiev(); - new npc_illidan_shadow_demon(); - new npc_cage_trap_trigger(); - new spell_illidan_akama_teleport(); - new spell_illidan_akama_door_channel(); - new spell_illidan_draw_soul(); - new spell_illidan_parasitic_shadowfiend(); - new spell_illidan_throw_warglaive(); - new spell_illidan_tear_of_azzinoth_channel(); - new spell_illidan_flame_blast(); - new spell_illidan_return_glaives(); - new spell_illidan_agonizing_flames(); - new spell_illidan_demon_transform1(); - new spell_illidan_demon_transform2(); - new spell_illidan_flame_burst(); - new spell_illidan_find_target(); - new spell_illidan_eye_blast(); - new spell_illidan_cage_trap(); - new spell_illidan_caged(); - new spell_maiev_down(); - new spell_illidan_cage_teleport(); - new spell_illidan_despawn_akama(); + RegisterBlackTempleCreatureAI(boss_illidan_stormrage); + RegisterBlackTempleCreatureAI(npc_akama_illidan); + RegisterBlackTempleCreatureAI(npc_parasitic_shadowfiend); + RegisterBlackTempleCreatureAI(npc_blade_of_azzinoth); + RegisterBlackTempleCreatureAI(npc_flame_of_azzinoth); + RegisterBlackTempleCreatureAI(npc_illidan_db_target); + RegisterBlackTempleCreatureAI(npc_maiev); + RegisterBlackTempleCreatureAI(npc_shadow_demon); + RegisterBlackTempleCreatureAI(npc_cage_trap_trigger); + RegisterBlackTempleCreatureAI(npc_illidari_elite); + RegisterSpellScript(spell_illidan_akama_teleport); + RegisterAuraScript(spell_illidan_akama_door_channel); + RegisterSpellScript(spell_illidan_draw_soul); + RegisterAuraScript(spell_illidan_parasitic_shadowfiend); + RegisterAuraScript(spell_illidan_remove_parasitic_shadowfiend); + RegisterSpellScript(spell_illidan_throw_warglaive); + RegisterAuraScript(spell_illidan_tear_of_azzinoth_channel); + RegisterSpellScript(spell_illidan_flame_blast); + RegisterSpellScript(spell_illidan_return_glaives); + RegisterSpellScript(spell_illidan_agonizing_flames); + RegisterAuraScript(spell_illidan_demon_transform1); + RegisterAuraScript(spell_illidan_demon_transform2); + RegisterSpellScript(spell_illidan_flame_burst); + RegisterSpellScript(spell_illidan_find_target); + RegisterAuraScript(spell_illidan_eye_blast); + RegisterSpellScript(spell_illidan_cage_trap); + RegisterAuraScript(spell_illidan_caged); + RegisterAuraScript(spell_maiev_down); + RegisterSpellScript(spell_illidan_cage_teleport); + RegisterSpellScript(spell_illidan_despawn_akama); } |