bool PlayerbotDruidAI::BuffPlayer(Unit *target)
{
    PlayerbotAI *ai = GetAI();
    Player *m_bot = GetPlayerBot();
    if (!m_bot || !ai || m_bot->isDead()) { return false; }

    if(!target || target->isDead()) { return false; }

    if (CanCast(THORNS,target,0,0,1) && !HasAuraName(target, THORNS)) {
        // Decide if it is worth to change form
        if( /*m_bot->HasAura(MOONKIN_FORM) ||*/ m_bot->HasAura(CAT_FORM) || m_bot->HasAura(BEAR_FORM))
        {
            if(GetAI()->GetManaPercent() >= 80 ) { ChangeForm(1); }
            else { return false; }
        }
        return CastSpell(THORNS, target, false);
    }
    if (CanCast(MARK_OF_THE_WILD,target,0,0,1) && !HasAuraName(target, GIFT_OF_THE_WILD) && !HasAuraName(target, MARK_OF_THE_WILD)) {
        // Decide if it is worth to change form
        if(/*m_bot->HasAura(MOONKIN_FORM) ||*/ m_bot->HasAura(CAT_FORM) || m_bot->HasAura(BEAR_FORM))
        {
            if(GetAI()->GetManaPercent() >= 70 ) { ChangeForm(1); }
            else return false;
        }
        return CastSpell(MARK_OF_THE_WILD, target, false);
    }
    return false;
}
示例#2
0
            void DoNonCombatActions()
            {
                //if eating or drinking don't do anything
                if (me->HasAura(10256) || me->HasAura(1137))
                    return;

                Feast();

                //buff master
                if (!HasAuraName(master, SPELL_PRAYER_OF_SHADOW, 0) && isTimerReady(uiGc_Timer))
                    doCast(master, SPELL_PRAYER_OF_SHADOW, true);

                if (!HasAuraName(master, SPELL_FEAR_WARD, 0) && isTimerReady(uiGc_Timer))
                    doCast(master, SPELL_FEAR_WARD, true);

                if (!HasAuraName(master, SPELL_DIVINE_SPIRIT, 0) && isTimerReady(uiGc_Timer))
                {
                    doCast(master, SPELL_DIVINE_SPIRIT, true);
                    GiveManaBack();
                }

                //buff myself
                if (!me->HasAura(SPELL_INNER_FIRE, 0) && isTimerReady(uiGc_Timer))
                    doCast(me, SPELL_INNER_FIRE, true);

                if (!me->HasAura(SPELL_PW_FORTITUDE, 0) && isTimerReady(uiGc_Timer))
                    doCast(me, SPELL_PW_FORTITUDE, true);

                //buff and heal master's group
                if (master->GetGroup())
                    RezGroup(SPELL_RESURRECTION, master);
            }
bool PlayerbotDruidAI::HealTarget(Unit *target, uint8 hp)
{
    PlayerbotAI *ai = GetAI();
    Player *m_bot = GetPlayerBot();
    if (!m_bot || !ai || m_bot->isDead()) { return false; }
    if (!target || target->isDead()) { return false; }

    // Decide if it is worth to change form
    if (ai->GetForm() == FORM_MOONKIN || ai->GetForm() == FORM_CAT || ai->GetForm() == FORM_DIREBEAR || ai->GetForm() == FORM_BEAR)
    {
        if (hp < 75 && GetAI()->GetManaPercent() >= 70 ) { ChangeForm(1); }
        else if (hp < 40 && GetAI()->GetManaPercent() >= 50) { ChangeForm(1); }
        else if (hp < 25 && GetAI()->GetManaPercent() >= 30) { ChangeForm(1); }
        else return false;
    }

    // if(m_bot->HasAura(TRAVEL_FORM)) ChangeForm(1);

    if(hp < 60 && m_bot->HasAura(NATURES_SWIFTNESS) && CastSpell(HEALING_TOUCH, target)) { return true; }
    if(hp < 90 && CastSpell(LIFEBLOOM, target)) { return true; }
    if(hp < 80 && CastSpell(REJUVENATION, target)) { return true; }
    if(hp < 60 && CastSpell(REGROWTH, target)) { return true; }
    if(hp < 70 && CanCast(NOURISH,target) &&
        (HasAuraName(target,REJUVENATION,m_bot->GetGUID()) || HasAuraName(target,LIFEBLOOM,m_bot->GetGUID()) || HasAuraName(target,REGROWTH,m_bot->GetGUID()))
        ) { return CastSpell(NOURISH, target, false); }
    if(hp < 50 && CanCast(SWIFTMEND,target) &&
        (HasAuraName(target,REJUVENATION,m_bot->GetGUID()) || HasAuraName(target,REGROWTH,m_bot->GetGUID()))
        ) { return CastSpell(SWIFTMEND, target, false); }
    if(hp < 40 && m_bot->isInCombat() && CastSpell(NATURES_SWIFTNESS, m_bot)) { } // NO gcd
    if(hp < 40 && CastSpell(HEALING_TOUCH, target)) { return true; }
    return false;
} //end HealTarget
示例#4
0
 uint8 Afflicted(Unit* target)
 {
     if (!target || target->IsDead()) return 0;
     bool aff = HasAuraName(target, UNSTABLE_AFFLICTION, me->GetGUID());
     bool imm = HasAuraName(target, IMMOLATE, me->GetGUID());
     if (imm) return 1;
     if (aff) return 2;
     return 0;
 }
示例#5
0
文件: bot_mage_ai.cpp 项目: ddark/ecl
        void DoNonCombatActions(uint32 diff)
        {
            if (GC_Timer > diff || me->IsMounted()) return;
            if (Feasting()) return;

            if (!HasAuraName(me, DAMPENMAGIC) && 
                doCast(me, DAMPENMAGIC))
            { /*GC_Timer = 800;*/ return; }

            if (!HasAuraName(me, ICEARMOR) && 
                doCast(me, ICEARMOR))
            { /*GC_Timer = 800;*/ return; }
        }
bool PlayerbotMageAI::BuffPlayer(Unit *target)
{
    if (!target || target->isDead()) return false;

    if (target->getClass() == CLASS_WARRIOR || target->getClass() == CLASS_DEATH_KNIGHT || target->getClass() == CLASS_ROGUE) return false;

    if (!HasAuraName(target, ARCANE_INTELLECT) && !HasAuraName(target, ARCANE_BRILLIANCE) && !HasAuraName(target, DALARAN_INTELLECT) && !HasAuraName(target, DALARAN_BRILLIANCE))
    {
        if (CastSpell(ARCANE_BRILLIANCE, target)) return true;
        else if (CastSpell (ARCANE_INTELLECT, target)) return true;
    }
    return false;
}
示例#7
0
            void BuffTarget(Unit* target)
            {
                if (!HasAuraName(target, GetSpellName(SPELL_PW_FORTITUDE)))
                {
                    doCast(target, SPELL_PW_FORTITUDE, false);
                    GiveManaBack();
                }

                if (!HasAuraName(target, GetSpellName(SPELL_PRAYER_OF_SHADOW)))
                {
                    doCast(target, SPELL_PRAYER_OF_SHADOW, false);
                    GiveManaBack();
                }
            }
示例#8
0
            bool CureTarget(Unit* target)
            {
                if (!isTimerReady(uiGc_Timer))
                    return false;

                if (HasAuraName(target, "Withering Heat"))
                    doCast(target, SPELL_CLEANSE);

                if (HasAuraName(target, "Ancient Dread"))
                    doCast(target, SPELL_CLEANSE);

                if (HasAuraName(target, "Ancient Dread"))
                    doCast(target, SPELL_CLEANSE);

                if (HasAuraName(target, "Arcane Buffet"))
                    doCast(target, SPELL_CLEANSE);

                if (HasAuraName(target, "Shadow Buffet"))
                    doCast(target, SPELL_CLEANSE);

                if (HasAuraName(target, "Flame Buffet"))
                    doCast(target, SPELL_CLEANSE);

                if (HasAuraName(target, "Frost Buffet"))
                doCast(target, SPELL_CLEANSE);

                return true;
            }
bool PlayerbotClassAI::HasAuraName (Unit *unit, uint32 spellId, uint64 casterGuid)
{
    const SpellEntry *const pSpellInfo = GetSpellStore()->LookupEntry (spellId);
    if(!pSpellInfo) return false;
    int loc = m_bot->GetSession()->GetSessionDbcLocale();
    const std::string  name = pSpellInfo->SpellName[loc];
    if(name.length() == 0) return false;
    return HasAuraName(unit, name, casterGuid);
}
bool PlayerbotShamanAI::ChangeTotems(uint32 mode)
{
    uint32 earth=0, fire=0, water=0, air=0;

    PlayerbotAI *ai = GetAI();
    if(!ai) return false;
    Player *m_bot = GetPlayerBot();
    if(!m_bot || m_bot->isDead()) return false;

    Unit *pTarget = m_bot->GetSelectedUnit();
    Unit *pVictim = NULL;
    if (m_bot->GetSelectedUnit()->IsFriendlyTo(m_bot)) pTarget = NULL;
    if (pTarget) pVictim = pTarget->getVictim();

    //Defaults
    if (!HasAuraName(m_bot,"Horn of Winter") )earth = STRENGTH_OF_EARTH_TOTEM;
    if (!earth) earth = STONESKIN_TOTEM;
    if (!earth) earth = EARTHBIND_TOTEM;
    fire = TOTEM_OF_WRATH;
    if (!fire) fire = FLAMETONGUE_TOTEM;
    if (!fire) fire = SEARING_TOTEM;
    water = MANA_SPRING_TOTEM;
    if (!water) water = HEALING_STREAM_TOTEM;
    if (TALENT_ELEMENTAL || TALENT_RESTO) air = WRATH_OF_AIR_TOTEM;
    else air = WINDFURY_TOTEM;

    //Target reactive stuff
    if (pTarget)
    {
        if (GROUNDING_TOTEM && pTarget->IsNonMeleeSpellCasted(true)) air = GROUNDING_TOTEM;
    }

    if (STONESKIN_TOTEM && isUnderAttack()) earth = STONESKIN_TOTEM;

    uint32 totz[4] = {earth, fire, water, air};

    for (int i = 0; i < 4; i++)
    {
        if (!totz[i]) continue;
        SpellInfo const *tSpell = GetSpellInfo(totz[i]);
        SpellEntry *tmp = 0;
        tmp->Id = tSpell->Id;
        if (!tSpell) continue;
        uint32 tEntry = (uint32) tSpell->Effects->MiscValue;
        if (!tEntry) continue;
        //CreatureTemplate const *totemEntry = ObjectMgr::GetCreatureTemplateStore(tEntry);
        if (!tEntry) continue;

        if (CanCast(totz[i], m_bot) && !m_bot->FindNearestCreature(tEntry,30)) {
            return CastSpell(totz[i],m_bot,false);
        }
    }
    return false;
}
void PlayerbotMageAI::DoNonCombatActions()
{
    PlayerbotAI *ai = GetAI();
    Player *m_bot = GetPlayerBot();
    if (!m_bot || !ai || m_bot->isDead()) { return; }

    // make sure pet stays by your side
    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){
            m_bot->GetSession()->HandlePetActionHelper(unit, pet_guid, COMMAND_FOLLOW, ACT_COMMAND, 0);
            m_bot->GetSession()->HandlePetActionHelper(unit, pet_guid, REACT_DEFENSIVE, ACT_REACTION, 0);
        }
    }


    //If Casting or Eating/Drinking return
    if (m_bot->HasUnitState(UNIT_STAT_CASTING)) { return; }
    if (m_bot->getStandState() == UNIT_STAND_STATE_SIT) { return; }

    //buff and heal raid
    if (DoSupportRaid(m_bot,30,0,0,0,1,1)) { return; }

    //Own Buffs
    if (MOLTEN_ARMOR) { if ( CastSpell(MOLTEN_ARMOR,m_bot)) { return; } }
    else if (CastSpell(MAGE_ARMOR,m_bot)) { return; }
    if (CastSpell(COMBUSTION,m_bot)) { } //nogcd
    if (!HasAuraName(m_bot, MANA_SHIELD)) CastSpell (MANA_SHIELD);

    //conjure food & water
    Item *pItem = ai->FindDrink();
	if(pItem == NULL && ai->GetManaPercent() >= 48)
    {
        if (CastSpell(CONJURE_REFRESHMENT, m_bot)) { return; }
        if (CastSpell(CONJURE_WATER, m_bot)) { return; }
        return;
    }
    pItem = ai->FindFood();
    if(pItem == NULL && ai->GetManaPercent() >= 48)
    {
        if (CastSpell(CONJURE_REFRESHMENT, m_bot)) { return; }
        if (CastSpell(CONJURE_FOOD, m_bot)) { return; }
        return;
    }
    //Conjure mana gem??

    //mana/hp check
    //Don't bother with eating, if low on hp, just let it heal themself
    if (m_bot->getRace() == (uint8) RACE_UNDEAD_PLAYER && ai->GetHealthPercent() < 75 && CastSpell(R_CANNIBALIZE,m_bot)) { return; }
    if (ai->GetManaPercent() < 50 && CastSpell (EVOCATION, m_bot)) { return; }
    if (ai->GetManaPercent() < 50 || ai->GetHealthPercent() < 50) { ai->Feast(); }
} //end DoNonCombatActions
示例#12
0
        bool BuffTarget(Unit* target, uint32 diff)
        {
            if (GC_Timer > diff || Rand() > 20) return false;
            if (me->IsInCombat() && !master->GetMap()->IsRaid()) return false;
            if (me->GetExactDist(target) > 30) return false;
            if (ARCANEBRILLIANCE && target->getPowerType() == POWER_MANA && !HasAuraName(target, ARCANEBRILLIANCE) &&
                doCast(target, ARCANEBRILLIANCE))
                return true;

            return false;
        }
示例#13
0
        void DoNonCombatActions(uint32 diff)
        {
            if (GC_Timer > diff || me->IsMounted()) return;
            if (Feasting()) return;

            //if (DAMPENMAGIC && !HasAuraName(me, DAMPENMAGIC) &&
            //    doCast(me, DAMPENMAGIC))
            //{ /*GC_Timer = 800;*/ return; }

            if (FROSTARMOR && !HasAuraName(me, FROSTARMOR) &&
                doCast(me, FROSTARMOR))
                return;
        }
示例#14
0
文件: bot_mage_ai.cpp 项目: ddark/ecl
 bool BuffTarget(Unit* target, uint32 diff)
 {
     if (GC_Timer > diff || !target || target->isDead() || Rand() > 50) return false;
     if (me->IsInCombat() && !master->GetMap()->IsRaid()) return false;
     if (me->GetExactDist(target) > 30) return false;
     if (target->getPowerType() == POWER_MANA && 
         !HasAuraName(target, ARCANEINTELLECT) && 
         doCast(target, ARCANEINTELLECT))
     {
         /*GC_Timer = 800;*/
         return true;
     }
     return false;
 }
示例#15
0
            void BuffTarget(Unit* target)
            {
                if (!target)
                    return;

                switch(target->getClass())
                {
                    case CLASS_MAGE:
                    case CLASS_PRIEST:
                    case CLASS_WARLOCK:
                        if (!HasAuraName(target, GetSpellName(SPELL_BLESSING_OF_WISDOM)))
                            doCast(target, SPELL_BLESSING_OF_WISDOM, true);
                        break;
                    case CLASS_PALADIN:
                        if (!HasAuraName(target, GetSpellName(SPELL_BLESSING_OF_SANCTUARY)))
                            doCast(target, SPELL_BLESSING_OF_SANCTUARY, true);
                        break;
                    default:
                        if (!HasAuraName(target, GetSpellName(SPELL_BLESSING_OF_KINGS)))
                            doCast(target, SPELL_BLESSING_OF_KINGS, true);
                        break;
                }
            }
示例#16
0
    void DoNormalAttack(const uint32 diff)
    {
        AttackerSet m_attackers = master->getAttackers();
        if(opponent == NULL) return;
        if(opponent->isDead()) return;

        //double check that pet didn't just die
        if(pet && pet != NULL && pet->isDead())
        {
            master->SetBotsPetDied();
            pet = NULL;
        }

        //send in the pet
        if(pet && pet != NULL && pet->isAlive() && !pet->isInCombat()) pet->AI()->AttackStart(opponent);

        if(!isTimerReady(GC_Timer)) return;

        if(opponent->HasUnitMovementFlag(UNIT_FLAG_FLEEING))
        {
            //MonsterSay("Mob is fleeing!", LANG_UNIVERSAL, NULL);
            return;
        }


        //if(RAIN_OF_FIRE && m_attackers.size() > 1)
        //{
            //doCast(opponent, RAIN_OF_FIRE);
            //return;
        //}
        if(CURSE_OF_THE_ELEMENTS && !HasAuraName(opponent, CURSE_OF_THE_ELEMENTS))
        {
            doCast(opponent, CURSE_OF_THE_ELEMENTS);
            GiveManaBack();
            //return;
        }

        if(CORRUPTION && !HasAuraName (opponent, CORRUPTION, m_creature->GetGUID()))
        {
            doCast(opponent, CORRUPTION);
            GiveManaBack();
            //return;
        }

        if(HAUNT && !HasAuraName (opponent, HAUNT, m_creature->GetGUID()))
        {
            doCast(opponent, HAUNT);
            GiveManaBack();
            return;
        }

        if(UNSTABLE_AFFLICTION && !HasAuraName (opponent, UNSTABLE_AFFLICTION, m_creature->GetGUID()))
        {
            doCast(opponent, UNSTABLE_AFFLICTION);
            GiveManaBack();
            return;
        }

        if(!HasAuraName(opponent, IMMOLATE, m_creature->GetGUID()))
        {
            doCast(opponent, IMMOLATE);
            GiveManaBack();
            return;
        } else if(CONFLAGRATE && isTimerReady(conflagarate_cd))
        {
            doCast(opponent, CONFLAGRATE);
            conflagarate_cd = CONFLAGRATE_CD;
            GiveManaBack();
            return;
        }

        if(CHAOS_BOLT && isTimerReady(chaos_bolt_cd))
        {
            doCast(opponent, CHAOS_BOLT);
            GiveManaBack();
            chaos_bolt_cd = CHAOS_BOLT_CD;
            return;
        } else
            doCast(opponent, SHADOW_BOLT);
        GiveManaBack();
    } //DoNormalAttack
示例#17
0
        void DoNormalAttack(uint32 const diff)
        {
            AttackerSet m_attackers = master->getAttackers();
            if (!opponent || opponent->isDead()) return;

            // try to get rid of enrage effect
            if (TRANQ_SHOT && (HasAuraName(opponent, "Enrage") || (HasAuraName(opponent, "Frenzy")))) 
            {
                me->InterruptNonMeleeSpells(true, AUTO_SHOT);
                me->MonsterSay("Tranquil shot!", LANG_UNIVERSAL, opponent->GetGUID());
                doCast(opponent, TRANQ_SHOT, true);
              //  doCast(opponent, AUTO_SHOT);
              //  return;
            }

            // silence it
            if (SILENCING_SHOT && opponent->HasUnitState(UNIT_STATE_CASTING) && SilencingShot_Timer <= diff)
            {
                doCast(opponent, SILENCING_SHOT);
                SilencingShot_Timer = 25000;
              //  doCast(opponent, AUTO_SHOT);
              //  return;
            }

            // mark it
            if (!HasAuraName(opponent, "Hunter's Mark"))
            {
                doCast(opponent, HUNTERS_MARK);
              //  doCast(opponent, AUTO_SHOT);
              //  return;
            }

            // sting it
            if (SCORPID_STING && !opponent->HasAura(SCORPID_STING, me->GetGUID())) 
            {
                me->InterruptNonMeleeSpells(true, AUTO_SHOT);
                doCast(opponent, SCORPID_STING);
               // me->MonsterSay("Scorpid Sting!", LANG_UNIVERSAL, NULL);
               // doCast(opponent, AUTO_SHOT);
               // return;
            }

             if (CHIMERA_SHOT && ChimeraShot_Timer <= diff && GC_Timer <= diff)
             {
                me->InterruptNonMeleeSpells(true, AUTO_SHOT);
                doCast(opponent, CHIMERA_SHOT);
                ChimeraShot_Timer = 10000;
               // me->MonsterSay("Chimera Sting!", LANG_UNIVERSAL, NULL);
              //  doCast(opponent, AUTO_SHOT);
              //  return;
            }

            if (ARCANE_SHOT && ArcaneShot_cd <= diff && GC_Timer <= diff)
            {
                me->InterruptNonMeleeSpells(true, AUTO_SHOT);
                doCast(opponent, ARCANE_SHOT);
               // me->MonsterSay("Arcane shot!", LANG_UNIVERSAL, NULL);
                ArcaneShot_cd = 60;
              //  doCast(opponent, AUTO_SHOT);
              //  return;
            }

            if (AIMED_SHOT && AimedShot_Timer <= diff && GC_Timer <= diff)
            {
                me->InterruptNonMeleeSpells( true, AUTO_SHOT );
                doCast(opponent, AIMED_SHOT);
               // me->MonsterSay("Aimed shot!", LANG_UNIVERSAL, NULL);
                AimedShot_Timer = 120;
              //  doCast(opponent, AUTO_SHOT);
              //  return;
            }
            //Temp Feign death For Debug
            AttackerSet b_attackers = me->getAttackers();
            if (!b_attackers.empty())
            {
            for(AttackerSet::iterator iter = b_attackers.begin(); iter != b_attackers.end(); ++iter)
                if (*iter && (*iter)->getVictim()->GetGUID() == me->GetGUID() && 
                    me->GetDistance(*iter) < 10 && 
                    Feign_Death_Timer <= diff && GC_Timer <= diff)
                {
                    doCast(me, FEIGN_DEATH, true);
                    opponent->AddThreat(me, -100000);
                    me->CombatStop();
                    Feign_Death_Timer = 25000;
                    me->CombatStart(opponent);
                }
            }

            doCast(opponent, AUTO_SHOT);
        }
bool PlayerbotPaladinAI::BuffPlayer(Unit *target)
{
    if(!target || target->isDead()) return false;
    Player *m_bot = GetPlayerBot();

    // Check if target already has a blessing by me..
    if (HasAuraName(target,BOW,m_bot->GetGUID()) ||
    HasAuraName(target,BOK,m_bot->GetGUID()) ||
    HasAuraName(target,BOM,m_bot->GetGUID()) ||
    HasAuraName(target,BOS,m_bot->GetGUID()) ||
    HasAuraName(target,GBOW,m_bot->GetGUID()) ||
    HasAuraName(target,GBOK,m_bot->GetGUID()) ||
    HasAuraName(target,GBOM,m_bot->GetGUID()) ||
    HasAuraName(target,GBOS,m_bot->GetGUID())
    ) return false;

#pragma region Choose Buff > Class
    switch(target->getClass())
    {
        case CLASS_MAGE:
        case CLASS_WARLOCK:
            if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false);
            else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
            else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
            break;
        case CLASS_PRIEST:
            if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
            else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false);
            else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
            break;
        case CLASS_HUNTER:
            if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false);
            else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
            else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false);
            else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
            break;
        case CLASS_ROGUE:
            if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false);
            else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
            else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
            break;
        case CLASS_WARRIOR:
        case CLASS_DEATH_KNIGHT:
            if (target->GetUnitDodgeChance() + target->GetUnitParryChance() > 40)
            {
                if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
                else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
                else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false);
            }
            else
            {
                if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
                else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false);
                else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
            }
            break;
        case CLASS_DRUID:
        case CLASS_SHAMAN:
        case CLASS_PALADIN:
            if (target->GetMaxPower(target->getPowerType()) > target->GetMaxHealth())
            {
                if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false);
                else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
                else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
                else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false);
            }
            else if (target->GetUnitDodgeChance() + target->GetUnitParryChance() > 40)
            {
                if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
                else if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
                else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false);
                else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false);
            }
            else
            {
                if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
                else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false);
                else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false);
                else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
            }
            break;

        default:
                if (CanCast(GBOK,target) && !HasAuraName(target,BOK) && !HasAuraName(target,GBOK) ) return CastSpell(GBOK,target,false);
                else if (CanCast(GBOM,target) && !HasAuraName(target,BOM) && !HasAuraName(target,GBOM) ) return CastSpell(GBOM,target,false);
                else if (CanCast(GBOW,target) && !HasAuraName(target,BOW) && !HasAuraName(target,GBOW) ) return CastSpell(GBOW,target,false);
                else if (CanCast(GBOS,target) && !HasAuraName(target,BOS) && !HasAuraName(target,GBOS) ) return CastSpell(GBOS,target,false);
                break;
    }
#pragma endregion

    return false;
}
示例#19
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
示例#20
0
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent);
            }
            else
                return;

            //TODO: add more damage spells

            if (fear_cd <= diff && GC_Timer <= diff)
            { CheckFear(); fear_cd = 2000; }

            if (RAIN_OF_FIRE && Rain_of_fire_cd <= diff && GC_Timer <= diff && !me->isMoving() && Rand() < 25)
            {
                Unit* blizztarget = FindAOETarget(35, true);
                if (blizztarget && doCast(blizztarget, RAIN_OF_FIRE))
                {
                    Rain_of_fire_cd = 5000;
                    return;
                }
                Rain_of_fire_cd = 2000;//fail
            }

            float dist = me->GetExactDist(opponent);

            if (CURSE_OF_THE_ELEMENTS && GC_Timer <= diff && dist < 40 && Rand() < 15 &&
                !HasAuraName(opponent, CURSE_OF_THE_ELEMENTS) &&
                doCast(opponent, CURSE_OF_THE_ELEMENTS))
            {
                GC_Timer = 800;
                return;
            }

            if (CORRUPTION && GC_Timer <= diff && dist < 40 && Rand() < 25 &&
                !opponent->HasAura(CORRUPTION, me->GetGUID()) &&
                doCast(opponent, CORRUPTION))
                return;

            if (HAUNT && Haunt_cd <= diff && GC_Timer <= diff && dist < 40 && Rand() < 25 &&
                !opponent->HasAura(HAUNT, me->GetGUID()) &&
                doCast(opponent, HAUNT))
            {
                Haunt_cd = 8000;
                return;
            }

            if (GC_Timer <= diff && dist < 40 && Rand() < 15 && !Afflicted(opponent))
            {
                if (IMMOLATE && (!CONFLAGRATE || conflagarate_cd <= 8000) && doCast(opponent, IMMOLATE))
                    return;
                else if (UNSTABLE_AFFLICTION && doCast(opponent, UNSTABLE_AFFLICTION))
                    return;
            }

            if (CONFLAGRATE && conflagarate_cd <= diff && GC_Timer <= diff && dist < 40 && Rand() < 35 &&
                HasAuraName(opponent, IMMOLATE) &&
                doCast(opponent, CONFLAGRATE))
            {
                conflagarate_cd = 8000;
                return;
            }

            if (CHAOS_BOLT && chaos_bolt_cd <= diff && GC_Timer <= diff && dist < 40 && Rand() < 50 &&
                doCast(opponent, CHAOS_BOLT))
            {
                chaos_bolt_cd = me->getLevel() < 80 ? 10000 : 8000;
                return;
            }

            if (SHADOW_BOLT && GC_Timer <= diff && dist < 40 &&
                doCast(opponent, SHADOW_BOLT))
                return;
        }
		void DoNonCombatActions()
		{
			if (ASPECT_OF_THE_WILD && !HasAuraName(m_creature, "Aspect of the Wild")) {
				doCast(master, ASPECT_OF_THE_WILD);
			}
		}
		void DoNormalAttack(const uint32 diff)
		{
			AttackerSet m_attackers = master->getAttackers();
			if(opponent == NULL) return;
			if(opponent->isDead()) return;


			// try to get rid of enrage
			if (TRANQ_SHOT && HasAuraName(opponent, "Enrage")) {
				m_creature->InterruptNonMeleeSpells(true, AUTO_SHOT);
			   // m_creature->MonsterSay("Tranquility shot!", LANG_UNIVERSAL, NULL);
				doCast(opponent, TRANQ_SHOT);
				GiveManaBack();
			  //  doCast(opponent, AUTO_SHOT);
			  //  return;
			}

			// silence it
			if(SILENCING_SHOT && opponent->IsNonMeleeSpellCasted(true) && isTimerReady(SilencingShot_Timer))
			{
				doCast(opponent, SILENCING_SHOT);
				SilencingShot_Timer = 200;
				GiveManaBack();
			  //  doCast(opponent, AUTO_SHOT);
			  //  return;
			}

			// mark it
			if (!HasAuraName(opponent, "Hunter's Mark")) {
				doCast(opponent, HUNTERS_MARK);
				GiveManaBack();
			  //  doCast(opponent, AUTO_SHOT);
			  //  return;
			}

			// sting it
			if (SCORPID_STING && !opponent->HasAura(SCORPID_STING, m_creature->GetGUID())) {
				m_creature->InterruptNonMeleeSpells(true, AUTO_SHOT);
				doCast(opponent, SCORPID_STING);
			   // m_creature->MonsterSay("Scorpid Sting!", LANG_UNIVERSAL, NULL);
				GiveManaBack();
			   // doCast(opponent, AUTO_SHOT);
			   // return;
			}

			 if (CHIMERA_SHOT && isTimerReady(ChimeraShot_Timer)) {
				m_creature->InterruptNonMeleeSpells(true, AUTO_SHOT);
				doCast(opponent, CHIMERA_SHOT);
				ChimeraShot_Timer = 100;
			   // m_creature->MonsterSay("Chimera Sting!", LANG_UNIVERSAL, NULL);
				GiveManaBack();
			  //  doCast(opponent, AUTO_SHOT);
			  //  return;
			}

			if(ARCANE_SHOT && isTimerReady(ArcaneShot_cd))
			{
				m_creature->InterruptNonMeleeSpells( true, AUTO_SHOT );
				doCast(opponent, ARCANE_SHOT);
			   // m_creature->MonsterSay("Arcane shot!", LANG_UNIVERSAL, NULL);
				ArcaneShot_cd = 60;
				GiveManaBack();
			  //  doCast(opponent, AUTO_SHOT);
			  //  return;
			}

			if(AIMED_SHOT && isTimerReady(AimedShot_Timer))
			{
				m_creature->InterruptNonMeleeSpells( true, AUTO_SHOT );
				doCast(opponent, AIMED_SHOT);
			   // m_creature->MonsterSay("Arcane shot!", LANG_UNIVERSAL, NULL);
				AimedShot_Timer = 100;
				GiveManaBack();
			  //  doCast(opponent, AUTO_SHOT);
			  //  return;
			}


			doCast(opponent, AUTO_SHOT);

		}
示例#23
0
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent);
            }
            else
                return;

            //TODO: add more damage spells

            if (feartimer <= diff && GC_Timer <= diff)
            { CheckFear(); feartimer = 2000; }

            if (IsSpellReady(RAIN_OF_FIRE_1, diff) && !me->isMoving() && HasRole(BOT_ROLE_DPS) && Rand() < 25)
            {
                Unit* blizztarget = FindAOETarget(30, true);
                if (blizztarget && doCast(blizztarget, GetSpell(RAIN_OF_FIRE_1)))
                    return;
                SetSpellCooldown(RAIN_OF_FIRE_1, 2000);//fail
            }

            float dist = me->GetExactDist(opponent);

            if (IsSpellReady(CURSE_OF_THE_ELEMENTS_1, diff) && dist < 30 && Rand() < 15 &&
                !HasAuraName(opponent, CURSE_OF_THE_ELEMENTS_1) &&
                doCast(opponent, GetSpell(CURSE_OF_THE_ELEMENTS_1)))
            {
                GC_Timer = 800;
                return;
            }

            if (IsSpellReady(CORRUPTION_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 25 &&
                !opponent->HasAura(GetSpell(CORRUPTION_1), me->GetGUID()) &&
                doCast(opponent, GetSpell(CORRUPTION_1)))
                return;

            if (IsSpellReady(HAUNT_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 25 &&
                !opponent->HasAura(GetSpell(HAUNT_1), me->GetGUID()) &&
                doCast(opponent, GetSpell(HAUNT_1)))
                return;

            if (GC_Timer <= diff && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 15 && !Afflicted(opponent))
            {
                if (GetSpellCooldown(CONFLAGRATE_1) <= 8000 && doCast(opponent, GetSpell(IMMOLATE_1)))
                    return;
                else if (doCast(opponent, GetSpell(UNSTABLE_AFFLICTION_1)))
                    return;
            }

            if (IsSpellReady(CONFLAGRATE_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 35 &&
                HasAuraName(opponent, IMMOLATE_1) &&
                doCast(opponent, GetSpell(CONFLAGRATE_1)))
                return;

            if (IsSpellReady(CHAOS_BOLT_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 && Rand() < 50 &&
                doCast(opponent, GetSpell(CHAOS_BOLT_1)))
                return;

            if (IsSpellReady(SHADOW_BOLT_1, diff) && HasRole(BOT_ROLE_DPS) && dist < 30 &&
                doCast(opponent, GetSpell(SHADOW_BOLT_1)))
                return;
        }
示例#24
0
文件: bot_mage_ai.cpp 项目: ddark/ecl
        void DoNormalAttack(uint32 diff)
        {
            opponent = me->GetVictim();
            if (opponent)
            {
                if (!IsCasting())
                    StartAttack(opponent);
            }
            else
                return;
            AttackerSet m_attackers = master->getAttackers();
            AttackerSet b_attackers = me->getAttackers();

            Unit* u = me->SelectNearestTarget(20);
            //ICE_BARRIER
            if (ICE_BARRIER && Ice_Barrier_cd <= diff && u && u->GetVictim() == me && 
                u->GetDistance(me) < 8 && !me->HasAura(ICE_BARRIER))
            {
                if (me->IsNonMeleeSpellCasted(true))
                    me->InterruptNonMeleeSpells(true);
                if (doCast(me, ICE_BARRIER))
                {
                    Ice_Barrier_cd = 41000 - me->getLevel()*200;//down to 25 sec on 80
                    GC_Timer = 800;
                    return;
                }
            }
            if ((!ICE_BARRIER || Ice_Barrier_cd > diff) && 
                BLINK && Blink_cd < 3000 && u && u->GetVictim() == me && 
                !me->HasAura(ICE_BARRIER) && u->GetDistance(me) < 6)
            {
                if (me->IsNonMeleeSpellCasted(true))
                    me->InterruptNonMeleeSpells(true);
                if (doCast(me, BLINK))
                {
                    Blink_cd = 15000 - me->getLevel()/4 * 100;
                    GC_Timer = 800;
                    return;
                }
            }

            if (me->HasAura(ICEBLOCK))
                if (((GetManaPCT(me) > 45 && GetHealthPCT(me) > 80) || b_attackers.empty()) && Iceblock_cd <= 57000 && tank)
                    me->RemoveAurasDueToSpell(ICEBLOCK);
            //ICEBLOCK
            if (ICEBLOCK && Rand() < 50 && !b_attackers.empty() && tank && Iceblock_cd <= diff && 
                (GetManaPCT(me) < 15 || GetHealthPCT(me) < 45 || b_attackers.size() > 4) && 
                !me->HasAura(ICEBLOCK))
            {
                if (me->IsNonMeleeSpellCasted(true))
                    me->InterruptNonMeleeSpells(true);
                if (doCast(me, ICEBLOCK))
                {
                    Iceblock_cd = 60000;
                    return;
                }
            }

            if (IsCasting()) return;

            BOLT = (CCed(opponent, true) || (opponent->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED) && me->HasAura(COMBUSTION))) ? FIREBALL : FROSTBOLT;
            NOVA = BOLT == FIREBALL && BLASTWAVE ? BLASTWAVE : FROSTNOVA ? FROSTNOVA : 0;

            float dist = me->GetExactDist(opponent);
            if (dist > 30)
                return;

            if (COMBUSTION && Rand() < 15 && 
                (opponent->GetMaxHealth() > master->GetMaxHealth()*10 || 
                m_attackers.size() > 1 || b_attackers.size() > 2))
            {
                if (!HasAuraName(me, "Combustion") && Combustion_cd <= diff)
                {
                    temptimer = GC_Timer;
                    if (doCast(me, COMBUSTION))
                    {
                        Combustion_cd = 60000;
                        //Reset timers for fun
                        Nova_cd = 0; FireBlast_cd = 0; DragonBreath_cd = 0;
                    }
                    GC_Timer = temptimer;
                }
            }
            //DAMAGE
            //PYROBLAST
            if (PYROBLAST && Rand() < 75 && Pyroblast_cd <= diff && GC_Timer <= diff && 
                b_attackers.size() < 2 && dist < 30 && opponent->IsPolymorphed() && 
                doCast(opponent, PYROBLAST))
                Pyroblast_cd = 50;
            //nova //TODO: SEPARATE
            u = me->SelectNearestTarget(7);
            if (u && NOVA && Nova_cd <= diff && !CCed(u, true) && IsInBotParty(u->GetVictim()))
            {
                Unit* tar = u->GetVictim();
                if (tar && IsInBotParty(tar) && doCast(me, NOVA))
                {
                    Nova_cd = 15000;
                    return;
                }
            }
            //living bomb
            if (LIVINGBOMB && Rand() < 25 && Living_Bomb_cd <= diff && GC_Timer <= diff && 
                dist < 30 && opponent->GetHealth() > me->GetHealth()/2 && 
                !opponent->HasAura(LIVINGBOMB, me->GetGUID()) && 
                doCast(opponent, LIVINGBOMB))
            {
                Living_Bomb_cd = 6000;
                GC_Timer = 500;
                return;
            }
            //cone of cold
            if (CONEOFCOLD && ConeofCold_cd <= diff && GC_Timer <= diff && dist < 7 && 
                me->HasInArc(M_PI, opponent) && 
                doCast(opponent, CONEOFCOLD))
            {
                ConeofCold_cd = 14000;
                GC_Timer = 500;
                return;
            }
            //dragon's breath
            u = me->SelectNearestTarget(7);
            if (DRAGONBREATH && u && DragonBreath_cd <= diff && GC_Timer <= diff && 
                me->HasInArc(M_PI, opponent) && !HasAuraName(u, FROSTNOVA) && 
                doCast(opponent, DRAGONBREATH))
            {
                DragonBreath_cd = 25000;
                GC_Timer = 800;
                return;
            }
            /*//blast wave //TODO Separate again
            u = me->SelectNearestTarget(8);
            if (BLASTWAVE != 0 && u && isTimerReady(BlastWave_cd) && 
                !HasAuraName(u, FROSTNOVA) && !HasAuraName(u, DRAGONBREATH) && 
                doCast(me, BLASTWAVE))
            {
                BlastWave_cd = BLASTWAVE_CD;
                GC_Timer = 800;
            }*/
            //fire blast
            if (FireBlast_cd <= diff && GC_Timer <= diff && dist < 20 && 
                Rand() < 20 + 80*(!opponent->HasAuraType(SPELL_AURA_MOD_STUN) && me->HasAura(IMPACT_BUFF)) && 
                doCast(opponent, FIREBLAST))
            {
                FireBlast_cd = 6000;
                GC_Timer = 500;
                return;
            }
            //flamestrike
            if (GC_Timer <= diff && Rand() < 60 && me->HasAura(FIRESTARTERBUFF))
            {
                Unit* FStarget = FindAOETarget(30, true, false);
                if (FStarget && doCast(FStarget, FLAMESTRIKE, true))
                {
                    me->RemoveAurasDueToSpell(FIRESTARTERBUFF);
                    GC_Timer = 0;
                    return;
                }
            }
            //blizzard
            if (BLIZZARD && Rand() < 80 && Blizzard_cd <= diff)
            {
                Unit* blizztarget = FindAOETarget(30, true);
                if (blizztarget && doCast(blizztarget, BLIZZARD))
                {
                    Blizzard_cd = 5000;
                    return;
                }
                Blizzard_cd = 2000;//fail
            }
            //Frost of Fire Bolt
            if (Rand() < 75 && Bolt_cd <= diff && dist < 30 && 
                doCast(opponent, BOLT))
            {
                Bolt_cd = uint32(float(sSpellMgr->GetSpellInfo(BOLT)->CalcCastTime()/100) * me->GetFloatValue(UNIT_MOD_CAST_SPEED) + 200);
                return;
            }
            //Arcane Missiles
            if (Rand() < 10 && GC_Timer <= diff && !me->isMoving() && dist < 20 && 
                doCast(opponent, ARCANEMISSILES))
                return;
        }
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