aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bindings/scripts/Makefile.am2
-rw-r--r--src/bindings/scripts/VC71/71ScriptDev2.vcproj8
-rw-r--r--src/bindings/scripts/VC80/80ScriptDev2.vcproj8
-rw-r--r--src/bindings/scripts/VC90/90ScriptDev2.vcproj8
-rw-r--r--src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp43
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp108
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp727
-rw-r--r--src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp605
-rw-r--r--src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp2
-rw-r--r--src/bindings/scripts/sql/Updates/r66_trinity.sql18
-rw-r--r--src/game/Unit.cpp2
11 files changed, 1450 insertions, 81 deletions
diff --git a/src/bindings/scripts/Makefile.am b/src/bindings/scripts/Makefile.am
index a08a8d078a0..feedd0e65d0 100644
--- a/src/bindings/scripts/Makefile.am
+++ b/src/bindings/scripts/Makefile.am
@@ -323,6 +323,8 @@ scripts/zone/stratholme/boss_timmy_the_cruel.cpp \
scripts/zone/stratholme/def_stratholme.h \
scripts/zone/stratholme/instance_stratholme.cpp \
scripts/zone/stratholme/stratholme.cpp \
+scripts/zone/sunwell_plateau/boss_eredar_twins.cpp \
+scripts/zone/sunwell_plateau/boss_felmyst.cpp \
scripts/zone/sunwell_plateau/boss_brutallus.cpp \
scripts/zone/sunwell_plateau/boss_kalecgos.cpp \
scripts/zone/sunwell_plateau/def_sunwell_plateau.h \
diff --git a/src/bindings/scripts/VC71/71ScriptDev2.vcproj b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
index 52dab53a239..e08a134fc01 100644
--- a/src/bindings/scripts/VC71/71ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC71/71ScriptDev2.vcproj
@@ -1926,6 +1926,14 @@
>
</File>
<File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_eredar_twins.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_felmyst.cpp"
+ >
+ </File>
+ <File
RelativePath="..\scripts\zone\sunwell_plateau\boss_kalecgos.cpp"
>
</File>
diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
index 7953c2093f3..3bbd3c61cd6 100644
--- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj
@@ -2159,6 +2159,14 @@
>
</File>
<File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_eredar_twins.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_felmyst.cpp"
+ >
+ </File>
+ <File
RelativePath="..\scripts\zone\sunwell_plateau\boss_kalecgos.cpp"
>
</File>
diff --git a/src/bindings/scripts/VC90/90ScriptDev2.vcproj b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
index 3e9a52e6401..9b65ba06917 100644
--- a/src/bindings/scripts/VC90/90ScriptDev2.vcproj
+++ b/src/bindings/scripts/VC90/90ScriptDev2.vcproj
@@ -2157,6 +2157,14 @@
>
</File>
<File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_eredar_twins.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\scripts\zone\sunwell_plateau\boss_felmyst.cpp"
+ >
+ </File>
+ <File
RelativePath="..\scripts\zone\sunwell_plateau\boss_kalecgos.cpp"
>
</File>
diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp
index 6bf64ba0036..7ab12293b0f 100644
--- a/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp
+++ b/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp
@@ -168,8 +168,7 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
if(TidalShieldTimer < diff)
{
- m_creature->InterruptNonMeleeSpells(false);
- DoCast(m_creature, SPELL_TIDAL_SHIELD, true);
+ m_creature->CastSpell(m_creature, SPELL_TIDAL_SHIELD, true);
ResetTimer(45000);
}else TidalShieldTimer -= diff;
@@ -186,11 +185,9 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
{
for(uint8 i = 0; i < 3; ++i)
{
- Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
- if(!target) target = m_creature->getVictim();
- m_creature->CastSpell(target, SPELL_NEEDLE_SPINE, true);
+ if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
+ m_creature->CastSpell(target, SPELL_NEEDLE_SPINE, true);
}
- m_creature->SetInFront(m_creature->getVictim());
NeedleSpineTimer = 30000;
}else NeedleSpineTimer -= diff;
@@ -213,24 +210,26 @@ struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI
{
Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);
if(!target) target = m_creature->getVictim();
- m_creature->CastSpell(target, SPELL_IMPALING_SPINE, true);
- m_creature->SetInFront(m_creature->getVictim());
- SpineTargetGUID = target->GetGUID();
- //must let target summon, otherwise you cannot click the spine
- target->SummonGameObject(GOBJECT_SPINE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), m_creature->GetOrientation(), 0, 0, 0, 0, 30);
-
- switch(rand()%2)
+ if(target)
{
- case 0:
- DoYell(SAY_NEEDLE1, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_NEEDLE1);
- break;
- case 1:
- DoYell(SAY_NEEDLE2, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_NEEDLE2);
- break;
+ m_creature->CastSpell(target, SPELL_IMPALING_SPINE, true);
+ SpineTargetGUID = target->GetGUID();
+ //must let target summon, otherwise you cannot click the spine
+ target->SummonGameObject(GOBJECT_SPINE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), m_creature->GetOrientation(), 0, 0, 0, 0, 30);
+
+ switch(rand()%2)
+ {
+ case 0:
+ DoYell(SAY_NEEDLE1, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_NEEDLE1);
+ break;
+ case 1:
+ DoYell(SAY_NEEDLE2, LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_NEEDLE2);
+ break;
+ }
+ ImpalingSpineTimer = 21000;
}
- ImpalingSpineTimer = 21000;
}else ImpalingSpineTimer -= diff;
DoMeleeAttackIfReady();
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp
index c14a80744d0..48f36d03ebd 100644
--- a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_brutallus.cpp
@@ -1,4 +1,4 @@
-/* Copyright © 2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
+/* Copyright ?2006,2007 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
@@ -16,49 +16,49 @@
/* ScriptData
SDName: Boss_Brutallus
-SD%Complete: 80
-SDComment: Needs intro. Talk to the dragon.
+SD%Complete: 90
+SDComment: Burn gets casted on himself and intro is missing.
EndScriptData */
#include "precompiled.h"
#include "def_sunwell_plateau.h"
// Yells and Sounds used by boss.
-#define YELL_AGGRO "Ahh! More lambs to the slaughter!"
-#define SOUND_AGGRO 12463
+#define YELL_AGGRO "Ahh! More lambs to the slaughter!"
+#define SOUND_AGGRO 12463
-#define YELL_BERSERK "So much for a real challenge... Die!"
-#define SOUND_BERSERK 12470
+#define YELL_BERSERK "So much for a real challenge... Die!"
+#define SOUND_BERSERK 12470
-#define YELL_KILL1 "Perish, insect!"
-#define SOUND_KILL1 12464
+#define YELL_KILL1 "Perish, insect!"
+#define SOUND_KILL1 12464
-#define YELL_KILL2 "You are meat!"
-#define SOUND_KILL2 12465
+#define YELL_KILL2 "You are meat!"
+#define SOUND_KILL2 12465
+
+#define YELL_KILL3 "Too easy!"
+#define SOUND_KILL3 12466
-#define YELL_KILL3 "Too easy!"
-#define SOUND_KILL3 12466
+#define YELL_CHARGE "I will crush you!"
+#define SOUND_CHARGE 12460
-#define YELL_CHARGE "I will crush you!" //I think it use this for stomp. No?
-#define SOUND_CHARGE 12460
+#define YELL_DEATH "Gah! Well done... Now... this gets... interesting..."
+#define SOUND_DEATH 12471
-#define YELL_DEATH "Gah! Well done... Now... this gets... interesting..."
-#define SOUND_DEATH 12471
+#define YELL_LOVE1 "Bring the fight to me!"
+#define SOUND_LOVE1 12467
-#define YELL_LOVE1 "Bring the fight to me!"
-#define SOUND_LOVE1 12467
+#define YELL_LOVE2 "Another day, another glorious battle!"
+#define SOUND_LOVE2 12468
-#define YELL_LOVE2 "Another day, another glorious battle!"
-#define SOUND_LOVE2 12468
-
-#define YELL_LOVE3 "I live for this!"
-#define SOUND_LOVE3 12469
+#define YELL_LOVE3 "I live for this!"
+#define SOUND_LOVE3 12469
// Boss spells.
-#define METEOR_SLASH 45150
-#define BURN 46394
-#define STOMP 45185
-#define BERSERK 26662
+#define SPELL_METEOR_SLASH 45150
+#define SPELL_BURN 46394
+#define SPELL_STOMP 45185
+#define SPELL_BERSERK 26662
struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
{
@@ -68,7 +68,6 @@ struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
uint32 BurnTimer;
uint32 StompTimer;
uint32 BerserkTimer;
- uint32 LoveTimer;
void Reset()
{
@@ -76,7 +75,6 @@ struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
StompTimer = 30000;
BurnTimer = 60000;
BerserkTimer = 360000;
- LoveTimer = 10000 + rand()%7000;
}
void Aggro(Unit *who)
@@ -115,38 +113,32 @@ struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
- if(LoveTimer < diff)
- {
- switch(rand()%3)
- {
- case 0:
- DoYell(YELL_LOVE1,LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_LOVE1);
- break;
- case 1:
- DoYell(YELL_LOVE2,LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_LOVE2);
- break;
- case 2:
- DoYell(YELL_LOVE3,LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_LOVE3);
- break;
- }
- LoveTimer = 15000 + rand()%8000;
- }else LoveTimer -= diff;
-
if(SlashTimer < diff)
{
- DoCast(m_creature->getVictim(),METEOR_SLASH);
+ DoCast(m_creature->getVictim(),SPELL_METEOR_SLASH);
SlashTimer = 11000;
}else SlashTimer -= diff;
if(StompTimer < diff)
{
- DoYell(YELL_CHARGE,LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(m_creature, SOUND_CHARGE);
- Unit *Target = m_creature->getVictim();
- DoCast(Target,STOMP);
+ switch(rand()%3)
+ {
+ case 0:
+ DoYell(YELL_LOVE1,LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_LOVE1);
+ break;
+ case 1:
+ DoYell(YELL_LOVE2,LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_LOVE2);
+ break;
+ case 2:
+ DoYell(YELL_LOVE3,LANG_UNIVERSAL, NULL);
+ DoPlaySoundToSet(m_creature, SOUND_LOVE3);
+ break;
+ }
+
+ Unit *Target = m_creature->getVictim();
+ DoCast(Target,SPELL_STOMP);
if(Target->HasAura(45151,0)) Target->RemoveAura(45151,0);
StompTimer = 30000;
}else StompTimer -= diff;
@@ -154,8 +146,8 @@ struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
if(BurnTimer < diff)
{
Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0);
- DoCast(target,BURN);
- BurnTimer = 60000;
+ //DoCast(target,SPELL_BURN);
+ BurnTimer = 60000;
}
else BurnTimer -= diff;
@@ -165,7 +157,7 @@ struct TRINITY_DLL_DECL boss_brutallusAI : public ScriptedAI
{
DoYell(YELL_BERSERK,LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_BERSERK);
- DoCast(m_creature,BERSERK);
+ DoCast(m_creature,SPELL_BERSERK);
BerserkTimer = 20000;
}
else BerserkTimer -= diff;
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp
new file mode 100644
index 00000000000..6f5b6af7969
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_eredar_twins.cpp
@@ -0,0 +1,727 @@
+/* ScriptData
+SDName: Boss_Eredar_Twins
+SD%Complete: 100
+SDComment:
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_sunwell_plateau.h"
+
+// Lady Sacrolash
+
+#define LADY_SACROLASH 25165
+
+#define SPELL_DARK_TOUCHED 45347
+#define SPELL_SHADOW_BLADES 45248//10 secs
+#define SPELL_DARK_STRIKE 45271
+#define SPELL_SHADOW_NOVA 45329//30-35 secs
+#define SPELL_CONFOUNDING_BLOW 45256//25 secs
+
+#define MOB_SHADOW_IMAGE 25214
+#define SPELL_SHADOW_FURY 45270
+#define SPELL_IMAGE_VISUAL 45263
+
+#define SOUND_INTRO 12484
+#define YELL_SHADOW_NOVA "Shadow to the aid of fire!" //only if Alythess is not dead
+#define SOUND_SHADOW_NOVA 12485
+#define YELL_SISTER_ALYTHESS_DEAD "Alythess! Your fire burns within me!"
+#define SOUND_SISTER_ALYTHESS_DEAD 12488
+#define YELL_SAC_KILL_1 "Shadow engulf."
+#define SOUND_SAC_KILL_1 12486
+#define YELL_SAC_KILL_2 "Ee-nok Kryul!"
+#define SOUND_SAC_KILL_2 12487
+#define SAY_SAC_DEAD "I... fade."
+#define YELL_ENRAGE "Time is a luxury you no longer possess!"
+
+//enrage 6 minutes
+#define SPELL_ENRAGE 46587
+//empower after sister is death
+#define SPELL_EMPOWER 45366
+
+//debuff prevents touched spell for 3 secounds
+#define SPELL_DARK_FLAME 45345
+
+//Grand Warlock Alythess
+// Don't move only spamm spells ...
+#define GRAND_WARLOCK_ALYTHESS 25166
+
+#define SPELL_PYROGENICS 45230//15secs
+#define SPELL_FLAME_TOUCHED 45348
+#define SPELL_CONFLAGRATION 45342//30-35 secs
+#define SPELL_BLAZE 45235//on main target every 3 secs
+#define SPELL_FLAME_SEAR 46771
+#define SPELL_BLAZE_SUMMON 45236 //187366 GO
+#define SPELL_BLAZE_BURN 45246
+
+#define YELL_CANFLAGRATION "Fire to the aid of shadow!" //only if Sacrolash is not dead
+#define SOUND_CANFLAGRATION 12489
+#define YELL_SISTER_SACROLASH_DEAD "Sacrolash!"
+#define SOUND_SISTER_SACROLASH_DEAD 12492
+#define YELL_ALY_KILL_1 "Fire consume."
+#define SOUND_ALY_KILL_1 12490
+#define YELL_ALY_KILL_2 "Ed-ir Halach!"
+#define SOUND_ALY_KILL_2 12491
+#define YELL_ALY_DEAD "De-ek Anur!"
+#define SOUND_ALY_DEAD 12494
+#define YELL_BERSERK "Your luck has run its curse!"
+#define SOUND_BERSERK 12493
+
+
+struct TRINITY_DLL_DECL boss_sacrolashAI : public ScriptedAI
+{
+ boss_sacrolashAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
+ Reset();
+ }
+
+ ScriptedInstance *pInstance;
+ bool InCombat;
+ bool sisterdeath;
+
+ uint32 shadowblades_timer;
+ uint32 shadownova_timer;
+ uint32 confoundingblow_timer;
+ uint32 shadowimage_timer;
+
+ uint32 conflagration_timer;
+
+
+ uint32 enrage_timer;
+
+ void Reset()
+ {
+ InCombat = false;
+ if(pInstance)
+ {
+ Unit* Temp = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_ALYTHESS));
+ if (Temp)
+ if (Temp->isDead())
+ {
+ ((Creature*)Temp)->Respawn();
+ }else
+ {
+ if(Temp->getVictim())
+ {
+ m_creature->getThreatManager().addThreat(Temp->getVictim(),0.0f);
+ InCombat = true;
+ }
+ }
+ }
+
+ if(!InCombat)
+ {
+ shadowblades_timer = 10000;
+ shadownova_timer = 30000;
+ confoundingblow_timer = 25000;
+ shadowimage_timer = 20000;
+ conflagration_timer = 30000;
+ sisterdeath = false;
+
+ enrage_timer = 360000;
+ }
+
+ }
+ void Aggro(Unit *who)
+ {
+ DoZoneInCombat();
+ if(pInstance)
+ {
+ Unit* Temp = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_ALYTHESS));
+ if (Temp && Temp->isAlive() && !(Temp->getVictim()))
+ Temp->getThreatManager().addThreat(who,0.0f);
+ }
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if(rand()%4 == 0)
+ {
+ switch (rand()%2)
+ {
+ case 0:
+ DoPlaySoundToSet(m_creature,SOUND_SAC_KILL_1);
+ DoYell(YELL_SAC_KILL_1 ,LANG_UNIVERSAL,NULL);
+ break;
+ case 1:
+ DoPlaySoundToSet(m_creature,SOUND_SAC_KILL_2);
+ DoYell(YELL_SAC_KILL_2 ,LANG_UNIVERSAL,NULL);
+ break;
+ }
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ // only if ALY death
+ if (sisterdeath)
+ {
+ DoYell(SAY_SAC_DEAD ,LANG_UNIVERSAL,NULL);
+ }
+ else
+ {
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+
+ void SpellHitTarget(Unit* target,const SpellEntry* spell)
+ {
+ switch(spell->Id)
+ {
+ case SPELL_SHADOW_BLADES:
+ case SPELL_SHADOW_NOVA:
+ case SPELL_CONFOUNDING_BLOW:
+ case SPELL_SHADOW_FURY:
+ HandleTouchedSpells(target, SPELL_DARK_TOUCHED);
+ break;
+ case SPELL_CONFLAGRATION:
+ HandleTouchedSpells(target, SPELL_FLAME_TOUCHED);
+ break;
+ }
+ }
+
+ void HandleTouchedSpells(Unit* target, uint32 TouchedType)
+ {
+ switch(TouchedType)
+ {
+ case SPELL_FLAME_TOUCHED:
+ if(!target->HasAura(SPELL_DARK_FLAME,0))
+ {
+ if(target->HasAura(SPELL_DARK_TOUCHED,0))
+ {
+ target->RemoveAurasDueToSpell(SPELL_DARK_TOUCHED);
+ target->CastSpell(target,SPELL_DARK_FLAME,true);
+ }else
+ {
+ target->CastSpell(target,SPELL_FLAME_TOUCHED,true);
+ }
+ }
+ break;
+ case SPELL_DARK_TOUCHED:
+ if(!target->HasAura(SPELL_DARK_FLAME,0))
+ {
+ if(target->HasAura(SPELL_FLAME_TOUCHED,0))
+ {
+ target->RemoveAurasDueToSpell(SPELL_FLAME_TOUCHED);
+ target->CastSpell(target,SPELL_DARK_FLAME,true);
+ }else
+ {
+ target->CastSpell(target,SPELL_DARK_TOUCHED,true);
+ }
+ }
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!sisterdeath)
+ {
+ if (pInstance)
+ {
+ Unit* Temp = NULL;
+ Temp = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_ALYTHESS));
+ if (Temp && Temp->isDead())
+ {
+ DoYell(YELL_SISTER_ALYTHESS_DEAD ,LANG_UNIVERSAL,NULL);
+ DoPlaySoundToSet(m_creature,SOUND_SISTER_ALYTHESS_DEAD);
+ sisterdeath = true;
+
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ DoCast(m_creature,SPELL_EMPOWER);
+ }
+ }
+ }
+
+ if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ return;
+
+ if(sisterdeath)
+ {
+ if (conflagration_timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ DoCast(target,SPELL_CONFLAGRATION);
+ conflagration_timer = 30000+(rand()%5000);
+ }
+ }else conflagration_timer -= diff;
+ }
+ else
+ {
+ if(shadownova_timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ DoCast(target,SPELL_SHADOW_NOVA);
+
+ if(!sisterdeath)
+ {
+ m_creature->MonsterTextEmote("directs Shadow Nova at $N",target->GetGUID(),true);
+ DoPlaySoundToSet(m_creature,SOUND_SHADOW_NOVA);
+ DoYell(YELL_SHADOW_NOVA,LANG_UNIVERSAL,NULL);
+ }
+
+ shadownova_timer= 30000+(rand()%5000);
+ }
+ }else shadownova_timer -=diff;
+ }
+
+ if(confoundingblow_timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ DoCast(target,SPELL_CONFOUNDING_BLOW);
+ confoundingblow_timer = 20000 + (rand()%5000);
+ }
+ }else confoundingblow_timer -=diff;
+
+ if(shadowimage_timer < diff)
+ {
+ Unit* target = NULL;
+ Creature* temp = NULL;
+ for(int i = 0;i<3;i++)
+ {
+ target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ temp = DoSpawnCreature(MOB_SHADOW_IMAGE,0,0,0,0,TEMPSUMMON_CORPSE_DESPAWN,10000);
+ temp->AI()->AttackStart(target);
+ }
+ shadowimage_timer = 20000;
+ }else shadowimage_timer -=diff;
+
+ if(shadowblades_timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(m_creature,SPELL_SHADOW_BLADES);
+ shadowblades_timer = 10000;
+
+ }
+ }else shadowblades_timer -=diff;
+
+ if (enrage_timer < diff)
+ {
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ DoYell(YELL_ENRAGE ,LANG_UNIVERSAL,NULL);
+ DoCast(m_creature,SPELL_ENRAGE);
+ enrage_timer = 300000;
+ }else enrage_timer -= diff;
+
+ if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))
+ {
+ //If we are within range melee the target
+ if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
+ {
+ HandleTouchedSpells(m_creature->getVictim(), SPELL_DARK_TOUCHED);
+ m_creature->AttackerStateUpdate(m_creature->getVictim());
+ m_creature->resetAttackTimer();
+ }
+ }
+ }
+};
+
+CreatureAI* GetAI_boss_sacrolash(Creature *_Creature)
+{
+ return new boss_sacrolashAI (_Creature);
+};
+
+struct TRINITY_DLL_DECL boss_alythessAI : public ScriptedAI
+{
+ boss_alythessAI(Creature *c) : ScriptedAI(c)
+ {
+ pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
+ Reset();
+ once = false;
+ }
+
+ ScriptedInstance *pInstance;
+ bool InCombat;
+ bool sisterdeath;
+ bool once;
+
+ uint32 conflagration_timer;
+ uint32 blaze_timer;
+ uint32 pyrogenics_timer;
+
+ uint32 shadownova_timer;
+ uint32 flamesear_timer;
+
+ uint32 enrage_timer;
+
+ void Reset()
+ {
+ InCombat = false;
+ if(pInstance)
+ {
+ Unit* Temp = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_SACROLASH));
+ if (Temp)
+ if (Temp->isDead())
+ {
+ ((Creature*)Temp)->Respawn();
+ }else
+ {
+ if(Temp->getVictim())
+ {
+ m_creature->getThreatManager().addThreat(Temp->getVictim(),0.0f);
+ InCombat = true;
+ }
+ }
+ }
+
+ if(!InCombat)
+ {
+ conflagration_timer = 45000;
+ blaze_timer = 100;
+ pyrogenics_timer = 15000;
+ shadownova_timer = 40000;
+ sisterdeath = false;
+ enrage_timer = 360000;
+ flamesear_timer = 15000;
+ }
+ }
+ void Aggro(Unit *who)
+ {
+ DoZoneInCombat();
+ if(pInstance)
+ {
+ Unit* Temp = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_SACROLASH));
+ if (Temp && Temp->isAlive() && !(Temp->getVictim()))
+ Temp->getThreatManager().addThreat(who,0.0f);
+ }
+ }
+
+ void AttackStart(Unit *who)
+ {
+ if (!who)
+ return;
+
+ if (who->isTargetableForAttack() && who!= m_creature)
+ {
+ if (!InCombat)
+ {
+ DoStartAttackNoMovement(who);
+ Aggro(who);
+ InCombat = true;
+ }
+ }
+ }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ if (!who || m_creature->getVictim())
+ return;
+
+ 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);
+
+ if (!InCombat)
+ {
+ DoStartAttackNoMovement(who);
+ Aggro(who);
+ InCombat = true;
+ }
+ }
+ }
+ else if (!once && m_creature->IsWithinLOSInMap(who)&& m_creature->IsWithinDistInMap(who, 30) )
+ {
+ DoPlaySoundToSet(m_creature,SOUND_INTRO);
+ once = true;
+ }
+ }
+
+ void KilledUnit(Unit *victim)
+ {
+ if(rand()%4 == 0)
+ {
+ switch (rand()%2)
+ {
+ case 0:
+ DoPlaySoundToSet(m_creature,SOUND_ALY_KILL_1);
+ DoYell(YELL_ALY_KILL_1 ,LANG_UNIVERSAL,NULL);
+ break;
+ case 1:
+ DoPlaySoundToSet(m_creature,SOUND_ALY_KILL_2);
+ DoYell(YELL_ALY_KILL_2 ,LANG_UNIVERSAL,NULL);
+ break;
+ }
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ if (sisterdeath)
+ {
+ DoYell(YELL_ALY_DEAD ,LANG_UNIVERSAL,NULL);
+ DoPlaySoundToSet(m_creature,SOUND_ALY_DEAD);
+ }
+ else
+ {
+ m_creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ }
+ }
+
+ void SpellHitTarget(Unit* target,const SpellEntry* spell)
+ {
+ switch(spell->Id)
+ {
+
+ case SPELL_BLAZE:
+ target->CastSpell(target,SPELL_BLAZE_SUMMON,true);
+ case SPELL_CONFLAGRATION:
+ case SPELL_FLAME_SEAR:
+ HandleTouchedSpells(target, SPELL_FLAME_TOUCHED);
+ break;
+ case SPELL_SHADOW_NOVA:
+ HandleTouchedSpells(target, SPELL_DARK_TOUCHED);
+ break;
+ }
+ }
+
+ void HandleTouchedSpells(Unit* target, uint32 TouchedType)
+ {
+ switch(TouchedType)
+ {
+ case SPELL_FLAME_TOUCHED:
+ if(!target->HasAura(SPELL_DARK_FLAME,0))
+ {
+ if(target->HasAura(SPELL_DARK_TOUCHED,0))
+ {
+ target->RemoveAurasDueToSpell(SPELL_DARK_TOUCHED);
+ target->CastSpell(target,SPELL_DARK_FLAME,true);
+ }else
+ {
+ target->CastSpell(target,SPELL_FLAME_TOUCHED,true);
+ }
+ }
+ break;
+ case SPELL_DARK_TOUCHED:
+ if(!target->HasAura(SPELL_DARK_FLAME,0))
+ {
+ if(target->HasAura(SPELL_FLAME_TOUCHED,0))
+ {
+ target->RemoveAurasDueToSpell(SPELL_FLAME_TOUCHED);
+ target->CastSpell(target,SPELL_DARK_FLAME,true);
+ }else
+ {
+ target->CastSpell(target,SPELL_DARK_TOUCHED,true);
+ }
+ }
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!sisterdeath)
+ {
+ if (pInstance)
+ {
+ Unit* Temp = NULL;
+ Temp = Unit::GetUnit((*m_creature),pInstance->GetData64(DATA_SACROLASH));
+ if (Temp && Temp->isDead())
+ {
+ DoYell(YELL_SISTER_SACROLASH_DEAD ,LANG_UNIVERSAL,NULL);
+ DoPlaySoundToSet(m_creature,SOUND_SISTER_SACROLASH_DEAD);
+ sisterdeath = true;
+
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ DoCast(m_creature,SPELL_EMPOWER);
+ }
+ }
+ }
+
+ if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ return;
+
+ if(sisterdeath)
+ {
+ if(shadownova_timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ DoCast(target,SPELL_SHADOW_NOVA);
+ shadownova_timer= 30000+(rand()%5000);
+ }
+ }else shadownova_timer -=diff;
+ }
+ else
+ {
+ if (conflagration_timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ Unit* target = NULL;
+ target = SelectUnit(SELECT_TARGET_RANDOM, 0);
+ DoCast(target,SPELL_CONFLAGRATION);
+ conflagration_timer = 30000+(rand()%5000);
+
+ if(!sisterdeath)
+ {
+ m_creature->MonsterTextEmote("directs Conflagration at $N",target->GetGUID(),true);
+ DoPlaySoundToSet(m_creature,SOUND_CANFLAGRATION);
+ DoYell(YELL_CANFLAGRATION,LANG_UNIVERSAL,NULL);
+ }
+
+ blaze_timer = 4000;
+ }
+ }else conflagration_timer -= diff;
+ }
+
+ if (flamesear_timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(m_creature,SPELL_FLAME_SEAR);
+ flamesear_timer = 15000;
+ }
+ }else flamesear_timer -=diff;
+
+ if (pyrogenics_timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(m_creature,SPELL_PYROGENICS,true);
+ pyrogenics_timer = 15000;
+ }
+ }else pyrogenics_timer -= diff;
+
+ if (blaze_timer < diff)
+ {
+ if (!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ DoCast(m_creature->getVictim(),SPELL_BLAZE);
+ blaze_timer = 3800;
+ }
+ }else blaze_timer -= diff;
+
+ if (enrage_timer < diff)
+ {
+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
+ DoPlaySoundToSet(m_creature,SOUND_BERSERK);
+ DoYell(YELL_BERSERK ,LANG_UNIVERSAL,NULL);
+ DoCast(m_creature,SPELL_ENRAGE);
+ enrage_timer = 300000;
+ }else enrage_timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_boss_alythess(Creature *_Creature)
+{
+ return new boss_alythessAI (_Creature);
+};
+
+struct TRINITY_DLL_DECL mob_shadow_imageAI : public ScriptedAI
+{
+ mob_shadow_imageAI(Creature *c) : ScriptedAI(c) {Reset();}
+
+ uint32 shadowfury_timer;
+ uint32 kill_timer;
+ uint32 darkstrike_timer;
+
+ void Reset()
+ {
+ shadowfury_timer = 5000 + (rand()%15000);
+ darkstrike_timer = 3000;
+ kill_timer = 15000;
+
+ }
+
+ void Aggro(Unit *who){}
+
+ void SpellHitTarget(Unit* target,const SpellEntry* spell)
+ {
+ switch(spell->Id)
+ {
+
+ case SPELL_SHADOW_FURY:
+ case SPELL_DARK_STRIKE:
+ if(!target->HasAura(SPELL_DARK_FLAME,0))
+ {
+ if(target->HasAura(SPELL_FLAME_TOUCHED,0))
+ {
+ target->RemoveAurasDueToSpell(SPELL_FLAME_TOUCHED);
+ target->CastSpell(target,SPELL_DARK_FLAME,true);
+ }else
+ {
+ target->CastSpell(target,SPELL_DARK_TOUCHED,true);
+ }
+ }
+ break;
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->HasAura(SPELL_IMAGE_VISUAL,0))
+ DoCast(m_creature,SPELL_IMAGE_VISUAL);
+
+ if(kill_timer < diff)
+ {
+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ kill_timer = 9999999;
+ }else kill_timer -=diff;
+
+ if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())
+ return;
+
+ if(shadowfury_timer < diff)
+ {
+ DoCast(m_creature,SPELL_SHADOW_FURY);
+ shadowfury_timer = 10000;
+ }else shadowfury_timer -=diff;
+
+ if(darkstrike_timer < diff)
+ {
+ if(!m_creature->IsNonMeleeSpellCasted(false))
+ {
+ //If we are within range melee the target
+ if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
+ {
+ DoCast(m_creature->getVictim(),SPELL_DARK_STRIKE);
+ }
+ }
+ darkstrike_timer = 3000;
+ }
+ else darkstrike_timer -= diff;
+ }
+};
+
+CreatureAI* GetAI_mob_shadow_image(Creature *_Creature)
+{
+ return new mob_shadow_imageAI (_Creature);
+};
+
+void AddSC_boss_eredar_twins()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_sacrolash";
+ newscript->GetAI = GetAI_boss_sacrolash;
+ m_scripts[nrscripts++] = newscript;
+
+ newscript = new Script;
+ newscript->Name="boss_alythess";
+ newscript->GetAI = GetAI_boss_alythess;
+ m_scripts[nrscripts++] = newscript;
+
+ newscript = new Script;
+ newscript->Name="mob_shadow_image";
+ newscript->GetAI = GetAI_mob_shadow_image;
+ m_scripts[nrscripts++] = newscript;
+}
diff --git a/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
new file mode 100644
index 00000000000..d0ca538d491
--- /dev/null
+++ b/src/bindings/scripts/scripts/zone/sunwell_plateau/boss_felmyst.cpp
@@ -0,0 +1,605 @@
+/* Copyright ?2006,2007 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_Felmyst
+SD%Complete: 0
+SDComment:
+EndScriptData */
+
+#include "precompiled.h"
+#include "def_sunwell_plateau.h"
+#include "player.h"
+
+// AURA
+#define AURA_SUNWELL_RADIANCE 45769
+#define AURA_NOXIOUS_FUMES 47002
+// LAND PHASE SPELL
+#define SPELL_CLEAVE 19983
+#define SPELL_CORROSION 45866
+#define SPELL_GAS_NOVA 45855
+#define SPELL_ENCAPSULATE_CHANNEL 45661
+#define SPELL_ENCAPSULATE_EFFECT 45665
+#define SPELL_ENCAPSULATE_AOE 45662
+// FLIGHT PHASE SPELL
+#define SPELL_VAPOR_SELECT 45391 // fel to player, force cast 45392, 50000y selete target
+#define SPELL_VAPOR_SUMMON 45392 // player summon vapor, radius around caster, 5y,
+#define SPELL_VAPOR_FORCE 45388 // vapor to fel, force cast 45389
+#define SPELL_VAPOR_CHANNEL 45389 // fel to vapor, green beam channel
+#define SPELL_VAPOR_TRIGGER 45411 // linked to 45389, vapor to self, trigger 45410 and 46931
+#define SPELL_VAPOR_DAMAGE 46931 // vapor damage, 4000
+#define SPELL_TRAIL_SUMMON 45410 // vapor summon trail
+#define SPELL_TRAIL_TRIGGER 45399 // trail to self, trigger 45402
+#define SPELL_TRAIL_DAMAGE 45402 // trail damage, 2000 + 2000 dot
+#define SPELL_DEAD_SUMMON 45400 // summon blazing dead, 5min
+#define SPELL_DEAD_PASSIVE 45415
+#define SPELL_FOG_BREATH 45495 // fel to self, speed burst
+#define SPELL_FOG_TRIGGER 45582 // fog to self, trigger 45782
+#define SPELL_FOG_FORCE 45782 // fog to player, force cast 45714
+#define SPELL_FOG_INFORM 45714 // player let fel cast 45717, script effect
+#define SPELL_FOG_CHARM 45717 // fel to player
+#define SPELL_FOG_CHARM2 45726 // link to 45717
+
+#define SPELL_TRANSFORM_TRIGGER 44885 // madrigosa to self, trigger 46350
+#define SPELL_TRANSFORM_VISUAL 46350 //46411stun?
+#define SPELL_TRANSFORM_FELMYST 45068 // become fel
+#define SPELL_FELMYST_SUMMON 45069
+// OTHER
+#define SPELL_BERSERK 45078
+#define SPELL_CLOUD_VISUAL 45212
+#define SPELL_CLOUD_SUMMON 45884
+
+#define MOB_FELMYST 25038
+#define MOB_BRUTALLUS
+#define MOB_KALECGOS
+#define MOB_DEAD 25268
+#define MOB_MADRIGOSA 25160
+#define MOB_FELMYST_VISUAL 25041
+#define MOB_FLIGHT_LEFT 25357
+#define MOB_FLIGHT_RIGHT 25358
+#define MOB_DEATH_CLOUD 25703
+#define MOB_VAPOR 25265
+#define MOB_VAPOR_TRAIL 25267
+
+#define YELL_BIRTH "Glory to Kil'jaeden! Death to all who oppose!"
+#define YELL_KILL1 "I kill for the master!"
+#define YELL_KILL2 "The end has come!"
+#define YELL_BREATH "Choke on your final breath!"
+#define YELL_TAKEOFF "I am stronger than ever before!"
+#define YELL_BERSERK "No more hesitation! Your fates are written!"
+#define YELL_DEATH "Kil'jaeden... will... prevail..."
+
+#define YELL_KALECGOS "Madrigosa deserved a far better fate. You did what had to be done, but this battle is far from over."
+
+enum PhaseFelmyst
+{
+ PHASE_NULL = 0,
+ PHASE_GROUND = 1,
+ PHASE_FLIGHT = 2,
+};
+
+enum EventFelmyst
+{
+ EVENT_NULL = 0,
+ EVENT_BERSERK = 1,
+
+ EVENT_CLEAVE = 2,
+ EVENT_CORROSION = 3,
+ EVENT_GAS_NOVA = 4,
+ EVENT_ENCAPSULATE = 5,
+ EVENT_FLIGHT = 6,
+
+ EVENT_FLIGHT_SEQUENCE = 2,
+ EVENT_SUMMON_DEAD = 3,
+ EVENT_SUMMON_FOG = 4
+};
+
+static EventFelmyst MaxTimer[]=
+{
+ EVENT_NULL,
+ EVENT_FLIGHT,
+ EVENT_SUMMON_FOG,
+};
+
+struct TRINITY_DLL_DECL boss_felmystAI : public ScriptedAI
+{
+ boss_felmystAI(Creature *c) : ScriptedAI(c)
+ {
+ Reset();
+
+ // wait for core patch be accepted
+ SpellEntry *TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_ENCAPSULATE_EFFECT);
+ if(TempSpell->SpellIconID == 2294)
+ TempSpell->SpellIconID = 2295;
+ TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_VAPOR_TRIGGER);
+ if((TempSpell->Attributes & SPELL_ATTR_PASSIVE) == 0)
+ TempSpell->Attributes |= SPELL_ATTR_PASSIVE;
+ TempSpell = (SpellEntry*)GetSpellStore()->LookupEntry(SPELL_FOG_CHARM2);
+ if((TempSpell->Attributes & SPELL_ATTR_PASSIVE) == 0)
+ TempSpell->Attributes |= SPELL_ATTR_PASSIVE;
+ }
+
+ PhaseFelmyst Phase;
+ EventFelmyst Event;
+ uint32 Timer[EVENT_FLIGHT + 1];
+
+ uint32 FlightCount;
+ uint32 BreathCount;
+
+ float BreathX, BreathY;
+
+ void Reset()
+ {
+ Phase = PHASE_NULL;
+ Event = EVENT_NULL;
+ Timer[EVENT_BERSERK] = 600000;
+ FlightCount = 0;
+
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10);
+ m_creature->SetFloatValue(UNIT_FIELD_COMBATREACH, 10);
+
+ DespawnSummons(MOB_VAPOR_TRAIL);
+ }
+
+ void Aggro(Unit *who)
+ {
+ DoZoneInCombat();
+ m_creature->CastSpell(m_creature, AURA_SUNWELL_RADIANCE, true);
+ m_creature->CastSpell(m_creature, AURA_NOXIOUS_FUMES, true);
+ EnterPhase(PHASE_GROUND);
+ }
+
+ void AttackStart(Unit *who)
+ {
+ if(Phase != PHASE_FLIGHT)
+ ScriptedAI::AttackStart(who);
+ }
+
+ void MoveInLineOfSight(Unit *who)
+ {
+ if(Phase != PHASE_FLIGHT)
+ ScriptedAI::MoveInLineOfSight(who);
+ }
+
+ void KilledUnit(Unit* victim)
+ {
+ switch(rand()%2)
+ {
+ case 0:
+ DoYell(YELL_KILL1,LANG_UNIVERSAL, NULL);
+ //DoPlaySoundToSet(m_creature, SOUND_KILL1);
+ break;
+ case 1:
+ DoYell(YELL_KILL2,LANG_UNIVERSAL, NULL);
+ //DoPlaySoundToSet(m_creature, SOUND_KILL2);
+ break;
+ }
+ }
+
+ void JustDied(Unit* Killer)
+ {
+ DoYell(YELL_DEATH, LANG_UNIVERSAL, NULL);
+ //DoPlaySoundToSet(m_creature, SOUND_DEATH);
+ }
+
+ void SpellHit(Unit *caster, const SpellEntry *spell)
+ {
+ // workaround for linked aura
+ /*if(spell->Id == SPELL_VAPOR_FORCE)
+ {
+ caster->CastSpell(caster, SPELL_VAPOR_TRIGGER, true);
+ }*/
+ // workaround for mind control
+ if(spell->Id == SPELL_FOG_INFORM)
+ {
+ float x, y, z;
+ caster->GetPosition(x, y, z);
+ Unit* summon = m_creature->SummonCreature(MOB_DEAD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ if(summon)
+ {
+ summon->SetMaxHealth(caster->GetMaxHealth());
+ summon->SetHealth(caster->GetMaxHealth());
+ summon->CastSpell(summon, SPELL_FOG_CHARM, true);
+ summon->CastSpell(summon, SPELL_FOG_CHARM2, true);
+ }
+ m_creature->DealDamage(caster, caster->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+ }
+
+ void JustSummoned(Creature *summon)
+ {
+ if(summon->GetEntry() == MOB_DEAD)
+ {
+ summon->AI()->AttackStart(SelectUnit(SELECT_TARGET_RANDOM, 0));
+ DoZoneInCombat(summon);
+ summon->CastSpell(summon, SPELL_DEAD_PASSIVE, true);
+ }
+ }
+
+ void MovementInform(uint32, uint32)
+ {
+ Timer[EVENT_FLIGHT_SEQUENCE] = 1;
+ }
+
+ void DamageTaken(Unit*, uint32 &damage)
+ {
+ if(Phase != PHASE_GROUND && damage >= m_creature->GetHealth())
+ damage = 0;
+ }
+
+ void EnterPhase(PhaseFelmyst NextPhase)
+ {
+ switch(NextPhase)
+ {
+ case PHASE_GROUND:
+ Timer[EVENT_CLEAVE] = 5000 + rand()%5 * 1000;
+ Timer[EVENT_CORROSION] = 10000 + rand()%10 * 1000;
+ Timer[EVENT_GAS_NOVA] = 15000 + rand()%5 * 1000;
+ Timer[EVENT_ENCAPSULATE] = 20000 + rand()%5 * 1000;
+ Timer[EVENT_FLIGHT] = 60000;
+ break;
+ case PHASE_FLIGHT:
+ Timer[EVENT_FLIGHT_SEQUENCE] = 1000;
+ Timer[EVENT_SUMMON_DEAD] = 0;
+ Timer[EVENT_SUMMON_FOG] = 0;
+ FlightCount = 0;
+ BreathCount = 0;
+ break;
+ default:
+ break;
+ }
+ Phase = NextPhase;
+ }
+
+ void HandleFlightSequence()
+ {
+ switch(FlightCount)
+ {
+ case 0:
+ m_creature->AttackStop();
+ m_creature->GetMotionMaster()->Clear(false);
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
+ m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
+ m_creature->StopMoving();
+ DoYell(YELL_TAKEOFF, LANG_UNIVERSAL, NULL);
+ //DoPlaySoundToSet(m_creature, SOUND_TAKEOFF);
+ Timer[EVENT_FLIGHT_SEQUENCE] = 2000;
+ break;
+ case 1:
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX()+1, m_creature->GetPositionY(), m_creature->GetPositionZ()+10);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+ break;
+ case 2:
+ if(Player* target = SelectRandomPlayer(50))
+ {
+ Creature* Vapor = m_creature->SummonCreature(MOB_VAPOR, target->GetPositionX()-5+rand()%10, target->GetPositionY()-5+rand()%10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
+ if(Vapor)
+ {
+ Vapor->AI()->AttackStart(target);
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->CastSpell(Vapor, SPELL_VAPOR_CHANNEL, false); // core bug
+ Vapor->CastSpell(Vapor, SPELL_VAPOR_TRIGGER, true);
+ }
+ }else EnterEvadeMode();
+ Timer[EVENT_FLIGHT_SEQUENCE] = 10000;
+ break;
+ case 3:
+ DespawnSummons(MOB_VAPOR_TRAIL);
+ //m_creature->CastSpell(m_creature, SPELL_VAPOR_SELECT); need core support
+ if(Player* target = SelectRandomPlayer(50))
+ {
+ //target->CastSpell(target, SPELL_VAPOR_SUMMON, true); need core support
+ Creature* Vapor = m_creature->SummonCreature(MOB_VAPOR, target->GetPositionX()-5+rand()%10, target->GetPositionY()-5+rand()%10, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
+ if(Vapor)
+ {
+ Vapor->AI()->AttackStart(target);
+ m_creature->InterruptNonMeleeSpells(false);
+ m_creature->CastSpell(Vapor, SPELL_VAPOR_CHANNEL, false); // core bug
+ Vapor->CastSpell(Vapor, SPELL_VAPOR_TRIGGER, true);
+ }
+ }else EnterEvadeMode();
+ Timer[EVENT_FLIGHT_SEQUENCE] = 10000;
+ break;
+ case 4:
+ DespawnSummons(MOB_VAPOR_TRAIL);
+ Timer[EVENT_FLIGHT_SEQUENCE] = 1;
+ break;
+ case 5:
+ if(Player* target = SelectRandomPlayer(80))
+ {
+ BreathX = target->GetPositionX();
+ BreathY = target->GetPositionY();
+ float x, y, z;
+ target->GetContactPoint(m_creature, x, y, z, 40);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->GetMotionMaster()->MovePoint(0, x, y, z+10);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ }else EnterEvadeMode();
+ Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+ break;
+ case 6:
+ m_creature->SetOrientation(m_creature->GetAngle(BreathX, BreathY));
+ m_creature->StopMoving();
+ DoTextEmote("takes a deep breath.", NULL);
+ Timer[EVENT_FLIGHT_SEQUENCE] = 10000;
+ break;
+ case 7:
+ m_creature->CastSpell(m_creature, SPELL_FOG_BREATH, true);
+ {
+ float x, y, z;
+ m_creature->GetPosition(x, y, z);
+ x = 2 * BreathX - x;
+ y = 2 * BreathY - y;
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ }
+ Timer[EVENT_SUMMON_FOG] = 1;
+ Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+ break;
+ case 8:
+ m_creature->RemoveAurasDueToSpell(SPELL_FOG_BREATH);
+ BreathCount++;
+ Timer[EVENT_SUMMON_FOG] = 0;
+ Timer[EVENT_FLIGHT_SEQUENCE] = 1;
+ if(BreathCount < 3) FlightCount = 4;
+ break;
+ case 9:
+ if(Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0))
+ {
+ float x, y, z;
+ target->GetContactPoint(m_creature, x, y, z);
+ m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ m_creature->GetMotionMaster()->MovePoint(0, x, y, z);
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
+ }else EnterEvadeMode();
+ Timer[EVENT_FLIGHT_SEQUENCE] = 0;
+ break;
+ case 10:
+ m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ m_creature->StopMoving();
+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
+ EnterPhase(PHASE_GROUND);
+ m_creature->AI()->AttackStart(SelectUnit(SELECT_TARGET_TOPAGGRO, 0));
+ break;
+ default:
+ break;
+ }
+ FlightCount++;
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!m_creature->SelectHostilTarget() && !m_creature->getVictim())
+ {
+ if(Phase == PHASE_FLIGHT && !m_creature->IsInEvadeMode())
+ EnterEvadeMode();
+ return;
+ }
+
+ Event = EVENT_NULL;
+ for(uint32 i = 1; i <= MaxTimer[Phase]; i++)
+ {
+ if(Timer[i])
+ if(Timer[i] <= diff)
+ {
+ if(!Event)
+ Event = (EventFelmyst)i;
+ }else Timer[i] -= diff;
+ }
+
+ if(m_creature->IsNonMeleeSpellCasted(false))
+ return;
+
+ if(Phase == PHASE_GROUND)
+ {
+ switch(Event)
+ {
+ case EVENT_BERSERK:
+ DoYell(YELL_BERSERK, LANG_UNIVERSAL, NULL);
+ //DoPlaySoundToSet(m_creature, SOUND_BERSERK);
+ m_creature->CastSpell(m_creature, SPELL_BERSERK, true);
+ Timer[EVENT_BERSERK] = 0;
+ break;
+ case EVENT_CLEAVE:
+ m_creature->CastSpell(m_creature->getVictim(), SPELL_CLEAVE, false);
+ Timer[EVENT_CLEAVE] = 5000 + rand()%5 * 1000;
+ break;
+ case EVENT_CORROSION:
+ m_creature->CastSpell(m_creature->getVictim(), SPELL_CORROSION, false);
+ Timer[EVENT_CORROSION] = 20000 + rand()%10 * 1000;
+ break;
+ case EVENT_GAS_NOVA:
+ m_creature->CastSpell(m_creature, SPELL_GAS_NOVA, false);
+ Timer[EVENT_GAS_NOVA] = 20000 + rand()%5 * 1000;
+ break;
+ case EVENT_ENCAPSULATE:
+ if(Unit* target = SelectRandomPlayer(50))
+ {
+ m_creature->CastSpell(target, SPELL_ENCAPSULATE_CHANNEL, false);
+ target->CastSpell(target, SPELL_ENCAPSULATE_EFFECT, true);// linked aura, need core patch to remove this hack
+ Timer[EVENT_ENCAPSULATE] = 25000 + rand()%5 * 1000;
+ }break;
+ case EVENT_FLIGHT:
+ EnterPhase(PHASE_FLIGHT);
+ break;
+ default:
+ DoMeleeAttackIfReady();
+ break;
+ }
+ }
+
+ if(Phase == PHASE_FLIGHT)
+ {
+ switch(Event)
+ {
+ case EVENT_BERSERK:
+ DoYell(YELL_BERSERK, LANG_UNIVERSAL, NULL);
+ //DoPlaySoundToSet(m_creature, SOUND_BERSERK);
+ m_creature->CastSpell(m_creature, SPELL_BERSERK, true);
+ Timer[EVENT_BERSERK] = 0;
+ break;
+ case EVENT_FLIGHT_SEQUENCE:
+ HandleFlightSequence();
+ break;
+ case EVENT_SUMMON_FOG:
+ {
+ float x, y, z;
+ m_creature->GetPosition(x, y, z);
+ m_creature->UpdateGroundPositionZ(x, y, z);
+ if(Creature *Fog = m_creature->SummonCreature(MOB_VAPOR_TRAIL, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 10000))
+ {
+ Fog->RemoveAurasDueToSpell(SPELL_TRAIL_TRIGGER);
+ Fog->CastSpell(Fog, SPELL_FOG_TRIGGER, true);
+ }
+ }
+ Timer[EVENT_SUMMON_FOG] = 1000;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void DespawnSummons(uint32 entry)
+ {
+ std::list<Creature*> templist;
+ float x, y, z;
+ m_creature->GetPosition(x, y, z);
+
+ {
+ CellPair pair(Trinity::ComputeCellPair(x, y));
+ Cell cell(pair);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ Trinity::AllCreaturesOfEntryInRange check(m_creature, entry, 100);
+ Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(templist, check);
+
+ TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
+
+ CellLock<GridReadGuard> cell_lock(cell, pair);
+ cell_lock->Visit(cell_lock, cSearcher, *(m_creature->GetMap()));
+ }
+
+ for(std::list<Creature*>::iterator i = templist.begin(); i != templist.end(); ++i)
+ {
+ if(entry == MOB_VAPOR_TRAIL && Phase == PHASE_FLIGHT)
+ {
+ float x, y, z;
+ (*i)->GetPosition(x, y, z);
+ m_creature->SummonCreature(MOB_DEAD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
+ }
+ (*i)->SetVisibility(VISIBILITY_OFF);
+ (*i)->setDeathState(JUST_DIED);
+ if((*i)->getDeathState() == CORPSE)
+ (*i)->RemoveCorpse();
+ }
+ }
+
+ Player* SelectRandomPlayer(float range = 0.0f)
+ {
+ Map *map = m_creature->GetMap();
+ if (!map->IsDungeon()) return NULL;
+
+ InstanceMap::PlayerList PlayerList = ((InstanceMap*)map)->GetPlayers();
+ InstanceMap::PlayerList::iterator i;
+ while(PlayerList.size())
+ {
+ i = PlayerList.begin();
+ advance(i, rand()%PlayerList.size());
+ if((range == 0.0f || m_creature->IsWithinDistInMap(*i, range))
+ && (*i)->isTargetableForAttack())
+ return *i;
+ else
+ PlayerList.erase(i);
+ }
+ return NULL;
+ }
+};
+
+struct TRINITY_DLL_DECL mob_felmyst_vaporAI : public ScriptedAI
+{
+ mob_felmyst_vaporAI(Creature *c) : ScriptedAI(c)
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->SetSpeed(MOVE_RUN, 0.8);
+ }
+ void Reset() {}
+ void Aggro(Unit* who)
+ {
+ DoZoneInCombat();
+ //m_creature->CastSpell(m_creature, SPELL_VAPOR_FORCE, true); core bug
+ }
+ void UpdateAI(const uint32 diff)
+ {
+ if(!m_creature->getVictim())
+ AttackStart(SelectUnit(SELECT_TARGET_RANDOM, 0));
+ }
+};
+
+struct TRINITY_DLL_DECL mob_felmyst_trailAI : public ScriptedAI
+{
+ mob_felmyst_trailAI(Creature *c) : ScriptedAI(c)
+ {
+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ m_creature->CastSpell(m_creature, SPELL_TRAIL_TRIGGER, true);
+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());
+ m_creature->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 0.01); // core bug
+ }
+ void Reset() {}
+ void Aggro(Unit* who) {}
+ void AttackStart(Unit* who) {}
+ void MoveInLineOfSight(Unit* who) {}
+ void UpdateAI(const uint32 diff) {}
+};
+
+CreatureAI* GetAI_boss_felmyst(Creature *_Creature)
+{
+ return new boss_felmystAI(_Creature);
+}
+
+CreatureAI* GetAI_mob_felmyst_vapor(Creature *_Creature)
+{
+ return new mob_felmyst_vaporAI(_Creature);
+}
+
+CreatureAI* GetAI_mob_felmyst_trail(Creature *_Creature)
+{
+ return new mob_felmyst_trailAI(_Creature);
+}
+
+void AddSC_boss_felmyst()
+{
+ Script *newscript;
+ newscript = new Script;
+ newscript->Name="boss_felmyst";
+ newscript->GetAI = GetAI_boss_felmyst;
+ m_scripts[nrscripts++] = newscript;
+
+ newscript = new Script;
+ newscript->Name="mob_felmyst_vapor";
+ newscript->GetAI = GetAI_mob_felmyst_vapor;
+ m_scripts[nrscripts++] = newscript;
+
+ newscript = new Script;
+ newscript->Name="mob_felmyst_trail";
+ newscript->GetAI = GetAI_mob_felmyst_trail;
+ m_scripts[nrscripts++] = newscript;
+}
diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
index dcb8113cd3d..e3efa2606ca 100644
--- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
+++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp
@@ -26,7 +26,7 @@ EndScriptData */
#define SPELL_POUNDING 34162
#define SPELL_ARCANE_ORB 34172
-#define SPELL_KNOCK_AWAY 11130
+#define SPELL_KNOCK_AWAY 25778
#define SPELL_BERSERK 27680
#define SAY_AGGRO "Alert, you are marked for extermination!"
diff --git a/src/bindings/scripts/sql/Updates/r66_trinity.sql b/src/bindings/scripts/sql/Updates/r66_trinity.sql
new file mode 100644
index 00000000000..c19fbe65b0a
--- /dev/null
+++ b/src/bindings/scripts/sql/Updates/r66_trinity.sql
@@ -0,0 +1,18 @@
+update instance_template set script = 'instance_sunwell_plateau' where map = 580;
+UPDATE creature_template SET ScriptName = 'boss_brutallus' WHERE entry = 24882;
+UPDATE `creature_template` SET `ScriptName` = 'boss_felmyst' WHERE `entry` = 25038;
+UPDATE `creature_template` SET `ScriptName` = 'mob_felmyst_vapor' WHERE `entry` = 25265;
+UPDATE `creature_template` SET `ScriptName` = 'mob_felmyst_trail' WHERE `entry` = 25267;
+update creature_template set scriptname = 'boss_sacrolash' where entry = 25165;
+update creature_template set scriptname = 'boss_alythess' where entry = 25166;
+update creature_template set scriptname = 'mob_shadow_image' where entry = 25214;
+REPLACE INTO `gameobject_template` VALUES (187366, 6, 4251, 'Blaze', '', 14, 0, 1, 0, 73, 2, 45246, 0, 1, 0, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '');
+UPDATE creature_template SET faction_H = 14, faction_A = 14, minlevel = 73, maxlevel = 73,rank = 3, flags = 33554434, flag1 = 0 WHERE entry = 25214;
+UPDATE `creature_template` SET `minlevel` = '70', `maxlevel` = '70',`faction_A` = '14', `faction_H` = '14' WHERE `entry` in (25265,25267,25268);
+UPDATE `creature_template` SET `mindmg` = '1500', `maxdmg` = '2500', `minhealth` = '40000', `maxhealth` = '40000', `baseattacktime` = '2000' WHERE `entry` = 25268;
+DELETE FROM `spell_script_target` WHERE `entry` in (44885,45388,45389,46350,45714);
+INSERT INTO `spell_script_target` VALUES ('45388', '1', '25038');
+INSERT INTO `spell_script_target` VALUES ('45389', '1', '25265');
+INSERT INTO `spell_script_target` VALUES ('44885', '1', '25160');
+INSERT INTO `spell_script_target` VALUES ('46350', '1', '25160');
+INSERT INTO `spell_script_target` VALUES ('45714', '1', '25038'); \ No newline at end of file
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index bcac14b77aa..ddce852a728 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -10647,6 +10647,7 @@ Unit* Unit::SelectNearbyTarget() const
void Unit::ApplyAttackTimePercentMod( WeaponAttackType att,float val, bool apply )
{
+ float remainingTimePct = (float)m_attackTimer[att] / (GetAttackTime(att) * m_modAttackSpeedPct[att]);
if(val > 0)
{
ApplyPercentModFloatVar(m_modAttackSpeedPct[att], val, !apply);
@@ -10657,6 +10658,7 @@ void Unit::ApplyAttackTimePercentMod( WeaponAttackType att,float val, bool apply
ApplyPercentModFloatVar(m_modAttackSpeedPct[att], -val, apply);
ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME+att,-val,apply);
}
+ m_attackTimer[att] = uint32(GetAttackTime(att) * m_modAttackSpeedPct[att] * remainingTimePct);
}
void Unit::ApplyCastTimePercentMod(float val, bool apply )