void PlayerbotDruidAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; if (!m_bot->isAlive() || m_bot->IsInDuel()) return; // Revive if (HealPlayer(GetResurrectionTarget()) & RETURN_CONTINUE) return; // Heal if (m_ai->IsHealer()) { if (HealPlayer(GetHealTarget()) & RETURN_CONTINUE) return;// RETURN_CONTINUE; } else { // Is this desirable? Debatable. // TODO: In a group/raid with a healer you'd want this bot to focus on DPS (it's not specced/geared for healing either) if (HealPlayer(m_bot) & RETURN_CONTINUE) return;// RETURN_CONTINUE; } // Buff group // the check for group targets is performed by NeedGroupBuff (if group is found for bots by the function) if (NeedGroupBuff(GIFT_OF_THE_WILD, MARK_OF_THE_WILD) && m_ai->HasSpellReagents(GIFT_OF_THE_WILD)) { if (Buff(&PlayerbotDruidAI::BuffHelper, GIFT_OF_THE_WILD) & RETURN_CONTINUE) return; } else if (Buff(&PlayerbotDruidAI::BuffHelper, MARK_OF_THE_WILD) & RETURN_CONTINUE) return; if (Buff(&PlayerbotDruidAI::BuffHelper, THORNS, (m_bot->GetGroup() ? JOB_TANK : JOB_ALL)) & RETURN_CONTINUE) return; if (OMEN_OF_CLARITY && !m_bot->HasAura(OMEN_OF_CLARITY) && CastSpell(OMEN_OF_CLARITY, m_bot)) return; // hp/mana check if (EatDrinkBandage()) return; if (INNERVATE && m_ai->In_Reach(m_bot, INNERVATE) && !m_bot->HasAura(INNERVATE) && m_ai->GetManaPercent() <= 20 && CastSpell(INNERVATE, m_bot)) return; // Return to fighting form AFTER reviving, healing, buffing CheckForms(); // Nothing else to do, Night Elves will cast Shadowmeld to reduce their aggro versus patrols or nearby mobs if (SHADOWMELD && !m_bot->HasAura(SHADOWMELD, EFFECT_INDEX_0) && m_ai->CastSpell(SHADOWMELD, *m_bot)) return; } // end DoNonCombatActions
void PlayerbotDruidAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; if (!m_bot->isAlive() || m_bot->IsInDuel()) return; // Revive if (HealPlayer(GetResurrectionTarget()) & RETURN_CONTINUE) return; // Heal if (m_ai->IsHealer()) { if (HealPlayer(GetHealTarget()) & RETURN_CONTINUE) return;// RETURN_CONTINUE; } else { // Is this desirable? Debatable. // TODO: In a group/raid with a healer you'd want this bot to focus on DPS (it's not specced/geared for healing either) if (HealPlayer(m_bot) & RETURN_CONTINUE) return;// RETURN_CONTINUE; } // Buff if (m_bot->GetGroup() && m_ai->HasSpellReagents(GIFT_OF_THE_WILD) && Buff(&PlayerbotDruidAI::BuffHelper, GIFT_OF_THE_WILD) & RETURN_CONTINUE) return; if (Buff(&PlayerbotDruidAI::BuffHelper, MARK_OF_THE_WILD) & RETURN_CONTINUE) return; if (Buff(&PlayerbotDruidAI::BuffHelper, THORNS, (m_bot->GetGroup() ? JOB_TANK : JOB_ALL)) & RETURN_CONTINUE) return; // Return to fighting form AFTER reviving, healing, buffing CheckForms(); // hp/mana check if (EatDrinkBandage()) return; if (INNERVATE && m_ai->In_Reach(m_bot,INNERVATE) && !m_bot->HasAura(INNERVATE) && m_ai->GetManaPercent() <= 20 && CastSpell(INNERVATE, m_bot)) return; } // end DoNonCombatActions
CombatManeuverReturns PlayerbotDruidAI::DoNextCombatManeuverPVE(Unit* pTarget) { if (!m_ai) return RETURN_NO_ACTION_ERROR; if (!m_bot) return RETURN_NO_ACTION_ERROR; //uint32 masterHP = GetMaster()->GetHealth() * 100 / GetMaster()->GetMaxHealth(); uint32 spec = m_bot->GetSpec(); if (spec == 0) // default to spellcasting or healing for healer spec = (PlayerbotAI::ORDERS_HEAL & m_ai->GetCombatOrder() ? DRUID_SPEC_RESTORATION : DRUID_SPEC_BALANCE); // Make sure healer stays put, don't even melee (aggro) if in range. if (m_ai->IsHealer() && m_ai->GetCombatStyle() != PlayerbotAI::COMBAT_RANGED) m_ai->SetCombatStyle(PlayerbotAI::COMBAT_RANGED); else if (!m_ai->IsHealer() && m_ai->GetCombatStyle() != PlayerbotAI::COMBAT_MELEE) m_ai->SetCombatStyle(PlayerbotAI::COMBAT_MELEE); //Unit* pVictim = pTarget->getVictim(); uint32 BEAR = (DIRE_BEAR_FORM > 0 ? DIRE_BEAR_FORM : BEAR_FORM); // TODO: do something to allow emergency heals for non-healers? switch (CheckForms()) { case RETURN_OK_SHIFTING: return RETURN_CONTINUE; case RETURN_FAIL: case RETURN_OK_CANNOTSHIFT: if (spec == DRUID_SPEC_FERAL) spec = DRUID_SPEC_BALANCE; // Can't shift, force spellcasting break; // rest functions without form //case RETURN_OK_NOCHANGE: // great! //case RETURN_FAIL_WAITINGONSELFBUFF: // This is war dammit! No time for silly buffs during combat... default: break; } //Used to determine if this bot is highest on threat Unit *newTarget = m_ai->FindAttacker((PlayerbotAI::ATTACKERINFOTYPE) (PlayerbotAI::AIT_VICTIMSELF | PlayerbotAI::AIT_HIGHESTTHREAT), m_bot); if (newTarget) // TODO: && party has a tank { if (HealPlayer(m_bot) == RETURN_CONTINUE) return RETURN_CONTINUE; // TODO: Heal tank // We have aggro, don't need to heal self or tank, wait for aggro to subside //if (m_ai->IsHealer()) // Commented out: not necessary because of below. Leave code here in case below ever changes. // return RETURN_NO_ACTION_OK; // We have no shoot spell; Assume auto-attack is on return RETURN_NO_ACTION_OK; } if (m_ai->IsHealer()) return _DoNextPVECombatManeuverHeal(); switch (spec) { case DRUID_SPEC_FERAL: if (BEAR > 0 && m_bot->HasAura(BEAR)) return _DoNextPVECombatManeuverBear(pTarget); if (CAT_FORM > 0 && m_bot->HasAura(CAT_FORM)) return _DoNextPVECombatManeuverCat(pTarget); // NO break - failover to DRUID_SPEC_BALANCE case DRUID_SPEC_RESTORATION: // There is no Resto DAMAGE rotation. If you insist, go Balance... case DRUID_SPEC_BALANCE: if (m_bot->HasAura(BEAR) || m_bot->HasAura(CAT_FORM) || m_bot->HasAura(TREE_OF_LIFE)) return RETURN_NO_ACTION_UNKNOWN; // Didn't shift out of inappropriate form return _DoNextPVECombatManeuverSpellDPS(pTarget); /*if (BASH > 0 && !pTarget->HasAura(BASH, EFFECT_INDEX_0) && DruidSpellCombat < 5 && CastSpell(BASH, pTarget)) return RETURN_CONTINUE; if (CHALLENGING_ROAR > 0 && pVictim != m_bot && !pTarget->HasAura(CHALLENGING_ROAR, EFFECT_INDEX_0) && !pTarget->HasAura(GROWL, EFFECT_INDEX_0) && CastSpell(CHALLENGING_ROAR, pTarget)) return RETURN_CONTINUE; if (ROOTS > 0 && !pTarget->HasAura(ROOTS, EFFECT_INDEX_0) && CastSpell(ROOTS, pTarget)) return RETURN_CONTINUE; if (HURRICANE > 0 && ai->In_Reach(target,HURRICANE) && m_ai->GetAttackerCount() >= 5 && CastSpell(HURRICANE, pTarget)) { m_ai->SetIgnoreUpdateTime(10); return RETURN_CONTINUE; } if (STARFALL > 0 && ai->In_Reach(target,STARFALL) && !m_bot->HasAura(STARFALL, EFFECT_INDEX_0) && m_ai->GetAttackerCount() >= 3 && CastSpell(STARFALL, pTarget)) return RETURN_CONTINUE; if (BARKSKIN > 0 && pVictim == m_bot && m_ai->GetHealthPercent() < 75 && !m_bot->HasAura(BARKSKIN, EFFECT_INDEX_0) && CastSpell(BARKSKIN, m_bot)) return RETURN_CONTINUE; if (INNERVATE > 0 && ai->In_Reach(m_bot,INNERVATE) && !m_bot->HasAura(INNERVATE, EFFECT_INDEX_0) && CastSpell(INNERVATE, m_bot)) return RETURN_CONTINUE; */ } return RETURN_NO_ACTION_UNKNOWN; } // end DoNextCombatManeuver
CombatManeuverReturns PlayerbotDruidAI::DoNextCombatManeuverPVE(Unit* pTarget) { if (!m_ai) return RETURN_NO_ACTION_ERROR; if (!m_bot) return RETURN_NO_ACTION_ERROR; bool meleeReach = m_bot->CanReachWithMeleeAttack(pTarget); //uint32 masterHP = GetMaster()->GetHealth() * 100 / GetMaster()->GetMaxHealth(); uint32 spec = m_bot->GetSpec(); if (spec == 0) // default to spellcasting or healing for healer spec = (PlayerbotAI::ORDERS_HEAL & m_ai->GetCombatOrder() ? DRUID_SPEC_RESTORATION : DRUID_SPEC_BALANCE); // Make sure healer stays put, don't even melee (aggro) if in range: only melee if feral spec AND not healer if (!m_ai->IsHealer() && spec == DRUID_SPEC_FERAL && m_ai->GetCombatStyle() != PlayerbotAI::COMBAT_MELEE) m_ai->SetCombatStyle(PlayerbotAI::COMBAT_MELEE); else // ranged combat in all other cases m_ai->SetCombatStyle(PlayerbotAI::COMBAT_RANGED); //Unit* pVictim = pTarget->getVictim(); uint32 BEAR = (DIRE_BEAR_FORM > 0 ? DIRE_BEAR_FORM : BEAR_FORM); // TODO: do something to allow emergency heals for non-healers? switch (CheckForms()) { case RETURN_OK_SHIFTING: return RETURN_CONTINUE; case RETURN_FAIL: case RETURN_OK_CANNOTSHIFT: if (spec == DRUID_SPEC_FERAL) spec = DRUID_SPEC_BALANCE; // Can't shift, force spellcasting break; // rest functions without form //case RETURN_OK_NOCHANGE: // great! //case RETURN_FAIL_WAITINGONSELFBUFF: // This is war dammit! No time for silly buffs during combat... default: break; } // Low mana and bot is a caster/healer: cast Innervate on self // TODO add group check to also cast on low mana healers or master if (m_ai->GetManaPercent() < 15 && ((m_ai->IsHealer() || spec == DRUID_SPEC_RESTORATION))) if (INNERVATE > 0 && !m_bot->HasAura(INNERVATE, EFFECT_INDEX_0) && CastSpell(INNERVATE, m_bot)) return RETURN_CONTINUE; //Used to determine if this bot is highest on threat Unit* newTarget = m_ai->FindAttacker((PlayerbotAI::ATTACKERINFOTYPE)(PlayerbotAI::AIT_VICTIMSELF | PlayerbotAI::AIT_HIGHESTTHREAT), m_bot); if (newTarget && !(m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TANK) && !m_ai->IsNeutralized(newTarget)) // TODO: && party has a tank { if (HealPlayer(m_bot) == RETURN_CONTINUE) return RETURN_CONTINUE; // Aggroed by an elite that came in melee range if (m_ai->IsElite(newTarget) && meleeReach) { // protect the bot with barkskin: the increased casting time is meaningless // because bot will then avoid to cast to not angry mob further if (m_ai->IsHealer() || spec == DRUID_SPEC_RESTORATION || spec == DRUID_SPEC_BALANCE) { if (BARKSKIN > 0 && !m_bot->HasAura(BARKSKIN, EFFECT_INDEX_0) && CastSpell(BARKSKIN, m_bot)) return RETURN_CONTINUE; return RETURN_NO_ACTION_OK; } //no other cases: cats have cower in the damage rotation and bears can tank } } if (m_ai->IsHealer()) if (_DoNextPVECombatManeuverHeal() & RETURN_CONTINUE) return RETURN_CONTINUE; switch (spec) { case DRUID_SPEC_FERAL: if (BEAR > 0 && m_bot->HasAura(BEAR)) return _DoNextPVECombatManeuverBear(pTarget); if (CAT_FORM > 0 && m_bot->HasAura(CAT_FORM)) return _DoNextPVECombatManeuverCat(pTarget); // NO break - failover to DRUID_SPEC_BALANCE case DRUID_SPEC_RESTORATION: // There is no Resto DAMAGE rotation. If you insist, go Balance... case DRUID_SPEC_BALANCE: if (m_bot->HasAura(BEAR) || m_bot->HasAura(CAT_FORM)) return RETURN_NO_ACTION_UNKNOWN; // Didn't shift out of inappropriate form return _DoNextPVECombatManeuverSpellDPS(pTarget); /*if (BASH > 0 && !pTarget->HasAura(BASH, EFFECT_INDEX_0) && DruidSpellCombat < 5 && CastSpell(BASH, pTarget)) return RETURN_CONTINUE; if (CHALLENGING_ROAR > 0 && pVictim != m_bot && !pTarget->HasAura(CHALLENGING_ROAR, EFFECT_INDEX_0) && !pTarget->HasAura(GROWL, EFFECT_INDEX_0) && CastSpell(CHALLENGING_ROAR, pTarget)) return RETURN_CONTINUE; if (ROOTS > 0 && !pTarget->HasAura(ROOTS, EFFECT_INDEX_0) && CastSpell(ROOTS, pTarget)) return RETURN_CONTINUE; */ } return RETURN_NO_ACTION_UNKNOWN; } // end DoNextCombatManeuver