1332 lines
56 KiB
C++
1332 lines
56 KiB
C++
/*
|
|
* Originally written by Xinef - Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
|
|
*/
|
|
|
|
#include "CreatureTextMgr.h"
|
|
#include "MoveSplineInit.h"
|
|
#include "ScriptedCreature.h"
|
|
#include "ScriptMgr.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,
|
|
|
|
// 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,
|
|
|
|
EVENT_GROUP_SPEACH = 1,
|
|
ACTION_START_POST_EVENT = 1,
|
|
ACTION_NO_KILL_TALK = 2,
|
|
|
|
// Text events
|
|
EVENT_TEXT_SPEACH11 = 1,
|
|
EVENT_TEXT_SPEACH21 = 2,
|
|
EVENT_TEXT_SPEACH22 = 3,
|
|
EVENT_TEXT_SPEACH23 = 4,
|
|
EVENT_TEXT_SPEACH31 = 5,
|
|
EVENT_TEXT_SPEACH32 = 6,
|
|
EVENT_TEXT_SPEACH33 = 7,
|
|
EVENT_TEXT_SPEACH41 = 8,
|
|
EVENT_TEXT_SPEACH42 = 9,
|
|
EVENT_TEXT_SPEACH43 = 10,
|
|
EVENT_TEXT_SPEACH44 = 11,
|
|
EVENT_TEXT_SPEACH45 = 12,
|
|
EVENT_TEXT_SPEACH46 = 13,
|
|
|
|
// Controller events
|
|
EVENT_RANDOM_TALK = 40,
|
|
EVENT_CHECK_PLAYERS = 41,
|
|
|
|
// Misc fight events
|
|
EVENT_REBIRTH = 50,
|
|
EVENT_INIT_FIGHT = 51,
|
|
EVENT_CHECK_HEALTH85 = 52,
|
|
EVENT_CHECK_HEALTH55 = 53,
|
|
EVENT_CHECK_HEALTH25 = 54,
|
|
EVENT_EMPOWER_ORBS1 = 55,
|
|
EVENT_EMPOWER_ORBS2 = 56,
|
|
EVENT_EMPOWER_ORBS3 = 57,
|
|
EVENT_RESTORE_MELEE = 58,
|
|
EVENT_KILL_SELF = 59,
|
|
EVENT_NO_KILL_TALK = 60,
|
|
|
|
// Abilities events
|
|
EVENT_SPELL_SOUL_FLAY = 100,
|
|
EVENT_SPELL_LEGION_LIGHTNING = 101,
|
|
EVENT_SPELL_FIRE_BLOOM = 102,
|
|
EVENT_SUMMON_ORBS = 103,
|
|
EVENT_SPELL_SHADOW_SPIKE = 104,
|
|
EVENT_SPELL_SINISTER_REFLECTION = 105,
|
|
EVENT_SPELL_FLAME_DART = 106,
|
|
EVENT_SPELL_DARKNESS = 107,
|
|
EVENT_SPELL_ARMAGEDDON = 108,
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
class npc_kiljaeden_controller : public CreatureScript
|
|
{
|
|
public:
|
|
npc_kiljaeden_controller() : CreatureScript("npc_kiljaeden_controller") { }
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return GetSunwellPlateauAI<npc_kiljaeden_controllerAI>(creature);
|
|
}
|
|
|
|
struct npc_kiljaeden_controllerAI : public NullCreatureAI
|
|
{
|
|
npc_kiljaeden_controllerAI(Creature* creature) : NullCreatureAI(creature), summons(me)
|
|
{
|
|
instance = creature->GetInstanceScript();
|
|
}
|
|
|
|
EventMap events;
|
|
InstanceScript* instance;
|
|
SummonList summons;
|
|
|
|
void ResetOrbs()
|
|
{
|
|
for (uint8 i = 0; i < 4; ++i)
|
|
if (GameObject* orb = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_1 + i)))
|
|
orb->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
|
}
|
|
|
|
void Reset() override
|
|
{
|
|
instance->SetBossState(DATA_KILJAEDEN, NOT_STARTED);
|
|
events.Reset();
|
|
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);
|
|
|
|
me->CastSpell(me, SPELL_DESTROY_ALL_DRAKES, true);
|
|
me->CastSpell(me, SPELL_ANVEENA_ENERGY_DRAIN, true);
|
|
events.ScheduleEvent(EVENT_RANDOM_TALK, 60000);
|
|
}
|
|
|
|
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);
|
|
|
|
me->CastSpell(me, SPELL_DESTROY_ALL_DRAKES, true);
|
|
summons.DespawnAll();
|
|
}
|
|
|
|
void JustSummoned(Creature* summon) override
|
|
{
|
|
summons.Summon(summon);
|
|
if (summon->GetEntry() == NPC_SINISTER_REFLECTION)
|
|
summon->SetInCombatWithZone();
|
|
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);
|
|
events.ScheduleEvent(EVENT_CHECK_PLAYERS, 1000);
|
|
|
|
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
|
|
{
|
|
events.Update(diff);
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_RANDOM_TALK:
|
|
if (instance->GetBossState(DATA_KILJAEDEN) == NOT_STARTED)
|
|
Talk(SAY_KJ_OFFCOMBAT);
|
|
events.ScheduleEvent(EVENT_RANDOM_TALK, urand(90000, 180000));
|
|
break;
|
|
case EVENT_CHECK_PLAYERS:
|
|
{
|
|
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
|
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
|
if (Player* player = itr->GetSource())
|
|
if (!player->IsGameMaster() && me->GetDistance2d(player) < 60.0f && player->IsAlive())
|
|
{
|
|
events.ScheduleEvent(EVENT_CHECK_PLAYERS, 1000);
|
|
return;
|
|
}
|
|
|
|
CreatureAI::EnterEvadeMode();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
class boss_kiljaeden : public CreatureScript
|
|
{
|
|
public:
|
|
boss_kiljaeden() : CreatureScript("boss_kiljaeden") { }
|
|
|
|
struct boss_kiljaedenAI : public ScriptedAI
|
|
{
|
|
boss_kiljaedenAI(Creature* creature) : ScriptedAI(creature)
|
|
{
|
|
instance = creature->GetInstanceScript();
|
|
me->SetReactState(REACT_PASSIVE);
|
|
}
|
|
|
|
InstanceScript* instance;
|
|
EventMap events;
|
|
EventMap events2;
|
|
uint8 phase;
|
|
|
|
void InitializeAI() override
|
|
{
|
|
ScriptedAI::InitializeAI();
|
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
|
|
|
phase = PHASE_NORMAL;
|
|
events.Reset();
|
|
events2.Reset();
|
|
events2.ScheduleEvent(EVENT_INIT_FIGHT, 11000);
|
|
events2.ScheduleEvent(EVENT_REBIRTH, 0);
|
|
me->SetVisible(false);
|
|
}
|
|
|
|
void Reset() override
|
|
{
|
|
events.Reset();
|
|
}
|
|
|
|
void EnterEvadeMode() override
|
|
{
|
|
if (me->GetReactState() == REACT_PASSIVE)
|
|
return;
|
|
ScriptedAI::EnterEvadeMode();
|
|
}
|
|
|
|
void AttackStart(Unit* who) override
|
|
{
|
|
if (me->GetReactState() == REACT_PASSIVE)
|
|
return;
|
|
ScriptedAI::AttackStart(who);
|
|
}
|
|
|
|
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
|
{
|
|
if (damage >= me->GetHealth())
|
|
{
|
|
me->SetTarget();
|
|
me->SetReactState(REACT_PASSIVE);
|
|
me->RemoveAllAuras();
|
|
me->DeleteThreatList();
|
|
me->SetRegeneratingHealth(false);
|
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
|
me->HandleEmoteCommand(EMOTE_ONESHOT_DROWN);
|
|
me->resetAttackTimer();
|
|
events.Reset();
|
|
events2.Reset();
|
|
events2.ScheduleEvent(EVENT_KILL_SELF, 500);
|
|
damage = 0;
|
|
}
|
|
}
|
|
|
|
void JustDied(Unit* /*killer*/) override
|
|
{
|
|
Talk(SAY_KJ_DEATH);
|
|
instance->SetBossState(DATA_KILJAEDEN, DONE);
|
|
if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KILJAEDEN_CONTROLLER)))
|
|
Unit::Kill(controller, controller);
|
|
}
|
|
|
|
void DoAction(int32 param) override
|
|
{
|
|
if (param == ACTION_NO_KILL_TALK)
|
|
{
|
|
events.ScheduleEvent(EVENT_NO_KILL_TALK, 0);
|
|
Talk(SAY_KJ_DARKNESS);
|
|
}
|
|
}
|
|
|
|
void KilledUnit(Unit* victim) override
|
|
{
|
|
if (victim->GetTypeId() == TYPEID_PLAYER && events.GetNextEventTime(EVENT_NO_KILL_TALK) == 0)
|
|
Talk(SAY_KJ_SLAY);
|
|
}
|
|
|
|
void EnterCombat(Unit* /*who*/) override
|
|
{
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH11, 26000, EVENT_GROUP_SPEACH);
|
|
Talk(SAY_KJ_EMERGE);
|
|
|
|
events.SetTimer(200000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH85, 1000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH55, 1000);
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH25, 1000);
|
|
events.ScheduleEvent(EVENT_SPELL_SOUL_FLAY, 0);
|
|
events.ScheduleEvent(EVENT_SPELL_LEGION_LIGHTNING, 7000);
|
|
events.ScheduleEvent(EVENT_SPELL_FIRE_BLOOM, 9000);
|
|
events.ScheduleEvent(EVENT_SUMMON_ORBS, 10000);
|
|
}
|
|
|
|
void JustSummoned(Creature* summon) override
|
|
{
|
|
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.AddEvent(new CastArmageddon(summon), summon->m_Events.CalculateTime(6000));
|
|
summon->DespawnOrUnsummon(10000);
|
|
}
|
|
}
|
|
|
|
void UpdateAI(uint32 diff) override
|
|
{
|
|
events2.Update(diff);
|
|
switch (events2.ExecuteEvent())
|
|
{
|
|
case EVENT_KILL_SELF:
|
|
Unit::Kill(me, me);
|
|
break;
|
|
case EVENT_REBIRTH:
|
|
me->SetVisible(true);
|
|
me->CastSpell(me, SPELL_REBIRTH, false);
|
|
break;
|
|
case EVENT_EMPOWER_ORBS1:
|
|
if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ)))
|
|
kalec->AI()->Talk(SAY_KALECGOS_READY1);
|
|
EmpowerOrb(false);
|
|
break;
|
|
case EVENT_EMPOWER_ORBS2:
|
|
if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ)))
|
|
kalec->AI()->Talk(SAY_KALECGOS_READY2);
|
|
EmpowerOrb(false);
|
|
break;
|
|
case EVENT_EMPOWER_ORBS3:
|
|
if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ)))
|
|
kalec->AI()->Talk(SAY_KALECGOS_READY_ALL);
|
|
EmpowerOrb(true);
|
|
break;
|
|
case EVENT_INIT_FIGHT:
|
|
me->SetReactState(REACT_AGGRESSIVE);
|
|
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
|
me->SetInCombatWithZone();
|
|
return;
|
|
case EVENT_TEXT_SPEACH11:
|
|
if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ)))
|
|
kalec->AI()->Talk(SAY_KALECGOS_JOIN);
|
|
break;
|
|
case EVENT_TEXT_SPEACH21:
|
|
if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ)))
|
|
kalec->AI()->Talk(SAY_KALECGOS_AWAKEN);
|
|
break;
|
|
case EVENT_TEXT_SPEACH22:
|
|
if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA)))
|
|
sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_IMPRISONED, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE);
|
|
break;
|
|
case EVENT_TEXT_SPEACH23:
|
|
Talk(SAY_KJ_PHASE3);
|
|
break;
|
|
case EVENT_TEXT_SPEACH31:
|
|
if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ)))
|
|
kalec->AI()->Talk(SAY_KALECGOS_LETGO);
|
|
break;
|
|
case EVENT_TEXT_SPEACH32:
|
|
if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA)))
|
|
sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_LOST, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE);
|
|
break;
|
|
case EVENT_TEXT_SPEACH33:
|
|
Talk(SAY_KJ_PHASE4);
|
|
break;
|
|
case EVENT_TEXT_SPEACH41:
|
|
if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ)))
|
|
kalec->AI()->Talk(SAY_KALECGOS_FOCUS);
|
|
break;
|
|
case EVENT_TEXT_SPEACH42:
|
|
if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA)))
|
|
sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_KALEC, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE);
|
|
break;
|
|
case EVENT_TEXT_SPEACH43:
|
|
if (Creature* kalec = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KALECGOS_KJ)))
|
|
kalec->AI()->Talk(SAY_KALECGOS_FATE);
|
|
break;
|
|
case EVENT_TEXT_SPEACH44:
|
|
if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA)))
|
|
sCreatureTextMgr->SendChat(anveena, SAY_ANVEENA_GOODBYE, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_ZONE);
|
|
break;
|
|
case EVENT_TEXT_SPEACH45:
|
|
if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA)))
|
|
{
|
|
anveena->RemoveAllAuras();
|
|
anveena->DespawnOrUnsummon(3500);
|
|
}
|
|
break;
|
|
case EVENT_TEXT_SPEACH46:
|
|
if (Creature* anveena = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_ANVEENA)))
|
|
{
|
|
anveena->CastSpell(anveena, SPELL_SACRIFICE_OF_ANVEENA, true);
|
|
me->CastSpell(me, SPELL_CUSTOM_08_STATE, true);
|
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
|
|
events.DelayEvents(7001);
|
|
events2.ScheduleEvent(EVENT_RESTORE_MELEE, 7000);
|
|
}
|
|
Talk(SAY_KJ_PHASE5);
|
|
break;
|
|
case EVENT_RESTORE_MELEE:
|
|
me->RemoveAurasDueToSpell(SPELL_CUSTOM_08_STATE);
|
|
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
|
|
break;
|
|
}
|
|
|
|
if (me->GetReactState() != REACT_AGGRESSIVE)
|
|
return;
|
|
|
|
if (!UpdateVictim())
|
|
return;
|
|
|
|
events.Update(diff);
|
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
|
return;
|
|
|
|
switch (events.ExecuteEvent())
|
|
{
|
|
case EVENT_CHECK_HEALTH85:
|
|
if (me->HealthBelowPct(85))
|
|
{
|
|
phase = PHASE_DARKNESS;
|
|
events2.CancelEvent(EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH21, 16000, EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH22, 22000, EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH23, 28000, EVENT_GROUP_SPEACH);
|
|
events2.RescheduleEvent(EVENT_EMPOWER_ORBS1, 35000);
|
|
|
|
events.DelayEvents(2000);
|
|
events.ScheduleEvent(EVENT_SPELL_SINISTER_REFLECTION, 500);
|
|
events.ScheduleEvent(EVENT_SPELL_SHADOW_SPIKE, 1200);
|
|
events.ScheduleEvent(EVENT_SPELL_FLAME_DART, 3000);
|
|
events.RescheduleEvent(EVENT_SPELL_DARKNESS, 16000); // will be delayed by 29 secs
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH85, 0);
|
|
break;
|
|
|
|
case EVENT_CHECK_HEALTH55:
|
|
if (me->HealthBelowPct(55))
|
|
{
|
|
phase = PHASE_ARMAGEDDON;
|
|
events2.CancelEventGroup(EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH31, 16000, EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH32, 22000, EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH33, 28000, EVENT_GROUP_SPEACH);
|
|
events2.RescheduleEvent(EVENT_EMPOWER_ORBS2, 35000);
|
|
|
|
events.DelayEvents(2000);
|
|
events.ScheduleEvent(EVENT_SPELL_SINISTER_REFLECTION, 500);
|
|
events.ScheduleEvent(EVENT_SPELL_SHADOW_SPIKE, 1200);
|
|
events.RescheduleEvent(EVENT_SPELL_DARKNESS, 15000); // will be delayed by 29 secs
|
|
events.ScheduleEvent(EVENT_SPELL_ARMAGEDDON, 10000);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH55, 0);
|
|
break;
|
|
|
|
case EVENT_CHECK_HEALTH25:
|
|
if (me->HealthBelowPct(25))
|
|
{
|
|
phase = PHASE_SACRIFICE;
|
|
events2.CancelEventGroup(EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH41, 8000, EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH42, 18000, EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH43, 20200, EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH44, 25000, EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH45, 28000, EVENT_GROUP_SPEACH);
|
|
events2.ScheduleEvent(EVENT_TEXT_SPEACH46, 30000, EVENT_GROUP_SPEACH);
|
|
events2.RescheduleEvent(EVENT_EMPOWER_ORBS3, 61000);
|
|
|
|
events.CancelEvent(EVENT_SUMMON_ORBS);
|
|
events.DelayEvents(4000);
|
|
events.ScheduleEvent(EVENT_SPELL_SINISTER_REFLECTION, 500);
|
|
events.ScheduleEvent(EVENT_SPELL_SHADOW_SPIKE, 1200);
|
|
events.RescheduleEvent(EVENT_SPELL_DARKNESS, 15000); // will be delayed by 29 secs
|
|
events.ScheduleEvent(EVENT_SPELL_ARMAGEDDON, 1500);
|
|
break;
|
|
}
|
|
events.ScheduleEvent(EVENT_CHECK_HEALTH25, 0);
|
|
break;
|
|
case EVENT_SPELL_SOUL_FLAY:
|
|
me->CastSpell(me->GetVictim(), SPELL_SOUL_FLAY, false);
|
|
events.ScheduleEvent(EVENT_SPELL_SOUL_FLAY, urand(4000, 5000));
|
|
break;
|
|
case EVENT_SPELL_LEGION_LIGHTNING:
|
|
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
|
|
me->CastSpell(target, SPELL_LEGION_LIGHTNING, false);
|
|
events.ScheduleEvent(EVENT_SPELL_LEGION_LIGHTNING, phase == PHASE_SACRIFICE ? 15000 : 30000);
|
|
events.RescheduleEvent(EVENT_SPELL_SOUL_FLAY, 2000);
|
|
break;
|
|
case EVENT_SPELL_FIRE_BLOOM:
|
|
me->CastCustomSpell(SPELL_FIRE_BLOOM, SPELLVALUE_MAX_TARGETS, 5, me, TRIGGERED_NONE);
|
|
me->SetTarget(me->GetVictim()->GetGUID());
|
|
events.ScheduleEvent(EVENT_SPELL_FIRE_BLOOM, phase == PHASE_SACRIFICE ? 20000 : 40000);
|
|
events.RescheduleEvent(EVENT_SPELL_SOUL_FLAY, 1500);
|
|
break;
|
|
case EVENT_SUMMON_ORBS:
|
|
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 * 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 * 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();
|
|
}
|
|
}
|
|
events.ScheduleEvent(EVENT_SUMMON_ORBS, 40000);
|
|
break;
|
|
case EVENT_SPELL_SHADOW_SPIKE:
|
|
events.DelayEvents(27000);
|
|
me->CastSpell(me, SPELL_SHADOW_SPIKE, false);
|
|
break;
|
|
case EVENT_SPELL_SINISTER_REFLECTION:
|
|
Talk(SAY_KJ_REFLECTION);
|
|
me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE);
|
|
me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE);
|
|
me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE);
|
|
me->CastCustomSpell(SPELL_SINISTER_REFLECTION, SPELLVALUE_MAX_TARGETS, 1, me, TRIGGERED_NONE);
|
|
break;
|
|
case EVENT_SPELL_FLAME_DART:
|
|
me->CastSpell(me, SPELL_FLAME_DART, false);
|
|
events.ScheduleEvent(EVENT_SPELL_FLAME_DART, 10000);
|
|
break;
|
|
case EVENT_SPELL_DARKNESS:
|
|
Talk(EMOTE_KJ_DARKNESS);
|
|
me->CastSpell(me, SPELL_DARKNESS_OF_A_THOUSAND_SOULS, false);
|
|
events.ScheduleEvent(EVENT_SPELL_DARKNESS, phase == PHASE_SACRIFICE ? 20000 : 45000);
|
|
events.DelayEvents(8000);
|
|
break;
|
|
case EVENT_SPELL_ARMAGEDDON:
|
|
me->CastSpell(me, SPELL_ARMAGEDDON_PERIODIC, true);
|
|
events.ScheduleEvent(EVENT_SPELL_ARMAGEDDON, phase == PHASE_SACRIFICE ? 20000 : 40000);
|
|
break;
|
|
}
|
|
|
|
DoMeleeAttackIfReady();
|
|
}
|
|
|
|
void EmpowerOrb(bool empowerAll)
|
|
{
|
|
for (uint8 i = 0; i < 4; ++i)
|
|
{
|
|
if (GameObject* orb = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_ORB_OF_THE_BLUE_DRAGONFLIGHT_1 + i)))
|
|
{
|
|
if (orb->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE))
|
|
{
|
|
orb->RemoveFlag(GAMEOBJECT_FLAGS, 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 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_KILJAEDEN_CONTROLLER)))
|
|
controller->AI()->JustSummoned(trigger);
|
|
}
|
|
|
|
if (!empowerAll)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return GetSunwellPlateauAI<boss_kiljaedenAI>(creature);
|
|
}
|
|
};
|
|
|
|
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<Creature*> cList;
|
|
_owner->GetCreaturesWithEntryInRange(cList, 20.0f, NPC_SHATTERED_SUN_SOLDIER);
|
|
for (std::list<Creature*>::const_iterator itr = cList.begin(); itr != cList.end(); ++itr)
|
|
(*itr)->SetFacingTo(_owner->GetOrientation());
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
Creature* _owner;
|
|
};
|
|
|
|
class npc_kalecgos_kj : public CreatureScript
|
|
{
|
|
public:
|
|
npc_kalecgos_kj() : CreatureScript("npc_kalecgos_kj") { }
|
|
|
|
CreatureAI* GetAI(Creature* creature) const override
|
|
{
|
|
return GetSunwellPlateauAI<npc_kalecgos_kjAI>(creature);
|
|
}
|
|
|
|
struct npc_kalecgos_kjAI : public NullCreatureAI
|
|
{
|
|
npc_kalecgos_kjAI(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, 35000);
|
|
}
|
|
}
|
|
|
|
void JustSummoned(Creature* summon) override
|
|
{
|
|
summons.Summon(summon);
|
|
if (summon->GetEntry() == NPC_SHATTERED_SUN_RIFTWAKER)
|
|
{
|
|
summon->CastSpell(summon, SPELL_TELEPORT_VISUAL, true);
|
|
Movement::MoveSplineInit init(summon);
|
|
if (summons.size() == 1)
|
|
{
|
|
init.MoveTo(1727.08f, 656.82f, 28.37f, false, true);
|
|
init.SetFacing(5.14f);
|
|
}
|
|
else
|
|
{
|
|
init.MoveTo(1738.84f, 627.32f, 28.26f, false, true);
|
|
init.SetFacing(2.0f);
|
|
}
|
|
init.Launch();
|
|
}
|
|
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, 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, 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, 15000);
|
|
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, 6000);
|
|
break;
|
|
case EVENT_SCENE_03:
|
|
me->SummonCreature(NPC_SHATTRATH_PORTAL_DUMMY, 1727.08f + cos(5.14f), 656.82f + 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 + sin(2.0f), 28.26f + 2.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
|
events.ScheduleEvent(eventId + 1, 11000);
|
|
break;
|
|
case EVENT_SCENE_04:
|
|
me->SummonCreature(NPC_INERT_PORTAL, 1734.96f, 642.43f, 28.06f, 3.49f);
|
|
events.ScheduleEvent(eventId + 1, 4000);
|
|
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.AddEvent(new MoveDelayed(first, 1718.70f, 607.78f, 28.06f, 2.323f), first->m_Events.CalculateTime(5000));
|
|
first->m_Events.AddEvent(new FixOrientation(first), first->m_Events.CalculateTime(12000));
|
|
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 * sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f))
|
|
follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first));
|
|
}
|
|
events.ScheduleEvent(eventId + 1, 10000);
|
|
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.AddEvent(new MoveDelayed(first, 1678.69f, 649.27f, 28.06f, 5.46f), first->m_Events.CalculateTime(5000));
|
|
first->m_Events.AddEvent(new FixOrientation(first), first->m_Events.CalculateTime(14500));
|
|
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 * sin(i * 2.0f * M_PI / 9), 28.06f, 3.49f))
|
|
follower->GetMotionMaster()->MoveFollow(first, 3.0f, follower->GetAngle(first));
|
|
}
|
|
events.ScheduleEvent(eventId + 1, 12000);
|
|
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, 7000);
|
|
break;
|
|
case EVENT_SCENE_08:
|
|
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
|
|
velen->AI()->Talk(SAY_VELEN_01);
|
|
events.ScheduleEvent(eventId + 1, 25000);
|
|
break;
|
|
case EVENT_SCENE_09:
|
|
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
|
|
velen->AI()->Talk(SAY_VELEN_02);
|
|
events.ScheduleEvent(eventId + 1, 14500);
|
|
break;
|
|
case EVENT_SCENE_10:
|
|
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
|
|
velen->AI()->Talk(SAY_VELEN_03);
|
|
events.ScheduleEvent(eventId + 1, 12500);
|
|
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, 8000);
|
|
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, 20000);
|
|
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, 6000);
|
|
break;
|
|
case EVENT_SCENE_14:
|
|
if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN))
|
|
liadrin->AI()->Talk(SAY_LIADRIN_01);
|
|
events.ScheduleEvent(eventId + 1, 10000);
|
|
break;
|
|
case EVENT_SCENE_15:
|
|
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
|
|
velen->AI()->Talk(SAY_VELEN_05);
|
|
events.ScheduleEvent(eventId + 1, 14000);
|
|
break;
|
|
case EVENT_SCENE_16:
|
|
if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN))
|
|
liadrin->AI()->Talk(SAY_LIADRIN_02);
|
|
events.ScheduleEvent(eventId + 1, 2000);
|
|
break;
|
|
case EVENT_SCENE_17:
|
|
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
|
|
velen->AI()->Talk(SAY_VELEN_06);
|
|
events.ScheduleEvent(eventId + 1, 3000);
|
|
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, 8000);
|
|
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, 2000);
|
|
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, 3000);
|
|
break;
|
|
case EVENT_SCENE_21:
|
|
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
|
|
velen->AI()->Talk(SAY_VELEN_07);
|
|
events.ScheduleEvent(eventId + 1, 15000);
|
|
break;
|
|
case EVENT_SCENE_22:
|
|
if (Creature* liadrin = summons.GetCreatureWithEntry(NPC_LADY_LIADRIN))
|
|
liadrin->AI()->Talk(SAY_LIADRIN_03);
|
|
events.ScheduleEvent(eventId + 1, 20000);
|
|
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, 8000);
|
|
break;
|
|
case EVENT_SCENE_24:
|
|
if (Creature* velen = summons.GetCreatureWithEntry(NPC_PROPHET_VELEN))
|
|
velen->AI()->Talk(SAY_VELEN_09);
|
|
events.ScheduleEvent(eventId + 1, 5000);
|
|
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(5000);
|
|
}
|
|
events.ScheduleEvent(eventId + 1, 3000);
|
|
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(summon->GetExactDist2d(1734.96f, 642.43f) * 100);
|
|
}
|
|
events.ScheduleEvent(eventId + 1, 7000);
|
|
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 : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_shadow_spike() : SpellScriptLoader("spell_kiljaeden_shadow_spike") { }
|
|
|
|
class spell_kiljaeden_shadow_spike_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_kiljaeden_shadow_spike_AuraScript);
|
|
|
|
void HandlePeriodic(AuraEffect const* aurEff)
|
|
{
|
|
PreventDefaultAction();
|
|
if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
|
|
GetUnitOwner()->CastSpell(target, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kiljaeden_shadow_spike_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const override
|
|
{
|
|
return new spell_kiljaeden_shadow_spike_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_kiljaeden_sinister_reflection : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_sinister_reflection() : SpellScriptLoader("spell_kiljaeden_sinister_reflection") { }
|
|
|
|
class spell_kiljaeden_sinister_reflection_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_kiljaeden_sinister_reflection_SpellScript);
|
|
|
|
void FilterTargets(std::list<WorldObject*>& targets)
|
|
{
|
|
targets.remove_if(Acore::UnitAuraCheck(true, SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT));
|
|
}
|
|
|
|
void HandleScriptEffect(SpellEffIndex effIndex)
|
|
{
|
|
PreventHitDefaultEffect(effIndex);
|
|
if (Unit* target = GetHitUnit())
|
|
{
|
|
target->CastSpell(target, SPELL_SINISTER_REFLECTION_SUMMON, true);
|
|
//target->CastSpell(target, SPELL_SINISTER_REFLECTION_CLONE, true);
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kiljaeden_sinister_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
|
OnEffectHitTarget += SpellEffectFn(spell_kiljaeden_sinister_reflection_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_kiljaeden_sinister_reflection_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_kiljaeden_sinister_reflection_clone : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_sinister_reflection_clone() : SpellScriptLoader("spell_kiljaeden_sinister_reflection_clone") { }
|
|
|
|
class spell_kiljaeden_sinister_reflection_clone_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_kiljaeden_sinister_reflection_clone_SpellScript);
|
|
|
|
void FilterTargets(std::list<WorldObject*>& targets)
|
|
{
|
|
targets.sort(Acore::ObjectDistanceOrderPred(GetCaster()));
|
|
WorldObject* target = targets.front();
|
|
|
|
targets.clear();
|
|
if (target && target->GetTypeId() == TYPEID_UNIT)
|
|
{
|
|
target->ToCreature()->AI()->SetData(1, GetCaster()->getClass());
|
|
targets.push_back(target);
|
|
}
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kiljaeden_sinister_reflection_clone_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_kiljaeden_sinister_reflection_clone_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_kiljaeden_flame_dart : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_flame_dart() : SpellScriptLoader("spell_kiljaeden_flame_dart") { }
|
|
|
|
class spell_kiljaeden_flame_dart_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_kiljaeden_flame_dart_SpellScript);
|
|
|
|
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_SpellScript::HandleSchoolDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_kiljaeden_flame_dart_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_kiljaeden_darkness : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_darkness() : SpellScriptLoader("spell_kiljaeden_darkness") { }
|
|
|
|
class spell_kiljaeden_darkness_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_kiljaeden_darkness_AuraScript);
|
|
|
|
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
|
{
|
|
if (GetUnitOwner()->GetTypeId() == TYPEID_UNIT)
|
|
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_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const override
|
|
{
|
|
return new spell_kiljaeden_darkness_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_kiljaeden_power_of_the_blue_flight : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_power_of_the_blue_flight() : SpellScriptLoader("spell_kiljaeden_power_of_the_blue_flight") { }
|
|
|
|
class spell_kiljaeden_power_of_the_blue_flight_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_kiljaeden_power_of_the_blue_flight_SpellScript);
|
|
|
|
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_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_kiljaeden_power_of_the_blue_flight_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_kiljaeden_vengeance_of_the_blue_flight : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_vengeance_of_the_blue_flight() : SpellScriptLoader("spell_kiljaeden_vengeance_of_the_blue_flight") { }
|
|
|
|
class spell_kiljaeden_vengeance_of_the_blue_flight_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_kiljaeden_vengeance_of_the_blue_flight_AuraScript);
|
|
|
|
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_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_MOD_POSSESS, AURA_EFFECT_HANDLE_REAL);
|
|
OnEffectApply += AuraEffectApplyFn(spell_kiljaeden_vengeance_of_the_blue_flight_AuraScript::HandleApply, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL);
|
|
OnEffectRemove += AuraEffectRemoveFn(spell_kiljaeden_vengeance_of_the_blue_flight_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_MOD_POSSESS, AURA_EFFECT_HANDLE_REAL);
|
|
OnEffectRemove += AuraEffectRemoveFn(spell_kiljaeden_vengeance_of_the_blue_flight_AuraScript::HandleRemove, EFFECT_2, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const override
|
|
{
|
|
return new spell_kiljaeden_vengeance_of_the_blue_flight_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_kiljaeden_armageddon_periodic : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_armageddon_periodic() : SpellScriptLoader("spell_kiljaeden_armageddon_periodic") { }
|
|
|
|
class spell_kiljaeden_armageddon_periodic_AuraScript : public AuraScript
|
|
{
|
|
PrepareAuraScript(spell_kiljaeden_armageddon_periodic_AuraScript);
|
|
|
|
void HandlePeriodic(AuraEffect const* aurEff)
|
|
{
|
|
PreventDefaultAction();
|
|
if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
|
|
GetUnitOwner()->CastSpell(target, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnEffectPeriodic += AuraEffectPeriodicFn(spell_kiljaeden_armageddon_periodic_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
|
}
|
|
};
|
|
|
|
AuraScript* GetAuraScript() const override
|
|
{
|
|
return new spell_kiljaeden_armageddon_periodic_AuraScript();
|
|
}
|
|
};
|
|
|
|
class spell_kiljaeden_armageddon_missile : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_armageddon_missile() : SpellScriptLoader("spell_kiljaeden_armageddon_missile") { }
|
|
|
|
class spell_kiljaeden_armageddon_missile_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_kiljaeden_armageddon_missile_SpellScript);
|
|
|
|
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_SpellScript::SetDest, EFFECT_0, TARGET_DEST_CASTER);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_kiljaeden_armageddon_missile_SpellScript();
|
|
}
|
|
};
|
|
|
|
class spell_kiljaeden_dragon_breath : public SpellScriptLoader
|
|
{
|
|
public:
|
|
spell_kiljaeden_dragon_breath() : SpellScriptLoader("spell_kiljaeden_dragon_breath") { }
|
|
|
|
class spell_kiljaeden_dragon_breath_SpellScript : public SpellScript
|
|
{
|
|
PrepareSpellScript(spell_kiljaeden_dragon_breath_SpellScript);
|
|
|
|
void FilterTargets(std::list<WorldObject*>& targets)
|
|
{
|
|
targets.remove_if(Acore::UnitAuraCheck(true, SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT));
|
|
}
|
|
|
|
void Register() override
|
|
{
|
|
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kiljaeden_dragon_breath_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_CONE_ALLY);
|
|
}
|
|
};
|
|
|
|
SpellScript* GetSpellScript() const override
|
|
{
|
|
return new spell_kiljaeden_dragon_breath_SpellScript();
|
|
}
|
|
};
|
|
|
|
void AddSC_boss_kiljaeden()
|
|
{
|
|
new npc_kiljaeden_controller();
|
|
new boss_kiljaeden();
|
|
new npc_kalecgos_kj();
|
|
new spell_kiljaeden_shadow_spike();
|
|
new spell_kiljaeden_sinister_reflection();
|
|
new spell_kiljaeden_sinister_reflection_clone();
|
|
new spell_kiljaeden_flame_dart();
|
|
new spell_kiljaeden_darkness();
|
|
new spell_kiljaeden_power_of_the_blue_flight();
|
|
new spell_kiljaeden_vengeance_of_the_blue_flight();
|
|
new spell_kiljaeden_armageddon_periodic();
|
|
new spell_kiljaeden_armageddon_missile();
|
|
new spell_kiljaeden_dragon_breath();
|
|
}
|