void MindControlGhost()
        {
            /************************************************************************/
            /** NOTE FOR FUTURE DEVELOPER: PROPERLY IMPLEMENT THE GHOST PORTION *****/
            /**  ONLY AFTER TrinIty FULLY IMPLEMENTS MIND CONTROL ABILITIES      *****/
            /**   THE CURRENT CODE IN THIS FUNCTION IS ONLY THE BEGINNING OF    *****/
            /**    WHAT IS FULLY NECESSARY FOR GOREFIEND TO BE 100% COMPLETE    *****/
            /************************************************************************/

            Unit* Ghost = NULL;
            if(GhostGUID)
                Ghost = Unit::GetUnit((*me), GhostGUID);
            if(Ghost && Ghost->isAlive() && Ghost->HasAura(SPELL_SHADOW_OF_DEATH))
            {
                for(uint8 i = 0; i < 4; ++i)
                {
                    Creature* Construct = NULL;
                    float X = CalculateRandomLocation(Ghost->GetPositionX(), 10);
                    float Y = CalculateRandomLocation(Ghost->GetPositionY(), 10);
                    Construct = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, Y, Ghost->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
                    if(Construct)
                    {
                        Construct->CastSpell(Construct, SPELL_PASSIVE_SHADOWFORM, true);
                        SetThreatList(Construct);               // Use same function as Doom Blossom to set Threat List.
                        CAST_AI(mob_shadowy_construct::mob_shadowy_constructAI, Construct->AI())->GhostGUID = GhostGUID;
                        Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                        if(!target)                             // someone's trying to solo.
                            target = me->getVictim();

                        if(target)
                            Construct->GetMotionMaster()->MoveChase(target);
                    }
                }
            }
        }
    void JustSummoned(Creature* pSummoned)
    {
        switch (pSummoned->GetEntry())
        {
            case NPC_FLAME_STRIKE_TRIGGER:
                pSummoned->CastSpell(pSummoned, SPELL_FLAME_STRIKE_DUMMY, false, NULL, NULL, m_creature->GetObjectGuid());
                break;
            case NPC_PHOENIX:
                // TODO ThreatList and Flag removal likely wrong
                pSummoned->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
                SetThreatList(pSummoned);

                if (m_creature->getVictim())
                    pSummoned->AI()->AttackStart(m_creature->getVictim());
                break;
        }
    }
        void MindControlGhost()
        {
            /************************************************************************/
            /** NOTE FOR FUTURE DEVELOPER: PROPERLY IMPLEMENT THE GHOST PORTION *****/
            /**  ONLY AFTER TrinIty FULLY IMPLEMENTS MIND CONTROL ABILITIES      *****/
            /**   THE CURRENT CODE IN THIS FUNCTION IS ONLY THE BEGINNING OF    *****/
            /**    WHAT IS FULLY NECESSARY FOR GOREFIEND TO BE 100% COMPLETE    *****/
            /************************************************************************/

            Unit* ghost = NULL;
            if (GhostGUID)
                ghost = ObjectAccessor::GetUnit(*me, GhostGUID);
            if (ghost && ghost->IsAlive() && ghost->HasAura(SPELL_SHADOW_OF_DEATH))
            {
                /*float x, y, z;
                ghost->GetPosition(x, y, z);
                if (Creature* control = me->SummonCreature(CREATURE_GHOST, x, y, z, 0, TEMPSUMMON_TIMED_DESAWN, 30000))
                {
                    if (Player* player = ghost->ToPlayer())
                        player->Possess(control);
                    ghost->DealDamage(ghost, ghost->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL,
                false);
                }*/
                for (uint8 i = 0; i < 4; ++i)
                {
                    Creature* Construct = NULL;
                    float X = CalculateRandomLocation(ghost->GetPositionX(), 10);
                    float Y = CalculateRandomLocation(ghost->GetPositionY(), 10);
                    Construct = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, Y, ghost->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
                    if (Construct)
                    {
                        Construct->CastSpell(Construct, SPELL_PASSIVE_SHADOWFORM, true);
                        SetThreatList(Construct);               // Use same function as Doom Blossom to set Threat List.
                        CAST_AI(npc_shadowy_construct::npc_shadowy_constructAI, Construct->AI())->GhostGUID = GhostGUID;
                        Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                        if (!target)                             // someone's trying to solo.
                            target = me->GetVictim();

                        if (target)
                            Construct->GetMotionMaster()->MoveChase(target);
                    }
                }
            }
        }
    void MindControlGhost()
    {
        /************************************************************************/
        /** NOTE FOR FUTURE DEVELOPER: PROPERLY IMPLEMENT THE GHOST PORTION *****/
        /**  ONLY AFTER MaNGOS FULLY IMPLEMENTS MIND CONTROL ABILITIES      *****/
        /**   THE CURRENT CODE IN THIS FUNCTION IS ONLY THE BEGINNING OF    *****/
        /**    WHAT IS FULLY NECESSARY FOR GOREFIEND TO BE 100% COMPLETE    *****/
        /************************************************************************/

        Player* pGhost = NULL;
        if (m_ghostGuid)
            pGhost = m_creature->GetMap()->GetPlayer(m_ghostGuid);

        if (pGhost && pGhost->isAlive() && pGhost->HasAura(SPELL_SHADOW_OF_DEATH, EFFECT_INDEX_0))
        {
            /*float x,y,z;
            pGhost->GetPosition(x,y,z);
            Creature* control = m_creature->SummonCreature(CREATURE_GHOST, x, y, z, 0, TEMPSUMMON_TIMED_DESAWN, 30000);
            if (control)
            {
                ((Player*)pGhost)->Possess(control);
                pGhost->DealDamage(pGhost, pGhost->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL,
            false);
            }*/
            for(uint8 i = 0; i < 4; ++i)
            {
                float fX = CalculateRandomLocation(pGhost->GetPositionX(), 10);
                float fY = CalculateRandomLocation(pGhost->GetPositionY(), 10);

                if (Creature* pConstruct = m_creature->SummonCreature(NPC_SHADOWY_CONSTRUCT, fX, fY, pGhost->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000))
                {
                    pConstruct->CastSpell(pConstruct, SPELL_PASSIVE_SHADOWFORM, true);

                    SetThreatList(pConstruct);               // Use same function as Doom Blossom to set Threat List.
                    if (mob_shadowy_constructAI* pConstructAI = dynamic_cast<mob_shadowy_constructAI*>(pConstruct->AI()))
                        pConstructAI->m_ghostGuid = m_ghostGuid;

                    Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1);
                    pConstruct->GetMotionMaster()->MoveChase(pTarget ? pTarget : m_creature->getVictim());
                }
            }
        }
    }
    void UpdateAI(const uint32 diff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        switch(Phase)
        {
            case 0:
            {
                // *Heroic mode only:
                if (!m_bIsRegularMode)
                {
                    if (PyroblastTimer < diff)
                    {
                        m_creature->InterruptSpell(CURRENT_CHANNELED_SPELL);
                        m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);
                        DoCastSpellIfCan(m_creature, SPELL_SHOCK_BARRIER, CAST_TRIGGERED);
                        DoCastSpellIfCan(m_creature->getVictim(), SPELL_PYROBLAST);
                        PyroblastTimer = 60000;
						FireballTimer += 6000;
						FlameStrikeTimer += 6000;
                    }else PyroblastTimer -= diff;
                }

                if (FireballTimer < diff)
                {
                    DoCastSpellIfCan(m_creature->getVictim(), m_bIsRegularMode ? SPELL_FIREBALL_NORMAL : SPELL_FIREBALL_HEROIC);
                    FireballTimer = urand(2000, 6000);
                }else FireballTimer -= diff;

                if (PhoenixTimer < diff)
                {

                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,1))
                    {
                        uint32 random = urand(1, 2);
                        float x = KaelLocations[random][0];
                        float y = KaelLocations[random][1];

                        if (Creature* Phoenix = m_creature->SummonCreature(CREATURE_PHOENIX, x, y, LOCATION_Z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000))
                        {
                            Phoenix->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
                            SetThreatList(Phoenix);
                            Phoenix->AI()->AttackStart(pTarget);
                            DoScriptText(SAY_PHOENIX, m_creature);
                        }
                    }

                    PhoenixTimer = 60000;
                }else PhoenixTimer -= diff;

                if (FlameStrikeTimer < diff)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (m_creature->IsNonMeleeSpellCasted(false))
                            m_creature->InterruptNonMeleeSpells(false);

                        DoCastSpellIfCan(pTarget, SPELL_FLAME_STRIKE);
                        DoScriptText(SAY_FLAMESTRIKE, m_creature);
                    }
                    FlameStrikeTimer = urand(15000, 25000);
                }else FlameStrikeTimer -= diff;

                // Below 50%
                if (m_creature->GetHealth() * 2 < m_creature->GetMaxHealth())
                {
                    m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
                    m_creature->StopMoving();
                    m_creature->GetMotionMaster()->Clear();
                    m_creature->GetMotionMaster()->MoveIdle();
                    GravityLapseTimer = 0;
                    GravityLapsePhase = 0;
                    Phase = 1;
                }

                DoMeleeAttackIfReady();
            }
            break;

            case 1:
            {
                if (GravityLapseTimer < diff)
                {
                    switch(GravityLapsePhase)
                    {
                        case 0:
                            if (FirstGravityLapse)          // Different yells at 50%, and at every following Gravity Lapse
                            {
                                DoScriptText(SAY_GRAVITY_LAPSE, m_creature);
                                FirstGravityLapse = false;

                                if (m_pInstance)
                                {
                                    if (GameObject* pKaelLeft = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_KAEL_STATUE_LEFT)))
                                        pKaelLeft->SetGoState(GO_STATE_ACTIVE);

                                    if (GameObject* pKaelRight = m_pInstance->instance->GetGameObject(m_pInstance->GetData64(DATA_KAEL_STATUE_RIGHT)))
                                        pKaelRight->SetGoState(GO_STATE_ACTIVE);
                                }
                            }
                            else
                            {
                                DoScriptText(SAY_RECAST_GRAVITY, m_creature);
                            }

                            DoCastSpellIfCan(m_creature, SPELL_GRAVITY_LAPSE_INITIAL);
                            GravityLapseTimer = 2000 + diff;// Don't interrupt the visual spell
                            GravityLapsePhase = 1;
                            break;

                        case 1:
                            TeleportPlayersToSelf();
                            GravityLapseTimer = 1000;
                            GravityLapsePhase = 2;
                            break;

                        case 2:
                            CastGravityLapseKnockUp();
                            GravityLapseTimer = 1000;
                            GravityLapsePhase = 3;
                            break;

                        case 3:
                            CastGravityLapseFly();
                            GravityLapseTimer = 30000;
                            GravityLapsePhase = 4;


                            for(uint8 i = 0; i < 3; ++i)
                            {
                                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM,0))
                                {
                                    if (Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000))
                                        Orb->AI()->AttackStart(pTarget);
                                }
                            }

                            DoCastSpellIfCan(m_creature, SPELL_GRAVITY_LAPSE_CHANNEL);
                            break;

                        case 4:
                            m_creature->InterruptNonMeleeSpells(false);
                            DoScriptText(SAY_TIRED, m_creature);
                            DoCastSpellIfCan(m_creature, SPELL_POWER_FEEDBACK);
                            RemoveGravityLapse();
                            GravityLapseTimer = 10000;
                            GravityLapsePhase = 0;
                            break;
                    }
                }else GravityLapseTimer -= diff;
            }
            break;
        }
    }
Example #6
0
        void UpdateAI(uint32 diff)
        {
            //Return since we have no target
            if (!UpdateVictim())
                return;

            switch (Phase)
            {
                case 0:
                {
                    // *Heroic mode only:
                    if (IsHeroic())
                    {
                        if (PyroblastTimer <= diff)
                        {
                            me->InterruptSpell(CURRENT_CHANNELED_SPELL);
                            me->InterruptSpell(CURRENT_GENERIC_SPELL);
                            DoCast(me, SPELL_SHOCK_BARRIER, true);
                            DoCast(me->getVictim(), SPELL_PYROBLAST);
                            PyroblastTimer = 60000;
                        } else PyroblastTimer -= diff;
                    }

                    if (FireballTimer <= diff)
                    {
                        DoCast(me->getVictim(), SPELL_FIREBALL_NORMAL);
                        FireballTimer = urand(2000, 6000);
                    } else FireballTimer -= diff;

                    if (PhoenixTimer <= diff)
                    {
                        Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);

                        uint8 random = urand(1, 2);
                        float x = KaelLocations[random][0];
                        float y = KaelLocations[random][1];

                        Creature* Phoenix = me->SummonCreature(CREATURE_PHOENIX, x, y, LOCATION_Z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
                        if (Phoenix)
                        {
                            Phoenix->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
                            SetThreatList(Phoenix);
                            Phoenix->AI()->AttackStart(target);
                        }

                        Talk(SAY_PHOENIX);

                        PhoenixTimer = 60000;
                    } else PhoenixTimer -= diff;

                    if (FlameStrikeTimer <= diff)
                    {
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                        {
                            me->InterruptSpell(CURRENT_CHANNELED_SPELL);
                            me->InterruptSpell(CURRENT_GENERIC_SPELL);
                            DoCast(target, SPELL_FLAMESTRIKE3, true);
                            Talk(SAY_FLAMESTRIKE);
                        }
                        FlameStrikeTimer = urand(15000, 25000);
                    } else FlameStrikeTimer -= diff;

                    // Below 50%
                    if (HealthBelowPct(50))
                    {
                        me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
                        me->StopMoving();
                        me->GetMotionMaster()->Clear();
                        me->GetMotionMaster()->MoveIdle();
                        GravityLapseTimer = 0;
                        GravityLapsePhase = 0;
                        Phase = 1;
                    }

                    DoMeleeAttackIfReady();
                }
                break;

                case 1:
                {
                    if (GravityLapseTimer <= diff)
                    {
                        switch (GravityLapsePhase)
                        {
                            case 0:
                                if (FirstGravityLapse)          // Different yells at 50%, and at every following Gravity Lapse
                                {
                                    Talk(SAY_GRAVITY_LAPSE);
                                    FirstGravityLapse = false;

                                    if (instance)
                                        instance->SetData(DATA_KAELTHAS_STATUES, 1);
                                }
                                else
                                    Talk(SAY_RECAST_GRAVITY);

                                DoCast(me, SPELL_GRAVITY_LAPSE_INITIAL);
                                GravityLapseTimer = 2000 + diff;// Don't interrupt the visual spell
                                GravityLapsePhase = 1;
                                break;

                            case 1:
                                TeleportPlayersToSelf();
                                GravityLapseTimer = 1000;
                                GravityLapsePhase = 2;
                                break;

                            case 2:
                                CastGravityLapseKnockUp();
                                GravityLapseTimer = 1000;
                                GravityLapsePhase = 3;
                                break;

                            case 3:
                                CastGravityLapseFly();
                                GravityLapseTimer = 30000;
                                GravityLapsePhase = 4;

                                for (uint8 i = 0; i < 3; ++i)
                                {
                                    Unit* target = NULL;
                                    target = SelectTarget(SELECT_TARGET_RANDOM, 0);

                                    Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
                                    if (Orb && target)
                                    {
                                        Orb->SetSpeed(MOVE_RUN, 0.5f);
                                        Orb->AddThreat(target, 1000000.0f);
                                        Orb->AI()->AttackStart(target);
                                    }
                                }

                                DoCast(me, SPELL_GRAVITY_LAPSE_CHANNEL);
                                break;

                            case 4:
                                me->InterruptNonMeleeSpells(false);
                                Talk(SAY_TIRED);
                                DoCast(me, SPELL_POWER_FEEDBACK);
                                RemoveGravityLapse();
                                GravityLapseTimer = 10000;
                                GravityLapsePhase = 0;
                                break;
                        }
                    } else GravityLapseTimer -= diff;
                }
                break;
            }
        }
        void UpdateAI(const uint32 diff)
        {
            if (Intro && !Done)
            {
                if (AggroTimer <= diff)
                {
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    DoScriptText(SAY_AGGRO, me);
                    me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
                    Done = true;
                    if (AggroTargetGUID)
                    {
                        Unit* pUnit = Unit::GetUnit((*me), AggroTargetGUID);
                        if (pUnit)
                            AttackStart(pUnit);

                        DoZoneInCombat();
                    }
                    else
                    {
                        EnterEvadeMode();
                        return;
                    }
                } else AggroTimer -= diff;
            }

            if (!UpdateVictim() || !Done)
                return;

            if (SummonShadowsTimer <= diff)
            {
                //MindControlGhost();

                for (uint8 i = 0; i < 2; ++i)
                {
                    Creature* Shadow = NULL;
                    float X = CalculateRandomLocation(me->GetPositionX(), 10);
                    Shadow = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0);
                    if (Shadow)
                    {
                        Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
                        if (!pTarget)
                            pTarget = me->getVictim();

                        if (pTarget)
                            Shadow->AI()->AttackStart(pTarget);
                    }
                }
                SummonShadowsTimer = 60000;
            } else SummonShadowsTimer -= diff;

            if (SummonDoomBlossomTimer <= diff)
            {
                if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
                {
                    float X = CalculateRandomLocation(pTarget->GetPositionX(), 20);
                    float Y = CalculateRandomLocation(pTarget->GetPositionY(), 20);
                    float Z = pTarget->GetPositionZ();
                    Z = me->GetMap()->GetHeight(X, Y, Z);
                    Creature* DoomBlossom = me->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
                    if (DoomBlossom)
                    {
                        DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                        DoomBlossom->setFaction(me->getFaction());
                        DoomBlossom->AddThreat(pTarget, 1.0f);
                        CAST_AI(mob_doom_blossom::mob_doom_blossomAI, DoomBlossom->AI())->SetTeronGUID(me->GetGUID());
                        pTarget->CombatStart(DoomBlossom);
                        SetThreatList(DoomBlossom);
                        SummonDoomBlossomTimer = 35000;
                    }
                }
            } else SummonDoomBlossomTimer -= diff;

            if (IncinerateTimer <= diff)
            {
                Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
                if (!pTarget)
                    pTarget = me->getVictim();

                if (pTarget)
                {
                    DoScriptText(RAND(SAY_SPECIAL1, SAY_SPECIAL2), me);
                    DoCast(pTarget, SPELL_INCINERATE);
                    IncinerateTimer = 20000 + rand()%31 * 1000;
                }
            } else IncinerateTimer -= diff;

            if (CrushingShadowsTimer <= diff)
            {
                Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                if (pTarget && pTarget->isAlive())
                    DoCast(pTarget, SPELL_CRUSHING_SHADOWS);
                CrushingShadowsTimer = 10000 + rand()%16 * 1000;
            } else CrushingShadowsTimer -= diff;

            /*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/
            /*if (ShadowOfDeathTimer <= diff)
            {
                Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);

                if (!pTarget)
                   pTarget = me->getVictim();

                if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
                {
                    DoCast(pTarget, SPELL_SHADOW_OF_DEATH);
                    GhostGUID = pTarget->GetGUID();
                    ShadowOfDeathTimer = 30000;
                    SummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the player
                }
            } else ShadowOfDeathTimer -= diff;*/

            if (RandomYellTimer <= diff)
            {
                DoScriptText(RAND(SAY_SPELL1, SAY_SPELL2), me);
                RandomYellTimer = 50000 + rand()%51 * 1000;
            } else RandomYellTimer -= diff;

            if (!me->HasAura(SPELL_BERSERK))
            {
                if (EnrageTimer <= diff)
            {
                DoCast(me, SPELL_BERSERK);
                DoScriptText(SAY_ENRAGE, me);
            } else EnrageTimer -= diff;
            }

            DoMeleeAttackIfReady();
        }
    void UpdateAI(const uint32 diff)
    {
        //Return since we have no target
        if (!UpdateVictim())
            return;

        switch(Phase)
        {
            case 0:
            {
                // *Heroic mode only:
                if (Heroic)
                {
                    if (PyroblastTimer < diff)
                    {
                        DoCast(m_creature, SPELL_SHOCK_BARRIER, true);
                        DoCast(m_creature->getVictim(), SPELL_PYROBLAST);
                        PyroblastTimer = 60000;
                    }else PyroblastTimer -= diff;
                }

                if (FireballTimer < diff)
                {
                    DoCast(m_creature->getVictim(), Heroic ? SPELL_FIREBALL_HEROIC : SPELL_FIREBALL_NORMAL);
                    FireballTimer = 2000 + rand()%4000;
                }else FireballTimer -= diff;

                if (PhoenixTimer < diff)
                {

                    Unit* target = NULL;
                    target = SelectUnit(SELECT_TARGET_RANDOM,1);

                    uint32 random = rand()%2 + 1;
                    float x = KaelLocations[random][0];
                    float y = KaelLocations[random][1];

                    Creature* Phoenix = m_creature->SummonCreature(CREATURE_PHOENIX, x, y, LOCATION_Z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
                    if (Phoenix)
                    {
                        Phoenix->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE + UNIT_FLAG_NON_ATTACKABLE);
                        SetThreatList(Phoenix);
                        Phoenix->AI()->AttackStart(target);
                    }

                    DoScriptText(SAY_PHOENIX, m_creature);

                    PhoenixTimer = 60000;
                }else PhoenixTimer -= diff;

                if (FlameStrikeTimer < diff)
                {
                    if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
                    {
                        DoCast(target, SPELL_FLAMESTRIKE3, true);
                        DoScriptText(SAY_FLAMESTRIKE, m_creature);
                    }
                    FlameStrikeTimer = 15000 + rand()%10000;
                }else FlameStrikeTimer -= diff;

                // Below 50%
                if (m_creature->GetMaxHealth() * 0.5 > m_creature->GetHealth())
                {
                    m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
                    m_creature->StopMoving();
                    m_creature->GetMotionMaster()->Clear();
                    m_creature->GetMotionMaster()->MoveIdle();
                    GravityLapseTimer = 0;
                    GravityLapsePhase = 0;
                    Phase = 1;
                }

                DoMeleeAttackIfReady();
            }
            break;

            case 1:
            {
                if (GravityLapseTimer < diff)
                {
                    switch(GravityLapsePhase)
                    {
                        case 0:
                            if (FirstGravityLapse)          // Different yells at 50%, and at every following Gravity Lapse
                            {
                                DoScriptText(SAY_GRAVITY_LAPSE, m_creature);
                                FirstGravityLapse = false;

                                if (pInstance)
                                {
                                    GameObject* KaelLeft = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_KAEL_STATUE_LEFT));
                                    if (KaelLeft) KaelLeft->SetGoState(GO_STATE_ACTIVE);
                                    GameObject* KaelRight = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_KAEL_STATUE_RIGHT));
                                    if (KaelRight) KaelRight->SetGoState(GO_STATE_ACTIVE);
                                }
                            }else
                            {
                                DoScriptText(SAY_RECAST_GRAVITY, m_creature);
                            }

                            DoCast(m_creature, SPELL_GRAVITY_LAPSE_INITIAL);
                            GravityLapseTimer = 2000 + diff;// Don't interrupt the visual spell
                            GravityLapsePhase = 1;
                            break;

                        case 1:
                            TeleportPlayersToSelf();
                            GravityLapseTimer = 1000;
                            GravityLapsePhase = 2;
                            break;

                        case 2:
                            CastGravityLapseKnockUp();
                            GravityLapseTimer = 1000;
                            GravityLapsePhase = 3;
                            break;

                        case 3:
                            CastGravityLapseFly();
                            GravityLapseTimer = 30000;
                            GravityLapsePhase = 4;


                            for(uint8 i = 0; i < 3; ++i)
                            {
                                Unit* target = NULL;
                                target = SelectUnit(SELECT_TARGET_RANDOM,0);

                                Creature* Orb = DoSpawnCreature(CREATURE_ARCANE_SPHERE, 5, 5, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
                                if (Orb && target)
                                {
                                    //SetThreatList(Orb);
                                    Orb->AddThreat(target, 1.0f);
                                    Orb->AI()->AttackStart(target);
                                }

                            }

                            DoCast(m_creature, SPELL_GRAVITY_LAPSE_CHANNEL);
                            break;

                        case 4:
                            m_creature->InterruptNonMeleeSpells(false);
                            DoScriptText(SAY_TIRED, m_creature);
                            DoCast(m_creature, SPELL_POWER_FEEDBACK);
                            RemoveGravityLapse();
                            GravityLapseTimer = 10000;
                            GravityLapsePhase = 0;
                            break;
                    }
                }else GravityLapseTimer -= diff;
            }
            break;
        }
    }
    void UpdateAI(const uint32 uiDiff)
    {
        if (m_bIntro)
        {
            if (m_uiAggroTimer < uiDiff)
            {
                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);

                DoScriptText(SAY_AGGRO, m_creature);

                m_creature->HandleEmote(EMOTE_STATE_NONE);
                m_bIntro = false;
                if (m_aggroTargetGuid)
                {
                    if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_aggroTargetGuid))
                        AttackStart(pPlayer);

                    m_creature->SetInCombatWithZone();
                }
                else
                    EnterEvadeMode();
            }
            else
                m_uiAggroTimer -= uiDiff;
        }

        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() || m_bIntro)
            return;

        if (m_uiSummonShadowsTimer < uiDiff)
        {
            //MindControlGhost();
            for(uint8 i = 0; i < 2; ++i)
            {
                float fX = CalculateRandomLocation(m_creature->GetPositionX(), 10);

                if (Creature* pShadow = m_creature->SummonCreature(NPC_SHADOWY_CONSTRUCT, fX, m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0))
                {
                    Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1);
                    pShadow->AI()->AttackStart(pTarget ? pTarget : m_creature->getVictim());
                }
            }
            m_uiSummonShadowsTimer = 60000;
        }
        else
            m_uiSummonShadowsTimer -= uiDiff;

        if (m_uiSummonDoomBlossomTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
            {
                float fX = CalculateRandomLocation(pTarget->GetPositionX(), 20);
                float fY = CalculateRandomLocation(pTarget->GetPositionY(), 20);

                if (Creature* pDoomBlossom = m_creature->SummonCreature(NPC_DOOM_BLOSSOM, fX, fY, pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000))
                {
                    pDoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    pDoomBlossom->setFaction(m_creature->getFaction());
                    pDoomBlossom->AddThreat(pTarget);

                    if (mob_doom_blossomAI* pDoomBlossomAI = dynamic_cast<mob_doom_blossomAI*>(pDoomBlossom->AI()))
                        pDoomBlossomAI->SetTeronGUID(m_creature->GetObjectGuid());

                    SetThreatList(pDoomBlossom);
                }

                m_uiSummonDoomBlossomTimer = 35000;
            }
        }
        else
            m_uiSummonDoomBlossomTimer -= uiDiff;

        if (m_uiIncinerateTimer < uiDiff)
        {
            DoScriptText(urand(0, 1) ? SAY_SPECIAL1 : SAY_SPECIAL2, m_creature);

            Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1);
            DoCastSpellIfCan(pTarget ? pTarget : m_creature->getVictim(), SPELL_INCINERATE);
            m_uiIncinerateTimer = urand(20000, 50000);
        }
        else
            m_uiIncinerateTimer -= uiDiff;

        if (m_uiCrushingShadowsTimer < uiDiff)
        {
            Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
            if (pTarget && pTarget->isAlive())
                DoCastSpellIfCan(pTarget, SPELL_CRUSHING_SHADOWS);

            m_uiCrushingShadowsTimer = urand(10000, 26000);
        }
        else
            m_uiCrushingShadowsTimer -= uiDiff;

        /*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/
        /*if (m_uiShadowOfDeathTimer < uiDiff)
        {
            Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1);

            if (!pTarget)
               pTarget = m_creature->getVictim();

            if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
            {
                DoCastSpellIfCan(pTarget, SPELL_SHADOW_OF_DEATH);
                m_ghostGuid = pTarget->GetObjectGuid();
                m_uiShadowOfDeathTimer = 30000;
                m_uiSummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the pPlayer
            }
        }else m_uiShadowOfDeathTimer -= uiDiff;*/

        if (m_uiRandomYellTimer < uiDiff)
        {
            DoScriptText(urand(0, 1) ? SAY_SPELL1 : SAY_SPELL2, m_creature);
            m_uiRandomYellTimer = urand(50000, 100000);
        }
        else
            m_uiRandomYellTimer -= uiDiff;

        if (!m_creature->HasAura(SPELL_BERSERK, EFFECT_INDEX_0))
        {
            if (m_uiEnrageTimer < uiDiff)
            {
                DoCastSpellIfCan(m_creature, SPELL_BERSERK);
                DoScriptText(SAY_ENRAGE, m_creature);
            }
            else
                m_uiEnrageTimer -= uiDiff;
        }

        DoMeleeAttackIfReady();
    }