Mercenaires : trois correctifs issus de l audit du module

1. La re-resolution des sorts passait par une file qui la jetait.

Le correctif 19c0cf03 poussait un BGSType_DelayLevelup apres la creation
de l IA de groupe. Mesure sur quatre mercenaires : deux repares, deux
non. En cause PushScheduleToQueue, qui jette silencieusement une tache
si une du meme type est deja en file, et -- pour ce type precisement --
si IsSettingFinish() est faux. La reparation ne partait qu au hasard.

On appelle desormais OnLevelupToBotAI() directement. L IA de groupe
vient d etre creee : le dynamic_cast qui l ouvre aboutit forcement.

2. Le raccourci de mise en place renvoyait des mercenaires nus.

Signale en jeu : « Kaerbrus n a meme pas d equipement ». Constate en
base : niveau 110, 76 sorts, zero piece portee.

ProcessSetting court-circuite le re-level d un bot deja au bon niveau,
avec ses talents et la bonne specialisation -- et saute du meme coup les
etapes d habillage. Un bot ayant perdu son equipement ne le retrouvait
jamais : a chaque embauche le raccourci concluait que tout allait bien.

On verifie donc qu il porte au moins dix pieces avant de couper.

3. Le rappel n intervenait qu au-dela de 160 metres.

Mesure : au moment d un « !attack », deux des quatre mercenaires se
trouvaient a 100 et 106 metres de leur employeur. Sous le seuil de
rappel, ils acceptaient l ordre et partaient A PIED -- une quinzaine de
secondes de marche, le combat fini avant leur arrivee. Vu du joueur, le
mercenaire « refuse d attaquer ».

Ce seuil convient a un bot de terrain, pas a un membre de groupe. Ramene
a deux fois la portee de recherche, soit 64 metres : bien au-dela des 32
ou l IA engage et des 28 de portee des sorts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
BlaMacfly
2026-09-11 13:25:34 +02:00
parent 7f0c3a5453
commit 65d5978f4a
3 changed files with 85 additions and 10 deletions
+24 -1
View File
@@ -405,7 +405,30 @@ bool PlayerBotSession::ProcessSetting(BotGlobleSchedule& schedule)
// heritage de l epoque ou LearnTalents() etait un corps vide.
PlayerTalentMap const* talents = player->GetTalentMap(player->GetActiveTalentGroup());
bool const hasTalents = talents && talents->size() >= player->CalculateTalentsTiers();
if (hasTalents && (schedule.parameter3 >= 4 || (player->FindTalentType() + 1 == schedule.parameter3)))
// SIGNALE EN JEU : « Kaerbrus n a meme pas d equipement ».
// Constate en base : niveau 110, 76 sorts, ZERO piece portee.
//
// Ce raccourci evite un re-level complet a un bot deja au bon
// niveau, avec ses talents et la bonne specialisation. Mais il
// saute du meme coup les etapes 6 a 10 de UpdateReset(), qui sont
// justement l habillage. Un mercenaire ayant perdu son equipement
// -- contrat precedent interrompu, re-level avorte -- ne le
// retrouvait donc JAMAIS : a chaque embauche, le raccourci
// concluait que tout allait bien et le renvoyait nu.
//
// On verifie donc qu il est reellement habille avant de couper.
// Dix pieces sur les dix-neuf emplacements : de quoi distinguer un
// bot equipe d un bot depouille, sans exiger un sans-faute (la
// seconde babiole et l arme de jet manquent souvent, legitimement).
uint32 piecesPortees = 0;
for (uint8 emplacement = EQUIPMENT_SLOT_START; emplacement < EQUIPMENT_SLOT_END; ++emplacement)
if (player->GetItemByPos(INVENTORY_SLOT_BAG_0, emplacement))
++piecesPortees;
bool const correctementEquipe = (piecesPortees >= 10);
if (hasTalents && correctementEquipe &&
(schedule.parameter3 >= 4 || (player->FindTalentType() + 1 == schedule.parameter3)))
return true;
}
}