raid optimizations

This commit is contained in:
nytmyr
2024-12-20 21:21:14 -06:00
parent c02259aceb
commit d05dcb5d60
9 changed files with 55 additions and 48 deletions
+4 -4
View File
@@ -815,10 +815,10 @@ RULE_INT(Bots, PercentChanceToCastGroupCure, 75, "The chance for a bot to attemp
RULE_INT(Bots, PercentChanceToCastHateRedux, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.") RULE_INT(Bots, PercentChanceToCastHateRedux, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.")
RULE_INT(Bots, PercentChanceToCastFear, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.") RULE_INT(Bots, PercentChanceToCastFear, 75, "The chance for a bot to attempt to cast the given spell type in combat. Default 75%.")
RULE_INT(Bots, PercentChanceToCastOtherType, 90, "The chance for a bot to attempt to cast the remaining spell types in combat. Default 0-%.") RULE_INT(Bots, PercentChanceToCastOtherType, 90, "The chance for a bot to attempt to cast the remaining spell types in combat. Default 0-%.")
RULE_INT(Bots, MinDelayBetweenInCombatCastAttempts, 250, "The minimum delay in milliseconds between cast attempts while in-combat. This is rolled between the min and max. Default 250ms.") RULE_INT(Bots, MinDelayBetweenInCombatCastAttempts, 500, "The minimum delay in milliseconds between cast attempts while in-combat. This is rolled between the min and max. Default 500ms.")
RULE_INT(Bots, MaxDelayBetweenInCombatCastAttempts, 2000, "The maximum delay in milliseconds between cast attempts while in-combat. This is rolled between the min and max. Default 2000ms.") RULE_INT(Bots, MaxDelayBetweenInCombatCastAttempts, 2000, "The maximum delay in milliseconds between cast attempts while in-combat. This is rolled between the min and max. Default 2500ms.")
RULE_INT(Bots, MinDelayBetweenOutCombatCastAttempts, 125, "The minimum delay in milliseconds between cast attempts while out-of-combat. This is rolled between the min and max. Default 125ms.") RULE_INT(Bots, MinDelayBetweenOutCombatCastAttempts, 1000, "The minimum delay in milliseconds between cast attempts while out-of-combat. This is rolled between the min and max. Default 1000ms.")
RULE_INT(Bots, MaxDelayBetweenOutCombatCastAttempts, 500, "The maximum delay in milliseconds between cast attempts while out-of-combat. This is rolled between the min and max. Default 500ms.") RULE_INT(Bots, MaxDelayBetweenOutCombatCastAttempts, 2500, "The maximum delay in milliseconds between cast attempts while out-of-combat. This is rolled between the min and max. Default 2500ms.")
RULE_INT(Bots, MezChance, 35, "35 Default. Chance for a bot to attempt to Mez a target after validating it is eligible.") RULE_INT(Bots, MezChance, 35, "35 Default. Chance for a bot to attempt to Mez a target after validating it is eligible.")
RULE_INT(Bots, AEMezChance, 35, "35 Default. Chance for a bot to attempt to AE Mez targets after validating they are eligible.") RULE_INT(Bots, AEMezChance, 35, "35 Default. Chance for a bot to attempt to AE Mez targets after validating they are eligible.")
RULE_INT(Bots, MezSuccessDelay, 3500, "3500 (3.5 sec) Default. Delay between successful Mez attempts.") RULE_INT(Bots, MezSuccessDelay, 3500, "3500 (3.5 sec) Default. Delay between successful Mez attempts.")
+2 -2
View File
@@ -2624,10 +2624,10 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
bool owner_in_group = false; bool owner_in_group = false;
if ( if (
give_exp->IsInGroupOrRaid(give_exp->GetUltimateOwner(), RuleB(Bots, SameRaidGroupForXP)) || give_exp->IsInGroupOrRaid(give_exp->GetUltimateOwner(), nullptr, RuleB(Bots, SameRaidGroupForXP)) ||
give_exp->IsPet() && give_exp->IsPet() &&
give_exp->GetOwner() && give_exp->GetOwner() &&
give_exp->GetOwner()->IsInGroupOrRaid(give_exp->GetUltimateOwner(), RuleB(Bots, SameRaidGroupForXP)) give_exp->GetOwner()->IsInGroupOrRaid(give_exp->GetUltimateOwner(), nullptr, RuleB(Bots, SameRaidGroupForXP))
) { ) {
owner_in_group = true; owner_in_group = true;
} }
+13 -14
View File
@@ -2093,7 +2093,7 @@ void Bot::AI_Process()
else { else {
follow_mob = entity_list.GetMob(GetFollowID()); follow_mob = entity_list.GetMob(GetFollowID());
if (!follow_mob || !IsInGroupOrRaid(follow_mob)) { if (!follow_mob || !IsInGroupOrRaid(follow_mob, raid)) {
follow_mob = leash_owner; follow_mob = leash_owner;
} }
} }
@@ -2367,7 +2367,7 @@ void Bot::AI_Process()
// AUTO DEFEND // AUTO DEFEND
if (TryAutoDefend(bot_owner, leash_distance) ) { if (TryAutoDefend(bot_owner, leash_distance, raid) ) {
return; return;
} }
@@ -2466,7 +2466,7 @@ bool Bot::TryIdleChecks(float fm_distance) {
// This is as close as I could get without modifying the aggro mechanics and making it an expensive process... // This is as close as I could get without modifying the aggro mechanics and making it an expensive process...
// 'class Client' doesn't make use of hate_list // 'class Client' doesn't make use of hate_list
bool Bot::TryAutoDefend(Client* bot_owner, float leash_distance) { bool Bot::TryAutoDefend(Client* bot_owner, float leash_distance, Raid* raid) {
if (RuleB(Bots, AllowOwnerOptionAutoDefend) && bot_owner->GetBotOption(Client::booAutoDefend)) { if (RuleB(Bots, AllowOwnerOptionAutoDefend) && bot_owner->GetBotOption(Client::booAutoDefend)) {
@@ -2503,14 +2503,13 @@ bool Bot::TryAutoDefend(Client* bot_owner, float leash_distance) {
bool assisteeFound = false; bool assisteeFound = false;
if (IsRaidGrouped()) { if (IsRaidGrouped()) {
Raid* r = entity_list.GetRaidByBot(this); if (raid) {
if (r) { for (const auto& m : raid->members) {
for (const auto& m : r->members) {
if ( if (
m.member && m.member &&
m.member->IsClient() && m.member->IsClient() &&
m.member->GetAggroCount() && m.member->GetAggroCount() &&
r->IsAssister(m.member_name) raid->IsAssister(m.member_name)
) { ) {
temp_xhaters = m.member->GetXTargetAutoMgr(); temp_xhaters = m.member->GetXTargetAutoMgr();
@@ -2554,7 +2553,7 @@ bool Bot::TryAutoDefend(Client* bot_owner, float leash_distance) {
if (bot_owner->GetAssistee()) { if (bot_owner->GetAssistee()) {
Client* c = entity_list.GetClientByCharID(bot_owner->GetAssistee()); Client* c = entity_list.GetClientByCharID(bot_owner->GetAssistee());
if (bot_owner->IsInGroupOrRaid(c) && c->GetAggroCount()) { if (bot_owner->IsInGroupOrRaid(c, raid) && c->GetAggroCount()) {
tempHaters = bot_owner->GetXTargetAutoMgr(); tempHaters = bot_owner->GetXTargetAutoMgr();
if (tempHaters && !tempHaters->empty()) { if (tempHaters && !tempHaters->empty()) {
@@ -7222,7 +7221,7 @@ bool Bot::AttemptCloseBeneficialSpells(uint16 spellType, Raid* raid, std::vector
} }
} }
result = AttemptAICastSpell(spellType, tar); result = AttemptAICastSpell(spellType, tar, raid);
if (!result) { if (!result) {
if (tar->HasPet() && (!m->GetPet()->IsFamiliar() || RuleB(Bots, AllowBuffingHealingFamiliars))) { if (tar->HasPet() && (!m->GetPet()->IsFamiliar() || RuleB(Bots, AllowBuffingHealingFamiliars))) {
@@ -7236,7 +7235,7 @@ bool Bot::AttemptCloseBeneficialSpells(uint16 spellType, Raid* raid, std::vector
continue; continue;
} }
result = AttemptAICastSpell(spellType, tar); result = AttemptAICastSpell(spellType, tar, raid);
} }
} }
@@ -10810,7 +10809,7 @@ std::list<BotSpellTypeOrder> Bot::GetSpellTypesPrioritized(uint8 priorityType) {
return castOrder; return castOrder;
} }
bool Bot::AttemptAICastSpell(uint16 spellType, Mob* tar) { bool Bot::AttemptAICastSpell(uint16 spellType, Mob* tar, Raid* raid) {
bool result = false; bool result = false;
if (!tar) { if (!tar) {
@@ -10834,12 +10833,12 @@ bool Bot::AttemptAICastSpell(uint16 spellType, Mob* tar) {
tar = this; tar = this;
} }
if (!PrecastChecks(tar, spellType) || !AICastSpell(tar, GetChanceToCastBySpellType(spellType), spellType)) { if (!PrecastChecks(tar, spellType) || !AICastSpell(tar, GetChanceToCastBySpellType(spellType), spellType, raid)) {
return result; return result;
} }
} }
else { else {
if (!PrecastChecks(tar, spellType) || !AICastSpell(tar, GetChanceToCastBySpellType(spellType), spellType)) { if (!PrecastChecks(tar, spellType) || !AICastSpell(tar, GetChanceToCastBySpellType(spellType), spellType, raid)) {
return result; return result;
} }
} }
@@ -10995,7 +10994,7 @@ bool Bot::AttemptForcedCastSpell(Mob* tar, uint16 spell_id) {
!RuleB(Bots, EnableBotTGB) && !RuleB(Bots, EnableBotTGB) &&
IsGroupSpell(forcedSpellID) && IsGroupSpell(forcedSpellID) &&
!IsTGBCompatibleSpell(forcedSpellID) && !IsTGBCompatibleSpell(forcedSpellID) &&
!IsInGroupOrRaid(tar, true) !IsInGroupOrRaid(tar, nullptr, true)
) { ) {
LogTestDebug("{} failed TGB for {} [#{}].", GetCleanName(), spell.name, forcedSpellID); //deleteme LogTestDebug("{} failed TGB for {} [#{}].", GetCleanName(), spell.name, forcedSpellID); //deleteme
return false; return false;
+4 -4
View File
@@ -397,8 +397,8 @@ public:
void AI_Bot_Event_SpellCastFinished(bool iCastSucceeded, uint16 slot); void AI_Bot_Event_SpellCastFinished(bool iCastSucceeded, uint16 slot);
// AI Methods // AI Methods
bool AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, uint16 subTargetType = UINT16_MAX, uint16 subType = UINT16_MAX); bool AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, Raid* raid = nullptr, uint16 subTargetType = UINT16_MAX, uint16 subType = UINT16_MAX);
bool AttemptAICastSpell(uint16 spellType, Mob* tar = nullptr); bool AttemptAICastSpell(uint16 spellType, Mob* tar = nullptr, Raid* raid = nullptr);
bool AttemptAACastSpell(Mob* tar, uint16 spell_id, AA::Rank* rank); bool AttemptAACastSpell(Mob* tar, uint16 spell_id, AA::Rank* rank);
bool AttemptForcedCastSpell(Mob* tar, uint16 spell_id); bool AttemptForcedCastSpell(Mob* tar, uint16 spell_id);
bool AttemptCloseBeneficialSpells(uint16 spellType, Raid* raid, std::vector<Mob*> targetList); bool AttemptCloseBeneficialSpells(uint16 spellType, Raid* raid, std::vector<Mob*> targetList);
@@ -597,7 +597,7 @@ public:
static std::list<BotSpell> GetBotSpellsForSpellEffect(Bot* botCaster, uint16 spellType, int spellEffect); static std::list<BotSpell> GetBotSpellsForSpellEffect(Bot* botCaster, uint16 spellType, int spellEffect);
static std::list<BotSpell> GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, uint16 spellType, int spellEffect, SpellTargetType targetType); static std::list<BotSpell> GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, uint16 spellType, int spellEffect, SpellTargetType targetType);
static std::list<BotSpell> GetBotSpellsBySpellType(Bot* botCaster, uint16 spellType); static std::list<BotSpell> GetBotSpellsBySpellType(Bot* botCaster, uint16 spellType);
static std::list<BotSpell_wPriority> GetPrioritizedBotSpellsBySpellType(Bot* botCaster, uint16 spellType, Mob* tar, bool AE = false, uint16 subTargetType = UINT16_MAX, uint16 subType = UINT16_MAX); static std::list<BotSpell_wPriority> GetPrioritizedBotSpellsBySpellType(Bot* botCaster, uint16 spellType, Mob* tar, bool AE = false, Raid* raid = nullptr, uint16 subTargetType = UINT16_MAX, uint16 subType = UINT16_MAX);
static BotSpell GetFirstBotSpellBySpellType(Bot* botCaster, uint16 spellType); static BotSpell GetFirstBotSpellBySpellType(Bot* botCaster, uint16 spellType);
static BotSpell GetBestBotSpellForVeryFastHeal(Bot* botCaster, Mob* tar, uint16 spellType = BotSpellTypes::RegularHeal); static BotSpell GetBestBotSpellForVeryFastHeal(Bot* botCaster, Mob* tar, uint16 spellType = BotSpellTypes::RegularHeal);
@@ -990,7 +990,7 @@ public:
bool TryFacingTarget(Mob* tar); bool TryFacingTarget(Mob* tar);
bool TryPursueTarget(float leash_distance, glm::vec3& Goal); bool TryPursueTarget(float leash_distance, glm::vec3& Goal);
bool TryMeditate(); bool TryMeditate();
bool TryAutoDefend(Client* bot_owner, float leash_distance); bool TryAutoDefend(Client* bot_owner, float leash_distance, Raid* raid = nullptr);
bool TryIdleChecks(float fm_distance); bool TryIdleChecks(float fm_distance);
bool TryNonCombatMovementChecks(Client* bot_owner, const Mob* follow_mob, glm::vec3& Goal); bool TryNonCombatMovementChecks(Client* bot_owner, const Mob* follow_mob, glm::vec3& Goal);
bool TryBardMovementCasts(); bool TryBardMovementCasts();
+2 -2
View File
@@ -506,7 +506,7 @@ void bot_command_cast(Client* c, const Seperator* sep)
if ( if (
IsBotSpellTypeBeneficial(spellType) && IsBotSpellTypeBeneficial(spellType) &&
!RuleB(Bots, CrossRaidBuffingAndHealing) && !RuleB(Bots, CrossRaidBuffingAndHealing) &&
!bot_iter->IsInGroupOrRaid(newTar, true) !bot_iter->IsInGroupOrRaid(newTar, nullptr, true)
) { ) {
continue; continue;
} }
@@ -588,7 +588,7 @@ void bot_command_cast(Client* c, const Seperator* sep)
LogTestDebug("{}: {} says, 'Attempting {} [{}-{}] on [{}]'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (subTargetType != UINT16_MAX ? c->GetSubTypeNameByID(subTargetType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme LogTestDebug("{}: {} says, 'Attempting {} [{}-{}] on [{}]'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (subTargetType != UINT16_MAX ? c->GetSubTypeNameByID(subTargetType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
bot_iter->SetCommandedSpell(true); bot_iter->SetCommandedSpell(true);
if (bot_iter->AICastSpell(newTar, 100, spellType, subTargetType, subType)) { if (bot_iter->AICastSpell(newTar, 100, spellType, nullptr, subTargetType, subType)) {
if (!firstFound) { if (!firstFound) {
firstFound = bot_iter; firstFound = bot_iter;
} }
+1 -1
View File
@@ -164,7 +164,7 @@ void bot_command_depart(Client* c, const Seperator* sep)
std::map<std::string, std::pair<uint8_t, uint8_t>> listZones; std::map<std::string, std::pair<uint8_t, uint8_t>> listZones;
for (auto bot_iter : sbl) { for (auto bot_iter : sbl) {
if (!bot_iter->IsInGroupOrRaid(tar, !single)) { if (!bot_iter->IsInGroupOrRaid(tar, nullptr, !single)) {
continue; continue;
} }
+12 -8
View File
@@ -21,7 +21,7 @@
#include "../common/repositories/bot_spells_entries_repository.h" #include "../common/repositories/bot_spells_entries_repository.h"
#include "../common/repositories/npc_spells_repository.h" #include "../common/repositories/npc_spells_repository.h"
bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, uint16 subTargetType, uint16 subType) { bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, Raid* raid, uint16 subTargetType, uint16 subType) {
if (!tar) { if (!tar) {
return false; return false;
} }
@@ -217,7 +217,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, uint16 subTarge
break; break;
} }
std::list<BotSpell_wPriority> botSpellList = GetPrioritizedBotSpellsBySpellType(this, spellType, tar, (IsAEBotSpellType(spellType) || subTargetType == CommandedSubTypes::AETarget), subTargetType, subType); std::list<BotSpell_wPriority> botSpellList = GetPrioritizedBotSpellsBySpellType(this, spellType, tar, (IsAEBotSpellType(spellType) || subTargetType == CommandedSubTypes::AETarget), raid, subTargetType, subType);
for (const auto& s : botSpellList) { for (const auto& s : botSpellList) {
@@ -651,7 +651,7 @@ bool Bot::AI_PursueCastCheck() {
continue; continue;
} }
result = AttemptAICastSpell(currentCast.spellType); result = AttemptAICastSpell(currentCast.spellType, nullptr, raid);
if (!result && IsBotSpellTypeBeneficial(currentCast.spellType)) { if (!result && IsBotSpellTypeBeneficial(currentCast.spellType)) {
result = AttemptCloseBeneficialSpells(currentCast.spellType, raid, v); result = AttemptCloseBeneficialSpells(currentCast.spellType, raid, v);
@@ -725,7 +725,7 @@ bool Bot::AI_IdleCastCheck() {
continue; continue;
} }
result = AttemptAICastSpell(currentCast.spellType); result = AttemptAICastSpell(currentCast.spellType, nullptr, raid);
if (result) { if (result) {
break; break;
@@ -784,7 +784,7 @@ bool Bot::AI_EngagedCastCheck() {
continue; continue;
} }
result = AttemptAICastSpell(currentCast.spellType); result = AttemptAICastSpell(currentCast.spellType, nullptr, raid);
if (!result && IsBotSpellTypeBeneficial(currentCast.spellType)) { if (!result && IsBotSpellTypeBeneficial(currentCast.spellType)) {
result = AttemptCloseBeneficialSpells(currentCast.spellType, raid, v); result = AttemptCloseBeneficialSpells(currentCast.spellType, raid, v);
@@ -1007,9 +1007,13 @@ std::list<BotSpell> Bot::GetBotSpellsBySpellType(Bot* botCaster, uint16 spellTyp
return result; return result;
} }
std::list<BotSpell_wPriority> Bot::GetPrioritizedBotSpellsBySpellType(Bot* botCaster, uint16 spellType, Mob* tar, bool AE, uint16 subTargetType, uint16 subType) { std::list<BotSpell_wPriority> Bot::GetPrioritizedBotSpellsBySpellType(Bot* botCaster, uint16 spellType, Mob* tar, bool AE, Raid* raid, uint16 subTargetType, uint16 subType) {
std::list<BotSpell_wPriority> result; std::list<BotSpell_wPriority> result;
if (!raid) {
raid = botCaster->GetRaid();
}
if (botCaster && botCaster->AI_HasSpells()) { if (botCaster && botCaster->AI_HasSpells()) {
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells; std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
@@ -1050,7 +1054,7 @@ std::list<BotSpell_wPriority> Bot::GetPrioritizedBotSpellsBySpellType(Bot* botCa
!RuleB(Bots, EnableBotTGB) && !RuleB(Bots, EnableBotTGB) &&
IsGroupSpell(botSpellList[i].spellid) && IsGroupSpell(botSpellList[i].spellid) &&
!IsTGBCompatibleSpell(botSpellList[i].spellid) && !IsTGBCompatibleSpell(botSpellList[i].spellid) &&
!botCaster->IsInGroupOrRaid(tar, true) !botCaster->IsInGroupOrRaid(tar, raid, true)
) { ) {
continue; continue;
} }
@@ -2009,7 +2013,7 @@ BotSpell Bot::GetBestBotSpellForResistDebuff(Bot* botCaster, Mob *tar) {
return result; return result;
} }
BotSpell Bot::GetBestBotSpellForCure(Bot* botCaster, Mob* tar, uint16 spellType) { BotSpell Bot::GetBestBotSpellForCure(Bot* botCaster, Mob* tar, uint16 spellType) { //TODO bot rewrite - add raid nd target list?
BotSpell_wPriority result; BotSpell_wPriority result;
result.SpellId = 0; result.SpellId = 0;
+16 -12
View File
@@ -9897,7 +9897,7 @@ void Mob::ClearDataBucketCache()
} }
} }
bool Mob::IsInGroupOrRaid(Mob *other, bool sameRaidGroup) { bool Mob::IsInGroupOrRaid(Mob *other, Raid* raid, bool sameRaidGroup) {
if (!other || !IsOfClientBotMerc() || !other->IsOfClientBotMerc()) { if (!other || !IsOfClientBotMerc() || !other->IsOfClientBotMerc()) {
return false; return false;
} }
@@ -9906,29 +9906,33 @@ bool Mob::IsInGroupOrRaid(Mob *other, bool sameRaidGroup) {
return true; return true;
} }
auto* r = GetRaid(); if (IsRaidGrouped() && !raid) {
auto* rO = other->GetRaid(); raid = GetRaid();
if (r) { if (!raid) {
if (!rO || r != rO) {
return false; return false;
} }
}
auto rG = r->GetGroup(GetCleanName()); if (raid) {
auto rOG = rO->GetGroup(other->GetCleanName()); if (!other->IsRaidGrouped()) {
return false;
}
auto rGroup = raid->GetGroup(GetCleanName());
auto rOGroup = raid->GetGroup(other->GetCleanName());
if (rG == RAID_GROUPLESS || rOG == RAID_GROUPLESS || (sameRaidGroup && rG != rOG)) { if (rGroup == RAID_GROUPLESS || rOGroup == RAID_GROUPLESS || (sameRaidGroup && rGroup != rOGroup)) {
return false; return false;
} }
return true; return true;
} }
else { else {
auto* g = GetGroup(); auto* group = GetGroup();
auto* gO = other->GetGroup(); auto* groupOther = other->GetGroup();
if (g) { if (group) {
if (!gO || g != gO) { if (!groupOther || group != groupOther) {
return false; return false;
} }
+1 -1
View File
@@ -779,7 +779,7 @@ public:
virtual bool HasGroup() = 0; virtual bool HasGroup() = 0;
virtual Raid* GetRaid() = 0; virtual Raid* GetRaid() = 0;
virtual Group* GetGroup() = 0; virtual Group* GetGroup() = 0;
bool IsInGroupOrRaid(Mob* other, bool sameRaidGroup = false); bool IsInGroupOrRaid(Mob* other, Raid* raid = nullptr, bool sameRaidGroup = false);
//Faction //Faction
virtual inline int32 GetPrimaryFaction() const { return 0; } virtual inline int32 GetPrimaryFaction() const { return 0; }