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 <noreply@anthropic.com>
This commit is contained in:
SylvaniaCore deploy
2026-08-12 23:52:39 +02:00
parent a7b1fa7843
commit abb14c4b19
5 changed files with 43 additions and 1 deletions
@@ -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())
@@ -91,6 +91,7 @@ private:
AIWaypoint* pTargetAIWP;
int32 m_MovementTick;
uint32 m_TargetLockTick = 0;
uint32 m_FlagTargetTick = 0;
uint32 lastPathfindSure;
uint32 m_LastSyncTick;
};
@@ -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<PlayerBotSession*>(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();
@@ -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;
@@ -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;