Пример #1
0
    void CastBunnySpell(Creature* pTarget, uint32 uSpell)
    {
        if (!uSpell)
            return;

        std::list<Creature*> creatureList;
        GetCreatureListWithEntryInGrid(creatureList, m_creature, NPC_VIMGOL_VISUAL_BUNNY, 200.0f);
        for (auto& bunny : creatureList)
            for (auto it = m_uiBunnyGuids.begin(); it != m_uiBunnyGuids.end(); ++it)
                if ((*it) == bunny->GetObjectGuid())
                    if (m_uiActiveCircles[std::distance(m_uiBunnyGuids.begin(), it)])
                        bunny->CastSpell(pTarget ? pTarget : bunny, uSpell, TRIGGERED_OLD_TRIGGERED);
    }
Пример #2
0
    npc_vimgol_visual_bunnyAI(Creature* pCreature) : ScriptedAI(pCreature)
    {
        m_pMap = (ScriptedMap*)pCreature->GetInstanceData();

        GuidVector bunnyGuids;

        if (m_pMap)
        {
            m_pMap->GetCreatureGuidVectorFromStorage(m_creature->GetEntry(), bunnyGuids);

            for (auto it = bunnyGuids.begin(); it != bunnyGuids.end(); ++it)
                if ((*it) == m_creature->GetObjectGuid())
                    m_uiBunnyId = std::distance(bunnyGuids.begin(), it);
        }

        Reset();
    }
Пример #3
0
    uint8 playersInsideCircles()
    {
        uint32 tmpAuras[5] = {
            SPELL_VIMGOL_POP_TEST_A, SPELL_VIMGOL_POP_TEST_B, SPELL_VIMGOL_POP_TEST_C,
            SPELL_VIMGOL_POP_TEST_D, SPELL_VIMGOL_POP_TEST_E
        };
        uint8 tmpCounter = 0;

        if (m_uiBunnyGuids.size() < 5 && m_pMap)
        {
            m_uiBunnyGuids.clear();
            m_pMap->GetCreatureGuidVectorFromStorage(NPC_VIMGOL_VISUAL_BUNNY, m_uiBunnyGuids);
        }

        for (int i = 0; i < 5; i++)
            m_uiActiveCircles[i] = false;

        std::list<Player*> playerList;
        GetPlayerListWithEntryInWorld(playerList, m_creature, 30);
        for (auto itr = playerList.begin(); itr != playerList.end(); ++itr)
        {
            if (!(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_A) && !(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_B) && !(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_C) &&
                !(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_D) && !(*itr)->HasAura(SPELL_VIMGOL_POP_TEST_E))
                continue;

            for (auto it = m_uiBunnyGuids.begin(); it != m_uiBunnyGuids.end(); ++it)
            {
                for (int i = 0; i < 5; ++i)
                {
                    if (!(*itr)->GetAura(tmpAuras[i], SpellEffectIndex(0)))
                        continue;

                    if ((*it) != (*itr)->GetAura(tmpAuras[i], SpellEffectIndex(0))->GetCasterGuid())
                        continue;

                    m_uiActiveCircles[std::distance(m_uiBunnyGuids.begin(), it)] = true;
                }
            }
        }

        for (int i = 0; i < 5; i++)
            if (m_uiActiveCircles[i])
                ++tmpCounter;

        return tmpCounter;
    }
 void AddJustAggroed(Unit* pWho)
 {
     // Let all adds attack
     for (GuidVector::const_iterator itr = m_vAddGuids.begin(); itr != m_vAddGuids.end(); ++itr)
     {
         Creature* pAdd = m_creature->GetMap()->GetCreature(*itr);
         if (pAdd && !pAdd->getVictim())
             pAdd->AI()->AttackStart(pWho);
     }
 }
        // Note: this should be done by creature linkin in core
        void DoDespawnAdds()
        {
            for (GuidVector::const_iterator itr = m_vAddGuids.begin(); itr != m_vAddGuids.end(); ++itr)
            {
                if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
                {
                    pTemp->ForcedDespawn();
                }
            }

            m_vAddGuids.clear();

            for (GuidVector::const_iterator itr = m_vAssassinGuids.begin(); itr != m_vAssassinGuids.end(); ++itr)
            {
                if (Creature* pTemp = m_creature->GetMap()->GetCreature(*itr))
                {
                    pTemp->ForcedDespawn();
                }
            }

            m_vAssassinGuids.clear();
        }
        void Cleanup(Creature* infernal, InfernalPoint *point)
        {
            for (GuidVector::iterator itr = infernals.begin(); itr!= infernals.end(); ++itr)
            {
                if (*itr == infernal->GetGUID())
                {
                    infernals.erase(itr);
                    break;
                }
            }

            positions.push_back(point);
        }
        void InfernalCleanup()
        {
            //Infernal Cleanup
            for (GuidVector::const_iterator itr = infernals.begin(); itr != infernals.end(); ++itr)
                if (Unit* pInfernal = ObjectAccessor::GetUnit(*me, *itr))
                    if (pInfernal->IsAlive())
                    {
                        pInfernal->SetVisible(false);
                        pInfernal->setDeathState(JUST_DIED);
                    }

            infernals.clear();
        }
    void JustDied(Unit* /*pKiller*/) override
    {
        for (GuidVector::const_iterator itr = m_vSnoboldGuidsVector.begin(); itr != m_vSnoboldGuidsVector.end(); ++itr)
        {
            if (Creature* pSnobold = m_creature->GetMap()->GetCreature(*itr))
            {
                if (!pSnobold->isAlive())
                    continue;

                // ToDo: check if there is any player vehicle mounting involved
                SendAIEvent(AI_EVENT_CUSTOM_EVENTAI_A, m_creature, pSnobold);
            }
        }
    }
    void DoSetupAdds()
    {
        m_uiSetupAddsTimer = 0;

        if (!m_pInstance)
            return;

        GuidList lAddGuids;
        m_pInstance->GetKelidanAddList(lAddGuids);

        // Sort Adds to vector if not already done
        if (!lAddGuids.empty())
        {
            m_vAddGuids.reserve(lAddGuids.size());
            std::list<Creature*> lAdds;
            for (GuidList::const_iterator itr = lAddGuids.begin(); itr != lAddGuids.end(); ++itr)
            {
                if (Creature* pAdd = m_pInstance->instance->GetCreature(*itr))
                    lAdds.push_back(pAdd);
            }
            // Sort them by angle
            lAdds.sort(SortByAngle(m_creature));
            for (std::list<Creature*>::const_iterator itr = lAdds.begin(); itr != lAdds.end(); ++itr)
                m_vAddGuids.push_back((*itr)->GetObjectGuid());
        }

        // Respawn killed adds and reset counter
        m_uiKilledAdds = 0;
        for (GuidVector::const_iterator itr = m_vAddGuids.begin(); itr != m_vAddGuids.end(); ++itr)
        {
            Creature* pAdd = m_pInstance->instance->GetCreature(*itr);
            if (pAdd && !pAdd->isAlive())
                pAdd->Respawn();
        }

        // Cast pentagram
        uint8 s = m_vAddGuids.size();
        for (uint8 i = 0; i < s; ++i)
        {
            Creature* pCaster = m_pInstance->instance->GetCreature(m_vAddGuids[i]);
            Creature* pTarget = m_pInstance->instance->GetCreature(m_vAddGuids[(i + 2) % s]);
            if (pCaster && pTarget)
                pCaster->CastSpell(pTarget, SPELL_CHANNELING, TRIGGERED_NONE);
        }

        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
        m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
    }
    // Wrapper to remove Gravity Lapse - this should be removed on aura 44251 expires
    void RemoveGravityLapse()
    {
        GuidVector vGuids;
        m_creature->FillGuidsListFromThreatList(vGuids);

        for (GuidVector::const_iterator itr = vGuids.begin(); itr != vGuids.end(); ++itr)
        {
            Unit* pUnit = m_creature->GetMap()->GetUnit(*itr);

            if (pUnit && pUnit->GetTypeId() == TYPEID_PLAYER)
            {
                pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_FLY);
                pUnit->RemoveAurasDueToSpell(SPELL_GRAVITY_LAPSE_DOT);
            }
        }
    }
        // Wrapper to teleport all players to the platform - Workaround for missing spell
        void DoTeleportToPlatform()
        {
            m_creature->NearTeleportTo(aVorpilTeleportLoc[0], aVorpilTeleportLoc[1], aVorpilTeleportLoc[2], 0.0f);

            float fX, fY, fZ;

            GuidVector vGuids;
            m_creature->FillGuidsListFromThreatList(vGuids);
            for (GuidVector::const_iterator itr = vGuids.begin(); itr != vGuids.end(); ++itr)
            {
                Unit* pTarget = m_creature->GetMap()->GetUnit(*itr);

                if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER)
                {
                    pTarget->GetRandomPoint(aVorpilTeleportLoc[0], aVorpilTeleportLoc[1], aVorpilTeleportLoc[2], 4.0f, fX, fY, fZ);
                    DoTeleportPlayer(pTarget, fX, fY, fZ, m_creature->GetAngle(fX, fY));
                }
            }
        }
Пример #12
0
    void UpdateAI(const uint32 uiDiff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // Shimmer Timer Timer
        if (m_uiShimmerTimer < uiDiff)
        {
            // Remove old vulnerability spell
            if (m_uiCurrentVulnerabilitySpell)
                m_creature->RemoveAurasDueToSpell(m_uiCurrentVulnerabilitySpell);

            // Cast new random vurlnabilty on self
            uint32 aSpellId[] = {SPELL_FIRE_VULNERABILITY, SPELL_FROST_VULNERABILITY, SPELL_SHADOW_VULNERABILITY, SPELL_NATURE_VULNERABILITY, SPELL_ARCANE_VULNERABILITY};
            uint32 uiSpell = aSpellId[urand(0, 4)];

            if (DoCastSpellIfCan(m_creature, uiSpell) == CAST_OK)
            {
                m_uiCurrentVulnerabilitySpell = uiSpell;

                DoScriptText(EMOTE_SHIMMER, m_creature);
                m_uiShimmerTimer = 45000;
            }
        }
        else
            m_uiShimmerTimer -= uiDiff;

        // Breath One Timer
        if (m_uiBreathOneTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, m_uiBreathOneSpell) == CAST_OK)
                m_uiBreathOneTimer = 60000;
        }
        else
            m_uiBreathOneTimer -= uiDiff;

        // Breath Two Timer
        if (m_uiBreathTwoTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, m_uiBreathTwoSpell) == CAST_OK)
                m_uiBreathTwoTimer = 60000;
        }
        else
            m_uiBreathTwoTimer -= uiDiff;

        // Affliction Timer
        if (m_uiAfflictionTimer < uiDiff)
        {
            uint32 m_uiSpellAfflict = 0;

            switch (urand(0, 4))
            {
                case 0: m_uiSpellAfflict = SPELL_BROODAF_BLUE; break;
                case 1: m_uiSpellAfflict = SPELL_BROODAF_BLACK; break;
                case 2: m_uiSpellAfflict = SPELL_BROODAF_RED; break;
                case 3: m_uiSpellAfflict = SPELL_BROODAF_BRONZE; break;
                case 4: m_uiSpellAfflict = SPELL_BROODAF_GREEN; break;
            }

            GuidVector vGuids;
            m_creature->FillGuidsListFromThreatList(vGuids);
            for (GuidVector::const_iterator i = vGuids.begin(); i != vGuids.end(); ++i)
            {
                Unit* pUnit = m_creature->GetMap()->GetUnit(*i);

                if (pUnit)
                {
                    // Cast affliction
                    DoCastSpellIfCan(pUnit, m_uiSpellAfflict, CAST_TRIGGERED);

                    // Chromatic mutation if target is effected by all afflictions
                    if (pUnit->HasAura(SPELL_BROODAF_BLUE, EFFECT_INDEX_0)
                            && pUnit->HasAura(SPELL_BROODAF_BLACK, EFFECT_INDEX_0)
                            && pUnit->HasAura(SPELL_BROODAF_RED, EFFECT_INDEX_0)
                            && pUnit->HasAura(SPELL_BROODAF_BRONZE, EFFECT_INDEX_0)
                            && pUnit->HasAura(SPELL_BROODAF_GREEN, EFFECT_INDEX_0))
                    {
                        // target->RemoveAllAuras();
                        // DoCastSpellIfCan(target,SPELL_CHROMATIC_MUT_1);

                        // Chromatic mutation is causing issues
                        // Assuming it is caused by a lack of core support for Charm
                        // So instead we instant kill our target

                        // WORKAROUND
                        if (pUnit->GetTypeId() == TYPEID_PLAYER)
                            m_creature->CastSpell(pUnit, 5, false);
                    }
                }
            }

            m_uiAfflictionTimer = 10000;
        }
        else
            m_uiAfflictionTimer -= uiDiff;

        // Frenzy Timer
        if (m_uiFrenzyTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_FRENZY) == CAST_OK)
            {
                DoScriptText(EMOTE_GENERIC_FRENZY_KILL, m_creature);
                m_uiFrenzyTimer = urand(10000, 15000);
            }
        }
        else
            m_uiFrenzyTimer -= uiDiff;

        // Enrage if not already enraged and below 20%
        if (!m_bEnraged && m_creature->GetHealthPercent() < 20.0f)
        {
            DoCastSpellIfCan(m_creature, SPELL_ENRAGE);
            m_bEnraged = true;
        }

        DoMeleeAttackIfReady();
    }
Пример #13
0
    void UpdateAI(const uint32 uiDiff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // When Solarian reaches 20% she will transform into a huge void walker.
        if (m_Phase != PHASE_VOID && m_creature->GetHealthPercent() < 20.0f)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_SOLARIAN_TRANSFORM) == CAST_OK)
            {
                DoScriptText(SAY_VOIDA, m_creature);
                m_uiDelayTimer = 2000;

                m_creature->SetArmor(WV_ARMOR);
                m_Phase = PHASE_VOID;

                if (m_creature->GetVisibility() != VISIBILITY_ON)
                    m_creature->SetVisibility(VISIBILITY_ON);

                // Stop the combat for a small delay
                SetCombatMovement(false);
                m_creature->GetMotionMaster()->MoveIdle();
            }
        }

        // Handle delays between combat phases
        if (m_uiDelayTimer)
        {
            if (m_uiDelayTimer <= uiDiff)
            {
                if (m_Phase == PHASE_SPLIT)
                {
                    // select two different numbers between 0 and 7 so we will get different spawn points for the spotlights
                    uint8 uiPos1 = urand(0, 7);
                    uint8 uiPos2 = (uiPos1 + urand(1, 7)) % 8;

                    // summon 3 spotlights
                    m_vSpotLightsGuidVector.clear();
                    DoSummonSpotlight(fSpotlightRadius[0], M_PI_F / 2, urand(0, 3));
                    DoSummonSpotlight(fSpotlightRadius[1], M_PI_F / 4, uiPos1);
                    DoSummonSpotlight(fSpotlightRadius[1], M_PI_F / 4, uiPos2);

                    m_creature->SetVisibility(VISIBILITY_OFF);

                    DoScriptText(urand(0, 1) ? SAY_SUMMON1 : SAY_SUMMON2, m_creature);
                    m_uiSummonAgentsTimer = 5000;
                }
                else if (m_Phase == PHASE_VOID)
                {
                    DoScriptText(SAY_VOIDB, m_creature);

                    SetCombatMovement(true);
                    m_creature->GetMotionMaster()->Clear();
                    m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
                }

                m_uiDelayTimer = 0;
            }
            else
                m_uiDelayTimer -= uiDiff;

            // Combat is still on hold
            return;
        }

        switch (m_Phase)
        {
            case PHASE_NORMAL:
                // Phase 1 Timer
                if (m_uiSplitTimer <= uiDiff)
                {
                    m_Phase = PHASE_SPLIT;

                    // After these 50 seconds she portals to the middle of the room and disappears, leaving 3 light portals behind.
                    // ToDo: check if there are some spells involved in this event!
                    m_creature->GetMotionMaster()->MoveIdle();
                    SetCombatMovement(false);
                    m_creature->NearTeleportTo(fRoomCenter[0], fRoomCenter[1], fRoomCenter[2], fRoomCenter[3], true);

                    m_uiDelayTimer = 1000;
                    m_uiSplitTimer = 75000;
                    // Do nothing more, if phase switched
                    return;
                }
                else
                    m_uiSplitTimer -= uiDiff;

                // Wrath of the Astromancer targets a random player which will explode after 6 secondes
                if (m_uiWrathOfTheAstromancerTimer <= uiDiff)
                {
                    // Target the tank ?
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, SPELL_WRATH_OF_THE_ASTROMANCER, SELECT_FLAG_PLAYER))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_WRATH_OF_THE_ASTROMANCER) == CAST_OK)
                            m_uiWrathOfTheAstromancerTimer = urand(12000, 18000);
                    }
                    else
                        m_uiWrathOfTheAstromancerTimer = 10000;
                }
                else
                    m_uiWrathOfTheAstromancerTimer -= uiDiff;

                // Blinding Light Timer
                if (m_uiBlindingLightTimer <= uiDiff)
                {
                    // She casts this spell every 45 seconds. It is a kind of Moonfire spell, which she strikes down on the whole raid simultaneously. It hits everyone in the raid for 2280 to 2520 arcane damage.
                    if (DoCastSpellIfCan(m_creature, SPELL_BLINDING_LIGHT) == CAST_OK && DoCastSpellIfCan(m_creature, SPELL_MARK_OF_SOLARIAN) == CAST_OK)
                        m_uiBlindingLightTimer = 20000;
                }
                else
                    m_uiBlindingLightTimer -= uiDiff;

                // Arcane Missiles Timer
                if (m_uiArcaneMissilesTimer <= uiDiff)
                {
                    // Solarian casts Arcane Missiles on on random targets in the raid.
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_ARCANE_MISSILES, SELECT_FLAG_PLAYER))
                    {
                        DoCastSpellIfCan(pTarget, SPELL_ARCANE_MISSILES);
                        m_uiArcaneMissilesTimer = urand(3000, 3500);
                        return;
                    }
                }
                else
                    m_uiArcaneMissilesTimer -= uiDiff;

                DoMeleeAttackIfReady();
                break;

            case PHASE_SPLIT:
                // Summon 4 Agents on each portal
                if (m_uiSummonAgentsTimer)
                {
                    if (m_uiSummonAgentsTimer <= uiDiff)
                    {
                        for (uint8 i = 0; i < MAX_SPOTLIGHTS; ++i)
                        {
                            if (Creature* pSpotlight = m_creature->GetMap()->GetCreature(m_vSpotLightsGuidVector[i]))
                            {
                                for (uint8 j = 0; j < MAX_AGENTS; ++j)
                                    m_creature->SummonCreature(NPC_SOLARIUM_AGENT, pSpotlight->GetPositionX(), pSpotlight->GetPositionY(), pSpotlight->GetPositionZ(), 0, TEMPSPAWN_DEAD_DESPAWN, 0);
                            }
                        }
                        m_uiSummonAgentsTimer  = 0;
                        m_uiSummonPriestsTimer = 16000;
                    }
                    else
                        m_uiSummonAgentsTimer -= uiDiff;
                }

                if (m_uiSummonPriestsTimer)
                {
                    if (m_uiSummonPriestsTimer <= uiDiff)
                    {
                        m_Phase = PHASE_NORMAL;
                        // Randomize the portals
                        std::random_shuffle(m_vSpotLightsGuidVector.begin(), m_vSpotLightsGuidVector.end());
                        // Summon 2 priests
                        for (uint8 i = 0; i < 2; ++i)
                        {
                            if (Creature* pSpotlight = m_creature->GetMap()->GetCreature(m_vSpotLightsGuidVector[i]))
                                m_creature->SummonCreature(NPC_SOLARIUM_PRIEST, pSpotlight->GetPositionX(), pSpotlight->GetPositionY(), pSpotlight->GetPositionZ(), 0, TEMPSPAWN_DEAD_DESPAWN, 0);
                        }
                        // Teleport the boss at the last portal
                        if (Creature* pSpotlight = m_creature->GetMap()->GetCreature(m_vSpotLightsGuidVector[2]))
                            m_creature->NearTeleportTo(pSpotlight->GetPositionX(), pSpotlight->GetPositionY(), pSpotlight->GetPositionZ(), pSpotlight->GetOrientation(), true);

                        SetCombatMovement(true);
                        m_creature->GetMotionMaster()->Clear();
                        m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());

                        // Set as visible and reset spells timers
                        m_creature->SetVisibility(VISIBILITY_ON);
                        m_uiArcaneMissilesTimer        = 0;
                        m_uiSummonPriestsTimer         = 0;
                        m_uiBlindingLightTimer         = 20000;
                        m_uiWrathOfTheAstromancerTimer = urand(20000, 25000);
                    }
                    else
                        m_uiSummonPriestsTimer -= uiDiff;
                }

                break;

            case PHASE_VOID:
                // Fear Timer
                if (m_uiFearTimer <= uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_PSYHIC_SCREAM) == CAST_OK)
                        m_uiFearTimer = 20000;
                }
                else
                    m_uiFearTimer -= uiDiff;

                // Void Bolt Timer
                if (m_uiVoidBoltTimer <= uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_VOID_BOLT) == CAST_OK)
                        m_uiVoidBoltTimer = 10000;
                }
                else
                    m_uiVoidBoltTimer -= uiDiff;

                DoMeleeAttackIfReady();
                break;
        }
    }
Пример #14
0
 void SummonedCreatureJustDied(Creature* summoned) override
 {
     m_skeletons.erase(std::remove(m_skeletons.begin(), m_skeletons.end(), summoned->GetObjectGuid()), m_skeletons.end());
 }
    void UpdateAI(const uint32 uiDiff) override
    {
        if (m_uiInciteChaosWaitTimer)
        {
            if (m_uiInciteChaosWaitTimer <= uiDiff)
            {
                // Restart attack on all targets
                for (GuidVector::const_iterator itr = m_vTargetsGuids.begin(); itr != m_vTargetsGuids.end(); ++itr)
                {
                    if (Unit* pTarget = m_creature->GetMap()->GetUnit(*itr))
                        AttackStart(pTarget);
                }

                m_creature->HandleEmote(EMOTE_STATE_NONE);
                m_uiInciteChaosWaitTimer = 0;
            }
            else
                m_uiInciteChaosWaitTimer -= uiDiff;
        }

        // Return since we have no pTarget
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (m_uiInciteChaosTimer < uiDiff)
        {
            // Store the threat list
            m_vTargetsGuids.clear();
            m_creature->FillGuidsListFromThreatList(m_vTargetsGuids);

            if (DoCastSpellIfCan(m_creature, SPELL_INCITE_CHAOS) == CAST_OK)
            {
                m_creature->HandleEmote(EMOTE_STATE_LAUGH);
                m_uiInciteChaosTimer = 55000;
                m_uiInciteChaosWaitTimer = 16000;
                return;
            }
        }
        else
            m_uiInciteChaosTimer -= uiDiff;

        // Charge Timer
        if (m_uiChargeTimer < uiDiff)
        {
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, SPELL_CHARGE, SELECT_FLAG_NOT_IN_MELEE_RANGE))
            {
                if (DoCastSpellIfCan(pTarget, SPELL_CHARGE) == CAST_OK)
                    m_uiChargeTimer = urand(30000, 43000);
            }
        }
        else
            m_uiChargeTimer -= uiDiff;

        // Knockback Timer
        if (m_uiKnockbackTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_WAR_STOMP) == CAST_OK)
                m_uiKnockbackTimer = urand(15000, 30000);
        }
        else
            m_uiKnockbackTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }