From 570787ff16d90dc527dbbbbcba51440906e9a6e9 Mon Sep 17 00:00:00 2001 From: SaW Date: Wed, 18 Dec 2024 18:29:35 +0100 Subject: [PATCH 01/12] Improve check to work in custom defines zones as well (#797) --- src/strategy/actions/AttackAction.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/strategy/actions/AttackAction.cpp b/src/strategy/actions/AttackAction.cpp index 3600ce66..4be5da24 100644 --- a/src/strategy/actions/AttackAction.cpp +++ b/src/strategy/actions/AttackAction.cpp @@ -105,7 +105,8 @@ bool AttackAction::Attack(Unit* target, bool with_pet /*true*/) return false; } - if (!bot->IsValidAttackTarget(target) && sPlayerbotAIConfig->IsInPvpProhibitedZone(bot->GetZoneId())) + if (sPlayerbotAIConfig->IsInPvpProhibitedZone(bot->GetZoneId()) + && (target->IsPlayer() || target->IsPet() || !bot->IsValidAttackTarget(target))) { if (verbose) botAI->TellError("I cannot attack others in PvP prohibited zones"); From a1b4681c58c2b04f6c224c07df0d7098bbf34da6 Mon Sep 17 00:00:00 2001 From: avirar Date: Thu, 19 Dec 2024 04:32:01 +1100 Subject: [PATCH 02/12] Resolved issues with rndbots and equipmentPersistence (#778) * Update PlayerbotFactory.cpp * Update PlayerbotFactory.cpp * Added !incremental checks for talent/gear init --- src/factory/PlayerbotFactory.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/factory/PlayerbotFactory.cpp b/src/factory/PlayerbotFactory.cpp index 89de2570..04f2fc9a 100644 --- a/src/factory/PlayerbotFactory.cpp +++ b/src/factory/PlayerbotFactory.cpp @@ -207,7 +207,10 @@ void PlayerbotFactory::Randomize(bool incremental) Prepare(); LOG_DEBUG("playerbots", "Resetting player..."); PerformanceMonitorOperation* pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Reset"); - bot->resetTalents(true); + if (!sPlayerbotAIConfig->equipmentPersistence || level < sPlayerbotAIConfig->equipmentPersistenceLevel) + { + bot->resetTalents(true); + } // bot->SaveToDB(false, false); ClearSkills(); // bot->SaveToDB(false, false); @@ -267,7 +270,7 @@ void PlayerbotFactory::Randomize(bool incremental) pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Talents"); LOG_DEBUG("playerbots", "Initializing talents..."); - if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel) + if (!incremental || !sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel) { InitTalentsTree(); } @@ -302,7 +305,7 @@ void PlayerbotFactory::Randomize(bool incremental) pmo = sPerformanceMonitor->start(PERF_MON_RNDBOT, "PlayerbotFactory_Equip"); LOG_DEBUG("playerbots", "Initializing equipmemt..."); - if (!sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel) + if (!incremental || !sPlayerbotAIConfig->equipmentPersistence || bot->GetLevel() < sPlayerbotAIConfig->equipmentPersistenceLevel) { InitEquipment(incremental, incremental ? false : sPlayerbotAIConfig->twoRoundsGearInit); } From 66f0cf27d3beea08c9d82211e161aa85ab269dfa Mon Sep 17 00:00:00 2001 From: SaW Date: Wed, 18 Dec 2024 23:21:50 +0100 Subject: [PATCH 03/12] Make AutoScaleActivity further configurable (#766) Make AutoScaleActivity configurable --- conf/playerbots.conf.dist | 11 ++++++++++- src/PlayerbotAI.cpp | 26 +++++++++++++++++++------- src/PlayerbotAIConfig.cpp | 9 +++++---- src/PlayerbotAIConfig.h | 7 ++++++- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 71c3a051..1e881ce8 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -1530,9 +1530,19 @@ AiPlayerbot.BotActiveAloneForceWhenInGuild = 1 # Specify smart scaling is enabled or not. # The default is 1. When enabled (smart) scales the 'BotActiveAlone' value. # Only when botLevel is between WhenMinLevel and WhenMaxLevel. +# +# AiPlayerbot.botActiveAloneDiff +# Method: 1 - Check against average Diff +# Method: 2 - Check against Max Diff (spikes) +# +# LimitFloor - No active bot decrease below this DIFF +# LimitCeiling - Max active bot decrease above this DIFF AiPlayerbot.botActiveAloneSmartScale = 1 AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel = 1 AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel = 80 +AiPlayerbot.botActiveAloneSmartScaleDiffMethod = 2 +AiPlayerbot.botActiveAloneSmartScaleDiffLimitFloor = 40 +AiPlayerbot.botActiveAloneSmartScaleDiffLimitCeiling = 150 # Premade spell to avoid (undetected spells) # spellid-radius, ... @@ -1543,7 +1553,6 @@ AiPlayerbot.MaxRandomBotsPriceChangeInterval = 172800 AiPlayerbot.MinRandomBotChangeStrategyTime = 180 AiPlayerbot.MaxRandomBotChangeStrategyTime = 720 - # How often tasks are changed AiPlayerbot.MinGuildTaskChangeTime = 172800 AiPlayerbot.MaxGuildTaskChangeTime = 432000 diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 00c84c57..fea6197f 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -4352,10 +4352,22 @@ bool PlayerbotAI::AllowActivity(ActivityType activityType, bool checkNow) uint32 PlayerbotAI::AutoScaleActivity(uint32 mod) { - uint32 maxDiff = sWorldUpdateTime.GetAverageUpdateTime(); + uint32 diffLimitFloor = sPlayerbotAIConfig->botActiveAloneSmartScaleDiffLimitFloor; + uint32 diffLimitCeil = sPlayerbotAIConfig->botActiveAloneSmartScaleDiffLimitCeiling; + uint32 chkDiff = (sPlayerbotAIConfig->botActiveAloneSmartScaleDiffMethod == 2) + ? sWorldUpdateTime.GetMaxUpdateTime() + : sWorldUpdateTime.GetAverageUpdateTime(); - if (maxDiff > 500) return 0; - if (maxDiff > 250) + if (diffLimitFloor > diffLimitCeil) + diffLimitFloor = diffLimitCeil; + + if (chkDiff <= diffLimitFloor) return mod; + if (chkDiff >= diffLimitCeil) return 0; + + uint32 diffRange = diffLimitCeil - diffLimitFloor; + double spread = (double)diffRange / 5; // Calculate the equal spread between each number /w 5 steps + + if (chkDiff > diffLimitFloor + (4 * spread)) { if (Map* map = bot->GetMap()) { @@ -4375,10 +4387,10 @@ uint32 PlayerbotAI::AutoScaleActivity(uint32 mod) return (mod * 1) / 10; } - if (maxDiff > 200) return (mod * 3) / 10; - if (maxDiff > 150) return (mod * 5) / 10; - if (maxDiff > 100) return (mod * 6) / 10; - if (maxDiff > 75) return (mod * 9) / 10; + if (chkDiff > diffLimitFloor + (3 * spread)) return (mod * 2) / 10; + if (chkDiff > diffLimitFloor + (2 * spread)) return (mod * 4) / 10; + if (chkDiff > diffLimitFloor + (1 * spread)) return (mod * 7) / 10; + if (chkDiff > diffLimitFloor + (0 * spread)) return (mod * 9) / 10; return mod; } diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index df0dd650..ef913533 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -476,10 +476,11 @@ bool PlayerbotAIConfig::Initialize() BotActiveAloneForceWhenIsFriend = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneForceWhenIsFriend", 1); BotActiveAloneForceWhenInGuild = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneForceWhenInGuild", 1); botActiveAloneSmartScale = sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScale", 1); - botActiveAloneSmartScaleWhenMinLevel = - sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel", 1); - botActiveAloneSmartScaleWhenMaxLevel = - sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel", 80); + botActiveAloneSmartScaleDiffMethod = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneSmartScaleDiffMethod", 2); + botActiveAloneSmartScaleDiffLimitFloor = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneSmartScaleDiffLimitFloor", 40); + botActiveAloneSmartScaleDiffLimitCeiling = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneSmartScaleDiffLimitCeiling", 150); + botActiveAloneSmartScaleWhenMinLevel = sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel", 1); + botActiveAloneSmartScaleWhenMaxLevel = sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel", 80); randombotsWalkingRPG = sConfigMgr->GetOption("AiPlayerbot.RandombotsWalkingRPG", false); randombotsWalkingRPGInDoors = sConfigMgr->GetOption("AiPlayerbot.RandombotsWalkingRPG.InDoors", false); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index f8d36152..919cc21d 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -263,15 +263,20 @@ public: bool disableRandomLevels; uint32 playerbotsXPrate; bool disableDeathKnightLogin; + uint32 botActiveAlone; uint32 BotActiveAloneForceWhenInRadius; bool BotActiveAloneForceWhenInZone; bool BotActiveAloneForceWhenInMap; bool BotActiveAloneForceWhenIsFriend; - bool BotActiveAloneForceWhenInGuild; + bool BotActiveAloneForceWhenInGuild; + bool botActiveAloneSmartScale; uint32 botActiveAloneSmartScaleWhenMinLevel; uint32 botActiveAloneSmartScaleWhenMaxLevel; + uint32 botActiveAloneSmartScaleDiffMethod; + uint32 botActiveAloneSmartScaleDiffLimitFloor; + uint32 botActiveAloneSmartScaleDiffLimitCeiling; bool freeMethodLoot; int32 lootRollLevel; From ea1ec98645b25142b90322595ee8a76647e63202 Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Thu, 19 Dec 2024 00:41:33 +0100 Subject: [PATCH 04/12] Revert "Make AutoScaleActivity further configurable (#766)" (#798) This reverts commit 66f0cf27d3beea08c9d82211e161aa85ab269dfa. --- conf/playerbots.conf.dist | 11 +---------- src/PlayerbotAI.cpp | 26 +++++++------------------- src/PlayerbotAIConfig.cpp | 9 ++++----- src/PlayerbotAIConfig.h | 7 +------ 4 files changed, 13 insertions(+), 40 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index 1e881ce8..71c3a051 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -1530,19 +1530,9 @@ AiPlayerbot.BotActiveAloneForceWhenInGuild = 1 # Specify smart scaling is enabled or not. # The default is 1. When enabled (smart) scales the 'BotActiveAlone' value. # Only when botLevel is between WhenMinLevel and WhenMaxLevel. -# -# AiPlayerbot.botActiveAloneDiff -# Method: 1 - Check against average Diff -# Method: 2 - Check against Max Diff (spikes) -# -# LimitFloor - No active bot decrease below this DIFF -# LimitCeiling - Max active bot decrease above this DIFF AiPlayerbot.botActiveAloneSmartScale = 1 AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel = 1 AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel = 80 -AiPlayerbot.botActiveAloneSmartScaleDiffMethod = 2 -AiPlayerbot.botActiveAloneSmartScaleDiffLimitFloor = 40 -AiPlayerbot.botActiveAloneSmartScaleDiffLimitCeiling = 150 # Premade spell to avoid (undetected spells) # spellid-radius, ... @@ -1553,6 +1543,7 @@ AiPlayerbot.MaxRandomBotsPriceChangeInterval = 172800 AiPlayerbot.MinRandomBotChangeStrategyTime = 180 AiPlayerbot.MaxRandomBotChangeStrategyTime = 720 + # How often tasks are changed AiPlayerbot.MinGuildTaskChangeTime = 172800 AiPlayerbot.MaxGuildTaskChangeTime = 432000 diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index fea6197f..00c84c57 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -4352,22 +4352,10 @@ bool PlayerbotAI::AllowActivity(ActivityType activityType, bool checkNow) uint32 PlayerbotAI::AutoScaleActivity(uint32 mod) { - uint32 diffLimitFloor = sPlayerbotAIConfig->botActiveAloneSmartScaleDiffLimitFloor; - uint32 diffLimitCeil = sPlayerbotAIConfig->botActiveAloneSmartScaleDiffLimitCeiling; - uint32 chkDiff = (sPlayerbotAIConfig->botActiveAloneSmartScaleDiffMethod == 2) - ? sWorldUpdateTime.GetMaxUpdateTime() - : sWorldUpdateTime.GetAverageUpdateTime(); + uint32 maxDiff = sWorldUpdateTime.GetAverageUpdateTime(); - if (diffLimitFloor > diffLimitCeil) - diffLimitFloor = diffLimitCeil; - - if (chkDiff <= diffLimitFloor) return mod; - if (chkDiff >= diffLimitCeil) return 0; - - uint32 diffRange = diffLimitCeil - diffLimitFloor; - double spread = (double)diffRange / 5; // Calculate the equal spread between each number /w 5 steps - - if (chkDiff > diffLimitFloor + (4 * spread)) + if (maxDiff > 500) return 0; + if (maxDiff > 250) { if (Map* map = bot->GetMap()) { @@ -4387,10 +4375,10 @@ uint32 PlayerbotAI::AutoScaleActivity(uint32 mod) return (mod * 1) / 10; } - if (chkDiff > diffLimitFloor + (3 * spread)) return (mod * 2) / 10; - if (chkDiff > diffLimitFloor + (2 * spread)) return (mod * 4) / 10; - if (chkDiff > diffLimitFloor + (1 * spread)) return (mod * 7) / 10; - if (chkDiff > diffLimitFloor + (0 * spread)) return (mod * 9) / 10; + if (maxDiff > 200) return (mod * 3) / 10; + if (maxDiff > 150) return (mod * 5) / 10; + if (maxDiff > 100) return (mod * 6) / 10; + if (maxDiff > 75) return (mod * 9) / 10; return mod; } diff --git a/src/PlayerbotAIConfig.cpp b/src/PlayerbotAIConfig.cpp index ef913533..df0dd650 100644 --- a/src/PlayerbotAIConfig.cpp +++ b/src/PlayerbotAIConfig.cpp @@ -476,11 +476,10 @@ bool PlayerbotAIConfig::Initialize() BotActiveAloneForceWhenIsFriend = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneForceWhenIsFriend", 1); BotActiveAloneForceWhenInGuild = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneForceWhenInGuild", 1); botActiveAloneSmartScale = sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScale", 1); - botActiveAloneSmartScaleDiffMethod = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneSmartScaleDiffMethod", 2); - botActiveAloneSmartScaleDiffLimitFloor = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneSmartScaleDiffLimitFloor", 40); - botActiveAloneSmartScaleDiffLimitCeiling = sConfigMgr->GetOption("AiPlayerbot.BotActiveAloneSmartScaleDiffLimitCeiling", 150); - botActiveAloneSmartScaleWhenMinLevel = sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel", 1); - botActiveAloneSmartScaleWhenMaxLevel = sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel", 80); + botActiveAloneSmartScaleWhenMinLevel = + sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMinLevel", 1); + botActiveAloneSmartScaleWhenMaxLevel = + sConfigMgr->GetOption("AiPlayerbot.botActiveAloneSmartScaleWhenMaxLevel", 80); randombotsWalkingRPG = sConfigMgr->GetOption("AiPlayerbot.RandombotsWalkingRPG", false); randombotsWalkingRPGInDoors = sConfigMgr->GetOption("AiPlayerbot.RandombotsWalkingRPG.InDoors", false); diff --git a/src/PlayerbotAIConfig.h b/src/PlayerbotAIConfig.h index 919cc21d..f8d36152 100644 --- a/src/PlayerbotAIConfig.h +++ b/src/PlayerbotAIConfig.h @@ -263,20 +263,15 @@ public: bool disableRandomLevels; uint32 playerbotsXPrate; bool disableDeathKnightLogin; - uint32 botActiveAlone; uint32 BotActiveAloneForceWhenInRadius; bool BotActiveAloneForceWhenInZone; bool BotActiveAloneForceWhenInMap; bool BotActiveAloneForceWhenIsFriend; - bool BotActiveAloneForceWhenInGuild; - + bool BotActiveAloneForceWhenInGuild; bool botActiveAloneSmartScale; uint32 botActiveAloneSmartScaleWhenMinLevel; uint32 botActiveAloneSmartScaleWhenMaxLevel; - uint32 botActiveAloneSmartScaleDiffMethod; - uint32 botActiveAloneSmartScaleDiffLimitFloor; - uint32 botActiveAloneSmartScaleDiffLimitCeiling; bool freeMethodLoot; int32 lootRollLevel; From 4e64745861c53323237ab3e58d93fa3a8c8835c0 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Thu, 19 Dec 2024 22:44:54 +0800 Subject: [PATCH 05/12] Fix JoinLFG crash --- src/strategy/actions/LfgActions.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/strategy/actions/LfgActions.cpp b/src/strategy/actions/LfgActions.cpp index fb3d008f..4a11bd3c 100644 --- a/src/strategy/actions/LfgActions.cpp +++ b/src/strategy/actions/LfgActions.cpp @@ -8,10 +8,14 @@ #include "AiFactory.h" #include "ItemVisitors.h" #include "LFGMgr.h" +#include "LFGPackets.h" +#include "Opcodes.h" #include "Playerbots.h" +#include "World.h" using namespace lfg; + bool LfgJoinAction::Execute(Event event) { return JoinLFG(); } uint32 LfgJoinAction::GetRoles() @@ -146,7 +150,19 @@ bool LfgJoinAction::JoinLFG() // Set RbotAId Browser comment std::string const _gs = std::to_string(botAI->GetEquipGearScore(bot, false, false)); - sLFGMgr->JoinLfg(bot, roleMask, list, _gs); + + WorldPacket* data = new WorldPacket(CMSG_LFG_JOIN); + *data << (uint32)roleMask; + *data << (bool)false; + *data << (bool)false; + // Slots + *data << (uint8)(list.size()); + for (uint32 dungeon : list) + *data << (uint32)dungeon; + // Needs + *data << (uint8)3 << (uint8)0 << (uint8)0 << (uint8)0; + *data << _gs; + bot->GetSession()->QueuePacket(data); return true; } From 360dc27c9c316d72ff10bb9a04746310b2ad9374 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Thu, 19 Dec 2024 22:50:59 +0800 Subject: [PATCH 06/12] Comment for threadsafe --- src/strategy/actions/LfgActions.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/strategy/actions/LfgActions.cpp b/src/strategy/actions/LfgActions.cpp index 4a11bd3c..48890077 100644 --- a/src/strategy/actions/LfgActions.cpp +++ b/src/strategy/actions/LfgActions.cpp @@ -151,6 +151,9 @@ bool LfgJoinAction::JoinLFG() // Set RbotAId Browser comment std::string const _gs = std::to_string(botAI->GetEquipGearScore(bot, false, false)); + // JoinLfg is not threadsafe, so make packet and queue into session + // sLFGMgr->JoinLfg(bot, roleMask, list, _gs); + WorldPacket* data = new WorldPacket(CMSG_LFG_JOIN); *data << (uint32)roleMask; *data << (bool)false; From 1ccde41feae239421418e440cd7f413412b22fbb Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Thu, 19 Dec 2024 22:58:26 +0800 Subject: [PATCH 07/12] Remove mark rti strats for tank warrior --- src/AiFactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index 8af2e0dd..57b4068c 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -312,7 +312,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa break; case CLASS_WARRIOR: if (tab == 2) - engine->addStrategiesNoInit("tank", "tank assist", "aoe", "mark rti", nullptr); + engine->addStrategiesNoInit("tank", "tank assist", "aoe", nullptr); else if (player->GetLevel() < 36 || tab == 0) engine->addStrategiesNoInit("arms", "aoe", "dps assist", /*"behind",*/ nullptr); else From 83369478c3387e34799a53da014609fe5de32d47 Mon Sep 17 00:00:00 2001 From: bash <31279994+hermensbas@users.noreply.github.com> Date: Thu, 19 Dec 2024 21:26:28 +0100 Subject: [PATCH 08/12] Minor updates after patches (#801) only freeze bots during init when not in combat --- src/PlayerbotAI.cpp | 50 +++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 00c84c57..2b2dfdb0 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -4135,18 +4135,27 @@ inline bool ZoneHasRealPlayers(Player* bot) bool PlayerbotAI::AllowActive(ActivityType activityType) { + // Is in combat. Always defend yourself. + if (activityType != OUT_OF_PARTY_ACTIVITY && activityType != PACKET_ACTIVITY) + { + if (bot->IsInCombat()) + { + return true; + } + } + // only keep updating till initializing time has completed, // which prevents unneeded expensive GameTime calls. - // if (_isBotInitializing) - // { - // _isBotInitializing = GameTime::GetUptime().count() < sPlayerbotAIConfig->maxRandomBots * 0.12; + if (_isBotInitializing) + { + _isBotInitializing = GameTime::GetUptime().count() < sPlayerbotAIConfig->maxRandomBots * 0.12; - // // no activity allowed during bot initialization - // if (_isBotInitializing) - // { - // return false; - // } - // } + // no activity allowed during bot initialization + if (_isBotInitializing) + { + return false; + } + } // General exceptions if (activityType == PACKET_ACTIVITY) @@ -4154,21 +4163,18 @@ bool PlayerbotAI::AllowActive(ActivityType activityType) return true; } + // when botActiveAlone is 100% and smartScale disabled + if (sPlayerbotAIConfig->botActiveAlone >= 100 && !sPlayerbotAIConfig->botActiveAloneSmartScale) + { + return true; + } + // bg, raid, dungeon if (!WorldPosition(bot).isOverworld()) { return true; } - - // Is in combat. Defend yourself. - if (activityType != OUT_OF_PARTY_ACTIVITY && activityType != PACKET_ACTIVITY) - { - if (bot->IsInCombat()) - { - return true; - } - } - + // bot map has active players. if (sPlayerbotAIConfig->BotActiveAloneForceWhenInMap) { @@ -4307,11 +4313,7 @@ bool PlayerbotAI::AllowActive(ActivityType activityType) { return false; } - if (sPlayerbotAIConfig->botActiveAlone >= 100 && !sPlayerbotAIConfig->botActiveAloneSmartScale) - { - return true; - } - + // ####################################################################################### // All mandatory conditations are checked to be active or not, from here the remaining // situations are usable for scaling when enabled. From eef41ab3b713334584c3807e6198354714a9316b Mon Sep 17 00:00:00 2001 From: kadeshar Date: Fri, 20 Dec 2024 23:04:22 +0100 Subject: [PATCH 09/12] Added worldbuff strategy --- src/strategy/StrategyContext.h | 2 ++ src/strategy/generic/NonCombatStrategy.cpp | 6 +++++- src/strategy/generic/NonCombatStrategy.h | 10 ++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/strategy/StrategyContext.h b/src/strategy/StrategyContext.h index dad46bd8..ff16df1a 100644 --- a/src/strategy/StrategyContext.h +++ b/src/strategy/StrategyContext.h @@ -119,6 +119,7 @@ public: creators["move random"] = &StrategyContext::move_random; creators["formation"] = &StrategyContext::combat_formation; creators["move from group"] = &StrategyContext::move_from_group; + creators["worldbuff"] = &StrategyContext::world_buff; } private: @@ -186,6 +187,7 @@ private: static Strategy* move_random(PlayerbotAI* ai) { return new MoveRandomStrategy(ai); } static Strategy* combat_formation(PlayerbotAI* ai) { return new CombatFormationStrategy(ai); } static Strategy* move_from_group(PlayerbotAI* botAI) { return new MoveFromGroupStrategy(botAI); } + static Strategy* world_buff(PlayerbotAI* botAI) { return new WorldBuffStrategy(botAI); } }; class MovementStrategyContext : public NamedObjectContext diff --git a/src/strategy/generic/NonCombatStrategy.cpp b/src/strategy/generic/NonCombatStrategy.cpp index c35e6168..1fa49d61 100644 --- a/src/strategy/generic/NonCombatStrategy.cpp +++ b/src/strategy/generic/NonCombatStrategy.cpp @@ -16,7 +16,6 @@ void NonCombatStrategy::InitTriggers(std::vector& triggers) // triggers.push_back(new TriggerNode("near dark portal", NextAction::array(0, new NextAction("move to dark portal", 1.0f), nullptr))); // triggers.push_back(new TriggerNode("at dark portal azeroth", NextAction::array(0, new NextAction("use dark portal azeroth", 1.0f), nullptr))); // triggers.push_back(new TriggerNode("at dark portal outland", NextAction::array(0, new NextAction("move from dark portal", 1.0f), nullptr))); - // triggers.push_back(new TriggerNode("need world buff", NextAction::array(0, new NextAction("world buff", 1.0f), nullptr))); // triggers.push_back(new TriggerNode("vehicle near", NextAction::array(0, new NextAction("enter vehicle", 10.0f), nullptr))); } @@ -33,3 +32,8 @@ void MountStrategy::InitTriggers(std::vector& triggers) nullptr)));*/ /*triggers.push_back(new TriggerNode("often", NextAction::array(0, new NextAction("mount", 4.0f), nullptr)));*/ } + +void WorldBuffStrategy::InitTriggers(std::vector& triggers) +{ + triggers.push_back(new TriggerNode("need world buff", NextAction::array(0, new NextAction("world buff", 1.0f), NULL))); +} diff --git a/src/strategy/generic/NonCombatStrategy.h b/src/strategy/generic/NonCombatStrategy.h index d032dcf4..c6f266d1 100644 --- a/src/strategy/generic/NonCombatStrategy.h +++ b/src/strategy/generic/NonCombatStrategy.h @@ -48,4 +48,14 @@ public: std::string const getName() override { return "attack tagged"; } }; +class WorldBuffStrategy : public Strategy +{ +public: + WorldBuffStrategy(PlayerbotAI* ai) : Strategy(ai) {} + + uint32 GetType() const override { return STRATEGY_TYPE_NONCOMBAT; } + void InitTriggers(std::vector& triggers) override; + std::string const getName() override { return "worldbuff"; } +}; + #endif From 99dd094a5b7095823eb3b7d45ddb66b870aff3ea Mon Sep 17 00:00:00 2001 From: SaW Date: Sat, 21 Dec 2024 13:33:47 +0100 Subject: [PATCH 10/12] Feature: Bots use flying mounts when player has flight form (#805) * Make bots use flying mounts when player goes into flight form * add && !bot->InBattleground() check * Final commit --- .../actions/CheckMountStateAction.cpp | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/strategy/actions/CheckMountStateAction.cpp b/src/strategy/actions/CheckMountStateAction.cpp index 7ae52f74..4b6c1dc8 100644 --- a/src/strategy/actions/CheckMountStateAction.cpp +++ b/src/strategy/actions/CheckMountStateAction.cpp @@ -71,14 +71,17 @@ bool CheckMountStateAction::Execute(Event event) if (!bot->GetGroup() || bot->GetGroup()->GetLeaderGUID() != master->GetGUID()) return false; + auto masterInShapeshiftForm = master->GetShapeshiftForm(); + // bool farFromMaster = sServerFacade->GetDistance2d(bot, master) > sPlayerbotAIConfig->sightDistance; - if (master->IsMounted() && !bot->IsMounted() && noattackers && shouldMount && !bot->IsInCombat() && - botAI->GetState() != BOT_STATE_COMBAT) + if ((master->IsMounted() || masterInShapeshiftForm == FORM_FLIGHT || masterInShapeshiftForm == FORM_FLIGHT_EPIC) + && !bot->IsMounted() && noattackers && shouldMount && !bot->IsInCombat() && botAI->GetState() != BOT_STATE_COMBAT) { return Mount(); } - if (!master->IsMounted() && bot->IsMounted()) + if ((!master->IsMounted() && masterInShapeshiftForm != FORM_FLIGHT && masterInShapeshiftForm != FORM_FLIGHT_EPIC) + && bot->IsMounted()) { WorldPacket emptyPacket; bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket); @@ -188,12 +191,23 @@ bool CheckMountStateAction::Mount() botAI->RemoveShapeshift(); botAI->RemoveAura("tree of life"); int32 masterSpeed = 59; + int32 masterMountType = 0; SpellInfo const* masterSpell = nullptr; - if (master && !master->GetAuraEffectsByType(SPELL_AURA_MOUNTED).empty() && !bot->InBattleground()) + if (master != nullptr && !bot->InBattleground()) { - masterSpell = master->GetAuraEffectsByType(SPELL_AURA_MOUNTED).front()->GetSpellInfo(); - masterSpeed = std::max(masterSpell->Effects[1].BasePoints, masterSpell->Effects[2].BasePoints); + auto masterInShapeshiftForm = master->GetShapeshiftForm(); + + if (!master->GetAuraEffectsByType(SPELL_AURA_MOUNTED).empty()) + { + masterSpell = master->GetAuraEffectsByType(SPELL_AURA_MOUNTED).front()->GetSpellInfo(); + masterSpeed = std::max(masterSpell->Effects[1].BasePoints, masterSpell->Effects[2].BasePoints); + } + else if (masterInShapeshiftForm == FORM_FLIGHT || masterInShapeshiftForm == FORM_FLIGHT_EPIC) + { + masterMountType = 1; + masterSpeed = (masterInShapeshiftForm == FORM_FLIGHT_EPIC) ? 279 : 149; + } } else { @@ -261,7 +275,6 @@ bool CheckMountStateAction::Mount() allSpells[index][effect].push_back(spellId); } - int32 masterMountType = 0; if (masterSpell) { masterMountType = (masterSpell->Effects[1].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED || From 8c36d0988bc486b0f612a34d3d667ccac841511c Mon Sep 17 00:00:00 2001 From: SaW Date: Sat, 21 Dec 2024 13:48:07 +0100 Subject: [PATCH 11/12] 5-8 percent performance increase when when botActiveAlone is 100% and smartScale disabled (#803) Diff-wise. By moving the when botActiveAlone is 100% and smartScale disabled return to the very top. --- src/PlayerbotAI.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 2b2dfdb0..cb9facf2 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -4135,6 +4135,12 @@ inline bool ZoneHasRealPlayers(Player* bot) bool PlayerbotAI::AllowActive(ActivityType activityType) { + // when botActiveAlone is 100% and smartScale disabled + if (sPlayerbotAIConfig->botActiveAlone >= 100 && !sPlayerbotAIConfig->botActiveAloneSmartScale) + { + return true; + } + // Is in combat. Always defend yourself. if (activityType != OUT_OF_PARTY_ACTIVITY && activityType != PACKET_ACTIVITY) { @@ -4163,12 +4169,6 @@ bool PlayerbotAI::AllowActive(ActivityType activityType) return true; } - // when botActiveAlone is 100% and smartScale disabled - if (sPlayerbotAIConfig->botActiveAlone >= 100 && !sPlayerbotAIConfig->botActiveAloneSmartScale) - { - return true; - } - // bg, raid, dungeon if (!WorldPosition(bot).isOverworld()) { From 848401be676d88bab431086157ddc44474c1aff2 Mon Sep 17 00:00:00 2001 From: SaW Date: Sat, 21 Dec 2024 17:22:06 +0100 Subject: [PATCH 12/12] Make bots use mounts when player is in travel form as well (#806) Addition to https://github.com/liyunfan1223/mod-playerbots/pull/805 --- src/strategy/actions/CheckMountStateAction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/strategy/actions/CheckMountStateAction.cpp b/src/strategy/actions/CheckMountStateAction.cpp index 4b6c1dc8..953f47c6 100644 --- a/src/strategy/actions/CheckMountStateAction.cpp +++ b/src/strategy/actions/CheckMountStateAction.cpp @@ -74,13 +74,13 @@ bool CheckMountStateAction::Execute(Event event) auto masterInShapeshiftForm = master->GetShapeshiftForm(); // bool farFromMaster = sServerFacade->GetDistance2d(bot, master) > sPlayerbotAIConfig->sightDistance; - if ((master->IsMounted() || masterInShapeshiftForm == FORM_FLIGHT || masterInShapeshiftForm == FORM_FLIGHT_EPIC) + if ((master->IsMounted() || masterInShapeshiftForm == FORM_FLIGHT || masterInShapeshiftForm == FORM_FLIGHT_EPIC || masterInShapeshiftForm == FORM_TRAVEL) && !bot->IsMounted() && noattackers && shouldMount && !bot->IsInCombat() && botAI->GetState() != BOT_STATE_COMBAT) { return Mount(); } - if ((!master->IsMounted() && masterInShapeshiftForm != FORM_FLIGHT && masterInShapeshiftForm != FORM_FLIGHT_EPIC) + if ((!master->IsMounted() && masterInShapeshiftForm != FORM_FLIGHT && masterInShapeshiftForm != FORM_FLIGHT_EPIC && masterInShapeshiftForm != FORM_TRAVEL) && bot->IsMounted()) { WorldPacket emptyPacket;