Compare commits

...

15 Commits

Author SHA1 Message Date
kadeshar
40874624a8
Merge pull request #1475 from EricksOliveira/patch-33
Improve Arena Bot Behavior When Target is Behind Obstacles
2025-07-31 17:25:42 +02:00
kadeshar
f76435b4c4
Merge pull request #1473 from Tierisch/master
Add option to remove 'healer dps' strategy based on specified map.
2025-07-31 16:50:06 +02:00
EricksOliveira
b7b8c60d17
Fix 2025-07-28 12:12:53 -03:00
EricksOliveira
e5f1446b9f
. 2025-07-28 12:05:22 -03:00
EricksOliveira
e92029dd6e
The bot immediately moves to a new position if the target is lost by LoS even during the cast. 2025-07-28 11:48:15 -03:00
EricksOliveira
b8c0a54f92
.. 2025-07-28 09:03:20 -03:00
EricksOliveira
18d1821dab
Fix 2025-07-28 08:57:19 -03:00
EricksOliveira
8a8571c54f
. 2025-07-28 08:45:20 -03:00
EricksOliveira
21bcbece7a
Improve Bot Repositioning Based on Line of Sight and Vertical Distance
This update enhances bot behavior by adding a check for both line of sight (LoS) and significant vertical height differences between the bot and its target. If the bot cannot see its target or if the height difference exceeds 5.0f, it calculates a valid path and moves closer to regain visibility and combat effectiveness. This resolves cases where bots would previously stand still when enemies jumped from elevated terrain or were behind obstacles.
2025-07-28 08:36:28 -03:00
EricksOliveira
8a9a833c98
fix 2025-07-27 19:31:54 -03:00
EricksOliveira
101c7f3046
. 2025-07-27 18:45:04 -03:00
EricksOliveira
d8d94f33ee
Improve Arena Bot Behavior When Target is Behind Obstacles
This update enhances bot behavior in arena scenarios by addressing the issue where bots remain idle if their target moves behind line-of-sight (LoS obstacles). The bot now attempts to reposition near the target to regain LoS instead of standing still, preventing situations where enemies can recover without pressure.

Could someone test it?
2025-07-27 18:35:43 -03:00
Spargel
66b326d79e
Merge branch 'master' into master 2025-07-27 02:57:03 -05:00
Spargel
0d8e8fbd61 Second pass for adding 'healer dps' check based on map ID. Now works when teleporting in addition to on init. 2025-07-27 02:29:07 -05:00
Spargel
64b09fd3ca First pass for adding 'healer dps' check based on map ID. 2025-07-27 01:20:57 -05:00
7 changed files with 66 additions and 8 deletions

View File

@ -809,6 +809,14 @@ AiPlayerbot.RandomBotNonCombatStrategies = ""
AiPlayerbot.CombatStrategies = "" AiPlayerbot.CombatStrategies = ""
AiPlayerbot.NonCombatStrategies = "" AiPlayerbot.NonCombatStrategies = ""
# Remove "healer dps" strategy on specified maps.
# Default: 0 (disabled)
AiPlayerbot.HealerDPSMapRestriction = 0
# List of Map IDs where "healer dps" strategy will be removed if AiPlayerbot.HealerDPSMapRestriction is enabled
# Default: (Dungeon and Raid maps) "33,34,36,43,47,48,70,90,109,129,209,229,230,329,349,389,429,1001,1004,1007,269,540,542,543,545,546,547,552,553,554,555,556,557,558,560,585,574,575,576,578,595,599,600,601,602,604,608,619,632,650,658,668,409,469,509,531,532,534,544,548,550,564,565,580,249,533,603,615,616,624,631,649,724"
AiPlayerbot.RestrictedHealerDPSMaps = "33,34,36,43,47,48,70,90,109,129,209,229,230,329,349,389,429,1001,1004,1007,269,540,542,543,545,546,547,552,553,554,555,556,557,558,560,585,574,575,576,578,595,599,600,601,602,604,608,619,632,650,658,668,409,469,509,531,532,534,544,548,550,564,565,580,249,533,603,615,616,624,631,649,724"
# #
# #
# #

View File

@ -420,7 +420,8 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa
{ {
if (sPlayerbotAIConfig->autoSaveMana) if (sPlayerbotAIConfig->autoSaveMana)
engine->addStrategy("save mana", false); engine->addStrategy("save mana", false);
engine->addStrategy("healer dps", false); if (!sPlayerbotAIConfig->IsRestrictedHealerDPSMap(player->GetMapId()))
engine->addStrategy("healer dps", false);
} }
if (facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player)) if (facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player))
{ {

View File

@ -722,6 +722,7 @@ void PlayerbotAI::HandleTeleportAck()
// SetNextCheckDelay(urand(2000, 5000)); // SetNextCheckDelay(urand(2000, 5000));
if (sPlayerbotAIConfig->applyInstanceStrategies) if (sPlayerbotAIConfig->applyInstanceStrategies)
ApplyInstanceStrategies(bot->GetMapId(), true); ApplyInstanceStrategies(bot->GetMapId(), true);
EvaluateHealerDpsStrategy();
Reset(true); Reset(true);
} }
@ -6407,3 +6408,14 @@ void PlayerbotAI::AddTimedEvent(std::function<void()> callback, uint32 delayMs)
// Every Player already owns an EventMap called m_Events // Every Player already owns an EventMap called m_Events
bot->m_Events.AddEvent(new LambdaEvent(std::move(callback)), bot->m_Events.CalculateTime(delayMs)); bot->m_Events.AddEvent(new LambdaEvent(std::move(callback)), bot->m_Events.CalculateTime(delayMs));
} }
void PlayerbotAI::EvaluateHealerDpsStrategy()
{
if (!IsHeal(bot, true))
return;
if (sPlayerbotAIConfig->IsRestrictedHealerDPSMap(bot->GetMapId()))
ChangeStrategy("-healer dps", BOT_STATE_COMBAT);
else
ChangeStrategy("+healer dps", BOT_STATE_COMBAT);
}

View File

@ -401,6 +401,7 @@ public:
void ClearStrategies(BotState type); void ClearStrategies(BotState type);
std::vector<std::string> GetStrategies(BotState type); std::vector<std::string> GetStrategies(BotState type);
void ApplyInstanceStrategies(uint32 mapId, bool tellMaster = false); void ApplyInstanceStrategies(uint32 mapId, bool tellMaster = false);
void EvaluateHealerDpsStrategy();
bool ContainsStrategy(StrategyType type); bool ContainsStrategy(StrategyType type);
bool HasStrategy(std::string const name, BotState type); bool HasStrategy(std::string const name, BotState type);
BotState GetState() { return currentState; }; BotState GetState() { return currentState; };

View File

@ -190,6 +190,15 @@ bool PlayerbotAIConfig::Initialize()
sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR); sConfigMgr->GetOption<int32>("AiPlayerbot.MaxRandomBotsPriceChangeInterval", 48 * HOUR);
randomBotJoinLfg = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinLfg", true); randomBotJoinLfg = sConfigMgr->GetOption<bool>("AiPlayerbot.RandomBotJoinLfg", true);
restrictHealerDPS = sConfigMgr->GetOption<bool>("AiPlayerbot.HealerDPSMapRestriction", false);
LoadList<std::vector<uint32>>(
sConfigMgr->GetOption<std::string>("AiPlayerbot.RestrictedHealerDPSMaps",
"33,34,36,43,47,48,70,90,109,129,209,229,230,329,349,389,429,1001,1004,"
"1007,269,540,542,543,545,546,547,552,553,554,555,556,557,558,560,585,574,"
"575,576,578,595,599,600,601,602,604,608,619,632,650,658,668,409,469,509,"
"531,532,534,544,548,550,564,565,580,249,533,603,615,616,624,631,649,724"),
restrictedHealerDPSMaps);
//////////////////////////// ICC //////////////////////////// ICC
EnableICCBuffs = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableICCBuffs", true); EnableICCBuffs = sConfigMgr->GetOption<bool>("AiPlayerbot.EnableICCBuffs", true);
@ -653,6 +662,12 @@ bool PlayerbotAIConfig::IsInPvpProhibitedArea(uint32 id)
return find(pvpProhibitedAreaIds.begin(), pvpProhibitedAreaIds.end(), id) != pvpProhibitedAreaIds.end(); return find(pvpProhibitedAreaIds.begin(), pvpProhibitedAreaIds.end(), id) != pvpProhibitedAreaIds.end();
} }
bool PlayerbotAIConfig::IsRestrictedHealerDPSMap(uint32 mapId) const
{
return restrictHealerDPS &&
std::find(restrictedHealerDPSMaps.begin(), restrictedHealerDPSMaps.end(), mapId) != restrictedHealerDPSMaps.end();
}
std::string const PlayerbotAIConfig::GetTimestampStr() std::string const PlayerbotAIConfig::GetTimestampStr()
{ {
time_t t = time(nullptr); time_t t = time(nullptr);

View File

@ -402,6 +402,10 @@ public:
static std::vector<std::vector<uint32>> ParseTempTalentsOrder(uint32 cls, std::string temp_talents_order); static std::vector<std::vector<uint32>> ParseTempTalentsOrder(uint32 cls, std::string temp_talents_order);
static std::vector<std::vector<uint32>> ParseTempPetTalentsOrder(uint32 spec, std::string temp_talents_order); static std::vector<std::vector<uint32>> ParseTempPetTalentsOrder(uint32 spec, std::string temp_talents_order);
bool restrictHealerDPS = false;
std::vector<uint32> restrictedHealerDPSMaps;
bool IsRestrictedHealerDPSMap(uint32 mapId) const;
}; };
#define sPlayerbotAIConfig PlayerbotAIConfig::instance() #define sPlayerbotAIConfig PlayerbotAIConfig::instance()

View File

@ -26,6 +26,7 @@
#include "Playerbots.h" #include "Playerbots.h"
#include "PositionValue.h" #include "PositionValue.h"
#include "PvpTriggers.h" #include "PvpTriggers.h"
#include "PathGenerator.h"
#include "ServerFacade.h" #include "ServerFacade.h"
#include "Vehicle.h" #include "Vehicle.h"
@ -4152,7 +4153,6 @@ bool ArenaTactics::Execute(Event event)
if (bot->isMoving()) if (bot->isMoving())
return false; return false;
// startup phase // startup phase
if (bg->GetStartDelayTime() > 0) if (bg->GetStartDelayTime() > 0)
return false; return false;
@ -4163,12 +4163,29 @@ bool ArenaTactics::Execute(Event event)
if (botAI->HasStrategy("buff", BOT_STATE_NON_COMBAT)) if (botAI->HasStrategy("buff", BOT_STATE_NON_COMBAT))
botAI->ChangeStrategy("-buff", BOT_STATE_NON_COMBAT); botAI->ChangeStrategy("-buff", BOT_STATE_NON_COMBAT);
// this causes bot to reset constantly in arena Unit* target = bot->GetVictim();
// if (sBattlegroundMgr->IsArenaType(bg->GetBgTypeID())) if (target)
// { {
// botAI->ResetStrategies(false); bool losBlocked = !bot->IsWithinLOSInMap(target) || fabs(bot->GetPositionZ() - target->GetPositionZ()) > 5.0f;
// botAI->SetMaster(nullptr);
// } if (losBlocked)
{
PathGenerator path(bot);
path.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
if (path.GetPathType() != PATHFIND_NOPATH)
{
// If you are casting a spell and lost your target due to LoS, interrupt the cast and move
if (bot->IsNonMeleeSpellCast(false, true, true, false, true))
bot->InterruptNonMeleeSpells(true);
float x, y, z;
target->GetPosition(x, y, z);
botAI->TellMasterNoFacing("Repositioning to exit the LoS target!");
return MoveTo(target->GetMapId(), x + frand(-1, +1), y + frand(-1, +1), z, false, true);
}
}
}
if (!bot->IsInCombat()) if (!bot->IsInCombat())
return moveToCenter(bg); return moveToCenter(bg);