/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see .
*/
#include "CreatureScript.h"
#include "CreatureTextMgr.h"
#include "MoveSplineInit.h"
#include "PassiveAI.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
#include "SpellScriptLoader.h"
#include "sunwell_plateau.h"
enum Yells
{
SAY_KJ_OFFCOMBAT = 0,
SAY_KALECGOS_ENCOURAGE = 0,
SAY_KALECGOS_READY1 = 1,
SAY_KALECGOS_READY2 = 2,
SAY_KALECGOS_READY_ALL = 3,
SAY_KALECGOS_AWAKEN = 5,
SAY_KALECGOS_LETGO = 6,
SAY_KALECGOS_FOCUS = 7,
SAY_KALECGOS_FATE = 8,
SAY_KALECGOS_GOODBYE = 9,
SAY_KALECGOS_JOIN = 10,
SAY_KJ_DEATH = 0,
SAY_KJ_SLAY = 1,
SAY_KJ_REFLECTION = 2,
SAY_KJ_EMERGE = 3,
SAY_KJ_DARKNESS = 4,
SAY_KJ_PHASE3 = 5,
SAY_KJ_PHASE4 = 6,
SAY_KJ_PHASE5 = 7,
EMOTE_KJ_DARKNESS = 8,
SAY_ANVEENA_IMPRISONED = 0,
SAY_ANVEENA_LOST = 1,
SAY_ANVEENA_KALEC = 2,
SAY_ANVEENA_GOODBYE = 3
};
enum Spells
{
// Kil'jaeden spells
SPELL_REBIRTH = 44200,
SPELL_SOUL_FLAY = 45442,
SPELL_LEGION_LIGHTNING = 45664,
SPELL_FIRE_BLOOM = 45641,
SPELL_SHADOW_SPIKE = 46680,
SPELL_SINISTER_REFLECTION = 45892,
SPELL_FLAME_DART = 45737,
SPELL_FLAME_DART_EXPLOSION = 45746,
SPELL_DARKNESS_OF_A_THOUSAND_SOULS = 46605,
SPELL_DARKNESS_OF_A_THOUSAND_SOULS_DAMAGE = 45657,
SPELL_ARMAGEDDON_PERIODIC = 45921,
SPELL_ARMAGEDDON_VISUAL = 45911,
SPELL_ARMAGEDDON_MISSILE = 45909,
SPELL_CUSTOM_08_STATE = 45800,
SPELL_DESTROY_ALL_DRAKES = 46707,
// Sinister Reflections
SPELL_SINISTER_REFLECTION_SUMMON = 45891,
SPELL_SINISTER_REFLECTION_CLASS = 45893,
SPELL_SINISTER_REFLECTION_CLONE = 45785,
// TODO
// These should be applied to target of SPELL_SINISTER_REFLECTION but not implemented
//SPELL_SINISTER_COPY_WEAPON = 41054,
//SPELL_SINISTER_COPY_OFFHAND_WEAPON = 45205,
// Misc
SPELL_ANVEENA_ENERGY_DRAIN = 46410,
SPELL_RING_OF_BLUE_FLAMES = 45825,
SPELL_SUMMON_BLUE_DRAKE = 45836,
SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT = 45839,
SPELL_POSSESS_DRAKE_IMMUNITY = 45838,
SPELL_SACRIFICE_OF_ANVEENA = 46474,
};
enum Misc
{
PHASE_DECEIVERS = 1,
PHASE_NORMAL = 2,
PHASE_DARKNESS = 3,
PHASE_ARMAGEDDON = 4,
PHASE_SACRIFICE = 5,
ACTION_START_POST_EVENT = 1,
ACTION_NO_KILL_TALK = 2
};
class CastArmageddon : public BasicEvent
{
public:
CastArmageddon(Creature* caster) : _caster(caster) { }
bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override
{
_caster->CastSpell(_caster, SPELL_ARMAGEDDON_MISSILE, true);
_caster->SetPosition(_caster->GetPositionX(), _caster->GetPositionY(), _caster->GetPositionZ() - 20.0f, 0.0f);
return true;
}
private:
Creature* _caster;
};
struct npc_kiljaeden_controller : public NullCreatureAI
{
npc_kiljaeden_controller(Creature* creature) : NullCreatureAI(creature), summons(me)
{
instance = creature->GetInstanceScript();
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void ResetOrbs()
{
for (uint8 i = DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_1; i < DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_4 + 1; ++i)
if (GameObject* orb = instance->GetGameObject(i))
orb->SetGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
}
void Reset() override
{
scheduler.CancelAll();
instance->SetBossState(DATA_KILJAEDEN, NOT_STARTED);
summons.DespawnAll();
ResetOrbs();
me->SummonCreature(NPC_HAND_OF_THE_DECEIVER, 1702.62f, 611.19f, 27.66f, 1.81f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
me->SummonCreature(NPC_HAND_OF_THE_DECEIVER, 1684.099f, 618.848f, 27.67f, 0.589f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
me->SummonCreature(NPC_HAND_OF_THE_DECEIVER, 1688.38f, 641.10f, 27.50f, 5.43f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
me->SummonCreature(NPC_ANVEENA, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 40.0f, 0.0f);
DoCastAOE(SPELL_DESTROY_ALL_DRAKES, true);
DoCastSelf(SPELL_ANVEENA_ENERGY_DRAIN, true);
scheduler.Schedule(1min, [this](TaskContext context) {
if (instance->GetBossState(DATA_KILJAEDEN) == NOT_STARTED)
Talk(SAY_KJ_OFFCOMBAT);
context.Repeat(90s, 3min);
});
}
void JustDied(Unit*) override
{
EntryCheckPredicate kilCheck(NPC_KILJAEDEN);
EntryCheckPredicate kalCheck(NPC_KALECGOS_KJ);
summons.DespawnIf(kilCheck);
summons.DoAction(ACTION_START_POST_EVENT, kalCheck);
summons.DespawnIf(kalCheck);
DoCastAOE(SPELL_DESTROY_ALL_DRAKES, true);
summons.DespawnAll();
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_SINISTER_REFLECTION)
{
summon->m_Events.AddEventAtOffset([summon] {
if (summon && summon->IsAlive() && !summon->IsInCombat())
summon->SetInCombatWithZone();
}, 5s);
}
else if (summon->GetEntry() == NPC_KALECGOS_KJ)
summon->setActive(true);
}
void SummonedCreatureDies(Creature* summon, Unit*) override
{
summons.Despawn(summon);
if (summon->GetEntry() == NPC_HAND_OF_THE_DECEIVER)
{
instance->SetBossState(DATA_KILJAEDEN, IN_PROGRESS);
scheduler.Schedule(1s, [this](TaskContext context) {
auto const& playerList = me->GetMap()->GetPlayers();
for (auto const& playerRef : playerList)
if (Player* player = playerRef.GetSource())
if (!player->IsGameMaster() && me->GetDistance2d(player) < 60.0f && player->IsAlive())
{
context.Repeat();
return;
}
CreatureAI::EnterEvadeMode();
});
if (!summons.HasEntry(NPC_HAND_OF_THE_DECEIVER))
{
me->RemoveAurasDueToSpell(SPELL_ANVEENA_ENERGY_DRAIN);
me->SummonCreature(NPC_KILJAEDEN, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 1.5f, 4.3f, TEMPSUMMON_MANUAL_DESPAWN);
me->SummonCreature(NPC_KALECGOS_KJ, 1726.80f, 661.43f, 138.65f, 3.95f, TEMPSUMMON_MANUAL_DESPAWN);
}
}
}
void UpdateAI(uint32 diff) override
{
scheduler.Update(diff);
}
private:
InstanceScript* instance;
SummonList summons;
};
struct boss_kiljaeden : public BossAI
{
boss_kiljaeden(Creature* creature) : BossAI(creature, DATA_KILJAEDEN)
{
me->SetReactState(REACT_PASSIVE);
scheduler.SetValidator([this]
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void InitializeAI() override
{
ScriptedAI::InitializeAI();
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetVisible(false);
me->m_Events.AddEventAtOffset([&] {
me->SetVisible(true);
DoCastSelf(SPELL_REBIRTH);
}, 1s);
me->m_Events.AddEventAtOffset([&] {
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetInCombatWithZone();
}, 11s);
}
void Reset() override
{
_phase = PHASE_NORMAL;
ScheduleHealthCheckEvent(85, [&]{
_phase = PHASE_DARKNESS;
if (Creature* kalec = instance->GetCreature(DATA_KALECGOS_KJ))
kalec->AI()->Talk(SAY_KALECGOS_AWAKEN, 21s);
if (Creature* anveena = instance->GetCreature(DATA_ANVEENA))
anveena->AI()->Talk(SAY_ANVEENA_IMPRISONED, 26s);
Talk(SAY_KJ_PHASE3, 32s);
scheduler.CancelAll();
ScheduleBasicAbilities();
me->m_Events.AddEventAtOffset([&] {
if (Creature* kalec = instance->GetCreature(DATA_KALECGOS_KJ))
kalec->AI()->Talk(SAY_KALECGOS_READY1);
EmpowerOrb(false);
}, 38s);
me->m_Events.AddEventAtOffset([&] {
Talk(SAY_KJ_REFLECTION);
me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE);
}, 1s);
scheduler.Schedule(1s+200ms, [this](TaskContext)
{
DoCastSelf(SPELL_SHADOW_SPIKE);
});
ScheduleTimedEvent(31s, [&] {
DoCastSelf(SPELL_FLAME_DART);
}, 20s);
ScheduleTimedEvent(55s, [&] {
Talk(EMOTE_KJ_DARKNESS);
DoCastAOE(SPELL_DARKNESS_OF_A_THOUSAND_SOULS);
}, 45s);
});
ScheduleHealthCheckEvent(55, [&] {
_phase = PHASE_ARMAGEDDON;
if (Creature* kalec = instance->GetCreature(DATA_KALECGOS_KJ))
kalec->AI()->Talk(SAY_KALECGOS_LETGO, 18s);
if (Creature* anveena = instance->GetCreature(DATA_ANVEENA))
anveena->AI()->Talk(SAY_ANVEENA_LOST, 25s);
Talk(SAY_KJ_PHASE4, 32s);
scheduler.CancelAll();
me->m_Events.AddEventAtOffset([&] {
if (Creature* kalec = instance->GetCreature(DATA_KALECGOS_KJ))
kalec->AI()->Talk(SAY_KALECGOS_READY2);
EmpowerOrb(false);
}, 38s);
scheduler.Schedule(1s, [this](TaskContext)
{
Talk(SAY_KJ_REFLECTION);
me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE);
});
scheduler.Schedule(1s + 200ms, [this](TaskContext)
{
DoCastSelf(SPELL_SHADOW_SPIKE);
ScheduleBasicAbilities();
});
ScheduleTimedEvent(28s, [&] {
DoCastSelf(SPELL_FLAME_DART);
}, 20s);
ScheduleTimedEvent(64s, [&] {
me->RemoveAurasDueToSpell(SPELL_ARMAGEDDON_PERIODIC);
Talk(EMOTE_KJ_DARKNESS);
DoCastAOE(SPELL_DARKNESS_OF_A_THOUSAND_SOULS);
me->m_Events.AddEventAtOffset([this]() {
if (me->IsAlive() && me->IsInCombat())
DoCastSelf(SPELL_ARMAGEDDON_PERIODIC, true);
}, 9s);
}, 45s);
ScheduleTimedEvent(10s, [&] {
DoCastSelf(SPELL_ARMAGEDDON_PERIODIC, true);
}, 40s);
});
ScheduleHealthCheckEvent(25, [&] {
_phase = PHASE_SACRIFICE;
scheduler.CancelAll();
scheduler.Schedule(1s, [this](TaskContext)
{
scheduler.Schedule(1s, [this](TaskContext)
{
Talk(SAY_KJ_REFLECTION);
me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE);
});
scheduler.Schedule(2s, [this](TaskContext)
{
DoCastSelf(SPELL_SHADOW_SPIKE);
});
if (Creature* kalec = instance->GetCreature(DATA_KALECGOS_KJ))
{
kalec->AI()->Talk(SAY_KALECGOS_FOCUS, 9s);
kalec->AI()->Talk(SAY_KALECGOS_FATE, 22s + 200ms);
}
if (Creature* anveena = instance->GetCreature(DATA_ANVEENA))
{
anveena->AI()->Talk(SAY_ANVEENA_KALEC, 20s);
anveena->AI()->Talk(SAY_ANVEENA_GOODBYE, 29s);
}
me->m_Events.AddEventAtOffset([&] {
if (Creature* anveena = instance->GetCreature(DATA_ANVEENA))
{
anveena->RemoveAllAuras();
anveena->CastSpell(anveena, SPELL_SACRIFICE_OF_ANVEENA, true);
anveena->DespawnOrUnsummon(1500ms);
DoCastSelf(SPELL_CUSTOM_08_STATE, true);
me->SetUnitFlag(UNIT_FLAG_PACIFIED);
scheduler.CancelAll();
me->m_Events.AddEventAtOffset([&] {
me->RemoveAurasDueToSpell(SPELL_CUSTOM_08_STATE);
me->RemoveUnitFlag(UNIT_FLAG_PACIFIED);
ScheduleBasicAbilities();
ScheduleTimedEvent(16s, [&] {
DoCastSelf(SPELL_FLAME_DART);
}, 20s);
ScheduleTimedEvent(15s, [&] {
me->RemoveAurasDueToSpell(SPELL_ARMAGEDDON_PERIODIC);
Talk(EMOTE_KJ_DARKNESS);
DoCastAOE(SPELL_DARKNESS_OF_A_THOUSAND_SOULS);
me->m_Events.AddEventAtOffset([this]() {
if (me->IsAlive() && me->IsInCombat())
DoCastSelf(SPELL_ARMAGEDDON_PERIODIC, true);
}, 9s);
}, 25s);
ScheduleTimedEvent(1500ms, [&] {
DoCastSelf(SPELL_ARMAGEDDON_PERIODIC, true);
}, 20s);
}, 7s);
}
Talk(SAY_KJ_PHASE5);
}, 36s);
me->m_Events.AddEventAtOffset([&] {
if (Creature* kalec = instance->GetCreature(DATA_KALECGOS_KJ))
kalec->AI()->Talk(SAY_KALECGOS_READY_ALL);
EmpowerOrb(true);
}, 48s);
});
});
}
void ScheduleBasicAbilities()
{
ScheduleTimedEvent(1s, [&] {
DoCastVictim(SPELL_SOUL_FLAY);
}, 4s, 5s);
ScheduleTimedEvent(7s, [&] {
DoCastRandomTarget(SPELL_LEGION_LIGHTNING, 0, 40.0f);
}, _phase == PHASE_SACRIFICE ? 15s : 30s);
ScheduleTimedEvent(9s, [&] {
me->CastCustomSpell(SPELL_FIRE_BLOOM, SPELLVALUE_MAX_TARGETS, 5, me, TRIGGERED_NONE);
me->SetTarget(me->GetVictim()->GetGUID());
}, _phase == PHASE_SACRIFICE ? 20s : 40s);
if (_phase != PHASE_SACRIFICE)
{
ScheduleTimedEvent(10s, [&] {
for (uint8 i = 1; i < _phase; ++i)
{
float x = me->GetPositionX() + 18.0f * cos((i * 2.0f - 1.0f) * M_PI / 3.0f);
float y = me->GetPositionY() + 18.0f * std::sin((i * 2.0f - 1.0f) * M_PI / 3.0f);
if (Creature* orb = me->SummonCreature(NPC_SHIELD_ORB, x, y, 40.0f, 0, TEMPSUMMON_CORPSE_DESPAWN))
{
Movement::PointsArray movementArray;
movementArray.push_back(G3D::Vector3(x, y, 40.0f));
// generate movement array
for (uint8 j = 1; j < 20; ++j)
{
x = me->GetPositionX() + 18.0f * cos(((i * 2.0f - 1.0f) * M_PI / 3.0f) + (j / 20.0f * 2 * M_PI));
y = me->GetPositionY() + 18.0f * std::sin(((i * 2.0f - 1.0f) * M_PI / 3.0f) + (j / 20.0f * 2 * M_PI));
movementArray.push_back(G3D::Vector3(x, y, 40.0f));
}
Movement::MoveSplineInit init(orb);
init.MovebyPath(movementArray);
init.SetCyclic();
init.Launch();
}
}
}, 40s);
}
}
void EnterEvadeMode(EvadeReason why) override
{
if (me->GetReactState() == REACT_PASSIVE)
return;
ScriptedAI::EnterEvadeMode(why);
if (InstanceScript* instance = me->GetInstanceScript())
if (Creature* controller = instance->GetCreature(DATA_KJ_CONTROLLER))
if (controller->IsAIEnabled)
controller->AI()->Reset();
}
void AttackStart(Unit* who) override
{
if (me->GetReactState() == REACT_PASSIVE)
return;
ScriptedAI::AttackStart(who);
}
void DamageTaken(Unit* unit, uint32& damage, DamageEffectType damageType, SpellSchoolMask schoolMask) override
{
BossAI::DamageTaken(unit, damage, damageType, schoolMask);
if (damage >= me->GetHealth())
{
me->SetTarget();
me->SetReactState(REACT_PASSIVE);
me->RemoveAllAuras();
me->GetThreatMgr().ClearAllThreat();
me->SetRegeneratingHealth(false);
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
me->HandleEmoteCommand(EMOTE_ONESHOT_DROWN);
me->resetAttackTimer();
events.Reset();
damage = 0;
me->m_Events.AddEventAtOffset([&] {
me->KillSelf();
}, 1s);
}
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_KJ_DEATH);
instance->SetBossState(DATA_KILJAEDEN, DONE);
if (Creature* controller = instance->GetCreature(DATA_KJ_CONTROLLER))
controller->KillSelf();
}
void DoAction(int32 param) override
{
if (param == ACTION_NO_KILL_TALK)
Talk(SAY_KJ_DARKNESS);
}
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer())
Talk(SAY_KJ_SLAY);
}
void JustEngagedWith(Unit* /*who*/) override
{
if (Creature* kalec = instance->GetCreature(DATA_KALECGOS_KJ))
kalec->AI()->Talk(SAY_KALECGOS_JOIN, 26s);
Talk(SAY_KJ_EMERGE);
ScheduleBasicAbilities();
}
void JustSummoned(Creature* summon) override
{
BossAI::JustSummoned(summon);
if (summon->GetEntry() == NPC_ARMAGEDDON_TARGET)
{
summon->SetCanFly(true);
summon->SetDisableGravity(true);
summon->CastSpell(summon, SPELL_ARMAGEDDON_VISUAL, true);
summon->SetPosition(summon->GetPositionX(), summon->GetPositionY(), summon->GetPositionZ() + 20.0f, 0.0f);
summon->m_Events.AddEventAtOffset(new CastArmageddon(summon), 6s);
summon->DespawnOrUnsummon(randtime(8s, 10s));
}
}
void UpdateAI(uint32 diff) override
{
if (me->GetReactState() != REACT_AGGRESSIVE)
return;
if (!UpdateVictim())
return;
scheduler.Update(diff,
std::bind(&BossAI::DoMeleeAttackIfReady, this));
}
void EmpowerOrb(bool empowerAll)
{
for (uint8 i = DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_1; i < DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_4 + 1; ++i)
{
if (GameObject* orb = instance->GetGameObject(i))
{
if (orb->HasGameObjectFlag(GO_FLAG_NOT_SELECTABLE))
{
orb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
if (Creature* trigger = me->SummonTrigger(orb->GetPositionX(), orb->GetPositionY(), orb->GetPositionZ(), 0, 10 * MINUTE * IN_MILLISECONDS))
{
trigger->CastSpell(trigger, SPELL_RING_OF_BLUE_FLAMES, true, nullptr, nullptr, trigger->GetGUID());
if (Creature* controller = instance->GetCreature(DATA_KJ_CONTROLLER))
controller->AI()->JustSummoned(trigger);
}
if (!empowerAll)
break;
}
}
}
}
private:
uint8 _phase;
};
enum postEvent
{
SAY_VELEN_01 = 0,
SAY_VELEN_02 = 1,
SAY_VELEN_03 = 2,
SAY_VELEN_04 = 3,
SAY_VELEN_05 = 4,
SAY_VELEN_06 = 5,
SAY_VELEN_07 = 6,
SAY_VELEN_08 = 7,
SAY_VELEN_09 = 8,
SAY_LIADRIN_01 = 0,
SAY_LIADRIN_02 = 1,
SAY_LIADRIN_03 = 2,
NPC_SHATTERED_SUN_RIFTWAKER = 26289,
NPC_SHATTRATH_PORTAL_DUMMY = 26251,
NPC_INERT_PORTAL = 26254,
NPC_SHATTERED_SUN_SOLDIER = 26259,
NPC_LADY_LIADRIN = 26247,
NPC_PROPHET_VELEN = 26246,
NPC_THE_CORE_OF_ENTROPIUS = 26262,
SPELL_TELEPORT_AND_TRANSFORM = 46473,
SPELL_OPEN_PORTAL_FROM_SHATTRATH = 46801,
SPELL_TELEPORT_VISUAL = 35517,
SPELL_BOSS_ARCANE_PORTAL_STATE = 42047,
SPELL_CALL_ENTROPIUS = 46818,
SPELL_BLAZE_TO_LIGHT = 46821,
SPELL_SUNWELL_IGNITION = 46822,
EVENT_SCENE_01 = 1,
EVENT_SCENE_02,
EVENT_SCENE_03,
EVENT_SCENE_04,
EVENT_SCENE_05,
EVENT_SCENE_06,
EVENT_SCENE_07,
EVENT_SCENE_08,
EVENT_SCENE_09,
EVENT_SCENE_10,
EVENT_SCENE_11,
EVENT_SCENE_12,
EVENT_SCENE_13,
EVENT_SCENE_14,
EVENT_SCENE_15,
EVENT_SCENE_16,
EVENT_SCENE_17,
EVENT_SCENE_18,
EVENT_SCENE_19,
EVENT_SCENE_20,
EVENT_SCENE_21,
EVENT_SCENE_22,
EVENT_SCENE_23,
EVENT_SCENE_24,
EVENT_SCENE_25,
EVENT_SCENE_26,
EVENT_SCENE_27
};
class MoveDelayed : public BasicEvent
{
public:
MoveDelayed(Creature* owner, float x, float y, float z, float o) : _owner(owner), _x(x), _y(y), _z(z), _o(o) { }
bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override
{
Movement::MoveSplineInit init(_owner);
init.MoveTo(_x, _y, _z, false, true);
init.SetFacing(_o);
init.Launch();
return true;
}
private:
Creature* _owner;
float _x, _y, _z, _o;
};
class FixOrientation : public BasicEvent
{
public:
FixOrientation(Creature* owner) : _owner(owner) { }
bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override
{
std::list cList;
_owner->GetCreaturesWithEntryInRange(cList, 20.0f, NPC_SHATTERED_SUN_SOLDIER);
for (std::list::const_iterator itr = cList.begin(); itr != cList.end(); ++itr)
(*itr)->SetFacingTo(_owner->GetOrientation());
return true;
}
private:
Creature* _owner;
};
struct npc_kalecgos_kj : public NullCreatureAI
{
npc_kalecgos_kj(Creature* creature) : NullCreatureAI(creature), summons(me)
{
instance = creature->GetInstanceScript();
}
EventMap events;
InstanceScript* instance;
SummonList summons;
void Reset() override
{
events.Reset();
summons.DespawnAll();
}
void DoAction(int32 param) override
{
if (param == ACTION_START_POST_EVENT)
{
me->SetCanFly(false);
me->SetDisableGravity(false);
me->CastSpell(me, SPELL_TELEPORT_AND_TRANSFORM, true);
events.ScheduleEvent(EVENT_SCENE_01, 35s);
}
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (summon->GetEntry() == NPC_SHATTERED_SUN_RIFTWAKER)
{
summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true);
if (summons.size() == 1)
summon->GetMotionMaster()->MovePoint(0, 1727.08f, 656.82f, 28.37f, FORCED_MOVEMENT_NONE, 0.f, 5.14f, false, true);
else
summon->GetMotionMaster()->MovePoint(0, 1738.84f, 627.32f, 28.26f, FORCED_MOVEMENT_NONE, 0.f, 2.0f, false, true);
}
else if (summon->GetEntry() == NPC_SHATTRATH_PORTAL_DUMMY)
{
if (Creature* riftwaker = summon->FindNearestCreature(NPC_SHATTERED_SUN_RIFTWAKER, 10.0f))
riftwaker->CastSpell(summon, SPELL_OPEN_PORTAL_FROM_SHATTRATH, false);
summon->SetWalk(true);
summon->GetMotionMaster()->MovePoint(0, summon->GetPositionX(), summon->GetPositionY(), summon->GetPositionZ() + 30.0f, FORCED_MOVEMENT_NONE, 0.f, 0.f, false, true);
}
else if (summon->GetEntry() == NPC_INERT_PORTAL)
summon->CastSpell(summon, SPELL_BOSS_ARCANE_PORTAL_STATE, true);
else if (summon->GetEntry() == NPC_SHATTERED_SUN_SOLDIER)
summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true);
else if (summon->GetEntry() == NPC_LADY_LIADRIN)
{
summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true);
summon->SetWalk(true);
}
else if (summon->GetEntry() == NPC_PROPHET_VELEN)
{
summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true);
summon->SetWalk(true);
summon->GetMotionMaster()->MovePoint(0, 1710.15f, 639.23f, 27.311f, FORCED_MOVEMENT_NONE, 0.f, 0.f, false, true);
}
else if (summon->GetEntry() == NPC_THE_CORE_OF_ENTROPIUS)
summon->GetMotionMaster()->MovePoint(0, summon->GetPositionX(), summon->GetPositionY(), 30.0f);
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
switch (uint32 eventId = events.ExecuteEvent())
{
case EVENT_SCENE_01:
Talk(SAY_KALECGOS_GOODBYE);
events.ScheduleEvent(eventId + 1, 15s);
break;
case EVENT_SCENE_02:
me->SummonCreature(NPC_SHATTERED_SUN_RIFTWAKER, 1688.42f, 641.82f, 27.60f, 0.67f);
me->SummonCreature(NPC_SHATTERED_SUN_RIFTWAKER, 1712.58f, 616.29f, 27.78f, 0.76f);
events.ScheduleEvent(eventId + 1, 6s);
break;
case EVENT_SCENE_03:
me->SummonCreature(NPC_SHATTRATH_PORTAL_DUMMY, 1727.08f + cos(5.14f), 656.82f + std::sin(5.14f), 28.37f + 2.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000);
me->SummonCreature(NPC_SHATTRATH_PORTAL_DUMMY, 1738.84f + cos(2.0f), 627.32f + std::sin(2.0f), 28.26f + 2.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000);
events.ScheduleEvent(eventId + 1, 11s);
break;
case EVENT_SCENE_04:
me->SummonCreature(NPC_INERT_PORTAL, 1734.96f, 642.43f, 28.06f, 3.49f);
events.ScheduleEvent(eventId + 1, 4s);
break;
case EVENT_SCENE_05:
if (Creature* first = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f, 640.49f, 28.06f, 3.49f))
{
first->m_Events.AddEventAtOffset(new MoveDelayed(first, 1718.70f, 607.78f, 28.06f, 2.323f), 5s);
first->m_Events.AddEventAtOffset(new FixOrientation(first), 12s);
for (uint8 i = 0; i < 9; ++i)
if (Creature* follower = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f + 5 * cos(i * 2.0f * M_PI / 9), 640.49f + 5 * std::sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f))
follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first));
}
events.ScheduleEvent(eventId + 1, 10s);
break;
case EVENT_SCENE_06:
if (Creature* first = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f, 640.49f, 28.06f, 3.49f))
{
first->m_Events.AddEventAtOffset(new MoveDelayed(first, 1678.69f, 649.27f, 28.06f, 5.46f), 5s);
first->m_Events.AddEventAtOffset(new FixOrientation(first), 14500ms);
for (uint8 i = 0; i < 9; ++i)
if (Creature* follower = me->SummonCreature(NPC_SHATTERED_SUN_SOLDIER, 1729.48f + 5 * cos(i * 2.0f * M_PI / 9), 640.49f + 5 * std::sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f))
follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first));
}
events.ScheduleEvent(eventId + 1, 12s);
break;
case EVENT_SCENE_07:
me->SummonCreature(NPC_LADY_LIADRIN, 1719.87f, 644.265f, 28.06f, 3.83f);
me->SummonCreature(NPC_PROPHET_VELEN, 1717.97f, 646.44f, 28.06f, 3.94f);
events.ScheduleEvent(eventId + 1, 7s);
break;
case EVENT_SCENE_08:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
velen->AI()->Talk(SAY_VELEN_01);
events.ScheduleEvent(eventId + 1, 25s);
break;
case EVENT_SCENE_09:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
velen->AI()->Talk(SAY_VELEN_02);
events.ScheduleEvent(eventId + 1, 14500ms);
break;
case EVENT_SCENE_10:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
velen->AI()->Talk(SAY_VELEN_03);
events.ScheduleEvent(eventId + 1, 12500ms);
break;
case EVENT_SCENE_11:
me->SummonCreature(NPC_THE_CORE_OF_ENTROPIUS, 1698.86f, 628.73f, 92.83f, 0.0f);
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
velen->CastSpell(velen, SPELL_CALL_ENTROPIUS, false);
events.ScheduleEvent(eventId + 1, 8s);
break;
case EVENT_SCENE_12:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
{
velen->InterruptNonMeleeSpells(false);
velen->AI()->Talk(SAY_VELEN_04);
}
events.ScheduleEvent(eventId + 1, 20s);
break;
case EVENT_SCENE_13:
if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN))
liadrin->GetMotionMaster()->MovePoint(0, 1711.28f, 637.29f, 27.29f);
events.ScheduleEvent(eventId + 1, 6s);
break;
case EVENT_SCENE_14:
if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN))
liadrin->AI()->Talk(SAY_LIADRIN_01);
events.ScheduleEvent(eventId + 1, 10s);
break;
case EVENT_SCENE_15:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
velen->AI()->Talk(SAY_VELEN_05);
events.ScheduleEvent(eventId + 1, 14s);
break;
case EVENT_SCENE_16:
if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN))
liadrin->AI()->Talk(SAY_LIADRIN_02);
events.ScheduleEvent(eventId + 1, 2s);
break;
case EVENT_SCENE_17:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
velen->AI()->Talk(SAY_VELEN_06);
events.ScheduleEvent(eventId + 1, 3s);
break;
case EVENT_SCENE_18:
if (Creature* core = summons.GetCreatureWithEntry(NPC_THE_CORE_OF_ENTROPIUS))
{
core->RemoveAllAuras();
core->CastSpell(core, SPELL_BLAZE_TO_LIGHT, true);
}
events.ScheduleEvent(eventId + 1, 8s);
break;
case EVENT_SCENE_19:
if (Creature* core = summons.GetCreatureWithEntry(NPC_THE_CORE_OF_ENTROPIUS))
{
core->SetObjectScale(0.75f);
core->GetMotionMaster()->MovePoint(0, core->GetPositionX(), core->GetPositionY(), 28.0f);
}
events.ScheduleEvent(eventId + 1, 2s);
break;
case EVENT_SCENE_20:
if (Creature* core = summons.GetCreatureWithEntry(NPC_THE_CORE_OF_ENTROPIUS))
core->CastSpell(core, SPELL_SUNWELL_IGNITION, true);
events.ScheduleEvent(eventId + 1, 3s);
break;
case EVENT_SCENE_21:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
velen->AI()->Talk(SAY_VELEN_07);
events.ScheduleEvent(eventId + 1, 15s);
break;
case EVENT_SCENE_22:
if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN))
liadrin->AI()->Talk(SAY_LIADRIN_03);
events.ScheduleEvent(eventId + 1, 20s);
break;
case EVENT_SCENE_23:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
velen->AI()->Talk(SAY_VELEN_08);
if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN))
liadrin->SetStandState(UNIT_STAND_STATE_KNEEL);
events.ScheduleEvent(eventId + 1, 8s);
break;
case EVENT_SCENE_24:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
velen->AI()->Talk(SAY_VELEN_09);
events.ScheduleEvent(eventId + 1, 5s);
break;
case EVENT_SCENE_25:
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
{
velen->GetMotionMaster()->MovePoint(0, 1739.38f, 643.79f, 28.06f);
velen->DespawnOrUnsummon(5s);
}
events.ScheduleEvent(eventId + 1, 3s);
break;
case EVENT_SCENE_26:
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
if (summon->GetEntry() == NPC_SHATTERED_SUN_SOLDIER)
{
summon->GetMotionMaster()->MovePoint(0, 1739.38f, 643.79f, 28.06f);
summon->DespawnOrUnsummon(Milliseconds(uint32(summon->GetExactDist2d(1734.96f, 642.43f) * 100)));
}
events.ScheduleEvent(eventId + 1, 7s);
break;
case EVENT_SCENE_27:
me->setActive(false);
summons.DespawnEntry(NPC_INERT_PORTAL);
summons.DespawnEntry(NPC_SHATTERED_SUN_RIFTWAKER);
break;
}
}
};
class spell_kiljaeden_shadow_spike_aura : public AuraScript
{
PrepareAuraScript(spell_kiljaeden_shadow_spike_aura);
void HandlePeriodic(AuraEffect const* aurEff)
{
PreventDefaultAction();
if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SelectTargetMethod::Random, 0, 60.0f, true))
GetUnitOwner()->CastSpell(target, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kiljaeden_shadow_spike_aura::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
class spell_kiljaeden_sinister_reflection : public SpellScript
{
PrepareSpellScript(spell_kiljaeden_sinister_reflection);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SINISTER_REFLECTION_SUMMON, SPELL_SINISTER_REFLECTION_CLONE });
}
void FilterTargets(std::list& targets)
{
targets.remove_if(Acore::UnitAuraCheck(true, SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT));
}
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Unit* target = GetHitUnit())
{
for (uint8 i = 0; i < 4; ++i)
{
target->CastSpell(target, SPELL_SINISTER_REFLECTION_SUMMON, true);
}
// TODO implement these auras
//target->AddAura(SPELL_SINISTER_COPY_WEAPON, target);
//target->AddAura(SPELL_SINISTER_COPY_OFFHAND_WEAPON, target);
target->CastSpell(target, SPELL_SINISTER_REFLECTION_CLONE, true);
}
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kiljaeden_sinister_reflection::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_kiljaeden_sinister_reflection::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_kiljaeden_sinister_reflection_clone : public SpellScript
{
PrepareSpellScript(spell_kiljaeden_sinister_reflection_clone);
void FilterTargets(std::list& targets)
{
if (targets.empty())
return;
targets.sort(Acore::ObjectDistanceOrderPred(GetCaster()));
WorldObject* target = targets.front();
targets.clear();
if (target && target->IsCreature())
{
target->ToCreature()->AI()->SetData(1, GetCaster()->getClass());
targets.push_back(target);
}
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kiljaeden_sinister_reflection_clone::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
class spell_kiljaeden_flame_dart : public SpellScript
{
PrepareSpellScript(spell_kiljaeden_flame_dart);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_FLAME_DART_EXPLOSION });
}
void HandleSchoolDamage(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
target->CastSpell(target, SPELL_FLAME_DART_EXPLOSION, true);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_kiljaeden_flame_dart::HandleSchoolDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
class spell_kiljaeden_darkness_aura : public AuraScript
{
PrepareAuraScript(spell_kiljaeden_darkness_aura);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_DARKNESS_OF_A_THOUSAND_SOULS_DAMAGE });
}
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
return;
if (GetUnitOwner()->IsCreature())
GetUnitOwner()->ToCreature()->AI()->DoAction(ACTION_NO_KILL_TALK);
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_DARKNESS_OF_A_THOUSAND_SOULS_DAMAGE, true);
}
void Register() override
{
OnEffectRemove += AuraEffectRemoveFn(spell_kiljaeden_darkness_aura::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_kiljaeden_power_of_the_blue_flight : public SpellScript
{
PrepareSpellScript(spell_kiljaeden_power_of_the_blue_flight);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SUMMON_BLUE_DRAKE, SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT });
}
void HandleScriptEffect(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Player* player = GetHitPlayer())
{
player->CastSpell(player, SPELL_SUMMON_BLUE_DRAKE, true);
player->CastSpell(player, SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT, true);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_kiljaeden_power_of_the_blue_flight::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class spell_kiljaeden_vengeance_of_the_blue_flight_aura : public AuraScript
{
PrepareAuraScript(spell_kiljaeden_vengeance_of_the_blue_flight_aura);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_POSSESS_DRAKE_IMMUNITY });
}
void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_POSSESS_DRAKE_IMMUNITY, true);
}
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
GetUnitOwner()->RemoveAurasDueToSpell(SPELL_POSSESS_DRAKE_IMMUNITY);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_kiljaeden_vengeance_of_the_blue_flight_aura::HandleApply, EFFECT_0, SPELL_AURA_MOD_POSSESS, AURA_EFFECT_HANDLE_REAL);
OnEffectApply += AuraEffectApplyFn(spell_kiljaeden_vengeance_of_the_blue_flight_aura::HandleApply, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_kiljaeden_vengeance_of_the_blue_flight_aura::HandleRemove, EFFECT_0, SPELL_AURA_MOD_POSSESS, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_kiljaeden_vengeance_of_the_blue_flight_aura::HandleRemove, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_kiljaeden_armageddon_periodic_aura : public AuraScript
{
PrepareAuraScript(spell_kiljaeden_armageddon_periodic_aura);
void HandlePeriodic(AuraEffect const* aurEff)
{
PreventDefaultAction();
Unit* caster = GetUnitOwner();
std::list armageddons;
caster->GetCreatureListWithEntryInGrid(armageddons, NPC_ARMAGEDDON_TARGET, 100.0f);
if (armageddons.size() >= 3)
return;
if (Unit* target = caster->GetAI()->SelectTarget(SelectTargetMethod::Random, 0, 60.0f, true))
caster->CastSpell(target, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kiljaeden_armageddon_periodic_aura::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
class spell_kiljaeden_armageddon_missile : public SpellScript
{
PrepareSpellScript(spell_kiljaeden_armageddon_missile);
void SetDest(SpellDestination& dest)
{
Position const offset = { 0.0f, 0.0f, -20.0f, 0.0f };
dest.RelocateOffset(offset);
}
void Register() override
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_kiljaeden_armageddon_missile::SetDest, EFFECT_0, TARGET_DEST_CASTER);
}
};
// 45856 - Breath: Haste
// 45860 - Breath: Revitalize
class spell_kiljaeden_dragon_breath : public SpellScript
{
PrepareSpellScript(spell_kiljaeden_dragon_breath);
void FilterTargets(std::list& targets)
{
targets.remove_if(Acore::UnitAuraCheck(true, SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT));
}
void HandleHit(SpellEffIndex /*effindex*/)
{
if (Unit* target = GetHitUnit())
target->RemoveMovementImpairingAuras(false);
}
void Register() override
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kiljaeden_dragon_breath::FilterTargets, EFFECT_ALL, TARGET_UNIT_CONE_ALLY);
OnEffectHitTarget += SpellEffectFn(spell_kiljaeden_dragon_breath::HandleHit, EFFECT_ALL, SPELL_EFFECT_ANY);
}
};
// 45848 - Shield of the Blue
class spell_kiljaeden_shield_of_the_blue : public AuraScript
{
PrepareAuraScript(spell_kiljaeden_shield_of_the_blue);
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* target = GetTarget())
{
target->RemoveAurasDueToSpell(SPELL_FIRE_BLOOM);
target->RemoveMovementImpairingAuras(false);
}
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_kiljaeden_shield_of_the_blue::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
}
};
void AddSC_boss_kiljaeden()
{
RegisterSunwellPlateauCreatureAI(npc_kiljaeden_controller);
RegisterSunwellPlateauCreatureAI(boss_kiljaeden);
RegisterSunwellPlateauCreatureAI(npc_kalecgos_kj);
RegisterSpellScript(spell_kiljaeden_shadow_spike_aura);
RegisterSpellScript(spell_kiljaeden_sinister_reflection);
RegisterSpellScript(spell_kiljaeden_sinister_reflection_clone);
RegisterSpellScript(spell_kiljaeden_flame_dart);
RegisterSpellScript(spell_kiljaeden_darkness_aura);
RegisterSpellScript(spell_kiljaeden_power_of_the_blue_flight);
RegisterSpellScript(spell_kiljaeden_vengeance_of_the_blue_flight_aura);
RegisterSpellScript(spell_kiljaeden_armageddon_periodic_aura);
RegisterSpellScript(spell_kiljaeden_armageddon_missile);
RegisterSpellScript(spell_kiljaeden_dragon_breath);
RegisterSpellScript(spell_kiljaeden_shield_of_the_blue);
}