From f160420d70414a4d580610dbb0667c5879096034 Mon Sep 17 00:00:00 2001 From: oskov Date: Fri, 20 Mar 2026 21:42:07 +0200 Subject: [PATCH] Fix/talent tree ordered map (#2222) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #2050 InitTalents builds a map of talentRow → [TalentEntry*] and iterates it to teach talents row by row. WoW's talent system requires each row to be filled before unlocking the next, so iteration must happen in ascending row order. Commit b474dc4 ("Performance optim") changed the container from std::map to std::unordered_map, which has no guaranteed key ordering. As a result, bots would frequently attempt to learn talents in a row whose prerequisites hadn't been met yet, silently skipping them. I belive it's the reason of #2050 issue. The fix is a one-character type change: restoring std::map, which guarantees ascending key (row) order. How to Test the Changes 1. Make fresh installation 2. Create new character 3. Observe talents tree of fresh rnd bots Was AI assistance used while working on this change? - [X] Yes — GitHub Copilot CLI was used to identify the root cause (unordered_map introduced in b474dc4 breaking talent row ordering), stage the one-line fix, and draft this PR description. The code change was reviewed and fully understood before submission. Root cause commit: b474dc44bb6323430a84fc17c1ec046f9919a101 ("Performance optim") — changed std::map to std::unordered_map in InitTalents, breaking the row-ordering guarantee that WoW's talent prerequisite system depends on. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Bot/Factory/PlayerbotFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bot/Factory/PlayerbotFactory.cpp b/src/Bot/Factory/PlayerbotFactory.cpp index c0e6d80db..506ad9154 100644 --- a/src/Bot/Factory/PlayerbotFactory.cpp +++ b/src/Bot/Factory/PlayerbotFactory.cpp @@ -762,7 +762,7 @@ void PlayerbotFactory::InitPetTalents() // pet_family->petTalentType); return; } - std::unordered_map> spells; + std::map> spells; bool diveTypePet = (1LL << ci->family) & diveMask; for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) @@ -2653,7 +2653,7 @@ void PlayerbotFactory::InitSpecialSpells() void PlayerbotFactory::InitTalents(uint32 specNo) { uint32 classMask = bot->getClassMask(); - std::unordered_map> spells; + std::map> spells; for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i) { TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);