From abb14c4b198d93e5a26789172e58d64eb62858d8 Mon Sep 17 00:00:00 2001 From: SylvaniaCore deploy Date: Wed, 12 Aug 2026 23:52:39 +0200 Subject: [PATCH] BG BotFill : priorite des ordres de banniere + nettoyage des BG deserts 1. ProcessRegulation appelait TryOccupied* (cible = banniere) puis Process*Requirement (cible = centre de la base) toutes les 500 ms : le second ecrasait le premier, les bots stationnaient a quelques metres des bannieres sans jamais les atteindre (zero capture constatee en jeu). Un ordre de banniere/drapeau prime desormais 20 s sur un ordre de position, dans les deux surcharges d AcceptCommand. 2. Distance de cast resserree a 4 m (le sort d ouverture 21651 echoue au-dela de sa portee). 3. Un BG sans joueur reel depuis plus d une minute renvoie ses bots au monde : un match Ile des Conquerants tournait a 40v39 bots pour personne. Co-Authored-By: Claude Fable 5 --- .../game/AI/PlayerAI/BotBGAIMovement.cpp | 13 +++++++++ src/server/game/AI/PlayerAI/BotBGAIMovement.h | 1 + .../game/Battlegrounds/Battleground.cpp | 27 +++++++++++++++++++ src/server/game/Battlegrounds/Battleground.h | 1 + .../Battlegrounds/CommandBG/CommandAB.cpp | 2 +- 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/server/game/AI/PlayerAI/BotBGAIMovement.cpp b/src/server/game/AI/PlayerAI/BotBGAIMovement.cpp index d21f7c3..2e9dcfa 100644 --- a/src/server/game/AI/PlayerAI/BotBGAIMovement.cpp +++ b/src/server/game/AI/PlayerAI/BotBGAIMovement.cpp @@ -189,6 +189,13 @@ void BotBGAIMovement::AcceptCommand(AIWaypoint* targetAIWP, bool isFlag) TC_LOG_ERROR("server.worldserver", "BGF-DBG: AcceptCommand #%u wp=%s", s_dbgAccept, targetAIWP ? "oui" : "NULL"); if (!targetAIWP) return; + // SylvaniaCore (module BG BotFill): un ordre de banniere/drapeau en cours n est pas + // ecrase par un ordre de position. ProcessRegulation appelait TryOccupied* (cible = + // banniere) puis Process*Requirement (cible = centre de la base) toutes les 500 ms : + // le second annulait le premier et les bots n approchaient jamais des bannieres. + if (!isFlag && m_IsFlagTarget && !targetGuid.IsEmpty() + && m_FlagTargetTick && GetMSTimeDiffToNow(m_FlagTargetTick) < 20000) + return; if (pTargetAIWP) { if (targetAIWP->entry == pTargetAIWP->entry && m_IsFlagTarget == isFlag) @@ -214,6 +221,12 @@ void BotBGAIMovement::AcceptCommand(AIWaypoint* targetAIWP, bool isFlag) void BotBGAIMovement::AcceptCommand(ObjectGuid guid, bool isFlag) { + // SylvaniaCore (module BG BotFill): idem, un ordre de banniere en cours prime + if (!isFlag && m_IsFlagTarget && !targetGuid.IsEmpty() && guid != targetGuid + && m_FlagTargetTick && GetMSTimeDiffToNow(m_FlagTargetTick) < 20000) + return; + if (isFlag) + m_FlagTargetTick = getMSTime(); m_IsFlagTarget = isFlag; targetGuid = guid; if (!targetGuid.IsEmpty()) diff --git a/src/server/game/AI/PlayerAI/BotBGAIMovement.h b/src/server/game/AI/PlayerAI/BotBGAIMovement.h index 4582c52..8dc8cba 100644 --- a/src/server/game/AI/PlayerAI/BotBGAIMovement.h +++ b/src/server/game/AI/PlayerAI/BotBGAIMovement.h @@ -91,6 +91,7 @@ private: AIWaypoint* pTargetAIWP; int32 m_MovementTick; uint32 m_TargetLockTick = 0; + uint32 m_FlagTargetTick = 0; uint32 lastPathfindSure; uint32 m_LastSyncTick; }; diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 12cee8e..c54f1e1 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -206,6 +206,32 @@ void Battleground::Update(uint32 diff) _ProcessProgress(diff); else if (m_PrematureCountDown) m_PrematureCountDown = false; + + // SylvaniaCore (module BG BotFill): un BG desert par les joueurs reels ne doit + // pas continuer entre bots (jusqu a 40v40 pendant 25 min de CPU pour personne). + // Passe la minute d entree, si plus aucun joueur reel n est present, on renvoie + // les bots au monde ; le BG se vide et se termine de lui-meme. + m_BotOnlyCheckTimer += diff; + if (m_BotOnlyCheckTimer >= 10 * IN_MILLISECONDS) + { + m_BotOnlyCheckTimer = 0; + if (GetElapsedTime() > MINUTE * IN_MILLISECONDS && !ExistRealPlayer() && !GetPlayers().empty()) + { + TC_LOG_INFO("bg.battleground", "BG BotFill: bg %u instance %u sans joueur reel -> renvoi des %u bots", + uint32(GetTypeID()), GetInstanceID(), uint32(GetPlayers().size())); + for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr) + { + Player* botPlayer = ObjectAccessor::FindPlayer(itr->first); + if (!botPlayer || !botPlayer->IsPlayerBot()) + continue; + if (PlayerBotSession* botSession = dynamic_cast(botPlayer->GetSession())) + { + BotGlobleSchedule leaveSchedule(BotGlobleScheduleType::BGSType_LeaveBG, 0); + botSession->PushScheduleToQueue(leaveSchedule); + } + } + } + } } break; case STATUS_WAIT_LEAVE: @@ -1165,6 +1191,7 @@ void Battleground::AddPlayer(Player* player) m_Players[player->GetGUID()] = bp; UpdatePlayersCountByTeam(team, false); // +1 player + TC_LOG_ERROR("server.worldserver", "BGF-DBG: AddPlayer %s bot=%u team=%u -> A=%u H=%u", player->GetName().c_str(), uint32(player->IsPlayerBot()), team, GetPlayersCountByTeam(ALLIANCE), GetPlayersCountByTeam(HORDE)); WorldPackets::Battleground::BattlegroundPlayerJoined playerJoined; playerJoined.Guid = player->GetGUID(); diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 8afd124..0db0b6b 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -651,6 +651,7 @@ class TC_GAME_API Battleground // Start location uint32 m_MapId; BattlegroundMap* m_Map; + uint32 m_BotOnlyCheckTimer = 0; // SylvaniaCore (module BG BotFill) Position StartPosition[BG_TEAMS_COUNT]; float m_StartMaxDist; uint32 ScriptId; diff --git a/src/server/game/Battlegrounds/CommandBG/CommandAB.cpp b/src/server/game/Battlegrounds/CommandBG/CommandAB.cpp index 6043eaa..0c1387a 100644 --- a/src/server/game/Battlegrounds/CommandBG/CommandAB.cpp +++ b/src/server/game/Battlegrounds/CommandBG/CommandAB.cpp @@ -317,7 +317,7 @@ void CommandAB::TryOccupiedABNode(ObjectGuid guid) // SylvaniaCore (module BG BotFill): hors de portee d interaction -> on marche vers la // banniere (ordre prioritaire type drapeau) au lieu de lancer un sort qui echouera float flagDist = player->GetDistance(pFlag); - if (flagDist > 8.0f) + if (flagDist > 4.0f) { pBotAI->GetAIMovement()->AcceptCommand(pFlag->GetGUID(), true); return;