void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        if (CloseDoorTimer)
        {
            if (CloseDoorTimer <= diff)
            {
                if (pInstance)
                {
                    pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_LIBRARY_DOOR), false);
                    CloseDoorTimer = 0;
                }
            }
            else CloseDoorTimer -= diff;
        }

        //Cooldowns for casts
        if (ArcaneCooldown)
        {
            if (ArcaneCooldown >= diff)
                ArcaneCooldown -= diff;
            else ArcaneCooldown = 2000;
        }

        if (FireCooldown)
        {
            if (FireCooldown >= diff)
                FireCooldown -= diff;
            else FireCooldown = 2000;
        }

        if (FrostCooldown)
        {
            if (FrostCooldown >= diff)
                FrostCooldown -= diff;
            else FrostCooldown = 2000;
        }

        if (!Drinking && me->GetMaxPower(POWER_MANA) && (me->GetPower(POWER_MANA) * 100 / me->GetMaxPower(POWER_MANA)) < 20)
        {
            Drinking = true;
            me->InterruptNonMeleeSpells(false);

            DoScriptText(SAY_DRINK, me);

            if (!DrinkInturrupted)
            {
                DoCast(me, SPELL_MASS_POLY, true);
                DoCast(me, SPELL_CONJURE, false);
                DoCast(me, SPELL_DRINK, false);
                me->SetStandState(UNIT_STAND_STATE_SIT);
                DrinkInturruptTimer = 10000;
            }
        }

        //Drink Inturrupt
        if (Drinking && DrinkInturrupted)
        {
            Drinking = false;
            me->RemoveAurasDueToSpell(SPELL_DRINK);
            me->SetStandState(UNIT_STAND_STATE_STAND);
            me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA) - 32000);
            DoCast(me, SPELL_POTION, false);
        }

        //Drink Inturrupt Timer
        if (Drinking && !DrinkInturrupted)
            if (DrinkInturruptTimer >= diff)
                DrinkInturruptTimer -= diff;
            else
            {
                me->SetStandState(UNIT_STAND_STATE_STAND);
                DoCast(me, SPELL_POTION, true);
                DoCast(me, SPELL_AOE_PYROBLAST, false);
                DrinkInturrupted = true;
                Drinking = false;
            }

        //Don't execute any more code if we are drinking
        if (Drinking)
            return;

        //Normal casts
        if (NormalCastTimer <= diff)
        {
            if (!me->IsNonMeleeSpellCast(false))
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
                if (!target)
                    return;

                uint32 Spells[3];
                uint8 AvailableSpells = 0;

                //Check for what spells are not on cooldown
                if (!ArcaneCooldown)
                {
                    Spells[AvailableSpells] = SPELL_ARCMISSLE;
                    ++AvailableSpells;
                }
                if (!FireCooldown)
                {
                    Spells[AvailableSpells] = SPELL_FIREBALL;
                    ++AvailableSpells;
                }
                if (!FrostCooldown)
                {
                    Spells[AvailableSpells] = SPELL_FROSTBOLT;
                    ++AvailableSpells;
                }

                //If no available spells wait 1 second and try again
                if (AvailableSpells)
                {
                    CurrentNormalSpell = Spells[rand() % AvailableSpells];
                    SetImmune(false);
                    DoCast(target, CurrentNormalSpell);
                }
            }
            NormalCastTimer = 2500;
        }
        else NormalCastTimer -= diff;

        if (SecondarySpellTimer <= diff)
        {
            switch (urand(0, 1))
            {
            case 0:
                DoCast(me, SPELL_AOE_CS);
                break;
            case 1:
                if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0))
                    DoCast(pUnit, SPELL_CHAINSOFICE);
                break;
            case 2:
                if (Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 0))
                    DoCast(pUnit, SPELL_DRAGONSBREATH);
                break;
            }
            SecondarySpellTimer = urand(3000, 8000);
        }
        else SecondarySpellTimer -= diff;

        if (SuperCastTimer <= diff)
        {
            uint8 Available[2];

            switch (LastSuperSpell)
            {
                case SUPER_AE:
                    Available[0] = SUPER_FLAME;
                    Available[1] = SUPER_BLIZZARD;
                    break;
                case SUPER_FLAME:
                    Available[0] = SUPER_AE;
                    Available[1] = SUPER_BLIZZARD;
                    break;
                case SUPER_BLIZZARD:
                    Available[0] = SUPER_FLAME;
                    Available[1] = SUPER_AE;
                    break;
            }

            LastSuperSpell = Available[urand(0, 1)];
            SetImmune(true);
 
            Map::PlayerList const &PlayerList = pInstance->instance->GetPlayers();
            WorldPacket data;
            switch (LastSuperSpell)
            {
            case SUPER_AE:
                DoScriptText(RAND(SAY_EXPLOSION1, SAY_EXPLOSION2), me);

                DoCast(me, SPELL_BLINK_CENTER, true);
                DoCast(me, SPELL_PLAYERPULL, true);
                DoCast(me, SPELL_MASSSLOW, true);
                DoCast(me, SPELL_ARCANE_BUBBLE, true);
                me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
                me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);
                AETimer = 1500;
                CastAE = true;
                break;

            case SUPER_FLAME:
                DoScriptText(RAND(SAY_FLAMEWREATH1, SAY_FLAMEWREATH2), me);

                FlameWreathTimer = 20000;
                FlameWreathCheckTime = 500;

                FlameWreathTarget[0] = 0;
                FlameWreathTarget[1] = 0;
                FlameWreathTarget[2] = 0;

                FlameWreathEffect();
                SecondarySpellTimer = 20500;
                break;

            case SUPER_BLIZZARD:
                DoScriptText(RAND(SAY_BLIZZARD1, SAY_BLIZZARD2), me);

                Creature* Blizzard = NULL;
                Blizzard = me->SummonCreature(NPC_ARAN_BLIZZARD, -11179.080f, -1905.279f, 232.008f, 2.9f, TEMPSUMMON_TIMED_DESPAWN, 25000);
                if (Blizzard)
                {
                    Blizzard->SetInCombatWithZone();
                    Blizzard->SetFaction(me->GetFaction());
                    me->CastSpell(Blizzard, SPELL_SUMMON_BLIZZ, false);
                    Blizzard->CastSpell(Blizzard, SPELL_CIRCULAR_BLIZZARD, false);
                    Blizzard->GetMotionMaster()->MovePath(110110101, false);
                }
                break;
            }

            SuperCastTimer = urand(35000, 40000);
        }
        else SuperCastTimer -= diff;

        if (!ElementalsSpawned && HealthBelowPct(40))
        {
            ElementalsSpawned = true;

            Creature* ElementalOne   = NULL;
            Creature* ElementalTwo   = NULL;
            Creature* ElementalThree = NULL;
            Creature* ElementalFour  = NULL;

            ElementalOne     = me->SummonCreature(NPC_WATER_ELEMENTAL, -11168.1f, -1939.29f, 232.092f, 1.46f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000);
            ElementalTwo     = me->SummonCreature(NPC_WATER_ELEMENTAL, -11138.2f, -1915.38f, 232.092f, 3.00f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000);
            ElementalThree   = me->SummonCreature(NPC_WATER_ELEMENTAL, -11161.7f, -1885.36f, 232.092f, 4.59f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000);
            ElementalFour    = me->SummonCreature(NPC_WATER_ELEMENTAL, -11192.4f, -1909.36f, 232.092f, 6.19f, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000);

            if (ElementalOne)
            {
                Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                if (!pTarget)
                    return;

                DoStartNoMovement(pTarget);
                ElementalOne->SetInCombatWithZone();
                ElementalOne->CombatStart(pTarget);
                ElementalOne->SetFaction(me->GetFaction());
                ElementalOne->SetRooted(true);
                ElementalOne->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
                ElementalOne->SetModifierValue(UNIT_MOD_RESISTANCE_FROST,  BASE_VALUE, 0);
            }

            if (ElementalTwo)
            {
                Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                if (!pTarget)
                    return;

                DoStartNoMovement(pTarget);
                ElementalTwo->SetInCombatWithZone();
                ElementalTwo->CombatStart(pTarget);
                ElementalTwo->SetFaction(me->GetFaction());
                ElementalTwo->SetRooted(true);
                ElementalTwo->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
                ElementalTwo->SetModifierValue(UNIT_MOD_RESISTANCE_FROST,  BASE_VALUE, 0);
            }

            if (ElementalThree)
            {
                Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                if (!pTarget)
                    return;

                DoStartNoMovement(pTarget);
                ElementalThree->SetInCombatWithZone();
                ElementalThree->CombatStart(pTarget);
                ElementalThree->SetFaction(me->GetFaction());
                ElementalThree->SetRooted(true);
                ElementalThree->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
                ElementalThree->SetModifierValue(UNIT_MOD_RESISTANCE_FROST,  BASE_VALUE, 0);
            }

            if (ElementalFour)
            {
                Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                if (!pTarget)
                    return;

                DoStartNoMovement(pTarget);
                ElementalFour->SetInCombatWithZone();
                ElementalFour->CombatStart(pTarget);
                ElementalFour->SetFaction(me->GetFaction());
                ElementalFour->SetRooted(true);
                ElementalFour->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
                ElementalFour->SetModifierValue(UNIT_MOD_RESISTANCE_FROST,  BASE_VALUE, 0);
            }

            DoScriptText(SAY_ELEMENTALS, me);
            DoScriptText(SAY_TIMEOVER, me);

            BerserkTimer = 60000;
        }
        else BerserkTimer -= diff;

        //Flame Wreath check
        if (FlameWreathTimer)
        {
            if (FlameWreathTimer >= diff)
                FlameWreathTimer -= diff;
            else FlameWreathTimer = 0;

            if (FlameWreathCheckTime <= diff)
            {
                for (uint8 i = 0; i < 3; ++i)
                {
                    if (!FlameWreathTarget[i])
                        continue;

                    Unit* unit = Unit::GetUnit(*me, FlameWreathTarget[i]);
                    if (unit && !unit->IsWithinDist2d(FWTargPosX[i], FWTargPosY[i], 3))
                    {
                        unit->CastSpell(unit, 20476, true, 0, 0, me->GetGUID());
                        unit->CastSpell(unit, 11027, true);
                        FlameWreathTarget[i] = 0;
                    }
                }
                FlameWreathCheckTime = 500;
            }
            else FlameWreathCheckTime -= diff;
        }

        if (ArcaneCooldown && FireCooldown && FrostCooldown && DragonsbreathCooldown)
            DoMeleeAttackIfReady();

        if (CastAE)
            if (AETimer < diff)
            {
                me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, true);
                me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true);
                me->CastSpell(me, SPELL_AEXPLOSION, false);
                AETimer = 1500;
                CastAE = false;
            }
            else AETimer -= diff;
    }
示例#2
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        DoSpecialThings(diff, DO_COMBAT_N_EVADE, 135.0f);

        if (!evocating && m_creature->GetPower(POWER_MANA) <= 1000)
        {
            evocating = true;
            ForceSpellCastWithScriptText(SPELL_EVOCATION, CAST_SELF, SAY_EVOCATE);
        }

        if (!enraged && !evocating)
        {
            if (addTimer < diff)
            {
                //Summon Astral Flare
                Creature* astralFlare = DoSpawnCreature(17096, rand()%37, rand()%37, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
                Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);

                if (astralFlare && target)
                {
                    astralFlare->CastSpell(astralFlare, SPELL_ASTRAL_FLARE_PASSIVE, false);
                    astralFlare->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_ARCANE, true);
                    astralFlare->AI()->AttackStart(target);
                }

                //Reduce Mana by 10%
                int32 mana = (int32)(0.1f*(m_creature->GetMaxPower(POWER_MANA)));
                m_creature->ModifyPower(POWER_MANA, -mana);

                DoScriptText(RAND(SAY_SUMMON1, SAY_SUMMON2, 0, 0), m_creature);

                addTimer = 10000;
            }
            else
                addTimer -= diff;

            if (hatefulBoltTimer < diff)
            {
                AddSpellToCast(SPELL_HATEFUL_BOLT, CAST_THREAT_SECOND);
                hatefulBoltTimer = enraged ? 7000 : 15000;
            }
            else
                hatefulBoltTimer -= diff;

            if (!enraged && HealthBelowPct(15))
            {
                enraged = true;
                ForceSpellCastWithScriptText(SPELL_ENRAGE, CAST_SELF, SAY_ENRAGE);
            }
        }

        if (berserkTimer < diff)
        {
            ForceSpellCastWithScriptText(SPELL_BERSERK, CAST_SELF, SAY_ENRAGE);
            berserkTimer = 60000;
        }
        else
            berserkTimer -= diff;

        CastNextSpellIfAnyAndReady();

        if (!evocating)
            DoMeleeAttackIfReady();
    }