From ca54cff6f522bd70eba5078f3ea804abf4309e94 Mon Sep 17 00:00:00 2001 From: Keleborn <22352763+Celandriel@users.noreply.github.com> Date: Sat, 4 Apr 2026 04:00:01 -0700 Subject: [PATCH] Bug fix. Edge case where bots would get stuck in cities. (#2269) ## Pull Request Description When I refactored flight destinations, I wanted to make where bots go more intentional. so I made it dependent on the allianceHubsPerLevelCache and hodeHubsPerLevelCache. This system relied on there being an innkeeper in each area that the bots would fly to. However, not every zone has an innkeeper, and so there was an odd situation where bots had nowhere to fly to. (Most notably at level 53.) This solves that by hardcoding the flightmasters in those areas into the cache. I also put back in the city teleport probability check which was forcing every bot to teleport to a city on level up. ## Feature Evaluation - Describe the **minimum logic** required to achieve the intended behavior. - Describe the **processing cost** when this logic executes across many bots. ## How to Test the Changes ## Impact Assessment - Does this change increase per-bot/per-tick processing or risk scaling poorly with thousands of bots? - - [x] No, not at all - - [ ] Minimal impact (**explain below**) - - [ ] Moderate impact (**explain below**) - Does this change modify default bot behavior? - - [x] No - - [ ] Yes (**explain why**) - Does this change add new decision branches or increase maintenance complexity? - - [x] No - - [ ] Yes (**explain below**) ## Messages to Translate - Does this change add bot messages to translate? - - [x] No - - [ ] Yes (**list messages in the table**) | Message key | Default message | | --------------- | ------------------ | | | | | | | ## AI Assistance - Was AI assistance used while working on this change? - - [ ] No - - [x] Yes (**explain below**) Debugging and comments. ## Final Checklist - - [x] Stability is not compromised. - - [x] Performance impact is understood, tested, and acceptable. - - [x] Added logic complexity is justified and explained. - - [x] Documentation updated if needed (Conf comments, WiKi commands). ## Notes for Reviewers --- src/Bot/RandomPlayerbotMgr.cpp | 13 ++++++++----- src/Mgr/Travel/TravelMgr.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/Bot/RandomPlayerbotMgr.cpp b/src/Bot/RandomPlayerbotMgr.cpp index 3fea369a5..a772136e7 100644 --- a/src/Bot/RandomPlayerbotMgr.cpp +++ b/src/Bot/RandomPlayerbotMgr.cpp @@ -1768,13 +1768,16 @@ void RandomPlayerbotMgr::RandomTeleportForLevel(Player* bot) if (bot->InBattleground()) return; - std::vector locs = sTravelMgr.GetCityLocations(bot); - if (!locs.empty()) + if (bot->GetLevel() >= 10 && urand(0, 100) < sPlayerbotAIConfig.probTeleToBankers * 100) { - RandomTeleport(bot, locs, true); - return; + std::vector locs = sTravelMgr.GetCityLocations(bot); + if (!locs.empty()) + { + RandomTeleport(bot, locs, true); + return; + } } - locs = sTravelMgr.GetTeleportLocations(bot); + std::vector locs = sTravelMgr.GetTeleportLocations(bot); if (!locs.empty()) { RandomTeleport(bot, locs, false); diff --git a/src/Mgr/Travel/TravelMgr.cpp b/src/Mgr/Travel/TravelMgr.cpp index 7a5ac4f2e..1868bc2e3 100644 --- a/src/Mgr/Travel/TravelMgr.cpp +++ b/src/Mgr/Travel/TravelMgr.cpp @@ -4419,6 +4419,7 @@ std::vector> TravelMgr::GetOptimalFlightDestinations(Player* bot->GetTeamId()); if (!fromNode) return validDestinations; + std::vector candidateLocations; if (bot->GetLevel() >= 10 && urand(0, 100) < sPlayerbotAIConfig.probTeleToBankers * 100) candidateLocations = GetCityLocations(bot); @@ -4673,6 +4674,31 @@ void TravelMgr::PrepareDestinationCache() if (forAlliance) allianceFlightMasterCache[guid] = pos; flightMastersCount++; + + // Zones that have flight masters but no innkeepers — use flight master as hub + static const std::set zonesWithoutInnkeeper = { + 4, // Blasted Lands (52-57) + 16, // Azshara (45-52) + 28, // Western Plaguelands (50-60) + 46, // Burning Steppes (51-60) + 51, // Searing Gorge (45-51) + 361, // Felwood (47-57) + 490, // Un'Goro Crater (49-56) + 2817, // Crystalsong Forest (77-80) + 4197 // Wintergrasp (79-80) + }; + if (zonesWithoutInnkeeper.count(areaId)) + { + LevelBracket bracket = zone2LevelBracket[areaId]; + WorldPosition loc(mapId, x + cos(orient) * 5.0f, y + sin(orient) * 5.0f, z + 0.5f, orient + M_PI); + for (int i = bracket.low; i <= bracket.high; i++) + { + if (forHorde) + hordeHubsPerLevelCache[i].push_back(loc); + if (forAlliance) + allianceHubsPerLevelCache[i].push_back(loc); + } + } } else if (creatureTemplate->npcflag & UNIT_NPC_FLAG_INNKEEPER) {