Esempio n. 1
0
        void UpdateAI(const uint32 diff)
        {
            if (!me->isInCombat())
            {
                if (pInstance)
                {
                    // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished.
                    if ((pInstance->GetData(DATA_AZGALOREVENT) < DONE) && (me->IsVisible() || (me->getFaction() != 35)))
                    {
                        me->SetVisible(false);
                        me->setFaction(35);
                    }
                    else if ((pInstance->GetData(DATA_AZGALOREVENT) >= DONE) && (!me->IsVisible() || (me->getFaction() == 35)))
                    {
                        me->setFaction(1720);
                        me->SetVisible(true);
                    }
                }

                if (DrainNordrassilTimer <= diff)
                {
                    if (!IsChanneling)
                    {
                        Creature *temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000);

                        if (temp)
                            WorldTreeGUID = temp->GetGUID();

                        if (Unit *Nordrassil = Unit::GetUnit(*me, WorldTreeGUID))
                        {
                            Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                            Nordrassil->SetDisplayId(11686);
                            DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE);
                            IsChanneling = true;
                        }
                    }

                    if (Unit *Nordrassil = Unit::GetUnit(*me, WorldTreeGUID))
                    {
                        Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true);
                        DrainNordrassilTimer = 1000;
                    }
                } else DrainNordrassilTimer -= diff;
            }

            if (!UpdateVictim())
                return;

            if (me->HealthBelowPct(10) && !BelowTenPercent && !Enraged)
                BelowTenPercent = true;

            if (!Enraged)
            {
                if (EnrageTimer <= diff)
                {
                    if (HealthAbovePct(10))
                    {
                        me->GetMotionMaster()->Clear(false);
                        me->GetMotionMaster()->MoveIdle();
                        Enraged = true;
                        DoScriptText(SAY_ENRAGE, me);
                    }
                } else EnrageTimer -= diff;

                if (CheckDistanceTimer <= diff)
                {
                    // To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature
                    Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000);
                    if (Check)
                    {
                        Check->SetVisible(false);

                        if (me->IsWithinDistInMap(Check, 75))
                        {
                            me->GetMotionMaster()->Clear(false);
                            me->GetMotionMaster()->MoveIdle();
                            Enraged = true;
                            DoScriptText(SAY_ENRAGE, me);
                        }
                    }
                    CheckDistanceTimer = 5000;
                } else CheckDistanceTimer -= diff;
            }

            if (BelowTenPercent)
            {
                if (!HasProtected)
                {
                    me->GetMotionMaster()->Clear(false);
                    me->GetMotionMaster()->MoveIdle();

                    //all members of raid must get this buff
                    DoCast(me->getVictim(), SPELL_PROTECTION_OF_ELUNE);
                    HasProtected = true;
                    Enraged = true;
                }

                if (SummonWispTimer <= diff)
                {
                    DoSpawnCreature(CREATURE_ANCIENT_WISP, float(rand()%40), float(rand()%40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                    SummonWispTimer = 1500;
                    ++WispCount;
                } else SummonWispTimer -= diff;

                if (WispCount >= 30)
                    me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            }

            if (Enraged)
            {
                if (HandOfDeathTimer <= diff)
                {
                    DoCast(me->getVictim(), SPELL_HAND_OF_DEATH);
                    HandOfDeathTimer = 2000;
                } else HandOfDeathTimer -= diff;
                return;                                         // Don't do anything after this point.
            }

            if (SoulChargeCount)
            {
                if (SoulChargeTimer <= diff)
                    UnleashSoulCharge();
                else SoulChargeTimer -= diff;
            }

            if (GripOfTheLegionTimer <= diff)
            {
                DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION);
                GripOfTheLegionTimer = urand(5000,25000);
            } else GripOfTheLegionTimer -= diff;

            if (AirBurstTimer <= diff)
            {
                if (urand(0,1))
                    DoScriptText(SAY_AIR_BURST1, me);
                else
                    DoScriptText(SAY_AIR_BURST2, me);

                DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank
                AirBurstTimer = urand(25000,40000);
            } else AirBurstTimer -= diff;

            if (FearTimer <= diff)
            {
                DoCast(me->getVictim(), SPELL_FEAR);
                FearTimer = 42000;
            } else FearTimer -= diff;

            if (DoomfireTimer <= diff)
            {
                if (urand(0,1))
                    DoScriptText(SAY_DOOMFIRE1, me);
                else
                    DoScriptText(SAY_DOOMFIRE2, me);

                Unit *temp = SelectUnit(SELECT_TARGET_RANDOM, 1);
                if (!temp)
                    temp = me->getVictim();

                //replace with spell cast 31903 once implicitTarget 73 implemented
                SummonDoomfire(temp);

                //supposedly three doomfire can be up at the same time
                DoomfireTimer = 20000;
            } else DoomfireTimer -= diff;

            if (MeleeRangeCheckTimer <= diff)
            {
                if (CanUseFingerOfDeath())
                {
                    DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
                    MeleeRangeCheckTimer = 1000;
                }

                MeleeRangeCheckTimer = 5000;
            } else MeleeRangeCheckTimer -= diff;

            DoMeleeAttackIfReady();
        }
        void ExecuteEvent(uint32 eventId) override
        {
            switch (eventId)
            {
                case EVENT_HAND_OF_DEATH:
                    DoCastAOE(SPELL_HAND_OF_DEATH);
                    events.ScheduleEvent(EVENT_HAND_OF_DEATH, 2000);
                    break;
                case EVENT_UNLEASH_SOUL_CHARGE:
                    _chargeSpell = 0;
                    _unleashSpell = 0;
                    me->InterruptNonMeleeSpells(false);
                    switch (urand(0, 2))
                    {
                        case 0:
                            _chargeSpell = SPELL_SOUL_CHARGE_RED;
                            _unleashSpell = SPELL_UNLEASH_SOUL_RED;
                            break;
                        case 1:
                            _chargeSpell = SPELL_SOUL_CHARGE_YELLOW;
                            _unleashSpell = SPELL_UNLEASH_SOUL_YELLOW;
                            break;
                        case 2:
                            _chargeSpell = SPELL_SOUL_CHARGE_GREEN;
                            _unleashSpell = SPELL_UNLEASH_SOUL_GREEN;
                            break;
                    }

                    if (me->HasAura(_chargeSpell))
                    {
                        me->RemoveAuraFromStack(_chargeSpell);
                        DoCastVictim(_unleashSpell);
                        SoulChargeCount--;
                        events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000));
                    }
                    break;
                case EVENT_FINGER_OF_DEATH:
                    if (!SelectTarget(SELECT_TARGET_RANDOM, 0, 5.0f)) // Checks if there are no targets in melee range
                    {
                        DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
                        events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 1000);
                    }
                    else
                        events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 5000);
                    break;
                case EVENT_GRIP_OF_THE_LEGION:
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        DoCast(target, SPELL_GRIP_OF_THE_LEGION);
                    events.ScheduleEvent(EVENT_GRIP_OF_THE_LEGION, urand(5000, 25000));
                    break;
                case EVENT_AIR_BURST:
                    Talk(SAY_AIR_BURST);
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
                        DoCast(target, SPELL_AIR_BURST); //not on tank
                    events.ScheduleEvent(EVENT_AIR_BURST, urand(25000, 40000));
                    break;
                case EVENT_FEAR:
                    DoCastAOE(SPELL_FEAR);
                    events.ScheduleEvent(EVENT_FEAR, 42000);
                    break;
                case EVENT_DOOMFIRE:
                    Talk(SAY_DOOMFIRE);
                    if (Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1))
                        SummonDoomfire(temp);
                    else
                        SummonDoomfire(me->GetVictim());
                    events.ScheduleEvent(EVENT_DOOMFIRE, 20000);
                    break;
                case EVENT_DISTANCE_CHECK:
                    if (Creature* channelTrigger = instance->GetCreature(DATA_CHANNEL_TARGET))
                        if (me->IsWithinDistInMap(channelTrigger, 75.0f))
                            DoAction(ACTION_ENRAGE);
                    events.ScheduleEvent(EVENT_DISTANCE_CHECK, 5000);
                    break;
                case EVENT_SUMMON_WHISP:
                    DoSpawnCreature(NPC_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                    ++WispCount;
                    if (WispCount >= 30)
                        me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                    events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500);
                    break;
                default:
                    break;
            }
        }