diff --git a/zone/bot.cpp b/zone/bot.cpp index c5f0278ee..7d1a8277d 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -7402,16 +7402,19 @@ bool Bot::AttemptCloseBeneficialSpells(uint16 spell_type) { bool result = false; Mob* tar = nullptr; - for (Mob* m : GetSpellTargetList()) { + for (Mob* m : GetSpellTargetList(RuleB(Bots, CrossRaidBuffingAndHealing))) { tar = m; if (!tar) { continue; } - if (IsGroupTargetOnlyBotSpellType(spell_type)) { + if (RuleB(Bots, CrossRaidBuffingAndHealing) && IsGroupTargetOnlyBotSpellType(spell_type)) { Raid* raid = GetStoredRaid(); - if (raid && (raid->GetGroup(GetName()) == raid->GetGroup(tar->GetName()))) { + + if (raid && + (raid->GetGroup(GetName()) == raid->GetGroup(tar->GetName())) + ) { continue; } } @@ -7419,24 +7422,26 @@ bool Bot::AttemptCloseBeneficialSpells(uint16 spell_type) { result = AttemptAICastSpell(spell_type, tar); if (!result) { - if ( - tar->HasPet() && - ( - !m->GetPet()->IsFamiliar() || - RuleB(Bots, AllowBuffingHealingFamiliars) - ) - ) { - tar = m->GetPet(); + if (tar->HasPet()) { + Mob* pet = m->GetPet(); - if (!tar) { - continue; + if (!pet->IsFamiliar() || RuleB(Bots, AllowBuffingHealingFamiliars)) { + tar = pet; + + if (!tar) { + continue; + } + + if (tar->IsOfClientBot() || + ( + tar->IsPet() && + tar->GetOwner() && + tar->GetOwner()->IsOfClientBot() + ) + ) { + result = AttemptAICastSpell(spell_type, tar); + } } - - if (!tar->IsOfClientBot() && !(tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot())) { - continue; - } - - result = AttemptAICastSpell(spell_type, tar); } } @@ -7679,29 +7684,21 @@ void EntityList::ShowSpawnWindow(Client* client, int Distance, bool NamedOnly) { return; } -uint8 Bot::GetNumberNeedingHealedInGroup(uint8 hpr, bool include_pets, Raid* raid) { +uint8 Bot::GetNumberNeedingHealedInGroup(Mob* tar, uint16 spell_type, uint16 spell_id, float range) { + if (!tar->IsBot()) { + return 0; + } - uint8 need_healed = 0; - if (HasGroup()) { + uint8 count = 0; + auto target_list = tar->IsClient() ? tar->CastToBot()->GatherSpellTargets() : tar->CastToBot()->GetSpellTargetList(); - auto group_members = GetGroup(); - if (group_members) { - - for (auto member : group_members->members) { - if (member && !member->qglobal) { - - if (member->GetHPRatio() <= hpr) { - need_healed++; - } - - if (include_pets && member->GetPet() && !member->GetPet()->IsFamiliar() && member->GetPet()->GetHPRatio() <= hpr) { - need_healed++; - } - } - } + for (Mob* m : target_list) { + if (tar->CalculateDistance(m) < range && CastChecks(spell_id, m, spell_type, true, IsGroupBotSpellType(spell_type))) { + ++count; } } - return GetNumberNeedingHealedInRaidGroup(need_healed, hpr, include_pets, raid); + + return count; } int Bot::GetRawACNoShield(int &shield_ac) { @@ -10049,27 +10046,24 @@ bool Bot::IsTargetAlreadyReceivingSpell(Mob* tar, uint16 spell_id) { uint16 target_id = tar->GetID(); - for (Mob* m : GetSpellTargetList()) { + for (Mob* m : GetSpellTargetList(RuleB(Bots, CrossRaidBuffingAndHealing))) { if ( m->IsBot() && m->IsCasting() && m->CastToBot()->casting_spell_targetid && m->CastingSpellID() == spell_id ) { - if (RuleB(Bots, CrossRaidBuffingAndHealing) && IsGroupSpell(spell_id)) { - std::vector t = GatherSpellTargets(false, tar); + if (m->CastToBot()->casting_spell_targetid == target_id) { + return true; + } - for (Mob* x : t) { + if (!RuleB(Bots, CrossRaidBuffingAndHealing) && IsGroupSpell(spell_id)) { + for (Mob* x : GatherSpellTargets(false, tar)) { if (x->GetID() == m->CastToBot()->casting_spell_targetid) { return true; } } } - else { - if (m->CastToBot()->casting_spell_targetid == target_id) { - return true; - } - } } } @@ -10203,7 +10197,7 @@ bool Bot::IsMobEngagedByAnyone(Mob* tar) { return false; } - for (Mob* m : GetSpellTargetList()) { + for (Mob* m : GetSpellTargetList(true)) { if (m->GetTarget() != tar) { continue; } @@ -12726,7 +12720,7 @@ std::vector Bot::GatherSpellTargets(bool entire_raid, Mob* target, bool no std::vector Bot::GetBuffTargets(Mob* spellTarget) { if (RuleB(Bots, RaidBuffing)) { - return GetSpellTargetList(); + return GetSpellTargetList(true); } return GatherSpellTargets(false, spellTarget); @@ -13310,11 +13304,13 @@ bool Bot::IsImmuneToBotSpell(uint16 spell_id, Mob* caster) { return false; } -std::vector Bot::GetSpellTargetList() { - if (_spell_target_list.empty()) { - std::vector spell_target_list = GatherSpellTargets(RuleB(Bots, CrossRaidBuffingAndHealing)); - SetSpellTargetList(spell_target_list); +std::vector Bot::GetSpellTargetList(bool entire_raid) { + if (entire_raid && _spell_target_list.empty()) { + _spell_target_list = GatherSpellTargets(RuleB(Bots, CrossRaidBuffingAndHealing)); + } + else if (!entire_raid && _group_spell_target_list.empty()) { + _group_spell_target_list = GatherSpellTargets(); } - return _spell_target_list; + return entire_raid ? _spell_target_list : _group_spell_target_list; } diff --git a/zone/bot.h b/zone/bot.h index ec7a441ff..d9efbefb9 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -364,8 +364,7 @@ public: bool GetIsUsingItemClick() { return is_using_item_click; } void SetIsUsingItemClick(bool flag = true) { is_using_item_click = flag; } bool UseDiscipline(uint32 spell_id, uint32 target); - uint8 GetNumberNeedingHealedInGroup(uint8 hpr, bool include_pets, Raid* raid); - uint8 GetNumberNeedingHealedInRaidGroup(uint8& need_healed, uint8 hpr, bool include_pets, Raid* raid); + uint8 GetNumberNeedingHealedInGroup(Mob* tar, uint16 spell_type, uint16 spell_id, float range); bool GetNeedsCured(Mob *tar); bool GetNeedsHateRedux(Mob *tar); bool HasOrMayGetAggro(bool SitAggro, uint32 spell_id = 0); @@ -560,7 +559,7 @@ public: // Movement checks bool PlotBotPositionAroundTarget(Mob* target, float& x_dest, float& y_dest, float& z_dest, float min_distance, float max_distance, bool behind_only = false, bool front_only = false, bool bypass_los = false); - std::vector GetSpellTargetList(); + std::vector GetSpellTargetList(bool entire_raid = false); void SetSpellTargetList(std::vector spell_target_list) { _spell_target_list = spell_target_list; } std::vector GetGroupSpellTargetList() { return _group_spell_target_list; } void SetGroupSpellTargetList(std::vector spell_target_list) { _group_spell_target_list = spell_target_list; } diff --git a/zone/bot_raid.cpp b/zone/bot_raid.cpp index aba5981a7..e1eb60748 100644 --- a/zone/bot_raid.cpp +++ b/zone/bot_raid.cpp @@ -133,26 +133,6 @@ void Raid::HandleOfflineBots(uint32 owner) { } } -uint8 Bot::GetNumberNeedingHealedInRaidGroup(uint8& need_healed, uint8 hpr, bool include_pets, Raid* raid) { - - if (raid) { - uint32 r_group = raid->GetGroup(GetName()); - - for (auto& m: raid->GetRaidGroupMembers(r_group)) { - if (m.member && !m.member->qglobal) { - if (m.member->GetHPRatio() <= hpr) { - need_healed++; - } - - if (include_pets && m.member->GetPet() && m.member->GetPet()->GetHPRatio() <= hpr) { - need_healed++; - } - } - } - } - return need_healed; -} - void Bot::ProcessRaidInvite(Mob* invitee, Client* invitor, bool group_invite) { if (!invitee || !invitor) { diff --git a/zone/botspellsai.cpp b/zone/botspellsai.cpp index d9e4863df..35ca8dedc 100644 --- a/zone/botspellsai.cpp +++ b/zone/botspellsai.cpp @@ -337,9 +337,7 @@ bool Bot::BotCastCure(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spe if (AIDoSpellCast(bot_spell.SpellIndex, tar, bot_spell.ManaCost)) { if (IsGroupSpell(bot_spell.SpellId)) { if (!IsCommandedSpell()) { - const std::vector v = GatherSpellTargets(false, tar); - - for (Mob* m : v) { + for (Mob* m : GatherSpellTargets(false, tar)) { SetBotSpellRecastTimer(spell_type, m, true); } } @@ -513,9 +511,7 @@ bool Bot::BotCastHeal(Mob* tar, uint8 bot_class, BotSpell& bot_spell, uint16 spe if (IsGroupSpell(bot_spell.SpellId)) { if (bot_class != Class::Bard) { if (!IsCommandedSpell()) { - const std::vector v = GatherSpellTargets(false, tar); - - for (Mob* m : v) { + for (Mob* m : GatherSpellTargets(false, tar)) { SetBotSpellRecastTimer(spell_type, m, true); } } @@ -1309,15 +1305,11 @@ BotSpell Bot::GetBestBotSpellForGroupHeal(Bot* caster, Mob* tar, uint16 spell_ty for (std::list::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) { // Assuming all the spells have been loaded into this list by level and in descending order - if (IsRegularGroupHealSpell(bot_spell_list_itr->SpellId)) { - if (!caster->IsCommandedSpell()) { - target_count = 0; + if (IsGroupHealOverTimeSpell(bot_spell_list_itr->SpellId)) { + uint16 spell_id = bot_spell_list_itr->SpellId; - for (Mob* m : caster->GetSpellTargetList()) { - if (caster->IsValidSpellRange(bot_spell_list_itr->SpellId, m) && caster->CastChecks(bot_spell_list_itr->SpellId, m, spell_type, true, IsGroupBotSpellType(spell_type))) { - ++target_count; - } - } + if (!caster->IsCommandedSpell() && caster->IsValidSpellRange(spell_id, tar)) { + target_count = caster->GetNumberNeedingHealedInGroup(tar, spell_type, spell_id, caster->GetAOERange(spell_id)); if (target_count < caster->GetSpellTypeAEOrGroupTargetCount(spell_type)) { continue; @@ -1351,14 +1343,10 @@ BotSpell Bot::GetBestBotSpellForGroupHealOverTime(Bot* caster, Mob* tar, uint16 for (std::list::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) { // Assuming all the spells have been loaded into this list by level and in descending order if (IsGroupHealOverTimeSpell(bot_spell_list_itr->SpellId)) { - if (!caster->IsCommandedSpell()) { - target_count = 0; + uint16 spell_id = bot_spell_list_itr->SpellId; - for (Mob* m : caster->GetSpellTargetList()) { - if (caster->IsValidSpellRange(bot_spell_list_itr->SpellId, m) && caster->CastChecks(bot_spell_list_itr->SpellId, m, spell_type, true, IsGroupBotSpellType(spell_type))) { - ++target_count; - } - } + if (!caster->IsCommandedSpell() && caster->IsValidSpellRange(spell_id, tar)) { + target_count = caster->GetNumberNeedingHealedInGroup(tar, spell_type, spell_id, caster->GetAOERange(spell_id)); if (target_count < caster->GetSpellTypeAEOrGroupTargetCount(spell_type)) { continue; @@ -1389,17 +1377,13 @@ BotSpell Bot::GetBestBotSpellForGroupCompleteHeal(Bot* caster, Mob* tar, uint16 int target_count = 0; - for(std::list::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) { + for (std::list::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) { // Assuming all the spells have been loaded into this list by level and in descending order - if (IsGroupCompleteHealSpell(bot_spell_list_itr->SpellId)) { - if (!caster->IsCommandedSpell()) { - target_count = 0; + if (IsGroupHealOverTimeSpell(bot_spell_list_itr->SpellId)) { + uint16 spell_id = bot_spell_list_itr->SpellId; - for (Mob* m : caster->GetSpellTargetList()) { - if (caster->IsValidSpellRange(bot_spell_list_itr->SpellId, m) && caster->CastChecks(bot_spell_list_itr->SpellId, m, spell_type, true, IsGroupBotSpellType(spell_type))) { - ++target_count; - } - } + if (!caster->IsCommandedSpell() && caster->IsValidSpellRange(spell_id, tar)) { + target_count = caster->GetNumberNeedingHealedInGroup(tar, spell_type, spell_id, caster->GetAOERange(spell_id)); if (target_count < caster->GetSpellTypeAEOrGroupTargetCount(spell_type)) { continue; @@ -2045,13 +2029,7 @@ BotSpell Bot::GetBestBotSpellForCure(Bot* caster, Mob* tar, uint16 spell_type) { continue; } - for (Mob* m : caster->GetSpellTargetList()) { - if (IsGroupBotSpellType(spell_type)) { - if (!caster->IsInGroupOrRaid(m, true)) { - continue; - } - } - + for (Mob* m : (IsGroupBotSpellType(spell_type) ? caster->GetSpellTargetList() : caster->GetSpellTargetList(true))) { if (caster->GetNeedsCured(m)) { if (caster->CastChecks(itr->SpellId, m, spell_type, true, IsGroupBotSpellType(spell_type))) { if (m->FindType(SE_PoisonCounter)) {