aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndy@conmuc-l03 <none@none>2009-04-25 21:30:09 +0200
committerAndy@conmuc-l03 <none@none>2009-04-25 21:30:09 +0200
commit4827f7fd3e1827f2d1cccbd34e3499d04ad5cc68 (patch)
treea6561f59a84d7be2d7ad31b3dd486cb698c48be2 /src
parent0cedb6c5b59f2c12a64c4fd24a8c63a689e82bc4 (diff)
Added KilJaeden-Script
--HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp1294
1 files changed, 1291 insertions, 3 deletions
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp
index 12f7e7b46b7..beb5a77e488 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_kiljaeden.cpp
@@ -16,12 +16,1300 @@
/* ScriptData
SDName: Boss_Kiljaeden
-SD%Complete: 0
-SDComment: Placeholer
+SD%Complete: 70
+SDComment: Phase4, Phase5, Shadow Spike, Armageddon
SDCategory: Sunwell_Plateau
EndScriptData */
+//TODO rewrite Amagedon
+//TODO Remove blue visual from Orbs on reset and if it is used
+
#include "precompiled.h"
+#include "def_sunwell_plateau.h"
+#include <math.h>
+
+/*** Speech and sounds***/
+enum Speeches
+{
+ // These are used throughout Sunwell and Magisters(?). Players can hear this while running through the instances.
+ SAY_KJ_OFFCOMBAT1 = -1580066,
+ SAY_KJ_OFFCOMBAT2 = -1580067,
+ SAY_KJ_OFFCOMBAT3 = -1580068,
+ SAY_KJ_OFFCOMBAT4 = -1580069,
+ SAY_KJ_OFFCOMBAT5 = -1580070,
+
+ // Encounter speech and sounds
+ SAY_KJ_EMERGE = -1580071,
+ SAY_KJ_SLAY1 = -1580072,
+ SAY_KJ_SLAY2 = -1580073,
+ SAY_KJ_REFLECTION1 = -1580074,
+ SAY_KJ_REFLECTION2 = -1580075,
+ SAY_KJ_DARKNESS1 = -1580076,
+ SAY_KJ_DARKNESS2 = -1580077,
+ SAY_KJ_DARKNESS3 = -1580078,
+ SAY_KJ_PHASE3 = -1580079,
+ SAY_KJ_PHASE4 = -1580080,
+ SAY_KJ_PHASE5 = -1580081,
+ SAY_KJ_DEATH = -1580093,
+ EMOTE_KJ_DARKNESS = -1580094,
+
+ /*** Kalecgos - Anveena speech at the beginning of Phase 5; Anveena's sacrifice ***/
+ SAY_KALECGOS_AWAKEN = -1580082,
+ SAY_ANVEENA_IMPRISONED = -1580083,
+ SAY_KALECGOS_LETGO = -1580084,
+ SAY_ANVEENA_LOST = -1580085,
+ SAY_KALECGOS_FOCUS = -1580086,
+ SAY_ANVEENA_KALEC = -1580087,
+ SAY_KALECGOS_FATE = -1580088,
+ SAY_ANVEENA_GOODBYE = -1580089,
+ SAY_KALECGOS_GOODBYE = -1580090,
+ SAY_KALECGOS_ENCOURAGE = -1580091,
+
+ /*** Kalecgos says throughout the fight ***/
+ SAY_KALECGOS_JOIN = -1580092,
+ SAY_KALEC_ORB_READY1 = -1580095,
+ SAY_KALEC_ORB_READY2 = -1580096,
+ SAY_KALEC_ORB_READY3 = -1580097,
+ SAY_KALEC_ORB_READY4 = -1580098
+};
+
+/*** Spells used during the encounter ***/
+enum SpellIds
+{
+ /* Hand of the Deceiver's spells and cosmetics */
+ SPELL_SHADOW_BOLT_VOLLEY = 45770, // ~30 yard range Shadow Bolt Volley for ~2k(?) damage
+ SPELL_SHADOW_INFUSION = 45772, // They gain this at 20% - Immunity to Stun/Silence and makes them look angry!
+ SPELL_FELFIRE_PORTAL = 46875, // Creates a portal that spawns Felfire Fiends (LIVE FOR THE SWARM!1 FOR THE OVERMIND!)
+ SPELL_SHADOW_CHANNELING = 46757, // Channeling animation out of combat
+
+ /* Volatile Felfire Fiend's spells */
+ SPELL_FELFIRE_FISSION = 45779, // Felfire Fiends explode when they die or get close to target.
+
+ /* Kil'Jaeden's spells and cosmetics */
+ SPELL_TRANS = 23188, // Surprisingly, this seems to be the right spell.. (Where is it used?)
+ SPELL_REBIRTH = 44200, // Emerge from the Sunwell
+ SPELL_SOUL_FLAY = 45442, // 9k Shadow damage over 3 seconds. Spammed throughout all the fight.
+ SPELL_SOUL_FLAY_SLOW = 47106,
+ SPELL_LEGION_LIGHTNING = 45664, // Chain Lightning, 4 targets, ~3k Shadow damage, 1.5k mana burn
+ SPELL_FIRE_BLOOM = 45641, // Places a debuff on 5 raid members, which causes them to deal 2k Fire damage to nearby allies and selves. MIGHT NOT WORK
+
+ SPELL_SINISTER_REFLECTION = 45785, // Summon shadow copies of 5 raid members that fight against KJ's enemies
+ SPELL_COPY_WEAPON = 41055, // }
+ SPELL_COPY_WEAPON2 = 41054, // }
+ SPELL_COPY_OFFHAND = 45206, // }- Spells used in Sinister Reflection creation
+ SPELL_COPY_OFFHAND_WEAPON = 45205, // }
+
+ SPELL_SHADOW_SPIKE = 46680, // Bombard random raid members with Shadow Spikes (Very similar to Void Reaver orbs)
+ SPELL_FLAME_DART = 45737, // Bombards the raid with flames every 3(?) seconds
+ SPELL_DARKNESS_OF_A_THOUSAND_SOULS = 46605, // Begins a 8-second channeling, after which he will deal 50'000 damage to the raid
+ SPELL_DARKNESS_OF_A_THOUSAND_SOULS_DAMAGE = 45657,
+
+ /* Armageddon spells wrong visual */
+ SPELL_ARMAGEDDON_TRIGGER = 45909, // Meteor spell trigger missile should cast creature on himself
+ SPELL_ARMAGEDDON_VISUAL = 45911, // Does the hellfire visual to indicate where the meteor missle lands
+ SPELL_ARMAGEDDON_VISUAL2 = 45914, // Does the light visual to indicate where the meteor missle lands
+ SPELL_ARMAGEDDON_VISUAL3 = 24207, // This shouldn't correct but same as seen on the movie
+ SPELL_ARMAGEDDON_SUMMON_TRIGGER = 45921, // Summons the triggers that cast the spells on himself need random target select
+ SPELL_ARMAGEDDON_DAMAGE = 45915, // This does the area damage
+
+ /* Shield Orb Spells*/
+ SPELL_SHADOW_BOLT = 45680, //45679 would be correct but triggers to often //TODO fix console error
+
+
+ /* Anveena's spells and cosmetics (Or, generally, everything that has "Anveena" in name) */
+ SPELL_ANVEENA_PRISON = 46367, // She hovers locked within a bubble
+ SPELL_ANVEENA_ENERGY_DRAIN = 46410, // Sunwell energy glow animation (Control mob uses this)
+ SPELL_SACRIFICE_OF_ANVEENA = 46474, // This is cast on Kil'Jaeden when Anveena sacrifices herself into the Sunwell
+
+ /* Sinister Reflection Spells */
+ SPELL_SR_CURSE_OF_AGONY = 46190,
+ SPELL_SR_SHADOW_BOLT = 47076,
+
+ SPELL_SR_EARTH_SHOCK = 47071,
+
+ SPELL_SR_FIREBALL = 47074,
+
+ SPELL_SR_HEMORRHAGE = 45897,
+
+ SPELL_SR_HOLY_SHOCK = 38921,
+ SPELL_SR_HAMMER_OF_JUSTICE = 37369,
+
+ SPELL_SR_HOLY_SMITE = 47077,
+ SPELL_SR_RENEW = 47079,
+
+ SPELL_SR_SHOOT = 16496,
+ SPELL_SR_MULTI_SHOT = 48098,
+ SPELL_SR_WING_CLIP = 40652,
+
+ SPELL_SR_WHIRLWIND = 17207,
+
+ SPELL_SR_MOONFIRE = 47072,
+ //SPELL_SR_PLAGU STRIKE = 58843, Dk Spell!
+
+ /*** Other Spells (used by players, etc) ***/
+ SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT = 45839, // Possess the blue dragon from the orb to help the raid.
+ SPELL_ENTROPIUS_BODY = 46819, // Visual for Entropius at the Epilogue
+ SPELL_RING_OF_BLUE_FLAMES = 45825 //Cast this spell when the go is activated
+};
+
+enum CreatureIds
+{
+ CREATURE_ANVEENA = 26046, // Embodiment of the Sunwell
+ CREATURE_KALECGOS = 25319, // Helps the raid throughout the fight
+ CREATURE_PROPHET = 26246, // Outro
+ CREATURE_KILJAEDEN = 25315, // Give it to 'em KJ!
+ CREATURE_HAND_OF_THE_DECEIVER = 25588, // Adds found before KJ emerges
+ CREATURE_FELFIRE_PORTAL = 25603, // Portal spawned be Hand of the Deceivers
+ CREATURE_VOLATILE_FELFIRE_FIEND = 25598, // Fiends spawned by the above portal
+ CREATURE_ARMAGEDDON_TARGET = 25735, // This mob casts meteor on itself.. I think
+ CREATURE_SHIELD_ORB = 25502, // Shield orbs circle the room raining shadow bolts on raid
+ CREATURE_THE_CORE_OF_ENTROPIUS = 26262, // Used in the ending cinematic?
+ CREATURE_POWER_OF_THE_BLUE_DRAGONFLIGHT = 25653, // NPC that players possess when using the Orb of the Blue Dragonflight
+ CREATURE_SPIKE_TARGET1 = 30598, //Should summon these under Shadow Spike Channel on targets place
+ CREATURE_SPIKE_TARGET2 = 30614,
+ CREATURE_SINISTER_REFLECTION = 25708 //Sinister Relection spawnd on Phase swichtes
+};
+
+/*** GameObjects ***/
+#define GAMEOBJECT_ORB_OF_THE_BLUE_DRAGONFLIGHT 188415
+
+/*** Error messages ***/
+#define ERROR_KJ_NOT_SUMMONED "TSCR ERROR: Unable to summon Kil'Jaeden for some reason"
+
+/*** Others ***/
+#define FLOOR_Z 28.050388
+#define SHIELD_ORB_Z 45.000
+
+enum Phase
+{
+ PHASE_DECEIVERS = 1, // Fight 3 adds
+ PHASE_NORMAL = 2, // Kil'Jaeden emerges from the sunwell
+ PHASE_DARKNESS = 3, // At 85%, he gains few abilities; Kalecgos joins the fight
+ PHASE_ARMAGEDDON = 4, // At 55%, he gains even more abilities
+ PHASE_SACRIFICE = 5, // At 25%, Anveena sacrifices herself into the Sunwell; at this point he becomes enraged and has *significally* shorter cooldowns.
+};
+
+//Timers
+enum KilJaedenTimers {
+ TIMER_KALEC_JOIN = 0,
+
+ //Phase 2 Timer
+ TIMER_SOUL_FLAY = 1,
+ TIMER_LEGION_LIGHTNING = 2,
+ TIMER_FIRE_BLOOM = 3,
+ TIMER_SUMMON_SHILEDORB = 4,
+
+ //Phase 3 Timer
+ TIMER_SHADOW_SPIKE = 5,
+ TIMER_FLAME_DART = 6,
+ TIMER_DARKNESS = 7,
+ TIMER_ORBS_EMPOWER = 8,
+
+ //Phase 4 Timer
+ TIMER_ARMAGEDDON = 9
+};
+
+// Locations of the Hand of Deceiver adds
+float DeceiverLocations[3][3]=
+{
+ {1682.045, 631.299, 5.936},
+ {1684.099, 618.848, 0.589},
+ {1694.170, 612.272, 1.416},
+};
+
+// Locations, where Shield Orbs will spawn
+float ShieldOrbLocations[4][2]=
+{
+ {1698.900, 627.870}, //middle pont of Sunwell
+ {12, 3.14}, // First one spawns northeast of KJ
+ {12, 3.14/0.7}, // Second one spawns southeast
+ {12, 3.14*3.8} // Third one spawns (?)
+};
+
+float OrbLocations[4][5] = {
+ (1694.48, 674.29, 28.0502, 4.86985),
+ (1745.68, 621.823, 28.0505, 2.93777),
+ (1704.14, 583.591, 28.1696, 1.59003),
+ (1653.12, 635.41, 28.0932, 0.0977725),
+};
+
+struct Speech
+{
+ int32 textid;
+ uint32 creature, timer;
+};
+// TODO: Timers
+static Speech Sacrifice[]=
+{
+ {SAY_KALECGOS_AWAKEN, CREATURE_KALECGOS, 5000},
+ {SAY_ANVEENA_IMPRISONED, CREATURE_ANVEENA, 5000},
+ {SAY_KALECGOS_LETGO, CREATURE_KALECGOS, 8000},
+ {SAY_ANVEENA_LOST, CREATURE_ANVEENA, 5000},
+ {SAY_KALECGOS_FOCUS, CREATURE_KALECGOS, 7000},
+ {SAY_ANVEENA_KALEC, CREATURE_ANVEENA, 2000},
+ {SAY_KALECGOS_FATE, CREATURE_KALECGOS, 3000},
+ {SAY_ANVEENA_GOODBYE, CREATURE_ANVEENA, 6000},
+ {SAY_KALECGOS_GOODBYE, CREATURE_KALECGOS, 12000},
+ {SAY_KJ_PHASE5, CREATURE_KILJAEDEN, 8000},
+ {SAY_KALECGOS_ENCOURAGE, CREATURE_KALECGOS, 5000}
+};
+
+class AllOrbsInGrid
+{
+public:
+ AllOrbsInGrid() {}
+ bool operator() (GameObject* go)
+ {
+ if(go->GetEntry() == GAMEOBJECT_ORB_OF_THE_BLUE_DRAGONFLIGHT)
+ return true;
+ return false;
+ }
+};
+
+bool GOHello_go_orb_of_the_blue_flight(Player *plr, GameObject* go)
+{
+ if(go->GetUInt32Value(GAMEOBJECT_FACTION) == 35){
+ ScriptedInstance* pInstance = ((ScriptedInstance*)go->GetInstanceData());
+ float x,y,z, dx,dy,dz;
+ go->SummonCreature(CREATURE_POWER_OF_THE_BLUE_DRAGONFLIGHT, plr->GetPositionX(), plr->GetPositionY(), plr->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 121000);
+ plr->CastSpell(plr, SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT, true);
+ go->SetUInt32Value(GAMEOBJECT_FACTION, 0);
+ Unit* Kalec = ((Creature*)Unit::GetUnit(*plr, pInstance->GetData64(DATA_KALECGOS_KJ)));
+ //Kalec->RemoveDynObject(SPELL_RING_OF_BLUE_FLAMES);
+ go->GetPosition(x,y,z);
+ for(uint8 i = 0; i < 4; ++i){
+ DynamicObject* Dyn = Kalec->GetDynObject(SPELL_RING_OF_BLUE_FLAMES);
+ if(Dyn){
+ Dyn->GetPosition(dx,dy,dz);
+ if(x == dx && dy == y && dz == z){
+ Dyn->RemoveFromWorld();
+ break;
+ }
+ }
+ }
+ go->Refresh();
+ }
+ return true;
+}
+
+//AI for Kalecgos
+struct TRINITY_DLL_DECL boss_kalecgosKJAI : public ScriptedAI
+{
+ boss_kalecgosKJAI(Creature* c) : ScriptedAI(c){
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ }
+
+ GameObject* Orb[4];
+ ScriptedInstance* pInstance;
+ uint8 OrbsEmpowered;
+ uint8 EmpowerCount;
+
+ bool Searched;
+
+ void InitializeAI(){
+ for(uint8 i = 0; i < 4; ++i)
+ Orb[i] = NULL;
+ FindOrbs();
+ OrbsEmpowered = 0;
+ EmpowerCount = 0;
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->setActive(true);
+ Searched = false;
+ FindOrbs();
+ }
+
+ void Reset(){}
+
+ void Aggro(Unit* who) {}
+
+ void FindOrbs()
+ {
+ CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY()));
+ Cell cell(pair);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+ std::list<GameObject*> orbList;
+ AllOrbsInGrid check;
+ Trinity::GameObjectListSearcher<AllOrbsInGrid> searcher(orbList, check);
+ TypeContainerVisitor<Trinity::GameObjectListSearcher<AllOrbsInGrid>, GridTypeMapContainer> visitor(searcher);
+ CellLock<GridReadGuard> cell_lock(cell, pair);
+ cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap()));
+ if(orbList.empty())
+ return;
+ uint8 i = 0;
+ for(std::list<GameObject*>::iterator itr = orbList.begin(); itr != orbList.end(); ++itr, ++i){
+ Orb[i] = GameObject::GetGameObject(*m_creature, (*itr)->GetGUID());
+ }
+ }
+
+ void ResetOrbs(){
+ m_creature->RemoveDynObject(SPELL_RING_OF_BLUE_FLAMES);
+ for(uint8 i = 0; i < 4; ++i)
+ if(Orb[i]) Orb[i]->SetUInt32Value(GAMEOBJECT_FACTION, 0);
+ }
+
+ void EmpowerOrb(bool all)
+ {
+ if(!Orb[OrbsEmpowered])
+ return;
+ uint8 random = rand()%3;
+ if(all){
+ m_creature->RemoveDynObject(SPELL_RING_OF_BLUE_FLAMES);
+ for(uint8 i = 0; i < 4; ++i){
+ if(!Orb[i]) return;
+ Orb[i]->CastSpell(m_creature, SPELL_RING_OF_BLUE_FLAMES);
+ Orb[i]->SetUInt32Value(GAMEOBJECT_FACTION, 35);
+ Orb[i]->setActive(true);
+ Orb[i]->Refresh();
+ }
+ }else{
+ float x,y,z, dx,dy,dz;
+ Orb[random]->GetPosition(x,y,z);
+ for(uint8 i = 0; i < 4; ++i){
+ DynamicObject* Dyn = m_creature->GetDynObject(SPELL_RING_OF_BLUE_FLAMES);
+ if(Dyn){
+ Dyn->GetPosition(dx,dy,dz);
+ if(x == dx && dy == y && dz == z){
+ Dyn->RemoveFromWorld();
+ break;
+ }
+ }
+ }
+ Orb[random]->CastSpell(m_creature, SPELL_RING_OF_BLUE_FLAMES);
+ Orb[random]->SetUInt32Value(GAMEOBJECT_FACTION, 35);
+ Orb[random]->setActive(true);
+ Orb[random]->Refresh();
+ ++OrbsEmpowered;
+ }
+ ++EmpowerCount;
+
+ switch(EmpowerCount){
+ case 1: DoScriptText(SAY_KALEC_ORB_READY1, m_creature); break;
+ case 2: DoScriptText(SAY_KALEC_ORB_READY2, m_creature); break;
+ case 3: DoScriptText(SAY_KALEC_ORB_READY3, m_creature); break;
+ case 4: DoScriptText(SAY_KALEC_ORB_READY4, m_creature); break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff){
+ if(!Searched){
+ FindOrbs();
+ Searched = true;
+ }
+
+ if(OrbsEmpowered == 4) OrbsEmpowered = 0;
+ }
+};
+
+CreatureAI* GetAI_boss_kalecgosKJ(Creature *_Creature)
+{
+ return new boss_kalecgosKJAI (_Creature);
+}
+
+//AI for Kil'jaeden
+struct TRINITY_DLL_DECL boss_kiljaedenAI : public Scripted_NoMovementAI
+{
+ boss_kiljaedenAI(Creature* c) : Scripted_NoMovementAI(c), Summons(m_creature){
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ }
+
+ ScriptedInstance* pInstance;
+ SummonList Summons;
+ Creature* Kalec;
+ Unit* randomPlayer;
+
+ uint8 Phase;
+ uint8 ActiveTimers;
+
+ uint32 Timer[10];
+ uint32 WaitTimer;
+
+ /* Boolean */
+ bool IsKalecJoined;
+ bool IsInDarkness;
+ bool TimerIsDeactiveted[10];
+ bool IsWaiting;
+ bool OrbActivated;
+
+ void Reset()
+ {
+ // TODO: Fix timers
+ Timer[TIMER_KALEC_JOIN] = 26000;
+
+ //Phase 2 Timer
+ Timer[TIMER_SOUL_FLAY] = 20000;
+ Timer[TIMER_LEGION_LIGHTNING] = 40000;
+ Timer[TIMER_FIRE_BLOOM] = 30000;
+ Timer[TIMER_SUMMON_SHILEDORB] = 45000;
+
+ //Phase 3 Timer
+ Timer[TIMER_SHADOW_SPIKE] = 4000;
+ Timer[TIMER_FLAME_DART] = 3000;
+ Timer[TIMER_DARKNESS] = 45000;
+ Timer[TIMER_ORBS_EMPOWER] = 35000;
+
+ //Phase 4 Timer
+ Timer[TIMER_ARMAGEDDON] = 2000;
+
+ ActiveTimers = 5;
+ WaitTimer = 0;
+
+ Phase = PHASE_DECEIVERS;
+
+ IsKalecJoined = false;
+ IsInDarkness = false;
+ IsWaiting = false;
+ OrbActivated = false;
+
+ Kalec = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KALECGOS_KJ)));
+ ChangeTimers(false, 0);
+ }
+
+ void ChangeTimers(bool status, uint32 WTimer){
+ for(uint8 i = 0; i < 10;++i)
+ TimerIsDeactiveted[i] = status;
+ TimerIsDeactiveted[TIMER_KALEC_JOIN] = IsKalecJoined;
+
+ if(WTimer > 0){
+ IsWaiting = true;
+ WaitTimer = WTimer;
+ }
+
+ if(OrbActivated) TimerIsDeactiveted[TIMER_ORBS_EMPOWER] = true;
+ if(Timer[TIMER_SHADOW_SPIKE] == 0) TimerIsDeactiveted[TIMER_SHADOW_SPIKE] = true;
+ if(Phase == PHASE_SACRIFICE) TimerIsDeactiveted[TIMER_SUMMON_SHILEDORB] = true;
+ }
+
+ void JustSummoned(Creature* summoned)
+ {
+ if(summoned->GetEntry() == CREATURE_ARMAGEDDON_TARGET)
+ {
+ summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }else{
+ summoned->SetLevel(m_creature->getLevel());
+ }
+ summoned->setFaction(m_creature->getFaction());
+ Summons.Summon(summoned);
+ }
+
+ void JustDied(Unit* killer)
+ {
+ DoScriptText(SAY_KJ_DEATH, m_creature);
+
+ if(pInstance)
+ pInstance->SetData(DATA_KILJAEDEN_EVENT, DONE);
+ }
+
+ void KilledUnit(Unit* victim)
+ {
+ switch(rand()%2)
+ {
+ case 0: DoScriptText(SAY_KJ_SLAY1, m_creature); break;
+ case 1: DoScriptText(SAY_KJ_SLAY2, m_creature); break;
+ }
+ }
+
+ void EnterEvadeMode()
+ {
+ Scripted_NoMovementAI::EnterEvadeMode();
+ Summons.DespawnAll();
+
+ // Reset the controller
+ if(pInstance){
+ Creature* Control = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KILJAEDEN_CONTROLLER)));
+ if(Control)
+ ((Scripted_NoMovementAI*)Control->AI())->Reset();
+ }
+ }
+
+ void Aggro(Unit* who){
+ DoZoneInCombat();
+ DoScriptText(SAY_KJ_EMERGE, m_creature);
+ }
+
+ void CastSinisterReflection()
+ {
+ switch(rand()%2){
+ case 0: DoScriptText(SAY_KJ_REFLECTION1, m_creature); break;
+ case 1: DoScriptText(SAY_KJ_REFLECTION2, m_creature); break;
+ }
+ DoCast(m_creature, SPELL_SINISTER_REFLECTION, true);
+ for(uint8 i = 0; i < 4; i++){
+ float x,y,z;
+ Unit* target;
+ for(uint8 z = 0; z < 6; ++z){
+ target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true);
+ if (!target->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break;
+ }
+ target->GetPosition(x,y,z);
+ Creature* SinisterReflection = m_creature->SummonCreature(CREATURE_SINISTER_REFLECTION, x,y,z,0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ SinisterReflection->AI()->AttackStart(target);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!UpdateVictim() || Phase < PHASE_NORMAL)
+ return;
+
+ if(IsWaiting){
+ if(WaitTimer < diff){
+ IsWaiting = false;
+ ChangeTimers(false, 0);
+ }
+ else WaitTimer -= diff;
+ }
+
+ for(uint8 t = 0; t < ActiveTimers; ++t){
+ if(Timer[t] < diff && !TimerIsDeactiveted[t]){
+ switch(t){
+ case TIMER_KALEC_JOIN:
+ if(Kalec){
+ DoScriptText(SAY_KALECGOS_JOIN, Kalec);
+ IsKalecJoined = true;
+ TimerIsDeactiveted[TIMER_KALEC_JOIN] = true;
+ }
+ break;
+ case TIMER_SOUL_FLAY:
+ if(!m_creature->IsNonMeleeSpellCasted(false)){
+ m_creature->CastSpell(m_creature->getVictim(), SPELL_SOUL_FLAY, false);
+ m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_SOUL_FLAY_SLOW, true);
+ Timer[TIMER_SOUL_FLAY] = 3500;
+ }
+ break;
+ case TIMER_LEGION_LIGHTNING:
+ if(!m_creature->IsNonMeleeSpellCasted(false)){
+ m_creature->RemoveAurasDueToSpell(SPELL_SOUL_FLAY);
+ for(uint8 z = 0; z < 6; ++z){
+ randomPlayer = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true);
+ if (!randomPlayer->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break;
+ }
+ if(randomPlayer)DoCast(randomPlayer, SPELL_LEGION_LIGHTNING, false);
+ else error_log("try to cast SPELL_LEGION_LIGHTNING on invalid target");
+ Timer[TIMER_LEGION_LIGHTNING] = (Phase == PHASE_SACRIFICE) ? 18000 : 30000; // 18 seconds in PHASE_SACRIFICE
+ Timer[TIMER_SOUL_FLAY] = 2500;
+ }
+ break;
+ case TIMER_FIRE_BLOOM:
+ if(!m_creature->IsNonMeleeSpellCasted(false)){
+ m_creature->RemoveAurasDueToSpell(SPELL_SOUL_FLAY);
+ DoCastAOE(SPELL_FIRE_BLOOM, false);
+ Timer[TIMER_FIRE_BLOOM] = (Phase == PHASE_SACRIFICE) ? 25000 : 40000; // 25 seconds in PHASE_SACRIFICE
+ Timer[TIMER_SOUL_FLAY] = 1000;
+ }
+ break;
+ case TIMER_SUMMON_SHILEDORB:
+ for(uint8 i = 1; i < Phase; ++i){
+ float sx, sy;
+ sx = ShieldOrbLocations[0][0] + sin(ShieldOrbLocations[i][0]);
+ sy = ShieldOrbLocations[0][1] + sin(ShieldOrbLocations[i][1]);
+ m_creature->SummonCreature(CREATURE_SHIELD_ORB, sx, sy, SHIELD_ORB_Z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
+ }
+ Timer[TIMER_SUMMON_SHILEDORB] = 30000+rand()%30*1000; // 30-60seconds cooldown
+ Timer[TIMER_SOUL_FLAY] = 2000;
+ break;
+ case TIMER_SHADOW_SPIKE: //Phase 3
+ if(!m_creature->IsNonMeleeSpellCasted(false)){
+ DoCastAOE(SPELL_SHADOW_SPIKE, false);
+ Timer[TIMER_SHADOW_SPIKE] = 0;
+ TimerIsDeactiveted[TIMER_SHADOW_SPIKE] = true;
+ ChangeTimers(true, 30000);
+ }
+ break;
+ case TIMER_FLAME_DART: //Phase 3
+ DoCastAOE(SPELL_FLAME_DART, false);
+ Timer[TIMER_FLAME_DART] = 3000; //TODO Timer
+ break;
+ case TIMER_DARKNESS: //Phase 3
+ if(!m_creature->IsNonMeleeSpellCasted(false)){
+ // Begins to channel for 8 seconds, then deals 50'000 damage to all raid members.
+ if(!IsInDarkness){
+ DoScriptText(EMOTE_KJ_DARKNESS, m_creature);
+ DoCastAOE(SPELL_DARKNESS_OF_A_THOUSAND_SOULS, false);
+ ChangeTimers(true, 9000);
+ Timer[TIMER_DARKNESS] = 8750;
+ TimerIsDeactiveted[TIMER_DARKNESS] = false;
+ if(Phase == PHASE_SACRIFICE) TimerIsDeactiveted[TIMER_ARMAGEDDON] = false;
+ IsInDarkness = true;
+ }else{
+ Timer[TIMER_DARKNESS] = (Phase == PHASE_SACRIFICE) ? 20000 + rand()%15000 : 40000 + rand()%30000;
+ IsInDarkness = false;
+ DoCastAOE(SPELL_DARKNESS_OF_A_THOUSAND_SOULS_DAMAGE);
+ switch(rand()%3){
+ case 0: DoScriptText(SAY_KJ_DARKNESS1, m_creature); break;
+ case 1: DoScriptText(SAY_KJ_DARKNESS2, m_creature); break;
+ case 2: DoScriptText(SAY_KJ_DARKNESS3, m_creature); break;
+ }
+ }
+ Timer[TIMER_SOUL_FLAY] = 9000;
+ }
+ break;
+ case TIMER_ORBS_EMPOWER: //Phase 3
+ if(Phase == PHASE_SACRIFICE){
+ if(Kalec)((boss_kalecgosKJAI*)Kalec->AI())->EmpowerOrb(true);
+ }else if(Kalec)((boss_kalecgosKJAI*)Kalec->AI())->EmpowerOrb(false);
+ Timer[TIMER_ORBS_EMPOWER]= (Phase == PHASE_SACRIFICE) ? 45000 : 35000;
+ OrbActivated = true;
+ TimerIsDeactiveted[TIMER_ORBS_EMPOWER] = true;
+ break;
+ case TIMER_ARMAGEDDON: //Phase 4
+ Unit* target;
+ for(uint8 z = 0; z < 6; ++z){
+ target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true);
+ if (!target->HasAura(SPELL_VENGEANCE_OF_THE_BLUE_FLIGHT,0)) break;
+ }
+ if(target){
+ float x, y, z;
+ target->GetPosition(x, y, z);
+ m_creature->SummonCreature(CREATURE_ARMAGEDDON_TARGET, x,y,z,0, TEMPSUMMON_TIMED_DESPAWN,15000);
+ }
+ Timer[TIMER_ARMAGEDDON] = 2000; // No, I'm not kidding
+ break;
+ }
+ break;
+ }
+ }
+ //Time runs over!
+ for(uint8 i = 0; i < ActiveTimers; ++i)
+ if(!TimerIsDeactiveted[i]){
+ Timer[i] -= diff;
+ if(((int32)Timer[i]) < 0) Timer[i] = 0;
+ }
+
+ //Phase 3
+ if(Phase <= PHASE_NORMAL){
+ if(Phase == PHASE_NORMAL && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 85)){
+ CastSinisterReflection();
+ DoScriptText(SAY_KJ_PHASE3, m_creature);
+ Phase = PHASE_DARKNESS;
+ OrbActivated = false;
+ ActiveTimers = 9;
+ }
+ else return;
+ }
+
+ //Phase 4
+ if(Phase <= PHASE_DARKNESS){
+ if(Phase == PHASE_DARKNESS && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 55)){
+ DoScriptText(SAY_KJ_PHASE4, m_creature);
+ Phase = PHASE_ARMAGEDDON;
+ OrbActivated = false;
+ ActiveTimers = 10;
+ }
+ else return;
+ }
+
+ //Phase 5 specific spells all we can
+ if(Phase <= PHASE_ARMAGEDDON){
+ if(Phase == PHASE_ARMAGEDDON && ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 25)){
+ Phase = PHASE_SACRIFICE;
+ Creature* Anveena = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_ANVEENA)));
+ if (Anveena)Anveena->CastSpell(m_creature, SPELL_SACRIFICE_OF_ANVEENA, false);
+ OrbActivated = false;
+ ChangeTimers(true, 10000);// He shouldn't cast spells for ~10 seconds after Anveena's sacrifice. This will be done within Anveena's script
+ }
+ else return;
+ }
+
+}
+};
+
+CreatureAI* GetAI_boss_kiljaeden(Creature *_Creature)
+{
+ return new boss_kiljaedenAI (_Creature);
+}
+
+//AI for Kil'jaeden Event Controller
+struct TRINITY_DLL_DECL mob_kiljaeden_controllerAI : public Scripted_NoMovementAI
+{
+ mob_kiljaeden_controllerAI(Creature* c) : Scripted_NoMovementAI(c), Summons(m_creature){
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ }
+
+ ScriptedInstance* pInstance;
+ Creature* KalecKJ;
+ SummonList Summons;
+
+ bool SummonedDeceivers;
+ bool KiljaedenDeath;
+
+ uint32 RandomSayTimer;
+ uint32 Phase;
+ uint8 DeceiverDeathCount;
+
+ void InitializeAI(){
+ KalecKJ = Unit::GetCreature((*m_creature), pInstance->GetData64(DATA_KALECGOS_KJ));
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->addUnitState(UNIT_STAT_STUNNED);
+ }
+
+ void Reset(){
+ Phase = PHASE_DECEIVERS;
+ if(KalecKJ)((boss_kalecgosKJAI*)KalecKJ->AI())->ResetOrbs();
+ DeceiverDeathCount = 0;
+ SummonedDeceivers = false;
+ KiljaedenDeath = false;
+ RandomSayTimer = 30000;
+ Summons.DespawnAll();
+ }
+
+ void JustSummoned(Creature* summoned){
+ switch(summoned->GetEntry()){
+ case CREATURE_HAND_OF_THE_DECEIVER:
+ summoned->CastSpell(summoned, SPELL_SHADOW_CHANNELING, false);
+ break;
+ case CREATURE_ANVEENA:
+ summoned->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ summoned->CastSpell(summoned, SPELL_ANVEENA_PRISON, true);
+ summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ break;
+ case CREATURE_KILJAEDEN:
+ summoned->CastSpell(summoned, SPELL_REBIRTH, false);
+ ((boss_kiljaedenAI*)summoned->AI())->Phase=PHASE_NORMAL;
+ summoned->AddThreat(m_creature->getVictim(), 1.0f);
+ break;
+ }
+ Summons.Summon(summoned);
+ }
+
+ void Aggro(Unit* who) {}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(RandomSayTimer < diff && pInstance->GetData(DATA_MURU_EVENT) != DONE && pInstance->GetData(DATA_KILJAEDEN_EVENT) == NOT_STARTED){
+ switch(rand()%5){
+ case 0: DoScriptText(SAY_KJ_OFFCOMBAT1, m_creature); break;
+ case 1: DoScriptText(SAY_KJ_OFFCOMBAT2, m_creature); break;
+ case 2: DoScriptText(SAY_KJ_OFFCOMBAT3, m_creature); break;
+ case 3: DoScriptText(SAY_KJ_OFFCOMBAT4, m_creature); break;
+ case 4: DoScriptText(SAY_KJ_OFFCOMBAT5, m_creature); break;
+ }
+ RandomSayTimer = 30000;
+ }else RandomSayTimer -= diff;
+
+ if(!SummonedDeceivers){
+ for(uint8 i = 0; i < 3; ++i)
+ m_creature->SummonCreature(CREATURE_HAND_OF_THE_DECEIVER, DeceiverLocations[i][0], DeceiverLocations[i][1], FLOOR_Z, DeceiverLocations[i][2], TEMPSUMMON_DEAD_DESPAWN, 0);
+
+ DoSpawnCreature(CREATURE_ANVEENA, 0, 0, 40, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
+ DoCast(m_creature, SPELL_ANVEENA_ENERGY_DRAIN);
+ SummonedDeceivers = true;
+ }
+
+ if(DeceiverDeathCount > 2 && Phase == PHASE_DECEIVERS){
+ m_creature->RemoveAurasDueToSpell(SPELL_ANVEENA_ENERGY_DRAIN) ;
+ Phase = PHASE_NORMAL;
+ DoSpawnCreature(CREATURE_KILJAEDEN, 0, 0,0, 0, TEMPSUMMON_MANUAL_DESPAWN, 0);
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_kiljaeden_controller(Creature *_Creature)
+{
+ return new mob_kiljaeden_controllerAI (_Creature);
+}
+
+//AI for Hand of the Deceiver
+struct TRINITY_DLL_DECL mob_hand_of_the_deceiverAI : public ScriptedAI
+{
+ mob_hand_of_the_deceiverAI(Creature* c) : ScriptedAI(c){
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ }
+ ScriptedInstance* pInstance;
+
+ uint32 ShadowBoltVolleyTimer;
+ uint32 FelfirePortalTimer;
+
+ void Reset(){
+ // TODO: Timers!
+ ShadowBoltVolleyTimer = 8000 + rand()%6000; // So they don't all cast it in the same moment.
+ FelfirePortalTimer = 20000;
+ if(pInstance)pInstance->SetData(DATA_KILJAEDEN_EVENT, NOT_STARTED);
+ }
+
+ void JustSummoned(Creature* summoned){
+ summoned->setFaction(m_creature->getFaction());
+ summoned->SetLevel(m_creature->getLevel());
+ }
+
+ void Aggro(Unit* who){
+ if(pInstance){
+ pInstance->SetData(DATA_KILJAEDEN_EVENT, IN_PROGRESS);
+ Creature* Control = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KILJAEDEN_CONTROLLER)));
+ if(Control)
+ Control->AddThreat(who, 1.0f);
+ }
+ m_creature->InterruptNonMeleeSpells(true);
+ }
+
+ void JustDied(Unit* killer){
+ if(!pInstance)
+ return;
+
+ Creature* Control = ((Creature*)Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_KILJAEDEN_CONTROLLER)));
+ if(Control)
+ ((mob_kiljaeden_controllerAI*)Control->AI())->DeceiverDeathCount++;
+ }
+
+ void UpdateAI(const uint32 diff){
+ if(!InCombat)
+ DoCast(m_creature, SPELL_SHADOW_CHANNELING);
+
+ if(!UpdateVictim())
+ return;
+
+ // Gain Shadow Infusion at 20% health
+ if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20) && !m_creature->HasAura(SPELL_SHADOW_INFUSION, 0))
+ DoCast(m_creature, SPELL_SHADOW_INFUSION, true);
+
+ // Shadow Bolt Volley - Shoots Shadow Bolts at all enemies within 30 yards, for ~2k Shadow damage.
+ if(ShadowBoltVolleyTimer < diff){
+ DoCast(m_creature->getVictim(), SPELL_SHADOW_BOLT_VOLLEY);
+ ShadowBoltVolleyTimer = 12000;
+ }else ShadowBoltVolleyTimer -= diff;
+
+ // Felfire Portal - Creatres a portal, that spawns Volatile Felfire Fiends, which do suicide bombing.
+ if(FelfirePortalTimer < diff){
+ Creature* Portal = DoSpawnCreature(CREATURE_FELFIRE_PORTAL, 0, 0,0, 0, TEMPSUMMON_TIMED_DESPAWN, 20000);
+ if(Portal)
+ {
+ std::list<HostilReference*>::iterator itr;
+ for(itr = m_creature->getThreatManager().getThreatList().begin(); itr != m_creature->getThreatManager().getThreatList().end(); ++itr)
+ {
+ Unit* pUnit = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
+ if(pUnit)
+ Portal->AddThreat(pUnit, 1.0f);
+ }
+ }
+ FelfirePortalTimer = 20000;
+ }else FelfirePortalTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
+
+CreatureAI* GetAI_mob_hand_of_the_deceiver(Creature *_Creature)
+{
+ return new mob_hand_of_the_deceiverAI (_Creature);
+}
+
+//AI for Felfire Portal
+struct TRINITY_DLL_DECL mob_felfire_portalAI : public Scripted_NoMovementAI
+{
+ mob_felfire_portalAI(Creature* c) : Scripted_NoMovementAI(c) {}
+
+ uint32 SpawnFiendTimer;
+
+ void InitializeAI(){
+ SpawnFiendTimer = 5000;
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ // TODO: Timers
+ void Reset() {
+
+ }
+
+ void Aggro(Unit* who) {}
+
+ void JustSummoned(Creature* summoned)
+ {
+ summoned->setFaction(m_creature->getFaction());
+ summoned->SetLevel(m_creature->getLevel());
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!UpdateVictim())
+ return;
+
+ if(SpawnFiendTimer < diff)
+ {
+ Creature* Fiend = DoSpawnCreature(CREATURE_VOLATILE_FELFIRE_FIEND, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000);
+ if(Fiend)
+ Fiend->AddThreat(SelectUnit(SELECT_TARGET_RANDOM,0), 100000.0f);
+ SpawnFiendTimer = 4000 + rand()%4000;
+ }else SpawnFiendTimer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_felfire_portal(Creature *_Creature)
+{
+ return new mob_felfire_portalAI (_Creature);
+}
+
+//AI for Felfire Fiend
+struct TRINITY_DLL_DECL mob_volatile_felfire_fiendAI : public ScriptedAI
+{
+ mob_volatile_felfire_fiendAI(Creature* c) : ScriptedAI(c) {}
+
+ uint32 ExplodeTimer;
+
+ bool LockedTarget;
+
+ void Reset()
+ {
+ ExplodeTimer = 2000;
+ LockedTarget = false;
+ }
+
+ void Aggro(Unit* who) {}
+
+ void DamageTaken(Unit *done_by, uint32 &damage)
+ {
+ if(damage > m_creature->GetHealth())
+ DoCast(m_creature, SPELL_FELFIRE_FISSION, true);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!UpdateVictim())
+ return;
+
+ if(!LockedTarget){
+ m_creature->AddThreat(m_creature->getVictim(), 10000000.0f);
+ LockedTarget = true;
+ }
+
+ if(ExplodeTimer){
+ if(ExplodeTimer < diff)
+ ExplodeTimer = 0;
+ else ExplodeTimer -= diff;
+ }
+ else if(m_creature->IsWithinDistInMap(m_creature->getVictim(), 3)) // Explode if it's close enough to it's target
+ {
+ DoCast(m_creature->getVictim(), SPELL_FELFIRE_FISSION);
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+};
+
+CreatureAI* GetAI_mob_volatile_felfire_fiend(Creature *_Creature)
+{
+ return new mob_volatile_felfire_fiendAI (_Creature);
+}
+
+//AI for Armageddon target
+struct TRINITY_DLL_DECL mob_armageddonAI : public Scripted_NoMovementAI
+{
+ mob_armageddonAI(Creature* c) : Scripted_NoMovementAI(c) {}
+
+ uint8 Spell;
+ uint32 Timer;
+
+ void Reset(){
+ Spell = 0;
+ Timer = 0;
+ }
+
+ void Aggro(Unit* who){}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(Timer < diff){
+ switch(Spell){
+ case 0:
+ DoCast(m_creature, SPELL_ARMAGEDDON_VISUAL, true);
+ ++Spell;
+ break;
+ case 1:
+ DoCast(m_creature, SPELL_ARMAGEDDON_VISUAL2, true);
+ Timer = 9000;
+ ++Spell;
+ break;
+ case 2:
+ DoCast(m_creature, SPELL_ARMAGEDDON_TRIGGER, true);
+ ++Spell;
+ Timer = 5000;
+ break;
+ case 3:
+ m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ m_creature->RemoveCorpse();
+ break;
+ }
+ }else Timer -=diff;
+ }
+};
+
+CreatureAI* GetAI_mob_armageddon(Creature *_Creature)
+{
+ return new mob_armageddonAI (_Creature);
+}
+
+//AI for Shield Orbs
+struct TRINITY_DLL_DECL mob_shield_orbAI : public ScriptedAI
+{
+ mob_shield_orbAI(Creature* c) : ScriptedAI(c) {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ }
+
+ bool PointReached;
+ bool Clockwise;
+ uint32 Timer;
+ uint32 CheckTimer;
+ ScriptedInstance* pInstance;
+ float x, y, r, c, mx, my;
+
+ void InitializeAI(){
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING);
+ PointReached = true;
+ Timer = 500+ rand()%500;
+ CheckTimer = 1000;
+ r = 17;
+ c = 0;
+ mx = ShieldOrbLocations[0][0];
+ my = ShieldOrbLocations[0][1];
+ if(rand()%2 == 0)Clockwise = true;
+ else Clockwise = false;
+ }
+
+ void Reset(){
+ }
+
+ void Aggro(Unit* who){}
+
+ void UpdateAI(const uint32 diff){
+ if(PointReached){
+ if(Clockwise){
+ y = my - r * sin(c);
+ x = mx - r * cos(c);
+ }else{
+ y = my + r * sin(c);
+ x = mx + r * cos(c);
+ }
+ PointReached = false;
+ CheckTimer = 1000;
+ m_creature->GetMotionMaster()->MovePoint(1,x, y, SHIELD_ORB_Z);
+ c += 3.1415926535/32;
+ if(c > 2*3.1415926535) c = 0;
+ }else{
+ if (CheckTimer < diff){
+ DoTeleportTo(x,y,SHIELD_ORB_Z);
+ PointReached = true;
+ }else CheckTimer -= diff;
+
+ }
+
+ if (Timer < diff){
+ Unit* random = (Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_PLAYER_GUID)));
+ if (random)DoCast(random, SPELL_SHADOW_BOLT, false);
+ Timer = 500+ rand()%500;
+ }else Timer -= diff;
+ }
+
+ void MovementInform(uint32 type, uint32 id){
+ if(type != POINT_MOTION_TYPE)
+ return;
+
+ PointReached = true;
+ }
+};
+
+CreatureAI* GetAI_mob_shield_orb(Creature *_Creature)
+{
+ return new mob_shield_orbAI (_Creature);
+}
+
+//AI for Sinister Reflection
+struct TRINITY_DLL_DECL mob_sinster_reflectionAI : public ScriptedAI
+{
+ mob_sinster_reflectionAI(Creature* c) : ScriptedAI(c) {}
+
+ uint8 Class;
+ uint32 Timer[3];
+
+ void Reset(){
+ Timer[0] = 0;
+ Timer[1] = 0;
+ Timer[2] = 0;
+ Class = 0;
+ }
+
+ void Aggro(Unit* who){}
+
+ void UpdateAI(const uint32 diff){
+
+ if(Class == 0){
+ Class = m_creature->getVictim()->getClass();
+ switch(Class){
+ case CLASS_DRUID:
+ break;
+ case CLASS_HUNTER:
+ break;
+ case CLASS_MAGE:
+ break;
+ case CLASS_WARLOCK:
+ break;
+ case CLASS_WARRIOR:
+ m_creature->SetCanDualWield(true);
+ break;
+ case CLASS_PALADIN:
+ break;
+ case CLASS_PRIEST:
+ break;
+ case CLASS_SHAMAN:
+ m_creature->SetCanDualWield(true);
+ break;
+ case CLASS_ROGUE:
+ m_creature->SetCanDualWield(true);
+ break;
+ }
+ }
+
+ switch(Class){
+ case CLASS_DRUID:
+ if(Timer[1] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_MOONFIRE, false);
+ Timer[1] = 3000;
+ }
+ DoMeleeAttackIfReady();
+ break;
+ case CLASS_HUNTER:
+ if(Timer[1] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_MULTI_SHOT, false);
+ Timer[1] = 9000;
+ }
+ if(Timer[2] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_SHOOT, false);
+ Timer[2] = 5000;
+ }
+ if(m_creature->IsWithinMeleeRange(m_creature->getVictim(), 6)){
+ if(Timer[3] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_MULTI_SHOT, false);
+ Timer[3] = 7000;
+ }
+ DoMeleeAttackIfReady();
+ }
+ break;
+ case CLASS_MAGE:
+ if(Timer[1] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_FIREBALL, false);
+ Timer[1] = 3000;
+ }
+ DoMeleeAttackIfReady();
+ break;
+ case CLASS_WARLOCK:
+ if(Timer[1] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_SHADOW_BOLT, false);
+ Timer[1] = 4000;
+ }
+ if(Timer[2] < diff){
+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_SR_CURSE_OF_AGONY, true);
+ Timer[2] = 3000;
+ }
+ DoMeleeAttackIfReady();
+ break;
+ case CLASS_WARRIOR:
+ if(Timer[1] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_WHIRLWIND, false);
+ Timer[1] = 10000;
+ }
+ DoMeleeAttackIfReady();
+ break;
+ case CLASS_PALADIN:
+ if(Timer[1] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_HAMMER_OF_JUSTICE, false);
+ Timer[1] = 7000;
+ }
+ if(Timer[2] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_HOLY_SHOCK, false);
+ Timer[2] = 3000;
+ }
+ DoMeleeAttackIfReady();
+ break;
+ case CLASS_PRIEST:
+ if(Timer[1] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_HOLY_SMITE, false);
+ Timer[1] = 5000;
+ }
+ if(Timer[2] < diff){
+ DoCast(m_creature, SPELL_SR_RENEW, false);
+ Timer[2] = 7000;
+ }
+ DoMeleeAttackIfReady();
+ break;
+ case CLASS_SHAMAN:
+ if(Timer[1] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_EARTH_SHOCK, false);
+ Timer[1] = 5000;
+ }
+ DoMeleeAttackIfReady();
+ break;
+ case CLASS_ROGUE:
+ if(Timer[1] < diff){
+ DoCast(m_creature->getVictim(), SPELL_SR_HEMORRHAGE, true);
+ Timer[1] = 5000;
+ }
+ DoMeleeAttackIfReady();
+ break;
+ }
+ debug_log("Sinister-Timer");
+ for(uint8 i = 0; i < 3; ++i)
+ Timer[i] -= diff;
+ }
+
+};
+
+CreatureAI* GetAI_mob_sinster_reflection(Creature *_Creature)
+{
+ return new mob_sinster_reflectionAI (_Creature);
+}
void AddSC_boss_kiljaeden()
-{};
+{
+ Script* newscript;
+
+ newscript = new Script;
+ newscript->pGOHello = &GOHello_go_orb_of_the_blue_flight;
+ newscript->Name = "go_orb_of_the_blue_flight";
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->GetAI = &GetAI_boss_kalecgosKJ;
+ newscript->Name = "boss_kalecgosKJ";
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->GetAI = &GetAI_boss_kiljaeden;
+ newscript->Name = "boss_kiljaeden";
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->GetAI = &GetAI_mob_kiljaeden_controller;
+ newscript->Name = "mob_kiljaeden_controller";
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->GetAI = &GetAI_mob_hand_of_the_deceiver;
+ newscript->Name = "mob_hand_of_the_deceiver";
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->GetAI = &GetAI_mob_felfire_portal;
+ newscript->Name = "mob_felfire_portal";
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->GetAI = &GetAI_mob_volatile_felfire_fiend;
+ newscript->Name = "mob_volatile_felfire_fiend";
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->GetAI = &GetAI_mob_armageddon;
+ newscript->Name = "mob_armageddon";
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->GetAI = &GetAI_mob_shield_orb;
+ newscript->Name = "mob_shield_orb";
+ newscript->RegisterSelf();
+
+ newscript = new Script;
+ newscript->GetAI = &GetAI_mob_sinster_reflection;
+ newscript->Name = "mob_sinster_reflection";
+ newscript->RegisterSelf();
+};