Titre « Mercenaire » obligatoire sur tous les playerbots

CharTitles.db2 (7.3.5) ne contient aucun titre « Mercenaire » : 364 entrees,
ID max 522, MaskID max 373. On cree donc l entree custom 600 / MaskID 380
dans la table `char_titles` de la base hotfix, poussee au client par une
ligne `hotfix_data` (TableHash CharTitles = 0x85DF9E8E).

PlayerBotMgr::ApplyBotTitle() accorde puis selectionne ce titre a chaque
connexion de bot, depuis OnPlayerBotLogin(). Un bot ne peut donc pas s en
defaire, et les vrais joueurs les reconnaissent d un coup d oeil.

Cle de configuration pbottitle (600 par defaut, 0 = aucun titre force).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
SylvaniaCore deploy
2026-08-16 00:15:23 +02:00
parent b448747b3b
commit 65dacb0de7
4 changed files with 69 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
-- =====================================================================
-- Sylvania Legion — Titre custom « Mercenaire » pour les PlayerBots
-- Base : dc_hotfixes
--
-- CharTitles.db2 (7.3.5, build 26972) : 364 enregistrements,
-- ID max = 522, MaskID max = 373. MAX_TITLE_INDEX du core = 384.
-- On prend donc un ID hors plage Blizzard (600) et un MaskID libre (380).
--
-- La ligne hotfix_data est indispensable : c'est elle qui pousse
-- l'enregistrement au client (SMSG_AVAILABLE_HOTFIXES -> CMSG_HOTFIX_REQUEST).
-- TableHash CharTitles = 0x85DF9E8E = 2246024846.
-- =====================================================================
DELETE FROM `char_titles` WHERE `ID` = 600;
INSERT INTO `char_titles` (`ID`, `Name`, `Name1`, `MaskID`, `Flags`, `VerifiedBuild`) VALUES
(600, 'Mercenaire %s', 'Mercenaire %s', 380, 0, 0);
DELETE FROM `hotfix_data` WHERE `TableHash` = 2246024846 AND `RecordId` = 600;
INSERT INTO `hotfix_data` (`TableHash`, `RecordId`, `Deleted`) VALUES
(2246024846, 600, 0);
@@ -1194,9 +1194,45 @@ void PlayerBotMgr::OnAccountBotDelete(ObjectGuid& guid, uint32 accountId)
pInfo->RemoveCharacterByGUID(guid);
}
// Titre obligatoire des playerbots.
// Tous les bots portent le titre custom 芦 Mercenaire 禄 (CharTitles 600 /
// MaskID 380, pousse au client par la table hotfix `char_titles`), afin que
// les vrais joueurs les distinguent d'un coup d'oeil. Le titre est accorde
// puis selectionne a chaque connexion : un bot ne peut donc pas s'en defaire.
void PlayerBotMgr::ApplyBotTitle(Player* pPlayer)
{
if (!pPlayer)
return;
uint32 titleId = uint32(sConfigMgr->GetIntDefault("pbottitle", 600));
if (!titleId)
return;
CharTitlesEntry const* title = sCharTitlesStore.LookupEntry(titleId);
if (!title)
{
static bool s_titleWarned = false;
if (!s_titleWarned)
{
s_titleWarned = true;
TC_LOG_ERROR("server.loading", "PlayerBotMgr: titre de bot %u absent de CharTitles - verifier la table `char_titles` de la base hotfix", titleId);
}
return;
}
if (!pPlayer->HasTitle(title))
pPlayer->SetTitle(title);
if (pPlayer->GetUInt32Value(PLAYER_CHOSEN_TITLE) != uint32(title->MaskID))
pPlayer->SetUInt32Value(PLAYER_CHOSEN_TITLE, uint32(title->MaskID));
}
void PlayerBotMgr::OnPlayerBotLogin(WorldSession* pSession, Player* pPlayer)
{
++m_BotOnlineCount;
ApplyBotTitle(pPlayer);
Group* pGroup = pPlayer->GetGroup();
if (pGroup)
{
+1
View File
@@ -325,6 +325,7 @@ public:
void OnAccountBotCreate(ObjectGuid const& guid, uint32 accountId, std::string const& name, uint8 gender, uint8 race, uint8 playerClass, uint8 level);
void OnAccountBotDelete(ObjectGuid& guid, uint32 accountId);
void OnPlayerBotLogin(WorldSession* pSession, Player* pPlayer);
void ApplyBotTitle(Player* pPlayer);
void OnPlayerBotLogout(WorldSession* pSession);
void OnPlayerBotLeaveOriginalGroup(Player* pPlayer);
void LoginGroupBotByPlayer(Player* pPlayer);
@@ -4653,6 +4653,18 @@ pbotbg_idlelogout = 300
pbotasl = 88
#
# pbottitle
# Description: ID CharTitles du titre porte obligatoirement par tous les
# playerbots, pour les distinguer des vrais joueurs.
# 600 = « Mercenaire », entree custom fournie par la table
# `char_titles` de la base hotfix (MaskID 380).
# Default: 600 - (titre Mercenaire)
# 0 - (aucun titre force)
pbottitle = 600
#
####################################################################################################
###################################################################################################