void PlayerbotPaladinAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; if (!m_bot->isAlive() || m_bot->IsInDuel()) return; CheckAuras(); //Put up RF if tank if (m_ai->IsTank()) m_ai->SelfBuff(RIGHTEOUS_FURY); //Disable RF if not tank else if (m_bot->HasAura(RIGHTEOUS_FURY)) m_bot->RemoveAurasDueToSpell(RIGHTEOUS_FURY); // Dispel magic/disease/poison if (m_ai->HasDispelOrder() && DispelPlayer() & RETURN_CONTINUE) return; // Revive if (ResurrectPlayer(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 if (Buff(&PlayerbotPaladinAI::BuffHelper, 1) & RETURN_CONTINUE) // Paladin's BuffHelper takes care of choosing the specific Blessing so just pass along a non-zero value return; // hp/mana check if (EatDrinkBandage()) return; // Search and apply stones to weapons // Mainhand ... Item* stone, * weapon; weapon = m_bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); if (weapon && weapon->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) == 0) { stone = m_ai->FindStoneFor(weapon); if (stone) { m_ai->UseItem(stone, EQUIPMENT_SLOT_MAINHAND); m_ai->SetIgnoreUpdateTime(5); } } }
void PlayerbotShamanAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; if (!m_bot->isAlive() || m_bot->IsInDuel()) return; uint32 spec = m_bot->GetSpec(); CheckShields(); /* // buff myself weapon if (ROCKBITER_WEAPON > 0) (!m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(WINDFURY_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && m_ai->CastSpell(ROCKBITER_WEAPON,*m_bot) ); else if (EARTHLIVING_WEAPON > 0) (!m_bot->HasAura(EARTHLIVING_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && m_ai->CastSpell(WINDFURY_WEAPON,*m_bot) ); else if (WINDFURY_WEAPON > 0) (!m_bot->HasAura(WINDFURY_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && m_ai->CastSpell(WINDFURY_WEAPON,*m_bot) ); else if (FLAMETONGUE_WEAPON > 0) (!m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(WINDFURY_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && m_ai->CastSpell(FLAMETONGUE_WEAPON,*m_bot) ); else if (FROSTBRAND_WEAPON > 0) (!m_bot->HasAura(FROSTBRAND_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(WINDFURY_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(FLAMETONGUE_WEAPON, EFFECT_INDEX_0) && !m_bot->HasAura(ROCKBITER_WEAPON, EFFECT_INDEX_0) && m_ai->CastSpell(FROSTBRAND_WEAPON,*m_bot) ); */ // Mainhand Item* weapon; weapon = m_bot->GetItemByPos(EQUIPMENT_SLOT_MAINHAND); if (weapon && (weapon->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) == 0) && spec == SHAMAN_SPEC_ELEMENTAL) m_ai->CastSpell(FLAMETONGUE_WEAPON, *m_bot); else if (weapon && (weapon->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) == 0) && spec == SHAMAN_SPEC_ENHANCEMENT) m_ai->CastSpell(WINDFURY_WEAPON, *m_bot); //Offhand weapon = m_bot->GetItemByPos(EQUIPMENT_SLOT_OFFHAND); if (weapon && (weapon->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) == 0) && spec == SHAMAN_SPEC_ENHANCEMENT) m_ai->CastSpell(FLAMETONGUE_WEAPON, *m_bot); // 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; } // hp/mana check if (EatDrinkBandage()) 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 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 PlayerbotPaladinAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; if (!m_bot->isAlive() || m_bot->IsInDuel()) return; CheckAuras(); //Put up RF if tank if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TANK) m_ai->SelfBuff(RIGHTEOUS_FURY); //Disable RF if not tank else if (m_bot->HasAura(RIGHTEOUS_FURY)) m_bot->RemoveAurasDueToSpell(RIGHTEOUS_FURY); // 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 if (Buff(&PlayerbotPaladinAI::BuffHelper, 1) & RETURN_CONTINUE) // Paladin's BuffHelper takes care of choosing the specific Blessing so just pass along a non-zero value return; //creat water if (m_ai->FindDrink() == nullptr && m_bot->getLevel() == 60) { if (Item* pItem = m_bot->StoreNewItemInInventorySlot(CRYSTAL_WATER, 20)) m_bot->SendNewItem(pItem, 20, true, false); return; } // hp/mana check if (EatDrinkBandage()) return; // m_ai->TellMaster("DoNonCombatActions() - 10. past EatDrinkBandage()"); // debug }
int Pickup_Health (gentity_t *ent, gentity_t *other) { qboolean goOverMax; int quantity; // small and mega healths will go over the max if (ent->item->quantity == 5 || ent->item->quantity == 100 ) goOverMax = qtrue; else goOverMax = qfalse; if ( ent->count ) quantity = ent->count; else quantity = ent->item->quantity; HealPlayer(other,quantity, goOverMax); other->client->ps.stats[STAT_HEALTH] = other->health; if ( ent->item->quantity == 100 ) { // mega health respawns slow return RESPAWN_MEGAHEALTH; } return RESPAWN_HEALTH; }
void PlayerbotPaladinAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; if (!m_bot->isAlive() || m_bot->IsInDuel()) return; CheckAuras(); CheckSeals(); //Put up RF if tank if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TANK) m_ai->SelfBuff(RIGHTEOUS_FURY); //Disable RF if not tank else if (m_bot->HasAura(RIGHTEOUS_FURY)) m_bot->RemoveAurasDueToSpell(RIGHTEOUS_FURY); // 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 if (Buff(&PlayerbotPaladinAI::BuffHelper, 1) & RETURN_CONTINUE) // Paladin's BuffHelper takes care of choosing the specific Blessing so just pass along a non-zero value return; // hp/mana check if (m_bot->getStandState() != UNIT_STAND_STATE_STAND) m_bot->SetStandState(UNIT_STAND_STATE_STAND); if (EatDrinkBandage()) return; // m_ai->TellMaster("DoNonCombatActions() - 10. past EatDrinkBandage()"); // debug }
CombatManeuverReturns PlayerbotDruidAI::_DoNextPVECombatManeuverHeal() { if (!m_ai) return RETURN_NO_ACTION_ERROR; if (!m_bot) return RETURN_NO_ACTION_ERROR; if (HealPlayer(GetHealTarget()) & (RETURN_NO_ACTION_OK | RETURN_CONTINUE)) return RETURN_CONTINUE; return RETURN_NO_ACTION_UNKNOWN; }
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 PlayerbotShamanAI::DoNextCombatManeuverPVP(Unit* pTarget) { DropTotems(); CheckShields(); UseCooldowns(); Player* healTarget = (m_ai->GetScenarioType() == PlayerbotAI::SCENARIO_PVP_DUEL) ? GetHealTarget() : m_bot; if (HealPlayer(healTarget) & (RETURN_NO_ACTION_OK | RETURN_CONTINUE)) return RETURN_CONTINUE; if (m_ai->CastSpell(LIGHTNING_BOLT)) return RETURN_CONTINUE; return DoNextCombatManeuverPVE(pTarget); // TODO: bad idea perhaps, but better than the alternative }
CombatManeuverReturns PlayerbotShamanAI::DoFirstCombatManeuver(Unit* pTarget) { // There are NPCs in BGs and Open World PvP, so don't filter this on PvP scenarios (of course if PvP targets anyone but tank, all bets are off anyway) // Wait until the tank says so, until any non-tank gains aggro or X seconds - whichever is shortest if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TEMP_WAIT_TANKAGGRO) { if (m_WaitUntil > m_ai->CurrentTime() && m_ai->GroupTankHoldsAggro()) { if (PlayerbotAI::ORDERS_HEAL & m_ai->GetCombatOrder()) return HealPlayer(GetHealTarget()); else return RETURN_NO_ACTION_OK; // wait it out } else { m_ai->ClearGroupCombatOrder(PlayerbotAI::ORDERS_TEMP_WAIT_TANKAGGRO); } } if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TEMP_WAIT_OOC) { if (m_WaitUntil > m_ai->CurrentTime() && !m_ai->IsGroupInCombat()) return RETURN_NO_ACTION_OK; // wait it out else m_ai->ClearGroupCombatOrder(PlayerbotAI::ORDERS_TEMP_WAIT_OOC); } switch (m_ai->GetScenarioType()) { case PlayerbotAI::SCENARIO_PVP_DUEL: case PlayerbotAI::SCENARIO_PVP_BG: case PlayerbotAI::SCENARIO_PVP_ARENA: case PlayerbotAI::SCENARIO_PVP_OPENWORLD: return DoFirstCombatManeuverPVP(pTarget); case PlayerbotAI::SCENARIO_PVE: case PlayerbotAI::SCENARIO_PVE_ELITE: case PlayerbotAI::SCENARIO_PVE_RAID: default: return DoFirstCombatManeuverPVE(pTarget); break; } return RETURN_NO_ACTION_ERROR; }
CombatManeuverReturns PlayerbotDruidAI::_DoNextPVECombatManeuverHeal() { if (!m_ai) return RETURN_NO_ACTION_ERROR; if (!m_bot) return RETURN_NO_ACTION_ERROR; // (un)Shapeshifting is considered one step closer so will return true (and have the bot wait a bit for the GCD) if (TREE_OF_LIFE > 0 && !m_bot->HasAura(TREE_OF_LIFE, EFFECT_INDEX_0)) if (CastSpell(TREE_OF_LIFE, m_bot)) return RETURN_CONTINUE; if (m_bot->HasAura(CAT_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(CAT_FORM_1); //m_ai->TellMaster("FormClearCat"); return RETURN_CONTINUE; } if (m_bot->HasAura(BEAR_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(BEAR_FORM_1); //m_ai->TellMaster("FormClearBear"); return RETURN_CONTINUE; } if (m_bot->HasAura(DIRE_BEAR_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(DIRE_BEAR_FORM_1); //m_ai->TellMaster("FormClearDireBear"); return RETURN_CONTINUE; } // spellcasting form, but disables healing spells so it's got to go if (m_bot->HasAura(MOONKIN_FORM, EFFECT_INDEX_0)) { m_bot->RemoveAurasDueToSpell(MOONKIN_FORM_1); //m_ai->TellMaster("FormClearMoonkin"); return RETURN_CONTINUE; } if (HealPlayer(GetHealTarget()) & (RETURN_NO_ACTION_OK | RETURN_CONTINUE)) return RETURN_CONTINUE; return RETURN_NO_ACTION_UNKNOWN; }
CombatManeuverReturns PlayerbotShamanAI::DoNextCombatManeuverPVE(Unit *pTarget) { if (!m_ai) return RETURN_NO_ACTION_ERROR; if (!m_bot) return RETURN_NO_ACTION_ERROR; uint32 spec = m_bot->GetSpec(); // 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); // Heal if (m_ai->IsHealer()) { if (HealPlayer(GetHealTarget()) & (RETURN_NO_ACTION_OK | 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; } // Damage Spells DropTotems(); CheckShields(); UseCooldowns(); switch (spec) { case SHAMAN_SPEC_ENHANCEMENT: if (STORMSTRIKE > 0 && (!m_bot->HasSpellCooldown(STORMSTRIKE)) && m_ai->CastSpell(STORMSTRIKE, *pTarget)) return RETURN_CONTINUE; if (FLAME_SHOCK > 0 && (!pTarget->HasAura(FLAME_SHOCK)) && m_ai->CastSpell(FLAME_SHOCK, *pTarget)) return RETURN_CONTINUE; if (EARTH_SHOCK > 0 && (!m_bot->HasSpellCooldown(EARTH_SHOCK)) && m_ai->CastSpell(EARTH_SHOCK, *pTarget)) return RETURN_CONTINUE; /*if (FOCUSED > 0 && m_ai->CastSpell(FOCUSED, *pTarget)) return RETURN_CONTINUE;*/ break; case SHAMAN_SPEC_RESTORATION: // fall through to elemental case SHAMAN_SPEC_ELEMENTAL: if (FLAME_SHOCK > 0 && (!pTarget->HasAura(FLAME_SHOCK)) && m_ai->CastSpell(FLAME_SHOCK, *pTarget)) return RETURN_CONTINUE; if (LIGHTNING_BOLT > 0 && m_ai->CastSpell(LIGHTNING_BOLT, *pTarget)) return RETURN_CONTINUE; /*if (PURGE > 0 && m_ai->CastSpell(PURGE, *pTarget)) return RETURN_CONTINUE;*/ /*if (FROST_SHOCK > 0 && !pTarget->HasAura(FROST_SHOCK, EFFECT_INDEX_0) && m_ai->CastSpell(FROST_SHOCK, *pTarget)) return RETURN_CONTINUE;*/ /*if (CHAIN_LIGHTNING > 0 && m_ai->CastSpell(CHAIN_LIGHTNING, *pTarget)) return RETURN_CONTINUE;*/ } return RETURN_NO_ACTION_OK; } // end DoNextCombatManeuver
void PlayerbotPriestAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; if (!m_bot->isAlive() || m_bot->IsInDuel()) return; uint32 spec = m_bot->GetSpec(); // selfbuff goes first if (m_ai->SelfBuff(INNER_FIRE)) return; // Revive if (HealPlayer(GetResurrectionTarget()) & RETURN_CONTINUE) return; // After revive if (spec == PRIEST_SPEC_SHADOW && SHADOWFORM > 0) m_ai->SelfBuff(SHADOWFORM); if (VAMPIRIC_EMBRACE > 0) m_ai->SelfBuff(VAMPIRIC_EMBRACE); // 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; } // Buffing // the check for group targets is performed by NeedGroupBuff (if group is found for bots by the function) if (NeedGroupBuff(PRAYER_OF_FORTITUDE, POWER_WORD_FORTITUDE) && m_ai->HasSpellReagents(PRAYER_OF_FORTITUDE)) { if (Buff(&PlayerbotPriestAI::BuffHelper, PRAYER_OF_FORTITUDE) & RETURN_CONTINUE) return; } else if (Buff(&PlayerbotPriestAI::BuffHelper, POWER_WORD_FORTITUDE) & RETURN_CONTINUE) return; if (NeedGroupBuff(PRAYER_OF_SPIRIT, DIVINE_SPIRIT) && m_ai->HasSpellReagents(PRAYER_OF_FORTITUDE)) { if (Buff(&PlayerbotPriestAI::BuffHelper, PRAYER_OF_SPIRIT) & RETURN_CONTINUE) return; } else if (Buff(&PlayerbotPriestAI::BuffHelper, DIVINE_SPIRIT, (JOB_ALL | JOB_MANAONLY)) & RETURN_CONTINUE) return; if (NeedGroupBuff(PRAYER_OF_SHADOW_PROTECTION, SHADOW_PROTECTION) && m_ai->HasSpellReagents(PRAYER_OF_FORTITUDE)) { if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_RESIST_SHADOW && Buff(&PlayerbotPriestAI::BuffHelper, PRAYER_OF_SHADOW_PROTECTION) & RETURN_CONTINUE) return; } else if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_RESIST_SHADOW && Buff(&PlayerbotPriestAI::BuffHelper, SHADOW_PROTECTION) & RETURN_CONTINUE) return; if (EatDrinkBandage()) return; // 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
CombatManeuverReturns PlayerbotPriestAI::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 spec = m_bot->GetSpec(); // Define a tank bot will look at Unit* pMainTank = GetHealTarget(JOB_TANK); if (m_ai->GetCombatStyle() != PlayerbotAI::COMBAT_RANGED && !meleeReach) m_ai->SetCombatStyle(PlayerbotAI::COMBAT_RANGED); // switch to melee if in melee range AND can't shoot OR have no ranged (wand) equipped AND is not healer else if(m_ai->GetCombatStyle() != PlayerbotAI::COMBAT_MELEE && meleeReach && (SHOOT == 0 || !m_bot->GetWeaponForAttack(RANGED_ATTACK, true, true)) && !m_ai->IsHealer()) m_ai->SetCombatStyle(PlayerbotAI::COMBAT_MELEE); // Priests will try to buff with Fear Ward if (FEAR_WARD > 0 && m_bot->IsSpellReady(FEAR_WARD)) { // Buff tank first if (pMainTank) { if (m_ai->In_Reach(pMainTank, FEAR_WARD) && !pMainTank->HasAura(FEAR_WARD, EFFECT_INDEX_0) && CastSpell(FEAR_WARD, pMainTank)) return RETURN_CONTINUE; } // Else try to buff master else if (GetMaster()) { if (m_ai->In_Reach(GetMaster(), FEAR_WARD) && !GetMaster()->HasAura(FEAR_WARD, EFFECT_INDEX_0) && CastSpell(FEAR_WARD, GetMaster())) 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->IsNeutralized(newTarget)) // TODO: && party has a tank { if (FADE > 0 && !m_bot->HasAura(FADE, EFFECT_INDEX_0) && m_bot->IsSpellReady(FADE)) { if (CastSpell(FADE, m_bot)) { m_ai->TellMaster("I'm casting fade."); return RETURN_CONTINUE; } else m_ai->TellMaster("I have AGGRO."); } // Heal myself // TODO: move to HealTarget code if (m_ai->GetHealthPercent() < 35 && POWER_WORD_SHIELD > 0 && !m_bot->HasAura(POWER_WORD_SHIELD, EFFECT_INDEX_0) && !m_bot->HasAura(WEAKNED_SOUL, EFFECT_INDEX_0)) { if (CastSpell(POWER_WORD_SHIELD) & RETURN_CONTINUE) { m_ai->TellMaster("I'm casting PW:S on myself."); return RETURN_CONTINUE; } else if (m_ai->IsHealer()) // Even if any other RETURN_ANY_OK - aside from RETURN_CONTINUE m_ai->TellMaster("Your healer's about TO DIE. HELP ME."); } if (m_ai->GetHealthPercent() < 35 && DESPERATE_PRAYER > 0 && m_ai->In_Reach(m_bot,DESPERATE_PRAYER) && CastSpell(DESPERATE_PRAYER, m_bot) & RETURN_CONTINUE) { m_ai->TellMaster("I'm casting desperate prayer."); return RETURN_CONTINUE; } // Night Elves priest bot can also cast Elune's Grace to improve his/her dodge rating if (ELUNES_GRACE && !m_bot->HasAura(ELUNES_GRACE, EFFECT_INDEX_0) && m_bot->IsSpellReady(ELUNES_GRACE) && CastSpell(ELUNES_GRACE, m_bot)) return RETURN_CONTINUE; // If enemy comes in melee reach if (meleeReach) { // Already healed self or tank. If healer, do nothing else to anger mob if (m_ai->IsHealer()) return RETURN_NO_ACTION_OK; // In a sense, mission accomplished. // Have threat, can't quickly lower it. 3 options remain: Stop attacking, lowlevel damage (wand), keep on keeping on. if (newTarget->GetHealthPercent() > 25) { // If elite, do nothing and pray tank gets aggro off you if (m_ai->IsElite(newTarget)) return RETURN_NO_ACTION_OK; // Not an elite. You could insert PSYCHIC SCREAM here but in any PvE situation that's 90-95% likely // to worsen the situation for the group. ... So please don't. return CastSpell(SHOOT, pTarget); } } } // Damage tweaking for healers if (m_ai->IsHealer()) { // Heal other players/bots first if (HealPlayer(GetHealTarget()) & RETURN_CONTINUE) return RETURN_CONTINUE; // No one needs to be healed: do small damage instead // If target is elite and not handled by MT: do nothing if (m_ai->IsElite(pTarget) && pMainTank && pMainTank->getVictim() != pTarget) return RETURN_NO_ACTION_OK; // Cast Shadow Word:Pain on current target and keep its up (if mana >= 40% or target HP < 15%) if (SHADOW_WORD_PAIN > 0 && m_ai->In_Reach(pTarget,SHADOW_WORD_PAIN) && !pTarget->HasAura(SHADOW_WORD_PAIN, EFFECT_INDEX_0) && (pTarget->GetHealthPercent() < 15 || m_ai->GetManaPercent() >= 40) && CastSpell(SHADOW_WORD_PAIN, pTarget)) return RETURN_CONTINUE; else // else shoot at it return CastSpell(SHOOT, pTarget); } // Damage Spells switch (spec) { case PRIEST_SPEC_HOLY: if (HOLY_FIRE > 0 && m_ai->In_Reach(pTarget,HOLY_FIRE) && !pTarget->HasAura(HOLY_FIRE, EFFECT_INDEX_0) && CastSpell(HOLY_FIRE, pTarget)) return RETURN_CONTINUE; if (SMITE > 0 && m_ai->In_Reach(pTarget,SMITE) && CastSpell(SMITE, pTarget)) return RETURN_CONTINUE; //if (HOLY_NOVA > 0 && m_ai->In_Reach(pTarget,HOLY_NOVA) && meleeReach && m_ai->CastSpell(HOLY_NOVA)) // return RETURN_CONTINUE; break; case PRIEST_SPEC_SHADOW: if (DEVOURING_PLAGUE > 0 && m_ai->In_Reach(pTarget,DEVOURING_PLAGUE) && !pTarget->HasAura(DEVOURING_PLAGUE, EFFECT_INDEX_0) && CastSpell(DEVOURING_PLAGUE, pTarget)) return RETURN_CONTINUE; if (VAMPIRIC_TOUCH > 0 && m_ai->In_Reach(pTarget,VAMPIRIC_TOUCH) && !pTarget->HasAura(VAMPIRIC_TOUCH, EFFECT_INDEX_0) && CastSpell(VAMPIRIC_TOUCH, pTarget)) return RETURN_CONTINUE; if (SHADOW_WORD_PAIN > 0 && m_ai->In_Reach(pTarget,SHADOW_WORD_PAIN) && !pTarget->HasAura(SHADOW_WORD_PAIN, EFFECT_INDEX_0) && CastSpell(SHADOW_WORD_PAIN, pTarget)) return RETURN_CONTINUE; if (MIND_BLAST > 0 && m_ai->In_Reach(pTarget,MIND_BLAST) && (m_bot->IsSpellReady(MIND_BLAST)) && CastSpell(MIND_BLAST, pTarget)) return RETURN_CONTINUE; if (MIND_FLAY > 0 && m_ai->In_Reach(pTarget,MIND_FLAY) && CastSpell(MIND_FLAY, pTarget)) { m_ai->SetIgnoreUpdateTime(3); return RETURN_CONTINUE; } if (SHADOWFIEND > 0 && m_ai->In_Reach(pTarget,SHADOWFIEND) && !m_bot->GetPet() && CastSpell(SHADOWFIEND)) return RETURN_CONTINUE; if (SHADOWFORM == 0 && MIND_FLAY == 0 && SMITE > 0 && m_ai->In_Reach(pTarget,SMITE) && CastSpell(SMITE, pTarget)) // low levels return RETURN_CONTINUE; break; case PRIEST_SPEC_DISCIPLINE: if (POWER_INFUSION > 0 && m_ai->In_Reach(GetMaster(),POWER_INFUSION) && CastSpell(POWER_INFUSION, GetMaster())) // TODO: just master? return RETURN_CONTINUE; if (INNER_FOCUS > 0 && m_ai->In_Reach(m_bot,INNER_FOCUS) && !m_bot->HasAura(INNER_FOCUS, EFFECT_INDEX_0) && CastSpell(INNER_FOCUS, m_bot)) return RETURN_CONTINUE; if (SMITE > 0 && m_ai->In_Reach(pTarget,SMITE) && CastSpell(SMITE, pTarget)) return RETURN_CONTINUE; break; } // No spec due to low level OR no spell found yet if (MIND_BLAST > 0 && m_ai->In_Reach(pTarget,MIND_BLAST) && (m_bot->IsSpellReady(MIND_BLAST)) && CastSpell(MIND_BLAST, pTarget)) return RETURN_CONTINUE; if (SHADOW_WORD_PAIN > 0 && m_ai->In_Reach(pTarget,SHADOW_WORD_PAIN) && !pTarget->HasAura(SHADOW_WORD_PAIN, EFFECT_INDEX_0) && CastSpell(SHADOW_WORD_PAIN, pTarget)) return RETURN_CONTINUE; if (MIND_FLAY > 0 && m_ai->In_Reach(pTarget,MIND_FLAY) && CastSpell(MIND_FLAY, pTarget)) { m_ai->SetIgnoreUpdateTime(3); return RETURN_CONTINUE; } if (SHADOWFORM == 0 && SMITE > 0 && m_ai->In_Reach(pTarget,SMITE) && CastSpell(SMITE, pTarget)) return RETURN_CONTINUE; // Default: shoot with wand return CastSpell(SHOOT, pTarget); return RETURN_NO_ACTION_OK; } // end DoNextCombatManeuver
CombatManeuverReturns PlayerbotPriestAI::DoNextCombatManeuverPVE(Unit *pTarget) { if (!m_ai) return RETURN_NO_ACTION_ERROR; if (!m_bot) return RETURN_NO_ACTION_ERROR; Unit* pVictim = pTarget->getVictim(); float dist = m_bot->GetCombatDistance(pTarget); uint32 spec = m_bot->GetSpec(); Group *m_group = m_bot->GetGroup(); if (m_ai->GetCombatStyle() != PlayerbotAI::COMBAT_RANGED && dist > ATTACK_DISTANCE) m_ai->SetCombatStyle(PlayerbotAI::COMBAT_RANGED); // if in melee range OR can't shoot OR have no ranged (wand) equipped else if(m_ai->GetCombatStyle() != PlayerbotAI::COMBAT_MELEE && (SHOOT == 0 || !m_bot->GetWeaponForAttack(RANGED_ATTACK, true, true)) && !m_ai->IsHealer()) m_ai->SetCombatStyle(PlayerbotAI::COMBAT_MELEE); //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 (newTarget && FADE > 0 && !m_bot->HasAura(FADE, EFFECT_INDEX_0)) { if (CastSpell(FADE, m_bot)) { //m_ai->TellMaster("I'm casting fade."); return RETURN_CONTINUE; } else m_ai->TellMaster("I have AGGRO."); } // Heal myself // TODO: move to HealTarget code // TODO: you forgot to check for the 'temporarily immune to PW:S because you only just got it cast on you' effect // - which is different effect from the actual shield. if (m_ai->GetHealthPercent() < 25 && POWER_WORD_SHIELD > 0 && !m_bot->HasAura(POWER_WORD_SHIELD, EFFECT_INDEX_0)) { if (CastSpell(POWER_WORD_SHIELD) & RETURN_CONTINUE) { //m_ai->TellMaster("I'm casting PW:S on myself."); return RETURN_CONTINUE; } else if (m_ai->IsHealer()) // Even if any other RETURN_ANY_OK - aside from RETURN_CONTINUE m_ai->TellMaster("Your healer's about TO DIE. HELP ME."); } if (m_ai->GetHealthPercent() < 35 && DESPERATE_PRAYER > 0 && CastSpell(DESPERATE_PRAYER, m_bot) & RETURN_CONTINUE) { //m_ai->TellMaster("I'm casting desperate prayer."); return RETURN_CONTINUE; } // Already healed self or tank. If healer, do nothing else to anger mob. if (m_ai->IsHealer()) return RETURN_NO_ACTION_OK; // In a sense, mission accomplished. // Have threat, can't quickly lower it. 3 options remain: Stop attacking, lowlevel damage (wand), keep on keeping on. if (newTarget->GetHealthPercent() > 25) { // If elite, do nothing and pray tank gets aggro off you // TODO: Is there an IsElite function? If so, find it and insert. //if (newTarget->IsElite()) // return; // Not an elite. You could insert PSYCHIC SCREAM here but in any PvE situation that's 90-95% likely // to worsen the situation for the group. ... So please don't. return CastSpell(SHOOT, pTarget); } } // Heal if (m_ai->IsHealer()) { if (HealPlayer(GetHealTarget()) & RETURN_CONTINUE) return RETURN_CONTINUE; } else { // Is this desirable? Debatable. // ... Certainly could be very detrimental to a shadow priest // 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; } // Do damage tweaking for healers here if (m_ai->IsHealer()) { // TODO: elite exception //if (Any target is an Elite) // return; return CastSpell(SHOOT, pTarget); } // Damage Spells switch (spec) { case PRIEST_SPEC_HOLY: if (HOLY_FIRE > 0 && !pTarget->HasAura(HOLY_FIRE, EFFECT_INDEX_0) && CastSpell(HOLY_FIRE, pTarget)) return RETURN_CONTINUE; if (SMITE > 0 && CastSpell(SMITE, pTarget)) return RETURN_CONTINUE; //if (HOLY_NOVA > 0 && dist <= ATTACK_DISTANCE && m_ai->CastSpell(HOLY_NOVA)) // return RETURN_CONTINUE; break; case PRIEST_SPEC_SHADOW: if (DEVOURING_PLAGUE > 0 && !pTarget->HasAura(DEVOURING_PLAGUE, EFFECT_INDEX_0) && CastSpell(DEVOURING_PLAGUE, pTarget)) return RETURN_CONTINUE; if (VAMPIRIC_TOUCH > 0 && !pTarget->HasAura(VAMPIRIC_TOUCH, EFFECT_INDEX_0) && CastSpell(VAMPIRIC_TOUCH, pTarget)) return RETURN_CONTINUE; if (SHADOW_WORD_PAIN > 0 && !pTarget->HasAura(SHADOW_WORD_PAIN, EFFECT_INDEX_0) && CastSpell(SHADOW_WORD_PAIN, pTarget)) return RETURN_CONTINUE; if (MIND_BLAST > 0 && (!m_bot->HasSpellCooldown(MIND_BLAST)) && CastSpell(MIND_BLAST, pTarget)) return RETURN_CONTINUE; if (MIND_FLAY > 0 && CastSpell(MIND_FLAY, pTarget)) { m_ai->SetIgnoreUpdateTime(3); return RETURN_CONTINUE; } if (SHADOWFIEND > 0 && !m_bot->GetPet() && CastSpell(SHADOWFIEND)) return RETURN_CONTINUE; /*if (MIND_SEAR > 0 && m_ai->GetAttackerCount() >= 3 && CastSpell(MIND_SEAR, pTarget)) { m_ai->SetIgnoreUpdateTime(5); return RETURN_CONTINUE; }*/ if (SHADOWFORM == 0 && MIND_FLAY == 0 && SMITE > 0 && CastSpell(SMITE, pTarget)) // low levels return RETURN_CONTINUE; break; case PRIEST_SPEC_DISCIPLINE: if (POWER_INFUSION > 0 && CastSpell(POWER_INFUSION, GetMaster())) // TODO: just master? return RETURN_CONTINUE; if (INNER_FOCUS > 0 && !m_bot->HasAura(INNER_FOCUS, EFFECT_INDEX_0) && CastSpell(INNER_FOCUS, m_bot)) return RETURN_CONTINUE; if (PENANCE > 0 && CastSpell(PENANCE)) return RETURN_CONTINUE; if (SMITE > 0 && CastSpell(SMITE, pTarget)) return RETURN_CONTINUE; break; } // No spec due to low level OR no spell found yet if (MIND_BLAST > 0 && (!m_bot->HasSpellCooldown(MIND_BLAST)) && CastSpell(MIND_BLAST, pTarget)) return RETURN_CONTINUE; if (SHADOW_WORD_PAIN > 0 && !pTarget->HasAura(SHADOW_WORD_PAIN, EFFECT_INDEX_0) && CastSpell(SHADOW_WORD_PAIN, pTarget)) return RETURN_CONTINUE; if (MIND_FLAY > 0 && CastSpell(MIND_FLAY, pTarget)) { m_ai->SetIgnoreUpdateTime(3); return RETURN_CONTINUE; } if (SHADOWFORM == 0 && SMITE > 0 && CastSpell(SMITE, pTarget)) return RETURN_CONTINUE; return RETURN_NO_ACTION_OK; } // 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
CombatManeuverReturns PlayerbotPaladinAI::DoNextCombatManeuverPVE(Unit* pTarget) { if (!m_ai) return RETURN_NO_ACTION_ERROR; if (!m_bot) return RETURN_NO_ACTION_ERROR; if (!pTarget) return RETURN_NO_ACTION_INVALIDTARGET; // damage spells uint32 spec = m_bot->GetSpec(); std::ostringstream out; // 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); // Emergency check: bot is about to die: use Divine Shield (first) // Use Divine Protection if Divine Shield is not available and bot is not tanking because of the pacify effect // TODO adjust treshold (may be too low) if (m_ai->GetHealthPercent() < 8) { if (DIVINE_SHIELD > 0 && m_bot->IsSpellReady(DIVINE_SHIELD) && !m_bot->HasAura(DIVINE_SHIELD, EFFECT_INDEX_0) && !m_bot->HasAura(DIVINE_PROTECTION, EFFECT_INDEX_0) && !m_bot->HasAura(FORBEARANCE, EFFECT_INDEX_0) && m_ai->CastSpell(DIVINE_SHIELD, *m_bot)) return RETURN_CONTINUE; if (DIVINE_PROTECTION > 0 && !(m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TANK) && m_bot->IsSpellReady(DIVINE_PROTECTION) && !m_bot->HasAura(DIVINE_SHIELD, EFFECT_INDEX_0) && !m_bot->HasAura(DIVINE_PROTECTION, EFFECT_INDEX_0) && !m_bot->HasAura(FORBEARANCE, EFFECT_INDEX_0) && m_ai->CastSpell(DIVINE_PROTECTION, *m_bot)) return RETURN_CONTINUE; } // Check if bot needs to cast a seal on self or judge the target if (CheckSealAndJudgement(pTarget)) return RETURN_CONTINUE; // Heal if (m_ai->IsHealer()) { if (HealPlayer(GetHealTarget()) & (RETURN_NO_ACTION_OK | 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_NO_ACTION_OK | RETURN_CONTINUE)) return RETURN_CONTINUE; } //Used to determine if this bot has highest 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 if (m_ai->IsElite(newTarget)) { // Try to stun the mob if (HAMMER_OF_JUSTICE > 0 && m_ai->In_Reach(newTarget, HAMMER_OF_JUSTICE) && m_bot->IsSpellReady(HAMMER_OF_JUSTICE) && !newTarget->HasAura(HAMMER_OF_JUSTICE) && m_ai->CastSpell(HAMMER_OF_JUSTICE, *newTarget)) return RETURN_CONTINUE; // Bot has low life: use divine powers to protect him/herself if (m_ai->GetHealthPercent() < 15) { if (DIVINE_SHIELD > 0 && m_bot->IsSpellReady(DIVINE_SHIELD) && !m_bot->HasAura(DIVINE_SHIELD, EFFECT_INDEX_0) && !m_bot->HasAura(DIVINE_PROTECTION, EFFECT_INDEX_0) && !m_bot->HasAura(FORBEARANCE, EFFECT_INDEX_0) && m_ai->CastSpell(DIVINE_SHIELD, *m_bot)) return RETURN_CONTINUE; if (DIVINE_PROTECTION > 0 && m_bot->IsSpellReady(DIVINE_PROTECTION) && !m_bot->HasAura(DIVINE_SHIELD, EFFECT_INDEX_0) && !m_bot->HasAura(DIVINE_PROTECTION, EFFECT_INDEX_0) && !m_bot->HasAura(FORBEARANCE, EFFECT_INDEX_0) && m_ai->CastSpell(DIVINE_PROTECTION, *m_bot)) return RETURN_CONTINUE; } // Else: do nothing and pray for tank to pick aggro from mob return RETURN_NO_ACTION_OK; } } // Damage rotation switch (spec) { case PALADIN_SPEC_HOLY: if (m_ai->IsHealer()) return RETURN_NO_ACTION_OK; // else: DPS (retribution, NEVER protection) case PALADIN_SPEC_RETRIBUTION: if (HAMMER_OF_WRATH > 0 && pTarget->GetHealth() < pTarget->GetMaxHealth() * 0.20 && m_ai->CastSpell(HAMMER_OF_WRATH, *pTarget)) return RETURN_CONTINUE; if (CRUSADER_STRIKE > 0 && m_bot->IsSpellReady(CRUSADER_STRIKE) && m_ai->CastSpell(CRUSADER_STRIKE, *pTarget)) return RETURN_CONTINUE; if (JUDGEMENT > 0 && m_ai->CastSpell(JUDGEMENT, *pTarget)) return RETURN_CONTINUE; if (AVENGING_WRATH > 0 && m_ai->CastSpell(AVENGING_WRATH, *m_bot)) return RETURN_CONTINUE; /*if (HAMMER_OF_JUSTICE > 0 && !pTarget->HasAura(HAMMER_OF_JUSTICE, EFFECT_INDEX_0) && m_ai->CastSpell (HAMMER_OF_JUSTICE, *pTarget)) return RETURN_CONTINUE;*/ /*if (HOLY_WRATH > 0 && m_ai->GetAttackerCount() >= 3 && meleeReach && m_ai->CastSpell (HOLY_WRATH, *pTarget)) return RETURN_CONTINUE;*/ /*if (BLESSING_OF_SACRIFICE > 0 && pVictim == GetMaster() && !GetMaster()->HasAura(BLESSING_OF_SACRIFICE, EFFECT_INDEX_0) && m_ai->CastSpell (BLESSING_OF_SACRIFICE, *GetMaster())) return RETURN_CONTINUE;*/ /*if (RIGHTEOUS_DEFENSE > 0 && pVictim != m_bot && m_ai->GetHealthPercent() > 70 && m_ai->CastSpell (RIGHTEOUS_DEFENSE, *pTarget)) return RETURN_CONTINUE;*/ /*if (DIVINE_FAVOR > 0 && !m_bot->HasAura(DIVINE_FAVOR, EFFECT_INDEX_0) && m_ai->CastSpell (DIVINE_FAVOR, *m_bot)) return RETURN_CONTINUE;*/ return RETURN_NO_ACTION_OK; case PALADIN_SPEC_PROTECTION: //Taunt if orders specify if (CONSECRATION > 0 && m_bot->IsSpellReady(CONSECRATION) && m_ai->CastSpell(CONSECRATION, *pTarget)) return RETURN_CONTINUE; if (HOLY_SHIELD > 0 && !m_bot->HasAura(HOLY_SHIELD) && m_ai->CastSpell(HOLY_SHIELD, *m_bot)) return RETURN_CONTINUE; if (AVENGERS_SHIELD > 0 && m_bot->IsSpellReady(AVENGERS_SHIELD) && m_ai->CastSpell(AVENGERS_SHIELD, *pTarget)) return RETURN_CONTINUE; if (JUDGEMENT > 0 && m_ai->CastSpell(JUDGEMENT, *pTarget)) return RETURN_CONTINUE; return RETURN_NO_ACTION_OK; } return RETURN_NO_ACTION_OK; }
CombatManeuverReturns PlayerbotPaladinAI::DoFirstCombatManeuver(Unit* pTarget) { // There are NPCs in BGs and Open World PvP, so don't filter this on PvP scenarios (of course if PvP targets anyone but tank, all bets are off anyway) // Wait until the tank says so, until any non-tank gains aggro or X seconds - whichever is shortest if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TEMP_WAIT_TANKAGGRO) { if (m_WaitUntil > m_ai->CurrentTime() && m_ai->GroupTankHoldsAggro()) { if (PlayerbotAI::ORDERS_TANK & m_ai->GetCombatOrder()) { if (m_bot->CanReachWithMeleeAttack(pTarget)) { // Set everyone's UpdateAI() waiting to 2 seconds m_ai->SetGroupIgnoreUpdateTime(2); // Clear their TEMP_WAIT_TANKAGGRO flag m_ai->ClearGroupCombatOrder(PlayerbotAI::ORDERS_TEMP_WAIT_TANKAGGRO); // Start attacking, force target on current target m_ai->Attack(m_ai->GetCurrentTarget()); // While everyone else is waiting 2 second, we need to build up aggro, so don't return } else { // TODO: add check if target is ranged return RETURN_NO_ACTION_OK; // wait for target to get nearer } } else if (PlayerbotAI::ORDERS_HEAL & m_ai->GetCombatOrder()) return HealPlayer(GetHealTarget()); else return RETURN_NO_ACTION_OK; // wait it out } else { m_ai->ClearGroupCombatOrder(PlayerbotAI::ORDERS_TEMP_WAIT_TANKAGGRO); } } if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TEMP_WAIT_OOC) { if (m_WaitUntil > m_ai->CurrentTime() && m_ai->IsGroupReady()) return RETURN_NO_ACTION_OK; // wait it out else m_ai->ClearGroupCombatOrder(PlayerbotAI::ORDERS_TEMP_WAIT_OOC); } switch (m_ai->GetScenarioType()) { case PlayerbotAI::SCENARIO_PVP_DUEL: case PlayerbotAI::SCENARIO_PVP_BG: case PlayerbotAI::SCENARIO_PVP_ARENA: case PlayerbotAI::SCENARIO_PVP_OPENWORLD: return DoFirstCombatManeuverPVP(pTarget); case PlayerbotAI::SCENARIO_PVE: case PlayerbotAI::SCENARIO_PVE_ELITE: case PlayerbotAI::SCENARIO_PVE_RAID: default: return DoFirstCombatManeuverPVE(pTarget); break; } return RETURN_NO_ACTION_ERROR; }
void PlayerbotPriestAI::DoNonCombatActions() { if (!m_ai) return; if (!m_bot) return; if (!m_bot->isAlive() || m_bot->IsInDuel()) return; uint32 spec = m_bot->GetSpec(); // selfbuff goes first if (m_ai->SelfBuff(INNER_FIRE)) return; // Revive if (HealPlayer(GetResurrectionTarget()) & RETURN_CONTINUE) return; // After revive if (spec == PRIEST_SPEC_SHADOW && SHADOWFORM > 0) m_ai->SelfBuff(SHADOWFORM); if (VAMPIRIC_EMBRACE > 0) m_ai->SelfBuff(VAMPIRIC_EMBRACE); // 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()) { if (PRAYER_OF_FORTITUDE && m_ai->HasSpellReagents(PRAYER_OF_FORTITUDE) && m_ai->Buff(PRAYER_OF_FORTITUDE, m_bot)) return; if (PRAYER_OF_SPIRIT && m_ai->HasSpellReagents(PRAYER_OF_SPIRIT) && m_ai->Buff(PRAYER_OF_SPIRIT, m_bot)) return; if (PRAYER_OF_SHADOW_PROTECTION && m_ai->HasSpellReagents(PRAYER_OF_SHADOW_PROTECTION) && m_ai->Buff(PRAYER_OF_SHADOW_PROTECTION, m_bot)) return; } if (Buff(&PlayerbotPriestAI::BuffHelper, POWER_WORD_FORTITUDE)) return; if (Buff(&PlayerbotPriestAI::BuffHelper, DIVINE_SPIRIT, (JOB_ALL | JOB_MANAONLY))) return; if (Buff(&PlayerbotPriestAI::BuffHelper, SHADOW_PROTECTION, (JOB_TANK | JOB_HEAL) )) return; // hp/mana check if (m_bot->getStandState() != UNIT_STAND_STATE_STAND) m_bot->SetStandState(UNIT_STAND_STATE_STAND); if (EatDrinkBandage()) return; } // end DoNonCombatActions
CombatManeuverReturns PlayerbotPaladinAI::DoNextCombatManeuverPVE(Unit* pTarget) { if (!m_ai) return RETURN_NO_ACTION_ERROR; if (!m_bot) return RETURN_NO_ACTION_ERROR; if (!pTarget) return RETURN_NO_ACTION_INVALIDTARGET; // damage spells uint32 spec = m_bot->GetSpec(); std::ostringstream out; // 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); // Heal if (m_ai->IsHealer()) { if (HealPlayer(GetHealTarget()) & (RETURN_NO_ACTION_OK | RETURN_CONTINUE)) return RETURN_CONTINUE; } else if (m_ai->GetGroupHealer() && m_ai->GetGroupHealer()->isAlive()) { // Desirable? Debatable. We should have faith in the healer. On the other hand this low HP could be considered a crisis, // and DPS is not crucial so probably a good thing (which is why I put it in) // Of course, keep in mind we're not healing specced so it's unlikely to do much later on... if (!m_ai->IsTank() && m_ai->GetHealthPercent() < 35 && HealPlayer(m_bot) & (RETURN_NO_ACTION_OK | 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 (m_ai->GetHealthPercent() < 50 && HealPlayer(m_bot) & (RETURN_NO_ACTION_OK | RETURN_CONTINUE)) return RETURN_CONTINUE; } //Used to determine if this bot has highest threat Unit* newTarget = m_ai->FindAttacker((PlayerbotAI::ATTACKERINFOTYPE)(PlayerbotAI::AIT_VICTIMSELF | PlayerbotAI::AIT_HIGHESTTHREAT), m_bot); switch (spec) { case PALADIN_SPEC_HOLY: if (m_ai->IsHealer()) return RETURN_NO_ACTION_OK; // else: DPS (retribution, NEVER protection) case PALADIN_SPEC_RETRIBUTION: if (HAMMER_OF_WRATH > 0 && pTarget->GetHealth() < pTarget->GetMaxHealth() * 0.20 && m_ai->CastSpell(HAMMER_OF_WRATH, *pTarget)) return RETURN_CONTINUE; if (ART_OF_WAR > 0 && EXORCISM > 0 && m_bot->IsSpellReady(EXORCISM) && m_bot->HasAura(ART_OF_WAR, EFFECT_INDEX_0) && m_ai->CastSpell(EXORCISM, *pTarget)) return RETURN_CONTINUE; if (CRUSADER_STRIKE > 0 && m_bot->IsSpellReady(CRUSADER_STRIKE) && m_ai->CastSpell(CRUSADER_STRIKE, *pTarget)) return RETURN_CONTINUE; if (DIVINE_STORM > 0 && /*m_ai->GetAttackerCount() >= 3 && meleeReach*/ m_bot->IsSpellReady(DIVINE_STORM) && m_ai->CastSpell(DIVINE_STORM, *pTarget)) return RETURN_CONTINUE; if (JUDGEMENT_OF_LIGHT > 0 && m_ai->CastSpell(JUDGEMENT_OF_LIGHT, *pTarget)) return RETURN_CONTINUE; if (AVENGING_WRATH > 0 && m_ai->CastSpell(AVENGING_WRATH, *m_bot)) return RETURN_CONTINUE; /*if (HAMMER_OF_JUSTICE > 0 && !pTarget->HasAura(HAMMER_OF_JUSTICE, EFFECT_INDEX_0) && m_ai->CastSpell (HAMMER_OF_JUSTICE, *pTarget)) return RETURN_CONTINUE;*/ /*if (SACRED_SHIELD > 0 && pVictim == m_bot && m_ai->GetHealthPercent() < 70 && !m_bot->HasAura(SACRED_SHIELD, EFFECT_INDEX_0) && m_ai->CastSpell (SACRED_SHIELD, *m_bot)) return RETURN_CONTINUE;*/ /*if (HOLY_WRATH > 0 && m_ai->GetAttackerCount() >= 3 && meleeReach && m_ai->CastSpell (HOLY_WRATH, *pTarget)) return RETURN_CONTINUE;*/ /*if (HAND_OF_SACRIFICE > 0 && pVictim == GetMaster() && !GetMaster()->HasAura(HAND_OF_SACRIFICE, EFFECT_INDEX_0) && m_ai->CastSpell (HAND_OF_SACRIFICE, *GetMaster())) return RETURN_CONTINUE;*/ /*if (DIVINE_PROTECTION > 0 && pVictim == m_bot && !m_bot->HasAura(FORBEARANCE, EFFECT_INDEX_0) && m_ai->GetHealthPercent() < 30 && m_ai->CastSpell (DIVINE_PROTECTION, *m_bot)) return RETURN_CONTINUE;*/ /*if (RIGHTEOUS_DEFENSE > 0 && pVictim != m_bot && m_ai->GetHealthPercent() > 70 && m_ai->CastSpell (RIGHTEOUS_DEFENSE, *pTarget)) return RETURN_CONTINUE;*/ /*if (DIVINE_PLEA > 0 && !m_bot->HasAura(DIVINE_PLEA, EFFECT_INDEX_0) && m_ai->CastSpell (DIVINE_PLEA, *m_bot)) return RETURN_CONTINUE;*/ /*if (DIVINE_FAVOR > 0 && !m_bot->HasAura(DIVINE_FAVOR, EFFECT_INDEX_0) && m_ai->CastSpell (DIVINE_FAVOR, *m_bot)) return RETURN_CONTINUE;*/ return RETURN_NO_ACTION_OK; case PALADIN_SPEC_PROTECTION: //Taunt if orders specify if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TANK && !newTarget && HAND_OF_RECKONING > 0 && m_bot->IsSpellReady(HAND_OF_RECKONING) && m_ai->CastSpell(HAND_OF_RECKONING, *pTarget)) return RETURN_CONTINUE; if (CONSECRATION > 0 && m_bot->IsSpellReady(CONSECRATION) && m_ai->CastSpell(CONSECRATION, *pTarget)) return RETURN_CONTINUE; if (HOLY_SHIELD > 0 && !m_bot->HasAura(HOLY_SHIELD) && m_ai->CastSpell(HOLY_SHIELD, *m_bot)) return RETURN_CONTINUE; if (AVENGERS_SHIELD > 0 && m_bot->IsSpellReady(AVENGERS_SHIELD) && m_ai->CastSpell(AVENGERS_SHIELD, *pTarget)) return RETURN_CONTINUE; if (HAMMER_OF_THE_RIGHTEOUS > 0 && m_bot->IsSpellReady(HAMMER_OF_THE_RIGHTEOUS) && m_ai->CastSpell(HAMMER_OF_THE_RIGHTEOUS, *pTarget)) return RETURN_CONTINUE; if (SHIELD_OF_RIGHTEOUSNESS > 0 && m_bot->IsSpellReady(SHIELD_OF_RIGHTEOUSNESS) && m_ai->CastSpell(SHIELD_OF_RIGHTEOUSNESS, *pTarget)) return RETURN_CONTINUE; if (JUDGEMENT_OF_LIGHT > 0 && m_ai->CastSpell(JUDGEMENT_OF_LIGHT, *pTarget)) return RETURN_CONTINUE; return RETURN_NO_ACTION_OK; } //if (DIVINE_SHIELD > 0 && m_ai->GetHealthPercent() < 30 && pVictim == m_bot && !m_bot->HasAura(FORBEARANCE, EFFECT_INDEX_0) && !m_bot->HasAura(DIVINE_SHIELD, EFFECT_INDEX_0)) // m_ai->CastSpell(DIVINE_SHIELD, *m_bot); //if (DIVINE_SACRIFICE > 0 && m_ai->GetHealthPercent() > 50 && pVictim != m_bot && !m_bot->HasAura(DIVINE_SACRIFICE, EFFECT_INDEX_0)) // m_ai->CastSpell(DIVINE_SACRIFICE, *m_bot); return RETURN_NO_ACTION_OK; }
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