Files
azerothcore-wotlk/src/scripts/Outland/BlackTemple/boss_illidan.cpp
Yehonal 2b2e299ccc Fixed all unused-parameters warnings
issue #121

used clang-tidy to achieve this
2017-09-18 14:23:26 +02:00

1420 lines
59 KiB
C++

/*
* Originally written by Xinef - Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-AGPL
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "black_temple.h"
enum Says
{
SAY_ILLIDAN_MINION = 0,
SAY_ILLIDAN_KILL = 1,
SAY_ILLIDAN_TAKEOFF = 2,
SAY_ILLIDAN_SUMMONFLAMES = 3,
SAY_ILLIDAN_EYE_BLAST = 4,
SAY_ILLIDAN_MORPH = 5,
SAY_ILLIDAN_ENRAGE = 6,
SAY_ILLIDAN_TAUNT = 7,
SAY_ILLIDAN_AKAMA1 = 8,
SAY_ILLIDAN_AKAMA2 = 9,
SAY_ILLIDAN_AKAMA3 = 10,
SAY_ILLIDAN_MAIEV1 = 11,
SAY_ILLIDAN_MAIEV2 = 12,
SAY_ILLIDAN_MAIEV3 = 13,
SAY_ILLIDAN_FRENZY = 14,
SAY_UDALO = 0,
SAY_OLUM = 0,
SAY_AKAMA_DOORS = 0,
SAY_AKAMA_FAIL = 1,
SAY_AKAMA_BEWARE = 2,
SAY_AKAMA_LEAVE = 3,
SAY_AKAMA_ILLIDAN1 = 4,
SAY_AKAMA_ILLIDAN2 = 5,
SAY_AKAMA_ILLIDAN3 = 6,
SAY_MAIEV_SHADOWSONG_TAUNT = 0,
SAY_MAIEV_SHADOWSONG_ILLIDAN1 = 1,
SAY_MAIEV_SHADOWSONG_ILLIDAN2 = 2,
SAY_MAIEV_SHADOWSONG_ILLIDAN3 = 3,
SAY_MAIEV_SHADOWSONG_ILLIDAN4 = 4,
SAY_MAIEV_SHADOWSONG_ILLIDAN5 = 5,
EMOTE_AZZINOTH_GAZE = 0
};
enum Spells
{
// Phase 1
SPELL_DUAL_WIELD = 42459,
SPELL_BERSERK = 45078,
SPELL_FLAME_CRASH = 40832,
SPELL_DRAW_SOUL = 40904,
SPELL_DRAW_SOUL_HEAL = 40903,
SPELL_PARASITIC_SHADOWFIEND = 41917,
SPELL_PARASITIC_SHADOWFIEND_TRIGGER = 41914,
SPELL_SUMMON_PARASITIC_SHADOWFIENDS = 41915,
// Phase 2
SPELL_THROW_GLAIVE = 39635,
SPELL_THROW_GLAIVE2 = 39849,
SPELL_GLAIVE_RETURNS = 39873,
SPELL_SUMMON_GLAIVE = 41466,
SPELL_FIREBALL = 40598,
SPELL_DARK_BARRAGE = 40585,
SPELL_EYE_BLAST = 39908,
SPELL_UNCAGED_WRATH = 39869,
SPELL_FLAME_BLAST = 40631,
SPELL_CHARGE = 42003,
// Phase 3
SPELL_AGONIZING_FLAMES = 40932,
SPELL_SUMMON_MAIEV = 40403,
SPELL_SHADOW_PRISON = 40647,
SPELL_TELEPORT_VISUAL_ONLY = 41232,
// Phase 4
SPELL_DEMON_TRANSFORM_1 = 40511,
SPELL_DEMON_TRANSFORM_2 = 40398,
SPELL_DEMON_TRANSFORM_3 = 40510,
SPELL_DEMON_FORM = 40506,
SPELL_SHADOW_BLAST = 41078,
SPELL_FLAME_BURST = 41126,
SPELL_FLAME_BURST_EFFECT = 41131,
SPELL_SUMMON_SHADOW_DEMON = 41117,
SPELL_CONSUME_SOUL = 41080,
SPELL_FIND_TARGET = 41081,
// Phase 5
SPELL_FRENZY = 40683,
SPELL_TELEPORT_MAIEV = 41221,
SPELL_SHADOW_STRIKE = 40685,
SPELL_THROW_DAGGER = 41152,
SPELL_DEATH = 41220,
// Cage
SPELL_CAGED_DEBUFF = 40695,
SPELL_CAGED_SUMMON1 = 40696,
SPELL_CAGED_SUMMON8 = 40703,
SPELL_CAGE_TRAP = 40760
};
enum Misc
{
ACTION_FIGHT_MINIONS = 1,
ACTION_RETURN_BLADE = 2,
ACTION_ILLIDAN_CAGED = 3,
ACTION_ILLIDAN_DEAD = 4,
ACTION_MAIEV_SET_DIST30 = 5,
ACTION_MAIEV_SET_DIST0 = 6,
ACTION_MAIEV_OUTRO = 7,
MAX_EYE_BEAM_POS = 4,
POINT_ILLIDAN_HOVER = 10,
POINT_ILLIDAN_MIDDLE = 11,
NPC_ILLIDAN_DB_TARGET = 23070,
NPC_MAIEV_SHADOWSONG = 23197,
GO_CAGE_TRAP = 185916
};
enum Events
{
EVENT_SPELL_FLAME_CRASH = 1,
EVENT_SPELL_BERSERK = 2,
EVENT_SPELL_DRAW_SOUL = 3,
EVENT_SPELL_PARASITIC_SHADOWFIEND = 4,
EVENT_SPELL_AGONIZING_FLAMES = 5,
EVENT_SPELL_FRENZY = 6,
EVENT_SUMMON_MINIONS = 20,
EVENT_SUMMON_MINIONS2 = 21,
EVENT_PHASE_2_START = 40,
EVENT_SPELL_FIREBALL = 41,
EVENT_SPELL_DARK_BARRAGE = 42,
EVENT_START_PHASE_2_END = 43,
EVENT_START_PHASE_2_WEAPON = 44,
EVENT_START_PHASE_3_LAND = 45,
EVENT_PHASE_2_SUMMON1 = 46,
EVENT_PHASE_2_SUMMON2 = 47,
EVENT_PHASE_2_EYE_BEAM = 48,
EVENT_PHASE_2_EYE_BEAM_START = 49,
EVENT_PHASE_2_CHANGE_POS = 50,
EVENT_PHASE_2_INTERRUPT = 51,
EVENT_PHASE_4_START = 60,
EVENT_PHASE_5_START = 61,
EVENT_PHASE_5_SCENE1 = 62,
EVENT_PHASE_5_SCENE2 = 63,
EVENT_PHASE_5_SCENE3 = 64,
EVENT_PHASE_5_SCENE4 = 65,
EVENT_PHASE_5_SCENE5 = 66,
EVENT_REMOVE_DEMON_FORM = 80,
EVENT_SPELL_FLAME_BURST = 81,
EVENT_SPELL_SHADOW_BLAST = 82,
EVENT_SPELL_SHADOW_DEMONS = 83,
EVENT_MOVE_MAIEV = 84,
EVENT_FINISH_TRANSFORM = 85, // Dummy, counter only
EVENT_OUTRO_DEMON = 90,
EVENT_OUTRO_1 = 91,
EVENT_OUTRO_2 = 92,
EVENT_OUTRO_3 = 93,
EVENT_KILL_TALK = 100,
EVENT_SAY_TAUNT = 101,
GROUP_PHASE_2_ABILITY = 1
};
const Position eyeBeamPos[MAX_EYE_BEAM_POS*2] =
{
{639.97f, 301.63f, 354.0f, 0.0f},
{658.83f, 265.10f, 354.0f, 0.0f},
{656.86f, 344.07f, 354.0f, 0.0f},
{640.70f, 310.47f, 354.0f, 0.0f},
{706.22f, 273.26f, 354.0f, 0.0f},
{717.55f, 328.33f, 354.0f, 0.0f},
{718.06f, 286.08f, 354.0f, 0.0f},
{705.92f, 337.14f, 354.0f, 0.0f}
};
const Position airHoverPos[MAX_EYE_BEAM_POS] =
{
{658.83f, 265.10f, 356.0f, 0.0f},
{706.22f, 273.26f, 356.0f, 0.0f},
{705.92f, 337.14f, 356.0f, 0.0f},
{656.86f, 344.07f, 356.0f, 0.0f}
};
class boss_illidan_stormrage : public CreatureScript
{
public:
boss_illidan_stormrage() : CreatureScript("boss_illidan_stormrage") { }
struct boss_illidan_stormrageAI : public BossAI
{
boss_illidan_stormrageAI(Creature* creature) : BossAI(creature, DATA_ILLIDAN_STORMRAGE)
{
}
EventMap events2;
uint8 beamPosId;
void Reset()
{
BossAI::Reset();
events2.Reset();
me->SetDisableGravity(false);
me->CastSpell(me, SPELL_DUAL_WIELD, true);
me->LoadEquipment(0, true);
me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
beamPosId = urand(0, 3);
}
void EnterEvadeMode()
{
BossAI::EnterEvadeMode();
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_AKAMA)))
akama->AI()->EnterEvadeMode();
}
bool CanAIAttack(const Unit* target) const
{
return target->GetEntry() != NPC_AKAMA && target->GetEntry() != NPC_MAIEV_SHADOWSONG;
}
void DoAction(int32 param)
{
if (param == ACTION_ILLIDAN_CAGED)
{
me->RemoveAurasDueToSpell(SPELL_FRENZY);
events.Reset();
events.ScheduleEvent(EVENT_PHASE_4_START, 16000);
}
}
void JustSummoned(Creature* summon)
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_ILLIDAN_DB_TARGET)
me->CastSpell(summon, SPELL_EYE_BLAST, false);
else if (summon->GetEntry() == NPC_MAIEV_SHADOWSONG)
{
me->SetTarget(summon->GetGUID());
me->SetFacingToObject(summon);
summon->SetFacingToObject(me);
summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
summon->SetReactState(REACT_PASSIVE);
summon->CastSpell(summon, SPELL_TELEPORT_VISUAL_ONLY, true);
}
}
void SummonedCreatureDies(Creature* summon, Unit*)
{
summons.Despawn(summon);
}
void SummonedCreatureDespawn(Creature* summon)
{
summons.Despawn(summon);
}
void MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE)
return;
if (id == POINT_ILLIDAN_HOVER)
{
if (events2.GetNextEventTime(EVENT_START_PHASE_2_END) == 0)
{
events.ScheduleEvent(EVENT_PHASE_2_SUMMON2, 2000);
events.ScheduleEvent(EVENT_PHASE_2_CHANGE_POS, 6000);
events.ScheduleEvent(EVENT_PHASE_2_EYE_BEAM, 15000, GROUP_PHASE_2_ABILITY);
events2.ScheduleEvent(EVENT_START_PHASE_2_END, 10000);
}
me->SetFacingTo(me->GetAngle(676.02f, 305.45f));
}
else if (id == POINT_ILLIDAN_MIDDLE)
{
EntryCheckPredicate pred(NPC_BLADE_OF_AZZINOTH);
summons.DoAction(ACTION_RETURN_BLADE, pred);
events.ScheduleEvent(EVENT_START_PHASE_2_WEAPON, 1500);
events.ScheduleEvent(EVENT_START_PHASE_3_LAND, 4000);
}
}
void ScheduleNormalEvents(uint8 phase)
{
events.ScheduleEvent(EVENT_SPELL_FLAME_CRASH, 15000);
events.ScheduleEvent(EVENT_SPELL_DRAW_SOUL, 30000);
events.ScheduleEvent(EVENT_SPELL_PARASITIC_SHADOWFIEND, 20000);
events.ScheduleEvent(EVENT_SAY_TAUNT, 40000);
if (phase >= 3)
{
events.ScheduleEvent(EVENT_PHASE_4_START, 60000);
events.ScheduleEvent(EVENT_SPELL_AGONIZING_FLAMES, 10000);
}
if (phase >= 5)
events.ScheduleEvent(EVENT_SPELL_FRENZY, 40000);
}
void EnterCombat(Unit* who)
{
summons.DespawnAll();
BossAI::EnterCombat(who);
ScheduleNormalEvents(1);
events.ScheduleEvent(EVENT_SPELL_BERSERK, 25*MINUTE*IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SUMMON_MINIONS, 1000);
events.ScheduleEvent(EVENT_PHASE_2_START, 1000);
}
void AttackStart(Unit* victim)
{
if (victim && me->Attack(victim, true))
me->GetMotionMaster()->MoveChase(victim, events.GetNextEventTime(EVENT_REMOVE_DEMON_FORM) != 0 ? 35.0f : 0.0f);
}
void MoveInLineOfSight(Unit*) { }
void JustDied(Unit* /*killer*/)
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
summons.DespawnEntry(NPC_PARASITIC_SHADOWFIEND);
instance->SetBossState(DATA_ILLIDAN_STORMRAGE, DONE);
instance->SaveToDB();
}
void KilledUnit(Unit* /*victim*/)
{
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
Talk(SAY_ILLIDAN_KILL);
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
}
}
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask)
{
if (damage >= me->GetHealth())
{
damage = 0;
// xinef: do not allow to start outro when transforming
if (events.GetNextEventTime(EVENT_FINISH_TRANSFORM))
return;
if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
{
if (Creature* maiev = summons.GetCreatureWithEntry(NPC_MAIEV_SHADOWSONG))
{
maiev->StopMovingOnCurrentPos();
maiev->GetMotionMaster()->Clear();
maiev->SetReactState(REACT_PASSIVE);
maiev->SetFullHealth();
maiev->RemoveAllAuras();
maiev->CombatStop();
}
if (events.GetNextEventTime(EVENT_REMOVE_DEMON_FORM) != 0)
{
me->CastSpell(me, SPELL_DEMON_TRANSFORM_1, true);
events2.ScheduleEvent(EVENT_OUTRO_DEMON, 12000);
}
else
{
me->CastSpell(me, SPELL_TELEPORT_MAIEV, true);
me->CastSpell(me, SPELL_DEATH, true);
events2.ScheduleEvent(EVENT_OUTRO_1, 1000);
}
if (Creature* maiev = summons.GetCreatureWithEntry(NPC_MAIEV_SHADOWSONG))
{
maiev->SetTarget(me->GetGUID());
maiev->SetFacingToObject(me);
}
events.Reset();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
}
}
void UpdateAI(uint32 diff)
{
events2.Update(diff);
switch (events2.ExecuteEvent())
{
case EVENT_SUMMON_MINIONS2:
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_AKAMA)))
akama->AI()->DoAction(ACTION_FIGHT_MINIONS);
break;
case EVENT_PHASE_2_EYE_BEAM_START:
Talk(SAY_ILLIDAN_EYE_BLAST);
if (Creature* trigger = summons.GetCreatureWithEntry(NPC_ILLIDAN_DB_TARGET))
trigger->GetMotionMaster()->MovePoint(0, eyeBeamPos[beamPosId+MAX_EYE_BEAM_POS], false, true);
break;
case EVENT_PHASE_2_INTERRUPT:
me->InterruptNonMeleeSpells(false);
break;
case EVENT_START_PHASE_2_END:
summons.RemoveNotExisting();
if (!summons.HasEntry(NPC_FLAME_OF_AZZINOTH))
{
events.Reset();
events2.Reset();
me->InterruptNonMeleeSpells(false);
me->GetMotionMaster()->MovePoint(POINT_ILLIDAN_MIDDLE, 676.02f, 305.45f, 353.6f);
break;
}
events2.ScheduleEvent(EVENT_START_PHASE_2_END, 1000);
break;
case EVENT_OUTRO_DEMON:
me->CastSpell(me, SPELL_TELEPORT_MAIEV, true);
me->CastSpell(me, SPELL_DEATH, true);
events2.ScheduleEvent(EVENT_OUTRO_1, 1000);
break;
case EVENT_OUTRO_1:
if (Creature* maiev = summons.GetCreatureWithEntry(NPC_MAIEV_SHADOWSONG))
{
maiev->SetTarget(me->GetGUID());
maiev->SetFacingToObject(me);
maiev->AI()->DoAction(ACTION_MAIEV_OUTRO);
maiev->AI()->Talk(SAY_MAIEV_SHADOWSONG_ILLIDAN3);
}
if (Creature* akama = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_AKAMA)))
{
akama->AI()->DoAction(ACTION_ILLIDAN_DEAD);
akama->SetTarget(me->GetGUID());
akama->GetMotionMaster()->MovePoint(0, 695.63f, 306.63f, 354.26f);
}
events2.ScheduleEvent(EVENT_OUTRO_2, 6000);
break;
case EVENT_OUTRO_2:
Talk(SAY_ILLIDAN_MAIEV3);
events2.ScheduleEvent(EVENT_OUTRO_3, 17000);
break;
case EVENT_OUTRO_3:
Unit::Kill(NULL, me);
break;
}
EnterEvadeIfOutOfCombatArea();
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (uint32 eventId = events.ExecuteEvent())
{
case EVENT_SUMMON_MINIONS:
if (me->HealthBelowPct(90))
{
Talk(SAY_ILLIDAN_MINION);
events2.ScheduleEvent(EVENT_SUMMON_MINIONS2, 10000);
break;
}
events.ScheduleEvent(EVENT_SUMMON_MINIONS, 1000);
break;
// ///////////////////////////
// PHASE 1, 3, 5
// ///////////////////////////
case EVENT_SPELL_BERSERK:
Talk(SAY_ILLIDAN_ENRAGE);
me->CastSpell(me, SPELL_BERSERK, true);
break;
case EVENT_SPELL_FLAME_CRASH:
me->CastSpell(me->GetVictim(), SPELL_FLAME_CRASH, false);
events.ScheduleEvent(EVENT_SPELL_FLAME_CRASH, 25000);
break;
case EVENT_SPELL_DRAW_SOUL:
me->CastSpell(me->GetVictim(), SPELL_DRAW_SOUL, false);
events.ScheduleEvent(EVENT_SPELL_DRAW_SOUL, 40000);
break;
case EVENT_SPELL_PARASITIC_SHADOWFIEND:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
me->CastSpell(target, SPELL_PARASITIC_SHADOWFIEND, false);
events.ScheduleEvent(EVENT_SPELL_PARASITIC_SHADOWFIEND, 30000);
break;
case EVENT_SAY_TAUNT:
Talk(SAY_ILLIDAN_TAUNT);
events.ScheduleEvent(EVENT_SAY_TAUNT, urand(30000, 60000));
break;
case EVENT_SPELL_FRENZY:
Talk(SAY_ILLIDAN_FRENZY);
me->CastSpell(me, SPELL_FRENZY, false);
break;
case EVENT_SPELL_AGONIZING_FLAMES:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
me->CastSpell(target, SPELL_AGONIZING_FLAMES, false);
break;
case EVENT_PHASE_5_START:
if (me->HealthBelowPct(30))
{
me->CastSpell(me, SPELL_SHADOW_PRISON, true);
me->SendMeleeAttackStop(me->GetVictim());
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
Talk(SAY_ILLIDAN_MAIEV1);
events.Reset();
events.ScheduleEvent(EVENT_PHASE_5_SCENE1, 9000);
events.ScheduleEvent(EVENT_PHASE_5_SCENE2, 18000);
events.ScheduleEvent(EVENT_PHASE_5_SCENE3, 24000);
events.ScheduleEvent(EVENT_PHASE_5_SCENE4, 27000);
events.ScheduleEvent(EVENT_PHASE_5_SCENE5, 30000);
break;
}
events.ScheduleEvent(EVENT_PHASE_5_START, 1000);
break;
case EVENT_PHASE_5_SCENE1:
me->CastSpell(me, SPELL_SUMMON_MAIEV, true);
break;
case EVENT_PHASE_5_SCENE2:
Talk(SAY_ILLIDAN_MAIEV2);
break;
case EVENT_PHASE_5_SCENE3:
if (Creature* maiev = summons.GetCreatureWithEntry(NPC_MAIEV_SHADOWSONG))
maiev->AI()->Talk(SAY_MAIEV_SHADOWSONG_ILLIDAN2);
break;
case EVENT_PHASE_5_SCENE4:
if (Creature* maiev = summons.GetCreatureWithEntry(NPC_MAIEV_SHADOWSONG))
maiev->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
break;
case EVENT_PHASE_5_SCENE5:
me->SetTarget(me->GetVictim()->GetGUID());
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE|UNIT_FLAG_NON_ATTACKABLE);
if (Creature* maiev = summons.GetCreatureWithEntry(NPC_MAIEV_SHADOWSONG))
{
maiev->SetReactState(REACT_AGGRESSIVE);
maiev->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
maiev->AI()->AttackStart(me);
}
ScheduleNormalEvents(5);
break;
// ///////////////////////////
// PHASE 2
// ///////////////////////////
case EVENT_PHASE_2_START:
if (me->HealthBelowPct(65))
{
if (events2.GetNextEventTime(EVENT_SUMMON_MINIONS2) != 0)
events2.RescheduleEvent(EVENT_SUMMON_MINIONS2, 0);
Talk(SAY_ILLIDAN_TAKEOFF);
me->SendMeleeAttackStop(me->GetVictim());
me->SetTarget(0);
me->GetMotionMaster()->Clear();
me->StopMovingOnCurrentPos();
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
me->SetDisableGravity(true);
events.Reset();
events.ScheduleEvent(EVENT_PHASE_2_SUMMON1, 6000);
break;
}
events.ScheduleEvent(EVENT_PHASE_2_START, 1000);
break;
case EVENT_PHASE_2_SUMMON1:
me->LoadEquipment(1, true);
me->GetMotionMaster()->MovePoint(POINT_ILLIDAN_HOVER, 727.875f, 305.365f, 356.0f, false, true);
break;
case EVENT_PHASE_2_SUMMON2:
Talk(SAY_ILLIDAN_SUMMONFLAMES);
me->LoadEquipment(0, true);
me->CastSpell(me, SPELL_THROW_GLAIVE, false);
me->CastSpell(me, SPELL_THROW_GLAIVE2, false);
break;
case EVENT_PHASE_2_CHANGE_POS:
beamPosId = (++beamPosId)%MAX_EYE_BEAM_POS;
events.ScheduleEvent(EVENT_SPELL_FIREBALL, 8000, GROUP_PHASE_2_ABILITY);
events.ScheduleEvent(EVENT_SPELL_DARK_BARRAGE, 18000, GROUP_PHASE_2_ABILITY);
events.ScheduleEvent(EVENT_PHASE_2_EYE_BEAM, urand(25000, 50000), GROUP_PHASE_2_ABILITY);
me->GetMotionMaster()->MovePoint(POINT_ILLIDAN_HOVER, airHoverPos[beamPosId], false, true);
break;
case EVENT_PHASE_2_EYE_BEAM:
me->SummonCreature(NPC_ILLIDAN_DB_TARGET, eyeBeamPos[beamPosId], TEMPSUMMON_TIMED_DESPAWN, 15000);
events.CancelEventGroup(GROUP_PHASE_2_ABILITY);
events.ScheduleEvent(EVENT_PHASE_2_CHANGE_POS, 20000);
events2.ScheduleEvent(EVENT_PHASE_2_EYE_BEAM_START, 2000);
events2.ScheduleEvent(EVENT_PHASE_2_INTERRUPT, 20000);
break;
case EVENT_SPELL_FIREBALL:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
me->CastSpell(target, SPELL_FIREBALL, false);
events.ScheduleEvent(EVENT_SPELL_FIREBALL, 2200, GROUP_PHASE_2_ABILITY);
break;
case EVENT_SPELL_DARK_BARRAGE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
me->CastSpell(target, SPELL_DARK_BARRAGE, false);
events.ScheduleEvent(EVENT_SPELL_DARK_BARRAGE, 30000, GROUP_PHASE_2_ABILITY);
break;
case EVENT_START_PHASE_2_WEAPON:
me->LoadEquipment(1, true);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->SetDisableGravity(false);
break;
case EVENT_START_PHASE_3_LAND:
me->getThreatManager().resetAllAggro();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetTarget(me->GetVictim()->GetGUID());
AttackStart(me->GetVictim());
me->GetMotionMaster()->MoveChase(me->GetVictim());
ScheduleNormalEvents(3);
events.ScheduleEvent(EVENT_PHASE_5_START, 1000);
break;
// ///////////////////////////
// PHASE 4
// ///////////////////////////
case EVENT_PHASE_4_START:
me->CastSpell(me, SPELL_DEMON_TRANSFORM_1, true);
me->getThreatManager().resetAllAggro();
me->GetMotionMaster()->MoveChase(me->GetVictim(), 35.0f);
events.Reset();
events.ScheduleEvent(EVENT_SPELL_SHADOW_BLAST, 11000);
events.ScheduleEvent(EVENT_MOVE_MAIEV, 5000);
events.ScheduleEvent(EVENT_FINISH_TRANSFORM, 10500);
events.ScheduleEvent(EVENT_SPELL_FLAME_BURST, 21000);
events.ScheduleEvent(EVENT_SPELL_SHADOW_DEMONS, 36000);
events.ScheduleEvent(EVENT_REMOVE_DEMON_FORM, 60000);
break;
case EVENT_SPELL_SHADOW_BLAST:
me->CastSpell(me->GetVictim(), SPELL_SHADOW_BLAST, false);
events.ScheduleEvent(EVENT_SPELL_SHADOW_BLAST, 2200);
break;
case EVENT_SPELL_FLAME_BURST:
me->CastSpell(me, SPELL_FLAME_BURST, false);
events.ScheduleEvent(EVENT_SPELL_FLAME_BURST, 22000);
break;
case EVENT_SPELL_SHADOW_DEMONS:
me->CastSpell(me, SPELL_SUMMON_SHADOW_DEMON, false);
break;
case EVENT_REMOVE_DEMON_FORM:
me->CastSpell(me, SPELL_DEMON_TRANSFORM_1, true);
me->getThreatManager().resetAllAggro();
events.Reset();
if (summons.HasEntry(NPC_MAIEV_SHADOWSONG))
{
ScheduleNormalEvents(5);
events.DelayEvents(11000);
events.ScheduleEvent(EVENT_MOVE_MAIEV, 10000);
events.ScheduleEvent(EVENT_FINISH_TRANSFORM, 10500);
}
else
{
ScheduleNormalEvents(3);
events.ScheduleEvent(EVENT_PHASE_5_START, 1000);
events.DelayEvents(11000);
events.ScheduleEvent(EVENT_FINISH_TRANSFORM, 10500);
}
break;
case EVENT_MOVE_MAIEV:
if (Creature* maiev = summons.GetCreatureWithEntry(NPC_MAIEV_SHADOWSONG))
{
if (events.GetNextEventTime(EVENT_REMOVE_DEMON_FORM) != 0)
{
maiev->AI()->DoAction(ACTION_MAIEV_SET_DIST30);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, -25.0f, true))
maiev->GetMotionMaster()->MoveCharge(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 7.0f, 0);
else
maiev->GetMotionMaster()->MoveCharge(678.04f, 378.34f, 353.0f, 7.0f, 0);
}
else
{
maiev->AI()->DoAction(ACTION_MAIEV_SET_DIST0);
maiev->GetMotionMaster()->MoveChase(me, 0.0f);
}
}
break;
case EVENT_FINISH_TRANSFORM:
me->GetMotionMaster()->MoveChase(me->GetVictim(), events.GetNextEventTime(EVENT_REMOVE_DEMON_FORM) != 0 ? 35.0f : 0.0f);
break;
}
if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
DoMeleeAttackIfReady();
}
bool CheckEvadeIfOutOfCombatArea() const
{
return me->GetHomePosition().GetExactDist(me) > 90.0f || !SelectTargetFromPlayerList(80.0f);
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_illidan_stormrageAI>(creature);
}
};
enum Akama
{
POINT_DOORS = 20,
POINT_ILLIDAN = 32,
POINT_FIGHT_MINIONS = 40,
SPELL_AKAMA_DOOR_OPEN = 41268,
SPELL_AKAMA_DOOR_FAIL = 41271,
SPELL_DEATHSWORN_DOOR_OPEN = 41269,
SPELL_HEALING_POTION = 40535,
SPELL_CHAIN_LIGHTNING = 40536,
NPC_SPIRIT_OF_OLUM = 23411,
NPC_SPIRIT_OF_UDALO = 23410,
NPC_ILLIDARI_ELITE = 23226,
EVENT_AKAMA_SCENE_1 = 1,
EVENT_AKAMA_SCENE_2 = 2,
EVENT_AKAMA_SCENE_3 = 3,
EVENT_AKAMA_SCENE_4 = 4,
EVENT_AKAMA_SCENE_5 = 5,
EVENT_AKAMA_SCENE_6 = 6,
EVENT_AKAMA_SCENE_7 = 7,
EVENT_AKAMA_SCENE_8 = 8,
EVENT_AKAMA_SCENE_9 = 9,
EVENT_AKAMA_SCENE_10 = 10,
EVENT_AKAMA_SCENE_11 = 11,
EVENT_AKAMA_SCENE_20 = 20,
EVENT_AKAMA_SCENE_21 = 21,
EVENT_AKAMA_SCENE_22 = 22,
EVENT_AKAMA_SCENE_23 = 23,
EVENT_AKAMA_SCENE_24 = 24,
EVENT_AKAMA_SCENE_25 = 25,
EVENT_AKAMA_SCENE_26 = 26,
EVENT_AKAMA_SCENE_27 = 27,
EVENT_AKAMA_SCENE_28 = 28,
EVENT_AKAMA_SCENE_29 = 29,
EVENT_AKAMA_SUMMON_ILLIDARI = 100,
EVENT_AKAMA_SPELL_CHAIN = 101,
EVENT_AKAMA_HEALTH = 102
};
class npc_akama_illidan : public CreatureScript
{
public:
npc_akama_illidan() : CreatureScript("npc_akama_illidan") { }
struct npc_akama_illidanAI : public npc_escortAI
{
npc_akama_illidanAI(Creature* creature) : npc_escortAI(creature), summons(me)
{
instance = creature->GetInstanceScript();
if (instance->GetBossState(DATA_AKAMA_FINISHED) == DONE)
{
me->GetMap()->LoadGrid(751.664f, 238.933f);
me->SetHomePosition(751.664f, 238.933f, 353.106f, 2.18f);
me->NearTeleportTo(751.664f, 238.933f, 353.106f, 2.18f);
}
}
void DoAction(int32 param)
{
if (param == ACTION_FIGHT_MINIONS)
{
me->CombatStop(true);
events.ScheduleEvent(EVENT_AKAMA_SUMMON_ILLIDARI, 8000);
events.ScheduleEvent(EVENT_AKAMA_SPELL_CHAIN, 7000);
events.ScheduleEvent(EVENT_AKAMA_HEALTH, 1000);
me->GetMotionMaster()->MoveCharge(741.97f, 358.74f, 353.0f, 10.0f, POINT_FIGHT_MINIONS);
Talk(SAY_AKAMA_LEAVE);
}
else if (param == ACTION_ILLIDAN_DEAD)
{
events.Reset();
summons.DespawnAll();
me->CombatStop(true);
}
}
void Reset()
{
me->SetReactState(REACT_AGGRESSIVE);
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
me->setActive(false);
me->SetVisible(instance->GetBossState(DATA_ILLIDARI_COUNCIL) == DONE && instance->GetBossState(DATA_ILLIDAN_STORMRAGE) != DONE);
events.Reset();
summons.DespawnAll();
}
void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/)
{
player->CLOSE_GOSSIP_MENU();
me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
me->setActive(true);
if (instance->GetBossState(DATA_AKAMA_FINISHED) != DONE)
{
me->SetReactState(REACT_PASSIVE);
Start(false, true);
SetDespawnAtEnd(false);
}
else
{
me->GetMotionMaster()->MovePoint(POINT_ILLIDAN, 744.45f, 304.84f, 353.0f);
events.Reset();
events.ScheduleEvent(EVENT_AKAMA_SCENE_20, 5000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_21, 8000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_22, 10000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_23, 23000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_24, 34000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_25, 41000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_26, 46000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_27, 49000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_28, 49200);
events.ScheduleEvent(EVENT_AKAMA_SCENE_29, 52000);
}
}
void JustSummoned(Creature* summon)
{
summons.Summon(summon);
summon->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
if (summon->GetEntry() == NPC_ILLIDARI_ELITE)
{
me->AddThreat(summon, 1000000.0f);
summon->AddThreat(me, 1000000.0f);
summon->AI()->AttackStart(me);
AttackStart(summon);
}
}
void WaypointReached(uint32 pointId)
{
if (pointId == POINT_DOORS)
{
SetEscortPaused(true);
events.ScheduleEvent(EVENT_AKAMA_SCENE_1, 0);
events.ScheduleEvent(EVENT_AKAMA_SCENE_2, 4000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_3, 7000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_4, 17000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_5, 23000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_6, 25000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_7, 31000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_8, 40000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_9, 54000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_10, 57000);
events.ScheduleEvent(EVENT_AKAMA_SCENE_11, 62000);
}
else if (pointId == POINT_ILLIDAN)
{
me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
me->setActive(false);
me->SetReactState(REACT_AGGRESSIVE);
}
}
void MoveInLineOfSight(Unit* /*who*/) { }
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask)
{
if (damage >= me->GetHealth())
damage = 0;
}
void UpdateEscortAI(uint32 diff)
{
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_AKAMA_SCENE_1:
me->SetFacingTo(0.0f);
break;
case EVENT_AKAMA_SCENE_2:
Talk(SAY_AKAMA_DOORS);
break;
case EVENT_AKAMA_SCENE_3:
me->CastSpell(me, SPELL_AKAMA_DOOR_FAIL, false);
break;
case EVENT_AKAMA_SCENE_4:
Talk(SAY_AKAMA_FAIL);
break;
case EVENT_AKAMA_SCENE_5:
me->SummonCreature(NPC_SPIRIT_OF_UDALO, me->GetPositionX()-5.0f, me->GetPositionY()+8.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000);
me->SummonCreature(NPC_SPIRIT_OF_OLUM, me->GetPositionX()-5.0f, me->GetPositionY()-8.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 60000);
break;
case EVENT_AKAMA_SCENE_6:
if (Creature* udalo = me->FindNearestCreature(NPC_SPIRIT_OF_UDALO, 15.0f))
udalo->AI()->Talk(SAY_UDALO);
break;
case EVENT_AKAMA_SCENE_7:
if (Creature* olum = me->FindNearestCreature(NPC_SPIRIT_OF_OLUM, 15.0f))
olum->AI()->Talk(SAY_OLUM);
break;
case EVENT_AKAMA_SCENE_8:
me->CastSpell(me, SPELL_AKAMA_DOOR_OPEN, false);
if (Creature* olum = me->FindNearestCreature(NPC_SPIRIT_OF_OLUM, 15.0f))
olum->CastSpell(olum, SPELL_AKAMA_DOOR_OPEN, false);
if (Creature* udalo = me->FindNearestCreature(NPC_SPIRIT_OF_UDALO, 15.0f))
udalo->CastSpell(udalo, SPELL_AKAMA_DOOR_OPEN, false);
break;
case EVENT_AKAMA_SCENE_9:
instance->SetBossState(DATA_AKAMA_FINISHED, NOT_STARTED);
instance->SetBossState(DATA_AKAMA_FINISHED, DONE);
break;
case EVENT_AKAMA_SCENE_10:
Talk(SAY_AKAMA_BEWARE);
break;
case EVENT_AKAMA_SCENE_11:
SetEscortPaused(false);
break;
case EVENT_AKAMA_SCENE_20:
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ILLIDAN_STORMRAGE)))
illidan->SetStandState(UNIT_STAND_STATE_STAND);
break;
case EVENT_AKAMA_SCENE_21:
me->SetFacingTo(M_PI);
break;
case EVENT_AKAMA_SCENE_22:
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ILLIDAN_STORMRAGE)))
illidan->AI()->Talk(SAY_ILLIDAN_AKAMA1);
break;
case EVENT_AKAMA_SCENE_23:
Talk(SAY_AKAMA_ILLIDAN1);
break;
case EVENT_AKAMA_SCENE_24:
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ILLIDAN_STORMRAGE)))
illidan->AI()->Talk(SAY_ILLIDAN_AKAMA2);
break;
case EVENT_AKAMA_SCENE_25:
Talk(SAY_AKAMA_ILLIDAN2);
break;
case EVENT_AKAMA_SCENE_26:
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ILLIDAN_STORMRAGE)))
illidan->AI()->Talk(SAY_ILLIDAN_AKAMA3);
break;
case EVENT_AKAMA_SCENE_27:
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ILLIDAN_STORMRAGE)))
illidan->LoadEquipment(1, true);
break;
case EVENT_AKAMA_SCENE_28:
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ILLIDAN_STORMRAGE)))
illidan->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
break;
case EVENT_AKAMA_SCENE_29:
if (Creature* illidan = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_ILLIDAN_STORMRAGE)))
{
illidan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
illidan->SetInCombatWithZone();
AttackStart(illidan);
}
break;
case EVENT_AKAMA_SUMMON_ILLIDARI:
me->SummonCreature(NPC_ILLIDARI_ELITE, 742.55f, 359.12f, 353.0f, 4.35f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
events.ScheduleEvent(EVENT_AKAMA_SUMMON_ILLIDARI, urand(2000, 6000));
break;
case EVENT_AKAMA_SPELL_CHAIN:
if (me->GetVictim())
me->CastSpell(me->GetVictim(), SPELL_CHAIN_LIGHTNING, false);
events.ScheduleEvent(EVENT_AKAMA_SPELL_CHAIN, 20000);
break;
case EVENT_AKAMA_HEALTH:
if (me->HealthBelowPct(20))
me->CastSpell(me, SPELL_HEALING_POTION, false);
events.ScheduleEvent(EVENT_AKAMA_HEALTH, 1000);
break;
}
DoMeleeAttackIfReady();
}
private:
EventMap events;
SummonList summons;
InstanceScript* instance;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<npc_akama_illidanAI>(creature);
}
};
class spell_illidan_draw_soul : public SpellScriptLoader
{
public:
spell_illidan_draw_soul() : SpellScriptLoader("spell_illidan_draw_soul") { }
class spell_illidan_draw_soul_SpellScript : public SpellScript
{
PrepareSpellScript(spell_illidan_draw_soul_SpellScript);
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Unit* target = GetHitUnit())
target->CastSpell(GetCaster(), SPELL_DRAW_SOUL_HEAL, true);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_illidan_draw_soul_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_illidan_draw_soul_SpellScript();
}
};
class spell_illidan_parasitic_shadowfiend : public SpellScriptLoader
{
public:
spell_illidan_parasitic_shadowfiend() : SpellScriptLoader("spell_illidan_parasitic_shadowfiend") { }
class spell_illidan_parasitic_shadowfiend_AuraScript : public AuraScript
{
PrepareAuraScript(spell_illidan_parasitic_shadowfiend_AuraScript)
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (!GetTarget()->HasAura(SPELL_SHADOW_PRISON) && GetTarget()->GetInstanceScript() && GetTarget()->GetInstanceScript()->IsEncounterInProgress())
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_PARASITIC_SHADOWFIENDS, true);
}
void Register()
{
AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_parasitic_shadowfiend_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_illidan_parasitic_shadowfiend_AuraScript();
}
};
class spell_illidan_parasitic_shadowfiend_trigger : public SpellScriptLoader
{
public:
spell_illidan_parasitic_shadowfiend_trigger() : SpellScriptLoader("spell_illidan_parasitic_shadowfiend_trigger") { }
class spell_illidan_parasitic_shadowfiend_trigger_AuraScript : public AuraScript
{
PrepareAuraScript(spell_illidan_parasitic_shadowfiend_trigger_AuraScript)
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (!GetTarget()->HasAura(SPELL_SHADOW_PRISON) && GetTarget()->GetInstanceScript() && GetTarget()->GetInstanceScript()->IsEncounterInProgress())
GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_PARASITIC_SHADOWFIENDS, true);
}
void Register()
{
AfterEffectRemove += AuraEffectRemoveFn(spell_illidan_parasitic_shadowfiend_trigger_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_illidan_parasitic_shadowfiend_trigger_AuraScript();
}
class spell_illidan_parasitic_shadowfiend_trigger_SpellScript : public SpellScript
{
PrepareSpellScript(spell_illidan_parasitic_shadowfiend_trigger_SpellScript);
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Creature* target = GetHitCreature())
target->DespawnOrUnsummon(1);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_illidan_parasitic_shadowfiend_trigger_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_illidan_parasitic_shadowfiend_trigger_SpellScript();
}
};
class spell_illidan_glaive_throw : public SpellScriptLoader
{
public:
spell_illidan_glaive_throw() : SpellScriptLoader("spell_illidan_glaive_throw") { }
class spell_illidan_glaive_throw_SpellScript : public SpellScript
{
PrepareSpellScript(spell_illidan_glaive_throw_SpellScript);
void HandleDummy(SpellEffIndex effIndex)
{
PreventHitEffect(effIndex);
if (Unit* target = GetHitUnit())
target->CastSpell(target, SPELL_SUMMON_GLAIVE, true);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_illidan_glaive_throw_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_illidan_glaive_throw_SpellScript();
}
};
class spell_illidan_tear_of_azzinoth_summon_channel : public SpellScriptLoader
{
public:
spell_illidan_tear_of_azzinoth_summon_channel() : SpellScriptLoader("spell_illidan_tear_of_azzinoth_summon_channel") { }
class spell_illidan_tear_of_azzinoth_summon_channel_AuraScript : public AuraScript
{
PrepareAuraScript(spell_illidan_tear_of_azzinoth_summon_channel_AuraScript);
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
if (Unit* caster = GetCaster())
{
if (GetTarget()->GetDistance2d(caster) > 25.0f)
{
SetDuration(0);
GetTarget()->CastSpell(GetTarget(), SPELL_UNCAGED_WRATH, true);
}
}
// xinef: ugly hax, dunno how it really works on blizz
Map::PlayerList const& pl = GetTarget()->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator itr = pl.begin(); itr != pl.end(); ++itr)
if (Player* player = itr->GetSource())
if (player->GetPositionX() > 693.4f || player->GetPositionY() < 271.8f || player->GetPositionX() < 658.43f || player->GetPositionY() > 338.68f)
{
GetTarget()->CastSpell(player, SPELL_CHARGE, true);
break;
}
}
void Register()
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_tear_of_azzinoth_summon_channel_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_illidan_tear_of_azzinoth_summon_channel_AuraScript();
}
};
class spell_illidan_shadow_prison : public SpellScriptLoader
{
public:
spell_illidan_shadow_prison() : SpellScriptLoader("spell_illidan_shadow_prison") { }
class spell_illidan_shadow_prison_SpellScript : public SpellScript
{
PrepareSpellScript(spell_illidan_shadow_prison_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(PlayerOrPetCheck());
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_illidan_shadow_prison_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_illidan_shadow_prison_SpellScript();
}
};
class spell_illidan_demon_transform1 : public SpellScriptLoader
{
public:
spell_illidan_demon_transform1() : SpellScriptLoader("spell_illidan_demon_transform1") { }
class spell_illidan_demon_transform1_AuraScript : public AuraScript
{
PrepareAuraScript(spell_illidan_demon_transform1_AuraScript);
bool Load()
{
return GetUnitOwner()->GetTypeId() == TYPEID_UNIT;
}
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
SetDuration(0);
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_DEMON_TRANSFORM_2, true);
GetUnitOwner()->ToCreature()->LoadEquipment(0, true);
}
void Register()
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform1_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_illidan_demon_transform1_AuraScript();
}
};
class spell_illidan_demon_transform2 : public SpellScriptLoader
{
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 Load()
{
return GetUnitOwner()->GetTypeId() == TYPEID_UNIT;
}
void OnPeriodic(AuraEffect const* aurEff)
{
PreventDefaultAction();
if (aurEff->GetTickNumber() == 1)
{
if (GetUnitOwner()->GetDisplayId() == GetUnitOwner()->GetNativeDisplayId())
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_DEMON_FORM, true);
else
GetUnitOwner()->RemoveAurasDueToSpell(SPELL_DEMON_FORM);
}
else if (aurEff->GetTickNumber() == 2)
{
SetDuration(0);
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_DEMON_TRANSFORM_3, true);
if (Aura* aura = GetUnitOwner()->GetAura(SPELL_DEMON_TRANSFORM_3))
aura->SetDuration(4500);
if (!GetUnitOwner()->HasAura(SPELL_DEMON_FORM))
GetUnitOwner()->ToCreature()->LoadEquipment(1, true);
}
}
void Register()
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_demon_transform2_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_illidan_demon_transform2_AuraScript();
}
};
class spell_illidan_flame_burst : public SpellScriptLoader
{
public:
spell_illidan_flame_burst() : SpellScriptLoader("spell_illidan_flame_burst") { }
class spell_illidan_flame_burst_SpellScript : public SpellScript
{
PrepareSpellScript(spell_illidan_flame_burst_SpellScript);
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitEffect(effIndex);
if (Unit* target = GetHitUnit())
target->CastSpell(target, SPELL_FLAME_BURST_EFFECT, true);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_illidan_flame_burst_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_illidan_flame_burst_SpellScript();
}
};
class spell_illidan_found_target : public SpellScriptLoader
{
public:
spell_illidan_found_target() : SpellScriptLoader("spell_illidan_found_target") { }
class spell_illidan_found_target_SpellScript : public SpellScript
{
PrepareSpellScript(spell_illidan_found_target_SpellScript);
void HandleDummy(SpellEffIndex effIndex)
{
PreventHitEffect(effIndex);
if (Unit* target = GetHitUnit())
if (GetCaster()->GetDistance(target) < 2.0f)
{
GetCaster()->CastSpell(target, SPELL_CONSUME_SOUL, true);
GetCaster()->CastSpell(GetCaster(), SPELL_FIND_TARGET, true);
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_illidan_found_target_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_illidan_found_target_SpellScript();
}
};
class spell_illidan_cage_trap : public SpellScriptLoader
{
public:
spell_illidan_cage_trap() : SpellScriptLoader("spell_illidan_cage_trap") { }
class spell_illidan_cage_trap_SpellScript : public SpellScript
{
PrepareSpellScript(spell_illidan_cage_trap_SpellScript);
bool Load()
{
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitEffect(effIndex);
if (Creature* target = GetHitCreature())
if (GetCaster()->GetExactDist2d(target) < 4.0f)
{
target->AI()->DoAction(ACTION_ILLIDAN_CAGED);
target->CastSpell(target, SPELL_CAGE_TRAP, true);
GetCaster()->ToCreature()->DespawnOrUnsummon(1);
if (GameObject* gobject = GetCaster()->FindNearestGameObject(GO_CAGE_TRAP, 10.0f))
gobject->SetLootState(GO_JUST_DEACTIVATED);
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_illidan_cage_trap_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
SpellScript* GetSpellScript() const
{
return new spell_illidan_cage_trap_SpellScript();
}
};
class spell_illidan_cage_trap_stun : public SpellScriptLoader
{
public:
spell_illidan_cage_trap_stun() : SpellScriptLoader("spell_illidan_cage_trap_stun") { }
class spell_illidan_cage_trap_stun_AuraScript : public AuraScript
{
PrepareAuraScript(spell_illidan_cage_trap_stun_AuraScript);
void OnPeriodic(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
SetDuration(0);
for (uint32 i = SPELL_CAGED_SUMMON1; i <= SPELL_CAGED_SUMMON8; ++i)
GetTarget()->CastSpell(GetTarget(), i, true);
GetTarget()->CastSpell(GetTarget(), SPELL_CAGED_DEBUFF, true);
}
void Register()
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_illidan_cage_trap_stun_AuraScript::OnPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_illidan_cage_trap_stun_AuraScript();
}
};
void AddSC_boss_illidan()
{
new boss_illidan_stormrage();
new npc_akama_illidan();
new spell_illidan_draw_soul();
new spell_illidan_parasitic_shadowfiend();
new spell_illidan_parasitic_shadowfiend_trigger();
new spell_illidan_glaive_throw();
new spell_illidan_tear_of_azzinoth_summon_channel();
new spell_illidan_shadow_prison();
new spell_illidan_demon_transform1();
new spell_illidan_demon_transform2();
new spell_illidan_flame_burst();
new spell_illidan_found_target();
new spell_illidan_cage_trap();
new spell_illidan_cage_trap_stun();
}