rendered paste bodyIndex: scripts/zone/black_temple/boss_bloodboil.cpp===================================================================--- scripts/zone/black_temple/boss_bloodboil.cpp (revision 272)+++ scripts/zone/black_temple/boss_bloodboil.cpp (working copy)@@ -17,14 +17,13 @@ /* ScriptData SDName: Boss_Bloodboil SD%Complete: 80-SDComment: Bloodboil not working correctly+SDComment: Bloodboil not working correctly, missing enrage SDCategory: Black Temple EndScriptData */ #include "../../sc_defines.h" #include "def_black_temple.h" #include "../../../../../game/TargetedMovementGenerator.h"-#include "../../../../../game/SpellAuras.h" //Spells #define SPELL_ACID_GEYSER 40630@@ -76,19 +75,19 @@ struct MANGOS_DLL_DECL boss_gurtogg_bloodboilAI : public ScriptedAI { boss_gurtogg_bloodboilAI(Creature *c) : ScriptedAI(c) - {- pInstance = ((ScriptedInstance*)c->GetInstanceData());- SetVariables();- }+ {+ pInstance = ((ScriptedInstance*)c->GetInstanceData());+ SetVariables();+ } - ScriptedInstance* pInstance;+ ScriptedInstance* pInstance; - uint64 TargetGUID;+ uint64 TargetGUID; - float TargetThreat;+ float TargetThreat; - uint32 BloodboilTimer;- uint32 BloodboilCount;+ uint32 BloodboilTimer;+ uint32 BloodboilCount; uint32 AcidGeyserTimer; uint32 AcidicWoundTimer; uint32 ArcingSmashTimer;@@ -120,6 +119,23 @@ PhaseChangeTimer = 60000; Phase1 = true;+ + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true); } void EnterEvadeMode()@@ -203,7 +219,7 @@ DoPlaySoundToSet(m_creature,SOUND_DEATH); } - // Note: This seems like a very complicated fix.+ // Note: This seems like a very complicated fix. The fix needs to be handled by the core, as implementation of limited-target AoE spells are still not implemented. void CastBloodboil() { // Get the Threat List@@ -238,7 +254,6 @@ { uint8 eff = spellInfo->Effect[i]; if (eff>=TOTAL_SPELL_EFFECTS)- continue; Aura *Aur = new Aura(spellInfo, i, NULL, target); target->AddAura(Aur);@@ -313,7 +328,7 @@ if(BloodboilTimer < diff) {- CastBloodboil();+ DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_BLOODBOIL); BloodboilCount++; if(BloodboilCount < 5) BloodboilTimer = 10000*BloodboilCount;Index: scripts/zone/black_temple/boss_illidan.cpp===================================================================--- scripts/zone/black_temple/boss_illidan.cpp (revision 272)+++ scripts/zone/black_temple/boss_illidan.cpp (working copy)@@ -17,7 +17,7 @@ /* ScriptData SDName: boss_illidan_stormrage SD%Complete: 90-SDComment: Eye Blast is buggy, some workarounds for Flame Crash and Parasitic Shadowfiend, unable to summon GOs.+SDComment: Eye Blast is buggy, some workarounds for Flame Crash, Flame Burst (damage portion) and Parasitic Shadowfiend, unable to summon GOs. SDCategory: Black Temple EndScriptData */ @@ -26,7 +26,6 @@ #include "def_black_temple.h" #include "../../../../../game/TargetedMovementGenerator.h" #include "../../../../../shared/WorldPacket.h"-#include "../../../../../game/SpellAuras.h" #include "../../../../../game/Player.h" #include "../../../../../game/GossipDef.h" @@ -36,89 +35,89 @@ // Intro speech with Akama #define SAY_INTRO_ILL1 "Akama... your duplicity is hardly surprising. I should have slaughtered you and your malformed brethren long ago."-#define SOUND_INTRO_ILL1 11463 // ~13 seconds+#define SOUND_INTRO_ILL1 11463 // ~13 seconds #define SAY_INTRO_AKA1 "We've come to end your reign, Illidan. My people and all of Outland shall be free!"-#define SOUND_INTRO_AKA1 11389 // ~12 seconds+#define SOUND_INTRO_AKA1 11389 // ~12 seconds #define SAY_INTRO_ILL2 "Boldly said. But I remain unconvinced."-#define SOUND_INTRO_ILL2 11464 // ~8 seconds+#define SOUND_INTRO_ILL2 11464 // ~8 seconds #define SAY_INTRO_AKA2 "The time has come! The moment is at hand!"-#define SOUND_INTRO_AKA2 11380 // ~5 seconds+#define SOUND_INTRO_AKA2 11380 // ~5 seconds #define SAY_INTRO_ILL3 "You are not prepared!" // He conjectures that your level of preparation could perhaps be improved somewhat-#define SOUND_INTRO_ILL3 11466+#define SOUND_INTRO_ILL3 11466 // Signal for Akama to leave-#define SAY_AKAMA_MINION "Come, my minions. Deal with this traitor as he deserves!"-#define SOUND_AKAMA_MINION 11465-#define SAY_AKAMA_LEAVE "I'll deal with these mongrels. Strike now, friends! Strike at the betrayer!"-#define SOUND_AKAMA_LEAVE 11390+#define SAY_AKAMA_MINION "Come, my minions. Deal with this traitor as he deserves!"+#define SOUND_AKAMA_MINION 11465+#define SAY_AKAMA_LEAVE "I'll deal with these mongrels. Strike now, friends! Strike at the betrayer!"+#define SOUND_AKAMA_LEAVE 11390 // Taunts?-#define SAY_HATRED "I can feel your hatred"-#define SOUND_HATRED 11467-#define SAY_FEAR "Give in to your fear!"-#define SOUND_FEAR 11468-#define SAY_POWER "You know nothing of power!"-#define SOUND_POWER 11469-#define SAY_ARROGANCE "Such..arrogance!"-#define SOUND_ARROGANCE 11471-#define SAY_RABBLE "I will not be touched by rabble such as you!"-#define SOUND_RABBLE 11479+#define SAY_HATRED "I can feel your hatred"+#define SOUND_HATRED 11467+#define SAY_FEAR "Give in to your fear!"+#define SOUND_FEAR 11468+#define SAY_POWER "You know nothing of power!"+#define SOUND_POWER 11469+#define SAY_ARROGANCE "Such..arrogance!"+#define SOUND_ARROGANCE 11471 // Maiev - Taunts-#define SAY_NAISHA "That is for Naisha!"-#define SOUND_NAISHA 11493-#define SAY_BLEED "Bleed as I have bled!"-#define SOUND_BLEED 11494-#define SAY_PRISON "There shall be no prison for you this time!"-#define SOUND_PRISON 11495-#define SAY_MEET_END "Meet your end, demon!"-#define SOUND_MEET_END 11500+#define SAY_NAISHA "That is for Naisha!"+#define SOUND_NAISHA 11493+#define SAY_BLEED "Bleed as I have bled!"+#define SOUND_BLEED 11494+#define SAY_PRISON "There shall be no prison for you this time!"+#define SOUND_PRISON 11495+#define SAY_MEET_END "Meet your end, demon!"+#define SOUND_MEET_END 11500 -// Attacking Maeiv-#define SAY_ATT_MAIEV "Feel the hatred of ten thousand years!"-#define SOUND_ATT_MAIEV 11470- // Self explanatory-#define SAY_KILL1 "Who shall be next to taste my blades?!"-#define SOUND_KILL1 11473-#define SAY_KILL2 "This is too easy!"-#define SOUND_KILL2 11472+#define SAY_KILL1 "Who shall be next to taste my blades?!"+#define SOUND_KILL1 11473+#define SAY_KILL2 "This is too easy!"+#define SOUND_KILL2 11472 // I think I'll fly now and let my subordinates take you on-#define SAY_PHASE2 "Behold the flames of Azzinoth!"-#define SOUND_PHASE2 11480+#define SAY_TAKEOFF "I will not be touched by rabble such as you!"+#define SOUND_TAKEOFF 11479+#define SAY_SUMMONFLAMES "Behold the flames of Azzinoth!"+#define SOUND_SUMMONFLAMES 11480 // When casting Eye Blast. Demon Fire will be appear on places that he casts this-#define SAY_EYE_BLAST "Stare into the eyes of the Betrayer!"-#define SOUND_EYE_BLAST 11481+#define SAY_EYE_BLAST "Stare into the eyes of the Betrayer!"+#define SOUND_EYE_BLAST 11481 // kk, I go big, dark and demon on you.-#define SAY_MORPH "Behold the power... of the demon within!"-#define SOUND_MORPH 11475+#define SAY_MORPH "Behold the power... of the demon within!"+#define SOUND_MORPH 11475 // I KILL!-#define SAY_ENRAGE "You've wasted too much time mortals, now you shall fall!"-#define SOUND_ENRAGE 11474+#define SAY_ENRAGE "You've wasted too much time mortals, now you shall fall!"+#define SOUND_ENRAGE 11474 // Speech when Maiev enters-#define SAY_SUMMON_MAIEV "Is this it, mortals? Is this all the fury you can muster?"-#define SOUND_SUMMON_MAIEV 11476 // ~8 seconds-#define SAY_MAIEV1 "Their fury pales before mine, Illidan. We have some unsettled business between us."-#define SOUND_MAIEV1 11491 // ~9 seconds-#define SAY_MAIEV_ILL2 "Maiev... How is this even possible?"-#define SOUND_MAIEV_ILL2 11477 // ~7 seconds-#define SAY_MAIEV2 "Ah, my long hunt is finally over. Today, Justice will be done!"-#define SOUND_MAIEV2 11492 // ~10 seconds+#define SAY_SUMMON_MAIEV "Is this it, mortals? Is this all the fury you can muster?"+#define SOUND_SUMMON_MAIEV 11476 // ~8 seconds+#define SAY_MAIEV1 "Their fury pales before mine, Illidan. We have some unsettled business between us."+#define SOUND_MAIEV1 11491 // ~9 seconds+#define SAY_MAIEV_ILL2 "Maiev... How is this even possible?"+#define SOUND_MAIEV_ILL2 11477 // ~7 seconds+#define SAY_MAIEV2 "Ah, my long hunt is finally over. Today, Justice will be done!"+#define SOUND_MAIEV2 11492 // ~10 seconds +// Attacking Maeiv+#define SAY_ATT_MAIEV "Feel the hatred of ten thousand years!"+#define SOUND_ATT_MAIEV 11470+ // Death speech-#define SAY_DEATH_MAIEV1 "Ahh... It is finished. You are beaten."-#define SOUND_DEATH_MAIEV1 11496 // ~6 seconds-#define SAY_DEATH_ILL "You have won... Maiev. But the huntress... is nothing without the hunt. You... are nothing... without me."-#define SOUND_DEATH_ILL 11478 // ~22 seconds-#define SAY_DEATH_MAIEV2 "He's right. I feel nothing. I am nothing. Farewell, champions."-#define SOUND_DEATH_MAIEV2 11497 // ~9 seconds-#define SAY_DEATH_AKA "The Light will fill these dismal halls once again. I swear it."-#define SOUND_DEATH_AKA 11387 // ~8 seconds+#define SAY_DEATH_MAIEV1 "Ahh... It is finished. You are beaten."+#define SOUND_DEATH_MAIEV1 11496 // ~6 seconds+#define SAY_DEATH_ILL "You have won... Maiev. But the huntress... is nothing without the hunt. You... are nothing... without me."+#define SOUND_DEATH_ILL 11478 // ~22 seconds+#define SAY_DEATH_MAIEV2 "He's right. I feel nothing. I am nothing. Farewell, champions."+#define SOUND_DEATH_MAIEV2 11497 // ~9 seconds+#define SAY_DEATH_AKA "The Light will fill these dismal halls once again. I swear it."+#define SOUND_DEATH_AKA 11387 // ~8 seconds /************** Spells *************/ // Normal Form@@ -170,59 +169,65 @@ #define Y_GLAIVE 305.303 #define Z_GLAIVE 354.256 -/**** Creature Summon IDs ****/-#define CREATURE_BLADE_OF_AZZINOTH 22996-#define CREATURE_FLAME_OF_AZZINOTH 22997-#define CREATURE_MAIEV_SHADOWSONG 23197-#define CREATURE_SHADOW_DEMON 23375-#define CREATURE_TARGET_TRIGGER 17474+/**** Creature Summon and Recognition IDs ****/+enum CreatureEntry+{+ EMPTY = 0,+ AKAMA = 22990,+ ILLIDAN_STORMRAGE = 22917,+ BLADE_OF_AZZINOTH = 22996,+ FLAME_OF_AZZINOTH = 22997,+ MAIEV_SHADOWSONG = 23197,+ SHADOW_DEMON = 23375,+ DEMON_FIRE = 23069,+ FLAME_CRASH = 23336,+}; struct Yells { uint32 sound; char* text;- char* creature;+ uint32 creature; uint32 timer, emote; bool Talk; }; static Yells Conversation[]= {- {SOUND_INTRO_ILL1, SAY_INTRO_ILL1, "Illidan", 8000, 0, true},- {0, NULL, "Illidan", 5000, 396, true}, - {SOUND_INTRO_AKA1, SAY_INTRO_AKA1, "Akama", 7000, 25, true},- {0, NULL, "Akama", 5000, 66, true},- {SOUND_INTRO_ILL2, SAY_INTRO_ILL2, "Illidan", 8000, 396, true},- {SOUND_INTRO_AKA2, SAY_INTRO_AKA2, "Akama", 3000, 22, true},- {0, NULL, "Akama", 2000, 15, true},- {SOUND_INTRO_ILL3, SAY_INTRO_ILL3, "Illidan", 3000, 406, true},- {0, NULL, "Empty", 1000, 0, true},- {0, NULL, "Empty", 0, 0, false},- {SOUND_SUMMON_MAIEV, SAY_SUMMON_MAIEV, "Illidan", 8000, 0, true},- {SOUND_MAIEV1, SAY_MAIEV1, "Maiev", 8000, 5, true},- {SOUND_MAIEV_ILL2, SAY_MAIEV_ILL2, "Illidan", 7000, 1, true},- {SOUND_MAIEV2, SAY_MAIEV2, "Maiev", 8000, 15, true},- {SOUND_ATT_MAIEV, SAY_ATT_MAIEV, "Illidan", 1000, 0, false},- {SOUND_DEATH_MAIEV1, SAY_DEATH_MAIEV1, "Maiev", 6000, 0, true},- {SOUND_DEATH_ILL, SAY_DEATH_ILL, "Illidan", 22000, 65, true}, // Emote death but do not kill him- {SOUND_DEATH_MAIEV2, SAY_DEATH_MAIEV2, "Maiev", 9000, 0, true},- {SOUND_DEATH_AKA, SAY_DEATH_AKA, "Akama", 8000, 0, false}+ {SOUND_INTRO_ILL1, SAY_INTRO_ILL1, ILLIDAN_STORMRAGE, 8000, 0, true},+ {0, NULL, ILLIDAN_STORMRAGE, 5000, 396, true}, + {SOUND_INTRO_AKA1, SAY_INTRO_AKA1, AKAMA, 7000, 25, true},+ {0, NULL, AKAMA, 5000, 66, true},+ {SOUND_INTRO_ILL2, SAY_INTRO_ILL2, ILLIDAN_STORMRAGE, 8000, 396, true},+ {SOUND_INTRO_AKA2, SAY_INTRO_AKA2, AKAMA, 3000, 22, true},+ {0, NULL, AKAMA, 2000, 15, true},+ {SOUND_INTRO_ILL3, SAY_INTRO_ILL3, ILLIDAN_STORMRAGE, 3000, 406, true},+ {0, NULL, EMPTY, 1000, 0, true},+ {0, NULL, EMPTY, 0, 0, false},+ {SOUND_SUMMON_MAIEV, SAY_SUMMON_MAIEV, ILLIDAN_STORMRAGE, 8000, 0, true},+ {SOUND_MAIEV1, SAY_MAIEV1, MAIEV_SHADOWSONG, 8000, 5, true},+ {SOUND_MAIEV_ILL2, SAY_MAIEV_ILL2, ILLIDAN_STORMRAGE, 7000, 1, true},+ {SOUND_MAIEV2, SAY_MAIEV2, MAIEV_SHADOWSONG, 8000, 15, true},+ {SOUND_ATT_MAIEV, SAY_ATT_MAIEV, ILLIDAN_STORMRAGE, 1000, 0, false},+ {SOUND_DEATH_MAIEV1, SAY_DEATH_MAIEV1, MAIEV_SHADOWSONG, 6000, 0, true},+ {SOUND_DEATH_ILL, SAY_DEATH_ILL, ILLIDAN_STORMRAGE, 22000, 65, true}, // Emote death but do not kill him+ {SOUND_DEATH_MAIEV2, SAY_DEATH_MAIEV2, MAIEV_SHADOWSONG, 9000, 0, true},+ {SOUND_DEATH_AKA, SAY_DEATH_AKA, AKAMA, 8000, 0, false} }; static Yells RandomTaunts[]= {- {SOUND_HATRED, SAY_HATRED, "Illidan", 0, 0, false},- {SOUND_FEAR, SAY_FEAR, "Illidan", 0, 0, false},- {SOUND_POWER, SAY_POWER, "Illidan", 0, 0, false},- {SOUND_ARROGANCE, SAY_ARROGANCE, "Illidan", 0, 0, false},- {SOUND_RABBLE, SAY_RABBLE, "Illidan", 0, 0, false}+ {SOUND_HATRED, SAY_HATRED, ILLIDAN_STORMRAGE, 0, 0, false},+ {SOUND_FEAR, SAY_FEAR, ILLIDAN_STORMRAGE, 0, 0, false},+ {SOUND_POWER, SAY_POWER, ILLIDAN_STORMRAGE, 0, 0, false},+ {SOUND_ARROGANCE, SAY_ARROGANCE, ILLIDAN_STORMRAGE, 0, 0, false} }; static Yells MaievTaunts[]= {- {11493, "That is for Naisha!", "Maiev", 0, 0, false},- {11494, "Bleed as I have bled!", "Maiev", 0, 0, false},- {11495, "There shall be no prison for you this time!", "Maiev", 0, 0, false},- {11500, "Meet your end, demon!", "Maiev", 0, 0, false},+ {SOUND_NAISHA, SAY_NAISHA, MAIEV_SHADOWSONG, 0, 0, false},+ {SOUND_BLEED, SAY_BLEED, MAIEV_SHADOWSONG, 0, 0, false},+ {SOUND_PRISON, SAY_PRISON, MAIEV_SHADOWSONG, 0, 0, false},+ {SOUND_MEET_END, SAY_MEET_END, MAIEV_SHADOWSONG, 0, 0, false} }; struct Locations@@ -241,10 +246,10 @@ static Locations EyeBlast[]= {- {653, 321, 354},- {653, 275, 354},- {702, 272, 353},- {713, 325, 353}+ {650.697, 320.128, 353.730},+ {652.799, 275.091, 353.367},+ {701.527, 273.815, 353.230},+ {709.865, 325.654, 353.322} }; static Locations CageTrap[]=@@ -266,7 +271,7 @@ static Animation DemonTransformation[]= {- {40511, 0, 1500, 0, 0, 6, true},+ {40511, 0, 1300, 0, 0, 6, true}, {40398, 40511, 4000, 0, 0, 6, true}, {0, 0, 3000, 1073741824, 21322, 6, false}, {40510, 40398, 3500, 0, 0, 6, false},@@ -277,9 +282,65 @@ {40510, 40398, 3500, 0, 0, 6, true}, {0, 0, 0, 0, 0, 8, true} };+/**** Demon Fire will be used for Eye Blast. Illidan needs to have access to it's vars and functions, so we'll set it here ****/+struct MANGOS_DLL_DECL demonfireAI : public ScriptedAI+{+ demonfireAI(Creature *c) : ScriptedAI(c) {EnterEvadeMode();}+ + bool IsWayPoint; + uint32 DemonFireTimer;+ uint32 DespawnTimer;++ void EnterEvadeMode()+ {+ IsWayPoint = false;++ DemonFireTimer = 0;+ DespawnTimer = 60000;++ m_creature->RemoveAllAuras();+ m_creature->DeleteThreatList();+ m_creature->CombatStop();+ DoGoHome();+ }+ + void AttackStart(Unit *who)+ {+ if(!who || IsWayPoint || (who->GetTypeId() == TYPEID_PLAYER))+ return;+ + if (who->isTargetableForAttack() && who!= m_creature)+ {+ //Begin melee attack if we are within range+ DoStartMeleeAttack(who);+ }+ }++ void MoveInLineOfSight(Unit *who){ return; }++ void UpdateAI(const uint32 diff)+ {+ if(IsWayPoint)+ return;++ if(DemonFireTimer < diff)+ {+ DoCast(m_creature, SPELL_DEMON_FIRE);+ DemonFireTimer = 30000;+ }else DemonFireTimer -= diff;++ if(DespawnTimer < diff)+ {+ m_creature->SetVisibility(VISIBILITY_OFF);+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);+ }else DespawnTimer -= diff;++ DoMeleeAttackIfReady();+ }+};+ /******* Functions and vars for Akama's AI ******/- struct MANGOS_DLL_SPEC npc_akama_illidanAI : public ScriptedAI { npc_akama_illidanAI(Creature* c) : ScriptedAI(c)@@ -318,7 +379,7 @@ boss_illidan_stormrageAI(Creature* c) : ScriptedAI(c) { pInstance = ((ScriptedInstance*)c->GetInstanceData());- SetVariables();+ EnterEvadeMode(); } /** Instance Data **/@@ -373,28 +434,22 @@ { if(FlameGUID[i]) {- if(InCombat)+ Unit* Flame = Unit::GetUnit((*m_creature), FlameGUID[i]);+ if(Flame) {- Unit* Flame = Unit::GetUnit((*m_creature), FlameGUID[i]);- if(Flame)- {- Flame->SetVisibility(VISIBILITY_OFF);- Flame->DealDamage(Flame, Flame->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);- }+ Flame->SetVisibility(VISIBILITY_OFF);+ Flame->DealDamage(Flame, Flame->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false); } FlameGUID[i] = 0; } if(GlaiveGUID[i]) {- if(InCombat)+ Unit* Glaive = Unit::GetUnit((*m_creature), GlaiveGUID[i]);+ if(Glaive) {- Unit* Glaive = Unit::GetUnit((*m_creature), GlaiveGUID[i]);- if(Glaive)- {- Glaive->SetVisibility(VISIBILITY_OFF);- Glaive->DealDamage(Glaive, Glaive->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);- }+ Glaive->SetVisibility(VISIBILITY_OFF);+ Glaive->DealDamage(Glaive, Glaive->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false); } GlaiveGUID[i] = 0; }@@ -458,6 +513,24 @@ //m_creature->setFaction(35); // Start him off as friendly. m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);++ // Immunities+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true); } void EnterEvadeMode()@@ -471,7 +544,7 @@ m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop();- DoGoHome();+ m_creature->GetMotionMaster()->TargetedHome(); SetVariables(); } @@ -519,6 +592,8 @@ pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, 3); // Completed IsTalking = false; InCombat = false;+ TalkCount = 0;+ TalkTimer = 0; m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } @@ -541,7 +616,7 @@ void DamageTaken(Unit *done_by, uint32 &damage) {- if(damage>m_creature->GetHealth())+ if(damage>m_creature->GetHealth()) // Don't let ourselves be killed before we do our death speech { damage = 0; m_creature->SetHealth(m_creature->GetMaxHealth()/100);@@ -592,11 +667,11 @@ float final_Y = EyeBlast[final].y; float final_Z = EyeBlast[final].z; Creature* BlastTrigger = NULL; // This mob will have fun running across the summit and spawning Demon Fires- BlastTrigger = m_creature->SummonCreature(CREATURE_TARGET_TRIGGER, initial_X, initial_Y, initial_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 40000);+ BlastTrigger = m_creature->SummonCreature(DEMON_FIRE, initial_X, initial_Y, initial_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 40000); Creature* BlueFlame = NULL; // This mob just does the Blue Flame animation. It follows close behind BlastTrigger...cosmetics ftw.- BlueFlame = m_creature->SummonCreature(CREATURE_TARGET_TRIGGER, initial_X,initial_Y,initial_Z,0,TEMPSUMMON_TIMED_DESPAWN,40000);+ BlueFlame = m_creature->SummonCreature(DEMON_FIRE, initial_X,initial_Y,initial_Z,0,TEMPSUMMON_TIMED_DESPAWN,40000); Creature* MoveTarget = NULL; // This is the mob that BlastTrigger will run towards.- MoveTarget = m_creature->SummonCreature(CREATURE_TARGET_TRIGGER,final_X,final_Y,final_Z,0,TEMPSUMMON_TIMED_DESPAWN, 40000);+ MoveTarget = m_creature->SummonCreature(DEMON_FIRE,final_X,final_Y,final_Z,0,TEMPSUMMON_TIMED_DESPAWN, 40000); if(BlastTrigger) { DoCast(BlastTrigger, SPELL_BLUE_BEAM);@@ -612,16 +687,21 @@ //BlueFlame->GetMotionMaster()->Clear(false); //BlueFlame->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*BlastTrigger)); BlueFlame->AddThreat(BlastTrigger, 1000000.0f);+ BlueFlame->AI()->AttackStart(BlastTrigger);+ BlueFlame->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*BlastTrigger)); BlastTrigger->SetHealth(100000); // Just so it won't die when attacked. BlueFlame->SetHealth(100000); } if(MoveTarget) {+ ((demonfireAI*)MoveTarget->AI())->IsWayPoint = true; MoveTarget->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); // Same reason as above two mobs... MoveTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // You know why... //BlastTrigger->GetMotionMaster()->Clear(false); //BlastTrigger->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*MoveTarget)); BlastTrigger->AddThreat(MoveTarget, 100000.0f);+ BlastTrigger->AI()->AttackStart(MoveTarget);+ BlastTrigger->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*MoveTarget)); MoveTarget->SetHealth(100000); // Same reason as BlastTrigger->SetHealth } }@@ -647,7 +727,7 @@ { std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList(); std::list<HostilReference*>::iterator i = m_threatlist.begin();- for(i = m_threatlist.begin(); i != m_threatlist.end(); ++i)+ for(i = m_threatlist.begin(); i != m_threatlist.end(); ++i) // Go through threatlist and set threat to -100% for everyone in it. { Unit* pUnit = NULL; pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());@@ -662,56 +742,50 @@ void Talk(uint32 count) { uint32 sound = Conversation[count].sound;- char* text;+ char* text = NULL; if(Conversation[count].text) text = Conversation[count].text; TalkTimer = Conversation[count].timer; uint32 emote = Conversation[count].emote; IsTalking = Conversation[count].Talk;- if(Conversation[count].creature == "Illidan")+ Creature* creature = NULL;+ uint64 GUID = 0;+ if(Conversation[count].creature == ILLIDAN_STORMRAGE)+ creature = m_creature;+ else if(Conversation[count].creature == AKAMA) {- if(text)- DoYell(text, LANG_UNIVERSAL, NULL);- m_creature->HandleEmoteCommand(emote);- if(sound)- DoPlaySoundToSet(m_creature, sound);- }- else if(Conversation[count].creature == "Akama")- { if(!AkamaGUID) { if(pInstance) { AkamaGUID = pInstance->GetData64(DATA_AKAMA);- if(!AkamaGUID) return;+ if(!AkamaGUID)+ return;+ GUID = AkamaGUID; } }-- Creature* Akama = ((Creature*)Unit::GetUnit((*m_creature), AkamaGUID));- if(Akama)- {- if(text)- Akama->Yell(text, LANG_UNIVERSAL, 0);- Akama->HandleEmoteCommand(emote);- if(sound)- DoPlaySoundToSet(Akama, sound);- }+ else GUID = AkamaGUID; }- else if(Conversation[count].creature == "Maiev")+ else if(Conversation[count].creature == MAIEV_SHADOWSONG) {- if(!MaievGUID) return;- Creature* Maiev = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID));- if(Maiev)- {- if(text)- Maiev->Yell(text, LANG_UNIVERSAL, 0);- Maiev->HandleEmoteCommand(emote);- if(sound)- DoPlaySoundToSet(Maiev, sound);- }+ if(!MaievGUID)+ return;+ GUID = MaievGUID; }- else if(Conversation[count].creature == "Empty") // This is just for special cases without speech/sounds/emotes.+ else if(Conversation[count].creature == EMPTY) // This is just for special cases without speech/sounds/emotes. return; ++ if(GUID) // Now we check if we actually specified a GUID, if so:+ creature = ((Creature*)Unit::GetUnit((*m_creature), GUID)); // we grab a pointer to that creature++ if(creature)+ {+ if(text)+ creature->Yell(text, LANG_UNIVERSAL, 0); // Have the creature yell out some text+ if(sound)+ DoPlaySoundToSet(creature, sound); // Play some sound on the creature+ creature->HandleEmoteCommand(emote); // Make the creature do some animation!+ } } void Move(float X, float Y, float Z, uint32 Time, Unit* c, uint32 flags = 0x0200)@@ -758,27 +832,27 @@ DoCast(m_creature, aura, true); if(displayid)- m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, displayid);+ m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, displayid); // It's morphin time! if(size)- m_creature->SetUInt32Value(OBJECT_FIELD_SCALE_X, size);+ m_creature->SetUInt32Value(OBJECT_FIELD_SCALE_X, size); // Let us grow! (or shrink) if(DemonTransformation[count].equip) {- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479);+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Requip warglaives if needed m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); } else {- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); // Unequip warglaives if needed m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); } if(DemonTransformation[count].phase != 8)- Phase = DemonTransformation[count].phase;+ Phase = DemonTransformation[count].phase; // Set phase properly else {- m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature->getVictim()));- if(MaievGUID) Phase = 5;+ m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature->getVictim())); // Refollow and attack our old victim+ if(MaievGUID) Phase = 5; // Depending on whether we summoned Maiev, we switch to either phase 5 or 3 else Phase = 3; } @@ -797,20 +871,20 @@ void UpdateAI(const uint32 diff) { /*** This section will handle the conversations ***/- if(IsTalking) // Is there a better way to do this without a long switch statement?+ if(IsTalking) // Somewhat more efficient using a function rather than a long switch { if(TalkTimer < diff) { switch(TalkCount) // This is only for specialized cases { case 0:- m_creature->RemoveAurasDueToSpell( SPELL_KNEEL );+ m_creature->RemoveAurasDueToSpell( SPELL_KNEEL ); // Time to stand up! break; case 8:- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479);+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Equip our warglaives! m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481);- m_creature->HandleEmoteCommand(406);- m_creature->setFaction(14);+ m_creature->HandleEmoteCommand(406); // Animate the equipping+ m_creature->setFaction(14); // Hostile if we weren't before break; case 9: if(AkamaGUID)@@ -819,9 +893,9 @@ if(Akama) { Akama->GetMotionMaster()->Clear(false);- Akama->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature));+ Akama->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature)); // Akama runs to us! m_creature->GetMotionMaster()->Clear(false);- m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature));+ m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature)); // We run to Akama! Akama->AddThreat(m_creature, 1000000.0f); AttackStart(Akama); // Start attacking Akama ((npc_akama_illidanAI*)Akama->AI())->IsTalking = false;@@ -830,7 +904,7 @@ } m_creature->RemoveAllAuras(); // Remove any auras we have on us m_creature->setFaction(14); // Make him hostile after Intro is done.- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE);+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE); // We are now attackable! break; case 11: if(MaievGUID)@@ -838,10 +912,10 @@ Unit* Maiev = Unit::GetUnit((*m_creature), MaievGUID); if(Maiev) {- Maiev->SetVisibility(VISIBILITY_ON);- Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);- Maiev->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID());- m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Maiev->GetGUID());+ Maiev->SetVisibility(VISIBILITY_ON); // Maiev is now visible+ Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); // onoz she looks like she teleported!+ Maiev->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); // Have her face us+ m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Maiev->GetGUID()); // Face her, so it's not rude =P } } break;@@ -853,8 +927,8 @@ { Maiev->GetMotionMaster()->Clear(false); Maiev->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature));+ Maiev->AddThreat(m_creature, 10000000.0f); // Have Maiev add a lot of threat on us so that players don't pull her off if they damage her via AOE Maiev->AI()->AttackStart(m_creature); // Force Maiev to attack us.- Maiev->AddThreat(m_creature, 10000000.0f); // Have Maiev add a lot of threat on us so that players don't pull her off Maiev->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } }@@ -925,60 +999,67 @@ /** Signal to change to phase 2 **/ if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 65) && (Phase == 1)) {- SummonTimer = 10000;+ DoYell(SAY_TAKEOFF, LANG_UNIVERSAL, NULL);+ DoPlaySoundToSet(m_creature, SOUND_TAKEOFF);++ SummonTimer = 10000; // SUmmon the Glaives + Flames when this decrements Phase = 2;- m_creature->SetHover(true);- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0);- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);- m_creature->GetMotionMaster()->Clear(false);+ m_creature->SetHover(true); // We now hover!+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // So players don't shoot us down+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); // ANimate our take off!+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); // We no longer wear the glaives! + m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); // since they are now channeling the flames+ m_creature->GetMotionMaster()->Clear(false); // Stop moving! } /** Signal to summon Maiev **/ if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30) && (!MaievGUID)) {- m_creature->setEmoteState(EMOTE_STATE_NONE);- m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);- Creature* Maiev = NULL;- Maiev = m_creature->SummonCreature(CREATURE_MAIEV_SHADOWSONG, m_creature->GetPositionX() + 10, m_creature->GetPositionY() + 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 0);+ m_creature->setEmoteState(EMOTE_STATE_NONE); // Stop whatever emote we might be doing+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); // Interrupt any of our spells+ Creature* Maiev = NULL; // Summon Maiev near Illidan+ Maiev = m_creature->SummonCreature(MAIEV_SHADOWSONG, m_creature->GetPositionX() + 10, m_creature->GetPositionY() + 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 0); if(Maiev) {- m_creature->GetMotionMaster()->Clear(false);+ m_creature->GetMotionMaster()->Clear(false); // STop moving, it's rude to walk and talk! m_creature->GetMotionMaster()->Idle();- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Just in case someone is unaffected by Shadow Prison DoCast(m_creature, SPELL_SHADOW_PRISON); TalkCount = 10;- IsTalking = true;+ IsTalking = true; // We are now talking/ Maiev->SetVisibility(VISIBILITY_OFF); // Leave her invisible until she has to talk MaievGUID = Maiev->GetGUID(); }+ else // If Maiev cannot be summoned, reset the encounter and post some errors to the console.+ {+ EnterEvadeMode();+ error_log("ERROR: Unable to summon Maiev Shadowsong (entry: 23197). Check your database to see if you have the proper SQL for Maiev Shadowsong (entry: 23197)");+ } } /** Time for the death speech **/ if((m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 1) && (!IsTalking)) {- DoCast(m_creature, SPELL_DEATH);- m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);- m_creature->GetMotionMaster()->Clear(false);+ DoCast(m_creature, SPELL_DEATH); // Animate his kneeling + stun him+ m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // Don't let the players interrupt our talk!+ m_creature->GetMotionMaster()->Clear(false); // No moving! m_creature->GetMotionMaster()->Idle(); if(MaievGUID) { Creature* Maiev = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID)); if(Maiev) {- Maiev->CombatStop();- Maiev->GetMotionMaster()->Clear(false);+ Maiev->CombatStop(); // Maiev shouldn't do anything either. No point in her attacking us =]+ Maiev->GetMotionMaster()->Clear(false); // Stop her from moving as well Maiev->GetMotionMaster()->Idle(); } } // Since we killed Akama before, summon him now.- Creature* Akama = DoSpawnCreature(22990, 10, 10, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 120000);+ Creature* Akama = DoSpawnCreature(AKAMA, 10, 10, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 120000); if(Akama) {- ((npc_akama_illidanAI*)Akama->AI())->RunAway = true; // Since we are resummoning him, his vars are at the default. That means he'll yell the Minions speech out. We have to avoid that like this- AkamaGUID = Akama->GetGUID();- Akama->SetVisibility(VISIBILITY_OFF);+ AkamaGUID = Akama->GetGUID(); // Overwrite old GUID+ Akama->SetVisibility(VISIBILITY_OFF); // Invisible for now, we'll make him visible during his turn to talk Akama->SetUInt32Value(UNIT_NPC_FLAGS, 0); // So they don't make him restart the event ~~ } IsTalking = true;@@ -988,13 +1069,15 @@ /***** Spells for Phase 1, 3 and 5 (Normal Form) ******/ if(Phase == 1 || Phase == 3 || Phase == 5) {- if(TauntTimer < diff)+ if(TauntTimer < diff) // His random taunt/yell timer. { uint32 random = rand()%5; char* text = RandomTaunts[random].text; uint32 sound = RandomTaunts[random].sound;- DoYell(text, LANG_UNIVERSAL, NULL);- DoPlaySoundToSet(m_creature, sound);+ if(text)+ DoYell(text, LANG_UNIVERSAL, NULL);+ if(sound)+ DoPlaySoundToSet(m_creature, sound); TauntTimer = 32000; }else TauntTimer -= diff; @@ -1012,7 +1095,7 @@ // It spawns multiple flames sometimes. Therefore, we'll do this manually. // DoCast(m_creature->getVictim(), SPELL_FLAME_CRASH); m_creature->HandleEmoteCommand(402);- Creature* FlameCrash = DoSpawnCreature(23336, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 40000);+ Creature* FlameCrash = DoSpawnCreature(FLAME_CRASH, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 40000); FlameCrashTimer = 35000; GlobalTimer += 2000; }else FlameCrashTimer -= diff;@@ -1023,9 +1106,9 @@ target = SelectUnit(SELECT_TARGET_RANDOM,1); if(target && target->isAlive()) {- DoCast(target, SPELL_PARASITIC_SHADOWFIEND);- ParasiticTargetGUID = target->GetGUID();- SummonParasiticTimer = 10000;+ DoCast(target, SPELL_PARASITIC_SHADOWFIEND); // The Parasitic Shadowfiend debuff doesn't summon 2 Shadowfiends on the target when it fades+ ParasiticTargetGUID = target->GetGUID(); // So we'll do it somewhat manually by recording the afflicted target's GUID and setting the summon timer+ SummonParasiticTimer = 10000; // Once the timer runs out, we cast the summon shadowfiend spell on the target and thereby summon the mobs. } ParasiticShadowFiendTimer = 40000; }else ParasiticShadowFiendTimer -= diff;@@ -1049,43 +1132,47 @@ { if(SummonTimer < diff) {+ DoYell(SAY_SUMMONFLAMES, LANG_UNIVERSAL, NULL);+ DoPlaySoundToSet(m_creature, SOUND_SUMMONFLAMES);+ Creature* Flame1 = NULL; Creature* Flame2 = NULL; Creature* Glaive1 = NULL; Creature* Glaive2 = NULL; // Summon Glaives.- Glaive1 = m_creature->SummonCreature(CREATURE_BLADE_OF_AZZINOTH, X_GLAIVE1, Y_GLAIVE, Z_GLAIVE, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);- Glaive2 = m_creature->SummonCreature(CREATURE_BLADE_OF_AZZINOTH, X_GLAIVE2, Y_GLAIVE, Z_GLAIVE, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);+ Glaive1 = m_creature->SummonCreature(BLADE_OF_AZZINOTH, X_GLAIVE1, Y_GLAIVE, Z_GLAIVE, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);+ Glaive2 = m_creature->SummonCreature(BLADE_OF_AZZINOTH, X_GLAIVE2, Y_GLAIVE, Z_GLAIVE, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); // Summon Flames near the Glaives and have the Glaives channel a green beam on the flames if(Glaive1) {- GlaiveGUID[0] = Glaive1->GetGUID();- Glaive1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);- Flame1 = m_creature->SummonCreature(22997, X_GLAIVE1-5, Y_GLAIVE, Z_GLAIVE, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000);+ GlaiveGUID[0] = Glaive1->GetGUID(); // We'll need the GUID to later remove the Glaive+ Glaive1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // They could be AoE'd to death if they were selectable+ Flame1 = m_creature->SummonCreature(FLAME_OF_AZZINOTH, X_GLAIVE1-5, Y_GLAIVE, Z_GLAIVE, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); // BRING ON THE FLAME! if(Flame1) { Flame1->SetUInt32Value(OBJECT_FIELD_SCALE_X, 1073741824); // Make the Flame bigger- Flame1->setFaction(m_creature->getFaction());+ Flame1->setFaction(m_creature->getFaction()); // Just in case the database has it as a different faction Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);- Flame1->Attack(target);- FlameGUID[0] = Flame1->GetGUID();- Glaive1->CastSpell(Flame1, SPELL_GREEN_BEAM, true);+ Flame1->AI()->AttackStart(target); // Attack our target!+ FlameGUID[0] = Flame1->GetGUID(); // Record GUID in order to check if they're dead later on to move to the next phase+ Glaive1->CastSpell(Flame1, SPELL_GREEN_BEAM, true); // Glaives do some random Beam type channel on it. } } + // Rinse and repeat with Glaive #2 if(Glaive2) { GlaiveGUID[1] = Glaive2->GetGUID(); Glaive2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);- Flame2 = m_creature->SummonCreature(22997, X_GLAIVE2+5, Y_GLAIVE, Z_GLAIVE, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000);+ Flame2 = m_creature->SummonCreature(FLAME_OF_AZZINOTH, X_GLAIVE2+5, Y_GLAIVE, Z_GLAIVE, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000); if(Flame2) { Flame2->SetUInt32Value(OBJECT_FIELD_SCALE_X, 1073741824); // BIG Flame Flame2->setFaction(m_creature->getFaction()); Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);- Flame2->Attack(target);+ Flame2->AI()->AttackStart(target); FlameGUID[1] = Flame2->GetGUID(); Glaive2->CastSpell(Flame2, SPELL_GREEN_BEAM, true); }@@ -1097,8 +1184,8 @@ // Check if we are hovering. Recast if we are not. if(!m_creature->isHover()) m_creature->SetHover(true); - if(!m_creature->GetMotionMaster()->empty())- m_creature->GetMotionMaster()->Clear(false);+/* if(!m_creature->GetMotionMaster()->empty())+ m_creature->GetMotionMaster()->Clear(false);*/ if(HasSummoned) {@@ -1110,6 +1197,7 @@ Unit* Flame = NULL; Flame = Unit::GetUnit((*m_creature), FlameGUID[i]); + // If the flame dies, or somehow the pointer becomes invalid, reset GUID to 0. if(!Flame || !Flame->isAlive()) FlameGUID[i] = 0; }@@ -1125,23 +1213,23 @@ Unit* Glaive = NULL; Glaive = Unit::GetUnit((*m_creature), GlaiveGUID[i]); if(Glaive)- Glaive->DealDamage(Glaive, Glaive->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);+ Glaive->DealDamage(Glaive, Glaive->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false); // No point letting the Glaives continue to exist GlaiveGUID[i] = 0;- LandTimer = 10000;- m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);+ LandTimer = 10000; // Prepare for landin!+ m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); // Interrupt any spells we might be doing *cough* DArk Barrage *cough* } } if(LandTimer) {- if(LandTimer < diff)+ if(LandTimer < diff) // Time to land! { m_creature->SetHover(false);- m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);+ m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); // anndddd touchdown! Phase = 3;- m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);- m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature->getVictim()));- m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479);+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); // We should let the raid fight us =)+ m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature->getVictim())); // Chase our victim!+ m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Re-equip our warblades! m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); }else LandTimer -= diff; return; // Do not continue past this point if LandTimer is not 0 and we are in phase 2.@@ -1239,11 +1327,18 @@ target = SelectUnit(SELECT_TARGET_RANDOM,0); if(target && target->GetTypeId() == TYPEID_PLAYER) // only on players. {- ShadowDemon = DoSpawnCreature(CREATURE_SHADOW_DEMON, 0,0,0,0,TEMPSUMMON_CORPSE_DESPAWN,0);+ ShadowDemon = DoSpawnCreature(SHADOW_DEMON, 0,0,0,0,TEMPSUMMON_CORPSE_DESPAWN,0); if(ShadowDemon) {+ ShadowDemon->AddThreat(target, 5000000.0f); ShadowDemon->AI()->AttackStart(target);- ShadowDemon->AddThreat(target, 5000000.0f);+ // Run through threatlist and give Shadow Demons targets if they kill the initial one.+ for(std::list<HostilReference*>::iterator itr = m_creature->getThreatManager().getThreatList().begin(); itr != m_creature->getThreatManager().getThreatList().end(); ++itr)+ {+ Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());+ if(pUnit && pUnit->isAlive())+ ShadowDemon->AddThreat(pUnit, 1.0f);+ } } } }@@ -1255,13 +1350,13 @@ if(ShadowBlastTimer < diff) { Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);- if(target)+ if(target && target->isAlive()) { m_creature->SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID());- DoCast(SelectUnit(SELECT_TARGET_TOPAGGRO, 0), SPELL_SHADOW_BLAST);- }- ShadowBlastTimer = 4000;- GlobalTimer += 1500;+ DoCast(target, SPELL_SHADOW_BLAST);+ ShadowBlastTimer = 4000;+ GlobalTimer += 1500;+ }else EnterEvadeMode(); // There were issues where he got stuck in demon form after raid wiped, possibly because TOPAGGRO is still there but dead? }else ShadowBlastTimer -= diff; if(FlameBurstTimer < diff)@@ -1285,6 +1380,7 @@ TransformTimer += 10000; }else EnrageTimer -= diff; + // We'll handle Cage Trap in Illidan's script for simplicity's sake if(CageTimer < diff) { if(MaievGUID)@@ -1292,13 +1388,13 @@ Unit* Maiev = Unit::GetUnit((*m_creature), MaievGUID); if(!Maiev) return; - uint32 random = rand()%7;+ uint32 random = rand()%7; // Get the location of a random cage trap float X = CageTrap[random].x; float Y = CageTrap[random].y; float Z = CageTrap[random].z;- Move(X, Y, Z, 0, Maiev);- Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true);- Maiev->CastSpell(Maiev, SPELL_CAGE_TRAP_SUMMON, false);+ Move(X, Y, Z, 0, Maiev); // Move Maiev there via our workaround+ Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); // Make it look like she 'teleported'+ Maiev->CastSpell(Maiev, SPELL_CAGE_TRAP_SUMMON, false); // summon the trap! } CageTimer = 15000; }else CageTimer -= diff;@@ -1325,7 +1421,6 @@ InCombat = false; IsTalking = false;- RunAway = false; m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 1); // Gossip flag m_creature->SetVisibility(VISIBILITY_ON);@@ -1428,7 +1523,7 @@ if(Illidan->IsInEvadeMode() && !m_creature->IsInEvadeMode()) EnterEvadeMode(); - if(((Illidan->GetHealth()*100 / Illidan->GetMaxHealth()) < 85) && (!RunAway))+ if(((Illidan->GetHealth()*100 / Illidan->GetMaxHealth()) < 85) && InCombat) { if(TalkTimer < diff) {@@ -1694,11 +1789,30 @@ FlameBlastTimer = 15000; SummonBlazeTimer = 10000; ChargeTimer = 5000;++ InCombat = false;+ + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true); } void EnterEvadeMode() {- InCombat = false;+ SetVariables(); m_creature->RemoveAllAuras(); m_creature->DeleteThreatList();@@ -1809,15 +1923,31 @@ uint64 TargetGUID; bool InCombat;- bool HasCast; void EnterEvadeMode() { TargetGUID = 0; InCombat = false;- HasCast = false; + + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true);+ m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop();@@ -1877,22 +2007,17 @@ if(m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) return; // Only cast the below on players. - if(!HasCast)+ if(!m_creature->getVictim()->HasAura(SPELL_PARALYZE, 0)) { TargetGUID = m_creature->getVictim()->GetGUID(); m_creature->AddThreat(m_creature->getVictim(), 10000000.0f); DoCast(m_creature, SPELL_SHADOW_DEMON_PASSIVE, true); DoCast(m_creature->getVictim(), SPELL_PURPLE_BEAM, true); DoCast(m_creature->getVictim(), SPELL_PARALYZE, true);- HasCast = true; }-+ // Kill our target if we're very close. if(m_creature->IsWithinDistInMap(m_creature->getVictim(), 3))- {- // Kill our target if we're very close. m_creature->DealDamage(m_creature->getVictim(), m_creature->getVictim()->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);- HasCast = false; // Just in case we aggro someone else after this- } } }; struct MANGOS_DLL_DECL flamecrashAI : public ScriptedAI@@ -1933,44 +2058,6 @@ } }; -struct MANGOS_DLL_DECL demonfireAI : public ScriptedAI-{- demonfireAI(Creature *c) : ScriptedAI(c) {EnterEvadeMode();}- - uint32 DemonFireTimer;- uint32 DespawnTimer;-- void EnterEvadeMode()- {- DemonFireTimer = 0;- DespawnTimer = 60000;-- m_creature->RemoveAllAuras();- m_creature->DeleteThreatList();- m_creature->CombatStop();- DoGoHome();- }- - void AttackStart(Unit *who){ return; }-- void MoveInLineOfSight(Unit *who){ return; }-- void UpdateAI(const uint32 diff)- {- if(DemonFireTimer < diff)- {- DoCast(m_creature, SPELL_DEMON_FIRE);- DemonFireTimer = 30000;- }else DemonFireTimer -= diff;-- if(DespawnTimer < diff)- {- m_creature->SetVisibility(VISIBILITY_OFF);- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);- }else DespawnTimer -= diff;- }-};- struct MANGOS_DLL_DECL blazeAI : public ScriptedAI { blazeAI(Creature *c) : ScriptedAI(c) {EnterEvadeMode();}Index: scripts/zone/black_temple/boss_mother_shahraz.cpp===================================================================--- scripts/zone/black_temple/boss_mother_shahraz.cpp (revision 272)+++ scripts/zone/black_temple/boss_mother_shahraz.cpp (working copy)@@ -25,6 +25,7 @@ #include "def_black_temple.h" #include "../../../../../game/Player.h" #include "../../../../../game/TargetedMovementGenerator.h"+#include "../../../../../shared/WorldPacket.h" //Spells #define SPELL_BEAM_SINISTER 40859@@ -221,6 +222,47 @@ DoPlaySoundToSet(m_creature,SOUND_DEATH); } + void TeleportPlayers()+ {+ std::list<HostilReference*> m_threatlist = m_creature->getThreatManager().getThreatList();+ if(m_threatlist.empty())+ return;+ std::list<HostilReference*>::iterator itr = m_threatlist.begin();+ std::list<Unit*> targets;+ for( ; itr != m_threatlist.end(); ++itr)+ {+ Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());+ if(pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER) && (pUnit != m_creature->getVictim()))+ targets.push_back(pUnit);+ }+ if(targets.empty() || (targets.size() < 3))+ return;+ targets.resize(3);+ uint32 random = rand()%7;+ float X = TeleportPoint[random].x;+ float Y = TeleportPoint[random].y;+ float Z = TeleportPoint[random].z;+ std::list<Unit*>::iterator i = targets.begin();+ uint32 index = 0;+ for( ; i != targets.end(); ++itr)+ {+ Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());+ if(pUnit && pUnit->isAlive())+ {+ if(index < 3)+ {+ TargetGUID[index] = pUnit->GetGUID();+ index++;+ }+ pUnit->CastSpell(pUnit, SPELL_TELEPORT_VISUAL, true);+ WorldPacket data;+ ((Player*)pUnit)->BuildTeleportAckMsg(&data, X, Y, Z, pUnit->GetOrientation());+ ((Player*)pUnit)->GetSession()->SendPacket(&data);+ ((Player*)pUnit)->SetPosition(X, Y, Z, pUnit->GetOrientation(), true);+ }+ }+ }+ void UpdateAI(const uint32 diff) { if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())@@ -303,22 +345,9 @@ // Select 3 random targets (can select same target more than once), teleport to a random location then make them cast explosions until they get away from each other. if(FatalAttractionTimer < diff) {- uint32 random = rand()%7;- float X = TeleportPoint[random].x;- float Y = TeleportPoint[random].y;- float Z = TeleportPoint[random].z; ExplosionCount = 0; - for(uint32 i = 0; i<4; i++)- {- Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);- if (target && target->GetTypeId() == TYPEID_PLAYER)- {- ((Player*)target)->TeleportTo(m_creature->GetMapId(), X, Y, Z, target->GetOrientation());- TargetGUID[i] = target->GetGUID();- target->CastSpell(target, SPELL_TELEPORT_VISUAL, true);- }- }+ TeleportPlayers(); switch(rand()%2) {Index: scripts/zone/black_temple/boss_reliquary_of_souls.cpp===================================================================--- scripts/zone/black_temple/boss_reliquary_of_souls.cpp (revision 272)+++ scripts/zone/black_temple/boss_reliquary_of_souls.cpp (working copy)@@ -29,22 +29,16 @@ //Suffering #define SUFF_SAY_FREED "Pain and suffering are all that await you!" #define SUFF_SOUND_FREED 11415- #define SUFF_SAY_AGGRO "Don't leave me alone!" #define SUFF_SOUND_AGGRO 11416- #define SUFF_SAY_SLAY1 "Look at what you make me do!" #define SUFF_SOUND_SLAY1 11417- #define SUFF_SAY_SLAY2 "I didn't ask for this!" #define SUFF_SOUND_SLAY2 11418- #define SUFF_SAY_SLAY3 "The pain is only beginning!" #define SUFF_SOUND_SLAY3 11419- #define SUFF_SAY_RECAP "I don't want to go back!" #define SUFF_SOUND_RECAP 11420- #define SUFF_SAY_AFTER "Now what do I do?" #define SUFF_SOUND_AFTER 11421 @@ -52,48 +46,34 @@ //Desire #define DESI_SAY_FREED "You can have anything you desire... for a price." #define DESI_SOUND_FREED 11408- #define DESI_SAY_SLAY1 "Fulfilment is at hand!" #define DESI_SOUND_SLAY1 11409- #define DESI_SAY_SLAY2 "Yes... you'll stay with us now..." #define DESI_SOUND_SLAY2 11410- #define DESI_SAY_SLAY3 "Your reach exceeds your grasp." #define DESI_SOUND_SLAY3 11412- #define DESI_SAY_SPEC "Be careful what you wish for..." #define DESI_SOUND_SPEC 11411- #define DESI_SAY_RECAP "I'll be waiting..." #define DESI_SOUND_RECAP 11413- #define DESI_SAY_AFTER "I won't be far..." #define DESI_SOUND_AFTER 11414 //Anger #define ANGER_SAY_FREED "Beware... I live." #define ANGER_SOUND_FREED 11399- #define ANGER_SAY_FREED2 "So... foolish." #define ANGER_SOUND_FREED2 11400- #define ANGER_SOUND_SLAY1 11401- #define ANGER_SAY_SLAY2 "Enough. No more." #define ANGER_SOUND_SLAY2 11402- #define ANGER_SAY_SPEC "On your knees!" #define ANGER_SOUND_SPEC 11403- #define ANGER_SAY_BEFORE "Beware, coward." #define ANGER_SOUND_BEFORE 11405- #define ANGER_SAY_DEATH "I won't... be... ignored." #define ANGER_SOUND_DEATH 11404 -- //Spells #define AURA_OF_SUFFERING 41292 #define AURA_OF_SUFFERING_ARMOR 42017@@ -298,6 +278,27 @@ m_creature->getThreatManager().setCurrentVictim(target->getThreatManager().getCurrentVictim()); // Set the target's current victim to ours. } + void AddImmunities(Unit* target)+ {+ if(!target)+ return;++ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ target->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true);+ } void JustDied(Unit* killer) { InCombat = false;@@ -305,7 +306,7 @@ void UpdateAI(const uint32 diff) {- if(Phase == 0)+ if(Phase == 0 || !m_creature->SelectHostilTarget()) return; if(Phase == 1)@@ -325,7 +326,9 @@ if(EssenceSuffering) {+ AddImmunities(EssenceSuffering); EssenceSuffering->AddThreat(m_creature->getVictim(), 1.0f);+ EssenceSuffering->AI()->AttackStart(m_creature->getVictim()); SufferingGUID = EssenceSuffering->GetGUID(); } @@ -422,10 +425,12 @@ if(EssenceDesire) {+ AddImmunities(EssenceDesire); Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM, 0); EssenceDesire->AddThreat(target, 1.0f);+ EssenceDesire->AI()->AttackStart(target); DesireGUID = EssenceDesire->GetGUID(); SoulDeathCount = 0; }@@ -519,11 +524,13 @@ { m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); // Ribs: open Creature* EssenceAnger = NULL;- EssenceAnger = m_creature->SummonCreature(23420, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_DEAD_DESPAWN, 0);+ EssenceAnger = m_creature->SummonCreature(23420, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5000); if(EssenceAnger) {+ AddImmunities(EssenceAnger); EssenceAnger->AddThreat(m_creature->getVictim(), 1.0f);+ EssenceAnger->AI()->AttackStart(m_creature->getVictim()); AngerGUID = EssenceAnger->GetGUID(); DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED); EssenceAnger->Yell(ANGER_SAY_FREED, LANG_UNIVERSAL, 0);Index: scripts/zone/black_temple/boss_shade_of_akama.cpp===================================================================--- scripts/zone/black_temple/boss_shade_of_akama.cpp (revision 272)+++ scripts/zone/black_temple/boss_shade_of_akama.cpp (working copy)@@ -89,8 +89,11 @@ mob_ashtongue_channelerAI(Creature* c) : ScriptedAI(c) { SetVariables();+ pInstance = ((ScriptedInstance*)c->GetInstanceData()); } + ScriptedInstance* pInstance;+ uint64 ShadeGUID; bool InCombat;@@ -127,11 +130,10 @@ { if(!InCombat) InCombat = true; - if(ShadeGUID)+ if(!ShadeGUID) {- Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);- if(Shade)- DoCast(Shade, SPELL_BEAM);+ if(pInstance)+ ShadeGUID = pInstance->GetData64(DATA_SHADEOFAKAMA); } } @@ -278,7 +280,23 @@ InCombat = false; HasKilledAkama = false; + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, SPELL_AURA_MOD_TAUNT, true);+ m_creature->SetVisibility(VISIBILITY_ON); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);Index: scripts/zone/black_temple/boss_supremus.cpp===================================================================--- scripts/zone/black_temple/boss_supremus.cpp (revision 272)+++ scripts/zone/black_temple/boss_supremus.cpp (working copy)@@ -16,8 +16,8 @@ /* ScriptData SDName: Boss_Supremus-SD%Complete: 90-SDComment: Using incorrect summon ids that are not official creature ids+SD%Complete: 98+SDComment: Missing Enrage SDCategory: Black Temple EndScriptData */ @@ -196,11 +196,11 @@ void npc_volcanoAI::UpdateAI(const uint32 diff) { // Workaround for the visual of the fireball that is spammed around the volcano. This seems to cause lots of lag and maybe client freezes?- /* if(FireballTimer < diff)+ if(FireballTimer < diff) { float X = CalculateRandomCoord(); float Y = CalculateRandomCoord();- Creature* Target = DoSpawnCreature(24550, X, Y, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 1000);+ Creature* Target = DoSpawnCreature(24550, X, Y, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 600); if(Target) { Target->SetVisibility(VISIBILITY_OFF);@@ -208,7 +208,7 @@ DoCast(Target, SPELL_VOLCANIC_FIREBALL); } FireballTimer = 500;- }else FireballTimer -= diff;*/+ }else FireballTimer -= diff; if(CheckTimer < diff) {@@ -260,6 +260,22 @@ SummonVolcanoTimer = 5000; Phase1 = true;+ + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true); } void EnterEvadeMode()Index: scripts/zone/black_temple/boss_teron_gorefiend.cpp===================================================================--- scripts/zone/black_temple/boss_teron_gorefiend.cpp (revision 272)+++ scripts/zone/black_temple/boss_teron_gorefiend.cpp (working copy)@@ -25,15 +25,13 @@ EndScriptData */ //Spells--#define SPELL_INCINERATE 40239+#define SPELL_INCINERATE 40239 #define SPELL_CRUSHING_SHADOWS 40243-#define SPELL_SHADOWBOLT 40185 +#define SPELL_SHADOWBOLT 40185 #define SPELL_PASSIVE_SHADOWFORM 41913 //Speech'n'sound- #define SAY_INTRO "I was the first, you know. For me, the wheel of death has spun many times. So much time has passed. I have a lot of catching up to do..." #define SOUND_INTRO 11512 @@ -65,12 +63,9 @@ #define SOUND_DEATH 11521 //Locations- #define Z_SUMMON 193.201141- #define X_SUMMON1 527.814087 #define Y_SUMMON1 380.843170- #define X_SUMMON2 527.814087 #define Y_SUMMON2 421.829803 @@ -196,6 +191,22 @@ HasEnraged = false; m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE); // Start off unattackable so that the intro is done properly++ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true); } void EnterEvadeMode()@@ -214,7 +225,7 @@ void AttackStart(Unit *who) {- if(!who || Intro)+ if(!who || !InCombat) return; if(who->isTargetableForAttack() && who!= m_creature)@@ -239,7 +250,7 @@ m_creature->AddThreat(who, 1.0f); } - if(!InCombat && !Intro && m_creature->IsWithinDistInMap(who, 200.0f))+ if(!InCombat && !Intro && m_creature->IsWithinDistInMap(who, 200.0f) && (who->GetTypeId() == TYPEID_PLAYER)) { if(pInstance) pInstance->SetData(DATA_TERONGOREFIENDEVENT, 1);@@ -328,7 +339,8 @@ { Unit* pUnit = Unit::GetUnit((*m_creature), AggroTargetGUID); if(pUnit) AttackStart(pUnit);- }+ }else EnterEvadeMode();+ }else AggroTimer -= diff; } Index: scripts/zone/black_temple/boss_warlord_najentus.cpp===================================================================--- scripts/zone/black_temple/boss_warlord_najentus.cpp (revision 272)+++ scripts/zone/black_temple/boss_warlord_najentus.cpp (working copy)@@ -172,6 +172,23 @@ if(pInstance) pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, 0);+ + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true); } void EnterEvadeMode()Index: scripts/zone/black_temple/illidari_council.cpp===================================================================--- scripts/zone/black_temple/illidari_council.cpp (revision 272)+++ scripts/zone/black_temple/illidari_council.cpp (working copy)@@ -25,20 +25,21 @@ #include "def_black_temple.h" #include "../../../../../game/TargetedMovementGenerator.h" -//Spells-+// High Nethermancer Zerevor's spells #define SPELL_FLAMESTRIKE 41481 #define SPELL_BLIZZARD 41482 #define SPELL_ARCANE_BOLT 41483 #define SPELL_ARCANE_EXPLOSION 41524 #define SPELL_DAMPEN_MAGIC 41478 +// Lady Malande's spells #define SPELL_EMPOWERED_SMITE 41471 #define SPELL_CIRCLE_OF_HEALING 41455 #define SPELL_REFLECTIVE_SHIELD 41475 #define SPELL_DIVINE_WRATH 41472 #define SPELL_HEAL_VISUAL 24171 +// Gathios the Shatterer's spells #define SPELL_BLESS_PROTECTION 41450 #define SPELL_BLESS_SPELLWARD 41451 #define SPELL_CONSECRATION 41541@@ -48,102 +49,73 @@ #define SPELL_CHROMATIC_AURA 41453 #define SPELL_DEVOTION_AURA 41452 +// Veras Darkshadow's spells #define SPELL_DEADLY_POISON 41485 #define SPELL_ENVENOM 41487 #define SPELL_VANISH 41479 //Speech'n'Sounds- #define SAY_GATH_AGGRO "I have better things to do!" #define SOUND_GATH_AGGRO 11422- #define SAY_GATH_SLAY "Selama am'oronor!" #define SOUND_GATH_SLAY 11423- #define SAY_GATH_COMNT "Well done!" #define SOUND_GATH_COMNT 11424- #define SAY_GATH_DEATH "Lord Illidan... I..." #define SOUND_GATH_DEATH 11425- #define SAY_GATH_SPECIAL1 "Enjoy your final moments!" #define SOUND_GATH_SPECIAL1 11426- #define SAY_GATH_SPECIAL2 "You are mine!" #define SOUND_GATH_SPECIAL2 11427- #define SAY_GATH_ENRAGE "Enough games!" #define SOUND_GATH_ENRAGE 11428 #define SAY_MALA_AGGRO "Flee, or die!" #define SOUND_MALA_AGGRO 11482- #define SAY_MALA_SLAY "My work is done." #define SOUND_MALA_SLAY 11483- #define SAY_MALA_COMNT "As it should be!" #define SOUND_MALA_COMNT 11484- #define SAY_MALA_DEATH "Destiny... awaits." #define SOUND_MALA_DEATH 11485- #define SAY_MALA_SPECIAL1 "No second chances!" #define SOUND_MALA_SPECIAL1 11486- #define SAY_MALA_SPECIAL2 "I'm full of surprises!" #define SOUND_MALA_SPECIAL2 11487- #define SAY_MALA_ENRAGE "For Quel'Thalas! For the Sunwell!" #define SOUND_MALA_ENRAGE 11488 #define SAY_ZERE_AGGRO "Common... such a crude language. Bandal!" #define SOUND_ZERE_AGGRO 11440- #define SAY_ZERE_SLAY "Shorel'aran." #define SOUND_ZERE_SLAY 11441- #define SAY_ZERE_COMNT "Belesa menoor!" #define SOUND_ZERE_COMNT 11442- #define SAY_ZERE_DEATH "Diel ma'ahn... oreindel'o" #define SOUND_ZERE_DEATH 11443- #define SAY_ZERE_SPECIAL1 "Diel fin'al" #define SOUND_ZERE_SPECIAL1 11444- #define SAY_ZERE_SPECIAL2 "Sha'amoor ara mashal?" #define SOUND_ZERE_SPECIAL2 11445- #define SAY_ZERE_ENRAGE "Sha'amoor sine menoor!" #define SOUND_ZERE_ENRAGE 11446 #define SAY_VERA_AGGRO "You wish to test me?" #define SOUND_VERA_AGGRO 11524- #define SAY_VERA_SLAY "Valiant effort!" #define SOUND_VERA_SLAY 11525- #define SAY_VERA_COMNT "A glorious kill!" #define SOUND_VERA_COMNT 11526- #define SAY_VERA_DEATH "You got lucky!" #define SOUND_VERA_DEATH 11527- #define SAY_VERA_SPECIAL1 "You're not caught up for this!" #define SOUND_VERA_SPECIAL1 11528- #define SAY_VERA_SPECIAL2 "Anar'alah belore!" #define SOUND_VERA_SPECIAL2 11529- #define SAY_VERA_ENRAGE "You wish to kill me? Hahaha, you first!" #define SOUND_VERA_ENRAGE 11530 -//Locations-#define X_VANISH 111.643913-#define Y_VANISH 561.843872-#define Z_VANISH 98.430679- struct MANGOS_DLL_DECL boss_illidari_councilAI : public ScriptedAI { boss_illidari_councilAI(Creature *c) : ScriptedAI(c) @@ -251,18 +223,52 @@ Malande = ((Creature*)Unit::GetUnit((*m_creature), Council[2])); Veras = ((Creature*)Unit::GetUnit((*m_creature), Council[3])); if(Gathios)+ { Gathios->AddThreat(target, 1.0f);+ AddImmunitiesToCouncil(Gathios);+ } if(Zerevor)+ { Zerevor->AddThreat(target, 1.0f);+ AddImmunitiesToCouncil(Zerevor);+ } if(Malande)+ { Malande->AddThreat(target, 1.0f);+ AddImmunitiesToCouncil(Malande);+ } if(Veras)+ { Veras->AddThreat(target, 1.0f);+ AddImmunitiesToCouncil(Veras);+ } pInstance->SetData(DATA_ILLIDARICOUNCILEVENT, 1); } } + void AddImmunitiesToCouncil(Unit* Member)+ {+ if(!Member)+ return;++ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); + Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM , true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR , true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_HORROR, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true);+ Member->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SNARE, true);+ }+ void UpdateAI(const uint32 diff) { if(!InCombat) return;@@ -732,8 +738,8 @@ { CastDampenMagicWorkaround(); Cooldown = 1000;- DampenMagicTimer = 2000; // Should be ~2 minutes.- ArcaneBoltTimer += 2000;+ DampenMagicTimer = 5000; // Should be ~2 minutes.+ ArcaneBoltTimer += 1000; }else DampenMagicTimer -= diff; if(ArcaneExplosionTimer < diff)@@ -1019,7 +1025,6 @@ AggroYellTimer = 0; HasVanished = false;- (*m_creature).GetMotionMaster()->Clear(false); m_creature->SetVisibility(VISIBILITY_ON); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); }Index: scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp===================================================================--- scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp (revision 272)+++ scripts/zone/caverns_of_time/hyjal/hyjalAI.cpp (working copy)@@ -29,7 +29,8 @@ NextWaveTimer = 10000; WaveCount = 0;- CheckTimer = 0;+ CheckRaidTimer = 0;+ CheckBossTimer = 0; Faction = 0; EventBegun = false;@@ -42,8 +43,6 @@ void hyjalAI::EnterEvadeMode() {- SetVariables();- m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop();@@ -61,10 +60,10 @@ if(!InCombat) {+ Talk(ATTACKED); InCombat = true; } }- } void hyjalAI::MoveInLineOfSight(Unit *who)@@ -88,6 +87,11 @@ } } +void hyjalAI::JustDied(Unit* killer)+{+ Talk(DEATH);+}+ void hyjalAI::SetFaction(uint32 faction) { Faction = faction;@@ -119,7 +123,10 @@ { Unit* pUnit = Unit::GetUnit((*m_creature), PlayerGUID); if(pUnit)+ { pCreature->AddThreat(pUnit, 10.0f);+ pCreature->AI()->AttackStart(pUnit);+ } } pCreature->AddThreat(m_creature, 1.0f);@@ -128,13 +135,16 @@ if(!FirstBossDead) BossGUID[0] = pCreature->GetGUID(); else BossGUID[1] = pCreature->GetGUID();+ CheckBossTimer = 5000; } } } - void hyjalAI::SummonNextWave(Wave wave[18], uint32 Count, uint32 faction) {+ if(rand()%6 == 0) // 1 in 6 chance we give a rally yell. Not sure if the chance is Blizzlike.+ Talk(RALLY);+ if(wave[Count].IsBoss) SummonCreature(wave[Count].Mob1, true); @@ -240,10 +250,58 @@ return 0; } +void hyjalAI::Talk(uint32 id)+{+ std::list<uint8> index;+ for(uint8 i = 0; i < 9; i++)+ {+ if(Faction == 0) // Alliance+ {+ if(JainaQuotes[i].id == id)+ index.push_back(i);+ }+ else if(Faction == 1) // Horde+ {+ if(ThrallQuotes[i].id == id)+ index.push_back(i);+ }+ }++ if(index.empty())+ return; // No quotes found, no use to continue++ uint8 ind = *(index.begin()) + rand()%index.size();++ char* Yell;+ uint32 Sound;+ if(Faction == 0) // Alliance+ {+ Yell = JainaQuotes[ind].text;+ Sound = JainaQuotes[ind].sound;+ }+ else if(Faction == 1) // Horde+ {+ Yell = ThrallQuotes[ind].text;+ Sound = ThrallQuotes[ind].sound;+ }+ if(Yell)+ DoYell(Yell, LANG_UNIVERSAL, NULL);+ if(Sound)+ DoPlaySoundToSet(m_creature, Sound);+}++void hyjalAI::Debug(char* text, ...)+{+/* if(text)+ sWorld.SendZoneText(m_creature->GetZoneId(), text); */+ if(text)+ debug_log(text);+}+ void hyjalAI::UpdateAI(const uint32 diff) { if(!EventBegun) return;-+/* if(NextWaveTimer) { if(NextWaveTimer < diff)@@ -255,8 +313,8 @@ WaveCount++; }else NextWaveTimer -= diff; }-- if(CheckTimer < diff)+*/+ if(CheckRaidTimer < diff) { if(NextWaveTimer) {@@ -284,7 +342,7 @@ { Player* member = ((Player*)Unit::GetUnit((*m_creature), itr->guid)); - if(member->GetMapId() != m_creature->GetMapId()) // Make sure they are in the same map.+ if(member && (member->GetMapId() != m_creature->GetMapId())) // Make sure they are in the same map. break; if(member && member->isAlive())@@ -292,40 +350,60 @@ else DeathCount++; + Debug("Raid Count is %d", RaidCount); RaidCount++; } if(DeathCount == RaidCount) {+ Talk(FAILED); EventBegun = false; EnterEvadeMode();+ SetVariables(); } }else { EventBegun = false; EnterEvadeMode();+ SetVariables(); } } } }+ CheckRaidTimer = 25000;+ }else CheckRaidTimer -= diff; - for(uint8 i = 0; i < 2; i++)+ if(CheckBossTimer)+ {+ if(CheckBossTimer < diff) {- if(BossGUID[i])+ Debug("Checking for boss deaths...");+ for(uint8 i = 0; i < 2; i++) {- Unit* pUnit = Unit::GetUnit((*m_creature), BossGUID[i]);- if(pUnit && (!pUnit->isAlive()))+ if(BossGUID[i]) {- if(BossGUID[i] == BossGUID[0])- FirstBossDead = true;- else if(BossGUID[i] == BossGUID[1])- SecondBossDead = true;- m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 1);- BossGUID[i] = 0;+ Unit* pUnit = Unit::GetUnit((*m_creature), BossGUID[i]);+ if(pUnit && (!pUnit->isAlive()))+ {+ Debug("Boss death detected...");+ if(BossGUID[i] == BossGUID[0])+ {+ Talk(INCOMING);+ FirstBossDead = true;+ }+ else if(BossGUID[i] == BossGUID[1])+ {+ Talk(SUCCESS);+ SecondBossDead = true;+ }+ CheckBossTimer = 0;+ m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 1);+ BossGUID[i] = 0;+ } }+ CheckBossTimer = 5000; }- }- CheckTimer = 25000;- }else CheckTimer -= diff;+ }else CheckBossTimer -= diff;+ } if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return; Index: scripts/zone/caverns_of_time/hyjal/hyjalAI.h===================================================================--- scripts/zone/caverns_of_time/hyjal/hyjalAI.h (revision 272)+++ scripts/zone/caverns_of_time/hyjal/hyjalAI.h (working copy)@@ -18,6 +18,8 @@ #include "../../../../../../game/Player.h" #include "../../../../../../game/Group.h" #include "../../../../../../game/GossipDef.h"+//#include "../../../../../../game/World.h"+//#include "../../../../../../game/WorldSession.h" // Trash Mobs summoned in waves #define NECROMANCER 17899@@ -138,26 +140,28 @@ static Yells JainaQuotes[]= {- {ATTACKED, "I'm in jeopardy, help me if you can!", 0},- {ATTACKED, "They've broken through!", 0},- {INCOMING, "Stay alert! Another wave approaches.", 0},- {RALLY, "Don't give up! We must prevail!", 0},- {RALLY, "We must hold strong!", 0},- {FAILED, "We are lost. Fall back!", 0},- {SUCCESS, "We have won valuable time. Now we must pull back!", 0},- {SUCCESS, "We have played our part and done well. It is up to the others now.", 0},- {DEATH, "I did... my best.", 0},+ {ATTACKED, "I'm in jeopardy, help me if you can!", 11007},+ {ATTACKED, "They've broken through!", 11049},+ {INCOMING, "Stay alert! Another wave approaches.", 11008},+ {RALLY, "Don't give up! We must prevail!", 11006},+ {RALLY, "Hold them back as long as possible", 11050},+ {RALLY, "We must hold strong!", 11051},+ {FAILED, "We are lost. Fall back!", 11009},+ {SUCCESS, "We have won valuable time. Now we must pull back!", 11011},+ {DEATH, "I did... my best.", 11010}, }; static Yells ThrallQuotes[]= { - {ATTACKED, "I will lie down for no one!", 0},- {ATTACKED, "Bring the fight to me and pay with your lives!", 0},- {INCOMING, "Make ready for another wave! Lok-Tar Ogar!", 0},- {RALLY, "Hold them back! Do not falter!", 0},- {RALLY, "Victory or death!", 0},- {RALLY, "Do not give an inch of ground!", 0},- {FAILED, "It is over. Withdraw! We have failed.", 0},+ {ATTACKED, "I will lie down for no one!", 11031},+ {ATTACKED, "Bring the fight to me and pay with your lives!", 11051},+ {INCOMING, "Make ready for another wave! LOK-TAR OGAR!", 11032},+ {RALLY, "Hold them back! Do not falter!", 11030},+ {RALLY, "Victory or death!", 11059},+ {RALLY, "Do not give an inch of ground!", 11060},+ {FAILED, "It is over. Withdraw! We have failed.", 11033},+ {SUCCESS, "We have played our part and done well. It is up to the others now.", 11035},+ {DEATH, "Uraaa...", 11034}, }; struct MANGOS_DLL_DECL hyjalAI : public ScriptedAI@@ -174,6 +178,8 @@ void UpdateAI(const uint32 diff); + void JustDied(Unit* killer);+ void SetFaction(uint32 faction); void TeleportRaid(Player *player, float X, float Y, float Z);@@ -189,6 +195,8 @@ uint32 GetInstanceData(uint32 Event); void Talk(uint32 id);++ void Debug(char* text, ...); public: ScriptedInstance* pInstance; @@ -197,7 +205,8 @@ uint32 NextWaveTimer; uint32 WaveCount;- uint32 CheckTimer;+ uint32 CheckRaidTimer;+ uint32 CheckBossTimer; uint32 Faction; bool EventBegun;@@ -206,4 +215,4 @@ private: bool InCombat;-};+};\ No newline at end of fileIndex: scripts/zone/caverns_of_time/hyjal/npc_hyjal.cpp===================================================================--- scripts/zone/caverns_of_time/hyjal/npc_hyjal.cpp (revision 272)+++ scripts/zone/caverns_of_time/hyjal/npc_hyjal.cpp (working copy)@@ -170,4 +170,4 @@ newscript->Name = "npc_tyrande_whisperwind"; newscript->pGossipHello = &GossipHello_npc_tyrande_whisperwind; m_scripts[nrscripts++] = newscript;-}+}\ No newline at end of file