void PlayerbotShamanAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    uint8 reqHeal = 0;
    uint8 OwnPartyHP = GetHealthPercentRaid(m_bot, reqHeal);

    switch(ai->GetScenarioType())
    {
        case SCENARIO_DUEL:
            ((ai->GetHealthPercent() < 80 && CastSpell(LESSER_HEAL)) ||
            CastSpell(LIGHTNING_BOLT, pTarget));
            return;
    }

    // Cast CC breakers if any match found (include any dispels first)  does not work yet
    //uint32 ccSpells[4] = { R_ESCAPE_ARTIST, R_EVERY_MAN_FOR_HIMSELF, R_WILL_OF_FORSAKEN, R_STONEFORM };
    //if (ai->GetManaPercent() < 35) { ccSpells[0] = 0; ccSpells[1] = 0; } //We dont have any mana to waste...
    //if (castSelfCCBreakers(ccSpells)) {  } // Most of them don't trigger gcd


    #pragma region Choose Actions
    // Choose actions accoring to talents
    if (m_tank->GetGUID() == m_bot->GetGUID()) { m_role=BOT_ROLE_TANK; } // Hey! I am Main Tank
    else if (TALENT_ENHANCEMENT) { m_role = BOT_ROLE_DPS_MELEE; }
    else if (TALENT_ELEMENTAL) { m_role = BOT_ROLE_DPS_RANGED; }
    else if (TALENT_RESTO) { m_role = BOT_ROLE_SUPPORT; }
    else { m_role = BOT_ROLE_DPS_MELEE; } //Unknown build or low level.. Mainly attack

    // if i am under attack and if i am not tank or offtank: change target if needed
    if (m_tank->GetGUID() != m_bot->GetGUID() && isUnderAttack()  )
    {
            if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
            else //Have to select nearest target
            {
                Unit *curAtt = GetNearestAttackerOf(m_bot);
                if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
                {
                    m_bot->SetSelection(curAtt->GetGUID());
                    //ai->AddLootGUID(curAtt->GetGUID());
                    DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..
                    return;
                }
            }
            //my target is attacking me
    }
    #pragma endregion

    // Choose Weapon Enchant
    if (ChangeWeaponEnchants()) return;

	if (TALENT_ELEMENTAL){ if (!m_bot->HasAura(WATER_SHIELD) && CastSpell(WATER_SHIELD,m_bot)) { return; }}
	if (TALENT_ENHANCEMENT){ if (!m_bot->HasAura(LIGHTNING_SHIELD) && CastSpell(LIGHTNING_SHIELD,m_bot)) { return; }}
	if (TALENT_RESTO){ if (!m_bot->HasAura(WATER_SHIELD) && CastSpell(WATER_SHIELD,m_bot)) { return; }}
    // Choose shield
	/*
    if (EARTH_SHIELD && ai->GetHealthPercent() < 80 && isUnderAttack()) { if (CastSpell(EARTH_SHIELD,m_bot)) { return; } }
    else if (WATER_SHIELD && ai->GetManaPercent() < 40) { if (CastSpell(WATER_SHIELD,m_bot)) { return; } }
    else if (LIGHTNING_SHIELD &&
        ( isUnderAttack() || m_tank->GetGUID() == m_bot->GetGUID() )  && !(m_bot->HasAura(WATER_SHIELD) && ai->GetManaPercent() < 80)
        ) { if (CastSpell(LIGHTNING_SHIELD,m_bot)) { return; } }
    else if (CastSpell(WATER_SHIELD,m_bot)) { return; }
	*/
    // If there's a cast stop
    if(m_bot->HasUnitState(UNIT_STAT_CASTING)) return;

    switch(m_role)
    {
        #pragma region BOT_ROLE_TANK / BOT_ROLE_OFFTANK
        case BOT_ROLE_TANK:
        case BOT_ROLE_OFFTANK:
             if (!TALENT_ELEMENTAL && !TALENT_RESTO) { TakePosition(pTarget); }
            else { TakePosition(pTarget,BOT_ROLE_DPS_RANGED); } // mob will come to you sooner or later no need to hurry

            // Do support stuff
            if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
            if (ai->GetManaPercent() > 70 && DoSupportRaid(m_bot)) { return; }

            break;
        #pragma endregion

        #pragma region BOT_ROLE_DPS_MELEE
        case BOT_ROLE_DPS_MELEE:
            TakePosition(pTarget);
            // Do support stuff
            if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
            if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; }
            break;
        #pragma endregion

        #pragma region BOT_ROLE_DPS_RANGED
        case BOT_ROLE_DPS_RANGED:
            TakePosition(pTarget);
            // Do support stuff
            if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
            if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; }
            break;
        #pragma endregion

        #pragma region BOT_ROLE_SUPPORT
        case BOT_ROLE_SUPPORT:
            TakePosition(pTarget);
            // Do support stuff
            if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
            if (DoSupportRaid(m_bot)) { return; }
            //heal pets and bots
            Unit *target = DoSelectLowestHpFriendly(40, 1000);
            if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; }

            break;
        #pragma endregion
    }
    #pragma region ShamanCommon


    //Defensive Stuff
    if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() )
    {
        if (pDist > 5 && CastSpell(FROST_SHOCK, pTarget)) { return; }
        if ((pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST || pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_HUMANOID) && CastSpell(HEX, pTarget)) { return; } // no gcd
        if (CastSpell(WIND_SHEAR, pTarget)) { } // no gcd
    }
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
    if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(WIND_SHEAR, pTarget)) { } //no gcd
    if (m_bot->getRace() == (uint8) RACE_TAUREN && pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; }

    //Catch
    if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING))
    {
        if (CastSpell(FROST_SHOCK,pTarget)) return;
    }


    //Buff and restores
    if ( ( (ai->GetHealthPercent() < 60 && isUnderAttack()) ||
        (ai->GetManaPercent() < 30) ) && CastSpell(SHAMANISTIC_RAGE, m_bot)) { return; }
    if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} // no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} // no GCD
    if (!m_bot->HasAura(HEROISM) && !m_bot->HasAura(EXHAUSTION) && !m_bot->HasAura(SATED) && CastSpell(HEROISM,m_bot)) { return; }
    if (m_role != BOT_ROLE_SUPPORT && CastSpell(NATURES_SWIFTNESS, m_bot)) { } //healers keep it for healing no gcd
    else if (CastSpell(ELEMENTAL_MASTERY, m_bot)) { } //no gcd

    // If at threat limit, use WIND_SHEAR to reduce threat
    if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack())
    {
        if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
        {
            m_bot->SetSelection(m_tank->getVictim()->GetGUID());
            return;
        }
        else
        {
            if (CastSpell(WIND_SHEAR,pTarget)) { return; } //Lets see if we can manage
            else { return; } //use no spells and wait threat to be reduced
        }
    }


	if (TALENT_ELEMENTAL)
	{
		if (CastSpell(ELEMENTAL_MASTERY, m_bot)) { } //no gcd
		if (!pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) && CastSpell(FLAME_SHOCK,pTarget)) { return; }
		if (CastSpell(LAVA_BURST,pTarget)) { return; }
		if (CastSpell(CHAIN_LIGHTNING,pTarget)) { return; }
		if (CastSpell(LIGHTNING_BOLT,pTarget)) { return; }
	}

    //dps
    if (MAELSTROM_WEAPON)
    {
        Aura *maelaura = m_bot->GetAura(MAELSTROM_WEAPON);
        if (maelaura && maelaura->GetStackAmount() == 5)
        {
            if ((isUnderAttack(m_tank,3) || m_tank->GetGUID() == m_bot->GetGUID()) && CastSpell(CHAIN_LIGHTNING,pTarget,true,true)) { return; }
            if (CastSpell(LIGHTNING_BOLT,pTarget,true,true)) { return; }
        }
    }
	if (CastSpell(FLAME_SHOCK,pTarget)) { return; }
    if (CastSpell(STORMSTRIKE,pTarget,true,true)) { return; }

    //if (!TALENT_ENHANCEMENT && CanCast(LAVA_BURST,pTarget,true) && pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) && CastSpell(LAVA_BURST,pTarget,false)) { return; }
	if (CastSpell(FERAL_SPIRIT,m_bot)) { return; }
    if (CanCast(EARTH_SHOCK,pTarget,true) && (pTarget->HasAura(STORMSTRIKE,m_bot->GetGUID()) || pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) ) && CastSpell(EARTH_SHOCK,pTarget)) { return; }
    //if (CanCast(FLAME_SHOCK,pTarget) && CastSpell(FLAME_SHOCK,pTarget)) { return; }
	if (CastSpell(LAVA_LASH,pTarget,true,true)) { return; }
	if (CastSpell(FIRE_NOVA,pTarget)) { return; }
    //if ((isUnderAttack(m_tank,4) || m_tank->GetGUID() == m_bot->GetGUID()) && CastSpell(FIRE_NOVA,pTarget)) { return; }
    if (ai->GetManaPercent() > 60 && castDispel(PURGE,pTarget)) { return; } //PURGE but dont overpurge

    #pragma endregion


    // drink potion if support / healer (Other builds simply overuse mana and waste mana pots)
    if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) )
    {
        Item *pItem = ai->FindPotion();
        if(pItem != NULL)
        {
            if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown
            ai->UseItem(*pItem);
        }
    }


} //end DoNextCombatManeuver
示例#2
0
void PlayerbotRogueAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    #pragma region Choose Target
    // Choose actions accoring to talents (ROGUE is always MELEE DPS)
    m_role = BOT_ROLE_DPS_MELEE;
    // if i am under attack and if i am not tank or offtank: change target if needed
    if (m_tank->GetGUID() != m_bot->GetGUID() && isUnderAttack() ) 
    {
        // Keep hitting but reduce threat
        if (CastSpell(TRICKS_OF_THE_TRADE,m_tank)) { return; }
        else if (CastSpell(VANISH,m_bot)) { return; }
        else //I cannot reduce threat so
        {
            if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
            else //Have to select nearest target
            {
                Unit *curAtt = GetNearestAttackerOf(m_bot);
                if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
                {
                    m_bot->SetSelection(curAtt->GetGUID());
                    DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..               
                    //return; 
                }
            }
            //my target is attacking me
        }
    }
    #pragma endregion

    // wait until we actually reach our target b4 we actually do anything
    if (m_bot->GetDistance(pTarget)>10.0 && 
        !m_bot->HasAura(STEALTH) &&
        !m_bot->isInCombat() && CastSpell(STEALTH)) 
    { return; }

    TakePosition(pTarget);

    // If there's a cast stop
    if (m_bot->hasUnitState(UNIT_STAT_CASTING)) { return; }

    // wait until we actually reach our target b4 we actually do anything
    /*if (GetPlayerBot()->GetDistance(pTarget)>10.0 && 
        !HasAuraName(GetPlayerBot(),STEALTH) &&
        !GetPlayerBot()->isInCombat() && CastSpell(STEALTH)) 
    { return; }*/

    //Buff
    if (CastSpell(PREMEDITATION,m_bot)) { return; }
    if (CastSpell(COLD_BLOOD,m_bot)) { } //no gcd

    //PROTECT UP
    if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() )
    {
        if (CastSpell(TRICKS_OF_THE_TRADE,m_tank)) { return; }
        if (CastSpell(FEINT,m_bot)) { return; }
        if (CastSpell(VANISH,m_bot)) { return; }
    }
    if (isUnderAttack() && pDist <= MELEE_RANGE && ai->GetHealthPercent() <= 85 && CastSpell(EVASION, m_bot)) { } //no GCD
    if (ai->GetHealthPercent() <= 55 && CastSpell(CLOAK_OF_SHADOWS, m_bot)) { return; }
    if (isUnderAttack() && ai->GetHealthPercent() <= 65 && CastSpell(GOUGE, m_bot)) { return; }
    if (isUnderAttack() && ai->GetHealthPercent() <= 45 && CastSpell(BLIND, m_bot)) { return; }
    if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot)) { } //no gcd

    //Break spells
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && (pTarget->IsNonMeleeSpellCasted(true) || ai->GetManaPercent() < 40) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
    else if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(KICK, pTarget)) { return; }
    else if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(GOUGE, pTarget)) { return; }
    else if (pTarget->IsNonMeleeSpellCasted(true) && m_bot->GetComboPoints() >= 1 && CastSpell(KIDNEY_SHOT, pTarget)) { return; }

    //Transfer threat
    if (m_tank->GetGUID() != m_bot->GetGUID() && CastSpell(TRICKS_OF_THE_TRADE,m_tank)) { return; }
	if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} //no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} //no GCD

    // sometimes we lose attack
    if (!m_bot->isInCombat()) {
        m_bot->Attack(pTarget, true); 
    }

	if(TALENT_ASSASSINATION)
	{
		if (!m_bot->HasAura(HUNGER_FOR_BLOOD) && CastSpell(HUNGER_FOR_BLOOD,m_bot)) { return; }
		if (m_bot->GetComboPoints() < 5)
		{
		    if (CastSpell(MUTILATE, pTarget)) { return; }
		}
		else
		{
			if (!pTarget->HasAura(RUPTURE) && CastSpell(RUPTURE)) { return; }
			
		}
	}
	
    if(TALENT_COMBAT)
	{        
		if (CastSpell(BLADE_FLURRY,m_bot)) { return; }
		if (ai->GetEnergyAmount() < 20 && CastSpell(ADRENALINE_RUSH,m_bot)) { return; }
		if (!CastSpell(ADRENALINE_RUSH) && CastSpell(KILLING_SPREE,m_bot,1,0,1)) { return; }
		if (m_bot->GetComboPoints() > 5)
		{
			if (!pTarget->HasAura(RUPTURE) && CastSpell(RUPTURE)) { return; }
		}
	}
	
    if(TALENT_SUBTELTY)
	{	
		if (CastSpell(PREMEDITATION,m_bot)) {}
		if (CastSpell(SHADOW_DANCE,m_bot)) {}
		if (!CastSpell(SHADOW_DANCE,m_bot) && CastSpell(PREPARATION,m_bot)) { return; }
		if (m_bot->GetComboPoints() < 5)
		{
			if (m_bot->HasAura(SHADOW_DANCE) && !pTarget->HasInArc(M_PI,m_bot)) { if (CastSpell(AMBUSH, pTarget)) { return; } }		
            if (CastSpell(GHOSTLY_STRIKE, pTarget)) { return; }
		}
		else
		{
			if (!pTarget->HasAura(RUPTURE) && CastSpell(RUPTURE)) { return; }
			if (!m_bot->HasAura(SLICE_AND_DICE) && CastSpell(SLICE_AND_DICE)) { return; }
			if (CastSpell(SHADOWSTEP,pTarget)) { }
		}
	}

    // defaults if not high enough do specialized attacks
    if (m_bot->GetComboPoints() < 5) {
        if (!pTarget->HasInArc(M_PI,m_bot)) { if (CastSpell(BACKSTAB, pTarget)) { return; } }
        if (!MUTILATE &&CastSpell(SINISTER_STRIKE,pTarget)) { return; } // Dont cast if we have mutilate, save energy for it
    } else {
        if (!m_bot->HasAura(SLICE_AND_DICE) && CastSpell(SLICE_AND_DICE)) {  return; }		
		if (CastSpell(ENVENOM,pTarget)) { return; }
        if (CastSpell(EVISCERATE,pTarget)) { return; }
    }
} //end DoNextCombatManeuver
void PlayerbotDruidAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    uint8 reqHeal = 0;
    uint8 OwnPartyHP = GetHealthPercentRaid(m_bot, reqHeal);


    #pragma region Select behaviour
    if (m_tank->GetGUID() == m_bot->GetGUID()) // Hey! I am Main Tank
    {
        if (TALENT_FERAL && BEAR_FORM) { m_role = BOT_ROLE_TANK; } //Just Keep Tanking dont even change forms for healing
        else
        {
            if (TALENT_BALANCE) {
                if ((ai->GetHealthPercent() <= 40 || masterHP <30 ) && (ai->GetManaPercent() >= 40)) { m_role = BOT_ROLE_SUPPORT; }
                else if (OwnPartyHP < 20 && ai->GetManaPercent() >= 30) { m_role = BOT_ROLE_SUPPORT; }
                else if (ai->GetManaPercent() < 25 ) { m_role = BOT_ROLE_TANK; }
                else { m_role = BOT_ROLE_DPS_RANGED; }
            }
            else //I am both healer and tank?? Hmm
            {
                if ((ai->GetHealthPercent() <= 70 || masterHP <70 ) && (ai->GetManaPercent() >= 50)) { m_role = BOT_ROLE_SUPPORT; }
                else if (OwnPartyHP < 20 && ai->GetManaPercent() >= 30) { m_role = BOT_ROLE_SUPPORT; }
                else if (ai->GetManaPercent() < 15 ) { m_role = BOT_ROLE_TANK; }
                else { m_role = BOT_ROLE_DPS_RANGED; }
            }
        }
    }
    else if (isUnderAttack() && !( ai->GetForm() == FORM_MOONKIN || ai->GetForm() == FORM_TREE)  ) // if i am under attack
    {
        // Keep being in Cat Form if you can reduce threat
        if (ai->GetForm() == FORM_CAT && CastSpell(COWER,pTarget)) {return; }
        else if (TALENT_RESTO && ai->GetManaPercent() > 10 ) { m_role = BOT_ROLE_SUPPORT; }
        else { m_role = BOT_ROLE_OFFTANK; }
    }
    else if (TALENT_FERAL && CAT_FORM) { // If has any feral forms at all
        if ((ai->GetHealthPercent() <= 40 || masterHP <40 ) && (ai->GetManaPercent() >= 40)) { m_role = BOT_ROLE_SUPPORT; }
        else if (OwnPartyHP < 30 && ai->GetManaPercent() >= 30) { m_role = BOT_ROLE_SUPPORT; }
        else{ m_role = BOT_ROLE_DPS_MELEE; }
    }
    else if (TALENT_BALANCE) {
        if ((ai->GetHealthPercent() <= 50 || masterHP <40 ) && (ai->GetManaPercent() >= 10)) { m_role = BOT_ROLE_SUPPORT; }
        else if (OwnPartyHP < 40 && ai->GetManaPercent() >= 30) { m_role = BOT_ROLE_SUPPORT; }
        else { m_role = BOT_ROLE_DPS_RANGED; }
    }
    else if (TALENT_RESTO)    { m_role = BOT_ROLE_SUPPORT; }
    else
    {
        // Unknown build or low level : Do not change forms rapidly..
        if ( (ai->GetManaPercent() < 30 && BEAR_FORM) || ( (ai->GetForm() == FORM_CAT || ai->GetForm() == FORM_DIREBEAR || ai->GetForm() == FORM_BEAR) && ai->GetManaPercent() < 70 )  ) m_role = BOT_ROLE_DPS_MELEE;
        else { m_role = BOT_ROLE_DPS_RANGED; }
    }

    if (!isUnderAttack() && m_tank->GetGUID() != m_bot->GetGUID())
    {
        // Select Attacking target
        if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {} //if my target is attacking me continue
        else
        {
            Unit *curAtt = GetNearestAttackerOf(m_bot);
            if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
            {
                m_bot->SetSelection(curAtt->GetGUID());
                //ai->AddLootGUID(curAtt->GetGUID());
                DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..
                return;
            }
        }
        //my target is attacking me
    }
    #pragma endregion

    // If there's a cast stop
    if (m_bot->HasUnitState(UNIT_STAT_CASTING)) return;
    // Return to normal form from non combat forms
    if (ai->GetForm() == FORM_NONE || ai->GetForm() == FORM_CAT || ai->GetForm() == FORM_TREE || ai->GetForm() == FORM_MOONKIN || ai->GetForm() == FORM_DIREBEAR || ai->GetForm() == FORM_BEAR )  { } //Those are valid incombat auras
    else if (ai->GetForm() != FORM_NONE && ChangeForm(1)) { } //return to caster form

    switch(m_role)
    {
        #pragma region BOT_ROLE_DPS_MELEE
        case BOT_ROLE_DPS_MELEE:
            //ai->TellMaster("DruidCombat");

            // Do caster form stuff
            if (ai->GetForm() == FORM_NONE)
            {
                //We have little mana probably cant change form
                if (ai->GetManaPercent() < 20 && CastSpell (INNERVATE, m_bot) ) { return; }
                else if(m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) {  return;}
                else if(DoSupportRaid(GetMaster(),false,false,false)) return;
                else if(m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup() && DoSupportRaid(m_bot,false,false,false)) { return; }
            }

            if (CAT_FORM) { if (ChangeForm(CAT_FORM)) { return; } }
            else if (BEAR_FORM) { if (ChangeForm(BEAR_FORM)) { return; } }
            else if (ai->GetForm() != FORM_NONE && ChangeForm(1)) {  } //Normal Form

            TakePosition(pTarget);
            break;
        #pragma endregion

        #pragma region BOT_ROLE_TANK / BOT_ROLE_OFFTANK
        case BOT_ROLE_OFFTANK:
        case BOT_ROLE_TANK: // It is a tank druid or a defending druid

            // Do what you must before getting attacked...
            if (ai->GetForm() == FORM_NONE)
            {
                // Non tank stuff to avoid
                if (m_tank->GetGUID() != m_bot->GetGUID())
                {
                    if (ROOTS && !pTarget->HasAura(CYCLONE) && !pTarget->HasAura(HIBERNATE) && CastSpell(ROOTS, pTarget)) { return; }
                    if (CYCLONE && pDist > 5 && !pTarget->HasAura(ROOTS) && !pTarget->HasAura(HIBERNATE) && CastSpell(CYCLONE, pTarget)) { return; }
                    if (HIBERNATE && pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST && !pTarget->HasAura(ROOTS) && !pTarget->HasAura(CYCLONE) && CastSpell(HIBERNATE, pTarget)) { return; }
                    //if (m_bot->getRace() == (uint8) RACE_NIGHTELF && isUnderAttack() && CastSpell(R_SHADOWMELD, m_bot)) { return; }
                }
                // Things to do wheter Tank or not
                if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd
                if (ai->GetManaPercent() < 20 && CastSpell (INNERVATE, m_bot) ) { return; } //We have little mana probably cant change form
            }
            TakePosition(pTarget);

            if (ChangeForm(BEAR_FORM)) { return; }

            // if i am main tank, protect master by taunt
            if(m_tank->GetGUID() == m_bot->GetGUID())
            {
                // Taunt if needed (Only for master)
                Unit *curAtt = GetAttackerOf(GetMaster());
                if (curAtt)
                {
                    if (isUnderAttack(GetMaster(),2) && CastSpell(CHALLENGING_ROAR, curAtt)) { return; }
                    if (CastSpell(GROWL, curAtt))  { return; }
                }
                // My target is not attacking me, taunt..
                if (pVictim && pVictim->GetGUID() != m_bot->GetGUID() && CastSpell(GROWL, pTarget) )  { return; }
            }
            break;
        #pragma endregion

        #pragma region BOT_ROLE_DPS_RANGED
        case BOT_ROLE_DPS_RANGED:
            if ( ai->GetManaPercent() < 20 && CastSpell (INNERVATE, m_bot)) { return; }

            // Do caster form stuff
            if (ai->GetForm() == FORM_NONE)
            {
                if(DoSupportRaid(GetMaster())) return;
                else if(m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup() && DoSupportRaid(m_bot)) { return; }
            }

            if (MOONKIN_FORM) { if (ChangeForm(MOONKIN_FORM)) { return; } }
            else if (ai->GetForm() != FORM_NONE && ChangeForm(1)) { } //Normal Form

            TakePosition(pTarget);

            // BUFF UP
            if(DoSupportRaid(GetMaster(),false,false,false)) return;
            else if(m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup() && DoSupportRaid(m_bot,false,false,false)) { return; }

            break;
        #pragma endregion

        #pragma region BOT_ROLE_SUPPORT
        case BOT_ROLE_SUPPORT:
            if ( ai->GetManaPercent() < 20 && CastSpell (INNERVATE,m_bot)) { return; }
            //Get to tree form only if you will no longer cast attack spells
            if( TREE_OF_LIFE_FORM && (ai->GetManaPercent() < offensiveSpellThreshold || isUnderAttack()) )
            {
                 if (ChangeForm(TREE_OF_LIFE_FORM)) { return; }
            }
            else if (ai->GetForm() != FORM_NONE && ChangeForm(1)) { }  //Normal Form no gcd

            TakePosition(pTarget);

            //RezGroup(REBIRTH, GetMaster());
            if (DoSupportRaid(GetMaster())) { return; }
            if (m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup() && DoSupportRaid(m_bot)) { return; }
            //heal pets and bots
            Unit *target = DoSelectLowestHpFriendly(30, 1000);
            if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; }

            break;
        #pragma endregion
    }

    #pragma region DruidCommon
    // Common Dps and protection routine
    if (ai->GetHealthPercent() <= 70 && CastSpell(BARKSKIN,m_bot)) { return; }
    if (isUnderAttack() && CastSpell(NATURES_GRASP,m_bot)) { return; }

    if (ai->GetForm() == FORM_CAT)
    {
        // If at threat limit, use Cower to reduce threat
        if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack())
        {
            if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
            {
                m_bot->SetSelection(m_tank->getVictim()->GetGUID());
                return;
            }
            else
            {
                if (CastSpell(COWER,pTarget)) { return; } //Lets see if we can manage
                else { return; } //use no spells and wait threat to be reduced
            }
        }
        if (CastSpell(FERAL_CHARGE_CAT,pTarget)) { return; }
        if (m_bot->GetComboPoints() >= 1 && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(MAIM, pTarget)) { return; }

        if (CastSpell(BERSERK, m_bot)) { return; }
        if (ai->GetHealthPercent() <= 75 && CastSpell(SURVIVAL_INSTINCTS, m_bot)) { return; }
        if (isUnderAttack() && CastSpell(NATURES_GRASP, m_bot)) { return; }
        if (CastSpell(FAERIE_FIRE_FERAL, pTarget)) { return; }

        if (m_bot->GetComboPoints() < 5)
        {
            if (CastSpell(RAKE, pTarget)) { return; }
            if (CastSpell(MANGLE_CAT, pTarget)) { return; }
            if (!pTarget->HasInArc(M_PI,m_bot) && CastSpell(SHRED, pTarget)) { return; }
            if (ai->GetEnergyAmount() > 65 && CastSpell(MANGLE_CAT, pTarget)) { return; } //Spam mangle if cannot cast shred
            if (ai->GetEnergyAmount() > 65 && CastSpell(CLAW, pTarget) ) { return; } //Spam Claw if there is no mangle
            // if (CanCast(COWER, pTarget) && CastSpell(COWER, pTarget)) { return; } //if still nothing, use COWER to reduce threat
        }
        else
        {
            if (CastSpell(SAVAGE_ROAR)) { return; }
            if (CastSpell(RIP, pTarget)) { return; }
            if (ai->GetEnergyAmount() >= 65 && CastSpell(FEROCIOUS_BITE, pTarget)) { return; } //maxhit for feracious bite
        }
        if (CastSpell(TIGERS_FURY, m_bot)) { return; } //if nothing is ready yet, use tigers fury
    }
    else if (ai->GetForm() == FORM_DIREBEAR || ai->GetForm() == FORM_BEAR)
    {
        // If at threat limit, stop
        if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack() )
        {
            //Change to tank's target
            if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) { m_bot->SetSelection(m_tank->getVictim()->GetGUID()); }
            return; //use no spells and wait threat to be reduced
        }
        if (CastSpell(FERAL_CHARGE_BEAR,pTarget)) { return; }
        if (CastSpell(BASH, pTarget,true,true)) { return; } //Need check for immunity
        if (CastSpell(BERSERK, m_bot)) { return; }
        if (CastSpell(DEMORALIZING_ROAR, pTarget)) { return; }
        if (ai->GetHealthPercent() > 90 && ai->GetRageAmount() < 50 && CastSpell(ENRAGE, m_bot)) { return; }
        if (ai->GetHealthPercent() <= 75 && CastSpell(SURVIVAL_INSTINCTS, m_bot)) { return; }
        if ( ( ai->GetHealthPercent() <= 30 || (ai->GetHealthPercent() < 85 && m_tank->GetGUID() != m_bot->GetGUID())  )
            && CastSpell(FRENZIED_REGENERATION)) { return; }
        if (CastSpell(FAERIE_FIRE_FERAL, pTarget)) { return; }
        if (CastSpell(MANGLE_BEAR, pTarget)) { return; }
        if ((ai->GetRageAmount() > 70 || m_tank->GetGUID() == m_bot->GetGUID()) && CastSpell(SWIPE_BEAR, pTarget)) { return; }
        if (ai->GetRageAmount() > 50 && CastSpell(MAUL, pTarget)) {} // Low Priority, Next Attack effect
        if (ai->GetRageAmount() > 60 && CastSpell(LACERATE, pTarget)) { return; } //Currently applies only 1
    }
    else
    {
        //Defensive stuff
        if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() )
        {
            if (ROOTS && !pTarget->HasAura(CYCLONE) && !pTarget->HasAura(HIBERNATE) && CastSpell(ROOTS, pTarget)) { return; }
            if (CYCLONE && pDist > 5 && !pTarget->HasAura(ROOTS) && !pTarget->HasAura(HIBERNATE) && CastSpell(CYCLONE, pTarget)) { return; }
            if (HIBERNATE && pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST && !pTarget->HasAura(ROOTS) && !pTarget->HasAura(CYCLONE) && CastSpell(HIBERNATE, pTarget)) { return; }
            //if (m_bot->getRace() == (uint8) RACE_NIGHTELF && isUnderAttack() && CastSpell(R_SHADOWMELD, m_bot)) { return; }
            if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; }
        }

        if (CastSpell(FAERIE_FIRE, pTarget)) { return; }

        // If at threat limit, stop
        if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack() )
        {
            //Change to tank's target
            if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) { m_bot->SetSelection(m_tank->getVictim()->GetGUID()); }
            return; //use no spells and wait threat to be reduced
        }
        // Continue attacking if theres excess mana (for healers)
        if (m_role == BOT_ROLE_SUPPORT && ai->GetManaPercent() < offensiveSpellThreshold) { return; }
        if (m_role != BOT_ROLE_SUPPORT && CastSpell(NATURES_SWIFTNESS, m_bot)) { } //only balance no gcd

        if (m_bot->HasAura(NATURES_SWIFTNESS) && CastSpell(STARFIRE, pTarget)) { return; }
        if (CastSpell(INSECT_SWARM, pTarget)) { return; }
        if (CastSpell(TYPHOON, pTarget)) { return; }
        if (isUnderAttack(m_tank,4) && CastSpell(HURRICANE, pTarget)) { ai->SetIgnoreUpdateTime(8); return; }
        if (isUnderAttack(m_tank,5) && CastSpell(FORCE_OF_NATURE, m_bot)) { return; }
        if (isUnderAttack(m_tank,4) && CastSpell(STARFALL, pTarget)) { return; }
        if (CastSpell(MOONFIRE, pTarget)) { return; }
        if (CastSpell(WRATH, pTarget)) { return; }
        if (CastSpell(STARFIRE, pTarget)) { return; }
    }

    // If there is nothing else to do buff UP
    if (m_role == BOT_ROLE_DPS_MELEE) //Those already healed and buffed or should never buff in combat
    {
        if (DoSupportRaid(GetMaster(),false,false,false)) { return; }
        if (m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup() && DoSupportRaid(m_bot,false,false,false)) { return; }
    }


    // drink potion if support / healer (Other builds simply overuse mana and waste mana pots)
    if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) )
    {
        Item *pItem = ai->FindPotion();
        if(pItem != NULL)
        {
            if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown
            ai->UseItem(*pItem);
        }
    }
    #pragma endregion
} //end DoNextCombatManeuver
void PlayerbotMageAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    #pragma region Choose Actions
    // Choose actions accoring to talents (MAGE is always ranged dps)
    m_role = BOT_ROLE_DPS_RANGED;

    // if i am under attack and if i am not tank or offtank: change target if needed
    if (isUnderAttack())
    {
        // Keep hitting but reduce threat
        //else if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot)) { return; }
            if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
            else //Have to select nearest target
            {
                Unit *curAtt = GetNearestAttackerOf(m_bot);
                if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
                {
                    m_bot->SetSelection(curAtt->GetGUID());
                    DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..
                    return;
                }
            }
            //my target is attacking me
    }
    #pragma endregion

    TakePosition(pTarget);
    // If there's a cast stop
    if (m_bot->HasUnitState(UNIT_STAT_CASTING)) { return; }

    if (DoSupportRaid(m_bot,30,0,0,0,1,1)) { return; }

    if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() )
    {
        //if (CastSpell(INVISIBILITY, m_bot)) { return; }
        if (ai->GetHealthPercent(*pTarget) > 50 && CastSpell(POLYMORPH)) { return; }
        //if (m_bot->getRace() == (uint8) RACE_NIGHTELF && isUnderAttack() && CastSpell(R_SHADOWMELD, m_bot)) { return; }
    }
    if (isUnderAttack() && pDist > 5 && CastSpell(FROST_NOVA, pTarget)) { return; }
    if (DEEP_FREEZE && pTarget->isFrozen() && CastSpell(DEEP_FREEZE,pTarget)) { return; }
    if (isUnderAttack() && CastSpell(DRAGONS_BREATH, pTarget)) { return; }
    if ((isUnderAttack() || ai->GetHealthPercent() < 75 && !HasAuraName(m_bot, MANA_SHIELD))  && ai->GetManaPercent() > 40 && CastSpell(MANA_SHIELD,m_bot)) { return; }
    if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot)) { } //no gcd
    if (m_bot->getRace() == (uint8) RACE_DRAENEI && ai->GetHealthPercent() < 55 && CastSpell(R_GIFT_OF_NAARU,m_bot)) { return; } //no Gcd, but has cast
    if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd but is cast
    if ((ai->GetHealthPercent() < 65 || ai->GetManaPercent() < 5) && CastSpell(ICE_BLOCK,m_bot)) { return; }
    if (isUnderAttack() && CastSpell(ICE_BARRIER, pTarget)) { return; }
    if (ai->GetManaPercent() < 30 && CastSpell (EVOCATION, m_bot)) { return; }


    //Break spells
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && (pTarget->IsNonMeleeSpellCasted(true) || ai->GetManaPercent() < 40) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
    else if (pThreat < threatThreshold && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(COUNTER_SPELL, pTarget)) { return; } //High threat
	if (!m_bot->HasAura(MOLTEN_ARMOR) && CastSpell(MOLTEN_ARMOR,m_bot)) { return; }

    if (ai->GetHealthPercent(*pTarget) > 96) { return; } // dont dps too early

    //Catch
    if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING))
    {
        if (CastSpell(FROST_NOVA,pTarget)) return;
        if (CastSpell(FROSTBOLT,pTarget)) return;
    }

    // If at threat limit, try to reduce threat
    if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack())
    {
        if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
        {
            m_bot->SetSelection(m_tank->getVictim()->GetGUID());
            return;
        }
        else
        {
            if (CastSpell(INVISIBILITY,m_bot)) { return; } //Lets see if we can manage
            else if (m_bot->FindCurrentSpellBySpellId(SHOOT)) { m_bot->InterruptNonMeleeSpells( true, SHOOT ); return; } //Disable wand
            else { return; } //use no spells and wait threat to be reduced
        }
    }


    // buff up
    if (CastSpell(ICY_VEINS,m_bot)) {} //nogcd
    if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} //no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} //no GCD
    if (CastSpell(POM,m_bot)) {} //nogcd

	if (TALENT_ARCANE)
	{
		if (CastSpell(ARCANE_POWER,m_bot)) {} //nogcd
		if (CastSpell(MIRROR_IMAGE,m_bot)) { return; }
		//AOE
		if (isUnderAttack(m_tank,5))
		{
			if (CastSpell(BLIZZARD,pTarget)) { return; }
		}
		//DPS
		if (ARCANE_BLAST)
        {
            Aura *abaura = m_bot->GetAura(P_ARCANE_BLAST);
            if (abaura && abaura->GetStackAmount() >= 3)
			{
				if (m_bot->HasAura(P_MISSILE_BARRAGE) && CastSpell(ARCANE_MISSILES,pTarget)) { return; }
				else if (CastSpell(ARCANE_BARRAGE,pTarget)) { return; }
			}
        }
        if (CastSpell(ARCANE_BARRAGE,pTarget) ) { return; }

	}
	if (TALENT_FIRE)
	{
		if (CastSpell(COMBUSTION,m_bot)) { } //nogcd
		if (CastSpell(MIRROR_IMAGE,m_bot)) { return; }

		//AOE
		if (isUnderAttack(m_tank,5))
		{
			if (CastSpell(FLAMESTRIKE,pTarget)) { return; }
			if (CastSpell(BLAST_WAVE,pTarget)) { return; }
			if (CastSpell(LIVING_BOMB,pTarget)) { return; }
			if (CastSpell(DRAGONS_BREATH,pTarget)) { return; }
		}

		//DPS
		if (m_bot->HasAura(P_HOT_STREAK) && CastSpell(PYROBLAST,pTarget)) { return; }
		if (!pTarget->HasAura(LIVING_BOMB,m_bot->GetGUID()) && CastSpell(LIVING_BOMB,pTarget)) { return; }
		//if (!pTarget->HasAura(IMP_SCORCH) && CastSpell(SCORCH,pTarget)) { return; }
		if (CastSpell(FIREBALL,pTarget)) { return; }
	}
	if (TALENT_FROST)
	{
		if (CastSpell(MIRROR_IMAGE,m_bot)) { return; }
        if (CastSpell(WATER_ELEMENTAL,m_bot)) { return; }

        uint64 pet_guid = m_bot->GetPetGUID();
        if (pet_guid>0){
            Pet* pet = ObjectAccessor::GetPet(*m_bot, pet_guid);
            Unit *unit = ObjectAccessor::GetUnit(*m_bot, pet_guid);
            if (unit!=NULL){
				if (!unit->isInCombat()) {
                    m_bot->GetSession()->HandlePetActionHelper(unit, pet_guid, COMMAND_ATTACK, ACT_COMMAND, pTarget->GetGUID());
				}
            }
        }

        //if (CastSpell(33395, pTarget)) // pet freeze spell
        //    sLog.outError ("successfully casted freeze");

        //AOE
        if (isUnderAttack(m_tank,5))
        {
            if (CastSpell(BLIZZARD,pTarget)) { return; }
        }

        //DPS
        if (m_bot->HasAura(P_FINGERS_OF_FROST) && CastSpell(DEEP_FREEZE,pTarget)) { return; }
        if (m_bot->HasAura(P_BRAIN_FREEZE) && CastSpell(FROSTFIRE_BOLT,pTarget)) { return; }
        if (CastSpell(FROSTBOLT,pTarget,true,true)) { return; }

    }

    // Defaults especialy for lower levels
    if (m_bot->HasAura(P_BRAIN_FREEZE) && CastSpell(FIREBALL,pTarget,1,1)) { return; }
        if (m_bot->HasAura(P_FIRESTARTER) && CastSpell(FLAMESTRIKE,pTarget,1,1)) { return; }
        if (m_bot->HasAura(P_HOT_STREAK) && CastSpell(PYROBLAST,pTarget,1,1)) { return; }
        if (m_bot->HasAura(POM) && (CastSpell(PYROBLAST,pTarget,1,1) || CastSpell(FIREBALL,pTarget,1,1) || CastSpell(FROSTBOLT,pTarget,1,1))) { return; }
        if (pTarget->isFrozen() && CastSpell(ICE_LANCE,pTarget)) { return; }
        if (m_bot->isMoving() && (CastSpell(FIRE_BLAST,pTarget,1,1) || CastSpell(ARCANE_BARRAGE,pTarget) || CastSpell(ICE_LANCE,pTarget))) { return; }
        if (CastSpell(FIREBALL,pTarget)) { return; }
        if (CastSpell(FROSTBOLT,pTarget)) { return; }
        if (CastSpell(ARCANE_MISSILES,pTarget)) { return; }

    // drink potion
    if(ai->GetManaPercent() < 5 )
    {
        Item *pItem = ai->FindPotion();
        if(pItem != NULL)
        {
            if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown
            ai->UseItem(*pItem);
        }
    }

    // if we get down here, it means we are out of mana, so use wand
    CastSpell(SHOOT, pTarget);

} //end DoNextCombatManeuver
示例#5
0
void PlayerbotRogueAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    /*switch (ai->GetScenarioType()) {
        case SCENARIO_DUEL: 
            ((CastSpell(BACKSTAB)) ||
            (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(KICK)) ||
            ((GetPlayerBot()->GetComboPoints()==5) && CastSpell(SLICE_DICE)) ||
            (CastSpell(SINISTER_STRIKE)));
            return;
    }*/
    #pragma region Choose Target
    // Choose actions accoring to talents (ROGUE is always MELEE DPS)
    m_role = BOT_ROLE_DPS_MELEE;

    // if i am under attack and if i am not tank or offtank: change target if needed
    if (m_tank->GetGUID() != m_bot->GetGUID() && isUnderAttack() ) 
    {
        // Keep hitting but reduce threat
        if (CastSpell(FEINT,m_bot)) { return; }
        else if (CastSpell(TRICKS_OF_THE_TRADE,m_tank)) { return; }
        else if (CastSpell(VANISH,m_bot)) { return; }
        //else if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot)) { return; }
        else //I cannot reduce threat so
        {
            if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
            else //Have to select nearest target
            {
                Unit *curAtt = GetNearestAttackerOf(m_bot);
                if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
                {
                    m_bot->SetSelection(curAtt->GetGUID());
                    //ai->AddLootGUID(curAtt->GetGUID());
                    DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..
                    return; 
                }
            }
            //my target is attacking me
        }
    }
    #pragma endregion

    // wait until we actually reach our target b4 we actually do anything
    /*if (m_bot->GetDistance(pTarget)>10.0 && 
        !m_bot->HasAura(STEALTH) &&
        !m_bot->isInCombat() && CastSpell(STEALTH)) 
    { return; }*/

    TakePosition(pTarget);

    // If there's a cast stop
    if (m_bot->hasUnitState(UNIT_STAT_CASTING)) { return; }

    // wait until we actually reach our target b4 we actually do anything
    if (GetPlayerBot()->GetDistance(pTarget)>10.0 && 
        !HasAuraName(GetPlayerBot(),STEALTH) &&
        !GetPlayerBot()->isInCombat() && CastSpell(STEALTH)) 
    { return; }

    //Buff
    if (CastSpell(PREMEDITATION,m_bot)) { return; }

    //PROTECT UP
    if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() )
    {
        if (CastSpell(FEINT,m_bot)) { return; }
        if (CastSpell(TRICKS_OF_THE_TRADE,m_tank)) { return; }
        if (CastSpell(VANISH,m_bot)) { return; }
    }
    if (isUnderAttack() && pDist <= MELEE_RANGE && ai->GetHealthPercent() <= 85 && CastSpell(EVASION, m_bot)) { } //no GCD
    if (ai->GetHealthPercent() <= 55 && CastSpell(CLOAK_OF_SHADOWS, m_bot)) { return; }
    if (isUnderAttack() && ai->GetHealthPercent() <= 65 && CastSpell(GOUGE, m_bot)) { return; }
    if (isUnderAttack() && ai->GetHealthPercent() <= 45 && CastSpell(BLIND, m_bot)) { return; }
    if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot)) { } //no gcd
    if (m_bot->getRace() == (uint8) RACE_DRAENEI && ai->GetHealthPercent() < 55 && CastSpell(R_GIFT_OF_NAARU,m_bot)) { return; } //no Gcd, but has cast
    if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd but is cast

    //Break spells
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && (pTarget->IsNonMeleeSpellCasted(true) || ai->GetManaPercent() < 40) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
    else if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(KICK, pTarget)) { return; }
    else if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(GOUGE, pTarget)) { return; }
    else if (pTarget->IsNonMeleeSpellCasted(true) && m_bot->GetComboPoints() >= 1 && CastSpell(KIDNEY_SHOT, pTarget)) { return; }

    // If at threat limit, try to reduce threat
    if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack())
    {
        if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
        {
            m_bot->SetSelection(m_tank->getVictim()->GetGUID());
            return;
        }
        else  
        {
            if (CastSpell(FEINT,m_bot)) { return; } //Lets see if we can manage
            else if (CastSpell(TRICKS_OF_THE_TRADE,m_tank)) { return; }
            else { return; } //use no spells and wait threat to be reduced
        }
    }

    //Transfer threat
    if (m_tank->GetGUID() != m_bot->GetGUID() && CastSpell(TRICKS_OF_THE_TRADE,m_tank)) { return; }

    //Urgent DPS
    if ((m_bot->HasAura(STEALTH) || m_bot->HasAura(VANISH))&& CastSpell(CHEAP_SHOT,pTarget)) { return; }

    //DPS UP
    if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} //no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} //no GCD
    if (CastSpell(COLD_BLOOD,m_bot)) { } //no gcd
    if (CastSpell(HUNGER_FOR_BLOOD,m_bot)) { return; }
    if (CastSpell(BLADE_FLURRY,m_bot)) { return; }
    if (ai->GetEnergyAmount() < 20 && CastSpell(ADRENALINE_RUSH,m_bot)) { return; }
    if (CastSpell(SHADOW_DANCE,m_bot)) { return; }
    if (CastSpell(DISMANTLE,pTarget)) { return; }
    if (CastSpell(PREPARATION,m_bot)) { return; }


    if (m_bot->GetComboPoints() < 5)
    {
        if (CastSpell(RIPOSTE,pTarget)) { return; }
        if (CastSpell(KILLING_SPREE,m_bot,1,0,1)) { return; } // KILLING SPREE works great on 1 mob
        if (isUnderAttack(m_tank,3) && CastSpell(FAN_OF_KNIVES,pTarget)) { return; }
        if (BACKSTAB && !pTarget->HasInArc(M_PI,m_bot)) { if (CastSpell(BACKSTAB, pTarget)) { return; } }
        else if (CastSpell(MUTILATE, pTarget)) { return; }
        if (CastSpell(SINISTER_STRIKE,pTarget)) { return; }
        if (CastSpell(HEMORRHAGE,pTarget)) { return; }
        if (CastSpell(GHOSTLY_STRIKE,pTarget)) { return; }        
    }
    else 
    {
        if (ai->GetHealthPercent(*pTarget) > 30 && !m_bot->HasAura(SLICE_AND_DICE) && CastSpell(SLICE_AND_DICE)) { return; }
        if (ai->GetHealthPercent(*pTarget) < 20 && CastSpell(EVISCERATE)) { return; }
        if (!pTarget->HasAura(RUPTURE) && CastSpell(RUPTURE)) { return; }
        if (CastSpell(EVISCERATE)) { return; } // default if all else fails
    }
   
   
} //end DoNextCombatManeuver
void PlayerbotPaladinAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    uint8 reqHeal = 0;
    uint8 OwnPartyHP = GetHealthPercentRaid(m_bot, reqHeal);


    // Fill mana if needed
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && ai->GetManaPercent() < 20 && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
    if (ai->GetManaPercent() < 30 && CastSpell (DIVINE_PLEA, m_bot)) { return; }

    // If hp is too low divine shield
    if (ai->GetHealthPercent() < 20 && (!m_bot->HasAura(DIVINE_SHIELD) || !m_bot->HasAura(HOP) || !m_bot->HasAura(SACRED_SHIELD)))
    {
        if (!m_bot->HasAura(FORBEARANCE))
        {
            if (CastSpell(DIVINE_SHIELD,m_bot)) { return; }
            if (CastSpell(HOP,m_bot)) { return; }
        }
        else if (CastSpell(SACRED_SHIELD,m_bot)) { return; }
    }

    // if i am under attack and if i am not tank or offtank: change target if needed
    if (m_tank->GetGUID() != m_bot->GetGUID() && !TALENT_PROT && isUnderAttack() )
    {
        // Keep hitting but reduce threat
        if (CastSpell(HOS,m_bot,true,true)) { }
        //else if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot)) { return; }
        else //I cannot reduce threat so
        {
            if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
            else //Have to select nearest target
            {
                Unit *curAtt = GetNearestAttackerOf(m_bot);
                if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
                {
                    m_bot->SetSelection(curAtt->GetGUID());
                    //ai->AddLootGUID(curAtt->GetGUID());
                    DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..
                    return;
                }
            }
            //my target is attacking me
        }
    }


    #pragma region Choose Actions
    // Choose actions accoring to talents
    if (m_tank->GetGUID() == m_bot->GetGUID()) // Hey! I am Main Tank
    {
        if (TALENT_PROT) { m_role=BOT_ROLE_TANK; } //Just Keep Tanking
        else
        {
            if (TALENT_RETRI) {
                if ((ai->GetHealthPercent() <= 40 || masterHP <40 ) && (ai->GetManaPercent() >= 40)) { m_role = BOT_ROLE_SUPPORT; }
                else if (OwnPartyHP < 40 && ai->GetManaPercent() >= 30) { m_role = BOT_ROLE_SUPPORT; }
                else { m_role = BOT_ROLE_TANK; } //have no shield but can tank if you think so
            }
            else if (TALENT_HOLY) //I am both healer and tank?? Hmm
            {
                if ((ai->GetHealthPercent() <= 70 || masterHP <70 ) && (ai->GetManaPercent() >= 50))m_role = BOT_ROLE_SUPPORT;
                else if (OwnPartyHP < 20 && ai->GetManaPercent() >= 30) { m_role = BOT_ROLE_SUPPORT; }
                else m_role = BOT_ROLE_TANK;
            }
            else { m_role = BOT_ROLE_TANK; } //Unknown build or low level
        }
    }
    else if (TALENT_RETRI) {
        if ((ai->GetHealthPercent() <= 40 || masterHP <40 ) && (ai->GetManaPercent() >= 40)) { m_role = BOT_ROLE_SUPPORT; }
        else if (OwnPartyHP < 40 && ai->GetManaPercent() >= 30) {m_role = BOT_ROLE_SUPPORT;}
        else { m_role = BOT_ROLE_DPS_MELEE; }
    }
    else if (TALENT_PROT) {
        if ((ai->GetHealthPercent() <= 30 || masterHP <40 ) && (ai->GetManaPercent() >= 20)) { m_role = BOT_ROLE_SUPPORT; }
        else if (OwnPartyHP < 40 && ai->GetManaPercent() >= 40) { m_role = BOT_ROLE_SUPPORT; }
        else { m_role = BOT_ROLE_OFFTANK; }
    }
    else if (TALENT_HOLY) { m_role = BOT_ROLE_SUPPORT; }
    else { m_role = BOT_ROLE_DPS_MELEE; } //Unknown build or low level.. Mainly attack

	//takepos
    if (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) TakePosition(pTarget,BOT_ROLE_DPS_MELEE,0.5f);
    else TakePosition(pTarget,m_role);

    // If there's a cast stop
    if(m_bot->HasUnitState(UNIT_STATE_CASTING)) return;

    Unit *target = DoSelectLowestHpFriendly(40, 1000);
    switch(m_role)
    {
        #pragma region BOT_ROLE_SUPPORT
        case BOT_ROLE_SUPPORT:

            ChangeAura(CONCENTRATION_AURA);
            if (!TALENT_PROT && m_tank->GetGUID() != m_bot->GetGUID()) m_bot->RemoveAurasDueToSpell(RIGHTEOUS_FURY);
            // Choose Seal
            if (SOW && ai->GetManaPercent() <= 30) {    if (CastSpell(SOW,m_bot)) { return; } }
            else if (m_bot->HasAura(SOW) && ai->GetManaPercent() < 85) { } // Paladin was striving for mana, keep until he got most of his mana back
            else if(SOL && ai->GetHealthPercent() < 40) { if(CastSpell(SOL,m_bot)) { return; } }
            else if(CastSpell(SOR, m_bot)) { return; }

            if (!m_bot->HasAura(FORBEARANCE) && CastSpell(AVENGING_WRATH,m_bot)) { } // no gcd

            if (DoSupportRaid(m_bot)) { return; }
            //heal pets and bots
            if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; }

            if (ai->GetManaPercent() <= 80 && CastSpell(JOW,pTarget,true,true)) { return; }

            // Use Spells only if mana is sufficient..
            if(ai->GetManaPercent() < offensiveSpellThreshold ) return;

        break;
        #pragma endregion

        #pragma region BOT_ROLE_TANK / BOT_ROLE_OFFTANK
        case BOT_ROLE_TANK:
        case BOT_ROLE_OFFTANK:

            ChangeAura(DEVOTION_AURA);
            if (CastSpell(RIGHTEOUS_FURY,m_bot)) { return; }
            // Choose Seal
            if (SOW && ai->GetManaPercent() <= 30) { if (CastSpell(SOW,m_bot)) { return; } }
            else if (m_bot->HasAura(SOW) && ai->GetManaPercent() < 85) { } // Paladin was striving for mana, keep until he got most of his mana back
            else if (SOL && ai->GetHealthPercent() < 40) { if (CastSpell(SOL,m_bot)) { return; } }
            else if (CastSpell(SOR,m_bot)) { return; }

            // We are tank/offtank threat is not an issiue;
            // Use taunts only if helping target is not main tank..
            // Taunt if needed (Only for master)
            if(GetMaster()->GetGUID() != m_tank->GetGUID())
            {
                // Taunt if needed (Only for master)
                Unit *curAtt = GetAttackerOf(GetMaster());
                if (curAtt)
                {
                    if (isUnderAttack(GetMaster(),2) && CastSpell(RIGHTEOUS_DEFENSE, GetMaster())) { return; }
                    if (CastSpell(HOR, curAtt,true,true))  { } //No GCD
                }
            }
            // My target is not attacking me, taunt..
            if ( m_tank->GetGUID() == m_bot->GetGUID() && pVictim && pVictim->GetGUID() != m_bot->GetGUID() && CastSpell(HOR, pTarget,true,true) )  { } //NO GCD

            // Tank specials
            if (TALENT_PROT && ai->GetManaPercent() < 90 && CastSpell (DIVINE_PLEA, m_bot)) { return; } //Prot paladin always uses this..
            if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && CastSpell(HOLY_SHIELD,m_bot)) { return; }
            if (CastSpell(AVENGERS_SHIELD,pTarget,true,true)) { return; }
            if (CastSpell(HOTR,pTarget,true,true)) { return; }
            if (CastSpell(HOLY_WRATH,pTarget,true,true)){ return; }
            if (CastSpell(CONSECRATION,pTarget)) { return; }
            if (m_bot->getRace() == (uint8) RACE_DWARF && CastSpell(R_STONEFORM,m_bot)) { return; }

            if (DoSupportRaid(m_bot)) { return; }
            //heal pets and bots
            if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; }


        break;
		#pragma endregion

		#pragma region BOT_ROLE_DPS_MELEE
		case BOT_ROLE_DPS_MELEE:

			ChangeAura(RETRIBUTION_AURA);
			if (!TALENT_PROT && m_tank->GetGUID() != m_bot->GetGUID()) m_bot->RemoveAurasDueToSpell(RIGHTEOUS_FURY);
			if (CastSpell(SOV,m_bot)) { return; }

			if (CastSpell (HAMMER_OF_JUSTICE, pTarget)) { return; }
			if (!m_bot->HasAura(FORBEARANCE) && CastSpell(AVENGING_WRATH,m_bot)) {} //no gcd
			if (CastSpell(JOW,pTarget)) { return; }
			if (CastSpell(DIVINE_STORM, pTarget)) { return; }
			if (CastSpell(CRUSADER_STRIKE, pTarget)) { return; }
			if (GetAI()->GetHealthPercent(*pTarget)<20 && CastSpell(HAMMER_OF_WRATH, pTarget)) { return; }
			if (CastSpell(CONSECRATION,pTarget)) { return; }
			if (m_bot->HasAura(AOW) && CastSpell(EXORCISM,pTarget)) { return; }
			if (CastSpell(HOLY_WRATH,pTarget)) { return; }

		break;
        #pragma endregion

    }
    #pragma region PaladinCommon
    // Shared dps spells
    if (pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_HUMANOID && pTarget->IsNonMeleeSpellCasted(true) && CastSpell (REPENTANCE, pTarget)) { return; }
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
    if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} // no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} // no GCD

    // If at threat limit, stop
    if(pThreat > threatThreshold && !TALENT_PROT && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack())
    {
        if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
        {
            m_bot->SetSelection(m_tank->getVictim()->GetGUID());
            return;
        }
        else
        {
            if (CastSpell(HOS,m_bot)) { return; } //Lets see if we can manage with HOS
            else { return; } //use no spells and wait threat to be reduced
        }
    }
    // Continue attacking if theres excess mana (for healers)
    if (m_role == BOT_ROLE_SUPPORT && ai->GetManaPercent() < offensiveSpellThreshold) { return; }

    if (GetAI()->GetHealthPercent(*pTarget)<20 && CastSpell(HAMMER_OF_WRATH, pTarget,true,true)) { return; } //no gcd but cast
    if (CastSpell (HAMMER_OF_JUSTICE, pTarget)) { return; }
    if (CanCast(JOW,pTarget,true) &&
        ( ( ai->GetManaPercent() <= 70 && ai->GetHealthPercent() > 90)
        || ( ai->GetManaPercent() <= 50 && ai->GetHealthPercent() > 75)
        || ( ai->GetManaPercent() <= 20 && ai->GetHealthPercent() > 20) )
        && CastSpell(JOW,pTarget,false)) { return; }
    else if (CastSpell(JOL,pTarget),true,true) { return; }
    if (CastSpell(SHIELD_OF_RIGHTEOUSNESS,pTarget,true,true)) { return; }
    if (CastSpell (DIVINE_STORM, pTarget,true,true)) { return; }
    if (CastSpell (CRUSADER_STRIKE, pTarget,true,true)) { return; }
    if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no GCD but cast
    if (isUnderAttack(m_tank,4) && CastSpell(HOLY_WRATH,pTarget,true,true)) { return; }
    if (isUnderAttack(m_tank,4) && CastSpell(CONSECRATION,pTarget)) { return; }
    if (CastSpell(HOLY_SHOCK,pTarget,true,true)) { return; }
    if (m_role != BOT_ROLE_SUPPORT && ai->GetManaPercent() > 60 && OwnPartyHP < 65 && DoSupportRaid(m_bot)) { return; } //if there is spare time and mana, do healz and other stuff..
    else if (m_role != BOT_ROLE_SUPPORT && ai->GetManaPercent() > 30 && DoSupportRaid(m_bot,30,false,false,false,true,false)) { return; }
    if (CastSpell(EXORCISM,pTarget,true,true)) { return; }


    // drink potion if support / healer (Other builds simply overuse mana and waste mana pots)
    if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) )
    {
        Item *pItem = ai->FindPotion();
        if(pItem != NULL)
        {
            if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown
            ai->UseItem(*pItem);
        }
    }
    #pragma endregion

} //end DoNextCombatManeuver
void PlayerbotHunterAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    Pet *pet = m_bot->GetPet();
    if (m_tank->GetGUID() == m_bot->GetGUID() && pet && pet->isAlive() && pet->isInCombat()) { m_tank = pet; }
    uint8 petThreat = 0;
    if (pet) { GetThreatPercent(pTarget,pet); }

 //   switch (ai->GetScenarioType())
//    {
//        case PlayerbotAI::SCENARIO_DUEL:
 //           ai->CastSpell(RAPTOR_STRIKE);
 //           return;
//    }

    // ------- Non Duel combat ----------


    #pragma region Choose Target
    // Choose Target
    if (isUnderAttack()) // I am under attack
    {
        if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
        else //Have to select nearest target
        {
            Unit *curAtt = GetNearestAttackerOf(m_bot);
            if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
            {
                m_bot->SetSelection(curAtt->GetGUID());
                //ai->AddLootGUID(curAtt->GetGUID());
                DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..
                return;
            }
        }
        //my target is attacking me
    }

    #pragma endregion

    #pragma region Pet Actions
    // Pet's own Actions
    if( pet && pet->isAlive() )
    {
        // Setup pet
        if (pet->GetCharmInfo()->IsAtStay()) {pet->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW); }

        //Heal pet
        if ( ( ((float)pet->GetHealth()/(float)pet->GetMaxHealth()) < 0.5f )
        && ( PET_MEND>0 && !pet->getDeathState() != ALIVE && pVictim != m_bot
        && CastSpell(PET_MEND,m_bot) )) { return; }

        // Set pet to attack hunter's attacker > its own attackers > hunter's target
        if (!pet->getVictim()) { pet->AI()->AttackStart(pTarget); }
        else if (isUnderAttack(m_bot)) { pet->AI()->AttackStart(pTarget); }  //Always help hunter if she's under attack
        else if (pet->getVictim()->GetGUID() != pTarget->GetGUID() && !isUnderAttack(pet)) { pet->AI()->AttackStart(pTarget); }
        else if (isUnderAttack(pet)) // Pet is under attack and hunter has no attackers
        {
            if ( pet->getVictim()->getVictim() && pet->getVictim()->getVictim()->GetGUID() == pet->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
            else //Have to select nearest target
            {
                Unit *curAtt = GetNearestAttackerOf(pet,true);
                if (curAtt && (!pet->getVictim() || curAtt->GetGUID() != pet->getVictim()->GetGUID()))
                {
                    pet->AI()->AttackStart(curAtt); //Attack nearest attacker
                }
            }
            //Actions to do under attack (Always tank it, and try to kill it, until someone (!= hunter) takes aggro back)
            //Hunter should help her pet whether main tank or not, unless she's being attacked (BEWARE Targeting Loop possibility)
            if (pet->getVictim() && !isUnderAttack(m_bot) && pet->getVictim()->GetGUID() != pTarget->GetGUID())
            {
                m_bot->SetSelection(pet->getVictim()->GetGUID());
                DoNextCombatManeuver(pet->getVictim()); //Restart new update to get variables fixed..
                return;
            }

        }
        // Pet tanking behaviour
        if (pet->GetGUID() == m_tank->GetGUID() || isUnderAttack(m_bot) || isUnderAttack(pet))
        {
            if (GROWL) pet->GetCharmInfo()->SetSpellAutocast(GROWL,true); //Autocast growl
            if (BAD_ATTITUDE) pet->GetCharmInfo()->SetSpellAutocast(BAD_ATTITUDE,true);
            if (COWER) pet->GetCharmInfo()->SetSpellAutocast(COWER,false);
            if (CastSpell(INTIMIDATION,m_bot)) { return; }
        }
        else
        {
            if (GROWL) pet->GetCharmInfo()->SetSpellAutocast(GROWL,false); //Do not try to get aggro
            if (BAD_ATTITUDE) pet->GetCharmInfo()->SetSpellAutocast(BAD_ATTITUDE,false);
            if (COWER) pet->GetCharmInfo()->SetSpellAutocast(COWER,true); //Autocast cower
        }
        // NORMAL PET dps attacks
        if (petThreat < threatThreshold || pet->GetGUID() == m_tank->GetGUID() || isUnderAttack(m_bot))
        {
            if (CastSpell(KILL_COMMAND,m_bot)) { }
            else if (CastSpell(BESTIAL_WRATH,m_bot)) { }
        }
        // NETHERSHOCK DEMORALIZINGSCREECH
    }
    #pragma endregion

    // If there's a cast stop
    if(m_bot->HasUnitState(UNIT_STAT_CASTING)) return;

    // Cast CC breakers if any match found  (does not work yet)
    // uint32 ccSpells[4] = { R_ESCAPE_ARTIST, R_EVERY_MAN_FOR_HIMSELF, R_WILL_OF_FORSAKEN, R_STONEFORM };
    // if (castSelfCCBreakers(ccSpells)) { } //most of them dont have gcd

    #pragma region Evasive manuevers
    // Do evasive manuevers if under attack
    if (isUnderAttack())
    {
        if (m_tank->GetGUID() == m_bot->GetGUID()) { } // i am tank and my pet is probably dead, so i have to face the attackers
        else if (CastSpell(FEIGN_DEATH,m_bot)) { return; } //avoid attack
        //else if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot) ) { return; }
        else if (CastSpell(CONCUSSIVE_SHOT,pTarget)) { return; }
        else if (CastSpell(WYVERN_STING,pTarget)) { return; }
        else if (CastSpell(SCATTER_SHOT,pTarget)) { return; }
        else if (CastSpell(FREEZING_ARROW,pTarget)) { return; }
        else if (CastSpell(MISDIRECTION,m_tank)) { return; }
        else if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget) ) { return; } //no gcd but is cast
        else if (pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST && CastSpell(SCARE_BEAST,pTarget)) { return; }
        else if (pDist <= 2 && CastSpell(FREEZING_TRAP,pTarget)) { return; }
    }
    #pragma endregion

    //Select combat mode
    m_role = BOT_ROLE_DPS_RANGED;
    if ((isUnderAttack()  && pDist <= ATTACK_DISTANCE) || !m_bot->GetUInt32Value(PLAYER_AMMO_ID) ) { m_role = BOT_ROLE_DPS_MELEE; }

    TakePosition(pTarget);

    #pragma region Buff / Protect
    //Buff UP
    if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot) ) {  } //no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot) ) { } //no GCD
    if (CastSpell(TRUESHOT_AURA, m_bot)) { return; }
    if (CastSpell(RAPID_FIRE,m_bot)) { return; }
    if (CastSpell(HUNTERS_MARK,pTarget)) { return; }
    if ((ai->GetHealthPercent() < 80 || ai->GetManaPercent() < 60 ) && CastSpell(READINESS,m_bot)) { } //no gcd


    //Protect yourself if needed
    if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot) ) { } //no gcd
    if (ai->GetHealthPercent() < 20 && CastSpell(DETERRENCE,m_bot)) {} //No GCD
    if (m_bot->getRace() == (uint8) RACE_DRAENEI && ai->GetHealthPercent() < 55 && CastSpell(R_GIFT_OF_NAARU,m_bot)) { return;  }

    //Break Spells
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && ( pTarget->IsNonMeleeSpellCasted(true) || ai->GetManaPercent() < 20 ) && CastSpell(R_ARCANE_TORRENT, pTarget) ) { } //no gcd
    if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(SILENCING_SHOT, pTarget) ) { return; }
    if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(SCATTER_SHOT, pTarget) ) { return; }

    //Catch
    if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING))
    {
        if (CastSpell(WING_CLIP,pTarget)) return;
        if (CastSpell(CONCUSSIVE_SHOT,pTarget)) return;
        if (CastSpell(SCATTER_SHOT, pTarget) ) { return; }
    }
    #pragma endregion

    //Do combat
    switch (m_role)
    {
        #pragma region BOT_ROLE_DPS_MELEE
        case BOT_ROLE_DPS_MELEE:
            if (AUTO_SHOT) { m_bot->InterruptNonMeleeSpells( true, AUTO_SHOT ); } //Stop autoshot
            if (CastSpell(ASPECT_OF_THE_MONKEY,m_bot)) { return; } //Get Monkey aspect

            if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd but is cast

            // Threat control
            if (pThreat < threatThreshold || m_tank->GetGUID() == m_bot->GetGUID() || m_bot->HasAura(MISDIRECTION) ) { } //Continue attack
            else
            {
                if (pet && isUnderAttack(pet) && pet->getVictim() && pet->getVictim()->GetGUID() != pTarget->GetGUID()) //Should be helping pet
                {
                    m_bot->SetSelection(pet->getVictim()->GetGUID());
                    return;
                }
                else if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
                {
                    m_bot->SetSelection(m_tank->getVictim()->GetGUID());
                    return;
                }
                else if (CastSpell(FEIGN_DEATH,m_bot)) { return; }
                else { return; } // No more threat reducing spells, just slow down
            }

            if (CastSpell(RAPTOR_STRIKE,pTarget,true,true)) {} //No gcd
            if (CastSpell(MONGOOSE_BITE,pTarget,true,true)) { return; } // Cannot be sure if casted or not
            else if (CastSpell(COUNTERATTACK,pTarget,true,true)) { return; } // Cannot be sure if casted or not
            if (CastSpell(WING_CLIP,pTarget)) { return; }
            if (isUnderAttack(m_tank,6) && CastSpell(SNAKE_TRAP,m_bot)) { return; }
            if (isUnderAttack(m_tank,4) && CastSpell(EXPLOSIVE_TRAP,m_bot)) { return; }
            if (CastSpell(IMMOLATION_TRAP,m_bot)) { return; }
            break;
        #pragma endregion

        #pragma region BOT_ROLE_DPS_RANGED
        case BOT_ROLE_DPS_RANGED:
            if (m_pulling) {
                if (GetAI()->CastSpell(CONCUSSIVE_SHOT,pTarget) ||
                    GetAI()->CastSpell(AUTO_SHOT,pTarget)) {
                    m_pulling = false;
                    GetAI()->SetCombatOrder(ORDERS_NONE);
                    GetAI()->Follow(*GetMaster());
                    GetAI()->SetIgnoreUpdateTime(2);

                    if(HasPet(GetPlayerBot()))
                        m_bot->GetPet()->SetReactState(REACT_DEFENSIVE);
                }
                return;
            }
            if (AUTO_SHOT && !m_bot->FindCurrentSpellBySpellId(AUTO_SHOT)) { ai->CastSpell(AUTO_SHOT,pTarget); } //Start autoshot
            if (!(ai->GetManaPercent() < 85 && m_bot->HasAura(ASPECT_OF_THE_VIPER)) && CastSpell(ASPECT_OF_THE_HAWK,m_bot)) { return; } //Get Hawk aspect
            if ((ai->GetManaPercent() < 25) && CastSpell(ASPECT_OF_THE_VIPER,m_bot,true,false,true)) { return; } //Build up mana

            // if i am main tank, protect master by taunt
            if(m_tank->GetGUID() == m_bot->GetGUID())
            {
                // Taunt if needed (Only for master)
                Unit *curAtt = GetAttackerOf(GetMaster());
                if (curAtt && CastSpell(DISTRACTING_SHOT, curAtt))  { return; }
                // My target is not attacking me, taunt..
                if (pVictim && pVictim->GetGUID() != m_bot->GetGUID() && CastSpell(DISTRACTING_SHOT, pTarget) )  { return; }
            }
            // If i am not tank, transfer threat to tank or pet..
            else
            {
                if (CastSpell(MISDIRECTION,m_tank)) { return; }
                if (pet && pet->isAlive() && CastSpell(MISDIRECTION,pet)) { return; }

                // Threat control
                if (pThreat < threatThreshold || m_bot->HasAura(MISDIRECTION) ) { } //Continue attack
                else
                {
                    if (pet && isUnderAttack(pet) && pet->getVictim() && pet->getVictim()->GetGUID() != pTarget->GetGUID()) //Should be helping pet
                    {
                        m_bot->SetSelection(pet->getVictim()->GetGUID());
                        return;
                    }
                    else if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
                    {
                        m_bot->SetSelection(m_tank->getVictim()->GetGUID());
                        return;
                    }
                    else if (CastSpell(FEIGN_DEATH,m_bot)) { return; }
                    else { return; } // No more threat reducing spells, just slow down
                }
            }

            // DO dps
            if (ai->GetHealthPercent(*pTarget) < 20 && CastSpell(KILL_SHOT,pTarget)) { return; }
            if (isUnderAttack(m_tank,4) && CastSpell(MULTI_SHOT,pTarget)) { return; }
            if (isUnderAttack(m_tank,4) && CastSpell(VOLLEY,pTarget)) { GetAI()->SetIgnoreUpdateTime(7); return; }
            if (CanCast(CHIMERA_SHOT,pTarget) &&
                (pTarget->HasAura(VIPER_STING,m_bot->GetGUID()) || pTarget->HasAura(SERPENT_STING,m_bot->GetGUID()) )
                && CastSpell(CHIMERA_SHOT,pTarget,false) ) { return; }
            if (ai->GetManaPercent() < 60 && ai->GetManaPercent(*pTarget) > 4 && CastSpell(VIPER_STING,pTarget)) { return; }
            if (!pTarget->HasAura(VIPER_STING,m_bot->GetGUID()) && CastSpell(SERPENT_STING,pTarget)) { return; }
            if (CastSpell(ARCANE_SHOT,pTarget)) { return; }
            if (CastSpell(BLACK_ARROW,pTarget)) { return; }
            if (CastSpell(EXPLOSIVE_SHOT,pTarget)) { return; }
            if (CastSpell(STEADY_SHOT,pTarget)) { return; }
            break;
        #pragma endregion
    }

    /*// drink potion if support / healer (Other builds simply overuse mana and waste mana pots)
    if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) )
    {
        Item *pItem = ai->FindPotion();
        if(pItem != NULL)
        {
            if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown
            ai->UseItem(*pItem);
        }
    }*/
} // end DoNextCombatManeuver
void PlayerbotDeathKnightAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    Pet *pet = m_bot->GetPet();
    std::ostringstream out;


    if (!m_pulling)
    {
        m_role = BOT_ROLE_DPS_MELEE;
        #pragma region Choose Role/Presence

        // Choose Presence
        if (m_tank->GetGUID() == m_bot->GetGUID()) // Hey! I am Main Tank
        {
            if (CastSpell(FROST_PRESENCE,m_bot)) { m_role = BOT_ROLE_TANK; return; }
        }
        else if (isUnderAttack()) // I am under attack
        {
            if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2)  {} // My target is almost up to me, no need to search
            else //Have to select nearest target
            {
                Unit *curAtt = GetNearestAttackerOf(m_bot);
                if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
                {
                    m_bot->SetSelection(curAtt->GetGUID());
                    //ai->AddLootGUID(curAtt->GetGUID());
                    DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..
                    return;
                }
            }
            //my target is attacking me
            //if (m_bot->getRace() == (uint8) RACE_NIGHTELF && CastSpell(R_SHADOWMELD,m_bot) ) { return; }
            if (CastSpell(FROST_PRESENCE,m_bot)) { m_role = BOT_ROLE_OFFTANK; return; }
        }
        else if (TALENT_UNHOLY)
        {
            if (CastSpell(UNHOLY_PRESENCE,m_bot)) return;
        }
        else if (CastSpell(BLOOD_PRESENCE,m_bot)) return;
        #pragma endregion
    }

    // Cast CC breakers if any match found  (does not work yet)
    // uint32 ccSpells[6] = { LICHBORNE, ICEBOUND_FORTITUDE, R_ESCAPE_ARTIST, R_EVERY_MAN_FOR_HIMSELF, R_WILL_OF_FORSAKEN, R_STONEFORM };
    // if (castSelfCCBreakers(ccSpells)) { } //most of them dont have gcd

    TakePosition(pTarget);


   if (m_pulling) {
        if (GetAI()->CastSpell(DEATH_GRIP,pTarget)) {
            m_pulling = false;
            GetAI()->SetCombatOrder(ORDERS_NONE);
            GetAI()->Follow(*GetMaster());
            GetAI()->SetIgnoreUpdateTime(2);

            if (m_bot->GetPet()) pet->SetReactState (REACT_DEFENSIVE);
         }
          return;
    }

    // If there's a cast stop
    if(m_bot->HasUnitState(UNIT_STATE_CASTING)) { return; }

    #pragma region Buff Heal Interrupt
    //Buff UP
    if (CastSpell(HORN_OF_WINTER,m_bot)) { return; }
    if (CastSpell(BONE_SHIELD,m_bot)) { return; }

    //HEAL UP && PROTECT UP
    if (ai->GetHealthPercent() < 80 && ai->GetHealthPercent() > 20 && CastSpell(VAMPIRIC_BLOOD,m_bot)) { }  //NO GCD
    if (ai->GetHealthPercent() < 65 && CastSpell(RUNE_TAP,m_bot)) { } //NO GCD
    if (CanCast(DEATH_STRIKE,pTarget,true) && ai->GetHealthPercent() < 90 &&
        (pTarget->HasAura(FROST_FEVER,m_bot->GetGUID()) ||pTarget->HasAura(BLOOD_PLAGUE,m_bot->GetGUID()) )
        && CastSpell(DEATH_STRIKE,pTarget,false) ) {return;}
    if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot)) { } //no gcd
    if (m_bot->getRace() == (uint8) RACE_DRAENEI && ai->GetHealthPercent() < 55 && CastSpell(R_GIFT_OF_NAARU,m_bot)) { return; } //no Gcd, but has cast
    if (pet && ai->GetHealthPercent() < 50 && CastSpell(DEATH_PACT,m_bot)) { return; }
    if (pet && ai->GetHealthPercent() < 60 && CastSpell(MARK_OF_BLOOD,pTarget)) { return; }
    if (ai->GetHealthPercent() < 65 && CastSpell(ICEBOUND_FORTITUDE,m_bot)) { } //No GCD
    if (ai->GetHealthPercent() < 65 && CastSpell(UNBREAKABLE_ARMOR,m_bot)) { return; }

    //Break spells being cast
    if (pTarget->IsNonMeleeSpellCasted(true))
    {
        if (CastSpell(MIND_FREEZE,pTarget)) {} // No GCD
        if (CastSpell(STRANGULATE,pTarget)) { return; }
        if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
        if (CastSpell(ANTI_MAGIC_ZONE,m_bot)) { return; }
        if (CastSpell(ANTI_MAGIC_SHELL,m_bot)) {} //NO GCD
    }

    //Catch
    if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING))
    {
        if (CastSpell(DEATH_GRIP,pTarget)) return;
        if (CastSpell(CHAINS_OF_ICE,pTarget)) return;
    }
    #pragma endregion

    #pragma region Taunt / Threat
    // if i am main tank, protect master by taunt
    if(m_tank->GetGUID() == m_bot->GetGUID())
    {
        // Taunt if needed (Only for master)
        Unit *curAtt = GetAttackerOf(GetMaster());
        if (curAtt && CastSpell(DARK_COMMAND, curAtt))  { }     //No gcd
        // My target is not attacking me, taunt..
        if (pVictim && pVictim->GetGUID() != m_bot->GetGUID() && CastSpell(DARK_COMMAND, pTarget) )  { } // No gcd
    }

    // If not in Frost Presence slow down due to threat
    if (pThreat > threatThreshold && !m_bot->HasAura(FROST_PRESENCE) && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack())
    {
        if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
        {
            m_bot->SetSelection(m_tank->getVictim()->GetGUID());
            return;
        }
        else { return; } //DK has no threat reducing spells, just slow down
    }
    #pragma endregion

    #pragma region Dps
    //Dps up
    if (CastSpell(EMPOWER_WEAPON,m_bot)) {} //NO GCD
    if (ai->GetHealthPercent() > 90 && CastSpell(HYSTERIA,m_bot)) {} //NO GCD
    if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} //no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} //no GCD

    // Use up excess Runic Power
    if (ai->GetRunicPower() > 60 && CastSpell(FROST_STRIKE,pTarget)) { return; }
    else if (ai->GetRunicPower() > 60 && CastSpell(DEATH_COIL,pTarget,true,true,true)) { return; }
    if ((isUnderAttack() || ai->GetRunicPower() > 70) && CastSpell(RUNE_STRIKE,pTarget)) {} //Next attack spell

    // Build Diseases
    if (!pTarget->HasAura(FROST_FEVER,m_bot->GetGUID()) && CastSpell(ICY_TOUCH,pTarget)) { return; }
    if (!pTarget->HasAura(BLOOD_PLAGUE,m_bot->GetGUID()) && CastSpell(PLAGUE_STRIKE,pTarget)) { return; }

    // Use AOEs summons
    if (isUnderAttack(m_tank,4) && CastSpell(DEATH_AND_DECAY,pTarget)) { return; }
    if (isUnderAttack(m_tank,4) && CastSpell(HOWLING_BLAST,pTarget)) { return; }
    if (CanCast(PESTILENCE,pTarget,true) && isUnderAttack(m_tank,4) &&
        (pTarget->HasAura(FROST_FEVER,m_bot->GetGUID()) && pTarget->HasAura(BLOOD_PLAGUE,m_bot->GetGUID()) )
        && CastSpell(PESTILENCE,pTarget,false)) { return; }
    if (CanCast(BLOOD_BOIL,pTarget,true) && isUnderAttack(m_tank,4) &&
        (pTarget->HasAura(FROST_FEVER,m_bot->GetGUID()) || pTarget->HasAura(BLOOD_PLAGUE,m_bot->GetGUID()) )
        && CastSpell(BLOOD_BOIL,pTarget,false)) { return; }
    if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd but is cast
    if (isUnderAttack(m_tank,6) && CastSpell(ARMY_OF_THE_DEAD,m_bot)) { return; }
    if (isUnderAttack(m_tank,4) && CastSpell(SUMMON_GARGOYLE,pTarget)) { return; } //This should be somewhat different

    // Use standard damage spells
    if (CastSpell(HEART_STRIKE,pTarget,true,true)) { return; }
    if (CastSpell(BLOOD_STRIKE,pTarget)) { return; }
    if (TALENT_FROST && CastSpell(OBLITERATE,pTarget)) { return; }
    else if (TALENT_UNHOLY && CastSpell(SCOURGE_STRIKE,pTarget)) { return; }
    else if (CastSpell(DEATH_STRIKE,pTarget)) { return; }
    #pragma endregion

} // end DoNextCombatManeuver