aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/Makefile.am1
-rw-r--r--src/bindings/scripts/ScriptMgr.cpp16
-rw-r--r--src/bindings/scripts/VC71/71ScriptDev2.vcproj4
-rw-r--r--src/bindings/scripts/VC80/80ScriptDev2.vcproj4
-rw-r--r--src/bindings/scripts/VC90/90ScriptDev2.vcproj4
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp496
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h1
-rw-r--r--src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp2
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp600
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h10
-rw-r--r--src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp296
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp532
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h1
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp18
-rw-r--r--src/bindings/scripts/sql/Updates/r86_trinity.sql6
15 files changed, 1505 insertions, 486 deletions
diff --git a/src/bindings/scripts/Makefile.am b/src/bindings/scripts/Makefile.am
index feedd0e65d0..bb4b690e0ef 100644
--- a/src/bindings/scripts/Makefile.am
+++ b/src/bindings/scripts/Makefile.am
@@ -337,6 +337,7 @@ scripts/zone/tempest_keep/arcatraz/instance_arcatraz.cpp \
scripts/zone/tempest_keep/botanica/boss_high_botanist_freywinn.cpp \
scripts/zone/tempest_keep/botanica/boss_laj.cpp \
scripts/zone/tempest_keep/botanica/boss_warp_splinter.cpp \
+scripts/zone/tempest_keep/the_eye/boss_alar.cpp \
scripts/zone/tempest_keep/the_eye/boss_astromancer.cpp \
scripts/zone/tempest_keep/the_eye/boss_kaelthas.cpp \
scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp \
diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp
index bef021af6f5..5502304c093 100644
--- a/src/bindings/scripts/ScriptMgr.cpp
+++ b/src/bindings/scripts/ScriptMgr.cpp
@@ -495,6 +495,13 @@ extern void AddSC_instance_stratholme();
extern void AddSC_stratholme();
//Sunken Temple
+//Sunwell Plateau
+extern void AddSC_instance_sunwell_plateau();
+extern void AddSC_boss_kalecgos();
+extern void AddSC_boss_brutallus();
+extern void AddSC_boss_felmyst();
+extern void AddSC_boss_eredar_twins();
+
//Tanaris
extern void AddSC_tanaris();
@@ -511,6 +518,7 @@ extern void AddSC_boss_laj();
extern void AddSC_boss_warp_splinter();
//--The Eye
+extern void AddSC_boss_alar();
extern void AddSC_boss_kaelthas();
extern void AddSC_boss_void_reaver();
extern void AddSC_boss_high_astromancer_solarian();
@@ -1677,6 +1685,13 @@ void ScriptsInit()
AddSC_stratholme();
//Sunken Temple
+ //Sunwell Plateau
+ AddSC_instance_sunwell_plateau();
+ AddSC_boss_kalecgos();
+ AddSC_boss_brutallus();
+ AddSC_boss_felmyst();
+ AddSC_boss_eredar_twins();
+
//Tanaris
AddSC_tanaris();
@@ -1693,6 +1708,7 @@ void ScriptsInit()
AddSC_boss_warp_splinter();
//--The Eye
+ AddSC_boss_alar();
AddSC_boss_kaelthas();
AddSC_boss_void_reaver();
AddSC_boss_high_astromancer_solarian();
diff --git a/src/bindings/scripts/VC71/71ScriptDev2.vcproj b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
index e08a134fc01..b6f5ae6b95b 100644
--- a/src/bindings/scripts/VC71/71ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
@@ -1521,6 +1521,10 @@
Name="The Eye"
>
<File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_alar.cpp"
+ >
+ </File>
+ <File
RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_astromancer.cpp"
>
</File>
diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
index 3bbd3c61cd6..384fb89f0b4 100644
--- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
@@ -1754,6 +1754,10 @@
Name="The Eye"
>
<File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_alar.cpp"
+ >
+ </File>
+ <File
RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_astromancer.cpp"
>
</File>
diff --git a/src/bindings/scripts/VC90/90ScriptDev2.vcproj b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
index 9b65ba06917..cd654ea6a50 100644
--- a/src/bindings/scripts/VC90/90ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
@@ -1752,6 +1752,10 @@
Name="The Eye"
>
<File
+ RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_alar.cpp"
+ >
+ </File>
+ <File
RelativePath="..\scripts\zone\tempest_keep\the_eye\boss_astromancer.cpp"
>
</File>
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp
index abee7b5f7aa..cdea78ce916 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp
@@ -16,272 +16,387 @@
/* ScriptData
SDName: Boss_Grandmaster_Vorpil
-SD%Complete: 75
-SDComment: Despawn all summoned on death not implemented. Void Traveler effects not implemented.
+SD%Complete: 100
+SDComment:
SDCategory: Auchindoun, Shadow Labyrinth
EndScriptData */
#include "precompiled.h"
#include "def_shadow_labyrinth.h"
-#define SPELL_DRAW_SHADOWS 33563
-#define SPELL_VOID_PORTAL_A 33566 //spell only summon one unit, but we use it for the visual effect and summon the 4 other portals manual way(only one spell exist)
-#define SPELL_VOID_PORTAL_VISUAL 33569
-#define SPELL_SHADOW_BOLT_VOLLEY 32963
-#define SPELL_SUMMON_VOIDWALKER_A 33582
-#define SPELL_SUMMON_VOIDWALKER_B 33583
-#define SPELL_SUMMON_VOIDWALKER_C 33584
-#define SPELL_SUMMON_VOIDWALKER_D 33585
-#define SPELL_SUMMON_VOIDWALKER_E 33586
-#define SPELL_RAIN_OF_FIRE 33617
-#define H_SPELL_RAIN_OF_FIRE 39363
-#define H_SPELL_BANISH 38791
-
-#define SAY_INTRO "Keep your minds focused for the days of reckoning are close at hand. Soon, the destroyer of worlds will return to make good on his promise. Soon the destruction of all that is will begin!"
-#define SAY_AGGRO1 "I'll make an offering of your blood!"
-#define SAY_AGGRO2 "You'll be a fine example, for the others."
-#define SAY_AGGRO3 "Good, a worthy sacrifice."
-#define SAY_HELP "Come to my aid, heed your master now!"
-#define SAY_SLAY1 "I serve with pride."
-#define SAY_SLAY2 "Your death is for the greater cause!"
-#define SAY_DEATH "I give my life... Gladly."
-
-#define SOUND_INTRO 10522
-#define SOUND_AGGRO1 10524
-#define SOUND_AGGRO2 10525
-#define SOUND_AGGRO3 10526
-#define SOUND_HELP 10523
-#define SOUND_SLAY1 10527
-#define SOUND_SLAY2 10528
-#define SOUND_DEATH 10529
-
-#define ENTRY_VOID_PORTAL 19224
-#define ENTRY_VOID_TRAVELER 19226
-
-#define LOCX -253.06f
-#define LOCY -264.02f
-#define LOCZ 17.08
+#define SAY_INTRO "Keep your minds focused for the days of reckoning are close at hand. Soon, the destroyer of worlds will return to make good on his promise. Soon the destruction of all that is will begin!"
+#define SAY_AGGRO1 "I'll make an offering of your blood!"
+#define SAY_AGGRO2 "You'll be a fine example, for the others."
+#define SAY_AGGRO3 "Good, a worthy sacrifice."
+#define SAY_HELP "Come to my aid, heed your master now!"
+#define SAY_SLAY1 "I serve with pride."
+#define SAY_SLAY2 "Your death is for the greater cause!"
+#define SAY_DEATH "I give my life... Gladly."
+
+#define SOUND_INTRO 10522
+#define SOUND_AGGRO1 10524
+#define SOUND_AGGRO2 10525
+#define SOUND_AGGRO3 10526
+#define SOUND_HELP 10523
+#define SOUND_SLAY1 10527
+#define SOUND_SLAY2 10528
+#define SOUND_DEATH 10529
+
+#define SPELL_RAIN_OF_FIRE 33617
+#define H_SPELL_RAIN_OF_FIRE 39363
+
+#define SPELL_DRAWN_SHADOWS 33563
+#define SPELL_SHADOWBOLT_VOLLEY 33841
+
+#define MOB_VOID_TRAVELER 19226
+#define SPELL_SACRIFICE 33587
+#define SPELL_SHADOW_NOVA 33846
+#define SPELL_HEALVORPIL 33783
+#define H_SPELL_HEALVORPIL 39364
+
+#define MOB_VOID_PORTAL 19224
+#define SPELL_VOID_PORTAL_VISUAL 33569
+
+float VorpilPosition[1][3] =
+{
+ {-252.8820,-264.3030,17.1}
+};
+
+float VoidPortalCoords[5][3] =
+{
+ {-283.5894, -239.5718, 12.7},
+ {-306.5853, -258.4539, 12.7},
+ {-295.8789, -269.0899, 12.7},
+ {-209.3401, -262.7564, 17.1},
+ {-261.4533, -297.3298, 17.1}
+};
struct TRINITY_DLL_DECL boss_grandmaster_vorpilAI : public ScriptedAI
{
boss_grandmaster_vorpilAI(Creature *c) : ScriptedAI(c)
{
pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ Intro = false;
Reset();
}
- ScriptedInstance* pInstance;
+ ScriptedInstance *pInstance;
+ bool Intro;
+ bool sumportals;
bool HeroicMode;
-
+
uint32 ShadowBoltVolley_Timer;
- uint32 DrawShadows_Timer;
- uint32 Teleport_Timer;
- uint32 VoidTraveler_Timer;
- uint32 Banish_Timer;
- bool Intro;
- bool Teleport;
+ uint32 DrawnShadows_Timer;
+ uint32 sumportals_Timer;
+ uint32 summonTraveler_Timer;
+ uint64 PortalsGuid[5];
+
+ void summonPortals()
+ {
+ for (int i = 0;i<5;i++)
+ {
+ Creature *Portal = NULL;
+ Portal = m_creature->SummonCreature(MOB_VOID_PORTAL,VoidPortalCoords[i][0],VoidPortalCoords[i][1],VoidPortalCoords[i][2],0,TEMPSUMMON_CORPSE_DESPAWN,3000000);
+ PortalsGuid[i] = Portal->GetGUID();
+ Portal->CastSpell(Portal,SPELL_VOID_PORTAL_VISUAL,false);
+ }
+ sumportals = true;
+ summonTraveler_Timer = 5000;
+ }
+
+ void destroyPortals()
+ {
+ for (int i = 0;i < 5; i ++)
+ {
+ Unit *Portal = Unit::GetUnit((*m_creature), PortalsGuid[i]);
+ if (Portal)
+ if (Portal->isAlive())
+ Portal->DealDamage(Portal, Portal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ PortalsGuid[i] = 0;
+ }
+ }
+
+ void spawnVoidTraveler()
+ {
+ srand( (unsigned) time(NULL) ) ;
+ int pos = rand()%5;
+ Creature *traveler;
+ traveler = m_creature->SummonCreature(MOB_VOID_TRAVELER,VoidPortalCoords[pos][0],VoidPortalCoords[pos][1],VoidPortalCoords[pos][2],0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000);
+ }
void Reset()
{
HeroicMode = m_creature->GetMap()->IsHeroic();
+ if( HeroicMode )
+ debug_log("SD2: creature %u is in heroic mode",m_creature->GetEntry());
ShadowBoltVolley_Timer = 15000;
- DrawShadows_Timer = 40000;
- Teleport_Timer = 1000;
- VoidTraveler_Timer = 20000;
- Banish_Timer = 25000;
- Intro = false;
- Teleport = false;
+ DrawnShadows_Timer = 45000;
+ sumportals_Timer = 10000;
+ summonTraveler_Timer = 90000;
- if( pInstance )
+ InCombat = false;
+ sumportals = false;
+ destroyPortals();
+
+ if(pInstance)
pInstance->SetData(DATA_GRANDMASTERVORPILEVENT, NOT_STARTED);
}
- void MoveInLineOfSight(Unit *who)
+ void KilledUnit(Unit *victim)
{
- if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) )
+ switch(rand()%2)
{
- //not sure about right radius
- if(!Intro && m_creature->IsWithinDistInMap(who, 50))
- {
- DoYell(SAY_INTRO, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_INTRO);
- DoCast(m_creature, SPELL_VOID_PORTAL_A,true);
- m_creature->SummonCreature(ENTRY_VOID_PORTAL,-262.40,-229.57,17.08,0,TEMPSUMMON_CORPSE_DESPAWN,0);
- m_creature->SummonCreature(ENTRY_VOID_PORTAL,-260.35,-297.56,17.08,0,TEMPSUMMON_CORPSE_DESPAWN,0);
- m_creature->SummonCreature(ENTRY_VOID_PORTAL,-292.05,-270.37,12.68,0,TEMPSUMMON_CORPSE_DESPAWN,0);
- m_creature->SummonCreature(ENTRY_VOID_PORTAL,-301.64,-255.97,12.68,0,TEMPSUMMON_CORPSE_DESPAWN,0);
- Intro = true;
- }
-
- if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE)
- return;
-
- float attackRadius = m_creature->GetAttackDistance(who);
- if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) )
- {
- DoStartAttackAndMovement(who);
- who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
+ case 0:
+ DoYell(SAY_SLAY1, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_SLAY1);
+ break;
- if (!InCombat)
- {
- InCombat = true;
- Aggro(who);
- }
- }
+ case 1:
+ DoYell(SAY_SLAY2, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_SLAY2);
+ break;
}
}
- void Aggro(Unit *who)
+ void JustDied(Unit *victim)
+ {
+ DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_DEATH);
+ destroyPortals();
+ if(pInstance)
+ pInstance->SetData(DATA_GRANDMASTERVORPILEVENT, DONE);
+ }
+
+ void StartEvent()
{
switch(rand()%3)
{
case 0:
- DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_AGGRO1);
- break;
+ DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_AGGRO1);
+ break;
+
case 1:
- DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_AGGRO2);
- break;
+ DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_AGGRO2);
+ break;
+
case 2:
- DoYell(SAY_AGGRO3, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_AGGRO3);
- break;
+ DoYell(SAY_AGGRO3, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_AGGRO3);
+ break;
}
- if( pInstance )
+ if(pInstance)
pInstance->SetData(DATA_GRANDMASTERVORPILEVENT, IN_PROGRESS);
}
- void KilledUnit(Unit *victim)
+ void Aggro(Unit *who)
{
- switch(rand()%2)
- {
- case 0:
- DoYell(SAY_SLAY1, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_SLAY1);
- break;
- case 1:
- DoYell(SAY_SLAY2, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_SLAY2);
- break;
+ if(!InCombat)
+ {
+ InCombat = true;
+ StartEvent();
}
}
- void JustSummoned(Creature *summoned)
+ void MoveInLineOfSight(Unit *who)
{
- if( summoned->GetEntry() == ENTRY_VOID_TRAVELER )
- {
- summoned->GetMotionMaster()->MoveChase(m_creature);
- summoned->SetSpeed(MOVE_WALK,0.8,true);
- }
+ if (!who || m_creature->getVictim())
+ return;
- if( summoned->GetEntry() == ENTRY_VOID_PORTAL )
- summoned->CastSpell(summoned,SPELL_VOID_PORTAL_VISUAL,true);
- }
+ if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
+ {
+ float attackRadius = m_creature->GetAttackDistance(who);
+ if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
+ {
+ if(who->HasStealthAura())
+ who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
- void JustDied(Unit *victim)
- {
- DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_DEATH);
+ DoStartAttackAndMovement(who);
+ Aggro(who);
+ }
+ }
+ else if (!Intro && m_creature->IsWithinLOSInMap(who)&& m_creature->IsWithinDistInMap(who, 100) ) //not sure about right radius
+ {
+ DoYell(SAY_INTRO, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_INTRO);
+ Intro = true;
+ }
- if( pInstance )
- pInstance->SetData(DATA_GRANDMASTERVORPILEVENT, DONE);
}
-
+
void UpdateAI(const uint32 diff)
{
- //Return since we have no target
- if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
- return;
- if( Teleport )
+ if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ return;
+
+ if (!sumportals)
+ if (sumportals_Timer < diff)
{
- if( Teleport_Timer <= diff )
- {
- m_creature->Relocate(LOCX,LOCY,LOCZ);
- m_creature->SendMonsterMove(LOCX,LOCY,LOCZ,0,true,0);
+ DoYell(SAY_HELP, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_HELP);
+ summonPortals();
+ sumportals_Timer = 1000000;
+
+ }else sumportals_Timer -= diff;
- float ranX = LOCX;
- float ranY = LOCY;
- float ranZ = LOCZ;
+ if (ShadowBoltVolley_Timer < diff)
+ {
+ DoCast(m_creature,SPELL_SHADOWBOLT_VOLLEY);
+ ShadowBoltVolley_Timer = 15000;
+ }else ShadowBoltVolley_Timer -= diff;
- std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
- for( std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr )
+ if ( DrawnShadows_Timer < diff)
+ {
+ Map *map = m_creature->GetMap();
+ if(map->IsDungeon())
+ {
+ InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers();
+ for (InstanceMap::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
- Unit* target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
- if( target && target->GetTypeId() == TYPEID_PLAYER )
+ if((*i)->isAlive())
{
- target->GetRandomPoint(LOCX,LOCY,LOCZ,3.0,ranX,ranY,ranZ);
- DoTeleportPlayer(target,ranX,ranY,ranZ,m_creature->GetAngle(m_creature->GetPositionX(),m_creature->GetPositionY()));
+ (*i)->TeleportTo(555,VorpilPosition[0][0],VorpilPosition[0][1],VorpilPosition[0][2],0);
}
}
- Teleport = false;
+ }
+ m_creature->Relocate(VorpilPosition[0][0],VorpilPosition[0][1],VorpilPosition[0][2],0);
+ DoCast(m_creature,SPELL_DRAWN_SHADOWS,true);
- if( HeroicMode ) DoCast(m_creature->getVictim(), H_SPELL_RAIN_OF_FIRE);
- else DoCast(m_creature->getVictim(), SPELL_RAIN_OF_FIRE);
+ if(!HeroicMode) DoCast(m_creature,SPELL_RAIN_OF_FIRE);
+ else DoCast(m_creature,H_SPELL_RAIN_OF_FIRE);
- Teleport_Timer = 1000;
- }else Teleport_Timer -= diff;
- }
+ ShadowBoltVolley_Timer = 6000;
+ DrawnShadows_Timer = 45000;
+ }else DrawnShadows_Timer -= diff;
- if( ShadowBoltVolley_Timer < diff )
+ if ( summonTraveler_Timer < diff)
{
- DoCast(m_creature->getVictim(), SPELL_SHADOW_BOLT_VOLLEY);
- ShadowBoltVolley_Timer = 30000;
- }else ShadowBoltVolley_Timer -= diff;
+ spawnVoidTraveler();
+ summonTraveler_Timer = 10000;
+ }else summonTraveler_Timer -=diff;
- if( DrawShadows_Timer < diff )
- {
- DoCast(m_creature,SPELL_DRAW_SHADOWS);
- DrawShadows_Timer = 35000;
- Teleport = true;
- }else DrawShadows_Timer -= diff;
+ DoMeleeAttackIfReady();
+ }
+};
+CreatureAI* GetAI_boss_grandmaster_vorpil(Creature *_Creature)
+{
+ return new boss_grandmaster_vorpilAI (_Creature);
+}
- if( VoidTraveler_Timer < diff )
- {
- DoYell(SAY_HELP, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_HELP);
+struct TRINITY_DLL_DECL mob_voidtravelerAI : public ScriptedAI
+{
+ mob_voidtravelerAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = ((ScriptedInstance*)c->GetInstanceData());
+ Reset();
+ }
- switch(rand()%5)
- {
- case 0:
- DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_A,true);
- break;
- case 1:
- DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_B,true);
- break;
- case 2:
- DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_C,true);
- break;
- case 3:
- DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_D,true);
- break;
- case 4:
- DoCast(m_creature,SPELL_SUMMON_VOIDWALKER_E,true);
- break;
- }
- //faster rate when below (X) health?
- VoidTraveler_Timer = 35000;
- }else VoidTraveler_Timer -= diff;
+ ScriptedInstance *pInstance;
+ uint32 VorpilCheck_Timer;
+ uint32 eventCheck_Timer;
+ bool sacrifice;
+ bool sacrificed;
+ bool oneTarget;
+ bool HeroicMode;
+
+ uint32 target_timer;
+ void Reset()
+ {
+ HeroicMode = m_creature->GetMap()->IsHeroic();
if( HeroicMode )
+ debug_log("SD2: creature %u is in heroic mode",m_creature->GetEntry());
+
+ VorpilCheck_Timer = 5000;
+ eventCheck_Timer = 1000;
+ target_timer = 2000;
+ oneTarget = false;
+ sacrificed = false;
+ sacrifice = false;
+ }
+ void EnterEvadeMode(){}
+ void Aggro(Unit *who) {}
+ void AttackStart(Unit *who){}
+ void MoveInLineOfSight(Unit *who){}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (eventCheck_Timer < diff)
{
- if( Banish_Timer < diff )
+ if(pInstance)
{
- if( Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1) )
- DoCast(target,H_SPELL_BANISH);
- Banish_Timer = 35000;
- }else Banish_Timer -= diff;
- }
+ Unit *Vorpil = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_GRANDMASTERVORPIL));
+ if (Vorpil)
+ {
+ if (Vorpil->isDead())
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
- DoMeleeAttackIfReady();
+ if (Vorpil->getVictim())
+ {
+ if((*m_creature).GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
+ (*m_creature).GetMotionMaster()->MoveFollow(Vorpil,1,0);
+ }
+ }
+ if(pInstance->GetData(DATA_GRANDMASTERVORPILEVENT) != IN_PROGRESS)
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+ eventCheck_Timer = 5000;
+ }else eventCheck_Timer -=diff;
+
+ if (VorpilCheck_Timer < diff)
+ {
+ if (pInstance)
+ {
+ if (!sacrificed)
+ {
+ if (!sacrifice)
+ {
+ Unit *Vorpil = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_GRANDMASTERVORPIL));
+ if (Vorpil)
+ if (Vorpil->isAlive())
+ {
+ if (m_creature->IsWithinDistInMap(Vorpil, 2))
+ {
+ sacrifice = true;
+ DoCast(m_creature,SPELL_SACRIFICE);
+ VorpilCheck_Timer = 2000;
+ }
+ }
+
+ if (!sacrifice)
+ VorpilCheck_Timer = 3000;
+ }
+ else
+ {
+ Unit *Vorpil = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_GRANDMASTERVORPIL));
+ if (Vorpil)
+ if (Vorpil->isAlive())
+ {
+ if(!HeroicMode) Vorpil->CastSpell(Vorpil,SPELL_HEALVORPIL,true);
+ else Vorpil->CastSpell(Vorpil,H_SPELL_HEALVORPIL,true);
+ };
+ DoCast(m_creature,SPELL_SHADOW_NOVA);
+ sacrificed = true;
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ VorpilCheck_Timer = 100000;
+ }
+ }
+ }
+ }else VorpilCheck_Timer -= diff;
}
};
-CreatureAI* GetAI_boss_grandmaster_vorpil(Creature *_Creature)
+
+CreatureAI* GetAI_mob_voidtraveler(Creature *_Creature)
{
- return new boss_grandmaster_vorpilAI (_Creature);
+ return new mob_voidtravelerAI (_Creature);
}
void AddSC_boss_grandmaster_vorpil()
@@ -291,4 +406,9 @@ void AddSC_boss_grandmaster_vorpil()
newscript->Name="boss_grandmaster_vorpil";
newscript->GetAI = GetAI_boss_grandmaster_vorpil;
m_scripts[nrscripts++] = newscript;
+
+ newscript = new Script;
+ newscript->Name="mob_voidtraveler";
+ newscript->GetAI = GetAI_mob_voidtraveler;
+ m_scripts[nrscripts++] = newscript;
}
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h
index 1300c926c7d..38b30fcd6fa 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/def_shadow_labyrinth.h
@@ -10,4 +10,5 @@
#define DATA_BLACKHEARTTHEINCITEREVENT 3
#define DATA_GRANDMASTERVORPILEVENT 4
#define DATA_MURMUREVENT 5
+#define DATA_GRANDMASTERVORPIL 6
#endif
diff --git a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp
index e50f1aeb43b..643887d64fb 100644
--- a/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp
+++ b/src/bindings/scripts/scripts/zone/aunchindoun/shadow_labyrinth/instance_shadow_labyrinth.cpp
@@ -156,7 +156,7 @@ struct TRINITY_DLL_DECL instance_shadow_labyrinth : public ScriptedInstance
uint64 GetData64(uint32 identifier)
{
- if(identifier == DATA_GRANDMASTERVORPILEVENT)
+ if(identifier == DATA_GRANDMASTERVORPIL)
return GrandmasterVorpil;
return 0;
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp
index 958e5958580..c1adb3bd3de 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/boss_magtheridon.cpp
@@ -1,18 +1,18 @@
-/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
+/* Copyright(C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+* 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
/* ScriptData
SDName: Boss_Magtheridon
@@ -23,116 +23,237 @@ EndScriptData */
#include "precompiled.h"
#include "def_magtheridons_lair.h"
-#include "WorldPacket.h"
-//Phase 2 Spells
-#define SPELL_QUAKE_PROC 30571
-#define SPELL_QUAKE 30576 //must be cast with 30561 as the proc spell
-#define SPELL_BLASTNOVA 30616
+#define MOB_MAGTHERIDON 17257
+#define MOB_ROOM 17516
+#define MOB_CHANNELLER 17256
+#define MOB_ABYSSAL 17454
+
+#define SPELL_BLASTNOVA 30616
#define SPELL_CLEAVE 30619
-#define SPELL_BERSERK 27680
-#define SPELL_DEBRIS 30631
+#define SPELL_QUAKE_TRIGGER 30576 // must be cast with 30561 as the proc spell
+#define SPELL_QUAKE_KNOCKBACK 30571
+#define SPELL_BLAZE_TARGET 30541 // core bug, does not support target 7
+#define SPELL_BLAZE_TRAP 30542
+#define SPELL_DEBRIS_KNOCKDOWN 36449
+#define SPELL_DEBRIS_VISUAL 30632
+#define SPELL_DEBRIS_DAMAGE 30631 // core bug, does not support target 8
#define SPELL_CAMERA_SHAKE 36455
+#define SPELL_BERSERK 27680
-//Banish
-#define SPELL_SHADOW_CAGE 30205
+#define SPELL_SHADOW_CAGE 30168
+#define SPELL_SHADOW_GRASP 30410
+#define SPELL_SHADOW_GRASP_VISUAL 30166
+#define SPELL_MIND_EXHAUSTION 44032 //Casted by the cubes when channeling ends
-//Player version of the banish
-#define SPELL_SHADOW_CAGE_2 30168
+#define SPELL_SHADOW_CAGE_C 30205
+#define SPELL_SHADOW_GRASP_C 30207
-//Spell that is cast on players from the cube
-#define SPELL_SHADOW_GRASP 30410
-#define SPELL_SHADOW_GRASP_UKN 30166
-#define SPELL_SHADOW_GRASP_VIS 30207
+#define SPELL_SHADOW_BOLT_VOLLEY 30510
+#define SPELL_DARK_MENDING 30528
+#define SPELL_FEAR 30530 //39176
+#define SPELL_BURNING_ABYSSAL 30511
+#define SPELL_SOUL_TRANSFER 30531 // core bug, does not support target 7
+
+#define SPELL_FIRE_BLAST 37110
//Dialog
#define SAY_AGGRO "Thank you for releasing me. Now...die!"
#define SOUND_AGGRO 10254
-
#define SAY_BANISH "Not again...NOT AGAIN!"
#define SOUND_BANISH 10256
-
#define SAY_FREED "I...am...UNLEASHED!!!"
#define SOUND_FREED 10253
-
#define SAY_CHAMBER_DESTROY "I will not be taken so easily. Let the walls of this prison tremble...and FALL!!!"
#define SOUND_CHAMBER_DESTROY 10257
-
#define SAY_PLAYER_KILLED "Did you think me weak? Soft? Who is the weak one now?!"
#define SOUND_PLAYER_KILLED 10255
-
#define SAY_DEATH "The Legion...will consume you...all...."
-#define SOUND_DEATH 10258
-
+#define SOUND_DEATH 10258
#define EMOTE_BERSERK "becomes enraged!"
#define EMOTE_BLASTNOVA "begins to cast Blast Nova!"
#define EMOTE_BEGIN "%s's bonds begin to weaken!"
-//Spawned objects
-#define SPELL_COLLAPSE 34233 //This spell casted by the "cave in" type object
+// count of clickers needed to interrupt blast nova
+#define CLICKERS_COUNT 5
-#define SPELL_CONFLAGERATION 35840 //Actually casted by a creature or object spawned on the ground
+// Unkown sounds
+uint32 RandomSound[] = {10247, 10248, 10249, 10250, 10251, 10252};
-//Cubes
-#define SPELL_MIND_EXHAUSTIOIN 30509 //Casted by the cubes when channeling ends
+typedef std::map<uint64, uint64> CubeMap;
-//Channeler spells
-//#define MOB_HELLFIRE_CHANNELLER 17256
+struct TRINITY_DLL_DECL mob_abyssalAI : public ScriptedAI
+{
+ mob_abyssalAI(Creature *c) : ScriptedAI(c)
+ {
+ trigger = 0;
+ Despawn_Timer = 60000;
+ Reset();
+ }
-#define SPELL_SOUL_TRANSFER 30531
-#define SPELL_SHADOW_BOLT_VOLLEY 30510
-#define SPELL_DARK_MENDING 30528
-#define SPELL_HELLFIRE_CHANNELING 31059
-#define SPELL_HELLFIRE_CAST_VISUAL 24207
-#define SPELL_FEAR 39176
+ uint32 FireBlast_Timer;
+ uint32 Despawn_Timer;
+ uint32 trigger;
-#define SPELL_BURNING_ABYSSAL 30511
+ void Reset()
+ {
+ FireBlast_Timer = 6000;
+ }
-// Unkown sounds
-uint32 RandomSound[] = {10247, 10248, 10249, 10250, 10251, 10252};
+ void SpellHit(Unit*, const SpellEntry *spell)
+ {
+ if(trigger == 2 && spell->Id == SPELL_BLAZE_TARGET)
+ {
+ m_creature->CastSpell(m_creature, SPELL_BLAZE_TRAP, true);
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ Despawn_Timer = 130000;
+ }
+ }
+
+ void SetTrigger(uint32 _trigger)
+ {
+ trigger = _trigger;
+ m_creature->SetDisplayId(11686);
+ if(trigger == 1) //debris
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->CastSpell(m_creature, SPELL_DEBRIS_VISUAL, true);
+ FireBlast_Timer = 5000;
+ Despawn_Timer = 10000;
+ }
+ }
+
+ void Aggro(Unit*) {DoZoneInCombat();}
+ void AttackStart(Unit *who) {if(!trigger) ScriptedAI::AttackStart(who);}
+ void MoveInLineOfSight(Unit *who) {if(!trigger) ScriptedAI::MoveInLineOfSight(who);}
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(trigger)
+ {
+ if(trigger == 1)
+ {
+ if(FireBlast_Timer < diff)
+ {
+ m_creature->CastSpell(m_creature, SPELL_DEBRIS_DAMAGE, true);
+ trigger = 3;
+ }else FireBlast_Timer -= diff;
+ }
+ return;
+ }
+
+ if(Despawn_Timer < diff)
+ {
+ m_creature->SetVisibility(VISIBILITY_OFF);
+ m_creature->setDeathState(JUST_DIED);
+ }else Despawn_Timer -= diff;
+
+ if(!m_creature->SelectHostilTarget() && !m_creature->getVictim())
+ return;
+
+ if(FireBlast_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_FIRE_BLAST);
+ FireBlast_Timer = 5000+rand()%10000;
+ }else FireBlast_Timer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+};
struct TRINITY_DLL_DECL boss_magtheridonAI : public ScriptedAI
{
- boss_magtheridonAI(Creature *c) : ScriptedAI(c)
+ boss_magtheridonAI(Creature *c) : ScriptedAI(c)
{
- pInst = (ScriptedInstance*)m_creature->GetInstanceData();
+ pInstance =(ScriptedInstance*)m_creature->GetInstanceData();
+ m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10);
+ m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 10);
Reset();
}
- ScriptedInstance* pInst;
+ CubeMap Cube;
+
+ ScriptedInstance* pInstance;
- uint32 Phase1_Timer;
+ uint32 Berserk_Timer;
+ uint32 Quake_Timer;
uint32 Cleave_Timer;
uint32 BlastNova_Timer;
- uint32 Quake_Timer;
- uint32 QuakePhase;
- uint32 Collapse_Timer;
- uint32 Berserk_Timer;
- bool Banished;
- bool Phase3;
+ uint32 Blaze_Timer;
+ uint32 Debris_Timer;
- uint32 RandChat_Timer;
+ bool Phase3;
+ bool NeedCheckCube;
void Reset()
- {
- RandChat_Timer = 90000;
+ {
+ if(pInstance)
+ {
+ pInstance->SetData(DATA_MAGTHERIDON_EVENT, NOT_STARTED);
+ pInstance->SetData(DATA_COLLAPSE, false);
+ }
- Phase1_Timer = 0;
- Cleave_Timer = 15000;
- Berserk_Timer = 1200000; //20 minutes
- BlastNova_Timer = 60000;
+ Berserk_Timer = 1320000;
Quake_Timer = 40000;
- QuakePhase = 0;
- Collapse_Timer = 0;
- Banished = false;
+ Debris_Timer = 10000;
+ Blaze_Timer = 10000+rand()%20000;
+ BlastNova_Timer = 60000;
+ Cleave_Timer = 15000;
- m_creature->setFaction(35);
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ Phase3 = false;
+
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- m_creature->CastSpell(m_creature, SPELL_SHADOW_CAGE, false);
+ m_creature->addUnitState(UNIT_STAT_STUNNED);
+ m_creature->CastSpell(m_creature, SPELL_SHADOW_CAGE_C, true);
+ }
+
+ void SetClicker(uint64 cubeGUID, uint64 clickerGUID)
+ {
+ // to avoid multiclicks from 1 cube
+ if(uint64 guid = Cube[cubeGUID])
+ DebuffClicker(Unit::GetUnit(*m_creature, guid));
+ Cube[cubeGUID] = clickerGUID;
+ NeedCheckCube = true;
+ }
+
+ //function to interrupt channeling and debuff clicker with mind exh(used if second person clicks with same cube or after dispeling/ending shadow grasp DoT)
+ void DebuffClicker(Unit *clicker)
+ {
+ if(!clicker || !clicker->isAlive())
+ return;
+
+ clicker->RemoveAurasDueToSpell(SPELL_SHADOW_GRASP); // cannot interrupt triggered spells
+ clicker->InterruptNonMeleeSpells(false);
+ clicker->CastSpell(clicker, SPELL_MIND_EXHAUSTION, true);
+ }
+
+ void NeedCheckCubeStatus()
+ {
+ uint32 ClickerNum = 0;
+ // now checking if every clicker has debuff from manticron(it is dispelable atm rev 6110 : S)
+ // if not - apply mind exhaustion and delete from clicker's list
+ for(CubeMap::iterator i = Cube.begin(); i != Cube.end(); ++i)
+ {
+ Unit *clicker = Unit::GetUnit(*m_creature, (*i).second);
+ if(!clicker || !clicker->HasAura(SPELL_SHADOW_GRASP, 1))
+ {
+ DebuffClicker(clicker);
+ (*i).second = 0;
+ }else ClickerNum++;
+ }
+
+ // if 5 clickers from other cubes apply shadow cage
+ if(ClickerNum >= CLICKERS_COUNT && !m_creature->HasAura(SPELL_SHADOW_CAGE, 0))
+ {
+ DoYell(SAY_BANISH, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_BANISH);
+ m_creature->CastSpell(m_creature, SPELL_SHADOW_CAGE, true);
+ }
+ else if(ClickerNum < CLICKERS_COUNT && m_creature->HasAura(SPELL_SHADOW_CAGE, 0))
+ m_creature->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE);
- if(pInst)
- pInst->SetData(DATA_MAGTHERIDON_EVENT_ENDED, false);
+ if(!ClickerNum) NeedCheckCube = false;
}
void KilledUnit(Unit* victim)
@@ -143,126 +264,122 @@ struct TRINITY_DLL_DECL boss_magtheridonAI : public ScriptedAI
void JustDied(Unit* Killer)
{
+ if(pInstance)
+ pInstance->SetData(DATA_MAGTHERIDON_EVENT, DONE);
+
DoYell(SAY_DEATH,LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_DEATH);
}
- void Aggro(Unit *who) {}
-
- void MoveInLineOfSight(Unit* who) {}
+ void MoveInLineOfSight(Unit*) {}
- void UpdateAI(const uint32 diff)
+ void AttackStart(Unit *who)
{
- if (!InCombat && !Phase1_Timer)
- if (RandChat_Timer < diff)
- {
- DoPlaySoundToSet(m_creature, RandomSound[rand()%5]);
-
- RandChat_Timer = 90000;
- }else RandChat_Timer -= diff;
-
- if (!InCombat && !Phase1_Timer && pInst && pInst->GetData64(DATA_EVENT_STARTER))
- {
- //Unbanish self after 2 minutes
- Phase1_Timer = 120000;
- DoTextEmote(EMOTE_BEGIN, NULL);
- return;
- }
+ if(!m_creature->hasUnitState(UNIT_STAT_STUNNED))
+ ScriptedAI::AttackStart(who);
+ }
- //Phase timer
- if (Phase1_Timer)
- if (Phase1_Timer <= diff)
- {
- m_creature->setFaction(14);
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ void Aggro(Unit *who)
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_MAGTHERIDON_EVENT, IN_PROGRESS);
+ DoZoneInCombat();
- DoYell(SAY_FREED, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_FREED);
- m_creature->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE);
- AttackStart(Unit::GetUnit(*m_creature, pInst->GetData64(DATA_EVENT_STARTER)));
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE_C);
- Phase1_Timer = 0;
- }else
- {
- if (!Unit::GetUnit(*m_creature, pInst->GetData64(DATA_EVENT_STARTER)))
- {
- Phase1_Timer = 0;
- return;
- }
+ DoYell(SAY_FREED, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_FREED);
+ }
- Phase1_Timer -= diff;
- return;
- }
-
- //Return since we have no target
- if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostilTarget() && !m_creature->getVictim())
return;
- //Interrupt Blast Nova
- if (m_creature->HasAura(SPELL_SHADOW_GRASP_VIS, 0) && m_creature->HasAura(SPELL_BLASTNOVA, 0) && !Banished)
- {
- DoYell(SAY_BANISH, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_BANISH);
- m_creature->RemoveAurasDueToSpell(SPELL_BLASTNOVA);
- m_creature->InterruptNonMeleeSpells(false);
- DoCast(m_creature, SPELL_SHADOW_CAGE_2);
- Banished = true;
- }
+ if(NeedCheckCube) NeedCheckCubeStatus();
- if (Banished && !m_creature->HasAura(SPELL_SHADOW_GRASP_VIS, 0))
+ if(Berserk_Timer < diff)
{
- Banished = false;
- m_creature->RemoveAurasDueToSpell(SPELL_SHADOW_CAGE_2);
- }
-
- //Berserk_Timer
- if (Berserk_Timer < diff)
- {
- DoCast(m_creature, SPELL_BERSERK);
+ m_creature->CastSpell(m_creature, SPELL_BERSERK, true);
DoTextEmote(EMOTE_BERSERK, NULL);
-
- Berserk_Timer = 300000;
+ Berserk_Timer = 60000;
}else Berserk_Timer -= diff;
- //Cleave_Timer
- if (Cleave_Timer < diff)
+ if(Cleave_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CLEAVE);
Cleave_Timer = 10000;
}else Cleave_Timer -= diff;
- //Quake_Timer
- if (Quake_Timer < diff)
+ if(BlastNova_Timer < diff)
{
- int32 i = SPELL_QUAKE_PROC;
- m_creature->CastCustomSpell(m_creature, SPELL_QUAKE, &i, 0, 0, false);
+ // to avoid earthquake interruption
+ if(!m_creature->hasUnitState(UNIT_STAT_STUNNED))
+ {
+ DoTextEmote(EMOTE_BLASTNOVA, NULL);
+ DoCast(m_creature, SPELL_BLASTNOVA);
+ BlastNova_Timer = 60000;
+ }
+ }else BlastNova_Timer -= diff;
- Quake_Timer = 40000;
+ if(Quake_Timer < diff)
+ {
+ // to avoid blastnova interruption
+ if(!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ int32 i = SPELL_QUAKE_KNOCKBACK;
+ m_creature->CastCustomSpell(m_creature, SPELL_QUAKE_TRIGGER, &i, 0, 0, false);
+ Quake_Timer = 50000;
+ }
}else Quake_Timer -= diff;
- //BlastNova_Timer
- if (BlastNova_Timer < diff)
+ if(Blaze_Timer < diff)
{
- //Inturrupt Quake if it is casting
- m_creature->InterruptNonMeleeSpells(false);
-
- DoTextEmote(EMOTE_BLASTNOVA, NULL);
- DoCast(m_creature, SPELL_BLASTNOVA);
-
- BlastNova_Timer = 40000;
- }else BlastNova_Timer -= diff;
+ if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ float x, y, z;
+ target->GetPosition(x, y, z);
+ Creature *summon = m_creature->SummonCreature(MOB_ABYSSAL, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ if(summon)
+ {
+ ((mob_abyssalAI*)summon->AI())->SetTrigger(2);
+ m_creature->CastSpell(summon, SPELL_BLAZE_TARGET, true);
+ summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ }
+ }
+ Blaze_Timer = 20000 + rand()%20000;
+ }else Blaze_Timer -= diff;
- //Phase3 if not already enraged and below 30%
- if (!Phase3 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30)
- {
+ if(!Phase3 && m_creature->GetHealth()*10 < m_creature->GetMaxHealth()*3
+ && !m_creature->IsNonMeleeSpellCasted(false) // blast nova
+ && !m_creature->hasUnitState(UNIT_STAT_STUNNED)) // shadow cage and earthquake
+ {
Phase3 = true;
-
DoYell(SAY_CHAMBER_DESTROY, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_CHAMBER_DESTROY);
+ m_creature->CastSpell(m_creature, SPELL_CAMERA_SHAKE, true);
+ m_creature->CastSpell(m_creature, SPELL_DEBRIS_KNOCKDOWN, true);
+
+ if(pInstance)
+ pInstance->SetData(DATA_COLLAPSE, true);
+ }
+
+ if(Phase3)
+ {
+ if(Debris_Timer < diff)
+ {
+ if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ float x, y, z;
+ target->GetPosition(x, y, z);
+ Creature *summon = m_creature->SummonCreature(MOB_ABYSSAL, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ if(summon) ((mob_abyssalAI*)summon->AI())->SetTrigger(1);
+ }
+ Debris_Timer = 10000;
+ }else Debris_Timer -= diff;
}
- //Melee
DoMeleeAttackIfReady();
}
};
@@ -271,150 +388,129 @@ struct TRINITY_DLL_DECL mob_hellfire_channelerAI : public ScriptedAI
{
mob_hellfire_channelerAI(Creature *c) : ScriptedAI(c)
{
- pInst = (ScriptedInstance*)m_creature->GetInstanceData();
+ pInstance =(ScriptedInstance*)m_creature->GetInstanceData();
Reset();
}
- ScriptedInstance* pInst;
+ ScriptedInstance* pInstance;
uint32 ShadowBoltVolley_Timer;
uint32 DarkMending_Timer;
uint32 Fear_Timer;
uint32 Infernal_Timer;
- bool InfernalSpawned;
+ uint32 Check_Timer;
void Reset()
{
ShadowBoltVolley_Timer = 8000 + rand()%2000;
- DarkMending_Timer = 30000;
+ DarkMending_Timer = 10000;
Fear_Timer = 15000 + rand()%5000;
- Infernal_Timer = 20000 + rand()%5000;
+ Infernal_Timer = 10000 + rand()%40000;
- InfernalSpawned = false;
+ Check_Timer = 5000;
- //Suprisingly this works very well, but only if the channelers are spawned after magtheridon
- DoCast(m_creature, SPELL_SHADOW_GRASP_VIS);
- if(pInst)
- pInst->SetData(DATA_MAGTHERIDON_EVENT_ENDED, false);
+ if(pInstance)
+ pInstance->SetData(DATA_CHANNELER_EVENT, NOT_STARTED);
+
+ m_creature->CastSpell(m_creature, SPELL_SHADOW_GRASP_C, false);
}
void Aggro(Unit *who)
{
+ if(pInstance)
+ pInstance->SetData(DATA_CHANNELER_EVENT, IN_PROGRESS);
+
m_creature->InterruptNonMeleeSpells(false);
+ DoZoneInCombat();
+ }
- if(!pInst || pInst->GetData64(DATA_EVENT_STARTER))
- return;
+ void JustSummoned(Creature *summon) {summon->AI()->AttackStart(m_creature->getVictim());}
- pInst->SetData64(DATA_EVENT_STARTER, who->GetGUID());
- pInst->SetData(DATA_MAGTHERIDON_EVENT_STARTED, true);
- }
+ void MoveInLineOfSight(Unit*) {}
- void MoveInLineOfSight(Unit*)
+ // bugged
+ /*void DamageTaken(Unit*, uint32 &damage)
{
+ if(damage >= m_creature->GetHealth())
+ m_creature->CastSpell(m_creature, SPELL_SOUL_TRANSFER, true);
+ }*/
+
+ void JustDied(Unit*)
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_CHANNELER_EVENT, DONE);
}
void UpdateAI(const uint32 diff)
{
- if (!InCombat && pInst && pInst->GetData64(DATA_EVENT_STARTER))
+ if(!m_creature->SelectHostilTarget() && !m_creature->getVictim())
+ return;
+
+ if(ShadowBoltVolley_Timer < diff)
{
- m_creature->InterruptNonMeleeSpells(false);
- AttackStart(Unit::GetUnit(*m_creature, pInst->GetData64(DATA_EVENT_STARTER)));
- return;
- }
-
- //Return since we have no target
- if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
- return;
-
- //Shadow bolt volley
- if (ShadowBoltVolley_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_SHADOW_BOLT_VOLLEY);
-
- ShadowBoltVolley_Timer = 10000 + (rand()%10000);
+ DoCast(m_creature, SPELL_SHADOW_BOLT_VOLLEY);
+ ShadowBoltVolley_Timer = 10000 + rand()%10000;
}else ShadowBoltVolley_Timer -= diff;
- //Dark Mending
- if (DarkMending_Timer < diff)
+ if(DarkMending_Timer < diff)
{
- if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 50)
- {
- //Cast on ourselves if we are lower then lowest hp friendly unit
- /*if (pLowestHPTarget && LowestHP < m_creature->GetHealth())
- DoCast(pLowestHPTarget, SPELL_DARK_MENDING);
- else*/
+ if((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 50)
DoCast(m_creature, SPELL_DARK_MENDING);
- }
-
- DarkMending_Timer = 10000 + (rand() % 10000);
+ DarkMending_Timer = 10000 +(rand() % 10000);
}else DarkMending_Timer -= diff;
- //Fear
- if (Fear_Timer < diff)
+ if(Fear_Timer < diff)
{
- Unit* target = NULL;
- target = SelectUnit(SELECT_TARGET_RANDOM, 1);
-
- if (target)
- DoCast(target,SPELL_FEAR);
-
- Fear_Timer = 25000 + (rand()%15000);
+ if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1))
+ DoCast(target, SPELL_FEAR);
+ Fear_Timer = 25000 + rand()%15000;
}else Fear_Timer -= diff;
- //Infernal spawning
- if (!InfernalSpawned && Infernal_Timer < diff)
+ if(Infernal_Timer < diff)
{
- Unit* target = NULL;
- target = SelectUnit(SELECT_TARGET_RANDOM, 0);
-
- if (target)
- DoCast(target, SPELL_BURNING_ABYSSAL);
-
- InfernalSpawned = true;
+ if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ m_creature->CastSpell(target, SPELL_BURNING_ABYSSAL, true);
+ Infernal_Timer = 30000 + rand()%10000;
}else Infernal_Timer -= diff;
DoMeleeAttackIfReady();
}
-
};
//Manticron Cube
bool GOHello_go_Manticron_Cube(Player *player, GameObject* _GO)
{
- ScriptedInstance* pInst = (ScriptedInstance*)_GO->GetInstanceData();
-
- Unit* pUnit = NULL;
- if(pInst)
- pUnit = Unit::GetUnit(*_GO, pInst->GetData64(DATA_MAGTHERIDON));
- else
- {
- _GO->TextEmote("Manticron Cube: NO INSTANCE", 0);
- return true;
- }
-
- if (!pUnit || !pUnit->isAlive() || !player)
- {
- _GO->TextEmote("Mantricon Cube: NO TARGET", 0);
+ ScriptedInstance* pInstance =(ScriptedInstance*)_GO->GetInstanceData();
+ if(!pInstance) return true;
+ if(pInstance->GetData(DATA_MAGTHERIDON_EVENT) != IN_PROGRESS) return true;
+ Creature *Magtheridon =(Creature*)Unit::GetUnit(*_GO, pInstance->GetData64(DATA_MAGTHERIDON));
+ if(!Magtheridon || !Magtheridon->isAlive()) return true;
+
+ // if exhausted or already channeling return
+ if(player->HasAura(SPELL_MIND_EXHAUSTION, 0) || player->HasAura(SPELL_SHADOW_GRASP, 1))
return true;
- }
player->InterruptNonMeleeSpells(false);
- player->CastSpell(pUnit, SPELL_SHADOW_GRASP, true);
- player->CastSpell(pUnit, SPELL_SHADOW_GRASP_VIS, false);
-
- _GO->Say("Mantricon Cube Clicked", LANG_UNIVERSAL, 0);
+ player->CastSpell(player, SPELL_SHADOW_GRASP, true);
+ player->CastSpell(player, SPELL_SHADOW_GRASP_VISUAL, false);
+ ((boss_magtheridonAI*)Magtheridon->AI())->SetClicker(_GO->GetGUID(), player->GetGUID());
return true;
}
CreatureAI* GetAI_boss_magtheridon(Creature *_Creature)
{
- return new boss_magtheridonAI (_Creature);
+ return new boss_magtheridonAI(_Creature);
}
CreatureAI* GetAI_mob_hellfire_channeler(Creature *_Creature)
{
- return new mob_hellfire_channelerAI (_Creature);
+ return new mob_hellfire_channelerAI(_Creature);
+}
+
+CreatureAI* GetAI_mob_abyssalAI(Creature *_Creature)
+{
+ return new mob_abyssalAI(_Creature);
}
void AddSC_boss_magtheridon()
@@ -434,4 +530,10 @@ void AddSC_boss_magtheridon()
newscript->Name="go_manticron_cube";
newscript->pGOHello = &GOHello_go_Manticron_Cube;
m_scripts[nrscripts++] = newscript;
-}
+
+ newscript = new Script;
+ newscript->Name="mob_abyssal";
+ newscript->GetAI = GetAI_mob_abyssalAI;
+ m_scripts[nrscripts++] = newscript;
+
+} \ No newline at end of file
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h
index 3001a964c34..2314dc344f9 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/def_magtheridons_lair.h
@@ -5,9 +5,9 @@
#ifndef DEF_MAGTHERIDONS_LAIR_H
#define DEF_MAGTHERIDONS_LAIR_H
-#define DATA_EVENT_STARTER 1
-#define DATA_MAGTHERIDON 2
-#define DATA_MAGTHERIDON_EVENT_ENDED 3
-#define DATA_MAGTHERIDON_EVENT_STARTED 4
-#define DATA_MAGTHERIDON_EVENT_STATUS 5
+#define DATA_MAGTHERIDON_EVENT 1
+#define DATA_MAGTHERIDON 3
+#define DATA_CHANNELER_EVENT 2
+#define DATA_COLLAPSE 6
+#define DATA_CHANNELER 9
#endif
diff --git a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp
index b6aef00cc4f..6c4609df4fd 100644
--- a/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp
+++ b/src/bindings/scripts/scripts/zone/hellfire_citadel/magtheridons_lair/instance_magtheridons_lair.cpp
@@ -6,12 +6,12 @@
*
* 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
+ * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
@@ -24,81 +24,297 @@ EndScriptData */
#include "precompiled.h"
#include "def_magtheridons_lair.h"
+#define SPELL_SOUL_TRANSFER 30531 // core bug, does not support target 7
+#define SPELL_BLAZE_TARGET 30541 // core bug, does not support target 7
+#define SPELL_DEBRIS_DAMAGE 30631 // core bug, does not support target 8
+#define SPELL_DEBRIS_KNOCKDOWN 36449 // core bug, does not support target 8
+
+#define CHAMBER_CENTER_X -15.14
+#define CHAMBER_CENTER_Y 1.8
+#define CHAMBER_CENTER_Z -0.4
+
+#define ENCOUNTERS 2
+
struct TRINITY_DLL_DECL instance_magtheridons_lair : public ScriptedInstance
{
- instance_magtheridons_lair(Map *Map) : ScriptedInstance(Map) {Initialize();};
+ instance_magtheridons_lair(Map *Map) : ScriptedInstance(Map)
+ {
+ Initialize();
+ // target 7, random target with certain entry spell, need core fix
+ SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_BLAZE_TARGET);
+ if(TempSpell && TempSpell->EffectImplicitTargetA[0] != 6)
+ {
+ TempSpell->EffectImplicitTargetA[0] = 6;
+ TempSpell->EffectImplicitTargetB[0] = 0;
+ }
+ TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_SOUL_TRANSFER);
+ if(TempSpell && TempSpell->EffectImplicitTargetB[0] != 30)
+ {
+ TempSpell->EffectImplicitTargetA[0] = 1;
+ TempSpell->EffectImplicitTargetA[1] = 1;
+ TempSpell->EffectImplicitTargetA[2] = 1;
+ TempSpell->EffectImplicitTargetB[0] = 0;
+ TempSpell->EffectImplicitTargetB[1] = 0;
+ TempSpell->EffectImplicitTargetB[2] = 0;
+ }
+ // target 8, but core only push back the caster
+ TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_DEBRIS_DAMAGE);
+ if(TempSpell && TempSpell->EffectImplicitTargetA[0] != 53)
+ {
+ TempSpell->EffectImplicitTargetA[0] = 53;
+ TempSpell->EffectImplicitTargetB[0] = 16;
+ }
+ TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_DEBRIS_KNOCKDOWN);
+ if(TempSpell && TempSpell->EffectImplicitTargetA[0] != 53)
+ {
+ TempSpell->EffectImplicitTargetA[0] = 53;
+ TempSpell->EffectImplicitTargetB[0] = 16;
+ TempSpell->EffectImplicitTargetA[1] = 53;
+ TempSpell->EffectImplicitTargetB[1] = 16;
+ }
+ }
+
+ uint32 Encounters[ENCOUNTERS];
+
+ uint64 MagtheridonGUID;
+ std::set<uint64> ChannelerGUID;
+ uint64 DoorGUID;
+ std::set<uint64> ColumnGUID;
- bool EncounterInProgress;
- uint64 Magtheridon;
- uint64 EventStarter;
+ uint32 CageTimer;
+ uint32 RespawnTimer;
void Initialize()
{
- Magtheridon = 0;
- EventStarter = 0;
- EncounterInProgress = false;
+ for(uint8 i = 0; i < ENCOUNTERS; i++)
+ Encounters[i] = NOT_STARTED;
+
+ MagtheridonGUID = 0;
+ ChannelerGUID.clear();
+ DoorGUID = 0;
+ ColumnGUID.clear();
+
+ CageTimer = 0;
+ RespawnTimer = 0;
}
bool IsEncounterInProgress() const
{
- return EncounterInProgress;
+ for(uint8 i = 0; i < ENCOUNTERS; i++)
+ if(Encounters[i] == IN_PROGRESS) return true;
+ return false;
}
void OnCreatureCreate(Creature *creature, uint32 creature_entry)
{
- if (creature_entry == 17257)
- Magtheridon = creature->GetGUID();
+ switch(creature->GetEntry())
+ {
+ case 17257:
+ MagtheridonGUID = creature->GetGUID();
+ break;
+ case 17256:
+ ChannelerGUID.insert(creature->GetGUID());
+ break;
+ }
}
- uint64 GetData64(uint32 identifier)
+ void OnObjectCreate(GameObject *go)
{
- switch(identifier)
+ switch(go->GetEntry())
{
- case DATA_MAGTHERIDON:
- return Magtheridon;
-
- case DATA_EVENT_STARTER:
- return EventStarter;
+ case 181713:
+ go->SetUInt32Value(GAMEOBJECT_FLAGS, 0);
+ break;
+ case 183847:
+ DoorGUID = go->GetGUID();
+ break;
+ case 184653: // hall
+ case 184634: // six columns
+ case 184635:
+ case 184636:
+ case 184637:
+ case 184638:
+ case 184639:
+ ColumnGUID.insert(go->GetGUID());
+ break;
}
- return 0;
}
- void SetData64(uint32 identifier, uint64 guid)
+ uint64 GetData64(uint32 type)
{
- switch(identifier)
+ switch(type)
{
- case DATA_MAGTHERIDON:
- Magtheridon = guid;
- break;
-
- case DATA_EVENT_STARTER:
- EventStarter = guid;
- break;
+ case DATA_MAGTHERIDON:
+ return MagtheridonGUID;
}
+ return 0;
}
void SetData(uint32 type, uint32 data)
{
+ Player *player = GetPlayer();
+ if(!player) return;
+
switch(type)
{
- case DATA_MAGTHERIDON_EVENT_STARTED:
- EncounterInProgress = true;
- break;
-
- case DATA_MAGTHERIDON_EVENT_ENDED:
- EncounterInProgress = false;
- EventStarter = 0;
- break;
+ case DATA_MAGTHERIDON_EVENT:
+ Encounters[0] = data;
+ if(data == NOT_STARTED)
+ RespawnTimer = 10000;
+ if(data != IN_PROGRESS)
+ {
+ if(GameObject *Door = GameObject::GetGameObject(*player, DoorGUID))
+ Door->SetGoState(0);
+ }
+ break;
+ case DATA_CHANNELER_EVENT:
+ switch(data)
+ {
+ case NOT_STARTED: // Reset all channelers once one is reset.
+ if(Encounters[1] != NOT_STARTED)
+ {
+ Encounters[1] = NOT_STARTED;
+ for(std::set<uint64>::iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i)
+ {
+ if(Creature *Channeler = (Creature*)Unit::GetUnit(*player, *i))
+ {
+ if(Channeler->isAlive())
+ Channeler->AI()->EnterEvadeMode();
+ else
+ Channeler->Respawn();
+ }
+ }
+ CageTimer = 0;
+ if(GameObject *Door = GameObject::GetGameObject(*player, DoorGUID))
+ Door->SetGoState(0);
+ }break;
+ case IN_PROGRESS: // Event start.
+ if(Encounters[1] != IN_PROGRESS)
+ {
+ Encounters[1] = IN_PROGRESS;
+ // Let all five channelers aggro.
+ for(std::set<uint64>::iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i)
+ {
+ Creature *Channeler = (Creature*)Unit::GetUnit(*player, *i);
+ if(Channeler && Channeler->isAlive())
+ {
+ //if(Unit *target = Channeler->SelectNearbyTarget())
+ //always return true, do not know why
+ AttackNearestTarget(Channeler);
+ }
+ }
+ // Release Magtheridon after two minutes.
+ Creature *Magtheridon = (Creature*)Unit::GetUnit(*player, MagtheridonGUID);
+ if(Magtheridon && Magtheridon->isAlive())
+ {
+ Magtheridon->TextEmote("'s bonds begin to weaken!", 0);
+ CageTimer = 120000;
+ }
+ if(GameObject *Door = GameObject::GetGameObject(*player, DoorGUID))
+ Door->SetGoState(1);
+ }break;
+ case DONE: // Add buff and check if all channelers are dead.
+ for(std::set<uint64>::iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i)
+ {
+ Unit *Channeler = Unit::GetUnit(*player, *i);
+ if(Channeler && Channeler->isAlive())
+ {
+ Channeler->CastSpell(Channeler, SPELL_SOUL_TRANSFER, true);
+ data = IN_PROGRESS;
+ }
+ }break;
+ }
+ Encounters[1] = data;
+ break;
+ case DATA_COLLAPSE:
+ // true - collapse / false - reset
+ for(std::set<uint64>::iterator i = ColumnGUID.begin(); i != ColumnGUID.end(); ++i)
+ {
+ if(GameObject *Column = GameObject::GetGameObject(*player, *i))
+ Column->SetGoState(!data);
+ }
+ break;
+ default:
+ break;
}
}
uint32 GetData(uint32 type)
{
- if(type == DATA_MAGTHERIDON_EVENT_STATUS)
- return EncounterInProgress;
-
+ if(type == DATA_MAGTHERIDON_EVENT)
+ return Encounters[0];
return 0;
}
+
+ Player* GetPlayer()
+ {
+ if(((InstanceMap*)instance)->GetPlayers().size())
+ return ((InstanceMap*)instance)->GetPlayers().front();
+ return NULL;
+ }
+
+ void AttackNearestTarget(Creature *creature)
+ {
+ float minRange = 999.0f;
+ float range;
+ Player* target = NULL;
+ InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)instance)->GetPlayers();
+ InstanceMap::PlayerList::const_iterator i;
+ for(i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ {
+ if((*i)->isTargetableForAttack())
+ {
+ range = (*i)->GetDistance(creature);
+ if(range < minRange)
+ {
+ minRange = range;
+ target = *i;
+ }
+ }
+ }
+ creature->AI()->AttackStart(target);
+ }
+
+ void Update(uint32 diff)
+ {
+ if(CageTimer)
+ {
+ if(CageTimer <= diff)
+ {
+ if(Player *player = GetPlayer())
+ {
+ Creature *Magtheridon = (Creature*)Unit::GetUnit(*player, MagtheridonGUID);
+ if(Magtheridon && Magtheridon->isAlive())
+ {
+ Magtheridon->clearUnitState(UNIT_STAT_STUNNED);
+ AttackNearestTarget(Magtheridon);
+ }
+ }
+ CageTimer = 0;
+ }else CageTimer -= diff;
+ }
+
+ if(RespawnTimer)
+ {
+ if(RespawnTimer <= diff)
+ {
+ if(Player *player = GetPlayer())
+ {
+ for(std::set<uint64>::iterator i = ChannelerGUID.begin(); i != ChannelerGUID.end(); ++i)
+ {
+ if(Creature *Channeler = (Creature*)Unit::GetUnit(*player, *i))
+ {
+ if(Channeler->isAlive())
+ Channeler->AI()->EnterEvadeMode();
+ else
+ Channeler->Respawn();
+ }
+ }
+ }
+ RespawnTimer = 0;
+ }else RespawnTimer -= diff;
+ }
+ }
};
InstanceData* GetInstanceData_instance_magtheridons_lair(Map* map)
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
new file mode 100644
index 00000000000..e54bdcb8079
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp
@@ -0,0 +1,532 @@
+/* Copyright(C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+* 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, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/* ScriptData
+SDName: boss_alar
+SD%Complete: 95
+SDComment:
+SDCategory: Tempest Keep, The Eye
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_the_eye.h"
+
+#define SPELL_FLAME_BUFFET 34121 // Flame Buffet - every 1,5 secs in phase 1 if there is no victim in melee range and after Dive Bomb in phase 2 with same conditions
+#define SPELL_FLAME_QUILLS 34229 // Randomly after changing position in phase after watching tonns of movies, set probability 20%
+#define SPELL_REBIRTH 34342 // Rebirth - beginning of second phase(after loose all health in phase 1)
+#define SPELL_REBIRTH_2 35369 // Rebirth(another, without healing to full HP) - after Dive Bomb in phase 2
+#define SPELL_MELT_ARMOR 35410 // Melt Armor - every 60 sec in phase 2
+#define SPELL_CHARGE 35412 // Charge - 30 sec cooldown
+#define SPELL_DIVE_BOMB_VISUAL 35367 // Bosskillers says 30 sec cooldown, wowwiki says 30 sec colldown, DBM and BigWigs addons says ~47 sec
+#define SPELL_DIVE_BOMB 35181 // after watching tonns of movies, set cooldown to 40+rand()%5.
+#define SPELL_BERSERK 45078 // 10 minutes after phase 2 starts(id is wrong, but proper id is unknown)
+
+#define CREATURE_EMBER_OF_ALAR 19551 // Al'ar summons one Ember of Al'ar every position change in phase 1 and two after Dive Bomb. Also in phase 2 when Ember of Al'ar dies, boss loose 3% health.
+#define SPELL_EMBER_BLAST 34133 // When Ember of Al'ar dies, it casts Ember Blast
+
+#define CREATURE_FLAME_PATCH_ALAR 20602 // Flame Patch - every 30 sec in phase 2
+#define SPELL_FLAME_PATCH 35380 //
+
+static float waypoint[6][3] =
+{
+ {340.15, 58.65, 17.71},
+ {388.09, 31.54, 20.18},
+ {388.18, -32.85, 20.18},
+ {340.29, -60.19, 17.72},
+ {332, 0.01, 39}, // better not use the same xy coord
+ {331, 0.01, -2.39}
+};
+
+enum WaitEventType
+{
+ WE_NONE = 0,
+ WE_DUMMY = 1,
+ WE_PLATFORM = 2,
+ WE_QUILL = 3,
+ WE_DIE = 4,
+ WE_REVIVE = 5,
+ WE_CHARGE = 6,
+ WE_METEOR = 7,
+ WE_DIVE = 8,
+ WE_LAND = 9,
+ WE_SUMMON = 10
+};
+
+struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI
+{
+ boss_alarAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance =((ScriptedInstance*)c->GetInstanceData());
+ DefaultMoveSpeedRate = m_creature->GetSpeedRate(MOVE_RUN);
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+
+ WaitEventType WaitEvent;
+ uint32 WaitTimer;
+
+ bool AfterMoving;
+
+ uint32 Platforms_Move_Timer;
+ uint32 DiveBomb_Timer;
+ uint32 MeltArmor_Timer;
+ uint32 Charge_Timer;
+ uint32 FlamePatch_Timer;
+ uint32 Berserk_Timer;
+
+ float DefaultMoveSpeedRate;
+
+ bool Phase1;
+
+ int8 cur_wp;
+
+ void Reset()
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_ALAREVENT, NOT_STARTED);
+
+ Berserk_Timer = 1200000;
+ Platforms_Move_Timer = 0;
+
+ Phase1 = true;
+ WaitEvent = WE_NONE;
+ WaitTimer = 0;
+ AfterMoving = false;
+
+ cur_wp = 4;
+
+ m_creature->SetDisplayId(m_creature->GetNativeDisplayId());
+ m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate);
+ m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10);
+ m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 10);
+ m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true);
+ m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+
+ void Aggro(Unit *who)
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_ALAREVENT, IN_PROGRESS);
+
+ m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); // after enterevademode will be set walk movement
+ DoZoneInCombat();
+ }
+
+ void JustDied(Unit *victim)
+ {
+ if(pInstance)
+ pInstance->SetData(DATA_ALAREVENT, DONE);
+ }
+
+ void JustSummoned(Creature *summon)
+ {
+ if(summon->GetEntry() == CREATURE_EMBER_OF_ALAR)
+ {
+ if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ summon->AI()->AttackStart(target);
+ summon->SetInCombatWith(target);
+ }
+ }
+ }
+
+ void MoveInLineOfSight(Unit *who) {}
+
+ void AttackStart(Unit* who)
+ {
+ if(!who)
+ return;
+
+ if(who->isTargetableForAttack())
+ {
+ //Begin attack
+ if(Phase1)
+ DoStartAttackNoMovement(who);
+ else
+ DoStartAttackAndMovement(who);
+
+ if(!InCombat)
+ {
+ Aggro(who);
+ InCombat = true;
+ }
+ }
+ }
+
+ void DamageTaken(Unit* pKiller, uint32 &damage)
+ {
+ if(damage >= m_creature->GetHealth() && Phase1)
+ {
+ damage = 0;
+ if(!WaitEvent)
+ {
+ WaitEvent = WE_DIE;
+ WaitTimer = 0;
+ m_creature->SetHealth(0);
+ m_creature->InterruptNonMeleeSpells(true);
+ m_creature->RemoveAllAuras();
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ m_creature->AttackStop();
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0);
+ m_creature->SetSpeed(MOVE_RUN, 5.0f);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->GetMotionMaster()->MovePoint(0, waypoint[5][0], waypoint[5][1], waypoint[5][2]);
+ }
+ }
+ }
+
+ void SpellHit(Unit*, const SpellEntry *spell)
+ {
+ if(spell->Id == SPELL_DIVE_BOMB_VISUAL)
+ {
+ m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true);
+ m_creature->SetDisplayId(11686);
+ //m_creature->SendUpdateObjectToAllExcept(NULL);
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if(type == POINT_MOTION_TYPE)
+ {
+ WaitTimer = 1;
+ AfterMoving = true;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->isInCombat()) // sometimes isincombat but !incombat, faction bug?
+ return;
+
+ if(Berserk_Timer < diff)
+ {
+ m_creature->CastSpell(m_creature, SPELL_BERSERK, true);
+ Berserk_Timer = 60000;
+ }else Berserk_Timer -= diff;
+
+ if(WaitEvent)
+ {
+ if(WaitTimer)
+ {
+ if(WaitTimer <= diff)
+ {
+ if(AfterMoving)
+ {
+ m_creature->GetMotionMaster()->MoveIdle();
+ AfterMoving = false;
+ }
+
+ switch(WaitEvent)
+ {
+ case WE_PLATFORM:
+ Platforms_Move_Timer = 30000+rand()%5000;
+ break;
+ case WE_QUILL:
+ m_creature->CastSpell(m_creature, SPELL_FLAME_QUILLS, true);
+ Platforms_Move_Timer = 1;
+ WaitTimer = 10000;
+ WaitEvent = WE_DUMMY;
+ return;
+ case WE_DIE:
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_DEAD);
+ WaitTimer = 5000;
+ WaitEvent = WE_REVIVE;
+ return;
+ case WE_REVIVE:
+ m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1, PLAYER_STATE_NONE);
+ m_creature->SetHealth(m_creature->GetMaxHealth());
+ m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ DoResetThreat();
+ DoZoneInCombat();
+ m_creature->CastSpell(m_creature, SPELL_REBIRTH, true);
+ MeltArmor_Timer = 60000;
+ Charge_Timer = 7000;
+ DiveBomb_Timer = 40000+rand()%5000;
+ FlamePatch_Timer = 30000;
+ Phase1 = false;
+ break;
+ case WE_CHARGE:
+ m_creature->SetSpeed(MOVE_RUN, DefaultMoveSpeedRate);
+ break;
+ case WE_METEOR:
+ m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, false);
+ m_creature->CastSpell(m_creature, SPELL_DIVE_BOMB_VISUAL, false);
+ WaitEvent = WE_DIVE;
+ WaitTimer = 4000;
+ return;
+ case WE_DIVE:
+ if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ m_creature->RemoveAurasDueToSpell(SPELL_DIVE_BOMB_VISUAL);
+ m_creature->CastSpell(target, SPELL_DIVE_BOMB, true);
+ float dist = m_creature->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
+ if (dist < 5.0f) dist = 5.0f;
+ WaitTimer = 1000 + floor(dist / 80 * 1000.0f);
+ m_creature->Relocate(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
+ m_creature->StopMoving();
+ WaitEvent = WE_LAND;
+ }else EnterEvadeMode();
+ return;
+ case WE_LAND:
+ WaitEvent = WE_SUMMON;
+ WaitTimer = 2000;
+ return;
+ case WE_SUMMON:
+ for(uint8 i = 0; i < 2; ++i)
+ DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10);
+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetDisplayId(m_creature->GetNativeDisplayId());
+ m_creature->CastSpell(m_creature, SPELL_REBIRTH_2, true);
+ break;
+ case WE_DUMMY:
+ default:
+ break;
+ }
+
+ WaitEvent = WE_NONE;
+ WaitTimer = 0;
+ }else WaitTimer -= diff;
+ }
+ return;
+ }
+
+ if(Phase1)
+ {
+ if(m_creature->getThreatManager().getThreatList().empty())
+ {
+ EnterEvadeMode();
+ return;
+ }
+
+ if(Platforms_Move_Timer < diff)
+ {
+ if(cur_wp == 4)
+ {
+ cur_wp = 0;
+ WaitEvent = WE_PLATFORM;
+ }
+ else
+ {
+ if(rand()%5) // next platform
+ {
+ DoSpawnCreature(CREATURE_EMBER_OF_ALAR, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ if(cur_wp == 3)
+ cur_wp = 0;
+ else
+ cur_wp++;
+ WaitEvent = WE_PLATFORM;
+ }
+ else // flame quill
+ {
+ cur_wp = 4;
+ WaitEvent = WE_QUILL;
+ }
+ }
+ m_creature->GetMotionMaster()->MovePoint(0, waypoint[cur_wp][0], waypoint[cur_wp][1], waypoint[cur_wp][2]);
+ WaitTimer = 0;
+ return;
+ }else Platforms_Move_Timer -= diff;
+ }
+ else
+ {
+ if(!m_creature->SelectHostilTarget() && !m_creature->getVictim())
+ return;
+
+ if(Charge_Timer < diff)
+ {
+ if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 1))
+ {
+ m_creature->SetInFront(target);
+ m_creature->GetMotionMaster()->Clear();
+ m_creature->AttackStop();
+ m_creature->SetSpeed(MOVE_RUN, 5.0f);
+ DoCast(target, SPELL_CHARGE);
+ WaitEvent = WE_CHARGE;
+ WaitTimer = 1000;
+ return;
+ }
+ Charge_Timer = 30000;
+ }else Charge_Timer -= diff;
+
+ if(MeltArmor_Timer < diff)
+ {
+ DoCast(m_creature->getVictim(), SPELL_MELT_ARMOR);
+ MeltArmor_Timer = 60000;
+ }else MeltArmor_Timer -= diff;
+
+ if(DiveBomb_Timer < diff)
+ {
+ m_creature->AttackStop();
+ m_creature->GetMotionMaster()->MovePoint(6, waypoint[4][0], waypoint[4][1], waypoint[4][2]);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 50);
+ WaitEvent = WE_METEOR;
+ WaitTimer = 0;
+ DiveBomb_Timer = 40000+rand()%5000;
+ return;
+ }else DiveBomb_Timer -= diff;
+
+ if(FlamePatch_Timer < diff)
+ {
+ if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ {
+ Creature* Summoned = m_creature->SummonCreature(CREATURE_FLAME_PATCH_ALAR, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 120000);
+ if(Summoned)
+ {
+ Summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ Summoned->SetFloatValue(OBJECT_FIELD_SCALE_X, Summoned->GetFloatValue(OBJECT_FIELD_SCALE_X)*2.5f);
+ Summoned->SetDisplayId(11686);
+ Summoned->setFaction(m_creature->getFaction());
+ Summoned->SetLevel(m_creature->getLevel());
+ Summoned->CastSpell(Summoned, SPELL_FLAME_PATCH, false);
+ }
+ }
+ FlamePatch_Timer = 30000;
+ }else FlamePatch_Timer -= diff;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ void DoMeleeAttackIfReady()
+ {
+ if(m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))
+ {
+ if(m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
+ {
+ m_creature->AttackerStateUpdate(m_creature->getVictim());
+ m_creature->resetAttackTimer();
+ }
+ else
+ {
+ Unit *target = NULL;
+ if(Phase1 && (target = m_creature->SelectNearbyTarget()) && m_creature->IsHostileTo(target)) // core bug, 1620 faction bugged
+ m_creature->AI()->AttackStart(target);
+ else
+ {
+ m_creature->CastSpell(m_creature, SPELL_FLAME_BUFFET, true);
+ m_creature->setAttackTimer(BASE_ATTACK, 1500);
+ }
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_alar(Creature *_Creature)
+{
+ return new boss_alarAI(_Creature);
+}
+
+struct TRINITY_DLL_DECL mob_ember_of_alarAI : public ScriptedAI
+{
+ mob_ember_of_alarAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = (ScriptedInstance*)c->GetInstanceData();
+ m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
+ m_creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true);
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ bool toDie;
+
+ void Reset() {toDie = false;}
+ void Aggro(Unit *who) {DoZoneInCombat();}
+ void EnterEvadeMode() {m_creature->setDeathState(JUST_DIED);}
+
+ void DamageTaken(Unit* pKiller, uint32 &damage)
+ {
+ if(damage >= m_creature->GetHealth() && pKiller != m_creature && !toDie)
+ {
+ damage = 0;
+ m_creature->CastSpell(m_creature, SPELL_EMBER_BLAST, true);
+ m_creature->SetDisplayId(11686);
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ if(pInstance && pInstance->GetData(DATA_ALAREVENT) == 2)
+ {
+ if(Unit* Alar = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_ALAR)))
+ {
+ int AlarHealth = Alar->GetHealth() - Alar->GetMaxHealth()*0.03;
+ if(AlarHealth > 0)
+ Alar->SetHealth(AlarHealth);
+ else
+ Alar->SetHealth(1);
+ }
+ }
+ toDie = true;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->SelectHostilTarget() && !m_creature->getVictim())
+ return;
+
+ if(toDie)
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ //m_creature->SetVisibility(VISIBILITY_OFF);
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+};
+
+CreatureAI* GetAI_mob_ember_of_alar(Creature *_Creature)
+{
+ return new mob_ember_of_alarAI(_Creature);
+}
+
+struct TRINITY_DLL_DECL mob_flame_patch_alarAI : public ScriptedAI
+{
+ mob_flame_patch_alarAI(Creature *c) : ScriptedAI(c) {}
+ void Reset() {}
+ void Aggro(Unit *who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff) {}
+};
+
+CreatureAI* GetAI_mob_flame_patch_alar(Creature *_Creature)
+{
+ return new mob_flame_patch_alarAI(_Creature);
+}
+
+void AddSC_boss_alar()
+{
+ Script *newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_alar";
+ newscript->GetAI = GetAI_boss_alar;
+ m_scripts[nrscripts++] = newscript;
+
+ newscript = new Script;
+ newscript->Name="mob_ember_of_alar";
+ newscript->GetAI = GetAI_mob_ember_of_alar;
+ m_scripts[nrscripts++] = newscript;
+
+ newscript = new Script;
+ newscript->Name="mob_flame_patch_alar";
+ newscript->GetAI = GetAI_mob_flame_patch_alar;
+ m_scripts[nrscripts++] = newscript;
+}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h
index 3478ae88970..9e9fe4c8b51 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/def_the_eye.h
@@ -17,4 +17,5 @@
#define DATA_SOLARIANEVENT 10
#define DATA_THALADREDTHEDARKENER 11
#define DATA_VOIDREAVEREVENT 12
+#define DATA_ALAR 13
#endif
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp
index 8c716204fb0..b2b3f76cbe6 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/instance_the_eye.cpp
@@ -6,12 +6,12 @@
*
* 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
+ * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
@@ -43,8 +43,10 @@ struct TRINITY_DLL_DECL instance_the_eye : public ScriptedInstance
uint64 MasterEngineerTelonicus;
uint64 Kaelthas;
uint64 Astromancer;
+ uint64 Alar;
uint8 KaelthasEventPhase;
+ uint8 AlarEventPhase;
bool Encounters[ENCOUNTERS];
@@ -56,8 +58,10 @@ struct TRINITY_DLL_DECL instance_the_eye : public ScriptedInstance
MasterEngineerTelonicus = 0;
Kaelthas = 0;
Astromancer = 0;
+ Alar = 0;
KaelthasEventPhase = 0;
+ AlarEventPhase = 0;
for(uint8 i = 0; i < ENCOUNTERS; i++)
Encounters[i] = false;
@@ -81,6 +85,10 @@ struct TRINITY_DLL_DECL instance_the_eye : public ScriptedInstance
case 20060: LordSanguinar = creature->GetGUID(); break;
case 19622: Kaelthas = creature->GetGUID(); break;
case 18805: Astromancer = creature->GetGUID(); break;
+
+ case 19514:
+ Alar = creature->GetGUID();
+ break;
}
}
@@ -105,6 +113,9 @@ struct TRINITY_DLL_DECL instance_the_eye : public ScriptedInstance
case DATA_ASTROMANCER:
return Astromancer;
+
+ case DATA_ALAR:
+ return Alar;
}
return 0;
@@ -115,6 +126,7 @@ struct TRINITY_DLL_DECL instance_the_eye : public ScriptedInstance
switch(type)
{
case DATA_ALAREVENT:
+ AlarEventPhase = data;
Encounters[0] = (data) ? true : false;
break;
@@ -143,7 +155,7 @@ struct TRINITY_DLL_DECL instance_the_eye : public ScriptedInstance
switch(type)
{
case DATA_ALAREVENT:
- return Encounters[0];
+ return AlarEventPhase;
case DATA_SOLARIANEVENT:
return Encounters[1];
diff --git a/src/bindings/scripts/sql/Updates/r86_trinity.sql b/src/bindings/scripts/sql/Updates/r86_trinity.sql
new file mode 100644
index 00000000000..8b1f96c1564
--- /dev/null
+++ b/src/bindings/scripts/sql/Updates/r86_trinity.sql
@@ -0,0 +1,6 @@
+update `creature_template` set `ScriptName`='boss_alar' where `entry`='19514';
+update `creature_template` set `ScriptName`='mob_ember_of_alar' where `entry`='19551';
+update `creature_template` set `ScriptName`='mob_flame_patch_alar' where `entry`='20602';
+
+update gameobject_template set scriptname = "go_manticron_cube" where entry = 181713;
+update creature_template set scriptname = "mob_abyssal" where entry = 17454; \ No newline at end of file