Changeset 57

Show
Ignore:
Timestamp:
11/19/08 13:29:59 (17 years ago)
Author:
yumileroy
Message:

[svn] Update some Black Temple boss scripts.
Implement some Black Temple boss spells.
Update maiden of virtue and void reaver scripts. Patch provided by Blaymoira.

Original author: megamage
Date: 2008-10-18 16:25:58-05:00

Location:
trunk/src
Files:
10 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp

    r48 r57  
    1818SDName: boss_illidan_stormrage 
    1919SD%Complete: 90 
    20 SDComment: 
     20SDComment: Somewhat of a workaround for Parasitic Shadowfiend, unable to summon GOs for Cage Trap. 
    2121SDCategory: Black Temple 
    2222EndScriptData */ 
     
    2424#include "precompiled.h" 
    2525#include "def_black_temple.h" 
    26 #include "WorldPacket.h" 
     26 
     27#define GETGO(obj, guid)      GameObject* obj = GameObject::GetGameObject(*m_creature, guid) 
     28#define GETUNIT(unit, guid)   Unit* unit = Unit::GetUnit(*m_creature, guid) 
     29#define GETCRE(cre, guid)     Creature* cre = (Creature*)Unit::GetUnit(*m_creature, guid) 
     30#define HPPCT(unit)           unit->GetHealth()*100 / unit->GetMaxHealth() 
    2731 
    2832/************* Quotes and Sounds ***********************/ 
    2933// Gossip for when a player clicks Akama 
    30 #define GOSSIP_ITEM          "We are ready to face Illidan" 
     34#define GOSSIP_ITEM           "We are ready to face Illidan" 
    3135 
    3236// Yells for/by Akama 
     
    6468/************** Spells *************/ 
    6569// Normal Form 
    66 #define SPELL_SHEAR                     41032               // Reduces Max. Health by 60% for 7 seconds. Can stack 19 times. 1.5 second cast 
    67 #define SPELL_FLAME_CRASH               40832               // Summons an invis/unselect passive mob that has an aura of flame in a circle around him. 
    68 #define SPELL_DRAW_SOUL                 40904               // 5k Shadow Damage in front of him. Heals Illidan for 100k health (script effect) 
    69 #define SPELL_PARASITIC_SHADOWFIEND     41917               // DoT of 3k Shadow every 2 seconds. Lasts 10 seconds. (Script effect: Summon 2 parasites once the debuff has ticked off) 
    70 #define SPELL_SUMMON_PARASITICS         41915               // Summons 2 Parasitic Shadowfiends on the target. It's supposed to be cast as soon as the Parasitic Shadowfiend debuff is gone, but the spells aren't linked :( 
    71 #define SPELL_AGONIZING_FLAMES          40932               // 4k fire damage initial to target and anyone w/i 5 yards. PHASE 3 ONLY 
    72 #define SPELL_ENRAGE                    40683               // Increases damage by 50% and attack speed by 30%. 20 seconds, PHASE 5 ONLY 
     70#define SPELL_SHEAR                     37335 // 41032 is bugged, cannot be block/dodge/parry// Reduces Max. Health by 60% for 7 seconds. Can stack 19 times. 1.5 second cast 
     71#define SPELL_FLAME_CRASH               40832 // Summons an invis/unselect passive mob that has an aura of flame in a circle around him. 
     72#define SPELL_DRAW_SOUL                 40904 // 5k Shadow Damage in front of him. Heals Illidan for 100k health (script effect) 
     73#define SPELL_PARASITIC_SHADOWFIEND     41917 // DoT of 3k Shadow every 2 seconds. Lasts 10 seconds. (Script effect: Summon 2 parasites once the debuff has ticked off) 
     74#define SPELL_SUMMON_PARASITICS         41915 // Summons 2 Parasitic Shadowfiends on the target. It's supposed to be cast as soon as the Parasitic Shadowfiend debuff is gone, but the spells aren't linked :( 
     75#define SPELL_AGONIZING_FLAMES          40932 // 4k fire damage initial to target and anyone w/i 5 yards. PHASE 3 ONLY 
     76#define SPELL_ENRAGE                    40683 // Increases damage by 50% and attack speed by 30%. 20 seconds, PHASE 5 ONLY 
    7377// Flying (Phase 2) 
    74 #define SPELL_THROW_GLAIVE              39635               // Throws a glaive on the ground 
    75 #define SPELL_THROW_GLAIVE2             39849               // Animation for the above spell 
    76 #define SPELL_GLAIVE_RETURNS            39873               // Glaive flies back to Illidan 
    77 #define SPELL_FIREBALL                  40598               // 2.5k-3.5k damage in 10 yard radius. 2 second cast time. 
    78 #define SPELL_DARK_BARRAGE              40585               // 10 second channeled spell, 3k shadow damage per second. 
     78#define SPELL_THROW_GLAIVE              39635 // Throws a glaive on the ground 
     79#define SPELL_THROW_GLAIVE2             39849 // Animation for the above spell 
     80#define SPELL_GLAIVE_RETURNS            39873 // Glaive flies back to Illidan 
     81#define SPELL_FIREBALL                  40598 // 2.5k-3.5k damage in 10 yard radius. 2 second cast time. 
     82#define SPELL_DARK_BARRAGE              40585 // 10 second channeled spell, 3k shadow damage per second. 
    7983// Demon Form 
    80 #define SPELL_DEMON_TRANSFORM_1         40511               // First phase of animations for transforming into Dark Illidan (fall to ground) 
    81 #define SPELL_DEMON_TRANSFORM_2         40398               // Second phase of animations (kneel) 
    82 #define SPELL_DEMON_TRANSFORM_3         40510               // Final phase of animations (stand up and roar) 
    83 #define SPELL_DEMON_FORM                40506               // Transforms into Demon Illidan. Has an Aura of Dread on him. 
    84 #define SPELL_SHADOW_BLAST              41078               // 8k - 11k Shadow Damage. Targets highest threat. Has a splash effect, damaging anyone in 20 yards of the target. 
    85 #define SPELL_FLAME_BURST               41126               // Hurls fire at entire raid for ~3.5k damage every 10 seconds. Resistable. (Does not work: Script effect) 
    86 #define SPELL_FLAME_BURST_EFFECT        41131               // The actual damage. Handled by core (41126 triggers 41131) 
     84#define SPELL_DEMON_TRANSFORM_1         40511 // First phase of animations for transforming into Dark Illidan (fall to ground) 
     85#define SPELL_DEMON_TRANSFORM_2         40398 // Second phase of animations (kneel) 
     86#define SPELL_DEMON_TRANSFORM_3         40510 // Final phase of animations (stand up and roar) 
     87#define SPELL_DEMON_FORM                40506 // Transforms into Demon Illidan. Has an Aura of Dread on him. 
     88#define SPELL_SHADOW_BLAST              41078 // 8k - 11k Shadow Damage. Targets highest threat. Has a splash effect, damaging anyone in 20 yards of the target. 
     89#define SPELL_FLAME_BURST               41126 // Hurls fire at entire raid for ~3.5k damage every 10 seconds. Resistable. (Does not work: Script effect) 
     90#define SPELL_FLAME_BURST_EFFECT        41131 // The actual damage. Have each player cast it on itself (workaround) 
    8791// Other Illidan spells 
    88 #define SPELL_KNEEL                     39656               // Before beginning encounter, this is how he appears (talking to Wilson). 
    89 #define SPELL_SHADOW_PRISON             40647               // Illidan casts this spell to immobilize entire raid when he summons Maiev. 
    90 #define SPELL_DEATH                     41220               // This spell doesn't do anything except stun Illidan and set him on his knees. 
    91 #define SPELL_BERSERK                   45078               // Damage increased by 500%, attack speed by 150% 
    92  
    93 // Non-Illidan spells 
    94 #define SPELL_AKAMA_DOOR_CHANNEL        41268               // Akama's channel spell on the door before the Temple Summit 
    95 #define SPELL_DEATHSWORN_DOOR_CHANNEL   41269               // Olum and Udalo's channel spell on the door before the Temple Summit 
    96 #define SPELL_AKAMA_DOOR_FAIL           41271               // Not sure where this is really used... 
    97 #define SPELL_HEALING_POTION            40535               // Akama uses this to heal himself to full. 
    98 #define SPELL_AZZINOTH_CHANNEL          39857               // Glaives cast it on Flames. Not sure if this is the right spell. 
    99 #define SPELL_SHADOW_DEMON_PASSIVE      41079               // Adds the "shadowform" aura to Shadow Demons. 
    100 #define SPELL_CONSUME_SOUL              41080               // Once the Shadow Demons reach their target, they use this to kill them 
    101 #define SPELL_PARALYZE                  41083               // Shadow Demons cast this on their target 
    102 #define SPELL_PURPLE_BEAM               39123               // Purple Beam connecting Shadow Demon to their target 
    103 #define SPELL_CAGE_TRAP_DUMMY           40761               // Put this in DB for cage trap GO. 
    104 #define SPELL_EYE_BLAST_TRIGGER         40017               // This summons Demon Form every few seconds and deals ~20k damage in its radius 
    105 #define SPELL_EYE_BLAST                 39908               // This does the blue flamey animation. 
    106 #define SPELL_FLAME_CRASH_EFFECT        40836               // Firey blue ring of circle that the other flame crash summons 
    107 #define SPELL_BLAZE_EFFECT              40610               // Green flame on the ground, triggers damage (5k) every few seconds 
    108 #define SPELL_BLAZE_SUMMON              40637               // Summons the Blaze creature 
    109 #define SPELL_DEMON_FIRE                40029               // Blue fire trail left by Eye Blast. Deals 2k per second if players stand on it. 
    110 #define SPELL_CAGED                     40695               // Caged Trap triggers will cast this on Illidan if he is within 3 yards 
    111 #define SPELL_CAGE_TRAP_SUMMON          40694               // Summons a Cage Trap GO (bugged) on the ground along with a Cage Trap Disturb Trigger mob (working) 
    112 #define SPELL_CAGE_TRAP_BEAM            40713               // 8 Triggers on the ground in an octagon cast spells like this on Illidan 'caging him' 
    113 #define SPELL_FLAME_BLAST               40631               // Flames of Azzinoth use this. Frontal cone AoE 7k-9k damage. 
    114 #define SPELL_CHARGE                    40602               // Flames of Azzinoth charges whoever is too far from them. They enrage after this. For simplicity, we'll use the same enrage as Illidan. 
    115 #define SPELL_TELEPORT_VISUAL           41232               // Teleport visual for Maiev 
    116 #define SPELL_SHADOWFIEND_PASSIVE       41913               // Passive aura for shadowfiends 
     92#define SPELL_KNEEL                     39656 // Before beginning encounter, this is how he appears (talking to skully). 
     93#define SPELL_SHADOW_PRISON             40647 // Illidan casts this spell to immobilize entire raid when he summons Maiev. 
     94#define SPELL_DEATH                     41220 // This spell doesn't do anything except stun Illidan and set him on his knees. 
     95#define SPELL_BERSERK                   45078 // Damage increased by 500%, attack speed by 150% 
     96#define SPELL_DUAL_WIELD                42459 
     97//Phase Normal spells 
     98#define SPELL_FLAME_CRASH_EFFECT        40836 // Firey blue ring of circle that the other flame crash summons 
     99#define SPELL_SHADOWFIEND_PASSIVE       41913 // Passive aura for shadowfiends 
     100#define SPELL_SHADOW_DEMON_PASSIVE      41079 // Adds the "shadowform" aura to Shadow Demons. 
     101#define SPELL_CONSUME_SOUL              41080 // Once the Shadow Demons reach their target, they use this to kill them 
     102#define SPELL_PARALYZE                  41083 // Shadow Demons cast this on their target 
     103#define SPELL_PURPLE_BEAM               39123 // Purple Beam connecting Shadow Demon to their target 
     104//Phase Flight spells 
     105#define SPELL_AZZINOTH_CHANNEL          39857 // Glaives cast it on Flames. Not sure if this is the right spell. 
     106#define SPELL_EYE_BLAST_TRIGGER         40017 // This summons Demon Form every few seconds and deals ~20k damage in its radius 
     107#define SPELL_EYE_BLAST                 39908 // This does the blue flamey animation. 
     108#define SPELL_BLAZE_EFFECT              40610 // Green flame on the ground, triggers damage (5k) every few seconds 
     109#define SPELL_BLAZE_SUMMON              40637 // Summons the Blaze creature 
     110#define SPELL_DEMON_FIRE                40029 // Blue fire trail left by Eye Blast. Deals 2k per second if players stand on it. 
     111#define SPELL_FLAME_BLAST               40631 // Flames of Azzinoth use this. Frontal cone AoE 7k-9k damage. 
     112#define SPELL_CHARGE                    41581 //40602 // Flames of Azzinoth charges whoever is too far from them. They enrage after this. For simplicity, we'll use the same enrage as Illidan. 
     113#define SPELL_FLAME_ENRAGE              45078 
     114//Akama spells 
     115#define SPELL_AKAMA_DOOR_CHANNEL        41268 // Akama's channel spell on the door before the Temple Summit 
     116#define SPELL_DEATHSWORN_DOOR_CHANNEL   41269 // Olum and Udalo's channel spell on the door before the Temple Summit 
     117#define SPELL_AKAMA_DOOR_FAIL           41271 // Not sure where this is really used... 
     118#define SPELL_HEALING_POTION            40535 // Akama uses this to heal himself to full. 
     119#define SPELL_CHAIN_LIGHTNING           40536 // 6938 to 8062 for 5 targets 
     120//Maiev spells 
     121#define SPELL_CAGE_TRAP_DUMMY           40761 // Put this in DB for cage trap GO. 
     122#define SPELL_CAGED                     40695 // Caged Trap triggers will cast this on Illidan if he is within 3 yards 
     123#define SPELL_CAGE_TRAP_SUMMON          40694 // Summons a Cage Trap GO (bugged) on the ground along with a Cage Trap Disturb Trigger mob (working) 
     124#define SPELL_CAGE_TRAP_BEAM            40713 // 8 Triggers on the ground in an octagon cast spells like this on Illidan 'caging him' 
     125#define SPELL_TELEPORT_VISUAL           41232 // Teleport visual for Maiev 
     126#define SPELL_SHADOW_STRIKE             40685 // 4375 to 5625 every 3 seconds for 12 seconds 
     127#define SPELL_THROW_DAGGER              41152 // 5400 to 6600 damage, need dagger 
     128#define SPELL_FAN_BLADES                39954 // bugged visual 
    117129 
    118130// Other defines 
    119 #define CENTER_X            676.740 
     131#define CENTER_X            676.740  
    120132#define CENTER_Y            305.297 
    121133#define CENTER_Z            353.192 
     134 
     135#define FLAME_ENRAGE_DISTANCE   30 
     136#define FLAME_CHARGE_DISTANCE   50 
    122137 
    123138/**** Creature Summon and Recognition IDs ****/ 
     
    142157 
    143158/*** Phase Names ***/ 
    144 enum Phase 
    145 { 
    146     PHASE_NORMAL            =   1, 
    147     PHASE_FLIGHT            =   2, 
    148     PHASE_NORMAL_2          =   3, 
    149     PHASE_DEMON             =   4, 
    150     PHASE_NORMAL_MAIEV      =   5, 
    151     PHASE_DEMON_SEQUENCE    =   6, 
     159enum PhaseIllidan 
     160{ 
     161    PHASE_NULL                  =   0, 
     162    PHASE_NORMAL                =   1, 
     163    PHASE_FLIGHT                =   2, 
     164    PHASE_NORMAL_2              =   3, 
     165    PHASE_DEMON                 =   4, 
     166    PHASE_NORMAL_MAIEV          =   5, 
     167    PHASE_TALK_SEQUENCE         =   6, 
     168    PHASE_FLIGHT_SEQUENCE       =   7, 
     169    PHASE_TRANSFORM_SEQUENCE    =   8, 
     170};//Maiev uses the same phase 
     171 
     172enum PhaseAkama 
     173{ 
     174    PHASE_AKAMA_NULL        =   0, 
     175    PHASE_CHANNEL           =   1, 
     176    PHASE_WALK              =   2, 
     177    PHASE_TALK              =   3, 
     178    PHASE_FIGHT_ILLIDAN     =   4, 
     179    PHASE_FIGHT_MINIONS     =   5, 
     180    PHASE_RETURN            =   6, 
     181}; 
     182 
     183enum EventIllidan 
     184{ 
     185    EVENT_NULL                  =   0, 
     186    EVENT_BERSERK               =   1, 
     187    //normal phase 
     188    EVENT_TAUNT                 =   2, 
     189    EVENT_SHEAR                 =   3, 
     190    EVENT_FLAME_CRASH           =   4, 
     191    EVENT_PARASITIC_SHADOWFIEND =   5, 
     192    EVENT_PARASITE_CHECK        =   6, 
     193    EVENT_DRAW_SOUL             =   7, 
     194    EVENT_AGONIZING_FLAMES      =   8, 
     195    EVENT_TRANSFORM_NORMAL      =   9, 
     196    EVENT_ENRAGE                =   10, 
     197    //flight phase 
     198    EVENT_FIREBALL              =   2, 
     199    EVENT_DARK_BARRAGE          =   3, 
     200    EVENT_EYE_BLAST             =   4, 
     201    EVENT_MOVE_POINT            =   5, 
     202    //demon phase 
     203    EVENT_SHADOW_BLAST          =   2, 
     204    EVENT_FLAME_BURST           =   3, 
     205    EVENT_SHADOWDEMON           =   4, 
     206    EVENT_TRANSFORM_DEMON       =   5, 
     207    //sequence phase 
     208    EVENT_TALK_SEQUENCE         =   2, 
     209    EVENT_FLIGHT_SEQUENCE       =   2, 
     210    EVENT_TRANSFORM_SEQUENCE    =   2, 
     211}; 
     212 
     213enum EventMaiev 
     214{ 
     215    EVENT_MAIEV_NULL            =   0, 
     216    EVENT_MAIEV_STEALTH         =   1, 
     217    EVENT_MAIEV_TAUNT           =   2, 
     218    EVENT_MAIEV_SHADOW_STRIKE   =   3, 
     219    EVENT_MAIEV_THROW_DAGGER    =   4, 
     220    EVENT_MAIEV_TRAP            =   5, 
     221}; 
     222 
     223static EventIllidan MaxTimer[]= 
     224{ 
     225    EVENT_NULL, 
     226    EVENT_DRAW_SOUL, 
     227    EVENT_MOVE_POINT, 
     228    EVENT_TRANSFORM_NORMAL, 
     229    EVENT_TRANSFORM_DEMON, 
     230    EVENT_ENRAGE, 
     231    EVENT_TALK_SEQUENCE, 
     232    EVENT_FLIGHT_SEQUENCE, 
     233    EVENT_TRANSFORM_SEQUENCE 
    152234}; 
    153235 
     
    163245{ 
    164246    {11463, "Akama... your duplicity is hardly surprising. I should have slaughtered you and your malformed brethren long ago.", ILLIDAN_STORMRAGE, 8000, 0, true}, 
    165     {0, NULL, ILLIDAN_STORMRAGE, 5000, 396, true}, 
     247    {0, NULL, ILLIDAN_STORMRAGE, 5000, 396, true},  
    166248    {11389, "We've come to end your reign, Illidan. My people and all of Outland shall be free!", AKAMA, 7000, 25, true}, 
    167249    {0, NULL, AKAMA, 5000, 66, true}, 
     
    171253    {11466, "You are not prepared!", ILLIDAN_STORMRAGE, 3000, 406, true}, 
    172254    {0, NULL, EMPTY, 1000, 0, true}, 
    173     {0, NULL, EMPTY, 0, 0, false}, 
     255    {0, NULL, EMPTY, 0, 0, false},//9 
    174256    {11476, "Is this it, mortals? Is this all the fury you can muster?", ILLIDAN_STORMRAGE, 8000, 0, true}, 
    175257    {11491, "Their fury pales before mine, Illidan. We have some unsettled business between us.", MAIEV_SHADOWSONG, 8000, 5, true}, 
    176     {11477, "Maiev... How is this even possible?", ILLIDAN_STORMRAGE, 7000, 1, true}, 
     258    {11477, "Maiev... How is this even possible?", ILLIDAN_STORMRAGE, 5000, 1, true}, 
    177259    {11492, "Ah... my long hunt is finally over. Today, Justice will be done!", MAIEV_SHADOWSONG, 8000, 15, true}, 
    178     {11470, "Feel the hatred of ten thousand years!", ILLIDAN_STORMRAGE, 1000, 0, false}, 
    179     {11496, "Ahh... It is finished. You are beaten.", MAIEV_SHADOWSONG, 6000, 0, true}, 
    180     {                                                       // Emote dead for now. Kill him later 
    181         11478, "You have won... Maiev...but the huntress... is nothing...without the hunt... you... are nothing... without me..", ILLIDAN_STORMRAGE, 22000, 65, true 
    182     }, 
     260    {11470, "Feel the hatred of ten thousand years!", ILLIDAN_STORMRAGE, 1000, 0, false},//14 
     261    {11496, "Ahh... It is finished. You are beaten.", MAIEV_SHADOWSONG, 6000, 0, true},//15 
     262    {11478, "You have won... Maiev...but the huntress... is nothing...without the hunt... you... are nothing... without me..", ILLIDAN_STORMRAGE, 30000, 65, true}, // Emote dead for now. Kill him later 
    183263    {11497, "He is right. I feel nothing... I am nothing... Farewell, champions.", MAIEV_SHADOWSONG, 9000, 0, true}, 
    184     {11498, NULL, MAIEV_SHADOWSONG, 0, true}, 
     264    {11498, NULL, MAIEV_SHADOWSONG, 5000, 0, true}, 
     265    {11498, NULL, EMPTY, 1000, 0, true},//19 Maiev disappear 
    185266    {11387, "The Light will fill these dismal halls once again. I swear it.", AKAMA, 8000, 0, true}, 
    186     {0, NULL, EMPTY, 1000, 0, false} 
     267    {0, NULL, EMPTY, 1000, 0, false}//21 
    187268}; 
    188269 
     
    206287{ 
    207288    float x, y, z; 
    208     uint32 id; 
     289}; 
     290 
     291static Locations HoverPosition[]= 
     292{ 
     293    {657, 340, 355}, 
     294    {657, 275, 355}, 
     295    {705, 275, 355}, 
     296    {705, 340, 355} 
    209297}; 
    210298 
     
    212300{ 
    213301    {695.105, 305.303, 354.256}, 
    214     {659.338, 305.303, 354.256}, 
     302    {659.338, 305.303, 354.256},//the distance between two glaives is 36 
    215303    {700.105, 305.303, 354.256}, 
    216304    {664.338, 305.303, 354.256} 
     
    219307static Locations EyeBlast[]= 
    220308{ 
    221     {650.697, 320.128, 353.730}, 
    222     {652.799, 275.091, 353.367}, 
    223     {701.527, 273.815, 353.230}, 
    224     {709.865, 325.654, 353.322} 
     309    {677, 350, 354},//start point, pass through glaive point 
     310    {677, 260, 354} 
    225311}; 
    226312 
    227313static Locations AkamaWP[]= 
    228314{ 
    229     { 770.01, 304.50, 312.29 },                            // Bottom of the first stairs, at the doors 
    230     { 780.66, 304.50, 319.74 },                            // Top of the first stairs 
    231     { 790.13, 319.68, 319.76 },                            // Bottom of the second stairs (left from the entrance) 
    232     { 787.17, 347.38, 341.42 },                            // Top of the second stairs 
    233     { 781.34, 350.31, 341.44 },                            // Bottom of the third stairs 
    234     { 762.60, 361.06, 353.60 },                            // Top of the third stairs 
    235     { 756.35, 360.52, 353.27 },                            // Before the door-thingy 
    236     { 743.82, 342.21, 353.00 },                            // Somewhere further 
    237     { 732.69, 305.13, 353.00 },                             // In front of Illidan 
    238     { 738.11, 365.44, 353.00 },                            // in front of the door-thingy (the other one!) 
    239     { 792.18, 366.62, 341.42 },                            // Down the first flight of stairs 
    240     { 796.84, 304.89, 319.76 },                            // Down the second flight of stairs 
    241     { 782.01, 304.55, 319.76 }                              // Final location - back at the initial gates. This is where he will fight the minions! 
     315    {770.01, 304.50, 312.29}, // Bottom of the first stairs, at the doors 
     316    {780.66, 304.50, 319.74}, // Top of the first stairs 
     317    {790.13, 319.68, 319.76}, // Bottom of the second stairs (left from the entrance) 
     318    {787.17, 347.38, 341.42}, // Top of the second stairs 
     319    {781.34, 350.31, 341.44}, // Bottom of the third stairs 
     320    {762.60, 361.06, 353.60}, // Top of the third stairs 
     321    {756.35, 360.52, 353.27}, // Before the door-thingy 
     322    {743.82, 342.21, 353.00}, // Somewhere further 
     323    {732.69, 305.13, 353.00}, // In front of Illidan - (8) 
     324    {738.11, 365.44, 353.00}, // in front of the door-thingy (the other one!) 
     325    {792.18, 366.62, 341.42}, // Down the first flight of stairs 
     326    {796.84, 304.89, 319.76}, // Down the second flight of stairs 
     327    {782.01, 304.55, 319.76}  // Final location - back at the initial gates. This is where he will fight the minions! (12) 
    242328}; 
    243329// 755.762, 304.0747, 312.1769 -- This is where Akama should be spawned 
    244330static Locations SpiritSpawns[]= 
    245331{ 
    246     {755.5426, 309.9156, 312.2129, SPIRIT_OF_UDALO}, 
    247     {755.5426, 298.7923, 312.0834, SPIRIT_OF_OLUM} 
    248 }; 
    249  
    250 struct WayPoints 
    251 { 
    252     WayPoints(uint32 _id, float _x, float _y, float _z) 
    253     { 
    254         id = _id; 
    255         x = _x; 
    256         y = _y; 
    257         z = _z; 
    258     } 
    259     uint32 id; 
    260     float x, y, z; 
    261 }; 
    262  
    263 struct Animation                                            // For the demon transformation 
     332    {755.5426, 309.9156, 312.2129}, 
     333    {755.5426, 298.7923, 312.0834} 
     334}; 
     335 
     336struct Animation // For the demon transformation 
    264337{ 
    265338    uint32 aura, unaura, timer, size, displayid, phase; 
     
    269342static Animation DemonTransformation[]= 
    270343{ 
    271     {SPELL_DEMON_TRANSFORM_1, 0, 1300, 0, 0, 6, true}, 
     344    {SPELL_DEMON_TRANSFORM_1, 0, 1000, 0, 0, 6, true}, 
    272345    {SPELL_DEMON_TRANSFORM_2, SPELL_DEMON_TRANSFORM_1, 4000, 0, 0, 6, true}, 
    273     {SPELL_DEMON_FORM, 0, 3000, 1073741824, 21322, 6, false}, 
     346    {0, 0, 3000, 1073741824, 21322, 6, false},//stunned, cannot cast demon form 
    274347    {SPELL_DEMON_TRANSFORM_3, SPELL_DEMON_TRANSFORM_2, 3500, 0, 0, 6, false}, 
    275     {0, 0, 0, 0, 0, 4, false}, 
    276     {SPELL_DEMON_TRANSFORM_1, 0, 1500, 0, 0, 6, false}, 
     348    {SPELL_DEMON_FORM, SPELL_DEMON_TRANSFORM_3, 0, 0, 0, 4, false}, 
     349    {SPELL_DEMON_TRANSFORM_1, 0, 1000, 0, 0, 6, false}, 
    277350    {SPELL_DEMON_TRANSFORM_2, SPELL_DEMON_TRANSFORM_1, 4000, 0, 0, 6, false}, 
    278351    {0, SPELL_DEMON_FORM, 3000, 1069547520, 21135, 6, false}, 
    279352    {SPELL_DEMON_TRANSFORM_3, SPELL_DEMON_TRANSFORM_2, 3500, 0, 0, 6, true}, 
    280     {0, 0, 0, 0, 0, 8, true} 
    281 }; 
    282  
    283 /**** 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 ****/ 
    284 struct TRINITY_DLL_DECL demonfireAI : public ScriptedAI 
    285 { 
    286     demonfireAI(Creature *c) : ScriptedAI(c) 
     353    {0, SPELL_DEMON_TRANSFORM_3, 0, 0, 0, 8, true} 
     354}; 
     355 
     356 
     357 
     358/************************************** Illidan's AI ***************************************/ 
     359struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI 
     360{ 
     361    boss_illidan_stormrageAI(Creature* c) : ScriptedAI(c) 
    287362    { 
    288363        pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     
    292367    ScriptedInstance* pInstance; 
    293368 
     369    PhaseIllidan Phase; 
     370    EventIllidan Event; 
     371    uint32 Timer[EVENT_ENRAGE + 1]; 
     372 
     373    uint32 TalkCount; 
     374    uint32 TransformCount; 
     375    uint32 FlightCount; 
     376 
     377    uint32 HoverPoint; 
     378 
     379    uint64 AkamaGUID; 
     380    uint64 MaievGUID; 
     381    uint64 FlameGUID[2]; 
     382    uint64 GlaiveGUID[2]; 
     383 
     384    std::list<uint64> ParasiteTargets; // for safety, do not use Unit* 
     385 
     386    void Reset(); 
     387 
     388    void JustSummoned(Creature* summon)//, TempSummonType type) 
     389    { 
     390        if(summon->GetCreatureInfo()->Entry == FLAME_CRASH) 
     391        { 
     392        //    type = TEMPSUMMON_TIMED_DESPAWN; 
     393        } 
     394        //error_log("justsummoned %d %d", summon->GetCreatureInfo()->Entry, summon->GetGUID()); 
     395    } 
     396 
     397    void SummonedCreatureDespawn(Creature* summon) 
     398    { 
     399        if(summon->GetCreatureInfo()->Entry == FLAME_OF_AZZINOTH) 
     400        { 
     401            for(uint8 i = 0; i < 2; i++) 
     402                if(summon->GetGUID() == FlameGUID[i]) 
     403                    FlameGUID[i] = 0; 
     404 
     405            if(!FlameGUID[0] && !FlameGUID[1]) 
     406            { 
     407                m_creature->InterruptNonMeleeSpells(true); 
     408                EnterPhase(PHASE_FLIGHT_SEQUENCE); 
     409            } 
     410        } 
     411    } 
     412 
     413    void MovementInform(uint32 MovementType, uint32 Data) 
     414    { 
     415        if(FlightCount == 7) //change hover point 
     416        { 
     417            if(m_creature->getVictim()) 
     418            { 
     419                m_creature->SetInFront(m_creature->getVictim()); 
     420                m_creature->StopMoving(); 
     421            } 
     422            EnterPhase(PHASE_FLIGHT); 
     423        } 
     424        else  
     425            Timer[EVENT_FLIGHT_SEQUENCE] = 1000;     
     426    } 
     427 
     428    void Aggro(Unit *who) 
     429    { 
     430        DoZoneInCombat(); 
     431    } 
     432 
     433    void AttackStart(Unit *who) 
     434    { 
     435        if(!who || Phase >= PHASE_TALK_SEQUENCE) 
     436            return; 
     437 
     438        if (who->isTargetableForAttack()) 
     439        { 
     440            if(Phase == PHASE_FLIGHT || Phase == PHASE_DEMON) 
     441                m_creature->Attack(who, false); 
     442            else 
     443                DoStartAttackAndMovement(who); 
     444 
     445            if (!InCombat) 
     446            { 
     447                Aggro(who); 
     448                InCombat = true; 
     449            } 
     450        } 
     451    } 
     452 
     453    void MoveInLineOfSight(Unit *who) {} 
     454 
     455    void JustDied(Unit *killer) 
     456    { 
     457        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     458 
     459        if(!pInstance) 
     460            return; 
     461 
     462        pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, DONE); // Completed 
     463 
     464        for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L + 1; ++i) 
     465        { 
     466            GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i)); 
     467            if(Door) 
     468                Door->SetUInt32Value(GAMEOBJECT_STATE, 0); // Open Doors 
     469        } 
     470    } 
     471 
     472    void KilledUnit(Unit *victim) 
     473    { 
     474        if(victim == m_creature) return; 
     475 
     476        switch(rand()%2) 
     477        { 
     478        case 0: 
     479            DoYell(SAY_KILL1, LANG_UNIVERSAL, victim); 
     480            DoPlaySoundToSet(m_creature, SOUND_KILL1); 
     481            break; 
     482        case 1: 
     483            DoYell(SAY_KILL2, LANG_UNIVERSAL, victim); 
     484            DoPlaySoundToSet(m_creature, SOUND_KILL2); 
     485            break; 
     486        } 
     487    } 
     488 
     489    void DamageTaken(Unit *done_by, uint32 &damage) 
     490    { 
     491        if(damage >= m_creature->GetHealth() && done_by != m_creature) 
     492            damage = 0; 
     493        if(done_by->GetGUID() == MaievGUID) 
     494            done_by->AddThreat(m_creature, -(3*(float)damage)/4); // do not let maiev tank him 
     495    } 
     496 
     497    void SpellHit(Unit *caster, const SpellEntry *spell) 
     498    { 
     499        if(spell->Id == SPELL_GLAIVE_RETURNS) // Re-equip our warblades! 
     500        { 
     501            if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY)) 
     502                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); 
     503            else 
     504                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); 
     505            m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); 
     506        } 
     507    } 
     508 
     509    void AddParasiteTarget(uint64 targetGUID) 
     510    { 
     511        for(std::list<uint64>::iterator tIter = ParasiteTargets.begin(); tIter != ParasiteTargets.end(); tIter++) 
     512        { 
     513            if(*tIter == targetGUID) 
     514                return; 
     515        } 
     516        ParasiteTargets.push_back(targetGUID); 
     517 
     518        if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV) 
     519            Timer[EVENT_PARASITE_CHECK] += 1000; 
     520    } 
     521 
     522    void DeleteFromThreatList(uint64 TargetGUID) 
     523    { 
     524        for(std::list<HostilReference*>::iterator itr = m_creature->getThreatManager().getThreatList().begin(); itr != m_creature->getThreatManager().getThreatList().end(); ++itr) 
     525        { 
     526            if((*itr)->getUnitGuid() == TargetGUID) 
     527            { 
     528                (*itr)->removeReference(); 
     529                break; 
     530            } 
     531        } 
     532    } 
     533 
     534    void Talk(uint32 count) 
     535    { 
     536        Timer[EVENT_TALK_SEQUENCE] = Conversation[count].timer; 
     537 
     538        Creature* creature = NULL; 
     539        if(Conversation[count].creature == ILLIDAN_STORMRAGE) 
     540            creature = m_creature; 
     541        else if(Conversation[count].creature == AKAMA) 
     542            creature = ((Creature*)Unit::GetUnit((*m_creature), AkamaGUID)); 
     543        else if(Conversation[count].creature == MAIEV_SHADOWSONG) 
     544            creature = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID)); 
     545 
     546        if(creature) 
     547        { 
     548            if(Conversation[count].emote) 
     549                creature->HandleEmoteCommand(Conversation[count].emote); // Make the creature do some animation! 
     550            if(Conversation[count].text) 
     551                creature->Yell(Conversation[count].text, LANG_UNIVERSAL, 0); // Have the creature yell out some text 
     552            if(Conversation[count].sound) 
     553                DoPlaySoundToSet(creature, Conversation[count].sound); // Play some sound on the creature 
     554        } 
     555    } 
     556 
     557    void EnterPhase(PhaseIllidan NextPhase); 
     558    void CastEyeBlast(); 
     559    void SummonFlamesOfAzzinoth(); 
     560    void SummonMaiev(); 
     561    void SummonShadowDemon() 
     562    { 
     563        Creature* ShadowDemon = NULL; 
     564        Unit* target = NULL; 
     565        for(uint8 i = 0; i < 4; i++) 
     566        { 
     567            ShadowDemon = DoSpawnCreature(SHADOW_DEMON, 0,0,0,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,25000); 
     568            if(ShadowDemon) 
     569            { 
     570                target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
     571                if(target && target->GetTypeId() == TYPEID_PLAYER) // only on players. 
     572                { 
     573                    ShadowDemon->AddThreat(target, 5000000.0f); 
     574                    ShadowDemon->AI()->AttackStart(target); 
     575                } 
     576                DoZoneInCombat(ShadowDemon); 
     577            } 
     578        } 
     579    } 
     580    void HandleTalkSequence(); 
     581    void HandleFlightSequence() 
     582    { 
     583        switch(FlightCount) 
     584        { 
     585        case 1://lift off 
     586            m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); 
     587            //m_creature->GetMotionMaster()->Clear(false); 
     588            m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING); 
     589            //m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ()); 
     590            m_creature->StopMoving(); 
     591            DoYell(SAY_TAKEOFF, LANG_UNIVERSAL, NULL); 
     592            DoPlaySoundToSet(m_creature, SOUND_TAKEOFF); 
     593            Timer[EVENT_FLIGHT_SEQUENCE] = 3000; 
     594            break; 
     595        case 2://move to center 
     596            //m_creature->GetMotionMaster()->Clear(false); 
     597            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); 
     598            m_creature->GetMotionMaster()->MovePoint(0, CENTER_X + 5, CENTER_Y, CENTER_Z); //+5, for SPELL_THROW_GLAIVE bug 
     599            m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); 
     600            Timer[EVENT_FLIGHT_SEQUENCE] = 0; 
     601            break; 
     602        case 3://throw one glaive 
     603            { 
     604                uint8 i=1; 
     605                Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     606                if(Glaive) 
     607                { 
     608                    GlaiveGUID[i] = Glaive->GetGUID(); 
     609                    Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
     610                    Glaive->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); 
     611                    Glaive->setFaction(m_creature->getFaction()); 
     612                    DoCast(Glaive, SPELL_THROW_GLAIVE2); 
     613                } 
     614            } 
     615            Timer[EVENT_FLIGHT_SEQUENCE] = 700; 
     616            break; 
     617        case 4://throw another 
     618            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); 
     619            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); 
     620            { 
     621                uint8 i=0; 
     622                Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     623                if(Glaive) 
     624                { 
     625                    GlaiveGUID[i] = Glaive->GetGUID(); 
     626                    Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
     627                    Glaive->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); 
     628                    Glaive->setFaction(m_creature->getFaction()); 
     629                    DoCast(Glaive, SPELL_THROW_GLAIVE, true); 
     630                } 
     631            } 
     632            Timer[EVENT_FLIGHT_SEQUENCE] = 5000; 
     633            break; 
     634        case 5://summon flames 
     635            SummonFlamesOfAzzinoth(); 
     636            Timer[EVENT_FLIGHT_SEQUENCE] = 3000; 
     637            break; 
     638        case 6://fly to hover point 
     639            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); 
     640            m_creature->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z); 
     641            m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); 
     642            Timer[EVENT_FLIGHT_SEQUENCE] = 0; 
     643            break; 
     644        case 7://return to center 
     645            m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); 
     646            m_creature->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z); 
     647            m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); 
     648            Timer[EVENT_FLIGHT_SEQUENCE] = 0; 
     649            break; 
     650        case 8://glaive return 
     651            for(uint8 i = 0; i < 2; i++) 
     652            { 
     653                if(GlaiveGUID[i]) 
     654                { 
     655                    Unit* Glaive = Unit::GetUnit((*m_creature), GlaiveGUID[i]); 
     656                    if(Glaive) 
     657                    { 
     658                        Glaive->CastSpell(m_creature, SPELL_GLAIVE_RETURNS, false); // Make it look like the Glaive flies back up to us 
     659                        Glaive->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); // disappear but not die for now 
     660                    } 
     661                } 
     662            } 
     663            Timer[EVENT_FLIGHT_SEQUENCE] = 2000; 
     664            break; 
     665        case 9://land 
     666            //m_creature->GetMotionMaster()->Clear(false); 
     667            m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); 
     668            //m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(),m_creature->GetPositionY(),m_creature->GetPositionZ()); 
     669            m_creature->StopMoving(); 
     670            m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); 
     671            for(uint8 i = 0; i < 2; i++) 
     672            { 
     673                if(GlaiveGUID[i]) 
     674                { 
     675                    if(GETUNIT(Glaive, GlaiveGUID[i])) 
     676                    { 
     677                        Glaive->SetVisibility(VISIBILITY_OFF); 
     678                        Glaive->setDeathState(JUST_DIED); // Despawn the Glaive 
     679                    } 
     680                    GlaiveGUID[i] = 0; 
     681                } 
     682            } 
     683            Timer[EVENT_FLIGHT_SEQUENCE] = 2000; 
     684            break; 
     685        case 10://attack 
     686            DoResetThreat(); 
     687            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); 
     688            //m_creature->GetMotionMaster()->Clear(); 
     689            m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); 
     690            EnterPhase(PHASE_NORMAL_2); 
     691            break; 
     692        default: 
     693            break; 
     694        } 
     695        FlightCount++; 
     696    } 
     697 
     698    void HandleTransformSequence() 
     699    { 
     700        if(DemonTransformation[TransformCount].unaura) 
     701            m_creature->RemoveAurasDueToSpell(DemonTransformation[TransformCount].unaura); 
     702 
     703        if(DemonTransformation[TransformCount].aura) 
     704            DoCast(m_creature, DemonTransformation[TransformCount].aura, true); 
     705 
     706        if(DemonTransformation[TransformCount].displayid) 
     707            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, DemonTransformation[TransformCount].displayid); // It's morphin time! 
     708 
     709        if(DemonTransformation[TransformCount].equip) 
     710        { 
     711            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Requip warglaives if needed 
     712            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); 
     713            m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); 
     714        } 
     715        else 
     716        { 
     717            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); // Unequip warglaives if needed 
     718            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); 
     719        } 
     720 
     721        switch(TransformCount) 
     722        { 
     723        case 2: 
     724            DoResetThreat(); 
     725            break; 
     726        case 4: 
     727            EnterPhase(PHASE_DEMON); 
     728            break; 
     729        case 7: 
     730            DoResetThreat(); 
     731            break; 
     732        case 9: 
     733            if(MaievGUID) 
     734                EnterPhase(PHASE_NORMAL_MAIEV); // Depending on whether we summoned Maiev, we switch to either phase 5 or 3 
     735            else 
     736                EnterPhase(PHASE_NORMAL_2); 
     737            break; 
     738        default: 
     739            break; 
     740        } 
     741        if(Phase == PHASE_TRANSFORM_SEQUENCE) 
     742            Timer[EVENT_TRANSFORM_SEQUENCE] = DemonTransformation[TransformCount].timer;         
     743        TransformCount++; 
     744    } 
     745 
     746    void UpdateAI(const uint32 diff) 
     747    { 
     748        if((!m_creature->SelectHostilTarget() || !m_creature->getVictim()) && Phase < PHASE_TALK_SEQUENCE) 
     749            return; 
     750 
     751        Event = EVENT_NULL; 
     752        for(uint32 i = 1; i <= MaxTimer[Phase]; i++) 
     753            if(Timer[i]) 
     754                if(Timer[i] <= diff) 
     755                { 
     756                    if(!Event) 
     757                        Event = (EventIllidan)i; 
     758                } 
     759                else Timer[i] -= diff; 
     760 
     761                switch(Phase) 
     762                { 
     763                case PHASE_NORMAL: 
     764                    if(HPPCT(m_creature) < 65) 
     765                        EnterPhase(PHASE_FLIGHT_SEQUENCE); 
     766                    break; 
     767 
     768                case PHASE_NORMAL_2: 
     769                    if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30) 
     770                        EnterPhase(PHASE_TALK_SEQUENCE); 
     771                    break; 
     772 
     773                case PHASE_NORMAL_MAIEV: 
     774                    if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 1) 
     775                        EnterPhase(PHASE_TALK_SEQUENCE); 
     776                    break; 
     777 
     778                case PHASE_TALK_SEQUENCE: 
     779                    if(Event == EVENT_TALK_SEQUENCE) 
     780                        HandleTalkSequence(); 
     781                    break; 
     782 
     783                case PHASE_FLIGHT_SEQUENCE: 
     784                    if(Event == EVENT_FLIGHT_SEQUENCE) 
     785                        HandleFlightSequence(); 
     786                    break; 
     787 
     788                case PHASE_TRANSFORM_SEQUENCE: 
     789                    if(Event == EVENT_TRANSFORM_SEQUENCE) 
     790                        HandleTransformSequence(); 
     791                    break; 
     792                } 
     793 
     794                if(m_creature->IsNonMeleeSpellCasted(false)) 
     795                    return; 
     796 
     797                if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV && !m_creature->HasAura(SPELL_CAGED, 0)) 
     798                { 
     799                    switch(Event) 
     800                    { 
     801                        //PHASE_NORMAL 
     802                    case EVENT_BERSERK: 
     803                        DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL); 
     804                        DoPlaySoundToSet(m_creature, SOUND_ENRAGE); 
     805                        DoCast(m_creature, SPELL_BERSERK, true); 
     806                        Timer[EVENT_BERSERK] = 5000;//The buff actually lasts forever. 
     807                        break; 
     808 
     809                    case EVENT_TAUNT: 
     810                        { 
     811                            uint32 random = rand()%4; 
     812                            char* yell = RandomTaunts[random].text; 
     813                            uint32 soundid = RandomTaunts[random].sound; 
     814                            if(yell) 
     815                                DoYell(yell, LANG_UNIVERSAL, NULL); 
     816                            if(soundid) 
     817                                DoPlaySoundToSet(m_creature, soundid); 
     818                        } 
     819                        Timer[EVENT_TAUNT] = 32000; 
     820                        break; 
     821 
     822                    case EVENT_SHEAR: 
     823                        DoCast(m_creature->getVictim(), SPELL_SHEAR); 
     824                        Timer[EVENT_SHEAR] = 25000 + (rand()%16 * 1000); 
     825                        break; 
     826 
     827                    case EVENT_FLAME_CRASH: 
     828                        DoCast(m_creature->getVictim(), SPELL_FLAME_CRASH); 
     829                        Timer[EVENT_FLAME_CRASH] = 35000; 
     830                        break; 
     831 
     832                    case EVENT_PARASITIC_SHADOWFIEND: 
     833                        { 
     834                            Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1); 
     835                            if(!target) target = m_creature->getVictim(); 
     836                            if(target->GetTypeId() == TYPEID_PLAYER && !target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)) 
     837                            { 
     838                                target->CastSpell(target, SPELL_PARASITIC_SHADOWFIEND, true); // do not miss 
     839                                ParasiteTargets.push_back(target->GetGUID()); 
     840                                Timer[EVENT_PARASITE_CHECK] += 1000; // do not check immediately 
     841                            } 
     842                            Timer[EVENT_PARASITIC_SHADOWFIEND] = 40000; 
     843                        } 
     844                        break; 
     845 
     846                    case EVENT_PARASITE_CHECK: 
     847                        for(std::list<uint64>::iterator tIter = ParasiteTargets.begin(); tIter != ParasiteTargets.end();) 
     848                        { 
     849                            Unit* target = Unit::GetUnit((*m_creature), *tIter); 
     850                            if(!target || !target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)) 
     851                            { 
     852                                if(target && target->isAlive()) 
     853                                    target->CastSpell(target, SPELL_SUMMON_PARASITICS, true); 
     854                                std::list<uint64>::iterator tIter2 = tIter; 
     855                                ++tIter; 
     856                                ParasiteTargets.erase(tIter2); 
     857                            } 
     858                            else 
     859                                ++tIter; 
     860                        } 
     861                        if(ParasiteTargets.empty()) 
     862                            Timer[EVENT_PARASITE_CHECK] = 0; 
     863                        else 
     864                            Timer[EVENT_PARASITE_CHECK] = 1000; 
     865                        break; 
     866 
     867                    case EVENT_DRAW_SOUL: 
     868                        DoCast(m_creature->getVictim(), SPELL_DRAW_SOUL); 
     869                        Timer[EVENT_DRAW_SOUL] = 55000;           
     870                        break; 
     871 
     872                        //PHASE_NORMAL_2 
     873                    case EVENT_AGONIZING_FLAMES: 
     874                        DoCast(SelectUnit(SELECT_TARGET_RANDOM,0), SPELL_AGONIZING_FLAMES); 
     875                        Timer[EVENT_AGONIZING_FLAMES] = 0; 
     876                        break; 
     877 
     878                    case EVENT_TRANSFORM_NORMAL: 
     879                        EnterPhase(PHASE_TRANSFORM_SEQUENCE); 
     880                        break; 
     881 
     882                        //PHASE_NORMAL_MAIEV 
     883                    case EVENT_ENRAGE: 
     884                        DoCast(m_creature, SPELL_ENRAGE); 
     885                        Timer[EVENT_ENRAGE] = 0; 
     886                        break; 
     887 
     888                    default: 
     889                        break; 
     890                    } 
     891                    DoMeleeAttackIfReady(); 
     892                } 
     893 
     894                if(Phase == PHASE_FLIGHT) 
     895                { 
     896                    switch(Event) 
     897                    { 
     898                    case EVENT_FIREBALL: 
     899                        DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FIREBALL); 
     900                        Timer[EVENT_FIREBALL] = 3000; 
     901                        break; 
     902 
     903                    case EVENT_DARK_BARRAGE: 
     904                        DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DARK_BARRAGE); 
     905                        Timer[EVENT_DARK_BARRAGE] = 0; 
     906                        break; 
     907 
     908                    case EVENT_EYE_BLAST: 
     909                        CastEyeBlast();  
     910                        Timer[EVENT_EYE_BLAST] = 0; 
     911                        break; 
     912 
     913                    case EVENT_MOVE_POINT: 
     914                        Phase = PHASE_FLIGHT_SEQUENCE; 
     915                        Timer[EVENT_FLIGHT_SEQUENCE] = 0;//do not start Event when changing hover point 
     916                        for (uint8 i = 0; i <= rand()%3; i++) 
     917                        { 
     918                            HoverPoint++; 
     919                            if(HoverPoint > 3) 
     920                                HoverPoint = 0; 
     921                        } 
     922                        m_creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); 
     923                        m_creature->GetMotionMaster()->MovePoint(0, HoverPosition[HoverPoint].x, HoverPosition[HoverPoint].y, HoverPosition[HoverPoint].z); 
     924                        m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); 
     925                        break; 
     926 
     927                    default: 
     928                        break; 
     929                    } 
     930                } 
     931 
     932                if(Phase == PHASE_DEMON) 
     933                { 
     934                    switch(Event) 
     935                    { 
     936                    case EVENT_SHADOW_BLAST: 
     937                        m_creature->GetMotionMaster()->Clear(false); 
     938                        if(!m_creature->IsWithinDistInMap(m_creature->getVictim(), 50)||!m_creature->IsWithinLOSInMap(m_creature->getVictim())) 
     939                            m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), 30); 
     940                        else 
     941                            m_creature->GetMotionMaster()->MoveIdle(); 
     942                        DoCast(m_creature->getVictim(), SPELL_SHADOW_BLAST); 
     943                        Timer[EVENT_SHADOW_BLAST] = 4000; 
     944                        break; 
     945                    case EVENT_SHADOWDEMON: 
     946                        SummonShadowDemon(); 
     947                        Timer[EVENT_SHADOWDEMON] = 0; 
     948                        Timer[EVENT_FLAME_BURST] += 10000; 
     949                        break; 
     950                    case EVENT_FLAME_BURST: 
     951                        DoCast(m_creature, SPELL_FLAME_BURST); 
     952                        Timer[EVENT_FLAME_BURST] = 15000; 
     953                        break; 
     954                    case EVENT_TRANSFORM_DEMON: 
     955                        EnterPhase(PHASE_TRANSFORM_SEQUENCE); 
     956                        break; 
     957                    default: 
     958                        break; 
     959                    } 
     960                } 
     961    } 
     962}; 
     963 
     964/********************************** End of Illidan AI ******************************************/ 
     965 
     966//This is used to sort the players by distance in preparation for being charged by the flames. 
     967struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool> 
     968{ 
     969    const Unit* MainTarget; 
     970    TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {}; 
     971    // functor for operator ">" 
     972    bool operator()(const Unit* _Left, const Unit* _Right) const 
     973    { 
     974        return (MainTarget->GetDistance(_Left) > MainTarget->GetDistance(_Right)); 
     975    } 
     976}; 
     977 
     978struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI 
     979{ 
     980    flame_of_azzinothAI(Creature *c) : ScriptedAI(c) {Reset();} 
     981 
     982    uint32 FlameBlastTimer; 
     983    uint32 CheckTimer; 
     984    uint64 GlaiveGUID; 
     985 
     986    void Reset() 
     987    { 
     988        FlameBlastTimer = 15000; 
     989        CheckTimer = 5000; 
     990        GlaiveGUID = 0; 
     991    } 
     992 
     993    void Aggro(Unit *who) {} 
     994 
     995    void ChargeCheck() 
     996    {         
     997        // Get the Threat List 
     998        std::list<HostilReference *> m_threatlist = m_creature->getThreatManager().getThreatList(); 
     999 
     1000        if(!m_threatlist.size()) return; // He doesn't have anyone in his threatlist, useless to continue 
     1001 
     1002        std::list<Unit *> targets; 
     1003        std::list<HostilReference *>::iterator itr = m_threatlist.begin(); 
     1004        for( ; itr!= m_threatlist.end(); ++itr) //store the threat list in a different container 
     1005        { 
     1006            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); 
     1007            if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER && target->GetPositionZ()>350) //only on alive players 
     1008                targets.push_back(target); 
     1009        } 
     1010 
     1011        if (!targets.size()) 
     1012            return; 
     1013 
     1014        //Sort the list of players 
     1015        targets.sort(TargetDistanceOrder(m_creature)); 
     1016        //Resize so we only get the furthest target 
     1017        targets.resize(1); 
     1018 
     1019        Unit* target = (*targets.begin()); 
     1020        if(target && (!m_creature->IsWithinDistInMap(target, FLAME_CHARGE_DISTANCE))) 
     1021        { 
     1022            m_creature->AttackStop(); 
     1023            m_creature->GetMotionMaster()->Clear(false); 
     1024            float x, y, z; // is it possible to fix charge? 
     1025            target->GetContactPoint(m_creature, x, y, z); 
     1026            m_creature->Relocate(x,y,z); 
     1027            m_creature->SendMonsterMove(x, y, z, 0, MOVEMENTFLAG_WALK_MODE, 1); 
     1028            //m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); 
     1029            m_creature->StopMoving(); 
     1030            //DoCast(target, SPELL_CHARGE); 
     1031            m_creature->AddThreat(target, 5000000.0f); 
     1032            DoTextEmote("sets its gaze on $N!", target); 
     1033        } 
     1034    } 
     1035 
     1036    void EnrageCheck() 
     1037    { 
     1038        if(GETUNIT(Glaive, GlaiveGUID)) 
     1039        { 
     1040            if(!m_creature->IsWithinDistInMap(Glaive, FLAME_ENRAGE_DISTANCE)) 
     1041            { 
     1042                Glaive->InterruptNonMeleeSpells(true); 
     1043                DoCast(m_creature, SPELL_FLAME_ENRAGE, true); 
     1044                DoResetThreat(); 
     1045                Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
     1046                if(target && target->isAlive()) 
     1047                { 
     1048                    m_creature->AddThreat(m_creature->getVictim(), 5000000.0f); 
     1049                    AttackStart(m_creature->getVictim()); 
     1050                } 
     1051            } 
     1052            else if(!m_creature->HasAura(SPELL_AZZINOTH_CHANNEL, 0)) 
     1053            { 
     1054                Glaive->CastSpell(m_creature, SPELL_AZZINOTH_CHANNEL, false); 
     1055                m_creature->RemoveAurasDueToSpell(SPELL_FLAME_ENRAGE); 
     1056            } 
     1057        } 
     1058    } 
     1059 
     1060    void SetGlaiveGUID(uint64 guid){ GlaiveGUID = guid; } 
     1061 
     1062    void UpdateAI(const uint32 diff) 
     1063    { 
     1064        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
     1065            return; 
     1066 
     1067        if(FlameBlastTimer < diff) 
     1068        { 
     1069            DoCast(m_creature->getVictim(), SPELL_BLAZE_SUMMON, true); //appear at victim 
     1070            DoCast(m_creature->getVictim(), SPELL_FLAME_BLAST); 
     1071            FlameBlastTimer = 15000; //10000 is official-like? 
     1072            DoZoneInCombat(); //in case someone is revived 
     1073        }else FlameBlastTimer -= diff; 
     1074 
     1075        if(CheckTimer < diff) 
     1076        { 
     1077            ChargeCheck(); 
     1078            EnrageCheck(); 
     1079            CheckTimer = 5000; 
     1080        }else CheckTimer -= diff; 
     1081 
     1082        DoMeleeAttackIfReady(); 
     1083    } 
     1084}; 
     1085 
     1086 
     1087 
     1088/******* Functions and vars for Akama's AI ******/ 
     1089struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI 
     1090{ 
     1091    npc_akama_illidanAI(Creature* c) : ScriptedAI(c) 
     1092    { 
     1093        pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     1094        Reset(); 
     1095    } 
     1096 
     1097    ScriptedInstance* pInstance; 
     1098 
     1099    PhaseAkama Phase; 
     1100    bool Event; 
     1101    uint32 Timer; 
     1102 
    2941103    uint64 IllidanGUID; 
    295  
    296     bool IsTrigger; 
    297  
    298     uint32 CheckTimer; 
    299     uint32 DemonFireTimer; 
    300     uint32 DespawnTimer; 
     1104    uint64 ChannelGUID; 
     1105    uint64 SpiritGUID[2]; 
     1106    uint64 GateGUID; 
     1107    uint64 DoorGUID[2]; 
     1108 
     1109    uint32 ChannelCount; 
     1110    uint32 WalkCount; 
     1111    uint32 TalkCount; 
    3011112 
    3021113    void Reset() 
    3031114    { 
    304         IllidanGUID = 0; 
    305  
    306         IsTrigger = false; 
    307  
    308         CheckTimer = 2000; 
    309         DemonFireTimer = 0; 
    310         DespawnTimer = 45000; 
    311     } 
    312  
    313     void Aggro(Unit *who) {} 
    314     void AttackStart(Unit* who) { } 
    315     void MoveInLineOfSight(Unit *who){ } 
    316  
    317     void UpdateAI(const uint32 diff) 
    318     { 
    319         if(IsTrigger) 
    320             return; 
    321  
    322         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    323  
    324         if(CheckTimer < diff) 
    325         { 
    326             if(!IllidanGUID && pInstance) 
    327             { 
    328                 IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE); 
    329                 if(IllidanGUID) 
    330                 { 
    331                     Unit* Illidan = Unit::GetUnit((*m_creature), IllidanGUID); 
    332                     if(Illidan && !Illidan->HasUnitMovementFlag(MOVEMENTFLAG_LEVITATING)) 
    333                         m_creature->setDeathState(JUST_DIED); 
    334                 } 
    335             } 
    336             CheckTimer = 2000; 
    337         }else CheckTimer -= diff; 
    338  
    339         if(DemonFireTimer < diff) 
    340         { 
    341             DoCast(m_creature, SPELL_DEMON_FIRE); 
    342             DemonFireTimer = 30000; 
    343         }else DemonFireTimer -= diff; 
    344  
    345         if(DespawnTimer < diff) 
    346             m_creature->setDeathState(JUST_DIED); 
    347         else DespawnTimer -= diff; 
    348  
    349         DoMeleeAttackIfReady(); 
    350     } 
    351 }; 
    352  
    353 /******* Functions and vars for Akama's AI ******/ 
    354 struct TRINITY_DLL_SPEC npc_akama_illidanAI : public ScriptedAI 
    355 { 
    356     npc_akama_illidanAI(Creature* c) : ScriptedAI(c) 
    357     { 
    358         pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
    359         WayPointList.clear(); 
    360         Reset(); 
    361     } 
    362  
    363     /* Instance Data */ 
    364     ScriptedInstance* pInstance; 
    365  
    366     /* Timers */ 
    367     uint32 ChannelTimer; 
    368     uint32 TalkTimer; 
    369     uint32 WalkTimer; 
    370     uint32 SummonMinionTimer; 
    371  
    372     /* GUIDs */ 
    373     uint64 IllidanGUID; 
    374     uint64 PlayerGUID; 
    375     uint64 SpiritGUID[2]; 
    376     uint64 ChannelGUID; 
    377  
    378     bool IsTalking; 
    379     bool StartChanneling; 
    380     bool DoorOpen; 
    381     bool FightMinions; 
    382     bool IsReturningToIllidan; 
    383     bool IsWalking; 
    384     uint32 TalkCount; 
    385     uint32 ChannelCount; 
    386  
    387     std::list<WayPoints> WayPointList; 
    388     std::list<WayPoints>::iterator WayPoint; 
    389  
    390     void BeginEvent(uint64 PlayerGUID); 
    391     void Aggro(Unit *who) {} 
    392  
    393     void Reset() 
    394     { 
    3951115        if(pInstance) 
    3961116        { 
    3971117            pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, NOT_STARTED); 
    398             GameObject* Gate = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE)); 
    399             if( Gate && !Gate->GetGoState() ) 
    400                 Gate->SetGoState(1);                        // close door if already open (when raid wipes or something) 
    401  
    402             for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L + 1; ++i) 
    403             { 
    404                 GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i)); 
    405                 if(Door) 
    406                     Door->SetGoState(0); 
    407             } 
    408         } 
    409  
    410         IllidanGUID = 0; 
    411         PlayerGUID  = 0; 
     1118 
     1119            IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE); 
     1120            GateGUID = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE); 
     1121            DoorGUID[0] = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_DOOR_R); 
     1122            DoorGUID[1] = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_DOOR_L); 
     1123 
     1124            if(GETGO(Gate, GateGUID)) 
     1125                Gate->SetUInt32Value(GAMEOBJECT_STATE, 1); 
     1126            for(uint8 i = 0; i < 2; i++) 
     1127                if(GETGO(Door, DoorGUID[i])) 
     1128                    Door->SetUInt32Value(GAMEOBJECT_STATE, 1); 
     1129        } 
     1130        else 
     1131        { 
     1132            IllidanGUID = 0; 
     1133            GateGUID = 0; 
     1134            DoorGUID[0] = 0; 
     1135            DoorGUID[1] = 0; 
     1136        } 
     1137 
    4121138        ChannelGUID = 0; 
    413         for(uint8 i = 0; i < 2; ++i) SpiritGUID[i] = 0; 
    414  
    415         ChannelTimer = 0; 
     1139        SpiritGUID[0] = 0; 
     1140        SpiritGUID[1] = 0; 
     1141 
     1142        Phase = PHASE_AKAMA_NULL; 
     1143        Timer = 0; 
     1144 
    4161145        ChannelCount = 0; 
    417         SummonMinionTimer = 2000; 
    418  
    419         WalkTimer = 0; 
    420  
    421         TalkTimer = 0; 
     1146        WalkCount = 0; 
    4221147        TalkCount = 0; 
    4231148 
    4241149        KillAllElites(); 
    4251150 
    426         IsReturningToIllidan = false; 
    427         FightMinions = false; 
    428         IsTalking = false; 
    429         StartChanneling = false; 
    430         DoorOpen = false; 
    431  
    432         m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0);      // Database sometimes has strange values.. 
     1151        m_creature->SetUInt32Value(UNIT_NPC_FLAGS, 0); // Database sometimes has strange values.. 
    4331152        m_creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); 
    434         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    435         m_creature->SetVisibility(VISIBILITY_ON); 
    4361153    } 
    4371154 
     
    4391156    void EnterEvadeMode() 
    4401157    { 
    441         InCombat = false; 
    442  
     1158        m_creature->InterruptNonMeleeSpells(true); 
    4431159        m_creature->RemoveAllAuras(); 
    4441160        m_creature->DeleteThreatList(); 
    4451161        m_creature->CombatStop(); 
     1162        InCombat = false; 
     1163    } 
     1164 
     1165    void Aggro(Unit *who) {} 
     1166 
     1167    void MovementInform(uint32 MovementType, uint32 Data) {Timer = 1;} 
     1168 
     1169    void DamageTaken(Unit *done_by, uint32 &damage) 
     1170    { 
     1171        if(damage > m_creature->GetHealth() || done_by->GetGUID() != IllidanGUID) 
     1172            damage = 0; 
    4461173    } 
    4471174 
     
    4551182                pUnit->setDeathState(JUST_DIED); 
    4561183        } 
    457     } 
    458  
    459     void ReturnToIllidan() 
    460     { 
    461         KillAllElites(); 
    462         InCombat = false; 
    463         FightMinions = false; 
    464         IsReturningToIllidan = true; 
    465         WayPoint = WayPointList.begin(); 
    466         m_creature->SetSpeed(MOVE_RUN, 2.0f); 
     1184        EnterEvadeMode(); 
     1185    } 
     1186 
     1187    void BeginTalk() 
     1188    { 
     1189        pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, IN_PROGRESS); 
     1190 
     1191        for(uint8 i = 0; i < 2; i++) 
     1192            if(GETGO(Door, DoorGUID[i])) 
     1193                Door->SetUInt32Value(GAMEOBJECT_STATE, 1); 
     1194 
     1195        if(GETCRE(Illidan, IllidanGUID)) 
     1196        { 
     1197            Illidan->RemoveAurasDueToSpell(SPELL_KNEEL); 
     1198            m_creature->SetInFront(Illidan); 
     1199            Illidan->SetInFront(m_creature); 
     1200            m_creature->StopMoving(); 
     1201            Illidan->StopMoving(); 
     1202            ((boss_illidan_stormrageAI*)Illidan->AI())->AkamaGUID = m_creature->GetGUID(); 
     1203            ((boss_illidan_stormrageAI*)Illidan->AI())->EnterPhase(PHASE_TALK_SEQUENCE); 
     1204        } 
     1205    } 
     1206 
     1207    void BeginChannel() 
     1208    { 
     1209        float x, y, z; 
     1210        if(GETGO(Gate, GateGUID)) 
     1211            Gate->GetPosition(x, y, z); 
     1212 
     1213        if(Creature* Channel = m_creature->SummonCreature(ILLIDAN_DOOR_TRIGGER, x, y, z+5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000)) 
     1214        { 
     1215            ChannelGUID = Channel->GetGUID(); 
     1216            Channel->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); // Invisible but spell visuals can still be seen. 
     1217            m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); 
     1218            DoCast(Channel, SPELL_AKAMA_DOOR_FAIL); 
     1219        } 
     1220 
     1221        for(uint8 i = 0; i < 2; ++i) 
     1222            if(Creature* Spirit = m_creature->SummonCreature(i ? SPIRIT_OF_OLUM : SPIRIT_OF_UDALO, SpiritSpawns[i].x, SpiritSpawns[i].y, SpiritSpawns[i].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000)) 
     1223            { 
     1224                Spirit->SetVisibility(VISIBILITY_OFF); 
     1225                SpiritGUID[i] = Spirit->GetGUID(); 
     1226            } 
     1227    } 
     1228 
     1229    void BeginWalk() 
     1230    { 
    4671231        m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); 
    468         IsWalking = true; 
    469     } 
    470  
    471     void AddWaypoint(uint32 id, float x, float y, float z) 
    472     { 
    473         WayPoints AkamaWP(id, x, y, z); 
    474         WayPointList.push_back(AkamaWP); 
    475     } 
    476  
    477     void DamageTaken(Unit *done_by, uint32 &damage) 
    478     { 
    479         if(damage > m_creature->GetHealth() && (done_by->GetGUID() != m_creature->GetGUID())) 
    480         { 
    481             damage = 0; 
    482             DoCast(m_creature, SPELL_HEALING_POTION); 
    483         } 
    484     } 
    485  
    486     void BeginDoorEvent(Player* player) 
    487     { 
    488         if(!pInstance) 
    489             return; 
    490  
    491         outstring_log("SD2: Akama - Door event initiated by player %s", player->GetName()); 
    492         PlayerGUID = player->GetGUID(); 
    493  
    494         GameObject* Gate = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE)); 
    495         if(Gate) 
    496         { 
    497             float x,y,z; 
    498             Gate->GetPosition(x, y, z); 
    499             Creature* Channel = m_creature->SummonCreature(ILLIDAN_DOOR_TRIGGER, x, y, z+5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000); 
    500             if(Channel) 
    501             { 
    502                 ChannelGUID = Channel->GetGUID(); 
    503                 // Invisible but spell visuals can still be seen. 
    504                 Channel->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); 
    505                 Channel->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    506                 float PosX, PosY, PosZ; 
    507                 m_creature->GetPosition(PosX, PosY, PosZ); 
    508                 for(uint8 i = 0; i < 2; ++i) 
     1232        m_creature->SetSpeed(MOVE_RUN, 1.0f); 
     1233        m_creature->GetMotionMaster()->MovePoint(0, AkamaWP[WalkCount].x, AkamaWP[WalkCount].y, AkamaWP[WalkCount].z); 
     1234    } 
     1235 
     1236    void EnterPhase(PhaseAkama NextPhase) 
     1237    { 
     1238        if(!pInstance)  return; 
     1239        switch(NextPhase) 
     1240        { 
     1241        case PHASE_CHANNEL: 
     1242            BeginChannel(); 
     1243            Timer = 5000; 
     1244            ChannelCount = 0; 
     1245            break; 
     1246        case PHASE_WALK: 
     1247            if(Phase == PHASE_CHANNEL) 
     1248                WalkCount = 0; 
     1249            else if(Phase == PHASE_TALK) 
     1250            { 
     1251                if(GETCRE(Illidan, IllidanGUID)) 
     1252                    ((boss_illidan_stormrageAI*)Illidan->AI())->DeleteFromThreatList(m_creature->GetGUID()); 
     1253                EnterEvadeMode(); 
     1254                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
     1255                WalkCount++; 
     1256            } 
     1257            BeginWalk(); 
     1258            Timer = 0; 
     1259            break; 
     1260        case PHASE_TALK: 
     1261            if(Phase == PHASE_WALK) 
     1262            { 
     1263                BeginTalk(); 
     1264                Timer = 0; 
     1265            } 
     1266            else if(Phase == PHASE_FIGHT_ILLIDAN) 
     1267            { 
     1268                Timer = 1; 
     1269                TalkCount = 0; 
     1270            } 
     1271            break; 
     1272        case PHASE_FIGHT_ILLIDAN: 
     1273            if(GETUNIT(Illidan, IllidanGUID)) 
     1274            { 
     1275                m_creature->AddThreat(Illidan, 10000000.0f); 
     1276                m_creature->GetMotionMaster()->MoveChase(Illidan); 
     1277            } 
     1278            Timer = 30000; //chain lightning 
     1279            break; 
     1280        case PHASE_FIGHT_MINIONS: 
     1281            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
     1282            Timer = 10000 + rand()%6000;//summon minion 
     1283            break; 
     1284        case PHASE_RETURN: 
     1285            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
     1286            KillAllElites(); 
     1287            WalkCount = 0; 
     1288            BeginWalk(); 
     1289            Timer = 1; 
     1290            break; 
     1291        default: 
     1292            break; 
     1293        } 
     1294        Phase = NextPhase; 
     1295        Event = false; 
     1296    } 
     1297 
     1298    void HandleTalkSequence() 
     1299    { 
     1300        switch(TalkCount) 
     1301        { 
     1302        case 0: 
     1303            if(GETCRE(Illidan, IllidanGUID)) 
     1304            { 
     1305                ((boss_illidan_stormrageAI*)Illidan->AI())->Timer[EVENT_TAUNT] += 30000; 
     1306                Illidan->Yell(SAY_AKAMA_MINION, LANG_UNIVERSAL, 0); 
     1307                DoPlaySoundToSet(Illidan, SOUND_AKAMA_MINION); 
     1308            } 
     1309            Timer = 8000; 
     1310            break; 
     1311        case 1: 
     1312            DoYell(SAY_AKAMA_LEAVE, LANG_UNIVERSAL, NULL); 
     1313            DoPlaySoundToSet(m_creature, SOUND_AKAMA_LEAVE); 
     1314            Timer = 3000; 
     1315            break; 
     1316        case 2: 
     1317            EnterPhase(PHASE_WALK); 
     1318            break; 
     1319        } 
     1320        TalkCount++; 
     1321    } 
     1322 
     1323    void HandleChannelSequence() 
     1324    { 
     1325        Unit* Channel, *Spirit[2]; 
     1326        if(ChannelCount <= 5) 
     1327        { 
     1328            Channel = Unit::GetUnit((*m_creature), ChannelGUID); 
     1329            Spirit[0] = Unit::GetUnit((*m_creature), SpiritGUID[0]); 
     1330            Spirit[1] = Unit::GetUnit((*m_creature), SpiritGUID[1]); 
     1331            if(!Channel || !Spirit[0] || !Spirit[1]) 
     1332                return; 
     1333        } 
     1334 
     1335        switch(ChannelCount) 
     1336        { 
     1337        case 0: // channel failed 
     1338            m_creature->InterruptNonMeleeSpells(true); 
     1339            Timer = 2000; 
     1340            break; 
     1341        case 1: // spirit appear 
     1342            Spirit[0]->SetVisibility(VISIBILITY_ON); 
     1343            Spirit[1]->SetVisibility(VISIBILITY_ON); 
     1344            Timer = 2000; 
     1345            break; 
     1346        case 2: // spirit help 
     1347            DoCast(Channel, SPELL_AKAMA_DOOR_CHANNEL); 
     1348            Spirit[0]->CastSpell(Channel, SPELL_DEATHSWORN_DOOR_CHANNEL,false); 
     1349            Spirit[1]->CastSpell(Channel, SPELL_DEATHSWORN_DOOR_CHANNEL,false); 
     1350            Timer = 5000; 
     1351            break; 
     1352        case 3: //open the gate 
     1353            m_creature->InterruptNonMeleeSpells(true); 
     1354            Spirit[0]->InterruptNonMeleeSpells(true); 
     1355            Spirit[1]->InterruptNonMeleeSpells(true); 
     1356            if(GETGO(Gate, GateGUID)) 
     1357                Gate->SetUInt32Value(GAMEOBJECT_STATE, 0); 
     1358            Timer = 2000; 
     1359            break; 
     1360        case 4: 
     1361            m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); 
     1362            Timer = 2000; 
     1363            break; 
     1364        case 5: 
     1365            DoYell(SAY_AKAMA_BEWARE, LANG_UNIVERSAL, NULL); 
     1366            DoPlaySoundToSet(m_creature, SOUND_AKAMA_BEWARE); 
     1367            Channel->setDeathState(JUST_DIED); 
     1368            Spirit[0]->setDeathState(JUST_DIED); 
     1369            Spirit[1]->setDeathState(JUST_DIED); 
     1370            Timer = 3000; 
     1371            break; 
     1372        case 6: 
     1373            EnterPhase(PHASE_WALK); 
     1374            break; 
     1375        default: 
     1376            break; 
     1377        } 
     1378        ChannelCount++; 
     1379    } 
     1380 
     1381    void HandleWalkSequence() 
     1382    { 
     1383        switch(WalkCount) 
     1384        { 
     1385        case 6: 
     1386            for(uint8 i = 0; i < 2; i++) 
     1387                if(GETGO(Door, DoorGUID[i])) 
     1388                    Door->SetUInt32Value(GAMEOBJECT_STATE, 0); 
     1389            break; 
     1390        case 8: 
     1391            if(Phase == PHASE_WALK) 
     1392                EnterPhase(PHASE_TALK); 
     1393            else 
     1394                EnterPhase(PHASE_FIGHT_ILLIDAN); 
     1395            break; 
     1396        case 12: 
     1397            EnterPhase(PHASE_FIGHT_MINIONS); 
     1398            break; 
     1399        } 
     1400 
     1401        if(Phase == PHASE_WALK) 
     1402        { 
     1403            Timer = 0; 
     1404            WalkCount++; 
     1405            m_creature->GetMotionMaster()->MovePoint(WalkCount, AkamaWP[WalkCount].x, AkamaWP[WalkCount].y, AkamaWP[WalkCount].z); 
     1406        } 
     1407    } 
     1408 
     1409    void UpdateAI(const uint32 diff) 
     1410    { 
     1411        Event = false; 
     1412        if(Timer) 
     1413        { 
     1414            if(Timer <= diff) 
     1415                Event = true; 
     1416            else Timer -= diff; 
     1417        } 
     1418 
     1419        if(Event) 
     1420        { 
     1421            switch(Phase) 
     1422            { 
     1423            case PHASE_CHANNEL: 
     1424                HandleChannelSequence(); 
     1425                break; 
     1426            case PHASE_TALK: 
     1427                HandleTalkSequence(); 
     1428                break; 
     1429            case PHASE_WALK: 
     1430            case PHASE_RETURN: 
     1431                HandleWalkSequence(); 
     1432                break; 
     1433            case PHASE_FIGHT_ILLIDAN: 
    5091434                { 
    510                     Creature* Spirit = m_creature->SummonCreature(SpiritSpawns[i].id, SpiritSpawns[i].x, SpiritSpawns[i].y, SpiritSpawns[i].z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000); 
    511                     if(Spirit) 
     1435                    GETUNIT(Illidan, IllidanGUID); 
     1436                    if(Illidan && HPPCT(Illidan) < 90) 
     1437                        EnterPhase(PHASE_TALK); 
     1438                    else 
    5121439                    { 
    513                         Spirit->SetVisibility(VISIBILITY_OFF); 
    514                         SpiritGUID[i] = Spirit->GetGUID(); 
     1440                        DoCast(m_creature->getVictim(), SPELL_CHAIN_LIGHTNING); 
     1441                        Timer = 30000; 
    5151442                    } 
    516                 } 
    517                 StartChanneling = true; 
    518                 m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); 
    519                 m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    520                 DoCast(Channel, SPELL_AKAMA_DOOR_FAIL); 
    521             } 
    522         } 
    523     } 
    524  
    525     void MovementInform(uint32 type, uint32 id) 
    526     { 
    527         if(type != POINT_MOTION_TYPE || !IsWalking) 
    528             return; 
    529  
    530         if(WayPoint->id != id) 
    531             return; 
    532  
    533         switch(id) 
    534         { 
    535             case 6: 
    536                 if(!IsReturningToIllidan) 
    537                 {                                           // open the doors that close the summit 
    538                     for(uint32 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L+1; ++i) 
     1443                }break; 
     1444            case PHASE_FIGHT_MINIONS: 
     1445                { 
     1446                    float x, y, z; 
     1447                    m_creature->GetPosition(x, y, z); 
     1448                    Creature* Elite = m_creature->SummonCreature(ILLIDARI_ELITE, x+rand()%10, y+rand()%10, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000); 
     1449                    //Creature* Elite = m_creature->SummonCreature(ILLIDARI_ELITE, x, y, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000); 
     1450                    if(Elite) 
    5391451                    { 
    540                         GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i)); 
    541                         if(Door) 
    542                             Door->SetGoState(0); 
     1452                        Elite->AI()->AttackStart(m_creature); 
     1453                        Elite->AddThreat(m_creature, 1000000.0f); 
     1454                        AttackStart(Elite); 
    5431455                    } 
    544                 } 
    545             case 7: 
    546                 if(IsReturningToIllidan) 
    547                 { 
    548                     IsWalking = false; 
    549                     if(IllidanGUID) 
    550                     { 
    551                         Unit* Illidan = Unit::GetUnit((*m_creature), IllidanGUID); 
    552                         if(Illidan) 
    553                         { 
    554                             float dx = Illidan->GetPositionX() + rand()%15; 
    555                             float dy = Illidan->GetPositionY() + rand()%15; 
    556                             m_creature->GetMotionMaster()->MovePoint(13, dx, dy, Illidan->GetPositionZ()); 
    557                             m_creature->SetUInt64Value(UNIT_FIELD_TARGET, IllidanGUID); 
    558                         } 
    559                     } 
     1456                    Timer = 10000 + rand()%6000; 
     1457                    GETUNIT(Illidan, IllidanGUID); 
     1458                    if(Illidan && HPPCT(Illidan) < 10) 
     1459                        EnterPhase(PHASE_RETURN); 
    5601460                } 
    5611461                break; 
    562             case 8: 
    563                 m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    564                 if(!IsReturningToIllidan) 
     1462            default: 
     1463                break; 
     1464            } 
     1465        } 
     1466 
     1467        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
     1468            return; 
     1469 
     1470        if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 20) 
     1471            DoCast(m_creature, SPELL_HEALING_POTION); 
     1472 
     1473        DoMeleeAttackIfReady(); 
     1474    } 
     1475}; 
     1476 
     1477 
     1478struct TRINITY_DLL_DECL boss_maievAI : public ScriptedAI 
     1479{ 
     1480    boss_maievAI(Creature *c) : ScriptedAI(c) { Reset(); }; 
     1481 
     1482    uint64 IllidanGUID; 
     1483 
     1484    PhaseIllidan Phase; 
     1485    EventMaiev Event; 
     1486    uint32 Timer[5]; 
     1487    uint32 MaxTimer; 
     1488 
     1489    void Reset() 
     1490    { 
     1491        MaxTimer = 0; 
     1492        Phase = PHASE_NORMAL_MAIEV; 
     1493        IllidanGUID = 0; 
     1494        Timer[EVENT_MAIEV_STEALTH] = 0; 
     1495        Timer[EVENT_MAIEV_TAUNT] = 22000 + rand()%21 * 1000; 
     1496        Timer[EVENT_MAIEV_SHADOW_STRIKE] = 30000; 
     1497        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 44850); 
     1498        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0); 
     1499        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 2, 45738); 
     1500    } 
     1501 
     1502    void Aggro(Unit *who) {} 
     1503    void MoveInLineOfSight(Unit *who) {} 
     1504    void EnterEvadeMode() {} 
     1505    void GetIllidanGUID(uint64 guid) { IllidanGUID = guid; } 
     1506 
     1507    void DamageTaken(Unit *done_by, uint32 &damage) 
     1508    { 
     1509        if(done_by->GetGUID() != IllidanGUID ) 
     1510            damage = 0; 
     1511        else 
     1512        { 
     1513            GETUNIT(Illidan, IllidanGUID); 
     1514            if(Illidan && Illidan->getVictim() == m_creature) 
     1515                damage = m_creature->GetMaxHealth()/10; 
     1516            if(damage >= m_creature->GetHealth()) 
     1517                damage = 0; 
     1518        } 
     1519    } 
     1520 
     1521    void AttackStart(Unit *who) 
     1522    { 
     1523        if(!who || Timer[EVENT_MAIEV_STEALTH]) 
     1524            return; 
     1525 
     1526        if (who->isTargetableForAttack()) 
     1527        { 
     1528            if(Phase == PHASE_TALK_SEQUENCE) 
     1529                m_creature->Attack(who, false); 
     1530            else if(Phase == PHASE_DEMON || Phase == PHASE_TRANSFORM_SEQUENCE ) 
     1531            { 
     1532                GETUNIT(Illidan, IllidanGUID); 
     1533                if(Illidan && m_creature->IsWithinDistInMap(Illidan, 25)) 
     1534                    BlinkToPlayer();//Do not let dread aura hurt her. 
     1535                m_creature->Attack(who, false); 
     1536            } 
     1537            else 
     1538                DoStartAttackAndMovement(who); 
     1539 
     1540            if (!InCombat) 
     1541            { 
     1542                Aggro(who); 
     1543                InCombat = true; 
     1544            } 
     1545        } 
     1546    } 
     1547 
     1548    void EnterPhase(PhaseIllidan NextPhase)//This is in fact Illidan's phase. 
     1549    { 
     1550        switch(NextPhase) 
     1551        { 
     1552        case PHASE_TALK_SEQUENCE: 
     1553            if(Timer[EVENT_MAIEV_STEALTH]) 
     1554            { 
     1555                m_creature->SetHealth(m_creature->GetMaxHealth()); 
     1556                m_creature->SetVisibility(VISIBILITY_ON); 
     1557                Timer[EVENT_MAIEV_STEALTH] = 0; 
     1558            } 
     1559            m_creature->InterruptNonMeleeSpells(false); 
     1560            m_creature->GetMotionMaster()->Clear(false); 
     1561            //m_creature->GetMotionMaster()->MoveIdle(); 
     1562            m_creature->AttackStop(); 
     1563            m_creature->SetUInt64Value(UNIT_FIELD_TARGET, IllidanGUID); 
     1564            MaxTimer = 0; 
     1565            break; 
     1566        case PHASE_TRANSFORM_SEQUENCE: 
     1567            MaxTimer = 4; 
     1568            Timer[EVENT_MAIEV_TAUNT] += 10000; 
     1569            Timer[EVENT_MAIEV_THROW_DAGGER] = 2000; 
     1570            break; 
     1571        case PHASE_DEMON: 
     1572            break; 
     1573        case PHASE_NORMAL_MAIEV: 
     1574            MaxTimer = 4; 
     1575            Timer[EVENT_MAIEV_TAUNT] += 10000; 
     1576            Timer[EVENT_MAIEV_TRAP] = 22000; 
     1577            break; 
     1578        default: 
     1579            break; 
     1580        } 
     1581        if(Timer[EVENT_MAIEV_STEALTH]) 
     1582            MaxTimer = 1; 
     1583        Phase = NextPhase; 
     1584    } 
     1585 
     1586    void BlinkTo(float x, float y, float z) 
     1587    { 
     1588        m_creature->AttackStop(); 
     1589        m_creature->InterruptNonMeleeSpells(false); 
     1590        m_creature->GetMotionMaster()->Clear(false); 
     1591        //m_creature->GetMotionMaster()->MoveIdle(); 
     1592        m_creature->Relocate(x, y, z); 
     1593        m_creature->SendMonsterMove(x, y, z, 0, 0, 0); 
     1594        DoCast(m_creature, SPELL_TELEPORT_VISUAL, true); 
     1595    } 
     1596 
     1597    void BlinkToPlayer() 
     1598    { 
     1599        if(GETCRE(Illidan, IllidanGUID)) 
     1600        { 
     1601            Unit* target = ((boss_illidan_stormrageAI*)Illidan->AI())->SelectUnit(SELECT_TARGET_RANDOM, 0); 
     1602 
     1603            if(!target || !m_creature->IsWithinDistInMap(target, 80) || Illidan->IsWithinDistInMap(target, 20)) 
     1604            { 
     1605                uint8 pos = rand()%4; 
     1606                BlinkTo(HoverPosition[pos].x, HoverPosition[pos].y, HoverPosition[pos].z); 
     1607            } 
     1608            else 
     1609            { 
     1610                float x, y, z; 
     1611                target->GetPosition(x, y, z); 
     1612                BlinkTo(x, y, z); 
     1613            } 
     1614        } 
     1615    } 
     1616 
     1617    void UpdateAI(const uint32 diff) 
     1618    { 
     1619        if((!m_creature->SelectHostilTarget() || !m_creature->getVictim()) && !Timer[1]) 
     1620            return; 
     1621 
     1622        Event = EVENT_MAIEV_NULL; 
     1623        for(uint8 i = 1; i <= MaxTimer; i++) 
     1624            if(Timer[i]) 
     1625            { 
     1626                if(Timer[i] <= diff) 
     1627                    Event = (EventMaiev)i; 
     1628                else Timer[i] -= diff; 
     1629            } 
     1630 
     1631            switch(Event) 
     1632            { 
     1633            case EVENT_MAIEV_STEALTH: 
    5651634                { 
    566                     IsWalking = false; 
    567                     BeginEvent(PlayerGUID); 
    568                 } 
     1635                    m_creature->SetHealth(m_creature->GetMaxHealth()); 
     1636                    m_creature->SetVisibility(VISIBILITY_ON); 
     1637                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
     1638                    Timer[EVENT_MAIEV_STEALTH] = 0; 
     1639                    BlinkToPlayer(); 
     1640                    EnterPhase(Phase); 
     1641                }break; 
     1642            case EVENT_MAIEV_TAUNT: 
     1643                { 
     1644                    uint32 random = rand()%4; 
     1645                    char* text = MaievTaunts[random].text; 
     1646                    uint32 sound = MaievTaunts[random].sound; 
     1647                    DoYell(text, LANG_UNIVERSAL, NULL); 
     1648                    DoPlaySoundToSet(m_creature, sound); 
     1649                    Timer[EVENT_MAIEV_TAUNT] = 22000 + rand()%21 * 1000; 
     1650                }break; 
     1651            case EVENT_MAIEV_SHADOW_STRIKE: 
     1652                DoCast(m_creature->getVictim(), SPELL_SHADOW_STRIKE); 
     1653                Timer[EVENT_MAIEV_SHADOW_STRIKE] = 60000; 
    5691654                break; 
    570             case 12: 
    571                 IsWalking = false; 
    572                 FightMinions = true; 
    573                 m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    574                 break; 
    575         } 
    576  
    577         ++WayPoint; 
    578         WalkTimer = 200; 
    579     } 
    580  
    581     void DeleteFromThreatList() 
    582     { 
    583         if(!IllidanGUID) return;                            // If we do not have Illidan's GUID, do not proceed 
    584                                                             // Create a pointer to Illidan 
    585         Creature* Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID)); 
    586         if(!Illidan) return;                                // No use to continue if Illidan does not exist 
    587         std::list<HostilReference*>::iterator itr = Illidan->getThreatManager().getThreatList().begin(); 
    588         for( ; itr != Illidan->getThreatManager().getThreatList().end(); ++itr) 
    589         { 
    590             // Loop through threatlist till our GUID is found in it. 
    591             if((*itr)->getUnitGuid() == m_creature->GetGUID()) 
    592             { 
    593                 (*itr)->removeReference();                  // Delete ourself from his threatlist. 
    594                 return;                                     // No need to continue anymore. 
    595             } 
    596         } 
    597  
    598         // Now we delete our threatlist to prevent attacking anyone for now 
    599         m_creature->DeleteThreatList(); 
    600     } 
    601  
    602     void UpdateAI(const uint32 diff) 
    603     { 
    604         if(IllidanGUID) 
    605         { 
    606             Creature* Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID)); 
    607             if(Illidan) 
    608             { 
    609                 if(Illidan->IsInEvadeMode() && !m_creature->IsInEvadeMode()) 
    610                     EnterEvadeMode(); 
    611  
    612                 if(((Illidan->GetHealth()*100 / Illidan->GetMaxHealth()) < 85) && InCombat && !FightMinions) 
     1655            case EVENT_MAIEV_TRAP: 
     1656                if(Phase == PHASE_NORMAL_MAIEV) 
    6131657                { 
    614                     if(TalkTimer < diff) 
    615                     { 
    616                         switch(TalkCount) 
    617                         { 
    618                             case 0: 
    619                                 Illidan->Yell(SAY_AKAMA_MINION, LANG_UNIVERSAL, 0); 
    620                                 DoPlaySoundToSet(Illidan, SOUND_AKAMA_MINION); 
    621                                 TalkTimer = 8000; 
    622                                 TalkCount = 1; 
    623                                 break; 
    624                             case 1: 
    625                                 DoYell(SAY_AKAMA_LEAVE, LANG_UNIVERSAL, NULL); 
    626                                 DoPlaySoundToSet(m_creature, SOUND_AKAMA_LEAVE); 
    627                                 TalkTimer = 3000; 
    628                                 TalkCount = 2; 
    629                                 break; 
    630                             case 2: 
    631                                 IsTalking = true; 
    632                                 TalkTimer = 2000; 
    633                                 m_creature->RemoveAllAuras(); 
    634                                 m_creature->CombatStop(); 
    635                                 m_creature->AttackStop(); 
    636                                 m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    637                                 TalkCount = 3; 
    638                                 break; 
    639                             case 3: 
    640                                 DeleteFromThreatList(); 
    641                                 IsWalking = true; 
    642                                 WayPoint = WayPointList.begin(); 
    643                                 std::advance(WayPoint, 9); 
    644                                 m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); 
    645                                 break; 
    646                         } 
    647                     }else TalkTimer -= diff; 
    648                 } 
    649  
    650                 if(((Illidan->GetHealth()*100 / Illidan->GetMaxHealth()) < 4) && !IsReturningToIllidan) 
    651                     ReturnToIllidan(); 
    652             } 
    653         }else 
    654         { 
    655             if(pInstance) 
    656                 IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE); 
    657         } 
    658  
    659         if(IsWalking && WalkTimer) 
    660         { 
    661             if(WalkTimer <= diff) 
    662             { 
    663                 if(WayPoint == WayPointList.end()) 
    664                     return; 
    665                 m_creature->GetMotionMaster()->MovePoint(WayPoint->id, WayPoint->x, WayPoint->y,WayPoint->z); 
    666                 WalkTimer = 0; 
    667             }else WalkTimer -= diff; 
    668         } 
    669  
    670         if(StartChanneling) 
    671         { 
    672             if(ChannelTimer < diff) 
    673             { 
    674                 switch(ChannelCount) 
    675                 { 
    676                     case 3: 
    677                         if(!DoorOpen) 
    678                         { 
    679                             m_creature->InterruptNonMeleeSpells(true); 
    680                             for(uint8 i = 0; i < 2; ++i) 
    681                             { 
    682                                 if(SpiritGUID[i]) 
    683                                 { 
    684                                     Unit* Spirit = Unit::GetUnit((*m_creature), SpiritGUID[i]); 
    685                                     if(Spirit) 
    686                                         Spirit->InterruptNonMeleeSpells(true); 
    687                                 } 
    688                             } 
    689                             GameObject* Gate = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_GATE)); 
    690                             if(Gate) 
    691                                 Gate->SetGoState(0); 
    692                             ChannelCount++; 
    693                             ChannelTimer = 5000; 
    694                         } 
    695                         break; 
    696                     case 4: 
    697                         m_creature->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE); 
    698                         ChannelTimer = 2000; 
    699                         ChannelCount++; 
    700                         break; 
    701                     case 5: 
    702                         DoYell(SAY_AKAMA_BEWARE, LANG_UNIVERSAL, NULL); 
    703                         DoPlaySoundToSet(m_creature, SOUND_AKAMA_BEWARE); 
    704                         if(ChannelGUID) 
    705                         { 
    706                             Unit* ChannelTarget = Unit::GetUnit((*m_creature), ChannelGUID); 
    707                             if(ChannelTarget) 
    708                                 ChannelTarget->setDeathState(JUST_DIED); 
    709                         } 
    710                         for(uint8 i = 0; i < 2; ++i) 
    711                         { 
    712                             if(SpiritGUID[i]) 
    713                             { 
    714                                 Unit* Spirit = Unit::GetUnit((*m_creature), SpiritGUID[i]); 
    715                                 if(Spirit) 
    716                                     Spirit->setDeathState(JUST_DIED); 
    717                             } 
    718                         } 
    719                         ChannelTimer = 6000; 
    720                         ChannelCount++; 
    721                         break; 
    722                     case 6: 
    723                         StartChanneling = false; 
    724                         if(WayPointList.empty()) 
    725                         { 
    726                             error_log("SD2: Akama has no waypoints to start with!"); 
    727                             return; 
    728                         } 
    729  
    730                         WayPoint = WayPointList.begin(); 
    731                         m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); 
    732                         m_creature->GetMotionMaster()->MovePoint(WayPoint->id, WayPoint->x, WayPoint->y, WayPoint->z); 
    733                         IsWalking = true; 
    734                         break; 
    735                     default: 
    736                         if(ChannelGUID) 
    737                         { 
    738                             Unit* Channel = Unit::GetUnit((*m_creature), ChannelGUID); 
    739                             if(Channel) 
    740                             { 
    741                                 m_creature->InterruptNonMeleeSpells(true); 
    742  
    743                                 for(uint8 i = 0; i < 2; ++i) 
    744                                 { 
    745                                     if(SpiritGUID[i]) 
    746                                     { 
    747                                         Unit* Spirit = Unit::GetUnit((*m_creature), SpiritGUID[i]); 
    748                                         if(Spirit) 
    749                                         { 
    750                                             Spirit->InterruptNonMeleeSpells(true); 
    751                                             if(ChannelCount%2 == 0) 
    752                                             { 
    753                                                 Spirit->CastSpell(Channel, SPELL_DEATHSWORN_DOOR_CHANNEL,false); 
    754                                                 DoCast(Channel, SPELL_AKAMA_DOOR_CHANNEL); 
    755                                             } 
    756                                             else 
    757                                             { 
    758                                                 if(Spirit->GetVisibility() == VISIBILITY_OFF) 
    759                                                     Spirit->SetVisibility(VISIBILITY_ON); 
    760                                             } 
    761                                         } 
    762                                     } 
    763                                 } 
    764                                 if(ChannelCount < 3) 
    765                                     ChannelCount++; 
    766                                 ChannelTimer = 10000; 
    767                             } 
    768                             break; 
    769                         } 
    770                 } 
    771             }else ChannelTimer -= diff; 
    772         } 
    773  
    774         if(FightMinions) 
    775         { 
    776             if(SummonMinionTimer < diff) 
    777             { 
    778                 if(IllidanGUID) 
    779                 { 
    780                     Creature* Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID)); 
    781                     if(!Illidan || Illidan->IsInEvadeMode()) 
    782                     { 
    783                         Reset(); 
    784                         EnterEvadeMode(); 
    785                         return; 
    786                     } 
    787                 } 
    788  
    789                 float x,y,z; 
    790                 m_creature->GetPosition(x,y,z); 
    791                 Creature* Elite = m_creature->SummonCreature(ILLIDARI_ELITE, x+rand()%10, y+rand()%10, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000); 
    792                 if(Elite) 
    793                 { 
    794                     Elite->AI()->AttackStart(m_creature); 
    795                     Elite->AddThreat(m_creature, 1000000.0f); 
    796                     AttackStart(Elite); 
    797                 } 
    798                 SummonMinionTimer = 10000 + rand()%6000; 
    799             }else SummonMinionTimer -= diff; 
    800         } 
    801  
    802         // If we don't have a target, or is talking, or has run away, return 
    803         if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return; 
    804  
    805         DoMeleeAttackIfReady(); 
    806     } 
    807 }; 
    808  
    809 /************* Custom check used for Agonizing Flames ***************/ 
    810 class AgonizingFlamesTargetCheck 
    811 { 
    812     public: 
    813         AgonizingFlamesTargetCheck(Unit const* unit) : pUnit(unit) {} 
    814         bool operator() (Player* plr) 
    815         { 
    816             // Faster than square rooting 
    817             if(!plr->isGameMaster() && pUnit->GetDistance2d(plr) > 225) 
    818                 return true; 
    819  
    820             return false; 
    821         } 
    822  
    823     private: 
    824         Unit const* pUnit; 
    825 }; 
    826  
    827 /************************************** Illidan's AI ***************************************/ 
    828 struct TRINITY_DLL_SPEC boss_illidan_stormrageAI : public ScriptedAI 
    829 { 
    830     boss_illidan_stormrageAI(Creature* c) : ScriptedAI(c) 
    831     { 
    832         pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
    833         Reset(); 
    834     } 
    835  
    836     /** Instance Data **/ 
    837     ScriptedInstance* pInstance; 
    838  
    839     /** Generic **/ 
    840     bool IsTalking; 
    841     bool HasSummoned; 
    842     bool RefaceVictim; 
    843     bool InformAkama; 
    844     uint32 Phase; 
    845     uint32 GlobalTimer; 
    846     uint32 TalkCount; 
    847     uint32 DemonFormSequence; 
    848  
    849     /** GUIDs **/ 
    850     uint64 FlameGUID[2]; 
    851     uint64 GlaiveGUID[2]; 
    852     uint64 AkamaGUID; 
    853     uint64 MaievGUID; 
    854  
    855     /** Timers **/ 
    856     uint32 ShearTimer; 
    857     uint32 DrawSoulTimer; 
    858     uint32 FlameCrashTimer; 
    859     uint32 ParasiticShadowFiendTimer; 
    860     uint32 FireballTimer; 
    861     uint32 EyeBlastTimer; 
    862     uint32 DarkBarrageTimer; 
    863     uint32 SummonBladesTimer;                               // Animate summoning the Blades of Azzinoth in Phase 2 
    864     uint32 SummonFlamesTimer;                               // Summon Flames of Azzinoth in Phase 2 
    865     uint32 CheckFlamesTimer;                                // This is used to check the status of the Flames to see if we should begin entering Phase 3 or not. 
    866     uint32 RetrieveBladesTimer;                             // Animate retrieving the Blades of Azzinoth in Phase 2 -> 3 transition 
    867     uint32 LandTimer;                                       // This is used at the end of phase 2 to signal Illidan landing after Flames are dead 
    868     uint32 AgonizingFlamesTimer; 
    869     uint32 ShadowBlastTimer; 
    870     uint32 FlameBurstTimer; 
    871     uint32 ShadowDemonTimer; 
    872     uint32 TalkTimer; 
    873     uint32 TransformTimer; 
    874     uint32 EnrageTimer; 
    875     uint32 CageTimer; 
    876     uint32 LayTrapTimer; 
    877     uint32 AnimationTimer; 
    878     uint32 TauntTimer;                                      // This is used for his random yells 
    879     uint32 FaceVictimTimer; 
    880     uint32 BerserkTimer; 
    881  
    882     void Reset() 
    883     { 
    884         Phase = PHASE_NORMAL; 
    885  
    886         // Check if any flames/glaives are alive/existing. Kill if alive and set GUIDs to 0 
    887         for(uint8 i = 0; i < 2; i++) 
    888         { 
    889             if(FlameGUID[i]) 
    890             { 
    891                 Unit* Flame = Unit::GetUnit((*m_creature), FlameGUID[i]); 
    892                 if(Flame) 
    893                     Flame->setDeathState(JUST_DIED); 
    894                 FlameGUID[i] = 0; 
    895             } 
    896  
    897             if(GlaiveGUID[i]) 
    898             { 
    899                 Unit* Glaive = Unit::GetUnit((*m_creature), GlaiveGUID[i]); 
    900                 if(Glaive) 
    901                     Glaive->setDeathState(JUST_DIED); 
    902                 GlaiveGUID[i] = 0; 
    903             } 
    904         } 
    905  
    906         if(AkamaGUID) 
    907         { 
    908             Creature* Akama = ((Creature*)Unit::GetUnit((*m_creature), AkamaGUID)); 
    909             if(Akama) 
    910             { 
    911                 if(!Akama->isAlive()) 
    912                     Akama->Respawn(); 
    913                 ((npc_akama_illidanAI*)Akama->AI())->Reset(); 
    914                 ((npc_akama_illidanAI*)Akama->AI())->EnterEvadeMode(); 
    915                 Akama->GetMotionMaster()->MoveTargetedHome(); 
    916             } 
    917         } 
    918  
    919         InformAkama = false; 
    920         RefaceVictim = false; 
    921         HasSummoned = false; 
    922         AkamaGUID = 0; 
    923         MaievGUID = 0; 
    924  
    925         FaceVictimTimer = 1000; 
    926         BerserkTimer = 1500000; 
    927         GlobalTimer = 0; 
    928         DemonFormSequence = 0; 
    929  
    930         /** Normal Form **/ 
    931         ShearTimer = 20000 + (rand()%11 * 1000);            // 20 to 30 seconds 
    932         FlameCrashTimer = 30000;                            //30 seconds 
    933         ParasiticShadowFiendTimer = 25000;                  // 25 seconds 
    934         DrawSoulTimer = 50000;                              // 50 seconds 
    935  
    936         /** Phase 2 **/ 
    937         SummonBladesTimer = 10000; 
    938         SummonFlamesTimer = 20000;                          // Phase 2 timers may be incorrect 
    939         FireballTimer = 5000; 
    940         DarkBarrageTimer = 45000; 
    941         EyeBlastTimer = 30000; 
    942         CheckFlamesTimer = 5000; 
    943         RetrieveBladesTimer = 5000; 
    944         LandTimer = 0; 
    945  
    946         /** Phase 3+ **/ 
    947         AgonizingFlamesTimer = 35000;                       // Phase 3+ timers may be incorrect 
    948         ShadowBlastTimer = 3000; 
    949         FlameBurstTimer = 10000; 
    950         ShadowDemonTimer = 30000; 
    951         TransformTimer = 90000; 
    952         EnrageTimer = 40000; 
    953         CageTimer = 30000; 
    954         LayTrapTimer = CageTimer + 2000; 
    955         AnimationTimer = 0; 
    956  
    957         TauntTimer = 30000;                                 // This timer may be off. 
    958  
    959         m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 21135); 
    960         m_creature->InterruptNonMeleeSpells(false); 
    961         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    962         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    963                                                             // Unequip warglaives if needed 
    964         m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); 
    965         m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); 
    966         m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); 
    967  
    968         IsTalking = false; 
    969  
    970         TalkCount = 0; 
    971         TalkTimer = 0; 
    972  
    973         if(pInstance) 
    974             pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, NOT_STARTED); 
    975     } 
    976  
    977     void Aggro(Unit *who) { DoZoneInCombat(); } 
    978  
    979     void AttackStart(Unit *who) 
    980     { 
    981         if(!who || IsTalking || Phase == 2 || Phase == 4 || Phase == 6 || m_creature->HasAura(SPELL_KNEEL, 0)) 
    982             return; 
    983  
    984         if (who->isTargetableForAttack() && who!= m_creature) 
    985         { 
    986             //Begin melee attack if we are within range 
    987             DoStartAttackAndMovement(who); 
    988         } 
    989     } 
    990  
    991     void MoveInLineOfSight(Unit *who) 
    992     { 
    993         if (!who || m_creature->getVictim() || IsTalking || m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) 
    994             return; 
    995  
    996         if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) 
    997         { 
    998             if (!m_creature->canFly() && m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) 
    999                 return; 
    1000  
    1001             float attackRadius = m_creature->GetAttackDistance(who); 
    1002             if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who)) 
    1003             { 
    1004                 if(who->HasStealthAura()) 
    1005                     who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); 
    1006  
    1007                 DoStartAttackAndMovement(who); 
    1008             } 
    1009         } 
    1010     } 
    1011  
    1012     void JustDied(Unit *killer) 
    1013     { 
    1014         IsTalking = false; 
    1015         TalkCount = 0; 
    1016         TalkTimer = 0; 
    1017  
    1018         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    1019  
    1020         if(!pInstance) 
    1021             return; 
    1022                                                             // Completed 
    1023         pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, DONE); 
    1024  
    1025         for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L + 1; ++i) 
    1026         { 
    1027             GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i)); 
    1028             if(Door) 
    1029                 Door->SetGoState(0);                        // Open Doors 
    1030         } 
    1031  
    1032     } 
    1033  
    1034     void KilledUnit(Unit *victim) 
    1035     { 
    1036         if(victim == m_creature) return; 
    1037  
    1038         switch(rand()%2) 
    1039         { 
    1040             case 0: 
    1041                 DoYell(SAY_KILL1, LANG_UNIVERSAL, victim); 
    1042                 DoPlaySoundToSet(m_creature, SOUND_KILL1); 
    1043                 break; 
    1044             case 1: 
    1045                 DoYell(SAY_KILL2, LANG_UNIVERSAL, victim); 
    1046                 DoPlaySoundToSet(m_creature, SOUND_KILL2); 
    1047                 break; 
    1048         } 
    1049     } 
    1050  
    1051     void DamageTaken(Unit *done_by, uint32 &damage) 
    1052     { 
    1053         if(damage > m_creature->GetHealth())                // Don't let ourselves be slain before we do our death speech 
    1054         { 
    1055             damage = 0; 
    1056             m_creature->SetHealth(m_creature->GetMaxHealth()/100); 
    1057         } 
    1058     } 
    1059  
    1060     void Cast(Unit* victim, uint32 Spell, bool triggered = false) 
    1061     { 
    1062         if(!victim) 
    1063             return; 
    1064  
    1065         RefaceVictim = true; 
    1066         m_creature->SetUInt64Value(UNIT_FIELD_TARGET, victim->GetGUID()); 
    1067         m_creature->CastSpell(victim, Spell, triggered); 
    1068     } 
    1069  
    1070     /** This will handle the cast of eye blast **/ 
    1071     void CastEyeBlast() 
    1072     { 
    1073         m_creature->InterruptNonMeleeSpells(false); 
    1074  
    1075         DarkBarrageTimer += 10000; 
    1076  
    1077         DoYell(SAY_EYE_BLAST, LANG_UNIVERSAL, NULL); 
    1078         DoPlaySoundToSet(m_creature, SOUND_EYE_BLAST); 
    1079  
    1080         uint32 initial = rand()%4; 
    1081         uint32 final = 0; 
    1082         if(initial < 3) 
    1083             final = initial+1; 
    1084  
    1085         float initial_X = EyeBlast[initial].x; 
    1086         float initial_Y = EyeBlast[initial].y; 
    1087         float initial_Z = EyeBlast[initial].z; 
    1088  
    1089         float final_X = EyeBlast[final].x; 
    1090         float final_Y = EyeBlast[final].y; 
    1091         float final_Z = EyeBlast[final].z; 
    1092  
    1093         for(uint8 i = 0; i < 2; ++i) 
    1094         { 
    1095             Creature* Trigger = NULL; 
    1096             Trigger = m_creature->SummonCreature(DEMON_FIRE, initial_X, initial_Y, initial_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 20000); 
    1097             if(Trigger) 
    1098             { 
    1099                 ((demonfireAI*)Trigger->AI())->IsTrigger = true; 
    1100                 Trigger->GetMotionMaster()->MovePoint(0, final_X, final_Y, final_Z); 
    1101  
    1102                 if(!i) 
    1103                     Trigger->CastSpell(Trigger, SPELL_EYE_BLAST_TRIGGER, true); 
    1104                 else 
    1105                 { 
    1106                     Trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    1107                     m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Trigger->GetGUID()); 
    1108                     DoCast(Trigger, SPELL_EYE_BLAST); 
    1109                 } 
    1110             } 
    1111         } 
    1112     } 
    1113  
    1114     // It's only cast on players that are greater than 15 yards away from Illidan. If no one is found, cast it on MT instead (since selecting someone in that 15 yard radius would cause the flames to hit the MT anyway). 
    1115     void CastAgonizingFlames() 
    1116     { 
    1117         // We'll use grid searching for this, using a custom searcher that selects a player that is at a distance >15 yards 
    1118         Player* target = NULL; 
    1119  
    1120         CellPair pair(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); 
    1121         Cell cell(pair); 
    1122         cell.data.Part.reserved = ALL_DISTRICT; 
    1123         cell.SetNoCreate(); 
    1124  
    1125         AgonizingFlamesTargetCheck check(m_creature); 
    1126         Trinity::PlayerSearcher<AgonizingFlamesTargetCheck> searcher(target, check); 
    1127         TypeContainerVisitor 
    1128             <Trinity::PlayerSearcher<AgonizingFlamesTargetCheck>, GridTypeMapContainer> visitor(searcher); 
    1129  
    1130         CellLock<GridReadGuard> cell_lock(cell, pair); 
    1131         cell_lock->Visit(cell_lock, visitor, *(m_creature->GetMap())); 
    1132  
    1133         if(target) 
    1134             DoCast(target, SPELL_AGONIZING_FLAMES); 
    1135         else 
    1136             DoCast(m_creature->getVictim(), SPELL_AGONIZING_FLAMES); 
    1137     } 
    1138  
    1139     void Talk(uint32 count) 
    1140     { 
    1141         if(!m_creature->isAlive()) return; 
    1142         uint32 sound = Conversation[count].sound; 
    1143         char* text = NULL; 
    1144         if(Conversation[count].text) 
    1145             text = Conversation[count].text; 
    1146         TalkTimer = Conversation[count].timer; 
    1147         uint32 emote = Conversation[count].emote; 
    1148         IsTalking = Conversation[count].Talk; 
    1149         Creature* creature = NULL; 
    1150         uint64 GUID = 0; 
    1151         if(Conversation[count].creature == ILLIDAN_STORMRAGE) 
    1152             creature = m_creature; 
    1153         else if(Conversation[count].creature == AKAMA) 
    1154         { 
    1155             if(!AkamaGUID) 
    1156             { 
    1157                 if(pInstance) 
    1158                 { 
    1159                     AkamaGUID = pInstance->GetData64(DATA_AKAMA); 
    1160                     if(!AkamaGUID) 
    1161                         return; 
    1162                     GUID = AkamaGUID; 
    1163                 } 
    1164             } 
    1165             else GUID = AkamaGUID; 
    1166         } 
    1167         else if(Conversation[count].creature == MAIEV_SHADOWSONG) 
    1168         { 
    1169             if(!MaievGUID) 
    1170                 return; 
    1171             GUID = MaievGUID; 
    1172         } 
    1173         else if(Conversation[count].creature == EMPTY)      // This is just for special cases without speech/sounds/emotes. 
    1174             return; 
    1175  
    1176         if(GUID)                                            // Now we check if we actually specified a GUID, if so: 
    1177                                                             // we grab a pointer to that creature 
    1178             creature = ((Creature*)Unit::GetUnit((*m_creature), GUID)); 
    1179  
    1180         if(creature) 
    1181         { 
    1182             creature->HandleEmoteCommand(emote);            // Make the creature do some animation! 
    1183             if(text) 
    1184                 creature->Yell(text, LANG_UNIVERSAL, 0);    // Have the creature yell out some text 
    1185             if(sound) 
    1186                 DoPlaySoundToSet(creature, sound);          // Play some sound on the creature 
    1187         } 
    1188     } 
    1189  
    1190     void Move(float X, float Y, float Z, Creature* _Creature) 
    1191     { 
    1192         _Creature->GetMotionMaster()->MovePoint(0, X, Y, Z); 
    1193     } 
    1194  
    1195     void HandleDemonTransformAnimation(uint32 count) 
    1196     { 
    1197         uint32 unaura = DemonTransformation[count].unaura; 
    1198         uint32 aura = DemonTransformation[count].aura; 
    1199         uint32 displayid = DemonTransformation[count].displayid; 
    1200         AnimationTimer = DemonTransformation[count].timer; 
    1201         uint32 size = DemonTransformation[count].size; 
    1202  
    1203         m_creature->InterruptNonMeleeSpells(false); 
    1204  
    1205         if(DemonTransformation[count].phase != 8) 
    1206         { 
    1207             m_creature->GetMotionMaster()->Clear(); 
    1208             m_creature->GetMotionMaster()->MoveIdle(); 
    1209         } 
    1210  
    1211         if(unaura) 
    1212             m_creature->RemoveAurasDueToSpell(unaura); 
    1213  
    1214         if(aura) 
    1215             DoCast(m_creature, aura, true); 
    1216  
    1217         if(displayid) 
    1218                                                             // It's morphin time! 
    1219             m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, displayid); 
    1220         /*if(size) 
    1221             m_creature->SetUInt32Value(OBJECT_FIELD_SCALE_X, size); // Let us grow! (or shrink)*/ 
    1222  
    1223         if(DemonTransformation[count].equip) 
    1224         { 
    1225                                                             // Requip warglaives if needed 
    1226             m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); 
    1227             m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); 
    1228         } 
    1229         else 
    1230         { 
    1231                                                             // Unequip warglaives if needed 
    1232             m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); 
    1233             m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); 
    1234         } 
    1235  
    1236         if(DemonTransformation[count].phase != 8) 
    1237             Phase = DemonTransformation[count].phase;       // Set phase properly 
    1238         else 
    1239         { 
    1240                                                             // Refollow and attack our old victim 
    1241             m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); 
    1242             if(MaievGUID) Phase = PHASE_NORMAL_MAIEV;       // Depending on whether we summoned Maiev, we switch to either phase 5 or 3 
    1243             else Phase = PHASE_NORMAL_2; 
    1244         } 
    1245  
    1246         if(count == 7) 
    1247         { 
    1248             DoResetThreat(); 
    1249             m_creature->RemoveAurasDueToSpell( SPELL_DEMON_FORM ); 
    1250         } 
    1251         else if(count == 4) 
    1252         { 
    1253             DoResetThreat(); 
    1254             if(!m_creature->HasAura(SPELL_DEMON_FORM, 0)) 
    1255                 DoCast(m_creature, SPELL_DEMON_FORM, true); 
    1256         } 
    1257     } 
    1258  
    1259     /** To reduce the amount of code in UpdateAI, we can seperate them into different functions and simply call them from UpdateAI **/ 
    1260     void EnterPhase2() 
    1261     { 
    1262         DoYell(SAY_TAKEOFF, LANG_UNIVERSAL, NULL); 
    1263         DoPlaySoundToSet(m_creature, SOUND_TAKEOFF); 
    1264  
    1265         SummonBladesTimer = 10000;                          // Summon Glaives when this decrements 
    1266         SummonFlamesTimer = 20000;                          // Summon Flames when this decrements 
    1267         GlobalTimer += 20000; 
    1268         LandTimer = 0; 
    1269         Phase = PHASE_FLIGHT; 
    1270         m_creature->RemoveAllAuras(); 
    1271         m_creature->SetUInt64Value(UNIT_FIELD_TARGET, 0); 
    1272                                                             // So players don't shoot us down 
    1273         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1274                                                             // Animate our take off! 
    1275         m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); 
    1276                                                             // We now hover! 
    1277         m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); 
    1278         m_creature->GetMotionMaster()->MovePoint(0, CENTER_X, CENTER_Y, CENTER_Z); 
    1279         for(uint8 i = 0; i < 2; ++i) 
    1280         { 
    1281             Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    1282             if(Glaive) 
    1283             { 
    1284                 GlaiveGUID[i] = Glaive->GetGUID();          // We need this to remove them later on 
    1285                 Glaive->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1286                 Glaive->SetVisibility(VISIBILITY_OFF); 
    1287                 Glaive->setFaction(m_creature->getFaction()); 
    1288             } 
    1289         } 
    1290     } 
    1291  
    1292     void SummonBladesOfAzzinoth() 
    1293     { 
    1294         m_creature->GetMotionMaster()->Clear(false); 
    1295  
    1296         LandTimer = 0; 
    1297         RetrieveBladesTimer = 0; 
    1298  
    1299         DoCast(m_creature, SPELL_THROW_GLAIVE2);            // Make it look like we're throwing the glaives on the ground 
    1300                                                             // We no longer wear the glaives! 
    1301         m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); 
    1302                                                             // since they are now channeling the flames (or will be) 
    1303         m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); 
    1304         for(uint8 i = 0; i < 2; ++i) 
    1305         { 
    1306             Creature* Glaive = NULL; 
    1307             Glaive = ((Creature*)Unit::GetUnit((*m_creature), GlaiveGUID[i])); 
    1308             if(Glaive) 
    1309             { 
    1310                 DoCast(Glaive, SPELL_THROW_GLAIVE, true); 
    1311                 Glaive->SetVisibility(VISIBILITY_ON); 
    1312             } 
    1313         } 
    1314     } 
    1315  
    1316     void SummonFlamesOfAzzinoth() 
    1317     { 
    1318         DoYell(SAY_SUMMONFLAMES, LANG_UNIVERSAL, NULL); 
    1319         DoPlaySoundToSet(m_creature, SOUND_SUMMONFLAMES); 
    1320  
    1321         for(uint8 i = 0; i < 2; ++i) 
    1322         { 
    1323             Creature* Flame = NULL; 
    1324             Creature* Glaive = NULL; 
    1325             Glaive = ((Creature*)Unit::GetUnit((*m_creature), GlaiveGUID[i])); 
    1326             if(Glaive) 
    1327             { 
    1328                 Flame = m_creature->SummonCreature(FLAME_OF_AZZINOTH, GlaivePosition[i+2].x, GlaivePosition[i+2].y, GlaivePosition[i+2].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); 
    1329                 if(Flame) 
    1330                 { 
    1331                                                             // Just in case the database has it as a different faction 
    1332                     Flame->setFaction(m_creature->getFaction()); 
    1333                                                             // Attack our target! 
    1334                     Flame->AI()->AttackStart(m_creature->getVictim()); 
    1335                     FlameGUID[i] = Flame->GetGUID();        // Record GUID in order to check if they're dead later on to move to the next phase 
    1336                                                             // Glaives do some random Beam type channel on it. 
    1337                     Glaive->CastSpell(Flame, SPELL_AZZINOTH_CHANNEL, true); 
    1338                     if(m_creature->getVictim()) 
    1339                         Flame->AI()->AttackStart(m_creature->getVictim()); 
     1658                    BlinkToPlayer(); 
     1659                    DoCast(m_creature, SPELL_CAGE_TRAP_SUMMON); 
     1660                    Timer[EVENT_MAIEV_TRAP] = 22000; 
    13401661                } 
    13411662                else 
    13421663                { 
    1343                     DoTextEmote("is unable to summon a Flame of Azzinoth.", NULL); 
    1344                     error_log("SD2 ERROR: Illidan Stormrage AI: Unable to summon Flame of Azzinoth (entry: 22997), please check your database"); 
    1345                     EnterEvadeMode(); 
     1664                    if(!m_creature->IsWithinDistInMap(m_creature->getVictim(), 40)) 
     1665                        m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim(), 30); 
     1666                    DoCast(m_creature->getVictim(), SPELL_THROW_DAGGER); 
     1667                    Timer[EVENT_MAIEV_THROW_DAGGER] = 2000; 
    13461668                } 
    1347             } 
    1348             else 
    1349             { 
    1350                 DoTextEmote("is unable to summon a Blade of Azzinoth.", NULL); 
    1351                 error_log("SD2 ERROR: Illidan Stormrage AI: Unable to summon Blade of Azzinoth (entry: 22996), please check your database"); 
    1352             } 
    1353         } 
    1354         DoResetThreat();                                    // And now reset our threatlist 
    1355         HasSummoned = true; 
    1356     } 
    1357  
    1358     void SummonMaiev() 
    1359     { 
    1360         TauntTimer += 4000; 
    1361         GlobalTimer += 4000; 
    1362  
    1363         m_creature->InterruptNonMeleeSpells(false);         // Interrupt any of our spells 
    1364         Creature* Maiev = NULL;                             // Summon Maiev near Illidan 
    1365         Maiev = m_creature->SummonCreature(MAIEV_SHADOWSONG, m_creature->GetPositionX() + 10, m_creature->GetPositionY() + 5, m_creature->GetPositionZ()+2, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000); 
    1366         if(Maiev) 
    1367         { 
    1368             m_creature->GetMotionMaster()->Clear(false);    // Stop moving, it's rude to walk and talk! 
    1369             m_creature->GetMotionMaster()->MoveIdle(); 
    1370                                                             // Just in case someone is unaffected by Shadow Prison 
    1371             m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1372             DoCast(m_creature, SPELL_SHADOW_PRISON, true); 
    1373             TalkCount = 10; 
    1374             IsTalking = true;                               // We are now talking/ 
    1375             Maiev->SetVisibility(VISIBILITY_OFF);           // Leave her invisible until she has to talk 
    1376             Maiev->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1377             MaievGUID = Maiev->GetGUID(); 
    1378         } 
    1379         else                                                // If Maiev cannot be summoned, reset the encounter and post some errors to the console. 
    1380         { 
    1381             EnterEvadeMode(); 
    1382             DoTextEmote("is unable to summon Maiev Shadowsong and enter Phase 4. Resetting Encounter.", NULL); 
    1383             error_log("SD2 ERROR: Unable to summon Maiev Shadowsong (entry: 23197). Check your database to see if you have the proper SQL for Maiev Shadowsong (entry: 23197)"); 
    1384         } 
    1385     } 
    1386  
    1387     void InitializeDeath() 
    1388     { 
    1389         m_creature->RemoveAllAuras(); 
    1390         DoCast(m_creature, SPELL_DEATH);                    // Animate his kneeling + stun him 
    1391                                                             // Don't let the players interrupt our talk! 
    1392         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1393         m_creature->GetMotionMaster()->Clear(false);        // No moving! 
    1394         m_creature->GetMotionMaster()->MoveIdle(); 
    1395         if(MaievGUID) 
    1396         { 
    1397             Creature* Maiev = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID)); 
    1398             if(Maiev) 
    1399             { 
    1400                 Maiev->CombatStop();                        // Maiev shouldn't do anything either. No point in her attacking us =] 
    1401                 Maiev->GetMotionMaster()->Clear(false);     // Stop her from moving as well 
    1402                 Maiev->GetMotionMaster()->MoveIdle(); 
    1403                 float distance = 10.0f; 
    1404                 float dx = m_creature->GetPositionX() + (distance*cos(m_creature->GetOrientation())); 
    1405                 float dy = m_creature->GetPositionY() + (distance*sin(m_creature->GetOrientation())); 
    1406                 Maiev->Relocate(dx,dy,Maiev->GetPositionZ()); 
    1407                 Maiev->SendMonsterMove(dx,dy,Maiev->GetPositionZ(), 0, 0, 0); 
    1408                 Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); 
    1409                 Maiev->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); 
    1410             } 
    1411         } 
    1412         IsTalking = true; 
    1413         TalkCount++; 
    1414     } 
    1415  
    1416     void UpdateAI(const uint32 diff) 
    1417     { 
    1418         /*** This section will handle the conversations ***/ 
    1419         if(IsTalking)                                       // Somewhat more efficient using a function rather than a long switch 
    1420         { 
    1421             if(TalkTimer < diff) 
    1422             { 
    1423                 switch(TalkCount)                           // This is only for specialized cases 
    1424                 { 
    1425                     case 0: 
    1426                                                             // Time to stand up! 
    1427                         m_creature->RemoveAurasDueToSpell( SPELL_KNEEL ); 
    1428                         break; 
    1429                     case 8: 
    1430                                                             // Equip our warglaives! 
    1431                         m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); 
    1432                         m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); 
    1433                         m_creature->setFaction(14);         // Hostile if we weren't before 
    1434                         break; 
    1435                     case 9: 
    1436                         if(AkamaGUID) 
    1437                         { 
    1438                             Creature* Akama = ((Creature*)Unit::GetUnit((*m_creature), AkamaGUID)); 
    1439                             if(Akama) 
    1440                             { 
    1441                                 Akama->GetMotionMaster()->Clear(false); 
    1442                                                             // Akama runs to us! 
    1443                                 Akama->GetMotionMaster()->MoveChase(m_creature); 
    1444                                 m_creature->GetMotionMaster()->Clear(false); 
    1445                                                             // We run to Akama! 
    1446                                 m_creature->GetMotionMaster()->MoveChase(Akama); 
    1447                                 Akama->AddThreat(m_creature, 1000000.0f); 
    1448                                 AttackStart(Akama);         // Start attacking Akama 
    1449                                 ((npc_akama_illidanAI*)Akama->AI())->IsTalking = false; 
    1450                                                             // Akama starts attacking us 
    1451                                 ((npc_akama_illidanAI*)Akama->AI())->AttackStart(m_creature); 
    1452                             } 
    1453                         } 
    1454                                                             // We are now attackable! 
    1455                         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1456                         break; 
    1457                     case 11: 
    1458                         if(MaievGUID) 
    1459                         { 
    1460                             Unit* Maiev = Unit::GetUnit((*m_creature), MaievGUID); 
    1461                             if(Maiev) 
    1462                             { 
    1463                                                             // Maiev is now visible 
    1464                                 Maiev->SetVisibility(VISIBILITY_ON); 
    1465                                                             // onoz she looks like she teleported! 
    1466                                 Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); 
    1467                                                             // Have her face us 
    1468                                 Maiev->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); 
    1469                                                             // Face her, so it's not rude =P 
    1470                                 m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Maiev->GetGUID()); 
    1471                             } 
    1472                         } 
    1473                         break; 
    1474                     case 14: 
    1475                         if(MaievGUID) 
    1476                         { 
    1477                             Creature* Maiev = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID)); 
    1478                             if(Maiev) 
    1479                             { 
    1480                                 Maiev->GetMotionMaster()->Clear(false); 
    1481                                 Maiev->GetMotionMaster()->MoveChase(m_creature); 
    1482                                                             // Have Maiev add a lot of threat on us so that players don't pull her off if they damage her via AOE 
    1483                                 Maiev->AddThreat(m_creature, 10000000.0f); 
    1484                                                             // Force Maiev to attack us. 
    1485                                 Maiev->AI()->AttackStart(m_creature); 
    1486                                 Maiev->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    1487                             } 
    1488                         } 
    1489                         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1490                         m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); 
    1491                         IsTalking = false; 
    1492                         FaceVictimTimer = 2000; 
    1493                         RefaceVictim = true; 
    1494                         break; 
    1495                     case 20:                                // Kill ourself. 
    1496                         if(MaievGUID) 
    1497                         { 
    1498                             Creature* Maiev = ((Creature*)Unit::GetUnit((*m_creature), MaievGUID)); 
    1499                             if(Maiev)                       // Make Maiev leave 
    1500                             { 
    1501                                 Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); 
    1502                                 Maiev->setDeathState(JUST_DIED); 
    1503                             } 
    1504                         } 
    1505                         IsTalking = false; 
    1506                         if(m_creature->getVictim()) 
    1507                             m_creature->getVictim()->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE,SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    1508                         else 
    1509                                                             // Now we kill ourself 
    1510                             m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    1511                         break; 
    1512                 } 
    1513                 Talk(TalkCount);                            // This function does most of the talking 
    1514                 TalkCount++; 
    1515             }else TalkTimer -= diff; 
    1516         } 
    1517  
    1518         // If we don't have a target, return. 
    1519         if(!m_creature->SelectHostilTarget() || !m_creature->getVictim() || IsTalking) 
    1520             return; 
    1521  
    1522         // If we are 'caged', then we shouldn't do anything such as cast spells or transform into Demon Form. 
    1523         if(m_creature->HasAura(SPELL_CAGED, 0)) 
    1524         { 
    1525             EnrageTimer = 40000;                            // Just so that he doesn't immediately enrage after he stops being caged. 
    1526             CageTimer = 30000; 
    1527             return; 
    1528         } 
    1529  
    1530         // Berserk Timer - flat 25 minutes 
    1531         if(!m_creature->HasAura(SPELL_BERSERK, 0) && Phase != PHASE_DEMON_SEQUENCE) 
    1532             if(BerserkTimer < diff) 
    1533         { 
    1534             DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL); 
    1535             DoPlaySoundToSet(m_creature, SOUND_ENRAGE); 
    1536             DoCast(m_creature, SPELL_BERSERK, true); 
    1537         }else BerserkTimer -= diff; 
    1538  
    1539         if(RefaceVictim) 
    1540             if(FaceVictimTimer < diff) 
    1541         { 
    1542             m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->getVictim()->GetGUID()); 
    1543             FaceVictimTimer = 1000; 
    1544             RefaceVictim = false; 
    1545         }else FaceVictimTimer -= diff; 
    1546  
    1547         /** Signal to change to phase 2 **/ 
    1548         if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 65) && (Phase == PHASE_NORMAL)) 
    1549             EnterPhase2(); 
    1550  
    1551         /** Signal to summon Maiev **/ 
    1552         if(((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30) && !MaievGUID && 
    1553             ((Phase != PHASE_DEMON) || (Phase != PHASE_DEMON_SEQUENCE))) 
    1554             SummonMaiev(); 
    1555  
    1556         /** Time for the death speech **/ 
    1557         if((m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 1) && (!IsTalking) && 
    1558             ((Phase != PHASE_DEMON) || (Phase != PHASE_DEMON_SEQUENCE))) 
    1559             InitializeDeath(); 
    1560  
    1561         /***** Spells for Phase 1, 3 and 5 (Normal Form) ******/ 
    1562         if(Phase == PHASE_NORMAL || Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV) 
    1563         { 
    1564             if(TauntTimer < diff)                           // His random taunt/yell timer. 
    1565             { 
    1566                 uint32 random = rand()%4; 
    1567                 char* yell = RandomTaunts[random].text; 
    1568                 uint32 soundid = RandomTaunts[random].sound; 
    1569                 if(yell) 
    1570                     DoYell(yell, LANG_UNIVERSAL, NULL); 
    1571                 if(soundid) 
    1572                     DoPlaySoundToSet(m_creature, soundid); 
    1573                 TauntTimer = 32000; 
    1574             }else TauntTimer -= diff; 
    1575  
    1576             if(GlobalTimer < diff)                          // Global Timer so that spells do not overlap. 
    1577             { 
    1578                 if(ShearTimer < diff) 
    1579                 { 
    1580                     DoCast(m_creature->getVictim(), SPELL_SHEAR); 
    1581                     ShearTimer = 25000 + (rand()%16 * 1000); 
    1582                     GlobalTimer += 2000; 
    1583                 }else ShearTimer -= diff; 
    1584  
    1585                 if(FlameCrashTimer < diff) 
    1586                 { 
    1587                     // It spawns multiple flames sometimes. Therefore, we'll do this manually. 
    1588                     //DoCast(m_creature->getVictim(), SPELL_FLAME_CRASH); 
    1589                     DoSpawnCreature(FLAME_CRASH, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 40000); 
    1590                     FlameCrashTimer = 35000; 
    1591                     GlobalTimer += 2000; 
    1592                 }else FlameCrashTimer -= diff; 
    1593  
    1594                 if(ParasiticShadowFiendTimer < diff) 
    1595                 { 
    1596                     Unit* target = NULL; 
    1597                     target = SelectUnit(SELECT_TARGET_RANDOM,1); 
    1598                     if(target && target->isAlive() && !target->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)) 
    1599                     { 
    1600                         Cast(target, SPELL_PARASITIC_SHADOWFIEND); 
    1601                         ParasiticShadowFiendTimer = 40000; 
    1602                     } 
    1603                 }else ParasiticShadowFiendTimer -= diff; 
    1604  
    1605                 if(DrawSoulTimer < diff) 
    1606                 { 
    1607                     DoCast(m_creature->getVictim(), SPELL_DRAW_SOUL); 
    1608                     DrawSoulTimer = 55000; 
    1609                     GlobalTimer += 3000; 
    1610                 }else DrawSoulTimer -= diff; 
    1611             }else GlobalTimer -= diff; 
    1612  
    1613             if(!IsTalking) 
     1669                break; 
     1670            default: 
     1671                break; 
     1672            } 
     1673 
     1674            if(m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 50) 
     1675            { 
     1676                m_creature->SetVisibility(VISIBILITY_OFF); 
     1677                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
     1678                if(GETCRE(Illidan, IllidanGUID)) 
     1679                    ((boss_illidan_stormrageAI*)Illidan->AI())->DeleteFromThreatList(m_creature->GetGUID()); 
     1680                m_creature->AttackStop(); 
     1681                Timer[EVENT_MAIEV_STEALTH] = 60000; //reappear after 1 minute 
     1682                MaxTimer = 1; 
     1683            } 
     1684 
     1685            if(Phase == PHASE_NORMAL_MAIEV) 
    16141686                DoMeleeAttackIfReady(); 
    1615         } 
    1616  
    1617         /*** Phase 2 ***/ 
    1618         if(Phase == PHASE_FLIGHT) 
    1619         { 
    1620             // Check if we have summoned or not. 
    1621             if(!HasSummoned) 
    1622             { 
    1623                 if(SummonBladesTimer) 
    1624                     if(SummonBladesTimer <= diff) 
    1625                 { 
    1626                     SummonBladesOfAzzinoth(); 
    1627                     SummonBladesTimer = 0; 
    1628                 }else SummonBladesTimer -= diff; 
    1629  
    1630                 if(SummonFlamesTimer < diff) 
    1631                 { 
    1632                     SummonFlamesOfAzzinoth(); 
    1633                 }else SummonFlamesTimer -= diff; 
    1634             } 
    1635  
    1636             if(!m_creature->GetMotionMaster()->empty() && (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)) 
    1637                 m_creature->GetMotionMaster()->Clear(false); 
    1638  
    1639             if(HasSummoned) 
    1640             { 
    1641                 if(CheckFlamesTimer) 
    1642                     if(CheckFlamesTimer <= diff) 
    1643                 { 
    1644                     // Check if flames are dead or non-existant. If so, set GUID to 0. 
    1645                     for(uint8 i = 0; i < 2; i++) 
    1646                     { 
    1647                         if(FlameGUID[i]) 
    1648                         { 
    1649                             Unit* Flame = NULL; 
    1650                             Flame = Unit::GetUnit((*m_creature), FlameGUID[i]); 
    1651  
    1652                             // If the flame dies, or somehow the pointer becomes invalid, reset GUID to 0. 
    1653                             if(!Flame || !Flame->isAlive()) 
    1654                                 FlameGUID[i] = 0; 
    1655                         } 
    1656                     } 
    1657                     CheckFlamesTimer = 500; 
    1658                 }else CheckFlamesTimer -= diff; 
    1659  
    1660                 // If both flames are dead/non-existant, kill glaives and change to phase 3. 
    1661                 if(!FlameGUID[0] && !FlameGUID[1] && CheckFlamesTimer) 
    1662                 { 
    1663                     RetrieveBladesTimer = 5000;             // Prepare for re-equipin! 
    1664                     CheckFlamesTimer = 0; 
    1665                 } 
    1666  
    1667                 if(RetrieveBladesTimer) 
    1668                     if(RetrieveBladesTimer <= diff)         // Time to get back our glaives! 
    1669                 { 
    1670                                                             // Interrupt any spells we might be doing *cough* DArk Barrage *cough* 
    1671                     m_creature->InterruptNonMeleeSpells(false); 
    1672                     for(uint8 i = 0; i < 2; i++) 
    1673                     { 
    1674                         if(GlaiveGUID[i]) 
    1675                         { 
    1676                             Unit* Glaive = NULL; 
    1677                             Glaive = Unit::GetUnit((*m_creature), GlaiveGUID[i]); 
    1678                             if(Glaive) 
    1679                             { 
    1680                                                             // Make it look like the Glaive flies back up to us 
    1681                                 Glaive->CastSpell(m_creature, SPELL_GLAIVE_RETURNS, true); 
    1682                                                             // Despawn the Glaive 
    1683                                 Glaive->setDeathState(JUST_DIED); 
    1684                             } 
    1685                             GlaiveGUID[i] = 0; 
    1686                         } 
    1687                     } 
    1688                                                             // Re-equip our warblades! 
    1689                     m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); 
    1690                     m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); 
    1691                     LandTimer = 5000;                       // Prepare for landin'! 
    1692                     RetrieveBladesTimer = 0; 
    1693                 }else RetrieveBladesTimer -= diff; 
    1694  
    1695                 if(LandTimer) 
    1696                 { 
    1697                     if(LandTimer <= diff)                   // Time to land! 
    1698                     { 
    1699                         DoResetThreat(); 
    1700                                                             // anndddd touchdown! 
    1701                         m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); 
    1702                         m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT + MOVEMENTFLAG_LEVITATING); 
    1703                         Phase = PHASE_NORMAL_2; 
    1704                                                             // We should let the raid fight us =) 
    1705                         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1706                         m_creature->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->getVictim()->GetGUID()); 
    1707                                                             // Chase our victim! 
    1708                         m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); 
    1709                     }else LandTimer -= diff; 
    1710                     return;                                 // Do not continue past this point if LandTimer is not 0 and we are in phase 2. 
    1711                 } 
    1712             } 
    1713  
    1714             if(GlobalTimer < diff) 
    1715             { 
    1716                 if(FireballTimer < diff) 
    1717                 { 
    1718                     Cast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FIREBALL); 
    1719                     FireballTimer = 5000; 
    1720                 }else FireballTimer -= diff; 
    1721  
    1722                 if(DarkBarrageTimer < diff) 
    1723                 { 
    1724                     m_creature->InterruptNonMeleeSpells(false); 
    1725                     DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DARK_BARRAGE); 
    1726                     DarkBarrageTimer = 35000; 
    1727                     GlobalTimer += 9000; 
    1728                 }else DarkBarrageTimer -= diff; 
    1729  
    1730                 if(EyeBlastTimer < diff) 
    1731                 { 
    1732                     CastEyeBlast(); 
    1733                     EyeBlastTimer = 30000; 
    1734                 }else EyeBlastTimer -= diff; 
    1735             }else GlobalTimer -= diff; 
    1736         } 
    1737  
    1738         /** Phase 3,5 spells only**/ 
    1739         if(Phase == PHASE_NORMAL_2 || Phase == PHASE_NORMAL_MAIEV) 
    1740         { 
    1741             if(GlobalTimer < diff) 
    1742             { 
    1743                 if(AgonizingFlamesTimer < diff) 
    1744                 { 
    1745                     CastAgonizingFlames(); 
    1746                     AgonizingFlamesTimer = 60000; 
    1747                 }else AgonizingFlamesTimer -= diff; 
    1748             }else GlobalTimer -= diff; 
    1749  
    1750             if(TransformTimer < diff) 
    1751             { 
    1752                 uint32 CurHealth = m_creature->GetHealth()*100 / m_creature->GetMaxHealth(); 
    1753                 // Prevent Illidan from morphing if less than 32% or 5%, as this may cause issues with the phase transition or death speech 
    1754                 if((CurHealth < 32 && !MaievGUID) || (CurHealth < 5)) 
    1755                     return; 
    1756  
    1757                 Phase = PHASE_DEMON_SEQUENCE;               // Transform sequence 
    1758                 DemonFormSequence = 0; 
    1759                 AnimationTimer = 0; 
    1760                 DoYell(SAY_MORPH, LANG_UNIVERSAL, NULL); 
    1761                 DoPlaySoundToSet(m_creature, SOUND_MORPH); 
    1762                 TransformTimer = 60000; 
    1763                 FlameBurstTimer = 10000; 
    1764                 ShadowDemonTimer = 30000; 
    1765                 m_creature->GetMotionMaster()->Clear(false);// Stop moving 
    1766             }else TransformTimer -= diff; 
    1767         } 
    1768  
    1769         /** Phase 4 spells only (Demon Form) **/ 
    1770         if(Phase == PHASE_DEMON) 
    1771         { 
    1772             // Stop moving if we are by clearing movement generators. 
    1773             if(!m_creature->GetMotionMaster()->empty()) 
    1774                 m_creature->GetMotionMaster()->Clear(false); 
    1775  
    1776             if(TransformTimer < diff) 
    1777             { 
    1778                 Phase = PHASE_DEMON_SEQUENCE; 
    1779                 DemonFormSequence = 5; 
    1780                 AnimationTimer = 100; 
    1781                 TransformTimer = 60000; 
    1782             }else TransformTimer -= diff; 
    1783  
    1784             if(ShadowDemonTimer < diff) 
    1785             { 
    1786                 m_creature->InterruptNonMeleeSpells(false); 
    1787                 Creature* ShadowDemon = NULL; 
    1788                 for(uint8 i = 0; i < 4; i++) 
    1789                 { 
    1790                     Unit* target = NULL; 
    1791                     target = SelectUnit(SELECT_TARGET_RANDOM,0); 
    1792                                                             // only on players. 
    1793                     if(target && target->GetTypeId() == TYPEID_PLAYER) 
    1794                     { 
    1795                         ShadowDemon = DoSpawnCreature(SHADOW_DEMON, 0,0,0,0,TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN,25000); 
    1796                         if(ShadowDemon) 
    1797                         { 
    1798                             ShadowDemon->AddThreat(target, 5000000.0f); 
    1799                             ShadowDemon->AI()->AttackStart(target); 
    1800                             DoZoneInCombat(ShadowDemon); 
    1801                         } 
    1802                     } 
    1803                 } 
    1804                 ShadowDemonTimer = 60000; 
    1805             }else ShadowDemonTimer -= diff; 
    1806  
    1807             if(GlobalTimer < diff) 
    1808             { 
    1809                 if(ShadowBlastTimer < diff) 
    1810                 { 
    1811                     Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0); 
    1812                     if(target && target->isAlive()) 
    1813                     { 
    1814                         m_creature->SetUInt64Value(UNIT_FIELD_TARGET, target->GetGUID()); 
    1815                         DoCast(target, SPELL_SHADOW_BLAST); 
    1816                         ShadowBlastTimer = 4000; 
    1817                         GlobalTimer += 1500; 
    1818                     } 
    1819                     if(!m_creature->HasAura(SPELL_DEMON_FORM, 0)) 
    1820                         DoCast(m_creature, SPELL_DEMON_FORM, true); 
    1821                 }else ShadowBlastTimer -= diff; 
    1822  
    1823                 if(FlameBurstTimer < diff) 
    1824                 { 
    1825                     DoCast(m_creature, SPELL_FLAME_BURST); 
    1826                     FlameBurstTimer = 15000; 
    1827                 }else FlameBurstTimer -= diff; 
    1828             }else GlobalTimer -= diff; 
    1829         } 
    1830  
    1831         /** Phase 5 timers. Enrage spell **/ 
    1832         if(Phase == PHASE_NORMAL_MAIEV) 
    1833         { 
    1834             if(EnrageTimer < diff) 
    1835             { 
    1836                 DoCast(m_creature, SPELL_ENRAGE); 
    1837                 EnrageTimer = 40000; 
    1838                 CageTimer = 30000; 
    1839                 TransformTimer += 10000; 
    1840             }else EnrageTimer -= diff; 
    1841  
    1842             // We'll handle Cage Trap in Illidan's script for simplicity's sake 
    1843             if(CageTimer < diff) 
    1844             { 
    1845                 if(MaievGUID) 
    1846                 { 
    1847                     Unit* Maiev = Unit::GetUnit((*m_creature), MaievGUID); 
    1848                     Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
    1849                     if(!Maiev || !target || (target->GetTypeId() != TYPEID_PLAYER)) 
    1850                         return; 
    1851                     float X, Y, Z; 
    1852                     target->GetPosition(X, Y, Z); 
    1853                     Maiev->Relocate(X, Y, Z, Maiev->GetOrientation()); 
    1854                                                             // Make it look like she 'teleported' 
    1855                     Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); 
    1856                                                             // summon the trap! 
    1857                     Maiev->CastSpell(Maiev, SPELL_CAGE_TRAP_SUMMON, false); 
    1858                 } 
    1859                 CageTimer = 15000; 
    1860             }else CageTimer -= diff; 
    1861         } 
    1862  
    1863         if(Phase == PHASE_DEMON_SEQUENCE)                   // Demonic Transformation 
    1864         { 
    1865             if(AnimationTimer < diff) 
    1866             { 
    1867                 HandleDemonTransformAnimation(DemonFormSequence); 
    1868                 DemonFormSequence++; 
    1869             }else AnimationTimer -= diff; 
    1870         } 
    1871     } 
    1872 }; 
    1873  
    1874 /*********************** End of Illidan AI ******************************************/ 
    1875  
    1876 void npc_akama_illidanAI::BeginEvent(uint64 PlayerGUID) 
    1877 { 
    1878     debug_log("SD2: Akama - Illidan Introduction started. Illidan event properly begun."); 
    1879     if(pInstance) 
    1880     { 
    1881         IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE); 
    1882         pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, IN_PROGRESS); 
    1883     } 
    1884  
    1885     if(pInstance) 
    1886         for(uint8 i = DATA_GAMEOBJECT_ILLIDAN_DOOR_R; i < DATA_GAMEOBJECT_ILLIDAN_DOOR_L+1; ++i) 
    1887     { 
    1888         GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i)); 
    1889         if(Door) 
    1890             Door->SetGoState(1); 
    1891     } 
    1892  
    1893     if(IllidanGUID) 
    1894     { 
    1895         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1896         Creature* Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID)); 
    1897         if(Illidan) 
    1898         { 
    1899             Illidan->RemoveAurasDueToSpell(SPELL_KNEEL);    // Time for Illidan to stand up. 
    1900                                                             // First line of Akama-Illidan convo 
    1901             ((boss_illidan_stormrageAI*)Illidan->AI())->TalkCount = 0; 
    1902                                                             // Begin Talking 
    1903             ((boss_illidan_stormrageAI*)Illidan->AI())->IsTalking = true; 
    1904             ((boss_illidan_stormrageAI*)Illidan->AI())->AkamaGUID = m_creature->GetGUID(); 
    1905             m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Illidan->GetGUID()); 
    1906             Illidan->SetUInt64Value(UNIT_FIELD_TARGET, m_creature->GetGUID()); 
    1907             IsTalking = true;                               // Prevent Akama from starting to attack him 
    1908                                                             // Prevent players from talking again 
    1909             m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); 
    1910             m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    1911             Illidan->GetMotionMaster()->Clear(false); 
    1912             Illidan->GetMotionMaster()->MoveIdle(); 
    1913             m_creature->GetMotionMaster()->Clear(false); 
    1914             m_creature->GetMotionMaster()->MoveIdle(); 
    1915  
    1916             if(PlayerGUID) 
    1917             { 
    1918                 Unit* player = Unit::GetUnit((*m_creature), PlayerGUID); 
    1919                 if(player) 
    1920                     Illidan->AddThreat(player, 100.0f); 
    1921             } 
    1922         } 
    1923     } 
    1924 } 
     1687    } 
     1688}; 
     1689 
    19251690 
    19261691bool GossipSelect_npc_akama_at_illidan(Player *player, Creature *_Creature, uint32 sender, uint32 action) 
    19271692{ 
    1928     if(action == GOSSIP_ACTION_INFO_DEF)                    // Time to begin the event 
     1693    if(action == GOSSIP_ACTION_INFO_DEF) // Time to begin the Event 
    19291694    { 
    19301695        player->CLOSE_GOSSIP_MENU(); 
    1931         ((npc_akama_illidanAI*)_Creature->AI())->BeginDoorEvent(player); 
     1696        ((npc_akama_illidanAI*)_Creature->AI())->EnterPhase(PHASE_CHANNEL); 
    19321697    } 
    19331698    return true; 
     
    19421707} 
    19431708 
    1944 struct TRINITY_DLL_SPEC boss_maievAI : public ScriptedAI 
    1945 { 
    1946     boss_maievAI(Creature *c) : ScriptedAI(c) 
    1947     { 
    1948         pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
    1949         Reset(); 
    1950     }; 
    1951  
    1952     uint32 TauntTimer; 
     1709struct TRINITY_DLL_DECL cage_trap_triggerAI : public ScriptedAI 
     1710{ 
     1711    cage_trap_triggerAI(Creature *c) : ScriptedAI(c) {Reset();} 
     1712 
    19531713    uint64 IllidanGUID; 
    1954  
    1955     ScriptedInstance* pInstance; 
    1956  
    1957     void Reset() 
    1958     { 
    1959         TauntTimer = 12000; 
    1960         IllidanGUID = 0; 
    1961     } 
    1962  
    1963     void Aggro(Unit *who) {} 
    1964  
    1965     void UpdateAI(const uint32 diff) 
    1966     { 
    1967         if(!IllidanGUID) 
    1968         { 
    1969             if(pInstance) 
    1970                 IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE); 
    1971         }else 
    1972         { 
    1973             Creature* Illidan = NULL; 
    1974             Illidan = ((Creature*)Unit::GetUnit((*m_creature), IllidanGUID)); 
    1975             if(!Illidan || !Illidan->isAlive() || Illidan->IsInEvadeMode()) 
    1976             { 
    1977                 m_creature->SetVisibility(VISIBILITY_OFF); 
    1978                 m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    1979             } 
    1980             else if(Illidan && ((Illidan->GetHealth()*100 / Illidan->GetMaxHealth()) < 2)) 
    1981                 return; 
    1982         } 
    1983  
    1984         // Return if we don't have a target 
    1985         if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
    1986             return; 
    1987  
    1988         if(TauntTimer < diff) 
    1989         { 
    1990             uint32 random = rand()%4; 
    1991             char* text = MaievTaunts[random].text; 
    1992             uint32 sound = MaievTaunts[random].sound; 
    1993             DoYell(text, LANG_UNIVERSAL, NULL); 
    1994             DoPlaySoundToSet(m_creature, sound); 
    1995             TauntTimer = 22000 + rand()%21 * 1000; 
    1996         }else TauntTimer -= diff; 
    1997  
    1998         DoMeleeAttackIfReady(); 
    1999     } 
    2000 }; 
    2001  
    2002 struct TRINITY_DLL_DECL cage_trap_triggerAI : public ScriptedAI 
    2003 { 
    2004     cage_trap_triggerAI(Creature *c) : ScriptedAI(c) {Reset();} 
    2005  
    2006     uint64 IllidanGUID; 
    2007     uint64 CageTrapGUID; 
    2008  
    20091714    uint32 DespawnTimer; 
    20101715 
     
    20151720    { 
    20161721        IllidanGUID = 0; 
    2017         CageTrapGUID = 0; 
    20181722 
    20191723        Active = false; 
     
    20341738        if(who && (who->GetTypeId() != TYPEID_PLAYER)) 
    20351739        { 
    2036             if(who->GetEntry() == ILLIDAN_STORMRAGE)        // Check if who is Illidan 
    2037             { 
    2038                 if(!IllidanGUID && m_creature->IsWithinDistInMap(who, 3) && !who->HasAura(SPELL_CAGED, 0)) 
     1740            if(who->GetEntry() == ILLIDAN_STORMRAGE) // Check if who is Illidan 
     1741            { 
     1742                if(!IllidanGUID && m_creature->IsWithinDistInMap(who, 3) && (!who->HasAura(SPELL_CAGED, 0))) 
    20391743                { 
    20401744                    IllidanGUID = who->GetGUID(); 
     
    20421746                    DespawnTimer = 5000; 
    20431747                    if(who->HasAura(SPELL_ENRAGE, 0)) 
    2044                                                             // Dispel his enrage 
    2045                         who->RemoveAurasDueToSpell(SPELL_ENRAGE); 
    2046  
    2047                     if(GameObject* CageTrap = GameObject::GetGameObject(*m_creature, CageTrapGUID)) 
    2048                         CageTrap->SetLootState(GO_JUST_DEACTIVATED); 
     1748                        who->RemoveAurasDueToSpell(SPELL_ENRAGE); // Dispel his enrage 
     1749                    //if(GameObject* CageTrap = GameObject::GetGameObject(*m_creature, CageTrapGUID)) 
     1750                    //    CageTrap->SetLootState(GO_JUST_DEACTIVATED); 
    20491751                } 
    20501752            } 
     
    20571759            if(DespawnTimer < diff) 
    20581760                m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    2059         else DespawnTimer -= diff; 
    2060  
    2061         //if(IllidanGUID && !SummonedBeams) 
    2062         //{ 
    2063         //    if(Unit* Illidan = Unit::GetUnit(*m_creature, IllidanGUID) 
    2064         //    { 
    2065         //        //TODO: Find proper spells and properly apply 'caged' Illidan effect 
    2066         //    } 
    2067         //} 
     1761            else DespawnTimer -= diff; 
     1762 
     1763            //if(IllidanGUID && !SummonedBeams) 
     1764            //{ 
     1765            //    if(Unit* Illidan = Unit::GetUnit(*m_creature, IllidanGUID) 
     1766            //    { 
     1767            //        //TODO: Find proper spells and properly apply 'caged' Illidan effect 
     1768            //    } 
     1769            //} 
    20681770    } 
    20691771}; 
     
    20901792    cell_lock->Visit(cell_lock, cSearcher, *(plr->GetMap())); 
    20911793 
    2092     if(!trigger) 
    2093     { 
    2094         plr->GetSession()->SendNotification("SD2: Summon failed. This trap is now useless.", LANG_UNIVERSAL, 0); 
    2095         error_log("SD2: Cage Trap- Unable to find trigger. This Cage Trap is now useless"); 
    2096         return false; 
    2097     } 
    2098  
    20991794    ((cage_trap_triggerAI*)trigger->AI())->Active = true; 
    2100     go->SetGoState(0); 
     1795    go->SetUInt32Value(GAMEOBJECT_STATE, 0); 
    21011796    return true; 
    21021797} 
    21031798 
    2104 //This is used to sort the players by distance in preparation for being charged by the flames. 
    2105 struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool> 
    2106 { 
    2107     const Unit* MainTarget; 
    2108     TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {}; 
    2109     // functor for operator ">" 
    2110     bool operator()(const Unit* _Left, const Unit* _Right) const 
    2111     { 
    2112         return (MainTarget->GetDistance(_Left) > MainTarget->GetDistance(_Right)); 
    2113     } 
    2114 }; 
    2115  
    2116 struct TRINITY_DLL_DECL flame_of_azzinothAI : public ScriptedAI 
    2117 { 
    2118     flame_of_azzinothAI(Creature *c) : ScriptedAI(c) {Reset();} 
    2119  
    2120     uint32 FlameBlastTimer; 
    2121     uint32 SummonBlazeTimer; 
    2122     uint32 ChargeTimer; 
     1799struct TRINITY_DLL_DECL shadow_demonAI : public ScriptedAI 
     1800{ 
     1801    shadow_demonAI(Creature *c) : ScriptedAI(c) {Reset();} 
     1802 
     1803    uint64 TargetGUID; 
     1804 
     1805    void Aggro(Unit *who) {} 
    21231806 
    21241807    void Reset() 
    21251808    { 
    2126         FlameBlastTimer = 15000 + rand()%15000; 
    2127         SummonBlazeTimer = 10000 + rand()%20000; 
    2128         ChargeTimer = 5000; 
    2129     } 
    2130  
    2131     void Aggro(Unit *who) {} 
    2132  
    2133     void Charge() 
    2134     { 
    2135         // Get the Threat List 
    2136         std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList(); 
    2137  
    2138         if(!m_threatlist.size()) return;                    // He doesn't have anyone in his threatlist, useless to continue 
    2139  
    2140         std::list<Unit*> targets; 
    2141         std::list<HostilReference *>::iterator itr = m_threatlist.begin(); 
    2142         for( ; itr!= m_threatlist.end(); ++itr)             //store the threat list in a different container 
    2143         { 
    2144             Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); 
    2145             //only on alive players 
    2146             if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER ) 
    2147                 targets.push_back( target); 
    2148         } 
    2149  
    2150         //Sort the list of players 
    2151         targets.sort(TargetDistanceOrder(m_creature)); 
    2152         //Resize so we only get the furthest target 
    2153         targets.resize(1); 
    2154  
    2155         Unit* target = (*targets.begin()); 
    2156         if(target && (!m_creature->IsWithinDistInMap(target, 40))) 
    2157         { 
    2158             DoCast(m_creature, SPELL_ENRAGE, true); 
    2159             DoCast(target, SPELL_CHARGE); 
    2160         } 
     1809        TargetGUID = 0; 
     1810        DoCast(m_creature, SPELL_SHADOW_DEMON_PASSIVE, true); 
     1811    } 
     1812 
     1813    void JustDied(Unit *killer) 
     1814    { 
     1815        Unit* target = Unit::GetUnit((*m_creature), TargetGUID); 
     1816        if(target) 
     1817            target->RemoveAurasDueToSpell(SPELL_PARALYZE); 
    21611818    } 
    21621819 
    21631820    void UpdateAI(const uint32 diff) 
    21641821    { 
    2165         // Return if we don't have a target 
    2166         if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
    2167             return; 
    2168  
    2169         if(FlameBlastTimer < diff) 
    2170         { 
    2171             DoCast(m_creature->getVictim(), SPELL_FLAME_BLAST); 
    2172             FlameBlastTimer = 30000; 
    2173         }else FlameBlastTimer -= diff; 
    2174  
    2175         if(SummonBlazeTimer < diff) 
    2176         { 
    2177             DoCast(m_creature, SPELL_BLAZE_SUMMON); 
    2178             SummonBlazeTimer = 30000 + rand()%20000; 
    2179         }else SummonBlazeTimer -= diff; 
    2180  
    2181         if(ChargeTimer < diff) 
    2182         { 
    2183             Charge(); 
    2184             ChargeTimer = 5000; 
    2185         }else ChargeTimer -= diff; 
    2186  
    2187         DoMeleeAttackIfReady(); 
    2188     } 
    2189 }; 
    2190  
    2191 struct TRINITY_DLL_DECL shadow_demonAI : public ScriptedAI 
    2192 { 
    2193     shadow_demonAI(Creature *c) : ScriptedAI(c) {Reset();} 
    2194  
    2195     uint64 TargetGUID; 
    2196  
    2197     void Reset() { TargetGUID = 0; } 
    2198  
    2199     void Aggro(Unit *who) {} 
    2200  
    2201     void JustDied(Unit *killer) 
    2202     { 
    2203         if(TargetGUID) 
    2204         { 
    2205             Unit* target = Unit::GetUnit((*m_creature), TargetGUID); 
    2206             if(target) 
    2207                 target->RemoveAurasDueToSpell(SPELL_PARALYZE); 
    2208         } 
    2209     } 
    2210  
    2211     void UpdateAI(const uint32 diff) 
    2212     { 
    22131822        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) return; 
    22141823 
    2215         // Only cast the below on players. 
    2216         if(m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) return; 
     1824        if(m_creature->getVictim()->GetTypeId() != TYPEID_PLAYER) return; // Only cast the below on players. 
    22171825 
    22181826        if(!m_creature->getVictim()->HasAura(SPELL_PARALYZE, 0)) 
     
    22201828            TargetGUID = m_creature->getVictim()->GetGUID(); 
    22211829            m_creature->AddThreat(m_creature->getVictim(), 10000000.0f); 
    2222             DoCast(m_creature, SPELL_SHADOW_DEMON_PASSIVE, true); 
    22231830            DoCast(m_creature->getVictim(), SPELL_PURPLE_BEAM, true); 
    22241831            DoCast(m_creature->getVictim(), SPELL_PARALYZE, true); 
     
    22301837}; 
    22311838 
    2232 struct TRINITY_DLL_DECL flamecrashAI : public ScriptedAI 
    2233 { 
    2234     flamecrashAI(Creature *c) : ScriptedAI(c) {Reset();} 
    2235  
    2236     uint32 FlameCrashTimer; 
     1839// Shadowfiends interact with Illidan, setting more targets in Illidan's hashmap 
     1840struct TRINITY_DLL_DECL mob_parasitic_shadowfiendAI : public ScriptedAI 
     1841{ 
     1842    mob_parasitic_shadowfiendAI(Creature* c) : ScriptedAI(c) 
     1843    { 
     1844        pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     1845        Reset(); 
     1846    } 
     1847 
     1848    ScriptedInstance* pInstance; 
     1849    uint64 IllidanGUID; 
     1850    uint32 CheckTimer; 
     1851 
     1852    void Reset() 
     1853    {         
     1854        if(pInstance) 
     1855            IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE); 
     1856        else 
     1857            IllidanGUID = 0; 
     1858 
     1859        CheckTimer = 5000; 
     1860        DoCast(m_creature, SPELL_SHADOWFIEND_PASSIVE, true); 
     1861    } 
     1862 
     1863    void Aggro(Unit* who) {} 
     1864    void MoveInLineOfSight(Unit *who){} 
     1865 
     1866    void DoMeleeAttackIfReady() 
     1867    { 
     1868        if( m_creature->isAttackReady() && m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) 
     1869        { 
     1870            if(!m_creature->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)) 
     1871            { 
     1872                m_creature->getVictim()->CastSpell(m_creature->getVictim(), SPELL_PARASITIC_SHADOWFIEND, true); //do not stack 
     1873                if(GETCRE(Illidan, IllidanGUID)) 
     1874                    ((boss_illidan_stormrageAI*)Illidan->AI())->AddParasiteTarget(m_creature->getVictim()->GetGUID()); 
     1875            } 
     1876            m_creature->AttackerStateUpdate(m_creature->getVictim()); 
     1877            m_creature->resetAttackTimer(); 
     1878        } 
     1879    } 
     1880 
     1881    void UpdateAI(const uint32 diff) 
     1882    { 
     1883        if(!m_creature->getVictim()) 
     1884        { 
     1885            if(GETCRE(Illidan, IllidanGUID)) 
     1886            { 
     1887                if(Illidan->getVictim() && !Illidan->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)) 
     1888                    AttackStart(Illidan->getVictim()); 
     1889                else 
     1890                    AttackStart(((boss_illidan_stormrageAI*)Illidan->AI())->SelectUnit(SELECT_TARGET_RANDOM, 1)); 
     1891            } 
     1892        } 
     1893        else 
     1894            DoMeleeAttackIfReady(); 
     1895 
     1896        if(CheckTimer < diff) 
     1897        { 
     1898            GETUNIT(Illidan, IllidanGUID); 
     1899            if(!Illidan || ((Creature*)Illidan)->IsInEvadeMode()) 
     1900            { 
     1901                m_creature->SetVisibility(VISIBILITY_OFF); 
     1902                m_creature->setDeathState(JUST_DIED); 
     1903                return; 
     1904            }else CheckTimer = 5000; 
     1905        }else CheckTimer -= diff; 
     1906    } 
     1907}; 
     1908 
     1909struct TRINITY_DLL_DECL demonfireAI : public ScriptedAI 
     1910{ 
     1911    demonfireAI(Creature *c) : ScriptedAI(c)  
     1912    { 
     1913        pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     1914        Reset(); 
     1915    } 
     1916 
     1917    ScriptedInstance* pInstance; 
     1918    uint64 IllidanGUID; 
     1919    bool IsTrigger; 
     1920    bool DemonFire; 
     1921    uint32 CheckTimer; 
    22371922    uint32 DespawnTimer; 
    22381923 
    22391924    void Reset() 
    22401925    { 
    2241         FlameCrashTimer = 3000 +rand()%5000; 
    2242         DespawnTimer = 60000; 
    2243     } 
    2244  
    2245     void Aggro(Unit *who){ return; } 
    2246  
    2247     void AttackStart(Unit *who) { } 
    2248  
    2249     void MoveInLineOfSight(Unit *who){ } 
     1926        if(pInstance) 
     1927            IllidanGUID = pInstance->GetData64(DATA_ILLIDANSTORMRAGE); 
     1928        else 
     1929            IllidanGUID = 0; 
     1930 
     1931        IsTrigger = false; 
     1932        DemonFire = false; 
     1933 
     1934        CheckTimer = 5000; 
     1935        DespawnTimer = 78000; //spell duration, core bug, cannot despawn self 
     1936    } 
     1937 
     1938    void Aggro(Unit *who) {} 
     1939    void AttackStart(Unit* who) {} 
     1940    void MoveInLineOfSight(Unit *who){} 
    22501941 
    22511942    void UpdateAI(const uint32 diff) 
    22521943    { 
    2253         if(FlameCrashTimer < diff) 
    2254         { 
    2255             DoCast(m_creature, SPELL_FLAME_CRASH_EFFECT); 
    2256             FlameCrashTimer = 15000; 
    2257         }else FlameCrashTimer -= diff; 
     1944        if(IsTrigger) 
     1945            return; 
     1946 
     1947        if(!DemonFire) 
     1948            DoCast(m_creature, SPELL_DEMON_FIRE); //duration 60s 
     1949 
     1950        if(CheckTimer < diff) 
     1951        { 
     1952            GETUNIT(Illidan, IllidanGUID); 
     1953            if(!Illidan || !Illidan->HasUnitMovementFlag(MOVEMENTFLAG_LEVITATING)) 
     1954            { 
     1955                m_creature->SetVisibility(VISIBILITY_OFF); 
     1956                m_creature->setDeathState(JUST_DIED); 
     1957                return; 
     1958            }else CheckTimer = 5000; 
     1959        }else CheckTimer -= diff; 
    22581960 
    22591961        if(DespawnTimer < diff) 
    22601962        { 
    2261             m_creature->SetVisibility(VISIBILITY_OFF);      // So that players don't see the sparkly effect when we die. 
    2262             m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
     1963            m_creature->SetVisibility(VISIBILITY_OFF); 
     1964            m_creature->setDeathState(JUST_DIED); 
    22631965        }else DespawnTimer -= diff; 
    2264     } 
    2265 }; 
    2266  
    2267 // Shadowfiends interact with Illidan, setting more targets in Illidan's hashmap 
    2268 struct TRINITY_DLL_SPEC mob_parasitic_shadowfiendAI : public ScriptedAI 
    2269 { 
    2270     mob_parasitic_shadowfiendAI(Creature* c) : ScriptedAI(c) 
    2271     { 
    2272         Reset(); 
    2273     } 
    2274  
    2275     void Reset() {} 
    2276  
    2277     void Aggro(Unit* who) {} 
    2278  
    2279     void DoMeleeAttackIfReady() 
    2280     { 
    2281         //If we are within range melee the target 
    2282         if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) 
    2283         { 
    2284             //Make sure our attack is ready and we aren't currently casting 
    2285             if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) 
    2286             { 
    2287                 if(!m_creature->getVictim()->HasAura(SPELL_PARASITIC_SHADOWFIEND, 0)) 
    2288                     DoCast(m_creature->getVictim(), SPELL_PARASITIC_SHADOWFIEND, true); 
    2289                 m_creature->AttackerStateUpdate(m_creature->getVictim()); 
    2290                 m_creature->resetAttackTimer(); 
    2291             } 
    2292         } 
    22931966    } 
    22941967}; 
     
    23031976    void Reset() 
    23041977    { 
    2305         BlazeTimer = 2000; 
    2306         DespawnTimer = 15000; 
    2307     } 
    2308  
    2309     void Aggro(Unit *who){ } 
    2310  
     1978        BlazeTimer = 3000;   
     1979        DespawnTimer = 60000; // Spell duration = 1 min 
     1980        //((TemporarySummon*)m_creature)->Summon(TEMPSUMMON_TIMED_DESPAWN, 0, false); 
     1981    } 
     1982 
     1983    void Aggro(Unit *who) {} 
    23111984    void AttackStart(Unit* who) { } 
    2312  
    23131985    void MoveInLineOfSight(Unit *who){ } 
    23141986 
    23151987    void UpdateAI(const uint32 diff) 
    23161988    { 
    2317         if(BlazeTimer < diff) 
    2318         { 
    2319             DoCast(m_creature, SPELL_BLAZE_EFFECT); 
    2320             BlazeTimer = 15000; 
    2321         }else BlazeTimer -= diff; 
     1989        if(BlazeTimer) 
     1990            if(BlazeTimer <= diff) 
     1991            { 
     1992                DoCast(m_creature, SPELL_BLAZE_EFFECT);//duration 60s 
     1993                BlazeTimer = 0; 
     1994            }else BlazeTimer -= diff; 
    23221995 
    23231996        if(DespawnTimer < diff) 
    23241997        { 
    23251998            m_creature->SetVisibility(VISIBILITY_OFF); 
    2326             m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
     1999            m_creature->setDeathState(JUST_DIED); 
    23272000        }else DespawnTimer -= diff; 
    23282001    } 
    23292002}; 
    23302003 
     2004struct TRINITY_DLL_DECL flamecrashAI : public ScriptedAI 
     2005{ 
     2006    flamecrashAI(Creature *c) : ScriptedAI(c) {Reset();} 
     2007 
     2008    uint32 DespawnTimer; 
     2009 
     2010    void Reset() 
     2011    { 
     2012        DoCast(m_creature, SPELL_FLAME_CRASH_EFFECT);//duration inf 
     2013        DespawnTimer = 120000; // summon spell duration 
     2014    } 
     2015 
     2016    void Aggro(Unit *who) {} 
     2017    void AttackStart(Unit *who) { } 
     2018    void MoveInLineOfSight(Unit *who){ } 
     2019 
     2020    void UpdateAI(const uint32 diff) 
     2021    { 
     2022        if(DespawnTimer < diff) 
     2023        { 
     2024            m_creature->SetVisibility(VISIBILITY_OFF); 
     2025            m_creature->setDeathState(JUST_DIED); 
     2026        }else DespawnTimer -= diff; 
     2027    } 
     2028}; 
     2029 
    23312030struct TRINITY_DLL_DECL blade_of_azzinothAI : public ScriptedAI 
    23322031{ 
    2333     blade_of_azzinothAI(Creature* c) : ScriptedAI(c) { Reset(); } 
    2334  
     2032    blade_of_azzinothAI(Creature* c) : ScriptedAI(c) {} 
    23352033    void Reset() {} 
    2336     // Do-Nothing-But-Stand-There 
    2337     void Aggro(Unit* who) { } 
     2034    void Aggro(Unit *who) {} 
    23382035    void AttackStart(Unit* who) { } 
    23392036    void MoveInLineOfSight(Unit* who) { } 
    23402037 
    2341 }; 
     2038    void SpellHit(Unit *caster, const SpellEntry *spell) 
     2039    { 
     2040        if(spell->Id == SPELL_THROW_GLAIVE2 || spell->Id == SPELL_THROW_GLAIVE) 
     2041            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 21431);//appear when hit by Illidan's glaive 
     2042    } 
     2043}; 
     2044 
     2045void boss_illidan_stormrageAI::Reset() 
     2046{ 
     2047    if(pInstance) 
     2048        pInstance->SetData(DATA_ILLIDANSTORMRAGEEVENT, NOT_STARTED); 
     2049 
     2050    for(uint8 i = 0; i < 2; i++) 
     2051    { 
     2052        if(FlameGUID[i]) 
     2053        { 
     2054            if(GETUNIT(Flame, FlameGUID[i])) 
     2055                Flame->setDeathState(JUST_DIED); 
     2056            FlameGUID[i] = 0; 
     2057        } 
     2058 
     2059        if(GlaiveGUID[i]) 
     2060        { 
     2061            if(GETUNIT(Glaive, GlaiveGUID[i])) 
     2062                Glaive->setDeathState(JUST_DIED); 
     2063            GlaiveGUID[i] = 0; 
     2064        } 
     2065    } 
     2066 
     2067    if(AkamaGUID) 
     2068    { 
     2069        if(GETCRE(Akama, AkamaGUID)) 
     2070        { 
     2071            if(!Akama->isAlive()) 
     2072                Akama->Respawn(); 
     2073            else 
     2074            { 
     2075                ((npc_akama_illidanAI*)Akama->AI())->EnterEvadeMode(); 
     2076                Akama->GetMotionMaster()->MoveTargetedHome(); 
     2077                ((npc_akama_illidanAI*)Akama->AI())->Reset(); 
     2078            } 
     2079        } 
     2080        AkamaGUID = 0; 
     2081    } 
     2082 
     2083    if(MaievGUID) 
     2084    { 
     2085        GETUNIT(Maiev, MaievGUID); 
     2086        if(Maiev && Maiev->isAlive()) 
     2087        { 
     2088            Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); 
     2089            Maiev->setDeathState(JUST_DIED); 
     2090        } 
     2091        MaievGUID = 0; 
     2092    } 
     2093 
     2094    Phase = PHASE_NULL; 
     2095    Event = EVENT_NULL; 
     2096    Timer[EVENT_BERSERK] = 1500000; 
     2097 
     2098    HoverPoint = 0; 
     2099    TalkCount = 0; 
     2100    FlightCount = 0; 
     2101    TransformCount = 0; 
     2102 
     2103    ParasiteTargets.clear(); 
     2104 
     2105    m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 21135); 
     2106    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
     2107    m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     2108    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); 
     2109    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); 
     2110    m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); 
     2111 
     2112    DoCast(m_creature, SPELL_DUAL_WIELD, true); 
     2113} 
     2114 
     2115void boss_illidan_stormrageAI::HandleTalkSequence() 
     2116{ 
     2117    switch(TalkCount) 
     2118    { 
     2119    case 0: 
     2120        m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     2121        break; 
     2122    case 8: 
     2123        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Equip our warglaives! 
     2124        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); 
     2125        m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); 
     2126        m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); 
     2127        break; 
     2128    case 9: 
     2129        if(GETCRE(Akama, AkamaGUID)) 
     2130        { 
     2131            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); 
     2132            m_creature->AddThreat(Akama, 100.0f); 
     2133            ((npc_akama_illidanAI*)Akama->AI())->EnterPhase(PHASE_FIGHT_ILLIDAN); 
     2134            EnterPhase(PHASE_NORMAL); 
     2135        } 
     2136        break; 
     2137    case 10: 
     2138        SummonMaiev(); 
     2139        break; 
     2140    case 11: 
     2141        if(GETUNIT(Maiev, MaievGUID)) 
     2142        { 
     2143            Maiev->SetVisibility(VISIBILITY_ON); // Maiev is now visible 
     2144            Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); // onoz she looks like she teleported! 
     2145            Maiev->SetInFront(m_creature); // Have her face us 
     2146            m_creature->SetInFront(Maiev); // Face her, so it's not rude =P 
     2147            Maiev->StopMoving(); 
     2148            m_creature->StopMoving(); 
     2149        }break; 
     2150    case 14: 
     2151        if(GETCRE(Maiev, MaievGUID)) 
     2152        { 
     2153            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); 
     2154            Maiev->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); 
     2155            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 
     2156            Maiev->AI()->AttackStart(m_creature); // Force Maiev to attack us. 
     2157            EnterPhase(PHASE_NORMAL_MAIEV); 
     2158        }break; 
     2159    case 15: 
     2160        DoCast(m_creature, SPELL_DEATH); // Animate his kneeling + stun him 
     2161        break; 
     2162    case 17: 
     2163        if(GETUNIT(Akama, AkamaGUID)) 
     2164        { 
     2165            if(!m_creature->IsWithinDistInMap(Akama, 15)) 
     2166            { 
     2167                float x, y, z; 
     2168                m_creature->GetPosition(x, y, z); 
     2169                x += 10; y += 10; 
     2170                Akama->GetMotionMaster()->Clear(false); 
     2171                //Akama->GetMotionMaster()->MoveIdle(); 
     2172                Akama->Relocate(x, y, z); 
     2173                Akama->SendMonsterMove(x, y, z, 0, 0, 0);//Illidan must not die until Akama arrives. 
     2174                Akama->GetMotionMaster()->MoveChase(m_creature); 
     2175            } 
     2176        } 
     2177        break; 
     2178    case 19: // Make Maiev leave 
     2179        if(GETUNIT(Maiev, MaievGUID)) 
     2180        { 
     2181            Maiev->CastSpell(Maiev, SPELL_TELEPORT_VISUAL, true); 
     2182            Maiev->setDeathState(JUST_DIED); 
     2183            m_creature->SetUInt32Value(UNIT_FIELD_BYTES_1,PLAYER_STATE_DEAD); 
     2184        } 
     2185        break; 
     2186    case 21: // Kill ourself. 
     2187        m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
     2188        break; 
     2189    default: 
     2190        break; 
     2191    } 
     2192    if(Phase == PHASE_TALK_SEQUENCE) 
     2193        Talk(TalkCount); // This function does most of the talking 
     2194    TalkCount++; 
     2195} 
     2196 
     2197 
     2198void boss_illidan_stormrageAI::CastEyeBlast() 
     2199{ 
     2200    m_creature->InterruptNonMeleeSpells(false); 
     2201 
     2202    DoYell(SAY_EYE_BLAST, LANG_UNIVERSAL, NULL); 
     2203    DoPlaySoundToSet(m_creature, SOUND_EYE_BLAST); 
     2204 
     2205    float distx, disty, dist[2]; 
     2206    for(uint8 i = 0; i < 2; ++i) 
     2207    { 
     2208        distx = EyeBlast[i].x - HoverPosition[HoverPoint].x; 
     2209        disty = EyeBlast[i].y - HoverPosition[HoverPoint].y; 
     2210        dist[i] = distx * distx + disty * disty; 
     2211    } 
     2212    Locations initial = EyeBlast[dist[0] < dist[1] ? 0 : 1]; 
     2213    for(uint8 i = 0; i < 2; ++i) 
     2214    { 
     2215        distx = GlaivePosition[i].x - HoverPosition[HoverPoint].x; 
     2216        disty = GlaivePosition[i].y - HoverPosition[HoverPoint].y; 
     2217        dist[i] = distx * distx + disty * disty; 
     2218    } 
     2219    Locations final = GlaivePosition[dist[0] < dist[1] ? 0 : 1]; 
     2220 
     2221    final.x = 2 * final.x - initial.x; 
     2222    final.y = 2 * final.y - initial.y; 
     2223 
     2224    for(uint8 i = 0; i < 2; ++i)//core bug, two buff do not coexist 
     2225    { 
     2226        Creature* Trigger = NULL; 
     2227        Trigger = m_creature->SummonCreature(DEMON_FIRE, initial.x, initial.y, initial.z, 0, TEMPSUMMON_TIMED_DESPAWN, 13000); 
     2228        if(Trigger) 
     2229        { 
     2230            ((demonfireAI*)Trigger->AI())->IsTrigger = true; 
     2231            Trigger->SetSpeed(MOVE_WALK, 3); 
     2232            Trigger->SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE); 
     2233            Trigger->GetMotionMaster()->MovePoint(0, final.x, final.y, final.z); 
     2234 
     2235            if(!i) 
     2236                Trigger->CastSpell(Trigger, SPELL_EYE_BLAST_TRIGGER, true); 
     2237            else 
     2238            { 
     2239                Trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     2240                m_creature->SetUInt64Value(UNIT_FIELD_TARGET, Trigger->GetGUID()); 
     2241                DoCast(Trigger, SPELL_EYE_BLAST); 
     2242            } 
     2243        } 
     2244    } 
     2245} 
     2246 
     2247void boss_illidan_stormrageAI::SummonFlamesOfAzzinoth() 
     2248{ 
     2249    DoYell(SAY_SUMMONFLAMES, LANG_UNIVERSAL, NULL); 
     2250    DoPlaySoundToSet(m_creature, SOUND_SUMMONFLAMES); 
     2251 
     2252    for(uint8 i = 0; i < 2; ++i) 
     2253    { 
     2254        if(GETUNIT(Glaive, GlaiveGUID[i])) 
     2255        { 
     2256            Creature* Flame = m_creature->SummonCreature(FLAME_OF_AZZINOTH, GlaivePosition[i+2].x, GlaivePosition[i+2].y, GlaivePosition[i+2].z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000); 
     2257            if(Flame) 
     2258            { 
     2259                Flame->setFaction(m_creature->getFaction()); // Just in case the database has it as a different faction 
     2260                Flame->SetMeleeDamageSchool(SPELL_SCHOOL_FIRE); 
     2261                Flame->AI()->AttackStart(m_creature->getVictim()); // Attack our target! 
     2262                FlameGUID[i] = Flame->GetGUID(); // Record GUID in order to check if they're dead later on to move to the next phase 
     2263                ((flame_of_azzinothAI*)Flame->AI())->SetGlaiveGUID(GlaiveGUID[i]); 
     2264                DoZoneInCombat(Flame); 
     2265                Glaive->CastSpell(Flame, SPELL_AZZINOTH_CHANNEL, false); // Glaives do some random Beam type channel on it. 
     2266            } 
     2267        } 
     2268    } 
     2269} 
     2270 
     2271void boss_illidan_stormrageAI::SummonMaiev() 
     2272{ 
     2273    DoCast(m_creature, SPELL_SHADOW_PRISON, true); 
     2274    Creature* Maiev = m_creature->SummonCreature(MAIEV_SHADOWSONG, m_creature->GetPositionX() + 10, m_creature->GetPositionY() + 5, m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     2275    if(Maiev) 
     2276    { 
     2277        Maiev->SetVisibility(VISIBILITY_OFF); // Leave her invisible until she has to talk 
     2278        Maiev->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
     2279        MaievGUID = Maiev->GetGUID(); 
     2280        ((boss_maievAI*)Maiev->AI())->GetIllidanGUID(m_creature->GetGUID()); 
     2281        ((boss_maievAI*)Maiev->AI())->EnterPhase(PHASE_TALK_SEQUENCE); 
     2282    } 
     2283    else // If Maiev cannot be summoned, reset the encounter and post some errors to the console. 
     2284    { 
     2285        EnterEvadeMode(); 
     2286        DoTextEmote("is unable to summon Maiev Shadowsong and enter Phase 4. Resetting Encounter.", NULL); 
     2287        error_log("SD2 ERROR: Unable to summon Maiev Shadowsong (entry: 23197). Check your database to see if you have the proper SQL for Maiev Shadowsong (entry: 23197)"); 
     2288    } 
     2289} 
     2290 
     2291 
     2292void boss_illidan_stormrageAI::EnterPhase(PhaseIllidan NextPhase) 
     2293{ 
     2294    DoZoneInCombat(); 
     2295    switch(NextPhase) 
     2296    { 
     2297    case PHASE_NORMAL: 
     2298    case PHASE_NORMAL_2: 
     2299    case PHASE_NORMAL_MAIEV: 
     2300        AttackStart(m_creature->getVictim()); 
     2301        Timer[EVENT_TAUNT] = 32000; 
     2302        Timer[EVENT_SHEAR] = 10000 + rand()%15 * 1000; 
     2303        Timer[EVENT_FLAME_CRASH] = 20000; 
     2304        Timer[EVENT_PARASITIC_SHADOWFIEND] = 25000; 
     2305        Timer[EVENT_PARASITE_CHECK] = 0; 
     2306        Timer[EVENT_DRAW_SOUL] = 30000; 
     2307        if(NextPhase == PHASE_NORMAL) 
     2308            break; 
     2309        Timer[EVENT_AGONIZING_FLAMES] = 35000; 
     2310        Timer[EVENT_TRANSFORM_NORMAL] = 60000; 
     2311        if(NextPhase == PHASE_NORMAL_2) 
     2312            break; 
     2313        Timer[EVENT_ENRAGE] = 30000 + rand()%10 * 1000; 
     2314        break; 
     2315    case PHASE_FLIGHT: 
     2316        Timer[EVENT_FIREBALL] = 1000; 
     2317        if(!(rand()%4)) 
     2318            Timer[EVENT_DARK_BARRAGE] = 10000; 
     2319        Timer[EVENT_EYE_BLAST] = 10000 + rand()%15 * 1000; 
     2320        Timer[EVENT_MOVE_POINT] = 20000 + rand()%20 * 1000; 
     2321        break; 
     2322    case PHASE_DEMON: 
     2323        Timer[EVENT_SHADOW_BLAST] = 1000; 
     2324        Timer[EVENT_FLAME_BURST] = 10000; 
     2325        Timer[EVENT_SHADOWDEMON] = 30000; 
     2326        Timer[EVENT_TRANSFORM_DEMON] = 60000; 
     2327        AttackStart(m_creature->getVictim()); 
     2328        break; 
     2329    case PHASE_TALK_SEQUENCE: 
     2330        Timer[EVENT_TALK_SEQUENCE] = 100; 
     2331        m_creature->RemoveAllAuras(); 
     2332        m_creature->InterruptNonMeleeSpells(false); 
     2333        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); 
     2334        m_creature->GetMotionMaster()->Clear(false); 
     2335        //m_creature->GetMotionMaster()->MoveIdle(); 
     2336        m_creature->AttackStop(); 
     2337        break; 
     2338    case PHASE_FLIGHT_SEQUENCE: 
     2339        if(Phase == PHASE_FLIGHT) //land 
     2340            Timer[EVENT_FLIGHT_SEQUENCE] = 2000; 
     2341        else //lift off 
     2342        { 
     2343            FlightCount = 1; 
     2344            Timer[EVENT_FLIGHT_SEQUENCE] = 1; 
     2345            m_creature->RemoveAllAuras(); 
     2346            m_creature->InterruptNonMeleeSpells(false); 
     2347            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE + UNIT_FLAG_NOT_SELECTABLE); 
     2348            m_creature->GetMotionMaster()->Clear(false); 
     2349            //m_creature->GetMotionMaster()->MoveIdle(); 
     2350            m_creature->AttackStop(); 
     2351        } 
     2352        break; 
     2353    case PHASE_TRANSFORM_SEQUENCE: 
     2354        if(Phase == PHASE_DEMON) 
     2355            Timer[EVENT_TRANSFORM_SEQUENCE] = 500; 
     2356        else 
     2357        { 
     2358            TransformCount = 0; 
     2359            Timer[EVENT_TRANSFORM_SEQUENCE] = 500; 
     2360            DoYell(SAY_MORPH, LANG_UNIVERSAL, NULL); 
     2361            DoPlaySoundToSet(m_creature, SOUND_MORPH); 
     2362        } 
     2363        m_creature->GetMotionMaster()->Clear(); 
     2364        //m_creature->GetMotionMaster()->MoveIdle(); 
     2365        m_creature->AttackStop(); 
     2366        break; 
     2367    default: 
     2368        break; 
     2369    } 
     2370    if(MaievGUID) 
     2371    { 
     2372        GETCRE(Maiev, MaievGUID); 
     2373        if(Maiev && Maiev->isAlive()) 
     2374            ((boss_maievAI*)Maiev->AI())->EnterPhase(NextPhase); 
     2375    } 
     2376    Phase = NextPhase; 
     2377    Event = EVENT_NULL; 
     2378} 
    23422379 
    23432380CreatureAI* GetAI_boss_illidan_stormrage(Creature *_Creature) 
     
    23482385CreatureAI* GetAI_npc_akama_at_illidan(Creature *_Creature) 
    23492386{ 
    2350     npc_akama_illidanAI* Akama_AI = new npc_akama_illidanAI(_Creature); 
    2351  
    2352     for(uint8 i = 0; i < 13; ++i) 
    2353         Akama_AI->AddWaypoint(i, AkamaWP[i].x, AkamaWP[i].y, AkamaWP[i].z); 
    2354  
    2355     return ((CreatureAI*)Akama_AI); 
     2387    return new npc_akama_illidanAI(_Creature); 
    23562388} 
    23572389 
  • trunk/src/bindings/scripts/scripts/zone/black_temple/boss_mother_shahraz.cpp

    r48 r57  
    3333#define SPELL_SILENCING_SHRIEK  40823 
    3434#define SPELL_ENRAGE            23537 
    35 #define SPELL_SABER_LASH        43267 
     35#define SPELL_SABER_LASH        40810//43267 
    3636#define SPELL_SABER_LASH_IMM    43690 
    3737#define SPELL_TELEPORT_VISUAL   40869 
     
    116116    uint32 FatalAttractionExplodeTimer; 
    117117    uint32 ShriekTimer; 
     118        uint32 SaberTimer; 
    118119    uint32 RandomYellTimer; 
    119120    uint32 EnrageTimer; 
     
    130131            TargetGUID[i] = 0; 
    131132 
    132         BeamTimer = 60000;                                  // Timers may be incorrect 
     133        BeamTimer = 20000; // Timers may be incorrect 
    133134        BeamCount = 0; 
    134135        CurrentBeam = 0;                                    // 0 - Sinister, 1 - Vile, 2 - Wicked, 3 - Sinful 
     
    137138        FatalAttractionExplodeTimer = 70000; 
    138139        ShriekTimer = 30000; 
     140                SaberTimer = 35000; 
    139141        RandomYellTimer = 70000 + rand()%41 * 1000; 
    140142        EnrageTimer = 600000; 
     
    302304        { 
    303305            DoCast(m_creature->getVictim(), SPELL_SILENCING_SHRIEK); 
    304             ShriekTimer = 30000; 
     306            ShriekTimer = 25000+rand()%10 * 1000; 
    305307        }else ShriekTimer -= diff; 
     308 
     309                if(SaberTimer < diff) 
     310        { 
     311            DoCast(m_creature->getVictim(), SPELL_SABER_LASH); 
     312            SaberTimer = 25000+rand()%10 * 1000; 
     313        }else SaberTimer -= diff; 
    306314 
    307315        //Enrage 
  • trunk/src/bindings/scripts/scripts/zone/black_temple/boss_reliquary_of_souls.cpp

    r48 r57  
    11/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> 
    2  * This program is free software; you can redistribute it and/or modify 
    3  * it under the terms of the GNU General Public License as published by 
    4  * the Free Software Foundation; either version 2 of the License, or 
    5  * (at your option) any later version. 
    6  * 
    7  * This program is distributed in the hope that it will be useful, 
    8  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
    10  * GNU General Public License for more details. 
    11  * 
    12  * You should have received a copy of the GNU General Public License 
    13  * along with this program; if not, write to the Free Software 
    14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
    15  */ 
     2* This program is free software; you can redistribute it and/or modify 
     3* it under the terms of the GNU General Public License as published by 
     4* the Free Software Foundation; either version 2 of the License, or 
     5* (at your option) any later version. 
     6* 
     7* This program is distributed in the hope that it will be useful, 
     8* but WITHOUT ANY WARRANTY; without even the implied warranty of 
     9* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
     10* GNU General Public License for more details. 
     11* 
     12* You should have received a copy of the GNU General Public License 
     13* along with this program; if not, write to the Free Software 
     14* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
     15*/ 
    1616 
    1717/* ScriptData 
    1818SDName: Boss_Reliquary_of_Souls 
    1919SD%Complete: 90 
    20 SDComment: Persistent Area Auras for each Essence (Aura of Suffering, Aura of Desire, Aura of Anger) requires core support. 
     20SDComment: 
    2121SDCategory: Black Temple 
    2222EndScriptData */ 
     
    2424#include "precompiled.h" 
    2525#include "def_black_temple.h" 
     26#include "Spell.h" 
    2627 
    2728//Sound'n'speech 
     
    3536#define SUFF_SAY_SLAY2      "I didn't ask for this!" 
    3637#define SUFF_SOUND_SLAY2    11418 
    37 #define SUFF_SAY_SLAY3      "The pain is only beginning!" 
    38 #define SUFF_SOUND_SLAY3    11419 
     38#define SUFF_SAY_ENRAGE     "The pain is only beginning!" 
     39#define SUFF_SOUND_ENRAGE   11419 
    3940#define SUFF_SAY_RECAP      "I don't want to go back!" 
    4041#define SUFF_SOUND_RECAP    11420 
     
    6162#define ANGER_SAY_FREED     "Beware... I live." 
    6263#define ANGER_SOUND_FREED   11399 
    63 #define ANGER_SAY_FREED2    "So... foolish." 
    64 #define ANGER_SOUND_FREED2  11400 
     64#define ANGER_SAY_SCREAM    "So... foolish." 
     65#define ANGER_SOUND_SCREAM  11400 
    6566#define ANGER_SOUND_SLAY1   11401 
    6667#define ANGER_SAY_SLAY2     "Enough. No more." 
     
    7576//Spells 
    7677#define AURA_OF_SUFFERING               41292 
    77 #define AURA_OF_SUFFERING_ARMOR         42017 
    78 #define ESSENCE_OF_SUFFERING_PASSIVE    41296 
     78#define AURA_OF_SUFFERING_ARMOR         42017 // linked aura, need core support 
     79#define ESSENCE_OF_SUFFERING_PASSIVE    41296 // periodic trigger 41294 
     80#define ESSENCE_OF_SUFFERING_PASSIVE2   41623  
     81#define SPELL_FIXATE_TARGET             41294 // dummy, select target 
     82#define SPELL_FIXATE_TAUNT              41295 // force taunt 
    7983#define SPELL_ENRAGE                    41305 
    8084#define SPELL_SOUL_DRAIN                41303 
    81 #define SPELL_FIXATE                    41295 
    8285 
    8386#define AURA_OF_DESIRE                  41350 
     87#define AURA_OF_DESIRE_DAMAGE           41352 
    8488#define SPELL_RUNE_SHIELD               41431 
    8589#define SPELL_DEADEN                    41410 
     
    8791 
    8892#define AURA_OF_ANGER                   41337 
    89 #define SPELL_SELF_SEETHE               41364 
     93#define SPELL_SELF_SEETHE               41364 // force cast 41520 
    9094#define SPELL_ENEMY_SEETHE              41520 
    9195#define SPELL_SOUL_SCREAM               41545 
    92 #define SPELL_SPITE                     41377 
     96#define SPELL_SPITE_TARGET              41376 // cast 41377 after 6 sec 
     97#define SPELL_SPITE_DAMAGE              41377 
    9398 
    9499#define ENSLAVED_SOUL_PASSIVE           41535 
    95100#define SPELL_SOUL_RELEASE              41542 
    96 #define SPELL_RESTORE_MANA              32848 
    97 #define SPELL_RESTORE_HEALTH            25329 
    98101 
    99102#define CREATURE_ENSLAVED_SOUL          23469 
     103#define NUMBER_ENSLAVED_SOUL            8 
    100104 
    101105struct Position 
     
    120124    uint64 ReliquaryGUID; 
    121125 
    122     void Reset() 
    123     { 
    124         ReliquaryGUID = 0; 
    125     } 
    126  
    127     void Aggro(Unit* who) {} 
    128  
    129     void DamageTaken(Unit *done_by, uint32 &damage) 
    130     { 
    131         if(damage >= m_creature->GetHealth()) 
    132         { 
    133             if(done_by->GetTypeId() == TYPEID_PLAYER) 
    134             { 
    135                 done_by->CastSpell(done_by, SPELL_RESTORE_HEALTH, true); 
    136                 if(done_by->GetMaxPower(POWER_MANA) > 0) 
    137                 { 
    138                     if((done_by->GetPower(POWER_MANA) / done_by->GetMaxPower(POWER_MANA)) < 70) 
    139                     { 
    140                         uint32 mana = done_by->GetPower(POWER_MANA) + (uint32)(done_by->GetMaxPower(POWER_MANA)*0.3); 
    141                         done_by->SetPower(POWER_MANA, mana); 
    142                     }else done_by->SetPower(POWER_MANA, done_by->GetMaxPower(POWER_MANA)); 
    143                 } 
    144             } 
    145             DoCast(done_by, SPELL_SOUL_RELEASE); 
    146         } 
     126    void Reset() {ReliquaryGUID = 0;} 
     127 
     128    void Aggro(Unit* who) 
     129    { 
     130        m_creature->CastSpell(m_creature, ENSLAVED_SOUL_PASSIVE, true); 
     131        DoZoneInCombat(); 
    147132    } 
    148133 
     
    152137struct TRINITY_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI 
    153138{ 
    154     boss_reliquary_of_soulsAI(Creature *c) : ScriptedAI(c) 
     139    boss_reliquary_of_soulsAI(Creature *c) : ScriptedAI(c)  
    155140    { 
    156141        pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     142        EssenceGUID = 0; 
    157143        Reset(); 
    158144    } 
     
    160146    ScriptedInstance* pInstance; 
    161147 
    162     uint64 SufferingGUID; 
    163     uint64 DesireGUID; 
    164     uint64 AngerGUID; 
    165  
     148    uint64 EssenceGUID; 
     149 
     150    uint32 Phase; 
     151    uint32 Counter; 
     152    uint32 Timer; 
     153 
     154    uint32 SoulCount; 
    166155    uint32 SoulDeathCount; 
    167     // 0 = Out of Combat, 1 = Not started, 2 = Suffering, 3 = Souls, 4 = Desire, 5 = Souls, 6 = Anger 
    168     uint32 Phase; 
    169     uint32 SummonEssenceTimer; 
    170     uint32 DespawnEssenceTimer; 
    171     uint32 SoulCount; 
    172     uint32 SummonSoulTimer; 
    173     uint32 AnimationTimer; 
    174  
    175     bool IsDead; 
    176     bool EndingPhase; 
    177156 
    178157    void Reset() 
     
    181160            pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, NOT_STARTED); 
    182161 
    183         DespawnEssences(); 
    184  
    185         SufferingGUID = 0; 
    186         DesireGUID = 0; 
    187         AngerGUID = 0; 
    188  
    189         SoulDeathCount = 0; 
     162        if(EssenceGUID) 
     163        { 
     164            if(Unit* Essence = Unit::GetUnit(*m_creature, EssenceGUID)) 
     165            { 
     166                Essence->SetVisibility(VISIBILITY_OFF); 
     167                Essence->setDeathState(DEAD); 
     168            } 
     169            EssenceGUID = 0; 
     170        } 
     171 
    190172        Phase = 0; 
    191         SummonEssenceTimer = 8000; 
    192         DespawnEssenceTimer = 2000; 
    193         SoulCount = 0; 
    194         SummonSoulTimer = 1000; 
    195         AnimationTimer = 8000; 
    196  
    197         IsDead = false; 
    198         EndingPhase = false; 
    199  
    200         m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     173 
    201174        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    202175        m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); 
    203         m_creature->GetMotionMaster()->Clear(false); 
    204     } 
    205  
    206     void Aggro(Unit* who) { } 
    207  
    208     void AttackStart(Unit* who) { } 
     176    } 
     177 
     178    void Aggro(Unit* who) 
     179    { 
     180        m_creature->AddThreat(who, 10000.0f); 
     181        DoZoneInCombat(); 
     182        if(pInstance) 
     183            pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, IN_PROGRESS); 
     184 
     185        Phase = 1; 
     186        Counter = 0; 
     187        Timer = 0; 
     188    } 
    209189 
    210190    void MoveInLineOfSight(Unit *who) 
    211191    { 
    212         if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) 
    213         { 
     192        if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) ) 
     193        { 
     194            if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) 
     195                return; 
     196 
    214197            float attackRadius = m_creature->GetAttackDistance(who); 
    215             if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) 
     198            if( m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->IsWithinLOSInMap(who) ) 
    216199            { 
    217                 if(who->HasStealthAura()) 
    218                     who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); 
    219  
    220                 if(!InCombat) 
     200                who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); 
     201 
     202                if (!InCombat) 
    221203                { 
    222                     if(pInstance) 
    223                         pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, IN_PROGRESS); 
    224  
    225                     Phase = 1; 
    226                                                             // I R ANNNGRRRY! 
    227                     m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,375); 
    228                     SummonEssenceTimer = 8000; 
    229                     AnimationTimer = 5100; 
    230                     m_creature->AddThreat(who, 1.0f); 
    231  
     204                    Aggro(who); 
    232205                    InCombat = true; 
    233206                } 
     
    236209    } 
    237210 
    238     void SummonSoul() 
     211    void AttackStart(Unit*) {} 
     212 
     213    bool SummonSoul() 
    239214    { 
    240215        uint32 random = rand()%6; 
    241216        float x = Coords[random].x; 
    242217        float y = Coords[random].y; 
    243         Creature* Soul = m_creature->SummonCreature(CREATURE_ENSLAVED_SOUL, x, y, m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000); 
    244         Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
    245         if (target && Soul) 
     218        Creature* Soul = m_creature->SummonCreature(CREATURE_ENSLAVED_SOUL, x, y, m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, 0); 
     219        if(!Soul) return false; 
     220        if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) 
    246221        { 
    247222            ((npc_enslaved_soulAI*)Soul->AI())->ReliquaryGUID = m_creature->GetGUID(); 
    248             Soul->CastSpell(Soul, ENSLAVED_SOUL_PASSIVE, true); 
    249             Soul->AddThreat(target, 1.0f); 
    250             SoulCount++; 
    251         } 
    252     } 
    253  
    254     void MergeThreatList(Creature* target) 
    255     { 
    256         if(!target) return; 
    257  
    258         std::list<HostilReference*>& m_threatlist = target->getThreatManager().getThreatList(); 
    259         std::list<HostilReference*>::iterator itr = m_threatlist.begin(); 
    260         for( ; itr != m_threatlist.end(); itr++) 
    261         { 
    262             Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid()); 
    263             if(pUnit) 
    264             { 
    265                 m_creature->AddThreat(pUnit, 1.0f);         // This is so that we make sure the unit is in Reliquary's threat list before we reset the unit's threat. 
    266                 m_creature->getThreatManager().modifyThreatPercent(pUnit, -100); 
    267                 float threat = target->getThreatManager().getThreat(pUnit); 
    268                 m_creature->AddThreat(pUnit, threat);       // This makes it so that the unit has the same amount of threat in Reliquary's threatlist as in the target creature's (One of the Essences). 
    269             } 
    270         } 
    271     } 
    272  
    273     void DespawnEssences() 
    274     { 
    275         // Despawn Essences 
    276         Unit* Essence = NULL; 
    277         if(SufferingGUID) 
    278             Essence = ((Creature*)Unit::GetUnit((*m_creature), SufferingGUID)); 
    279         else if(DesireGUID) 
    280             Essence = ((Creature*)Unit::GetUnit((*m_creature), DesireGUID)); 
    281         else if(AngerGUID) 
    282             Essence = ((Creature*)Unit::GetUnit((*m_creature), AngerGUID)); 
    283         if(Essence && Essence->isAlive()) 
    284             Essence->setDeathState(JUST_DIED); 
     223            Soul->AI()->AttackStart(target); 
     224        }else EnterEvadeMode(); 
     225        return true; 
    285226    } 
    286227 
     
    298239            return; 
    299240 
    300         // Reset if event is begun and we don't have a threatlist 
    301         if(Phase && m_creature->getThreatManager().getThreatList().empty()) 
     241        if(m_creature->getThreatManager().getThreatList().empty()) // Reset if event is begun and we don't have a threatlist 
     242        { 
    302243            EnterEvadeMode(); 
    303  
    304         if(Phase == 1) 
    305         { 
    306             if(AnimationTimer < diff) 
     244            return; 
     245        } 
     246 
     247        Creature* Essence; 
     248        if(EssenceGUID) 
     249        { 
     250            Essence = (Creature*)Unit::GetUnit(*m_creature, EssenceGUID); 
     251            if(!Essence) 
    307252            { 
    308                 // Release the cube 
    309                 m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); 
    310                 AnimationTimer = 8300; 
    311             }else AnimationTimer -= diff; 
    312  
    313             if(SummonEssenceTimer < diff) 
     253                EnterEvadeMode(); 
     254                return; 
     255            } 
     256        } 
     257 
     258        if(Timer < diff) 
     259        { 
     260            switch(Counter) 
    314261            { 
    315                 // Ribs: open 
    316                 m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); 
    317                 Creature* EssenceSuffering = NULL; 
    318                 EssenceSuffering = m_creature->SummonCreature(23418, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); 
    319  
    320                 if(EssenceSuffering) 
     262            case 0: 
     263                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,375);  // I R ANNNGRRRY! 
     264                Timer = 3000; 
     265                break; 
     266            case 1: 
     267                Timer = 2800; 
     268                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374);  // Release the cube 
     269                break; 
     270            case 2: 
     271                Timer = 5000; 
     272                if(Creature* Summon = DoSpawnCreature(23417+Phase, 0, 0, 0, 0, TEMPSUMMON_DEAD_DESPAWN, 0)) 
    321273                { 
    322                     EssenceSuffering->Yell(SUFF_SAY_FREED, LANG_UNIVERSAL, 0); 
    323                     DoPlaySoundToSet(m_creature, SUFF_SOUND_FREED); 
    324                     Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0); 
    325                     if(target) 
     274                    m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373);  // Ribs: open 
     275                    Summon->AI()->AttackStart(SelectUnit(SELECT_TARGET_TOPAGGRO, 0)); 
     276                    EssenceGUID = Summon->GetGUID(); 
     277                }else EnterEvadeMode(); 
     278                break; 
     279            case 3: 
     280                Timer = 1000; 
     281                if(Phase == 3) 
     282                { 
     283                    if(!Essence->isAlive()) 
     284                        m_creature->CastSpell(m_creature, 7, true); 
     285                    else return; 
     286                } 
     287                else 
     288                { 
     289                    if(Essence->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)) 
    326290                    { 
    327                         EssenceSuffering->AddThreat(target, 1.0f); 
    328                         EssenceSuffering->AI()->AttackStart(target); 
    329                     } 
    330                     SufferingGUID = EssenceSuffering->GetGUID(); 
     291                        Essence->AI()->EnterEvadeMode(); 
     292                        Essence->GetMotionMaster()->MoveFollow(m_creature, 0, 0); 
     293                    }else return; 
    331294                } 
    332  
    333                 EndingPhase = false; 
    334                 Phase = 2; 
    335             }else SummonEssenceTimer -= diff; 
    336         } 
    337  
    338         if(Phase == 2) 
    339         { 
    340             if(SufferingGUID) 
    341             { 
    342                 Creature* EssenceSuffering = NULL; 
    343                 EssenceSuffering = ((Creature*)Unit::GetUnit((*m_creature), SufferingGUID)); 
    344  
    345                 if(!EssenceSuffering || (!EssenceSuffering->isAlive())) 
    346                     EnterEvadeMode(); 
    347  
    348                 if(!EndingPhase) 
     295                break; 
     296            case 4: 
     297                Timer = 1500; 
     298                if(Essence->IsWithinDistInMap(m_creature, 10)) 
     299                    Essence->SetUInt32Value(UNIT_NPC_EMOTESTATE, 374); //rotate and disappear 
     300                else 
     301                    return; 
     302                break; 
     303            case 5: 
     304                if(Phase == 1) 
    349305                { 
    350                     if(EssenceSuffering) 
    351                     { 
    352                         if(EssenceSuffering->GetHealth() < (EssenceSuffering->GetMaxHealth()*0.1)) 
    353                         { 
    354                             MergeThreatList(EssenceSuffering); 
    355                             EssenceSuffering->RemoveAllAuras(); 
    356                             EssenceSuffering->DeleteThreatList(); 
    357                             EssenceSuffering->GetMotionMaster()->MoveFollow(m_creature,0.0f,0.0f); 
    358                             EssenceSuffering->Yell(SUFF_SAY_RECAP,LANG_UNIVERSAL,0); 
    359                             DoPlaySoundToSet(m_creature, SUFF_SOUND_RECAP); 
    360                             EssenceSuffering->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    361                             DespawnEssenceTimer = 4000; 
    362                             AnimationTimer = 2200; 
    363                             EndingPhase = true; 
    364                         } 
    365                     } 
     306                    Essence->Yell(SUFF_SAY_AFTER,LANG_UNIVERSAL,0); 
     307                    DoPlaySoundToSet(Essence, SUFF_SOUND_AFTER); 
    366308                } 
    367  
    368                 if((EndingPhase) && (EssenceSuffering) && (EssenceSuffering->isAlive())) 
     309                else 
    369310                { 
    370                     if(AnimationTimer < diff) 
    371                     { 
    372                         // Return 
    373                         EssenceSuffering->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); 
    374                         AnimationTimer = 10000; 
    375                     }else AnimationTimer -= diff; 
    376  
    377                     if(DespawnEssenceTimer < diff) 
    378                     { 
    379                         EssenceSuffering->DeleteThreatList(); 
    380                         EssenceSuffering->Yell(SUFF_SAY_AFTER,LANG_UNIVERSAL,0); 
    381                         DoPlaySoundToSet(m_creature, SUFF_SOUND_AFTER); 
    382                         EssenceSuffering->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); 
    383                         EssenceSuffering->setFaction(35); 
    384                         m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); 
    385                         SummonEssenceTimer = 20000;         //60000; 
    386                         AnimationTimer = 18200;             //58100; 
    387                         SoulDeathCount = 0; 
    388                         SoulCount = 0; 
    389                         SummonSoulTimer = 1000; 
    390                         EndingPhase = false; 
    391                         Phase = 3; 
    392                         SufferingGUID = 0; 
    393                     }else DespawnEssenceTimer -= diff; 
     311                    Essence->Yell(DESI_SAY_AFTER,LANG_UNIVERSAL,0); 
     312                    DoPlaySoundToSet(Essence, DESI_SOUND_AFTER); 
    394313                } 
    395             } 
    396         } 
    397  
    398         if(Phase == 3) 
    399         { 
    400             if(SoulCount < 36) 
    401             { 
    402                 if(SummonSoulTimer < diff) 
     314                Essence->SetVisibility(VISIBILITY_OFF); 
     315                Essence->setDeathState(DEAD); 
     316                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); 
     317                EssenceGUID = 0; 
     318                SoulCount = 0; 
     319                SoulDeathCount = 0; 
     320                Timer = 3000;             
     321                break; 
     322            case 6: 
     323                if(SoulCount < NUMBER_ENSLAVED_SOUL) 
    403324                { 
    404                     SummonSoul(); 
    405                     SummonSoulTimer = 500; 
    406                 }else SummonSoulTimer -= diff; 
    407             } 
    408  
    409             if(SoulDeathCount >= SoulCount) 
    410             { 
    411                 if(AnimationTimer < diff) 
     325                    if(SummonSoul()) 
     326                        SoulCount++; 
     327                    Timer = 500; 
     328                    return; 
     329                }break; 
     330            case 7: 
     331                if(SoulDeathCount >= SoulCount) 
    412332                { 
    413                     // Release the cube 
    414                     m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); 
    415                     AnimationTimer = 10000; 
    416                 }else AnimationTimer -= diff; 
    417  
    418                 if(SummonEssenceTimer < diff) 
    419                 { 
    420                     // Ribs: open 
    421                     m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); 
    422                     Creature* EssenceDesire = NULL; 
    423                     EssenceDesire = m_creature->SummonCreature(23419, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); 
    424  
    425                     if(EssenceDesire) 
    426                     { 
    427                         EssenceDesire->Yell(DESI_SAY_FREED, LANG_UNIVERSAL, NULL); 
    428                         DoPlaySoundToSet(m_creature, DESI_SOUND_FREED); 
    429                         Unit* target = NULL; 
    430                         target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
    431                         if(target) 
    432                         { 
    433                             EssenceDesire->AddThreat(target, 1.0f); 
    434                             EssenceDesire->AI()->AttackStart(target); 
    435                         } 
    436                         DesireGUID = EssenceDesire->GetGUID(); 
    437                         SoulDeathCount = 0; 
    438                     } 
    439  
    440                     Phase = 4; 
    441                 }else SummonEssenceTimer -= diff; 
    442             } 
    443         } 
    444  
    445         if(Phase == 4) 
    446         { 
    447             if(DesireGUID) 
    448             { 
    449                 Creature* EssenceDesire = NULL; 
    450                 EssenceDesire = ((Creature*)Unit::GetUnit((*m_creature), DesireGUID)); 
    451  
    452                 if(!EssenceDesire || !EssenceDesire->isAlive()) 
    453                     EnterEvadeMode(); 
    454  
    455                 if(!EndingPhase && EssenceDesire) 
    456                 { 
    457                     if(EssenceDesire->GetHealth() < (EssenceDesire->GetMaxHealth()*0.1)) 
    458                     { 
    459                         MergeThreatList(EssenceDesire); 
    460                         EssenceDesire->GetMotionMaster()->MoveFollow(m_creature,0.0f,0.0f); 
    461                         EssenceDesire->RemoveAllAuras(); 
    462                         EssenceDesire->DeleteThreatList(); 
    463                         EssenceDesire->Yell(DESI_SAY_RECAP,LANG_UNIVERSAL,0); 
    464                         DoPlaySoundToSet(m_creature, DESI_SOUND_RECAP); 
    465                         EssenceDesire->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    466                         DespawnEssenceTimer = 4000; 
    467                         AnimationTimer = 2200; 
    468                         EndingPhase = true; 
    469                     } 
     333                    Counter = 1; 
     334                    Phase++; 
     335                    Timer = 5000; 
    470336                } 
    471  
    472                 if(EndingPhase && EssenceDesire) 
    473                 { 
    474                     if(EssenceDesire->isAlive()) 
    475                     { 
    476                         if(AnimationTimer < diff) 
    477                         { 
    478                             // Return 
    479                             EssenceDesire->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); 
    480                             AnimationTimer = 10000; 
    481                         }else AnimationTimer -= diff; 
    482  
    483                         if(DespawnEssenceTimer < diff) 
    484                         { 
    485                             EssenceDesire->DeleteThreatList(); 
    486                             EssenceDesire->setFaction(35); 
    487                             EssenceDesire->Yell(DESI_SAY_AFTER, LANG_UNIVERSAL, 0); 
    488                             DoPlaySoundToSet(m_creature, DESI_SOUND_AFTER); 
    489                             EssenceDesire->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686); 
    490                             m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0); 
    491                             SummonEssenceTimer = 20000; 
    492                             AnimationTimer = 18200; 
    493                             SoulDeathCount = 0; 
    494                             SoulCount = 0; 
    495                             SummonSoulTimer = 1000; 
    496                             EndingPhase = false; 
    497                             Phase = 5; 
    498                             DesireGUID = 0; 
    499                         }else DespawnEssenceTimer -= diff; 
    500                     } 
    501                 } 
    502             } 
    503         } 
    504  
    505         if(Phase == 5) 
    506         { 
    507             if(SoulCount < 36) 
    508             { 
    509                 if(SummonSoulTimer < diff) 
    510                 { 
    511                     SummonSoul(); 
    512                     SummonSoulTimer = 500; 
    513                 }else SummonSoulTimer -= diff; 
    514             } 
    515  
    516             if(SoulDeathCount >= SoulCount) 
    517             { 
    518                 if(AnimationTimer < diff) 
    519                 { 
    520                     // Release the cube 
    521                     m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); 
    522                     AnimationTimer = 10000; 
    523                 }else AnimationTimer -= diff; 
    524  
    525                 if(SummonEssenceTimer < diff) 
    526                 { 
    527                     // Ribs: open 
    528                     m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); 
    529                     Creature* EssenceAnger = NULL; 
    530                     EssenceAnger = m_creature->SummonCreature(23420, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000); 
    531  
    532                     if(EssenceAnger) 
    533                     { 
    534                         Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0); 
    535                         if(target) 
    536                         { 
    537                             EssenceAnger->AddThreat(target, 1.0f); 
    538                             EssenceAnger->AI()->AttackStart(target); 
    539                         } 
    540                         AngerGUID = EssenceAnger->GetGUID(); 
    541                         DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED); 
    542                         EssenceAnger->Yell(ANGER_SAY_FREED, LANG_UNIVERSAL, 0); 
    543                         SoulDeathCount = 0; 
    544                     } 
    545  
    546                     Phase = 6; 
    547                 }else SummonEssenceTimer -= diff; 
    548             } 
    549         } 
    550  
    551         if(Phase == 6) 
    552         { 
    553             if(AngerGUID) 
    554             { 
    555                 Creature* EssenceAnger = NULL; 
    556                 EssenceAnger = ((Creature*)Unit::GetUnit((*m_creature), AngerGUID)); 
    557  
    558                 if(!EssenceAnger) 
    559                     EnterEvadeMode(); 
    560  
    561                 if(m_creature->isAlive() && EssenceAnger) 
    562                 { 
    563                     if(!EssenceAnger->isAlive()) 
    564                     { 
    565                         AngerGUID = 0; 
    566                         m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    567                     } 
    568                 } 
    569             } 
    570         } 
     337                return; 
     338            default: 
     339                break; 
     340            } 
     341            Counter++; 
     342        }else Timer -= diff; 
    571343    } 
    572344}; 
     
    594366    uint32 EnrageTimer; 
    595367    uint32 SoulDrainTimer; 
     368    uint32 AuraTimer; 
    596369 
    597370    void Reset() 
     
    600373 
    601374        AggroYellTimer = 5000; 
    602         FixateTimer = 5000; 
     375        FixateTimer = 8000; 
    603376        EnrageTimer = 30000; 
    604         SoulDrainTimer = 150000; 
     377        SoulDrainTimer = 45000; 
     378        AuraTimer = 5000; 
    605379    } 
    606380 
    607381    void DamageTaken(Unit *done_by, uint32 &damage) 
    608382    { 
    609         if((damage >= m_creature->GetHealth()) && (done_by != m_creature)) 
     383        if(damage >= m_creature->GetHealth()) 
    610384        { 
    611385            damage = 0; 
    612             // 10% of total health, signalling time to return 
    613             m_creature->SetHealth(m_creature->GetMaxHealth()/10); 
    614             if(StatAuraGUID) 
    615             { 
    616                 Unit* pUnit = Unit::GetUnit((*m_creature), StatAuraGUID); 
    617                 if(pUnit) 
    618                     pUnit->RemoveAurasDueToSpell(AURA_OF_SUFFERING_ARMOR); 
    619             } 
     386            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     387            m_creature->Yell(SUFF_SAY_RECAP,LANG_UNIVERSAL,0); 
     388            DoPlaySoundToSet(m_creature, SUFF_SOUND_RECAP); 
    620389        } 
    621390    } 
     
    623392    void Aggro(Unit *who) 
    624393    { 
     394        m_creature->Yell(SUFF_SAY_FREED, LANG_UNIVERSAL, 0); 
     395        DoPlaySoundToSet(m_creature, SUFF_SOUND_FREED); 
    625396        DoZoneInCombat(); 
    626         DoCast(who, AURA_OF_SUFFERING, true); 
    627         DoCast(m_creature, ESSENCE_OF_SUFFERING_PASSIVE, true); 
     397        m_creature->CastSpell(m_creature, AURA_OF_SUFFERING, true); // linked aura need core support 
     398        m_creature->CastSpell(m_creature, ESSENCE_OF_SUFFERING_PASSIVE, true); 
     399        m_creature->CastSpell(m_creature, ESSENCE_OF_SUFFERING_PASSIVE2, true); 
    628400    } 
    629401 
    630402    void KilledUnit(Unit *victim) 
    631403    { 
    632         switch(rand()%3) 
    633         { 
    634             case 0: 
    635                 DoYell(SUFF_SAY_SLAY1,LANG_UNIVERSAL,NULL); 
    636                 DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY1); 
    637                 break; 
    638             case 1: 
    639                 DoYell(SUFF_SAY_SLAY2,LANG_UNIVERSAL,NULL); 
    640                 DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY2); 
    641                 break; 
    642             case 2: 
    643                 DoYell(SUFF_SAY_SLAY3,LANG_UNIVERSAL,NULL); 
    644                 DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY3); 
    645                 break; 
    646         } 
    647     } 
    648  
    649     void JustDied(Unit* killer) 
    650     { 
     404        switch(rand()%2) 
     405        { 
     406        case 0: 
     407            DoYell(SUFF_SAY_SLAY1,LANG_UNIVERSAL,NULL); 
     408            DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY1); 
     409            break; 
     410        case 1: 
     411            DoYell(SUFF_SAY_SLAY2,LANG_UNIVERSAL,NULL); 
     412            DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY2); 
     413            break; 
     414        } 
    651415    } 
    652416 
     
    655419        std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList(); 
    656420        if(m_threatlist.empty()) 
    657             return;                                         // No point continuing if empty threatlist. 
     421            return; // No point continuing if empty threatlist. 
    658422        std::list<Unit*> targets; 
    659423        std::list<HostilReference*>::iterator itr = m_threatlist.begin(); 
     
    661425        { 
    662426            Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid()); 
    663                                                             // Only alive players 
    664             if(pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER)) 
     427            if(pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER)) // Only alive players 
    665428                targets.push_back(pUnit); 
    666429        } 
    667430        if(targets.empty()) 
    668             return;                                         // No targets added for some reason. No point continuing. 
    669         targets.sort(TargetDistanceOrder(m_creature));      // Sort players by distance. 
    670         targets.resize(1);                                  // Only need closest target. 
    671         Unit* target = targets.front();                     // Get the first target. 
    672                                                             // Add threat equivalent to threat on victim. 
    673         m_creature->AddThreat(target, m_creature->getThreatManager().getThreat(m_creature->getVictim())); 
    674         DoCast(target, SPELL_FIXATE); 
     431            return; // No targets added for some reason. No point continuing. 
     432        targets.sort(TargetDistanceOrder(m_creature)); // Sort players by distance. 
     433        targets.resize(1); // Only need closest target. 
     434        Unit* target = targets.front(); // Get the first target. 
     435        target->CastSpell(m_creature, SPELL_FIXATE_TAUNT, true); 
    675436    } 
    676437 
     
    678439    { 
    679440        //Return since we have no target 
    680         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
     441        if (!m_creature->SelectHostilTarget() && !m_creature->getVictim()) 
    681442            return; 
    682  
    683         if(m_creature->GetHealth() <= (m_creature->GetMaxHealth()*0.1)) 
    684         { 
    685             if(StatAuraGUID) 
    686             { 
    687                 Unit* pUnit = NULL; 
    688                 pUnit = Unit::GetUnit((*m_creature), StatAuraGUID); 
    689                 if(pUnit) 
    690                     pUnit->RemoveAurasDueToSpell(AURA_OF_SUFFERING_ARMOR); 
    691             } 
    692         } 
    693  
    694         if(m_creature->GetHealth() <= (m_creature->GetMaxHealth()*0.1)) 
    695         { 
    696             if(m_creature->getVictim()) 
    697                 m_creature->DeleteThreatList();             // Delete our threatlist if below 10% as we should no longer attack. 
    698             return; 
    699         } 
    700  
    701         // Prevent overlapping yells 
    702         if(AggroYellTimer) 
    703             if(AggroYellTimer < diff) 
    704         { 
    705             DoYell(SUFF_SAY_AGGRO, LANG_UNIVERSAL, NULL); 
    706             DoPlaySoundToSet(m_creature, SUFF_SOUND_AGGRO); 
    707             AggroYellTimer = 0; 
    708         }else AggroYellTimer -= diff; 
    709443 
    710444        //Supposed to be cast on nearest target 
     
    713447            CastFixate(); 
    714448            FixateTimer = 5000; 
     449            if(!(rand()%16)) 
     450            { 
     451                DoYell(SUFF_SAY_AGGRO,LANG_UNIVERSAL,NULL); 
     452                DoPlaySoundToSet(m_creature, SUFF_SOUND_AGGRO); 
     453            } 
    715454        }else FixateTimer -= diff; 
    716455 
     
    719458            DoCast(m_creature, SPELL_ENRAGE); 
    720459            EnrageTimer = 60000; 
     460            DoYell(SUFF_SAY_ENRAGE,LANG_UNIVERSAL,NULL); 
     461            DoPlaySoundToSet(m_creature, SUFF_SOUND_ENRAGE); 
    721462        }else EnrageTimer -= diff; 
    722463 
    723464        if(SoulDrainTimer < diff) 
    724465        { 
    725             Unit* target = NULL; 
    726             target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
    727  
    728             if(target) 
    729                 DoCast(target, SPELL_SOUL_DRAIN); 
     466            DoCast(m_creature, SPELL_SOUL_DRAIN); 
    730467            SoulDrainTimer = 60000; 
    731468        }else SoulDrainTimer -= diff; 
     
    734471    } 
    735472}; 
     473 
    736474struct TRINITY_DLL_DECL boss_essence_of_desireAI : public ScriptedAI 
    737475{ 
    738476    boss_essence_of_desireAI(Creature *c) : ScriptedAI(c) {Reset();} 
    739477 
    740     uint32 AggroYellTimer; 
    741478    uint32 RuneShieldTimer; 
    742479    uint32 DeadenTimer; 
     
    745482    void Reset() 
    746483    { 
    747         AggroYellTimer = 5000; 
    748484        RuneShieldTimer = 60000; 
    749         DeadenTimer = 15000; 
    750         SoulShockTimer = 40000; 
     485        DeadenTimer = 30000; 
     486        SoulShockTimer = 5000; 
     487        m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_CONFUSE, true); 
    751488    } 
    752489 
    753490    void DamageTaken(Unit *done_by, uint32 &damage) 
    754491    { 
    755         if((damage >= m_creature->GetHealth()) && (done_by != m_creature)) 
     492        if(done_by == m_creature) 
     493            return; 
     494 
     495        if(damage >= m_creature->GetHealth()) 
    756496        { 
    757497            damage = 0; 
    758             // 10% of total health, signalling time to return 
    759             m_creature->SetHealth(m_creature->GetMaxHealth()/10); 
     498            m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     499            m_creature->Yell(DESI_SAY_RECAP,LANG_UNIVERSAL,0); 
     500            DoPlaySoundToSet(m_creature, DESI_SOUND_RECAP); 
    760501        } 
    761502        else 
    762503        { 
    763             if(done_by && (done_by->GetTypeId() == TYPEID_PLAYER) && done_by->isAlive()) 
    764                 done_by->DealDamage(done_by, damage/2, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    765         } 
    766     } 
    767  
    768     void Aggro(Unit *who) { DoZoneInCombat(); } 
     504            int32 bp0 = damage / 2; 
     505            m_creature->CastCustomSpell(done_by, AURA_OF_DESIRE_DAMAGE, &bp0, NULL, NULL, true); 
     506        } 
     507    } 
     508 
     509    void SpellHit(Unit *caster, const SpellEntry *spell) 
     510    { 
     511        if(m_creature->m_currentSpells[CURRENT_GENERIC_SPELL]) 
     512            for(uint8 i = 0; i < 3; ++i) 
     513                if(spell->Effect[i] == SPELL_EFFECT_INTERRUPT_CAST) 
     514                    if(m_creature->m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id == SPELL_SOUL_SHOCK  
     515                        || m_creature->m_currentSpells[CURRENT_GENERIC_SPELL]->m_spellInfo->Id == SPELL_DEADEN) 
     516                        m_creature->InterruptSpell(CURRENT_GENERIC_SPELL, false); 
     517    } 
     518 
     519    void Aggro(Unit *who) 
     520    { 
     521        m_creature->Yell(DESI_SAY_FREED, LANG_UNIVERSAL, 0); 
     522        DoPlaySoundToSet(m_creature, DESI_SOUND_FREED); 
     523        DoZoneInCombat(); 
     524        DoCast(m_creature, AURA_OF_DESIRE, true); 
     525    } 
    769526 
    770527    void KilledUnit(Unit *victim) 
     
    772529        switch(rand()%3) 
    773530        { 
    774             case 0: 
    775                 DoYell(DESI_SAY_SLAY1,LANG_UNIVERSAL,NULL); 
    776                 DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY1); 
    777                 break; 
    778             case 1: 
    779                 DoYell(DESI_SAY_SLAY2,LANG_UNIVERSAL,NULL); 
    780                 DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY2); 
    781                 break; 
    782             case 2: 
    783                 DoYell(DESI_SAY_SLAY3,LANG_UNIVERSAL,NULL); 
    784                 DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY3); 
    785                 break; 
    786         } 
    787     } 
    788  
    789     void MoveInLineOfSight(Unit *who) 
    790     { 
    791         if (!who || m_creature->getVictim()) 
     531        case 0: 
     532            DoYell(DESI_SAY_SLAY1,LANG_UNIVERSAL,NULL); 
     533            DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY1); 
     534            break; 
     535        case 1: 
     536            DoYell(DESI_SAY_SLAY2,LANG_UNIVERSAL,NULL); 
     537            DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY2); 
     538            break; 
     539        case 2: 
     540            DoYell(DESI_SAY_SLAY3,LANG_UNIVERSAL,NULL); 
     541            DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY3); 
     542            break; 
     543        } 
     544    } 
     545 
     546    void UpdateAI(const uint32 diff) 
     547    { 
     548        if (!m_creature->SelectHostilTarget() && !m_creature->getVictim()) 
    792549            return; 
    793550 
    794         if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) 
    795         { 
    796             float attackRadius = m_creature->GetAttackDistance(who); 
    797             if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) 
    798             { 
    799                 if(who->HasStealthAura()) 
    800                     who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); 
    801  
    802                 //Begin melee attack if we are within range 
    803                 DoStartAttackAndMovement(who); 
    804  
    805                 if (!InCombat) 
    806                 { 
    807                     DoCast(who, AURA_OF_DESIRE); 
    808                 } 
    809             } 
    810         } 
    811     } 
    812  
    813     void UpdateAI(const uint32 diff) 
    814     { 
    815         //Return since we have no target 
    816         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
    817             return; 
    818  
    819         if(m_creature->GetHealth() <= (m_creature->GetMaxHealth()*0.1)) 
    820         { 
    821             if(m_creature->getVictim()) 
    822                 m_creature->DeleteThreatList();             // Delete our threatlist if below 10% as we should no longer attack. 
    823             return; 
    824         } 
    825  
    826551        if(RuneShieldTimer < diff) 
    827552        { 
    828             DoCast(m_creature, SPELL_RUNE_SHIELD); 
     553            m_creature->InterruptNonMeleeSpells(false); 
     554            m_creature->CastSpell(m_creature, SPELL_RUNE_SHIELD, true); 
     555            SoulShockTimer += 2000; 
     556            DeadenTimer += 2000; 
    829557            RuneShieldTimer = 60000; 
    830558        }else RuneShieldTimer -= diff; 
    831559 
     560        if(SoulShockTimer < diff) 
     561        { 
     562            DoCast(m_creature->getVictim(), SPELL_SOUL_SHOCK); 
     563            SoulShockTimer = 5000; 
     564        }else SoulShockTimer -= diff; 
     565 
    832566        if(DeadenTimer < diff) 
    833567        { 
     568            m_creature->InterruptNonMeleeSpells(false); 
    834569            DoCast(m_creature->getVictim(), SPELL_DEADEN); 
    835             DeadenTimer = 30000 + rand()%30001; 
    836         }else DeadenTimer -= diff; 
    837  
    838         if(SoulShockTimer < diff) 
    839         { 
    840             DoCast(m_creature->getVictim(), SPELL_SOUL_SHOCK); 
    841             SoulShockTimer = 40000; 
    842             if(rand()%2 == 0) 
     570            DeadenTimer = 25000 + rand()%10000; 
     571            if(!(rand()%2)) 
    843572            { 
    844573                DoYell(DESI_SAY_SPEC,LANG_UNIVERSAL,NULL); 
    845574                DoPlaySoundToSet(m_creature, DESI_SOUND_SPEC); 
    846575            } 
    847  
    848         }else SoulShockTimer -= diff; 
     576        }else DeadenTimer -= diff; 
    849577 
    850578        DoMeleeAttackIfReady(); 
     
    858586    uint64 AggroTargetGUID; 
    859587 
    860     uint32 AggroYellTimer; 
    861588    uint32 CheckTankTimer; 
    862589    uint32 SoulScreamTimer; 
    863590    uint32 SpiteTimer; 
    864591 
     592    std::list<uint64> SpiteTargetGUID; 
     593 
    865594    bool CheckedAggro; 
    866595 
     
    869598        AggroTargetGUID = 0; 
    870599 
    871         AggroYellTimer = 5000; 
    872600        CheckTankTimer = 5000; 
    873601        SoulScreamTimer = 10000; 
    874602        SpiteTimer = 30000; 
    875603 
     604        SpiteTargetGUID.clear(); 
     605 
    876606        CheckedAggro = false; 
    877607    } 
     
    879609    void Aggro(Unit *who) 
    880610    { 
     611        m_creature->Yell(ANGER_SAY_FREED, LANG_UNIVERSAL, 0); 
     612        DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED); 
    881613        DoZoneInCombat(); 
    882         DoCast(m_creature->getVictim(), AURA_OF_ANGER, true); 
    883     } 
    884  
    885     void MoveInLineOfSight(Unit *who) 
    886     { 
    887         if (!who || m_creature->getVictim()) 
    888             return; 
    889  
    890         if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) 
    891         { 
    892             float attackRadius = m_creature->GetAttackDistance(who); 
    893             if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) 
    894             { 
    895                 if(who->HasStealthAura()) 
    896                     who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); 
    897  
    898                 //Begin melee attack if we are within range 
    899                 DoStartAttackAndMovement(who); 
    900  
    901                 if (!InCombat) 
    902                 { 
    903                     DoCast(who, AURA_OF_ANGER); 
    904                 } 
    905             } 
    906         } 
     614        DoCast(m_creature, AURA_OF_ANGER, true); 
    907615    } 
    908616 
     
    917625        switch(rand()%2) 
    918626        { 
    919             case 0: 
    920                 DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY1); 
    921                 break; 
    922             case 1: 
    923                 DoYell(ANGER_SAY_SLAY2,LANG_UNIVERSAL,NULL); 
    924                 DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY2); 
    925                 break; 
    926         } 
     627        case 0: 
     628            DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY1); 
     629            break; 
     630        case 1: 
     631            DoYell(ANGER_SAY_SLAY2,LANG_UNIVERSAL,NULL); 
     632            DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY2); 
     633            break; 
     634        } 
     635    } 
     636 
     637    void SelectSpiteTarget(uint32 num, float max_range = 999) 
     638    { 
     639        if(!num) return; 
     640 
     641        CellPair p(Trinity::ComputeCellPair(m_creature->GetPositionX(), m_creature->GetPositionY())); 
     642        Cell cell(p); 
     643        cell.data.Part.reserved = ALL_DISTRICT; 
     644        cell.SetNoCreate(); 
     645 
     646        std::list<Unit *> tempUnitMap; 
     647 
     648        { 
     649            Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(m_creature, m_creature, max_range); 
     650            Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(tempUnitMap, u_check); 
     651 
     652            TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); 
     653            TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer >  grid_unit_searcher(searcher); 
     654 
     655            CellLock<GridReadGuard> cell_lock(cell, p); 
     656            cell_lock->Visit(cell_lock, world_unit_searcher, *(m_creature->GetMap())); 
     657            cell_lock->Visit(cell_lock, grid_unit_searcher, *(m_creature->GetMap())); 
     658        } 
     659 
     660        std::list<Unit*>::iterator itr; 
     661        while(tempUnitMap.size() && SpiteTargetGUID.size() < num) 
     662        { 
     663            itr = tempUnitMap.begin(); 
     664            advance(itr, rand()%tempUnitMap.size()); 
     665            SpiteTargetGUID.push_back((*itr)->GetGUID()); 
     666            tempUnitMap.erase(itr); 
     667        } 
     668 
     669        for(itr = tempUnitMap.begin(); itr != tempUnitMap.end(); ++itr) 
     670            (*itr)->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     671        m_creature->CastSpell(m_creature, SPELL_SPITE_TARGET, true); // must true 
     672        for(itr = tempUnitMap.begin(); itr != tempUnitMap.end(); ++itr) 
     673            (*itr)->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    927674    } 
    928675 
     
    930677    { 
    931678        //Return since we have no target 
    932         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
     679        if (!m_creature->SelectHostilTarget() && !m_creature->getVictim()) 
    933680            return; 
    934681 
     
    939686        } 
    940687 
    941         if(AggroYellTimer) 
    942             if(AggroYellTimer < diff) 
    943         { 
    944             DoYell(ANGER_SAY_FREED2,LANG_UNIVERSAL,NULL); 
    945             DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED2); 
    946             AggroYellTimer = 0; 
    947         }else AggroYellTimer -= diff; 
    948  
    949688        if(CheckTankTimer < diff) 
    950689        { 
    951690            if(m_creature->getVictim()->GetGUID() != AggroTargetGUID) 
    952             { 
     691            {      
    953692                DoYell(ANGER_SAY_BEFORE,LANG_UNIVERSAL,NULL); 
    954693                DoPlaySoundToSet(m_creature, ANGER_SOUND_BEFORE); 
    955                 DoCast(m_creature, SPELL_SELF_SEETHE); 
    956                 DoCast(m_creature->getVictim(), SPELL_ENEMY_SEETHE, true); 
     694                DoCast(m_creature, SPELL_SELF_SEETHE, true); 
    957695                AggroTargetGUID = m_creature->getVictim()->GetGUID(); 
    958696            } 
     
    964702            DoCast(m_creature->getVictim(), SPELL_SOUL_SCREAM); 
    965703            SoulScreamTimer = 10000; 
     704            if(!(rand()%3)) 
     705            { 
     706                DoYell(ANGER_SAY_SCREAM,LANG_UNIVERSAL,NULL); 
     707                DoPlaySoundToSet(m_creature, ANGER_SOUND_SCREAM); 
     708            } 
    966709        }else SoulScreamTimer -= diff; 
    967710 
    968711        if(SpiteTimer < diff) 
    969712        { 
    970             for(uint8 i = 0; i < 4; i++) 
     713            if(!SpiteTargetGUID.empty()) 
    971714            { 
    972                 Unit* target = NULL; 
    973                 target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
    974  
    975                 if(target) 
    976                     DoCast(target, SPELL_SPITE); 
    977  
    978             } 
    979  
    980             SpiteTimer = 30000; 
    981             DoYell(ANGER_SAY_SPEC,LANG_UNIVERSAL,NULL); 
    982             DoPlaySoundToSet(m_creature, ANGER_SOUND_SPEC); 
     715                for (std::list<uint64>::iterator itr = SpiteTargetGUID.begin(); itr != SpiteTargetGUID.end(); ++itr) 
     716                { 
     717                    if(Unit* target = Unit::GetUnit(*m_creature, *itr)) 
     718                    { 
     719                        target->RemoveAurasDueToSpell(SPELL_SPITE_TARGET); 
     720                        m_creature->CastSpell(target, SPELL_SPITE_DAMAGE, true); 
     721                    } 
     722                } 
     723                SpiteTargetGUID.clear(); 
     724                SpiteTimer = 24000; 
     725            } 
     726            else 
     727            { 
     728                SelectSpiteTarget(3); 
     729                SpiteTimer = 6000; 
     730                DoYell(ANGER_SAY_SPEC,LANG_UNIVERSAL,NULL); 
     731                DoPlaySoundToSet(m_creature, ANGER_SOUND_SPEC); 
     732            } 
    983733        }else SpiteTimer -= diff; 
    984734 
     
    995745            ((boss_reliquary_of_soulsAI*)Reliquary->AI())->SoulDeathCount++; 
    996746    } 
     747    DoCast(m_creature, SPELL_SOUL_RELEASE, true); 
    997748} 
    998749 
  • trunk/src/bindings/scripts/scripts/zone/black_temple/boss_supremus.cpp

    r48 r57  
    117117        FireballTimer = 500; 
    118118        GeyserTimer = 0; 
     119        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); 
     120        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    119121    } 
    120122 
     
    122124    void AttackStart(Unit* who) {} 
    123125    void MoveInLineOfSight(Unit* who) {} 
    124     void SetSupremusGUID(uint64 guid) { SupremusGUID = guid; } 
    125126 
    126127    void UpdateAI(const uint32 diff) 
    127128    { 
    128         if(CheckTimer < diff) 
    129         { 
    130             if(SupremusGUID) 
    131             { 
    132                 Unit* Supremus = NULL; 
    133                 Supremus = Unit::GetUnit((*m_creature), SupremusGUID); 
    134                 if(Supremus && (!Supremus->isAlive())) 
    135                     m_creature->DealDamage(m_creature, m_creature->GetHealth(), 0, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    136             } 
    137             CheckTimer = 2000; 
    138         }else CheckTimer -= diff; 
    139  
    140129        if(GeyserTimer < diff) 
    141130        { 
     
    143132            GeyserTimer = 18000; 
    144133        }else GeyserTimer -= diff; 
     134 
     135        if(FireballTimer < diff) 
     136        { 
     137            DoCast(m_creature, SPELL_VOLCANIC_FIREBALL, true); 
     138            FireballTimer = 1000; 
     139        }else FireballTimer -= diff; 
    145140    } 
    146141}; 
     
    272267            if(BerserkTimer < diff) 
    273268                DoCast(m_creature, SPELL_BERSERK); 
    274         else BerserkTimer -= diff; 
     269            else BerserkTimer -= diff; 
    275270 
    276271        if(SummonFlameTimer < diff) 
     
    333328                if(target) 
    334329                { 
    335                     Creature* Volcano = NULL; 
    336                     Volcano = SummonCreature(CREATURE_VOLCANO, target); 
    337  
    338                     if(Volcano) 
    339                     { 
    340                         DoCast(target, SPELL_VOLCANIC_ERUPTION); 
    341                         ((npc_volcanoAI*)Volcano->AI())->SetSupremusGUID(m_creature->GetGUID()); 
    342                     } 
    343  
     330                    DoCast(target, SPELL_VOLCANIC_ERUPTION); 
    344331                    DoTextEmote("roars and the ground begins to crack open!", NULL); 
    345332                    SummonVolcanoTimer = 10000; 
     
    356343                PhaseSwitchTimer = 60000; 
    357344                m_creature->SetSpeed(MOVE_RUN, 1.0f); 
     345                DoZoneInCombat(); 
    358346            } 
    359347            else 
     
    365353                PhaseSwitchTimer = 60000; 
    366354                m_creature->SetSpeed(MOVE_RUN, 0.9f); 
     355                DoZoneInCombat(); 
    367356            } 
    368357        }else PhaseSwitchTimer -= diff; 
  • trunk/src/bindings/scripts/scripts/zone/black_temple/boss_warlord_najentus.cpp

    r48 r57  
    1717/* ScriptData 
    1818SDName: Boss_Warlord_Najentus 
    19 SD%Complete: 90 
    20 SDComment: Using a creature workaround instead of a GO for Impaling Spine. 
     19SD%Complete: 95 
     20SDComment: 
    2121SDCategory: Black Temple 
    2222EndScriptData */ 
     
    5959 
    6060//Spells 
    61 #define SPELL_CRASHINGWAVE             40100 
    6261#define SPELL_NEEDLE_SPINE             39835 
    6362#define SPELL_NEEDLE_AOE               39968 
    6463#define SPELL_TIDAL_BURST              39878 
    65 #define SPELL_TIDAL_SHIELD             39872                // Not going to use this since Hurl Spine doesn't dispel it. 
     64#define SPELL_TIDAL_SHIELD             39872 
    6665#define SPELL_IMPALING_SPINE           39837 
    6766#define SPELL_CREATE_NAJENTUS_SPINE    39956 
    6867#define SPELL_HURL_SPINE               39948 
    69 #define SPELL_SHIELD_VISUAL            37136 
    7068#define SPELL_BERSERK                  45078 
    7169 
    72 #define DISPLAYID_SPINE         7362 
    73  
    74 struct TRINITY_DLL_DECL mob_najentus_spineAI : public ScriptedAI 
    75 { 
    76     mob_najentus_spineAI(Creature *c) : ScriptedAI(c) 
    77     { 
    78         Reset(); 
    79     } 
    80  
    81     uint64 SpineVictimGUID; 
    82  
    83     void Reset() {  SpineVictimGUID = 0; } 
    84  
    85     void SetSpineVictimGUID(uint64 guid){ SpineVictimGUID = guid; } 
    86  
    87     void JustDied(Unit *killer) 
    88     { 
    89         // Make the killer have the Najentus Spine item to pierce Tidal Shield 
    90         if(killer) 
    91             killer->CastSpell(killer, SPELL_CREATE_NAJENTUS_SPINE, true); 
    92     } 
    93  
    94     void DamageTaken(Unit *done_by, uint32 &damage) 
    95     { 
    96         if(damage < m_creature->GetHealth()) return; 
    97  
    98         // Remove the Impaling Spine DoT from whoever was affected 
    99         if(SpineVictimGUID) 
    100         { 
    101             Unit* victim = Unit::GetUnit((*m_creature), SpineVictimGUID); 
    102             if(victim && ((victim->HasAura(SPELL_IMPALING_SPINE, 0)) || (victim->HasAura(SPELL_IMPALING_SPINE, 1)) || (victim->HasAura(SPELL_IMPALING_SPINE, 2)))) 
    103                 victim->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE); 
    104         } 
    105     } 
    106  
    107     void Aggro(Unit* who) {} 
    108     void AttackStart(Unit* who) {} 
    109     void MoveInLineOfSight(Unit* who) {} 
    110     void UpdateAI(const uint32 diff) {} 
    111 }; 
     70#define GOBJECT_SPINE                  185584 
    11271 
    11372struct TRINITY_DLL_DECL boss_najentusAI : public ScriptedAI 
    11473{ 
    115     boss_najentusAI(Creature *c) : ScriptedAI(c) 
     74    boss_najentusAI(Creature *c) : ScriptedAI(c)  
    11675    { 
    11776        pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     
    12079 
    12180    ScriptedInstance* pInstance; 
    122     uint32 CrashingWaveTimer; 
     81 
    12382    uint32 NeedleSpineTimer; 
    12483    uint32 EnrageTimer; 
     
    12685    uint32 TidalShieldTimer; 
    12786    uint32 ImpalingSpineTimer; 
    128     uint32 CheckTimer;                                      // This timer checks if Najentus is Tidal Shielded and if so, regens health. If not, sets IsShielded to false 
    129     uint32 DispelShieldTimer;                               // This shield is only supposed to last 30 seconds, but the SPELL_SHIELD_VISUAL lasts forever 
    13087 
    13188    uint64 SpineTargetGUID; 
    132     uint64 SpineGUID; 
    133  
    134     bool IsShielded; 
    13589 
    13690    void Reset() 
    13791    { 
    138         IsShielded = false; 
    139  
    140         CrashingWaveTimer = 28000; 
    141         NeedleSpineTimer = 10000; 
    14292        EnrageTimer = 480000; 
    14393        SpecialYellTimer = 45000 + (rand()%76)*1000; 
    144         TidalShieldTimer = 60000; 
    145         ImpalingSpineTimer = 45000; 
    146         CheckTimer = 2000; 
    147         DispelShieldTimer = 30000; 
     94 
     95        ResetTimer(); 
    14896 
    14997        SpineTargetGUID = 0; 
    150         SpineGUID = 0; 
    15198 
    15299        if(pInstance) 
    153         { 
    154             if(m_creature->isAlive()) 
    155             { 
    156                 pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, NOT_STARTED); 
    157                 ToggleGate(true); 
    158             } 
    159             else  ToggleGate(false); 
     100            pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, NOT_STARTED); 
     101    } 
     102 
     103    void KilledUnit(Unit *victim) 
     104    { 
     105        switch(rand()%2) 
     106        { 
     107        case 0: 
     108            DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL); 
     109            DoPlaySoundToSet(m_creature, SOUND_SLAY1); 
     110            break; 
     111        case 1: 
     112            DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL); 
     113            DoPlaySoundToSet(m_creature, SOUND_SLAY2); 
     114            break; 
    160115        } 
    161116    } 
    162117 
    163     void KilledUnit(Unit *victim) 
    164     { 
    165         switch(rand()%2) 
    166         { 
    167             case 0: 
    168                 DoYell(SAY_SLAY1,LANG_UNIVERSAL,NULL); 
    169                 DoPlaySoundToSet(m_creature, SOUND_SLAY1); 
    170                 break; 
    171             case 1: 
    172                 DoYell(SAY_SLAY2,LANG_UNIVERSAL,NULL); 
    173                 DoPlaySoundToSet(m_creature, SOUND_SLAY2); 
    174                 break; 
    175         } 
    176     } 
    177  
    178118    void JustDied(Unit *victim) 
    179119    { 
    180120        if(pInstance) 
    181         { 
    182121            pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, DONE); 
    183             ToggleGate(false); 
    184         } 
    185122 
    186123        DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL); 
     
    188125    } 
    189126 
    190     void ToggleGate(bool close) 
    191     { 
    192         if(GameObject* Gate = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_GAMEOBJECT_NAJENTUS_GATE))) 
    193             if(close)   Gate->SetGoState(0);                // Closed 
    194         else        Gate->SetGoState(2);                    // Opened 
    195     } 
    196  
    197127    void SpellHit(Unit *caster, const SpellEntry *spell) 
    198128    { 
    199         if(IsShielded) 
    200         { 
    201             if(spell->Id == SPELL_HURL_SPINE) 
    202             { 
    203                 if(m_creature->HasAura(SPELL_SHIELD_VISUAL, 0)) 
    204                     m_creature->RemoveAurasDueToSpell(SPELL_SHIELD_VISUAL); 
    205                 if(m_creature->HasAura(SPELL_TIDAL_SHIELD, 0)) 
    206                     m_creature->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD); 
    207                 DoCast(m_creature->getVictim(), SPELL_TIDAL_BURST); 
    208                 IsShielded = false; 
    209             } 
     129        if(spell->Id == SPELL_HURL_SPINE && m_creature->HasAura(SPELL_TIDAL_SHIELD, 0)) 
     130        { 
     131            m_creature->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD); 
     132            m_creature->CastSpell(m_creature, SPELL_TIDAL_BURST, true); 
     133            ResetTimer(); 
    210134        } 
    211     } 
    212  
    213     void DamageTaken(Unit *done_by, uint32 &damage) 
    214     { 
    215         if(IsShielded) 
    216             damage = 0; 
    217135    } 
    218136 
     
    224142        DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL); 
    225143        DoPlaySoundToSet(m_creature, SOUND_AGGRO); 
    226  
    227144        DoZoneInCombat(); 
    228145    } 
    229146 
    230     // This is a workaround since we cannot summon GameObjects at will. 
    231     // Instead, we create a custom creature on top of the player. 
    232     // When someone kills the creature, the killer gets the "Naj'entus Spine" item. 
    233     // This item is the only item that should be able to pierce Tidal Shield 
    234     void DoImpalingSpineWorkaround(Unit* target) 
    235     { 
    236         Creature* Spine = NULL; 
    237         Spine = m_creature->SummonCreature(500000, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_DEAD_DESPAWN, 10000); 
    238         if(Spine) 
    239         { 
    240             Spine->setFaction(m_creature->getFaction()); 
    241             ((mob_najentus_spineAI*)Spine->AI())->SetSpineVictimGUID(target->GetGUID()); 
    242             SpineTargetGUID = target->GetGUID(); 
    243         } 
    244     } 
    245  
    246     bool RemoveImpalingSpine(uint64 guid) 
    247     { 
    248         if(!IsShielded || guid == SpineTargetGUID) return false; 
    249  
    250         if(SpineTargetGUID) 
    251         { 
    252             Unit* target = Unit::GetUnit((*m_creature), SpineTargetGUID); 
    253             if(target && target->HasAura(SPELL_IMPALING_SPINE, 0)) 
    254             { 
    255                 target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE); 
    256                 return true; 
    257             } 
    258         } 
    259  
    260         return false; 
     147    bool RemoveImpalingSpine() 
     148    { 
     149        if(!SpineTargetGUID) return false; 
     150        Unit* target = Unit::GetUnit(*m_creature, SpineTargetGUID); 
     151        if(target && target->HasAura(SPELL_IMPALING_SPINE, 1)) 
     152            target->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE); 
     153        SpineTargetGUID=0; 
     154        return true; 
     155    } 
     156 
     157    void ResetTimer(uint32 inc = 0) 
     158    { 
     159        NeedleSpineTimer = 10000 + inc; 
     160        TidalShieldTimer = 60000 + inc; 
     161        ImpalingSpineTimer = 20000 + inc; 
    261162    } 
    262163 
    263164    void UpdateAI(const uint32 diff) 
    264165    { 
    265         //Return since we have no target 
    266166        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
    267167            return; 
    268168 
    269         if(CheckTimer < diff) 
    270         { 
    271             // if(m_creature->HasAura(SPELL_TIDAL_SHIELD, 0)) 
    272             if(m_creature->HasAura(SPELL_SHIELD_VISUAL, 0)) 
    273                 m_creature->SetHealth(m_creature->GetHealth() + (m_creature->GetMaxHealth()/100)); 
    274             else 
    275                 IsShielded = false; 
    276  
    277             CheckTimer = 2000; 
    278         }else CheckTimer -= diff; 
    279  
    280         if(IsShielded) 
    281         { 
    282             m_creature->GetMotionMaster()->Clear(false); 
    283             m_creature->GetMotionMaster()->MoveIdle(); 
    284             if(!m_creature->HasAura(SPELL_SHIELD_VISUAL, 0)) 
    285                 DoCast(m_creature, SPELL_SHIELD_VISUAL); 
    286             if(DispelShieldTimer < diff) 
    287             { 
    288                 m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); 
    289                 if(m_creature->HasAura(SPELL_SHIELD_VISUAL, 0)) 
    290                     m_creature->RemoveAurasDueToSpell(SPELL_SHIELD_VISUAL); 
    291                 IsShielded = false; 
    292             }else DispelShieldTimer -= diff; 
    293  
    294             return;                                         // Don't cast or do anything while Shielded 
    295         } 
    296  
    297         // Crashing Wave 
    298         if(CrashingWaveTimer < diff) 
    299         { 
    300             DoCast(m_creature->getVictim(), SPELL_CRASHINGWAVE); 
    301             CrashingWaveTimer = 28500; 
    302         }else CrashingWaveTimer -= diff; 
    303  
    304         if(!m_creature->HasAura(SPELL_BERSERK, 0)) 
    305             if(EnrageTimer < diff) 
     169        if(TidalShieldTimer < diff) 
     170        { 
     171            m_creature->InterruptNonMeleeSpells(false); 
     172            DoCast(m_creature, SPELL_TIDAL_SHIELD, true); 
     173            ResetTimer(45000); 
     174        }else TidalShieldTimer -= diff; 
     175 
     176        if(EnrageTimer < diff) 
    306177        { 
    307178            DoYell(SAY_ENRAGE, LANG_UNIVERSAL, NULL); 
    308179            DoPlaySoundToSet(m_creature, SOUND_ENRAGE); 
    309             DoCast(m_creature, SPELL_BERSERK); 
     180            m_creature->CastSpell(m_creature, SPELL_BERSERK, true); 
     181            EnrageTimer = 600000; 
    310182        }else EnrageTimer -= diff; 
    311183 
     
    316188            { 
    317189                Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1); 
    318                 if(!target) 
    319                     target = m_creature->getVictim(); 
    320  
    321                 DoCast(target, SPELL_NEEDLE_AOE, true); 
    322                 DoCast(target, SPELL_NEEDLE_SPINE); 
    323             } 
    324  
    325             NeedleSpineTimer = 60000; 
     190                if(!target) target = m_creature->getVictim(); 
     191                m_creature->CastSpell(target, SPELL_NEEDLE_SPINE, true); 
     192            } 
     193            m_creature->SetInFront(m_creature->getVictim()); 
     194            NeedleSpineTimer = 30000; 
    326195        }else NeedleSpineTimer -= diff; 
    327196 
     
    330199            switch(rand()%2) 
    331200            { 
    332                 case 0: 
    333                     DoPlaySoundToSet(m_creature, SOUND_SPECIAL1); 
    334                     break; 
    335                 case 1: 
    336                     DoYell(SAY_SPECIAL2, LANG_UNIVERSAL, NULL); 
    337                     DoPlaySoundToSet(m_creature, SOUND_SPECIAL2); 
    338                     break; 
     201            case 0: 
     202                DoPlaySoundToSet(m_creature, SOUND_SPECIAL1); 
     203                break; 
     204            case 1: 
     205                DoYell(SAY_SPECIAL2, LANG_UNIVERSAL, NULL); 
     206                DoPlaySoundToSet(m_creature, SOUND_SPECIAL2); 
     207                break; 
    339208            } 
    340209            SpecialYellTimer = 25000 + (rand()%76)*1000; 
     
    344213        { 
    345214            Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1); 
    346             if(!target) 
    347                 target = m_creature->getVictim(); 
    348  
    349             if(target && (target->GetTypeId() == TYPEID_PLAYER)) 
    350             { 
    351                 DoCast(target, SPELL_IMPALING_SPINE); 
    352                 //DoImpalingSpineWorkaround(target); 
    353                 SpineTargetGUID = target->GetGUID(); 
    354                 ImpalingSpineTimer = 45000; 
    355  
    356                 switch(rand()%2) 
    357                 { 
    358                     case 0: 
    359                         DoYell(SAY_NEEDLE1, LANG_UNIVERSAL, NULL); 
    360                         DoPlaySoundToSet(m_creature, SOUND_NEEDLE1); 
    361                         break; 
    362                     case 1: 
    363                         DoYell(SAY_NEEDLE2, LANG_UNIVERSAL, NULL); 
    364                         DoPlaySoundToSet(m_creature, SOUND_NEEDLE2); 
    365                         break; 
    366                 } 
    367             } 
     215            if(!target) target = m_creature->getVictim(); 
     216            m_creature->CastSpell(target, SPELL_IMPALING_SPINE, true); 
     217            m_creature->SetInFront(m_creature->getVictim()); 
     218            SpineTargetGUID = target->GetGUID(); 
     219            m_creature->SummonGameObject(GOBJECT_SPINE, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), m_creature->GetOrientation(), 0, 0, 0, 0, 30); 
     220 
     221            switch(rand()%2) 
     222            { 
     223            case 0: 
     224                DoYell(SAY_NEEDLE1, LANG_UNIVERSAL, NULL); 
     225                DoPlaySoundToSet(m_creature, SOUND_NEEDLE1); 
     226                break; 
     227            case 1: 
     228                DoYell(SAY_NEEDLE2, LANG_UNIVERSAL, NULL); 
     229                DoPlaySoundToSet(m_creature, SOUND_NEEDLE2); 
     230                break; 
     231            } 
     232            ImpalingSpineTimer = 21000; 
    368233        }else ImpalingSpineTimer -= diff; 
    369234 
    370         if(TidalShieldTimer < diff) 
    371         { 
    372             m_creature->InterruptNonMeleeSpells(false); 
    373             DoCast(m_creature, SPELL_SHIELD_VISUAL, true); 
    374             // DoCast(m_creature, SPELL_TIDAL_SHIELD); 
    375             m_creature->GetMotionMaster()->Clear(false); 
    376             m_creature->GetMotionMaster()->MoveIdle(); 
    377             IsShielded = true; 
    378             TidalShieldTimer = 60000; 
    379             CheckTimer = 2000; 
    380             DispelShieldTimer = 30000; 
    381         }else TidalShieldTimer -= diff; 
    382  
    383235        DoMeleeAttackIfReady(); 
    384236    } 
     
    387239bool GOHello_go_najentus_spine(Player *player, GameObject* _GO) 
    388240{ 
    389     ScriptedInstance* pInstance = ((ScriptedInstance*)_GO->GetInstanceData()); 
    390     if(pInstance) 
    391     { 
    392         uint64 NajentusGUID = pInstance->GetData64(DATA_HIGHWARLORDNAJENTUS); 
    393         if(NajentusGUID) 
    394         { 
    395             Creature* Najentus = ((Creature*)Unit::GetUnit((*_GO), NajentusGUID)); 
    396             if(Najentus) 
    397             { 
    398                 if(((boss_najentusAI*)Najentus->AI())->RemoveImpalingSpine(player->GetGUID())) 
    399                     return true; 
    400             }else error_log("ERROR: Na'entus Spine GameObject unable to find Naj'entus"); 
    401         }else error_log("ERROR: Invalid GUID acquired for Naj'entus by Naj'entus Spine GameObject"); 
    402     } 
    403     else error_log("ERROR: Naj'entus Spine spawned in invalid instance or location"); 
    404  
     241    if(ScriptedInstance* pInstance = (ScriptedInstance*)_GO->GetInstanceData()) 
     242        if(Creature* Najentus = (Creature*)Unit::GetUnit(*_GO, pInstance->GetData64(DATA_HIGHWARLORDNAJENTUS))) 
     243            if(((boss_najentusAI*)Najentus->AI())->RemoveImpalingSpine()) 
     244            { 
     245                player->CastSpell(player, SPELL_CREATE_NAJENTUS_SPINE, true); 
     246                _GO->SetLootState(GO_NOT_READY); 
     247                _GO->SetRespawnTime(0); 
     248            } 
    405249    return true; 
    406 } 
    407  
    408 CreatureAI* GetAI_mob_najentus_spine(Creature *_Creature) 
    409 { 
    410     return new mob_najentus_spineAI (_Creature); 
    411250} 
    412251 
     
    425264 
    426265    newscript = new Script; 
    427     newscript->Name = "mob_najentus_spine"; 
    428     newscript->GetAI = GetAI_mob_najentus_spine; 
    429     m_scripts[nrscripts++] = newscript; 
    430  
    431     newscript = new Script; 
    432266    newscript->Name = "go_najentus_spine"; 
    433267    newscript->pGOHello = &GOHello_go_najentus_spine; 
  • trunk/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp

    r48 r57  
    127127            case 185905:                                    // Gate leading to Temple Summit 
    128128                IllidanGate = go->GetGUID(); 
     129                go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND); 
    129130                break; 
    130131            case 186261:                                    // Right door at Temple Summit 
    131132                IllidanDoor[0] = go->GetGUID(); 
     133                go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND); 
    132134                break; 
    133135            case 186262:                                    // Left door at Temple Summit 
    134136                IllidanDoor[1] = go->GetGUID(); 
     137                go->SetUInt32Value(GAMEOBJECT_FLAGS,GO_FLAG_NODESPAWN+GO_FLAG_INTERACT_COND); 
    135138                break; 
    136139        } 
  • trunk/src/bindings/scripts/scripts/zone/karazhan/boss_maiden_of_virtue.cpp

    r48 r57  
    2828#define SPELL_HOLYWRATH         32445 
    2929#define SPELL_HOLYGROUND        29512 
     30#define SPELL_BERSERK           26662 
    3031 
    3132#define SAY_AGGRO               "Your behavior will not be tolerated!" 
     
    5354    uint32 Holywrath_Timer; 
    5455    uint32 Holyground_Timer; 
     56    uint32 Enrage_Timer; 
     57 
     58    bool Enraged; 
    5559 
    5660    void Reset() 
     
    6064        Holywrath_Timer     = 20000+(rand()%10000); 
    6165        Holyground_Timer    = 3000; 
     66        Enrage_Timer        = 600000; 
     67 
     68        Enraged = false; 
     69 
     70        m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); 
     71        m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); 
    6272    } 
    6373 
     
    6878        switch(rand()%3) 
    6979        { 
    70             case 0: 
    71                 DoYell(SAY_SLAY1,LANG_UNIVERSAL,Victim); 
    72                 DoPlaySoundToSet(m_creature, SOUND_SLAY1); 
    73                 break; 
    74             case 1: 
    75                 DoYell(SAY_SLAY2,LANG_UNIVERSAL,Victim); 
    76                 DoPlaySoundToSet(m_creature, SOUND_SLAY2); 
    77                 break; 
    78             case 2: 
    79                 DoYell(SAY_SLAY3,LANG_UNIVERSAL,Victim); 
    80                 DoPlaySoundToSet(m_creature, SOUND_SLAY3); 
    81                 break; 
     80        case 0: 
     81            DoYell(SAY_SLAY1,LANG_UNIVERSAL,Victim); 
     82            DoPlaySoundToSet(m_creature, SOUND_SLAY1); 
     83            break; 
     84        case 1: 
     85            DoYell(SAY_SLAY2,LANG_UNIVERSAL,Victim); 
     86            DoPlaySoundToSet(m_creature, SOUND_SLAY2); 
     87            break; 
     88        case 2: 
     89            DoYell(SAY_SLAY3,LANG_UNIVERSAL,Victim); 
     90            DoPlaySoundToSet(m_creature, SOUND_SLAY3); 
     91            break; 
    8292        } 
    8393    } 
     
    100110            return; 
    101111 
     112        if (Enrage_Timer < diff && !Enraged) 
     113        { 
     114            DoCast(m_creature, SPELL_BERSERK,true); 
     115            Enraged = true; 
     116        }else Enrage_Timer -=diff; 
     117 
    102118        if (Holyground_Timer < diff) 
    103119        { 
     
    112128            switch(rand()%2) 
    113129            { 
    114                 case 0: 
    115                     DoYell(SAY_REPENTANCE1,LANG_UNIVERSAL,NULL); 
    116                     DoPlaySoundToSet(m_creature, SOUND_REPENTANCE1); 
    117                     break; 
    118                 case 1: 
    119                     DoYell(SAY_REPENTANCE2,LANG_UNIVERSAL,NULL); 
    120                     DoPlaySoundToSet(m_creature, SOUND_REPENTANCE2); 
    121                     break; 
     130            case 0: 
     131                DoYell(SAY_REPENTANCE1,LANG_UNIVERSAL,NULL); 
     132                DoPlaySoundToSet(m_creature, SOUND_REPENTANCE1); 
     133                break; 
     134            case 1: 
     135                DoYell(SAY_REPENTANCE2,LANG_UNIVERSAL,NULL); 
     136                DoPlaySoundToSet(m_creature, SOUND_REPENTANCE2); 
     137                break; 
    122138            } 
    123139            Repentance_Timer = 30000 + rand()%15000;        //A little randomness on that spell 
     
    126142        if (Holyfire_Timer < diff) 
    127143        { 
    128             //Time for an omgwtfpwn code to make maiden cast holy fire only on units outside the holy ground's 18 yard range 
    129144            Unit* target = NULL; 
    130             std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList(); 
    131             std::vector<Unit *> target_list; 
    132             for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) 
     145            target = SelectUnit(SELECT_TARGET_RANDOM,0);             
     146 
     147            if(target) 
    133148            { 
    134                 target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); 
    135                 if(target && target->GetDistance2d(m_creature) > 12 ) 
    136                     target_list.push_back(target); 
    137                 target = NULL; 
     149                DoCast(target,SPELL_HOLYFIRE); 
     150                Holyfire_Timer = 8000 + rand()%17000; //Anywhere from 8 to 25 seconds, good luck having several of those in a row! 
    138151            } 
    139             if(target_list.size()) 
    140                 target = *(target_list.begin()+rand()%target_list.size()); 
    141  
    142             DoCast(target,SPELL_HOLYFIRE); 
    143  
    144             Holyfire_Timer = 8000 + rand()%17000;           //Anywhere from 8 to 25 seconds, good luck having several of those in a row! 
    145152        }else Holyfire_Timer -= diff; 
    146153 
  • trunk/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_void_reaver.cpp

    r48 r57  
    2626 
    2727#define SPELL_POUNDING              34162 
    28 #define SPELL_ARCANE_ORB_TRIGGER    34172 
     28#define SPELL_ARCANE_ORB            34172 
    2929#define SPELL_KNOCK_AWAY            11130 
    3030#define SPELL_BERSERK               27680 
     
    4646#define SOUND_POUNDING2         11219 
    4747 
    48 #define CREATURE_ORB_TARGET     19577 
    49  
    5048struct TRINITY_DLL_DECL boss_void_reaverAI : public ScriptedAI 
    5149{ 
     
    6563    void Reset() 
    6664    { 
     65        m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); 
     66        m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, true); 
     67 
    6768        Pounding_Timer = 12000; 
    68         ArcaneOrb_Timer = 3000; 
     69        ArcaneOrb_Timer = 6000; 
    6970        KnockAway_Timer = 30000; 
    7071        Berserk_Timer = 600000; 
     
    144145            { 
    145146                target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); 
    146                                                             //15 yard radius minimum 
    147                 if(target && target->GetDistance2d(m_creature) > 15) 
     147                                                            //18 yard radius minimum 
     148                if(target && target->GetDistance2d(m_creature) > 18) 
    148149                    target_list.push_back(target); 
    149150                target = NULL; 
     
    153154 
    154155            if (target) 
    155             { 
    156                 Unit* Spawn = NULL; 
    157                 Spawn = m_creature->SummonCreature(CREATURE_ORB_TARGET, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000); 
    158                 if (Spawn) 
    159                     m_creature->CastSpell(Spawn, SPELL_ARCANE_ORB_TRIGGER, true); 
    160             } 
     156                m_creature->CastSpell(target, SPELL_ARCANE_ORB, true); 
    161157 
    162             ArcaneOrb_Timer = 3000; 
     158            ArcaneOrb_Timer = 6000; 
    163159        }else ArcaneOrb_Timer -= diff; 
    164160 
  • trunk/src/game/SpellAuras.cpp

    r44 r57  
    16511651//                    // Prismatic Shield 
    16521652//                    case 40879: break; 
    1653 //                    // Aura of Desire 
    1654 //                    case 41350: break; 
     1653                    // Aura of Desire 
     1654                    case 41350: 
     1655                    { 
     1656                        Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT); 
     1657                        for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i) 
     1658                        { 
     1659                            if ((*i)->GetId() == 41350) 
     1660                            { 
     1661                                (*i)->ApplyModifier(false); 
     1662                                (*i)->GetModifier()->m_amount -= 5; 
     1663                                (*i)->ApplyModifier(true); 
     1664                                break; 
     1665                            } 
     1666                        }                         
     1667                    }break; 
    16551668//                    // Dementia 
    16561669//                    case 41404: break; 
     
    56155628                        break; 
    56165629                    } 
     5630                    case 41337:// aura of anger 
     5631                    {                         
     5632                        Unit::AuraList const& mMod = m_target->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE); 
     5633                        for(Unit::AuraList::const_iterator i = mMod.begin(); i != mMod.end(); ++i) 
     5634                        { 
     5635                            if ((*i)->GetId() == 41337) 
     5636                            { 
     5637                                (*i)->ApplyModifier(false); 
     5638                                (*i)->GetModifier()->m_amount += 5; 
     5639                                (*i)->ApplyModifier(true); 
     5640                                break; 
     5641                            } 
     5642                        }                         
     5643                        m_modifier.m_amount += 100; 
     5644                    }break; 
    56175645                    default: 
    56185646                        break; 
  • trunk/src/game/SpellEffects.cpp

    r56 r57  
    46664666        } 
    46674667 
    4668         // Dreaming Glory 
    4669         case 28698: 
    4670         { 
    4671             if(!unitTarget) 
    4672                 return; 
    4673             unitTarget->CastSpell(unitTarget, 28694, true); 
    4674             break; 
    4675         } 
    4676  
    46774668        // Netherbloom 
    46784669        case 28702: 
     
    47474738                } 
    47484739            } 
    4749             break; 
    4750         } 
    4751         case 41126:                                         // Flame Crash 
    4752         { 
    4753             if(!unitTarget) 
    4754                 return; 
    4755  
    4756            unitTarget->CastSpell(unitTarget, 41131, true); 
    4757            break; 
    4758         } 
    4759         case 44876:                                         // Force Cast - Portal Effect: Sunwell Isle 
    4760         { 
    4761             if(!unitTarget) 
    4762                 return; 
    4763  
    4764             unitTarget->CastSpell(unitTarget, 44870, true); 
    47654740            break; 
    47664741        } 
     
    47914766            break; 
    47924767        } 
     4768 
     4769    } 
     4770 
     4771    if(!unitTarget || !unitTarget->isAlive()) // can we remove this check? 
     4772    { 
     4773        sLog.outError("Spell %u in EffectScriptEffect does not have unitTarget", m_spellInfo->Id); 
     4774        return; 
     4775    } 
     4776 
     4777    switch(m_spellInfo->Id) 
     4778    { 
     4779        // Dreaming Glory 
     4780        case 28698: unitTarget->CastSpell(unitTarget, 28694, true); break; 
     4781        // Needle Spine 
     4782        case 39835: unitTarget->CastSpell(unitTarget, 39968, true); break; 
     4783        // Draw Soul 
     4784        case 40904: unitTarget->CastSpell(m_caster, 40903, true); break; 
     4785        // Flame Crash 
     4786        case 41126: unitTarget->CastSpell(unitTarget, 41131, true); break; 
     4787        // Force Cast - Portal Effect: Sunwell Isle 
     4788        case 44876: unitTarget->CastSpell(unitTarget, 44870, true); break; 
    47934789        //5,000 Gold 
    47944790        case 46642: 
    47954791        { 
    4796             if(!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) 
    4797                 return; 
    4798  
    4799             ((Player*)unitTarget)->ModifyMoney(50000000); 
    4800  
     4792            if(unitTarget->GetTypeId() == TYPEID_PLAYER) 
     4793                ((Player*)unitTarget)->ModifyMoney(50000000); 
    48014794            break; 
    48024795        } 
     
    48104803            case 0x800000: 
    48114804            { 
    4812                 if(!unitTarget || !unitTarget->isAlive()) 
    4813                     return; 
    48144805                uint32 spellId2 = 0; 
    48154806 
     
    48624853 
    48634854    // normal DB scripted effect 
    4864     if(!unitTarget) 
    4865         return; 
    4866  
    48674855    sLog.outDebug("Spell ScriptStart spellid %u in EffectScriptEffect ", m_spellInfo->Id); 
    48684856    sWorld.ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);