aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/master/2021_01_15_01_world_2017_10_27_00_world.sql13
-rw-r--r--src/server/game/Spells/SpellInfo.cpp4
-rw-r--r--src/server/scripts/Outland/BlackTemple/black_temple.h5
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp3213
4 files changed, 1511 insertions, 1724 deletions
diff --git a/sql/updates/world/master/2021_01_15_01_world_2017_10_27_00_world.sql b/sql/updates/world/master/2021_01_15_01_world_2017_10_27_00_world.sql
new file mode 100644
index 00000000000..90558be747a
--- /dev/null
+++ b/sql/updates/world/master/2021_01_15_01_world_2017_10_27_00_world.sql
@@ -0,0 +1,13 @@
+UPDATE `creature_template` SET `ScriptName`='npc_illidari_elite' WHERE `entry`=23226;
+
+DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_illidan_remove_parasitic_shadowfiend';
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(41923,'spell_illidan_remove_parasitic_shadowfiend');
+
+DELETE FROM `spell_dbc` WHERE `Id`=41923;
+INSERT INTO `spell_dbc` (`Id`, `Attributes`, `AttributesEx`, `AttributesEx2`, `AttributesEx3`, `AttributesEx4`, `AttributesEx5`, `AttributesEx6`, `AttributesEx7`, `AttributesEx8`, `AttributesEx9`, `AttributesEx10`, `CastingTimeIndex`, `DurationIndex`, `RangeIndex`, `SchoolMask`, `SpellAuraOptionsId`, `SpellCastingRequirementsId`, `SpellCategoriesId`, `SpellClassOptionsId`, `SpellEquippedItemsId`, `SpellLevelsId`, `SpellTargetRestrictionsId`, `SpellInterruptsId`, `Comment`) VALUES
+(41923, 536871296, 268435592, 4, 256, 0, 8, 0, 0, 0, 0, 0, 1, 27, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Remove Parasitic Shadowfiends');
+
+DELETE FROM `spelleffect_dbc` WHERE `Id`=155918;
+INSERT INTO `spelleffect_dbc` (`Id`, `Effect`, `EffectValueMultiplier`, `EffectApplyAuraName`, `EffectAmplitude`, `EffectBasePoints`, `EffectBonusMultiplier`, `EffectDamageMultiplier`, `EffectChainTarget`, `EffectDieSides`, `EffectItemType`, `EffectMechanic`, `EffectMiscValue`, `EffectMiscValueB`, `EffectRadiusIndex`, `EffectRadiusIndexMax`, `EffectRealPointsPerLevel`, `EffectSpellClassMaskA`, `EffectSpellClassMaskB`, `EffectSpellClassMaskC`, `EffectTriggerSpell`, `EffectImplicitTargetA`, `EffectImplicitTargetB`, `EffectSpellId`, `EffectIndex`) VALUES
+(155918, 6, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 22, 15, 41923, 0);
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);
}