Changeset 182 for trunk

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

[svn] Update SerpentShrine? Cavern script. Patch provided by streetrat.

Original author: megamage
Date: 2008-11-06 16:17:36-06:00

Location:
trunk
Files:
1 added
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_hydross_the_unstable.cpp

    r164 r182  
    5757#define SPELL_SUMMON_WATER_ELEMENT  36459                   //not in use yet(in use ever?) 
    5858#define SPELL_ELEMENTAL_SPAWNIN     25035 
    59 //#define SPELL_BLUE_BEAM             38015                   //channeled Hydross Beam Helper (not in use yet) 
     59#define SPELL_BLUE_BEAM             /*40227*/38015                   //channeled Hydross Beam Helper (not in use yet) 
    6060 
    6161#define ENTRY_PURE_SPAWN            22035 
    6262#define ENTRY_TAINTED_SPAWN         22036 
     63#define ENTRY_BEAM_DUMMY            21934 
    6364 
    6465#define HYDROSS_X                   -239.439 
     
    7677struct TRINITY_DLL_DECL boss_hydross_the_unstableAI : public ScriptedAI 
    7778{ 
    78     boss_hydross_the_unstableAI(Creature *c) : ScriptedAI(c) 
     79    boss_hydross_the_unstableAI(Creature *c) : ScriptedAI(c), Summons(m_creature) 
    7980    { 
    8081        pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
    81         Reset(); 
     82        Reset();                 
    8283    } 
    8384 
    8485    ScriptedInstance* pInstance; 
    85  
     86        uint64 beams[2]; 
    8687    uint32 PosCheck_Timer; 
    8788    uint32 MarkOfHydross_Timer; 
     
    9394    uint32 EnrageTimer; 
    9495    bool CorruptedForm; 
     96        bool beam; 
     97        SummonList Summons; 
    9598 
    9699    void Reset() 
    97100    { 
     101                DeSummonBeams(); 
     102                beams[0] = 0; 
     103                beams[1] = 0; 
    98104        PosCheck_Timer = 2500; 
    99105        MarkOfHydross_Timer = 15000; 
     
    114120        if (pInstance) 
    115121            pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED); 
    116     } 
    117  
     122                beam = false; 
     123                Summons.DespawnAll(); 
     124    } 
     125 
     126        void SummonBeams() 
     127        {                
     128                Creature* beamer = m_creature->SummonCreature(ENTRY_BEAM_DUMMY,-258.333,-356.34,22.0499,5.90835,TEMPSUMMON_CORPSE_DESPAWN,0); 
     129                if(beamer) 
     130                { 
     131                        beamer->CastSpell(m_creature,SPELL_BLUE_BEAM,true); 
     132                        beamer->SetUInt32Value(UNIT_FIELD_DISPLAYID , 11686);  //invisible 
     133                        beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     134                        beams[0]=beamer->GetGUID(); 
     135                } 
     136                beamer = beamer = m_creature->SummonCreature(ENTRY_BEAM_DUMMY,-219.918,-371.308,22.0042,2.73072,TEMPSUMMON_CORPSE_DESPAWN,0);            
     137                if(beamer) 
     138                { 
     139                        beamer->CastSpell(m_creature,SPELL_BLUE_BEAM,true); 
     140                        beamer->SetUInt32Value(UNIT_FIELD_DISPLAYID , 11686);  //invisible 
     141                        beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
     142                        beams[1]=beamer->GetGUID(); 
     143                } 
     144        } 
     145        void DeSummonBeams() 
     146        {                
     147                for(uint8 i=0;i<2;i++) 
     148                { 
     149                        Creature* mob = (Creature*)Unit::GetUnit(*m_creature,beams[i]); 
     150                        if(mob) 
     151                        { 
     152                                mob->setDeathState(DEAD); 
     153                mob->RemoveCorpse(); 
     154                        } 
     155                } 
     156        } 
    118157    void Aggro(Unit *who) 
    119158    { 
     
    147186    { 
    148187        if (summoned->GetEntry() == ENTRY_PURE_SPAWN) 
    149             summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); 
     188                { 
     189                        summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true); 
     190                        summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true); 
     191                        Summons.Summon(summoned); 
     192                } 
    150193        if (summoned->GetEntry() == ENTRY_TAINTED_SPAWN) 
    151             summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); 
    152  
    153         summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true); 
     194                { 
     195                        summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true); 
     196                        summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true); 
     197                        Summons.Summon(summoned); 
     198                } 
     199    } 
     200 
     201        void SummonedCreatureDespawn(Creature *summon) 
     202    { 
     203        Summons.Despawn(summon); 
    154204    } 
    155205 
     
    163213        if (pInstance) 
    164214            pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED); 
     215                Summons.DespawnAll(); 
    165216    } 
    166217 
    167218    void UpdateAI(const uint32 diff) 
    168219    { 
     220                if(!beam) 
     221                { 
     222                        SummonBeams(); 
     223                        beam=true; 
     224                } 
    169225        //Return since we have no target 
    170226        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) 
     
    222278                    DoScriptText(SAY_SWITCH_TO_CLEAN, m_creature); 
    223279                    DoResetThreat(); 
     280                                        SummonBeams(); 
    224281 
    225282                    // spawn 4 adds 
    226                     DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    227                     DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    228                     DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    229                     DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     283                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     284                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     285                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     286                    DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    230287 
    231288                    m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_FROST); 
     
    288345                    DoScriptText(SAY_SWITCH_TO_CORRUPT, m_creature); 
    289346                    DoResetThreat(); 
     347                                        DeSummonBeams(); 
    290348 
    291349                    // spawn 4 adds 
    292                     DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    293                     DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    294                     DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    295                     DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     350                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     351                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     352                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
     353                    DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    296354 
    297355                    m_creature->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE); 
  • trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp

    r164 r182  
    2525#include "def_serpent_shrine.h" 
    2626#include "../../../creature/simple_ai.h" 
    27 #include "Item.h" 
    2827#include "Spell.h" 
    2928 
     
    4342#define SAY_DEATH                   -1548055 
    4443 
     44#define SPELL_SURGE                                 38044 
    4545#define SPELL_MULTI_SHOT            38310 
    4646#define SPELL_SHOCK_BLAST           38509 
     
    6262#define SPOREBAT_O                  5.223932 
    6363 
    64 #define SHIED_GENERATOR_CHANNEL     19870 
    65 #define ENCHANTED_ELEMENTAL         21958 
    66 #define TAINTED_ELEMENTAL           22009 
    67 #define COILFANG_STRIDER            22056 
    68 #define COILFANG_ELITE              22055 
    69 #define TOXIC_SPOREBAT             22140 
     64#define SHIED_GENERATOR_CHANNEL       19870 
     65#define ENCHANTED_ELEMENTAL           21958 
     66#define TAINTED_ELEMENTAL             22009 
     67#define COILFANG_STRIDER              22056 
     68#define COILFANG_ELITE                22055 
     69#define TOXIC_SPOREBAT                22140  
     70#define TOXIC_SPORES_TRIGGER          22207  
    7071 
    7172float ElementPos[8][4] = 
     
    8182}; 
    8283 
     84float ElementWPPos[8][3] =  
     85{ 
     86    {71.700752, -883.905884, 41.097168}, 
     87    {45.039848, -868.022827, 41.097015}, 
     88    {14.585141, -867.894470, 41.097061}, 
     89    {-25.415508, -906.737732, 41.097061}, 
     90    {-11.801594, -963.405884, 41.097067}, 
     91    {14.556657, -979.051514, 41.097137}, 
     92    {43.466549, -979.406677, 41.097027}, 
     93    {69.945908, -964.663940, 41.097054} 
     94}; 
     95 
     96float SporebatWPPos[8][3] =  
     97{ 
     98    {31.6,-896.3,59.1}, 
     99    {9.1, -913.9, 56}, 
     100    {5.2, -934.4, 52.4}, 
     101    {20.7, -946.9, 49.7}, 
     102    {41, -941.9, 51}, 
     103    {47.7, -927.3, 55}, 
     104    {42.2, -912.4, 51.7}, 
     105    {27, -905.9, 50} 
     106}; 
     107 
    83108float CoilfangElitePos[3][4] = 
    84109{ 
     
    108133    boss_lady_vashjAI (Creature *c) : ScriptedAI(c) 
    109134    { 
    110         pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
    111         Reset(); 
     135        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL; 
     136                Intro = false; 
     137                Reset(); 
     138                CanAttack = false;//must be after reset()     
     139                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); //set it only once on creature create (no need do intro if wiped) 
    112140    } 
    113141 
     
    115143 
    116144    uint64 ShieldGeneratorChannel[4]; 
    117         uint64 AggroTargetGUID; 
    118  
     145 
     146        uint32 AggroTimer;  
    119147    uint32 ShockBlast_Timer; 
    120148    uint32 Entangle_Timer; 
     
    128156    uint32 SummonSporebat_Timer; 
    129157    uint32 SummonSporebat_StaticTimer; 
    130         uint32 AggroTimer; 
    131  
    132158    uint8 EnchantedElemental_Pos; 
    133159    uint8 Phase; 
    134160 
    135161    bool Entangle; 
     162    bool InCombat; 
    136163        bool Intro; 
     164        bool CanAttack; 
    137165 
    138166    void Reset() 
    139167    { 
     168                AggroTimer = 19000;  
    140169        ShockBlast_Timer = 1+rand()%60000; 
    141170        Entangle_Timer = 30000; 
     
    151180        EnchantedElemental_Pos = 0; 
    152181        Phase = 0; 
    153                 AggroTimer = 19000; 
    154         AggroTargetGUID = 0; 
    155  
    156                 m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    157         // Start off unattackable so that the intro is done properly 
    158         m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    159182 
    160183        Entangle = false; 
    161                 Intro = false; 
     184        InCombat = false; 
     185                CanAttack = true; 
     186 
     187                Unit *remo; 
     188        for(uint8 i = 0; i < 4; i++) 
     189        { 
     190            remo = Unit::GetUnit(*m_creature, ShieldGeneratorChannel[i]); 
     191            if (remo) 
     192                                remo->setDeathState(JUST_DIED); 
     193        } 
    162194 
    163195        if(pInstance) 
    164             pInstance->SetData(DATA_LADYVASHJEVENT, NOT_STARTED); 
    165  
     196                        pInstance->SetData(DATA_LADYVASHJEVENT, NOT_STARTED);                    
    166197        ShieldGeneratorChannel[0] = 0; 
    167198        ShieldGeneratorChannel[1] = 0; 
    168199        ShieldGeneratorChannel[2] = 0; 
    169200        ShieldGeneratorChannel[3] = 0; 
     201 
     202                m_creature->SetCorpseDelay(1000*60*60); 
    170203    } 
    171204 
     
    177210            TaintedElemental_Timer = 50000; 
    178211    } 
    179  
    180         void MoveInLineOfSight(Unit *who) 
    181     { 
    182         if(!who || (!who->isAlive())) return; 
    183  
    184         if(who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) 
    185         { 
    186             float attackRadius = m_creature->GetAttackDistance(who); 
    187  
    188             if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) 
    189             { 
    190                 if(who->HasStealthAura()) 
    191                     who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); 
    192  
    193                 m_creature->AddThreat(who, 1.0f); 
    194             } 
    195  
    196             if(!InCombat && !Intro && m_creature->IsWithinDistInMap(who, 40.0f) && (who->GetTypeId() == TYPEID_PLAYER)) 
    197             { 
    198                 if(pInstance) 
    199                     pInstance->SetData(DATA_LADYVASHJEVENT, IN_PROGRESS); 
    200  
    201                 m_creature->GetMotionMaster()->Clear(false); 
    202                 m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    203                 DoScriptText(SAY_INTRO, m_creature); 
    204                 m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK); 
    205                 AggroTargetGUID = who->GetGUID(); 
    206                 Intro = true; 
    207             } 
    208         } 
    209     } 
    210  
    211212    void KilledUnit(Unit *victim) 
    212213    { 
     
    227228    } 
    228229 
    229 /*    void StartEvent() 
     230    void StartEvent() 
    230231    { 
    231232        switch(rand()%4) 
     
    237238        } 
    238239 
     240        InCombat = true; 
    239241        Phase = 1; 
    240242 
    241243        if(pInstance) 
    242244            pInstance->SetData(DATA_LADYVASHJEVENT, IN_PROGRESS); 
    243     }*/ 
    244  
    245     void Aggro(Unit *who){} 
     245    } 
     246 
     247    void Aggro(Unit *who) 
     248    { 
     249                if (pInstance) 
     250                { 
     251                        //remove old tainted cores to prevent cheating in phase 2 
     252                        Map *map = m_creature->GetMap(); 
     253                        InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers(); 
     254                        for(InstanceMap::PlayerList::const_iterator i = PlayerList.begin();i != PlayerList.end(); ++i) 
     255            { 
     256                if((*i)) 
     257                { 
     258                    (*i)->DestroyItemCount(31088, 1, true); 
     259                } 
     260            } 
     261                } 
     262        if(Phase != 2) 
     263            AttackStart(who); 
     264 
     265        if(!InCombat) 
     266            StartEvent(); 
     267    } 
     268 
     269    void MoveInLineOfSight(Unit *who) 
     270    { 
     271                if (!Intro) 
     272                { 
     273                        Intro = true; 
     274                        DoScriptText(SAY_INTRO, m_creature);                     
     275                } 
     276                if (!CanAttack) 
     277                        return; 
     278        if (!who || m_creature->getVictim()) 
     279            return; 
     280 
     281        if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) 
     282        { 
     283            float attackRadius = m_creature->GetAttackDistance(who); 
     284            if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) 
     285            { 
     286                if(who->HasStealthAura()) 
     287                    who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); 
     288 
     289                if(Phase != 2) 
     290                    AttackStart(who); 
     291 
     292                if(!InCombat) 
     293                    StartEvent(); 
     294            } 
     295        } 
     296    } 
    246297 
    247298    void CastShootOrMultishot() 
     
    260311                break; 
    261312        } 
    262  
    263313        if(rand()%3) 
    264314        { 
     
    273323    void UpdateAI(const uint32 diff) 
    274324    { 
     325                if(!CanAttack && Intro) 
     326                { 
     327                        if(AggroTimer < diff) 
     328                        { 
     329                                CanAttack = true; 
     330                                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);  
     331                                AggroTimer=19000; 
     332                        }else  
     333                        { 
     334                                AggroTimer-=diff; 
     335                                return; 
     336                        } 
     337                } 
    275338        //to prevent abuses during phase 2 
    276339        if(Phase == 2 && !m_creature->getVictim() && InCombat) 
    277340                { 
    278          EnterEvadeMode(); 
    279                  return; 
     341                        EnterEvadeMode(); 
     342                        return; 
    280343                } 
    281  
    282344        //Return since we have no target 
    283345        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) 
    284346            return; 
    285  
    286                 //Intro 
    287                 if(Intro) 
    288         { 
    289             if(AggroTimer < diff) 
    290             { 
    291                 m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    292                 m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    293                                 switch(rand()%4) 
    294                                 { 
    295                     case 0: DoScriptText(SAY_AGGRO1, m_creature); break; 
    296                     case 1: DoScriptText(SAY_AGGRO2, m_creature); break; 
    297                     case 2: DoScriptText(SAY_AGGRO3, m_creature); break; 
    298                     case 3: DoScriptText(SAY_AGGRO4, m_creature); break; 
    299                                 } 
    300                                 Phase = 1; 
    301                 m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); 
    302                 Intro = false; 
    303                                 //Begin melee attack if we are within range 
    304                 if(AggroTargetGUID && Phase != 2) 
    305                 { 
    306                     Unit* pUnit = Unit::GetUnit((*m_creature), AggroTargetGUID); 
    307                     if(pUnit) 
    308                     { 
    309                         m_creature->GetMotionMaster()->MoveChase(pUnit); 
    310                         AttackStart(pUnit); 
    311                     } 
    312                     DoZoneInCombat(); 
    313                 }else EnterEvadeMode(); 
    314             }else AggroTimer -= diff; 
    315         } 
    316347 
    317348        if(Phase == 1 || Phase == 3) 
     
    371402                    Phase = 2; 
    372403 
    373                     m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    374404                    m_creature->GetMotionMaster()->Clear(); 
    375405                    m_creature->Relocate(MIDDLE_X, MIDDLE_Y, MIDDLE_Z); 
    376406                    m_creature->SendMonsterMove(MIDDLE_X, MIDDLE_Y, MIDDLE_Z, 0, 0, 0); 
    377  
    378                     m_creature->RemoveAllAuras(); 
    379                                                             // This needs an entry in spell_script_target 
    380                     DoCast(m_creature, SPELL_MAGIC_BARRIER, true); 
    381407 
    382408                    Creature *pCreature; 
     
    387413                            ShieldGeneratorChannel[i] = pCreature->GetGUID(); 
    388414                    } 
    389  
    390415                    DoScriptText(SAY_PHASE2, m_creature); 
    391416                } 
     
    398423                { 
    399424                    Creature *Sporebat = NULL; 
    400                     Sporebat = m_creature->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); 
     425                    Sporebat = m_creature->SummonCreature(TOXIC_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_CORPSE_DESPAWN, 0); 
    401426 
    402427                    if(Sporebat) 
     
    413438 
    414439                    SummonSporebat_Timer = SummonSporebat_StaticTimer; 
     440 
     441                                        if(SummonSporebat_Timer < 5000) 
     442                        SummonSporebat_Timer = 5000; 
     443 
    415444                }else SummonSporebat_Timer -= diff; 
    416445            } 
     
    466495            { 
    467496                Creature *Elemental; 
    468                 Elemental = m_creature->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElemental_Pos][0], ElementPos[EnchantedElemental_Pos][1], ElementPos[EnchantedElemental_Pos][2], ElementPos[EnchantedElemental_Pos][3], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); 
    469                 if(Elemental) 
    470                     Elemental->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ()); 
     497                Elemental = m_creature->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElemental_Pos][0], ElementPos[EnchantedElemental_Pos][1], ElementPos[EnchantedElemental_Pos][2], ElementPos[EnchantedElemental_Pos][3], TEMPSUMMON_CORPSE_DESPAWN, 0); 
    471498 
    472499                if(EnchantedElemental_Pos == 7) 
     
    483510                Creature *Tain_Elemental; 
    484511                uint32 pos = rand()%8; 
    485                 Tain_Elemental = m_creature->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); 
    486                 if(Tain_Elemental) 
    487                 { 
    488                     Tain_Elemental->GetMotionMaster()->Clear(); 
    489                     Tain_Elemental->GetMotionMaster()->MoveIdle(); 
    490                 } 
     512                Tain_Elemental = m_creature->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0); 
    491513 
    492514                TaintedElemental_Timer = 120000; 
     
    496518            if(CoilfangElite_Timer < diff) 
    497519            { 
    498                 Creature *CoilfangElite; 
    499520                uint32 pos = rand()%3; 
    500                 CoilfangElite = m_creature->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000); 
    501                 if(CoilfangElite) 
     521                Creature* CoilfangElite = NULL; 
     522                                CoilfangElite = m_creature->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); 
     523                                if(CoilfangElite) 
    502524                { 
    503525                    Unit *target = NULL; 
     
    505527                    if(target) 
    506528                        CoilfangElite->AI()->AttackStart(target); 
     529                                        else if(m_creature->getVictim()) 
     530                                                CoilfangElite->AI()->AttackStart(m_creature->getVictim()); 
    507531                } 
    508  
    509                 CoilfangElite_Timer = 45000+rand()%5000;    //wowwiki says 50 seconds, bosskillers says 45 
     532                CoilfangElite_Timer = 45000+rand()%5000; 
    510533            }else CoilfangElite_Timer -= diff; 
    511534 
     
    513536            if(CoilfangStrider_Timer < diff) 
    514537            { 
    515                 Creature *CoilfangStrider; 
    516538                uint32 pos = rand()%3; 
    517                 CoilfangStrider = m_creature->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000); 
    518                 if(CoilfangStrider) 
     539                                Creature* CoilfangStrider = NULL; 
     540                                CoilfangStrider = m_creature->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); 
     541                                 if(CoilfangStrider) 
    519542                { 
    520543                    Unit *target = NULL; 
     
    522545                    if(target) 
    523546                        CoilfangStrider->AI()->AttackStart(target); 
     547                                        else if(m_creature->getVictim()) 
     548                                                CoilfangStrider->AI()->AttackStart(m_creature->getVictim()); 
    524549                } 
    525  
    526                 CoilfangStrider_Timer = 60000+rand()%10000; //wowwiki says 60 seconds, bosskillers says 60-70 
     550                CoilfangStrider_Timer = 60000+rand()%10000; 
    527551            }else CoilfangStrider_Timer -= diff; 
    528552 
     
    536560                    m_creature->SetHealth(m_creature->GetMaxHealth()/2); 
    537561 
    538                     m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); 
    539562                    m_creature->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER); 
    540563 
     
    551574    } 
    552575}; 
    553  
     576class TRINITY_DLL_DECL VashjSurgeAura : public Aura 
     577{ 
     578    public: 
     579        VashjSurgeAura(SpellEntry *spell, uint32 eff, int32 *bp, Unit *target, Unit *caster) : Aura(spell, eff, bp, target, caster, NULL) 
     580            {} 
     581}; 
    554582//Enchanted Elemental 
    555583//If one of them reaches Vashj he will increase her damage done by 5%. 
     
    558586    mob_enchanted_elementalAI(Creature *c) : ScriptedAI(c) 
    559587    { 
    560         pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     588        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL; 
    561589        Reset(); 
    562590    } 
    563591 
    564592    ScriptedInstance *pInstance; 
    565  
    566     uint32 Check_Timer; 
    567     uint32 Movement_Timer; 
     593        uint32 move; 
     594        uint32 phase; 
     595        float x, y, z; 
     596        Unit *Vashj; 
    568597 
    569598    void Reset() 
    570     { 
    571         Check_Timer = 5000; 
    572         Movement_Timer = 500; 
     599    {         
     600                m_creature->SetSpeed(MOVE_WALK,0.6,true);//walk 
     601                m_creature->SetSpeed(MOVE_RUN,0.6,true);//run 
     602                move = 0; 
     603                phase = 1; 
     604                Vashj = NULL; 
    573605    } 
    574606 
    575607    void Aggro(Unit *who) { return; } 
    576608 
    577     void MoveInLineOfSight(Unit *who) { return; } 
    578  
     609    void MoveInLineOfSight(Unit *who){return;} 
     610         
    579611    void UpdateAI(const uint32 diff) 
    580612    { 
    581         //Check_Timer 
    582         if(Check_Timer < diff) 
    583         { 
    584             if(pInstance) 
    585             { 
    586                 Unit *Vashj = NULL; 
    587                 Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)); 
    588                 if(Vashj) 
     613                if(!pInstance) 
     614                        return; 
     615 
     616                if (!Vashj){ Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)); } 
     617 
     618                for (int i = 0;i<8;i++)//search for nearest waypoint (up on stairs) 
     619                { 
     620                        if (!x || !y || !z) 
     621                        { 
     622                                x = ElementWPPos[i][0]; 
     623                                y = ElementWPPos[i][1]; 
     624                                z = ElementWPPos[i][2]; 
     625                        } 
     626                        else 
     627                        { 
     628                                if (m_creature->GetDistance(ElementWPPos[i][0],ElementWPPos[i][1],ElementWPPos[i][2]) < m_creature->GetDistance(x,y,z)) 
     629                                { 
     630                                        x = ElementWPPos[i][0]; 
     631                                        y = ElementWPPos[i][1]; 
     632                                        z = ElementWPPos[i][2]; 
     633                                } 
     634                        } 
     635                } 
     636 
     637                if (!Vashj)  
     638                { 
     639                        m_creature->Say("Error Vashj not found!", LANG_UNIVERSAL, NULL); 
     640                        return; 
     641                } 
     642 
     643                if(move < diff) 
     644        { 
     645                        if (phase == 1) 
     646                        { 
     647                                m_creature->GetMotionMaster()->MovePoint(0, x, y, z); 
     648                        } 
     649                        if (phase == 1 && m_creature->GetDistance(x,y,z) < 0.1) 
     650                        { 
     651                                phase = 2; 
     652                        } 
     653                        if (phase == 2) 
     654                        { 
     655                                m_creature->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z); 
     656                                phase = 3; 
     657                        } 
     658                        if (phase == 3) 
     659            { 
     660                m_creature->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z); 
     661                if(m_creature->GetDistance(MIDDLE_X, MIDDLE_Y, MIDDLE_Z) < 3) 
    589662                { 
    590                     if(Vashj->IsWithinDistInMap(m_creature, 5)) 
     663                    SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_SURGE); 
     664                    if( spell ) 
    591665                    { 
    592                         //increase lady vashj damage (+5%) 
    593                         const CreatureInfo *cinfo = m_creature->GetCreatureInfo(); 
    594                         Vashj->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 5))); 
    595                         Vashj->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 5))); 
    596                         m_creature->UpdateDamagePhysical(BASE_ATTACK); 
    597  
    598                         //call Unsummon() 
    599                         m_creature->setDeathState(JUST_DIED); 
     666                        for(uint32 i = 0;i<3;i++) 
     667                        { 
     668                            if (!spell->Effect[i]) 
     669                                continue; 
     670 
     671                            Vashj->AddAura(new VashjSurgeAura(spell, i, NULL, Vashj, Vashj)); 
     672                        } 
    600673                    } 
    601                     else if(((boss_lady_vashjAI*)((Creature*)Vashj)->AI())->InCombat == false) 
    602                     { 
    603                         //call Unsummon() 
    604                         m_creature->setDeathState(JUST_DIED); 
    605                     } 
     674                    m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    606675                } 
    607676            } 
    608             else error_log("ERROR: Instance Data for Serpentshrine Caverns not set"); 
    609             Check_Timer = 1000; 
    610         }else Check_Timer -= diff; 
     677                        if(((boss_lady_vashjAI*)((Creature*)Vashj)->AI())->InCombat == false || ((boss_lady_vashjAI*)((Creature*)Vashj)->AI())->Phase != 2 || Vashj->isDead()) 
     678            { 
     679                //call Unsummon() 
     680                                m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
     681            }    
     682                        move = 1000; 
     683                }else move -= diff;       
    611684    } 
    612685}; 
     
    618691    mob_tainted_elementalAI(Creature *c) : ScriptedAI(c) 
    619692    { 
    620         pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     693        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL; 
    621694        Reset(); 
    622695    } 
     
    625698 
    626699    uint32 PoisonBolt_Timer; 
     700    uint32 Despawn_Timer; 
    627701 
    628702    void Reset() 
    629703    { 
    630704        PoisonBolt_Timer = 5000+rand()%5000; 
     705        Despawn_Timer = 30000; 
    631706    } 
    632707 
     
    645720    void Aggro(Unit *who) 
    646721    { 
     722                m_creature->AddThreat(who, 0.1f); 
    647723    } 
    648724 
     
    660736            PoisonBolt_Timer = 5000+rand()%5000; 
    661737        }else PoisonBolt_Timer -= diff; 
     738 
     739        //Despawn_Timer 
     740        if(Despawn_Timer < diff) 
     741        { 
     742            //call Unsummon() 
     743            m_creature->setDeathState(DEAD); 
     744 
     745            //to prevent crashes 
     746            Despawn_Timer = 1000; 
     747        }else Despawn_Timer -= diff; 
    662748    } 
    663749}; 
     
    669755    mob_toxic_sporebatAI(Creature *c) : ScriptedAI(c) 
    670756    { 
    671         pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
    672         Reset(); 
     757        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL; 
     758        EnterEvadeMode(); 
    673759    } 
    674760 
    675761    ScriptedInstance *pInstance; 
    676762 
     763        uint32 movement_timer; 
    677764    uint32 ToxicSpore_Timer; 
     765        uint32 bolt_timer; 
    678766    uint32 Check_Timer; 
    679767 
    680768    void Reset() 
    681769    { 
    682                 m_creature->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);         
    683                 m_creature->setFaction(14); 
     770                m_creature->AddUnitMovementFlag(/*MOVEMENTFLAG_ONTRANSPORT + */MOVEMENTFLAG_LEVITATING); 
     771        m_creature->setFaction(14); 
     772                movement_timer = 0; 
    684773        ToxicSpore_Timer = 5000; 
     774                bolt_timer = 5500; 
    685775        Check_Timer = 1000; 
    686776    } 
    687777 
    688     void Aggro(Unit *who) {} 
     778    void Aggro(Unit *who) 
     779    { 
     780                 
     781    } 
     782 
     783    void MoveInLineOfSight(Unit *who) 
     784        { 
     785                 
     786    } 
     787 
     788        void MovementInform(uint32 type, uint32 id) 
     789    { 
     790        if(type != POINT_MOTION_TYPE) 
     791            return; 
     792 
     793        if(id == 1) 
     794                        movement_timer = 0; 
     795        } 
    689796 
    690797    void UpdateAI (const uint32 diff) 
    691798    { 
    692         //Return since we have no target 
    693         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) 
    694             return; 
    695  
    696         //ToxicSpore_Timer 
    697         if(ToxicSpore_Timer < diff) 
    698         { 
    699             Unit *target = NULL; 
    700             target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
    701  
    702             //The Spores will hit you anywhere in the instance: underwater, at the elevator, at the entrance, wherever. 
    703             if(target) 
    704                 DoCast(target, SPELL_TOXIC_SPORES); 
    705  
    706             ToxicSpore_Timer = 20000+rand()%5000; 
    707         }else ToxicSpore_Timer -= diff; 
     799 
     800                /*if(!m_creature->isInCombat()) 
     801                        m_creature->SetInCombatState(false);*/ 
     802 
     803                //Random movement 
     804        if (movement_timer < diff) 
     805        { 
     806                        uint32 rndpos = rand()%8; 
     807                        m_creature->GetMotionMaster()->MovePoint(1,SporebatWPPos[rndpos][0], SporebatWPPos[rndpos][1], SporebatWPPos[rndpos][2]); 
     808                        movement_timer = 6000; 
     809                }else movement_timer -= diff; 
     810                 
     811                //toxic spores 
     812                if(bolt_timer < diff) 
     813                { 
     814                        Unit *target = NULL; 
     815                        target = SelectUnit(SELECT_TARGET_RANDOM, 0); 
     816                        if(target) 
     817                        { 
     818                                Creature* trig = m_creature->SummonCreature(TOXIC_SPORES_TRIGGER,target->GetPositionX(),target->GetPositionY(),target->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,30000); 
     819                                if(trig) 
     820                                { 
     821                                        trig->setFaction(14); 
     822                                        trig->CastSpell(trig, SPELL_TOXIC_SPORES,true); 
     823                                } 
     824                        } 
     825                        bolt_timer = 10000+rand()%5000; 
     826                } 
     827                else bolt_timer -= diff; 
    708828 
    709829        //Check_Timer 
     
    715835                Unit *Vashj = NULL; 
    716836                Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)); 
    717                 if(!Vashj || (Vashj && !Vashj->isAlive())) 
     837                if(!Vashj || (Vashj && !Vashj->isAlive()) || (Vashj && ((boss_lady_vashjAI*)((Creature*)Vashj)->AI())->Phase != 3)) 
    718838                { 
    719839                    //remove 
     
    726846            Check_Timer = 1000; 
    727847        }else Check_Timer -= diff; 
    728  
    729         DoMeleeAttackIfReady(); 
    730     } 
     848        } 
    731849}; 
    732850 
     
    749867} 
    750868 
    751 //Coilfang Strifer 
     869//Coilfang Strider 
    752870//It hits plate for about 8000 damage, has a Mind Blast spell doing about 3000 shadow damage, and a Psychic Scream Aura, which fears everybody in a 8 yard range of it every 2-3 seconds , for 5 seconds and increasing their movement speed by 150% during the fear. 
    753871CreatureAI* GetAI_mob_coilfang_strider(Creature *_Creature) 
     
    773891    mob_shield_generator_channelAI(Creature *c) : ScriptedAI(c) 
    774892    { 
    775         pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     893        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL; 
    776894        Reset(); 
    777895    } 
    778896 
    779897    ScriptedInstance *pInstance; 
    780  
    781898    uint32 Check_Timer; 
    782     bool Channeled; 
    783  
     899        bool Casted; 
    784900    void Reset() 
    785901    { 
    786         Check_Timer = 1000; 
    787         Channeled = false; 
    788                                                             //invisible 
    789         m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID , 11686); 
     902        Check_Timer = 0; 
     903                Casted = false; 
     904        m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID , 11686);  //invisible 
     905 
    790906        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); 
    791907    } 
     
    800916            return; 
    801917 
    802         if(!Channeled) 
     918        if(Check_Timer < diff) 
    803919        { 
    804920            Unit *Vashj = NULL; 
     
    808924            { 
    809925                //start visual channel 
    810                 m_creature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, Vashj->GetGUID()); 
    811                 m_creature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_MAGIC_BARRIER); 
    812                 Channeled = true; 
     926                                if (!Casted || !Vashj->HasAura(SPELL_MAGIC_BARRIER,0)) 
     927                                { 
     928                                        m_creature->CastSpell(Vashj,SPELL_MAGIC_BARRIER,true); 
     929                                        Casted = true; 
     930                                } 
    813931            } 
    814         } 
     932                        Check_Timer = 1000; 
     933        }else Check_Timer -= diff; 
    815934    } 
    816935}; 
     
    818937bool ItemUse_item_tainted_core(Player *player, Item* _Item, SpellCastTargets const& targets) 
    819938{ 
    820     ScriptedInstance *pInstance = ((ScriptedInstance*)player->GetInstanceData()); 
     939    ScriptedInstance *pInstance = (player->GetInstanceData()) ? ((ScriptedInstance*)player->GetInstanceData()) : NULL; 
    821940 
    822941    if(!pInstance) 
    823942    { 
    824         player->GetSession()->SendNotification("ERROR: Instance script not initialized. Notify your administrator."); 
    825         error_log("ERROR: Lady Vashj Tainted Core: Instance Script Not Initialized"); 
     943        player->GetSession()->SendNotification("Instance script not initialized"); 
    826944        return true; 
    827945    } 
     
    855973                default: 
    856974                    return true; 
    857                     break; 
    858975            } 
    859976 
     
    870987            { 
    871988                //call Unsummon() 
    872                 Channel->setDeathState(JUST_DIED); 
     989                Channel->setDeathState(JUST_DIED);                               
    873990            } 
    874991 
     
    9501067    m_scripts[nrscripts++] = newscript; 
    9511068} 
     1069 
     1070 
  • trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp

    r164 r182  
    1717/* ScriptData 
    1818SDName: Boss_Leotheras_The_Blind 
    19 SD%Complete: 50 
    20 SDComment: Missing Inner Demons 
     19SD%Complete: 80 
     20SDComment: Possesion Support 
    2121SDCategory: Coilfang Resevoir, Serpent Shrine Cavern 
    2222EndScriptData */ 
     
    2424#include "precompiled.h" 
    2525#include "def_serpent_shrine.h" 
     26 
     27// --- Spells used by Leotheras The Blind 
     28#define SPELL_WHIRLWIND         37640 
     29#define SPELL_CHAOS_BLAST       37674 
     30#define SPELL_BERSERK                   26662 
     31#define SPELL_INSIDIOUS_WHISPER 37676 
     32#define SPELL_DUAL_WIELD                42459 
     33 
     34// --- Spells used in banish phase --- 
     35#define BANISH_BEAM                             38909 
     36#define AURA_BANISH                             37833 
     37 
     38// --- Spells used by Greyheart Spellbinders 
     39#define SPELL_EARTHSHOCK                39076 
     40#define SPELL_MINDBLAST                 37531 
     41 
     42// --- Spells used by Inner Demons and creature ID 
     43#define INNER_DEMON_ID                  21857  
     44#define AURA_DEMONIC_ALIGNMENT  37713 
     45#define SPELL_SHADOWBOLT                39309 
     46#define SPELL_SOUL_LINK                 38007 
     47#define SPELL_CONSUMING_MADNESS 37749 //not supported by core yet 
     48 
     49//Misc. 
     50#define MODEL_DEMON                             20125 
     51#define MODEL_NIGHTELF                  20514 
     52#define DEMON_FORM                              21875 
     53#define MOB_SPELLBINDER                 21806 
    2654 
    2755#define SAY_AGGRO               -1548009 
     
    3866#define SAY_DEATH               -1548020 
    3967 
    40 #define SPELL_WHIRLWIND         40653 
    41 #define SPELL_CHAOS_BLAST       37675 
    42 //#define SPELL_INSIDIOUS_WHISPER 37676                       // useless - dummy effect that can't be implemented 
    43  
    44 #define MODEL_DEMON             14555 
    45 #define MODEL_NIGHTELF          20514 
    46  
    47 #define DEMON_FORM              21845 
    48  
     68class TRINITY_DLL_DECL InsidiousAura : public Aura { 
     69public: 
     70        InsidiousAura(SpellEntry *spell, uint32 eff, int32 *bp, Unit *target, Unit *caster) : Aura(spell, eff, bp, target, caster, NULL) 
     71        {} 
     72}; 
     73 
     74struct TRINITY_DLL_DECL mob_inner_demonAI : public ScriptedAI 
     75{ 
     76    mob_inner_demonAI(Creature *c) : ScriptedAI(c) 
     77    { 
     78                victimGUID = 0; 
     79        Reset(); 
     80    } 
     81 
     82    uint32 ShadowBolt_Timer; 
     83         
     84        uint32 Link_Timer; 
     85        uint64 victimGUID; 
     86 
     87    void Reset() 
     88    { 
     89        ShadowBolt_Timer = 10000;                
     90                Link_Timer = 1000; 
     91    } 
     92        void JustDied(Unit *victim) 
     93    { 
     94                Unit* pUnit = Unit::GetUnit((*m_creature),victimGUID); 
     95                if (pUnit && pUnit->HasAura(SPELL_INSIDIOUS_WHISPER,0)) 
     96                        pUnit->RemoveAurasDueToSpell(SPELL_INSIDIOUS_WHISPER); 
     97        } 
     98 
     99        void DamageTaken(Unit *done_by, uint32 &damage) 
     100        { 
     101                if(done_by->GetGUID() != victimGUID && done_by->GetGUID() != m_creature->GetGUID()) 
     102                { 
     103                        damage = 0; 
     104                        m_creature->getThreatManager().modifyThreatPercent(done_by, -100); 
     105                } 
     106        } 
     107 
     108        void Aggro(Unit *who) 
     109    { 
     110                if (!victimGUID) return; 
     111    } 
     112 
     113    void UpdateAI(const uint32 diff) 
     114    { 
     115        //Return since we have no target 
     116        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
     117            return; 
     118 
     119                if (m_creature->getVictim()->GetGUID() != victimGUID) 
     120                { 
     121                        Unit* owner = Unit::GetUnit((*m_creature),victimGUID); 
     122                                if (owner) 
     123                                        AttackStart(owner); 
     124                } 
     125                if(Link_Timer < diff) 
     126                { 
     127                        DoCast(m_creature->getVictim(), SPELL_SOUL_LINK, true); 
     128                        Link_Timer = 1000; 
     129                }else Link_Timer -= diff; 
     130 
     131 
     132                if(!m_creature->HasAura(AURA_DEMONIC_ALIGNMENT, 0)) 
     133                        DoCast(m_creature, AURA_DEMONIC_ALIGNMENT,true); 
     134 
     135                if(ShadowBolt_Timer < diff) 
     136                { 
     137                        DoCast(m_creature->getVictim(), SPELL_SHADOWBOLT, false); 
     138                        ShadowBolt_Timer = 10000; 
     139                }else ShadowBolt_Timer -= diff;  
     140 
     141       DoMeleeAttackIfReady(); 
     142    } 
     143}; 
    49144//Original Leotheras the Blind AI 
    50145struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI 
     
    52147    boss_leotheras_the_blindAI(Creature *c) : ScriptedAI(c) 
    53148    { 
    54         pInstance = ((ScriptedInstance*)c->GetInstanceData()); 
     149                m_creature->GetPosition(x,y,z); 
     150        pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL; 
    55151        Demon = 0; 
     152                 
     153                for(uint8 i = 0; i < 3; i++)//clear guids 
     154                        SpellBinderGUID[i] = 0; 
    56155        Reset(); 
    57     } 
    58  
     156 
     157        } 
    59158    ScriptedInstance *pInstance; 
    60159 
    61160    uint32 Whirlwind_Timer; 
    62161    uint32 ChaosBlast_Timer; 
    63     uint32 Switch_Timer; 
    64  
     162        uint32 SwitchToDemon_Timer; 
     163    uint32 SwitchToHuman_Timer; 
     164        uint32 Berserk_Timer; 
     165        uint32 InnerDemons_Timer; 
     166        uint32 BanishTimer; 
     167         
     168        bool DealDamage; 
     169        bool NeedThreatReset; 
    65170    bool DemonForm; 
    66171    bool IsFinalForm; 
    67  
     172        bool EnrageUsed; 
     173        float x,y,z; 
     174         
     175        uint64 InnderDemon[5]; 
     176        uint32 InnderDemon_Count; 
    68177    uint64 Demon; 
     178        uint64 SpellBinderGUID[3]; 
    69179 
    70180    void Reset() 
    71181    { 
    72         Whirlwind_Timer = 20000; 
     182                CheckChannelers(); 
     183                BanishTimer = 1000; 
     184        Whirlwind_Timer = 15000; 
    73185        ChaosBlast_Timer = 1000; 
    74         Switch_Timer = 45000; 
    75  
     186                SwitchToDemon_Timer = 45000; 
     187        SwitchToHuman_Timer = 60000; 
     188                Berserk_Timer = 600000; 
     189                InnerDemons_Timer = 30000; 
     190                m_creature->SetCanDualWield(true); 
     191                DealDamage = true; 
    76192        DemonForm = false; 
    77193        IsFinalForm = false; 
    78  
    79         m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); 
    80  
    81         if (pInstance) 
    82             pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, NOT_STARTED); 
    83     } 
     194                NeedThreatReset = false; 
     195                EnrageUsed = false; 
     196                InnderDemon_Count = 0; 
     197                m_creature->SetSpeed( MOVE_RUN, 2.0f, true); 
     198                m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); 
     199                m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); 
     200                m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); 
     201                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY  , 0); 
     202        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); 
     203                m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true); 
     204                m_creature->SetCorpseDelay(1000*60*60); 
     205                if(pInstance) 
     206                        pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, NOT_STARTED);  
     207    } 
     208 
     209        void CheckChannelers(bool DoEvade = true) 
     210        { 
     211                for(uint8 i = 0; i < 3; i++) 
     212                { 
     213                        Creature *add = (Creature*)Unit::GetUnit(*m_creature,SpellBinderGUID[i]); 
     214                        if (add && add->isAlive()) 
     215                        { 
     216                                add->setDeathState(DEAD); 
     217                add->RemoveCorpse(); 
     218                        }else{ 
     219                                if(add && add->isDead()) 
     220                                        add->RemoveCorpse(); 
     221                        } 
     222                        float nx = x; 
     223                        float ny = y; 
     224                        float o = 2.4f; 
     225                        if (i == 0) {nx += 20;o=3.0f;} 
     226                        if (i == 1) ny -= 20; 
     227                        if (i == 2) {nx += 18;ny -= 18;o=2.0f;} 
     228                        Creature* binder = m_creature->SummonCreature(MOB_SPELLBINDER,nx,ny,z,o,TEMPSUMMON_DEAD_DESPAWN,0); 
     229                        if (binder) 
     230                                SpellBinderGUID[i] = binder->GetGUID(); 
     231                         
     232                } 
     233        } 
     234        void MoveInLineOfSight(Unit *who) 
     235        { 
     236                if(m_creature->HasAura(AURA_BANISH, 0)) 
     237                        return; 
     238 
     239                if( !m_creature->getVictim() && who->isTargetableForAttack() && ( m_creature->IsHostileTo( who )) && who->isInAccessablePlaceFor(m_creature) ) 
     240                { 
     241                        if (m_creature->GetDistanceZ(who) > CREATURE_Z_ATTACK_RANGE) 
     242                                return; 
     243 
     244                        float attackRadius = m_creature->GetAttackDistance(who); 
     245                        if(m_creature->IsWithinDistInMap(who, attackRadius)) 
     246                        { 
     247                                // Check first that object is in an angle in front of this one before LoS check 
     248                                if( m_creature->HasInArc(M_PI/2.0f, who) && m_creature->IsWithinLOSInMap(who) ) 
     249                                { 
     250                                        AttackStart(who); 
     251                                        who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); 
     252                                        if (!InCombat) 
     253                                        { 
     254                                                Aggro(who); 
     255                                                InCombat = true; 
     256                                        } 
     257                                } 
     258                        } 
     259                } 
     260        } 
    84261 
    85262    void StartEvent() 
    86263    { 
    87264        DoScriptText(SAY_AGGRO, m_creature); 
    88  
    89         if (pInstance) 
     265        if(pInstance) 
    90266            pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, IN_PROGRESS); 
    91267    } 
     268 
     269        void CheckBanish() 
     270        { 
     271                uint8 AliveChannelers = 0; 
     272                for(uint8 i = 0; i < 3; i++) 
     273                { 
     274                        Unit *add = Unit::GetUnit(*m_creature,SpellBinderGUID[i]); 
     275                        if (add && add->isAlive()) 
     276                                AliveChannelers++; 
     277                } 
     278 
     279                // channelers == 0 remove banish aura 
     280                if(AliveChannelers == 0 && m_creature->HasAura(AURA_BANISH, 0)) 
     281                {        
     282                        // removing banish aura 
     283                        m_creature->RemoveAurasDueToSpell(AURA_BANISH); 
     284 
     285                        // Leotheras is getting immune again  
     286            m_creature->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, true); 
     287 
     288                        // changing model to bloodelf  
     289            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); 
     290 
     291                        // and reseting equipment 
     292                        m_creature->LoadEquipment(m_creature->GetEquipmentId()); 
     293 
     294                        if(pInstance && pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) 
     295                        { 
     296                                Unit *victim = NULL; 
     297                                victim = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)); 
     298                                if(victim) 
     299                                        m_creature->getThreatManager().addThreat(victim, 1); 
     300                                StartEvent(); 
     301                        }                
     302                } 
     303                else if(AliveChannelers != 0 && !m_creature->HasAura(AURA_BANISH, 0)) 
     304                { 
     305                        // channelers != 0 apply banish aura 
     306                        // removing Leotheras banish immune to apply AURA_BANISH 
     307            m_creature->ApplySpellImmune(AURA_BANISH, IMMUNITY_MECHANIC, MECHANIC_BANISH, false); 
     308                        DoCast(m_creature, AURA_BANISH); 
     309 
     310                        // changing model 
     311            m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON); 
     312                         
     313                        // and removing weapons 
     314            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY  , 0); 
     315            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); 
     316                } 
     317        } 
     318 
     319        //Despawn all Inner Demon summoned 
     320        void DespawnDemon() 
     321        { 
     322        for(int i=0; i<5; i++) 
     323                { 
     324            if(InnderDemon[i]) 
     325                        { 
     326                    //delete creature 
     327                    Unit* pUnit = Unit::GetUnit((*m_creature), InnderDemon[i]); 
     328                    if (pUnit && pUnit->isAlive()) 
     329                                        { 
     330                        pUnit->DealDamage(pUnit, pUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
     331                                        } 
     332                                        InnderDemon[i] = 0; 
     333                        } 
     334                } 
     335 
     336                InnderDemon_Count = 0; 
     337        } 
     338 
     339        void CastConsumingMadness()     //remove this once SPELL_INSIDIOUS_WHISPER is supported by core 
     340        { 
     341        for(int i=0; i<5; i++) 
     342                { 
     343            if(InnderDemon[i] > 0 ) 
     344                        { 
     345                Unit* pUnit = Unit::GetUnit((*m_creature), InnderDemon[i]); 
     346                if (pUnit && pUnit->isAlive()) 
     347                                { 
     348                                        Unit* pUnit_target = Unit::GetUnit((*pUnit), ((mob_inner_demonAI *)((Creature *)pUnit)->AI())->victimGUID); 
     349                                        if( pUnit_target && pUnit_target->isAlive()) 
     350                                        { 
     351                                                pUnit->CastSpell(pUnit_target, SPELL_CONSUMING_MADNESS, true); 
     352                                                m_creature->getThreatManager().modifyThreatPercent(pUnit_target, -100); 
     353                                        } 
     354                                } 
     355                        } 
     356                } 
     357        } 
    92358 
    93359    void KilledUnit(Unit *victim) 
     
    129395                pUnit->DealDamage(pUnit, pUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 
    130396        } 
    131  
    132397        if (pInstance) 
    133398            pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, DONE); 
     
    136401    void Aggro(Unit *who) 
    137402    { 
    138         StartEvent(); 
     403                if(m_creature->HasAura(AURA_BANISH, 0)) 
     404                return; 
     405 
     406                m_creature->LoadEquipment(m_creature->GetEquipmentId()); 
    139407    } 
    140408 
     
    142410    { 
    143411        //Return since we have no target 
    144         if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) 
    145             return; 
    146  
    147         if (!DemonForm) 
     412        if (m_creature->HasAura(AURA_BANISH, 0) || !m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
     413                { 
     414                        if(BanishTimer<diff) 
     415                        { 
     416                                CheckBanish();//no need to check every update tick 
     417                                BanishTimer = 1000; 
     418                        }else BanishTimer -= diff; 
     419                        return; 
     420                } 
     421                if(m_creature->HasAura(SPELL_WHIRLWIND, 0)) 
     422                        if(Whirlwind_Timer < diff) 
     423                        { 
     424                                Unit *newTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); 
     425                                if(newTarget) 
     426                                { 
     427                                        DoResetThreat();                                 
     428                                        m_creature->GetMotionMaster()->Clear(); 
     429                                        m_creature->GetMotionMaster()->MovePoint(0,newTarget->GetPositionX(),newTarget->GetPositionY(),newTarget->GetPositionZ()); 
     430                                } 
     431                                Whirlwind_Timer = 2000; 
     432                        }else Whirlwind_Timer -= diff; 
     433 
     434                // reseting after changing forms and after ending whirlwind 
     435                if(NeedThreatReset && !m_creature->HasAura(SPELL_WHIRLWIND, 0)) 
     436                {        
     437                        // when changing forms seting timers (or when ending whirlwind - to avoid adding new variable i use Whirlwind_Timer to countdown 2s while whirlwinding) 
     438                        if(DemonForm) 
     439                                InnerDemons_Timer = 30000; 
     440                        else 
     441                                Whirlwind_Timer =  15000; 
     442                         
     443                        NeedThreatReset = false; 
     444                        DoResetThreat(); 
     445                        m_creature->GetMotionMaster()->Clear(); 
     446                        m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); 
     447                } 
     448 
     449        //Enrage_Timer ( 10 min ) 
     450        if(Berserk_Timer < diff && !EnrageUsed) 
    148451        { 
    149             //Whirlwind_Timer 
    150             if (Whirlwind_Timer < diff) 
    151             { 
    152                 DoCast(m_creature, SPELL_WHIRLWIND); 
    153                 Whirlwind_Timer = 25000; 
    154             }else Whirlwind_Timer -= diff; 
    155  
     452            DoCast(m_creature, SPELL_BERSERK); 
     453                        EnrageUsed = true; 
     454        }else Berserk_Timer -= diff; 
     455 
     456        if(!DemonForm) 
     457        { 
     458                        //Whirldind Timer 
     459            if(!m_creature->HasAura(SPELL_WHIRLWIND, 0)) 
     460                        { 
     461                                if(Whirlwind_Timer < diff) 
     462                                { 
     463                                        DoCast(m_creature, SPELL_WHIRLWIND); 
     464                                        // while whirlwinding this variable is used to countdown target's change 
     465                                        Whirlwind_Timer = 2000; 
     466                                        NeedThreatReset = true; 
     467                                }else Whirlwind_Timer -= diff; 
     468                        } 
    156469            //Switch_Timer 
    157             if (!IsFinalForm) 
    158             { 
    159                 if (Switch_Timer < diff) 
     470 
     471            if(!IsFinalForm) 
     472                if(SwitchToDemon_Timer < diff) 
    160473                { 
    161474                    //switch to demon form 
    162                     m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON); 
    163                     DoScriptText(SAY_SWITCH_TO_DEMON, m_creature); 
    164                     DemonForm = true; 
    165                     Switch_Timer = 60000; 
    166                 }else Switch_Timer -= diff; 
    167             } 
    168  
     475                                        m_creature->RemoveAurasDueToSpell(SPELL_WHIRLWIND,0); 
     476                                        m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON); 
     477                                        DoScriptText(SAY_SWITCH_TO_DEMON, m_creature); 
     478                                        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY  , 0); 
     479                                    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); 
     480                                        DemonForm = true; 
     481                                        NeedThreatReset = true; 
     482                    SwitchToDemon_Timer = 45000; 
     483                }else SwitchToDemon_Timer -= diff; 
    169484            DoMeleeAttackIfReady(); 
    170485        } 
     
    172487        { 
    173488            //ChaosBlast_Timer 
    174             if (ChaosBlast_Timer < diff) 
    175             { 
    176                 DoCast(m_creature->getVictim(), SPELL_CHAOS_BLAST); 
    177                 ChaosBlast_Timer = 1500; 
    178             }else ChaosBlast_Timer -= diff; 
     489            if (!m_creature->getVictim()) 
     490                                return; 
     491                        if(m_creature->GetDistance(m_creature->getVictim()) < 30) 
     492                                m_creature->StopMoving(); 
     493                        if(ChaosBlast_Timer < diff) 
     494                        { 
     495                                // will cast only when in range of spell  
     496                                if(m_creature->GetDistance(m_creature->getVictim()) < 30) 
     497                                { 
     498                                        //m_creature->CastSpell(m_creature->getVictim(), SPELL_CHAOS_BLAST, true); 
     499                                        int damage = 100; 
     500                                        m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_CHAOS_BLAST, &damage, NULL, NULL, false, NULL, NULL, m_creature->GetGUID()); 
     501                                } 
     502                                ChaosBlast_Timer = 3000; 
     503                        }else ChaosBlast_Timer -= diff; 
     504                        //Summon Inner Demon 
     505                        if(InnerDemons_Timer < diff) 
     506                        { 
     507                                std::list<HostilReference *>& ThreatList = m_creature->getThreatManager().getThreatList(); 
     508                                std::vector<Unit *> TargetList;  
     509                                for(std::list<HostilReference *>::iterator itr = ThreatList.begin(); itr != ThreatList.end(); ++itr) 
     510                                { 
     511                                        Unit *tempTarget = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); 
     512                                        if(tempTarget && tempTarget->GetTypeId() == TYPEID_PLAYER && tempTarget->GetGUID() != m_creature->getVictim()->GetGUID() && TargetList.size()<5) 
     513                                                TargetList.push_back( tempTarget ); 
     514                                }        
     515                                SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SPELL_INSIDIOUS_WHISPER); 
     516                                for(std::vector<Unit *>::iterator itr = TargetList.begin(); itr != TargetList.end(); ++itr) 
     517                                { 
     518                                        if( (*itr) && (*itr)->isAlive() ) 
     519                                        { 
     520                                                Creature * demon = (Creature *)m_creature->SummonCreature(INNER_DEMON_ID, (*itr)->GetPositionX()+10, (*itr)->GetPositionY()+10, (*itr)->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); 
     521                                                if(demon) 
     522                                                { 
     523                                                        ((ScriptedAI *)demon->AI())->AttackStart( (*itr) ); 
     524                                                        ((mob_inner_demonAI *)demon->AI())->victimGUID = (*itr)->GetGUID(); 
     525                                                                                                                 
     526                                                        for (int i=0; i<3; i++) 
     527                                                        { 
     528                                                                if (!spell->Effect[i]) 
     529                                                                        continue; 
     530                                                                (*itr)->AddAura(new InsidiousAura(spell, i, NULL, (*itr), (*itr))); 
     531                                                        } 
     532                                                        if( InnderDemon_Count > 4 ) InnderDemon_Count = 0; 
     533 
     534                                                        //Safe storing of creatures 
     535                                                        InnderDemon[InnderDemon_Count] = demon->GetGUID(); 
     536 
     537                                                        //Update demon count 
     538                                                        InnderDemon_Count++; 
     539                                                } 
     540                                        } 
     541                                } 
     542                                DoScriptText(SAY_INNER_DEMONS, m_creature); 
     543 
     544                                InnerDemons_Timer = 999999; 
     545                        }else InnerDemons_Timer -= diff; 
    179546 
    180547            //Switch_Timer 
    181             if (Switch_Timer < diff) 
     548            if(SwitchToHuman_Timer < diff) 
    182549            { 
    183550                //switch to nightelf form 
    184551                m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); 
     552                                m_creature->LoadEquipment(m_creature->GetEquipmentId()); 
     553 
     554                                CastConsumingMadness(); 
     555                                DespawnDemon(); 
     556 
    185557                DemonForm = false; 
    186  
    187                 Switch_Timer = 45000; 
    188             }else Switch_Timer -= diff; 
    189         } 
     558                                NeedThreatReset = true; 
     559 
     560                SwitchToHuman_Timer = 60000; 
     561            }else SwitchToHuman_Timer -= diff; 
     562                } 
    190563 
    191564        if (!IsFinalForm && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 15) 
    192565        { 
    193566            //at this point he divides himself in two parts 
    194             Creature *Copy = NULL; 
    195             Copy = DoSpawnCreature(DEMON_FORM, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); 
    196  
    197             if (Copy) 
    198             { 
    199                 Demon = Copy->GetGUID(); 
    200                 Copy->AI()->AttackStart(m_creature->getVictim()); 
    201             } 
    202  
     567                        Creature *Copy = NULL; 
     568            Copy = DoSpawnCreature(DEMON_FORM, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 6000); 
     569                        if(Copy) 
     570             { 
     571                 Demon = Copy->GetGUID(); 
     572                                if (m_creature->getVictim()) 
     573                                        Copy->AI()->AttackStart(m_creature->getVictim()); 
     574                        } 
    203575            //set nightelf final form 
    204576            IsFinalForm = true; 
     
    206578 
    207579            DoScriptText(SAY_FINAL_FORM, m_creature); 
    208             m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); 
     580                m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); 
     581                        m_creature->LoadEquipment(m_creature->GetEquipmentId()); 
    209582        } 
    210583    } 
     
    220593 
    221594    uint32 ChaosBlast_Timer; 
     595        bool DealDamage; 
    222596 
    223597    void Reset() 
    224598    { 
    225599        ChaosBlast_Timer = 1000; 
     600                DealDamage = true; 
    226601    } 
    227602 
     
    260635        if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() ) 
    261636            return; 
    262  
    263637        //ChaosBlast_Timer 
    264         if (ChaosBlast_Timer < diff) 
    265         { 
    266             DoCast(m_creature->getVictim(), SPELL_CHAOS_BLAST); 
    267             ChaosBlast_Timer = 1500; 
    268         }else ChaosBlast_Timer -= diff; 
     638                if(m_creature->GetDistance(m_creature->getVictim()) < 30) 
     639                        m_creature->StopMoving(); 
     640                 
     641                if(ChaosBlast_Timer < diff) 
     642         { 
     643                        // will cast only when in range od spell  
     644                        if(m_creature->GetDistance(m_creature->getVictim()) < 30) 
     645                        { 
     646                                //m_creature->CastSpell(m_creature->getVictim(),SPELL_CHAOS_BLAST,true); 
     647                                int damage = 100; 
     648                                m_creature->CastCustomSpell(m_creature->getVictim(), SPELL_CHAOS_BLAST, &damage, NULL, NULL, false, NULL, NULL, m_creature->GetGUID());   
     649                                ChaosBlast_Timer = 3000; 
     650                        } 
     651         }else ChaosBlast_Timer -= diff; 
    269652 
    270653        //Do NOT deal any melee damage to the target. 
    271654    } 
    272655}; 
    273  
     656struct TRINITY_DLL_DECL mob_greyheart_spellbinderAI : public ScriptedAI 
     657{ 
     658        mob_greyheart_spellbinderAI(Creature *c) : ScriptedAI(c) 
     659    { 
     660                pInstance = ((ScriptedInstance *)c->GetInstanceData());; 
     661                leotherasGUID = 0; 
     662                AddedBanish = false; 
     663                Reset(); 
     664        } 
     665 
     666        ScriptedInstance *pInstance; 
     667 
     668        uint64 leotherasGUID; 
     669 
     670        uint32 Mindblast_Timer; 
     671        uint32 Earthshock_Timer; 
     672 
     673        bool AddedBanish; 
     674 
     675        void Reset() 
     676        { 
     677                Mindblast_Timer  = 3000 + rand()%5000; 
     678                Earthshock_Timer = 5000 + rand()%5000; 
     679 
     680                if(pInstance) 
     681                { 
     682                        pInstance->SetData64(DATA_LEOTHERAS_EVENT_STARTER, 0); 
     683                        Creature *leotheras = (Creature *)Unit::GetUnit(*m_creature, leotherasGUID); 
     684                        if(leotheras && leotheras->isAlive()) 
     685                                ((boss_leotheras_the_blindAI*)leotheras->AI())->CheckChannelers(false); 
     686                } 
     687        } 
     688 
     689        void Aggro(Unit *who) 
     690        { 
     691                m_creature->InterruptNonMeleeSpells(false); 
     692                if(pInstance) 
     693                        pInstance->SetData64(DATA_LEOTHERAS_EVENT_STARTER, who->GetGUID()); 
     694        } 
     695 
     696        void JustRespawned() 
     697        { 
     698                InCombat = false; 
     699                AddedBanish = false; 
     700                Reset(); 
     701        } 
     702 
     703        void CastChanneling() 
     704        { 
     705                if(!InCombat && !m_creature->m_currentSpells[CURRENT_CHANNELED_SPELL]) 
     706                { 
     707                        if(leotherasGUID) 
     708                        { 
     709                                Creature *leotheras = (Creature *)Unit::GetUnit(*m_creature, leotherasGUID); 
     710                                if(leotheras && leotheras->isAlive()) 
     711                                        DoCast(leotheras, BANISH_BEAM); 
     712                        } 
     713                } 
     714        }        
     715 
     716        void UpdateAI(const uint32 diff) 
     717        { 
     718                if(pInstance) 
     719                {        
     720                        if(!leotherasGUID) 
     721                                leotherasGUID = pInstance->GetData64(DATA_LEOTHERAS); 
     722 
     723                        if(!InCombat && pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) 
     724                        { 
     725                                Unit *victim = NULL; 
     726                                victim = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)); 
     727                                if(victim) 
     728                                        AttackStart(victim); 
     729                        } 
     730                } 
     731                 
     732                if(!m_creature->SelectHostilTarget() || !m_creature->getVictim()) 
     733                { 
     734                        CastChanneling(); 
     735                        return; 
     736                } 
     737 
     738                if(pInstance && !pInstance->GetData64(DATA_LEOTHERAS_EVENT_STARTER)) 
     739                { 
     740                        EnterEvadeMode(); 
     741                        return; 
     742                } 
     743 
     744                if(Mindblast_Timer < diff) 
     745                { 
     746                        Unit* target = NULL; 
     747            target = SelectUnit(SELECT_TARGET_RANDOM,0); 
     748 
     749                        if ( target )DoCast(target, SPELL_MINDBLAST); 
     750 
     751                        Mindblast_Timer = 10000 + rand()%5000; 
     752                }else Mindblast_Timer -= diff; 
     753 
     754                if(Earthshock_Timer < diff) 
     755                { 
     756                        Map *map = m_creature->GetMap(); 
     757                        InstanceMap::PlayerList const &PlayerList = ((InstanceMap*)map)->GetPlayers(); 
     758                        for(InstanceMap::PlayerList::const_iterator itr = PlayerList.begin();itr != PlayerList.end(); ++itr) 
     759            { 
     760                                bool isCasting = false; 
     761                                for(uint8 i = 0; i < CURRENT_MAX_SPELL; ++i) 
     762                                        if((*itr)->m_currentSpells[i]) 
     763                                                isCasting = true; 
     764                                 
     765                                if(isCasting) 
     766                                { 
     767                                        DoCast((*itr), SPELL_EARTHSHOCK); 
     768                                        break; 
     769                                } 
     770                        } 
     771                        Earthshock_Timer = 8000 + rand()%7000; 
     772                }else Earthshock_Timer -= diff; 
     773                DoMeleeAttackIfReady(); 
     774        } 
     775 
     776        void JustDied(Unit *killer)     {} 
     777}; 
    274778CreatureAI* GetAI_boss_leotheras_the_blind(Creature *_Creature) 
    275779{ 
     
    282786} 
    283787 
     788CreatureAI* GetAI_mob_greyheart_spellbinder(Creature *_Creature) 
     789{ 
     790        return new mob_greyheart_spellbinderAI (_Creature); 
     791} 
     792 
     793CreatureAI* GetAI_mob_inner_demon(Creature *_Creature) 
     794{ 
     795        return new mob_inner_demonAI (_Creature); 
     796} 
    284797void AddSC_boss_leotheras_the_blind() 
    285798{ 
     
    295808    newscript->GetAI = GetAI_boss_leotheras_the_blind_demonform; 
    296809    m_scripts[nrscripts++] = newscript; 
     810 
     811        newscript = new Script; 
     812    newscript->Name="mob_greyheart_spellbinder"; 
     813    newscript->GetAI = GetAI_mob_greyheart_spellbinder; 
     814    m_scripts[nrscripts++] = newscript; 
     815 
     816        newscript = new Script; 
     817    newscript->Name="mob_inner_demon"; 
     818    newscript->GetAI = GetAI_mob_inner_demon; 
     819    m_scripts[nrscripts++] = newscript; 
    297820} 
  • trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/def_serpent_shrine.h

    r90 r182  
    2424#define DATA_TIDALVESS 17 
    2525#define DATA_FATHOMLORDKARATHRESSEVENT 18 
     26#define DATA_LEOTHERAS 19 
     27#define DATA_LEOTHERAS_EVENT_STARTER 20 
    2628#endif 
  • trunk/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp

    r90 r182  
    1717/* ScriptData 
    1818SDName: Instance_Serpent_Shrine 
    19 SD%Complete: 0 
    20 SDComment: VERIFY SCRIPT 
     19SD%Complete: 100 
     20SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Serpent Shrine Scripts 
    2121SDCategory: Coilfang Resevoir, Serpent Shrine Cavern 
    2222EndScriptData */ 
     
    4747    uint64 KarathressEvent_Starter; 
    4848 
     49        uint64 LeotherasTheBlind; 
     50        uint64 LeotherasEventStarter; 
     51 
    4952    bool ShieldGeneratorDeactivated[4]; 
    5053 
     
    6063        KarathressEvent_Starter = 0; 
    6164 
     65                LeotherasTheBlind = 0; 
     66                LeotherasEventStarter = 0; 
     67 
    6268        ShieldGeneratorDeactivated[0] = false; 
    6369        ShieldGeneratorDeactivated[1] = false; 
     
    8187        switch(creature_entry) 
    8288        { 
    83             case 21212: LadyVashj = creature->GetGUID(); break; 
    84             case 21214: Karathress = creature->GetGUID(); break; 
    85             case 21966: Sharkkis = creature->GetGUID(); break; 
    86             case 21965: Tidalvess = creature->GetGUID(); break; 
    87             case 21964: Caribdis = creature->GetGUID(); break; 
    88         } 
     89            case 21212: LadyVashj = creature->GetGUID();                        break; 
     90            case 21214: Karathress = creature->GetGUID();                       break; 
     91            case 21966: Sharkkis = creature->GetGUID();                         break; 
     92            case 21965: Tidalvess = creature->GetGUID();                        break; 
     93            case 21964: Caribdis = creature->GetGUID();                         break; 
     94                        case 21215:     LeotherasTheBlind = creature->GetGUID();        break;} 
    8995    } 
    9096 
     
    9298    { 
    9399        if(type == DATA_KARATHRESSEVENT_STARTER) 
    94             KarathressEvent_Starter = data; 
     100                        KarathressEvent_Starter = data; 
     101                if(type == DATA_LEOTHERAS_EVENT_STARTER) 
     102                        LeotherasEventStarter = data; 
    95103    } 
    96104 
     
    99107        switch(identifier) 
    100108        { 
    101             case DATA_SHARKKIS: 
    102                 return Sharkkis; 
    103             case DATA_TIDALVESS: 
    104                 return Tidalvess; 
    105             case DATA_CARIBDIS: 
    106                 return Caribdis; 
    107             case DATA_LADYVASHJ: 
    108                 return LadyVashj; 
    109             case DATA_KARATHRESS: 
    110                 return Karathress; 
    111             case DATA_KARATHRESSEVENT_STARTER: 
    112                 return KarathressEvent_Starter; 
     109            case DATA_SHARKKIS:                                 return Sharkkis; 
     110                        case DATA_TIDALVESS:                            return Tidalvess; 
     111            case DATA_CARIBDIS:                                 return Caribdis; 
     112            case DATA_LADYVASHJ:                                return LadyVashj; 
     113            case DATA_KARATHRESS:                               return Karathress; 
     114            case DATA_KARATHRESSEVENT_STARTER:  return KarathressEvent_Starter; 
     115                        case DATA_LEOTHERAS:                            return LeotherasTheBlind; 
     116                        case DATA_LEOTHERAS_EVENT_STARTER:      return LeotherasEventStarter; 
    113117        } 
    114118        return 0; 
     
    119123        switch(type) 
    120124        { 
    121             case DATA_HYDROSSTHEUNSTABLEEVENT: 
    122                 Encounters[0] = (data) ? true : false; 
    123                 break; 
    124  
    125             case DATA_LEOTHERASTHEBLINDEVENT: 
    126                 Encounters[1] = (data) ? true : false; 
    127                 break; 
    128  
    129             case DATA_THELURKERBELOWEVENT: 
    130                 Encounters[2] = (data) ? true : false; 
    131                 break; 
    132  
    133             case DATA_KARATHRESSEVENT: 
    134                 Encounters[3] = (data) ? true : false; 
    135                 break; 
    136  
    137             case DATA_MOROGRIMTIDEWALKEREVENT: 
    138                 Encounters[4] = (data) ? true : false; 
    139                 break; 
     125            case DATA_HYDROSSTHEUNSTABLEEVENT:  Encounters[0] = data;   break; 
     126            case DATA_LEOTHERASTHEBLINDEVENT:   Encounters[1] = data;   break; 
     127            case DATA_THELURKERBELOWEVENT:              Encounters[2] = data;   break; 
     128            case DATA_KARATHRESSEVENT:                  Encounters[3] = data;   break; 
     129            case DATA_MOROGRIMTIDEWALKEREVENT:  Encounters[4] = data;   break; 
    140130                //Lady Vashj 
    141131            case DATA_LADYVASHJEVENT: 
    142                 if(data == 0) 
     132                if(data == NOT_STARTED) 
    143133                { 
    144134                    ShieldGeneratorDeactivated[0] = false; 
     
    147137                    ShieldGeneratorDeactivated[3] = false; 
    148138                } 
    149                 Encounters[5] = (data) ? true : false; 
    150                 break; 
    151  
    152             case DATA_SHIELDGENERATOR1: 
    153                 ShieldGeneratorDeactivated[0] = (data) ? true : false; 
    154                 break; 
    155  
    156             case DATA_SHIELDGENERATOR2: 
    157                 ShieldGeneratorDeactivated[1] = (data) ? true : false; 
    158                 break; 
    159  
    160             case DATA_SHIELDGENERATOR3: 
    161                 ShieldGeneratorDeactivated[2] = (data) ? true : false; 
    162                 break; 
    163  
    164             case DATA_SHIELDGENERATOR4: 
    165                 ShieldGeneratorDeactivated[3] = (data) ? true : false; 
    166                 break; 
    167         } 
     139                Encounters[5] = data;   break; 
     140            case DATA_SHIELDGENERATOR1:ShieldGeneratorDeactivated[0] = (data) ? true : false;   break; 
     141            case DATA_SHIELDGENERATOR2:ShieldGeneratorDeactivated[1] = (data) ? true : false;   break; 
     142            case DATA_SHIELDGENERATOR3:ShieldGeneratorDeactivated[2] = (data) ? true : false;   break; 
     143            case DATA_SHIELDGENERATOR4:ShieldGeneratorDeactivated[3] = (data) ? true : false;   break; 
     144        } 
     145                if(data = DONE) 
     146                        SaveToDB(); 
    168147    } 
    169148 
     
    172151        switch(type) 
    173152        { 
    174             case DATA_HYDROSSTHEUNSTABLEEVENT: 
    175                 return Encounters[0]; 
    176  
    177             case DATA_LEOTHERASTHEBLINDEVENT: 
    178                 return Encounters[1]; 
    179  
    180             case DATA_THELURKERBELOWEVENT: 
    181                 return Encounters[2]; 
    182  
    183             case DATA_KARATHRESSEVENT: 
    184                 return Encounters[3]; 
    185  
    186             case DATA_MOROGRIMTIDEWALKEREVENT: 
    187                 return Encounters[4]; 
    188  
     153            case DATA_HYDROSSTHEUNSTABLEEVENT:  return Encounters[0]; 
     154            case DATA_LEOTHERASTHEBLINDEVENT:   return Encounters[1]; 
     155            case DATA_THELURKERBELOWEVENT:              return Encounters[2]; 
     156            case DATA_KARATHRESSEVENT:                  return Encounters[3]; 
     157            case DATA_MOROGRIMTIDEWALKEREVENT:  return Encounters[4]; 
    189158                //Lady Vashj 
    190             case DATA_LADYVASHJEVENT: 
    191                 return Encounters[5]; 
    192  
    193             case DATA_SHIELDGENERATOR1: 
    194                 return ShieldGeneratorDeactivated[0]; 
    195  
    196             case DATA_SHIELDGENERATOR2: 
    197                 return ShieldGeneratorDeactivated[1]; 
    198  
    199             case DATA_SHIELDGENERATOR3: 
    200                 return ShieldGeneratorDeactivated[2]; 
    201  
    202             case DATA_SHIELDGENERATOR4: 
    203                 return ShieldGeneratorDeactivated[3]; 
    204  
     159            case DATA_LADYVASHJEVENT:                   return Encounters[5]; 
     160            case DATA_SHIELDGENERATOR1:                 return ShieldGeneratorDeactivated[0]; 
     161            case DATA_SHIELDGENERATOR2:                 return ShieldGeneratorDeactivated[1]; 
     162            case DATA_SHIELDGENERATOR3:                 return ShieldGeneratorDeactivated[2]; 
     163            case DATA_SHIELDGENERATOR4:                 return ShieldGeneratorDeactivated[3]; 
    205164            case DATA_CANSTARTPHASE3: 
    206                 if(ShieldGeneratorDeactivated[0] && ShieldGeneratorDeactivated[1] && ShieldGeneratorDeactivated[2] && ShieldGeneratorDeactivated[3]) 
    207                     return 1; 
    208                 break; 
    209         } 
    210  
     165                                if(ShieldGeneratorDeactivated[0] && ShieldGeneratorDeactivated[1] && ShieldGeneratorDeactivated[2] && ShieldGeneratorDeactivated[3])return 1;break; 
     166        } 
    211167        return 0; 
     168    } 
     169        const char* Save() 
     170        { 
     171                OUT_SAVE_INST_DATA; 
     172        std::ostringstream stream; 
     173        stream << Encounters[0] << " " << Encounters[1] << " " << Encounters[2] << " " 
     174            << Encounters[3] << " " << Encounters[4] << " " << Encounters[5]; 
     175        char* out = new char[stream.str().length() + 1]; 
     176        strcpy(out, stream.str().c_str()); 
     177        if(out) 
     178        { 
     179            OUT_SAVE_INST_DATA_COMPLETE; 
     180            return out; 
     181        } 
     182        return NULL; 
     183    } 
     184 
     185    void Load(const char* in) 
     186    { 
     187        if(!in) 
     188        { 
     189            OUT_LOAD_INST_DATA_FAIL; 
     190            return; 
     191        } 
     192        OUT_LOAD_INST_DATA(in); 
     193        std::istringstream stream(in); 
     194        stream >> Encounters[0] >> Encounters[1] >> Encounters[2] >> Encounters[3] 
     195                >> Encounters[4] >> Encounters[5]; 
     196                for(uint8 i = 0; i < ENCOUNTERS; ++i) 
     197                        if(Encounters[i] == IN_PROGRESS)                // Do not load an encounter as "In Progress" - reset it instead. 
     198                                Encounters[i] = NOT_STARTED; 
     199                OUT_LOAD_INST_DATA_COMPLETE; 
    212200    } 
    213201};