From 3e215636694c93c77af48a458da33fd7849ab6cc Mon Sep 17 00:00:00 2001 From: Keleborn <22352763+Celandriel@users.noreply.github.com> Date: Fri, 23 Jan 2026 11:36:57 -0800 Subject: [PATCH] Create Flightmastercache to handle finding the nearest flight master. (#1979) Refactor the flightmastercache the bots use for finding the nearest available flight master. I made a small change to how the original function worked by storing the database position for the flightmaster in the cache itself. This allows us to calculate the distance from bot before accessing the creature object, should be faster overall. --- src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp | 18 +-------- src/Bot/RandomPlayerbotMgr.cpp | 11 +++--- src/Bot/RandomPlayerbotMgr.h | 3 +- src/Db/FlightMasterCache.cpp | 39 ++++++++++++++++++++ src/Db/FlightMasterCache.h | 27 ++++++++++++++ 5 files changed, 74 insertions(+), 24 deletions(-) create mode 100644 src/Db/FlightMasterCache.cpp create mode 100644 src/Db/FlightMasterCache.h diff --git a/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp b/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp index f61c2b33..4898d7e3 100644 --- a/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp +++ b/src/Ai/World/Rpg/Action/NewRpgBaseAction.cpp @@ -3,6 +3,7 @@ #include "BroadcastHelper.h" #include "ChatHelper.h" #include "Creature.h" +#include "FlightMasterCache.h" #include "G3D/Vector2.h" #include "GameObject.h" #include "GossipDef.h" @@ -968,22 +969,7 @@ WorldPosition NewRpgBaseAction::SelectRandomCampPos(Player* bot) bool NewRpgBaseAction::SelectRandomFlightTaxiNode(ObjectGuid& flightMaster, uint32& fromNode, uint32& toNode) { - const std::vector& flightMasters = IsAlliance(bot->getRace()) - ? sRandomPlayerbotMgr->allianceFlightMasterCache - : sRandomPlayerbotMgr->hordeFlightMasterCache; - Creature* nearestFlightMaster = nullptr; - for (const uint32& guid : flightMasters) - { - Creature* flightMaster = ObjectAccessor::GetSpawnedCreatureByDBGUID(bot->GetMapId(), guid); - if (!flightMaster) - continue; - - if (bot->GetMapId() != flightMaster->GetMapId()) - continue; - - if (!nearestFlightMaster || bot->GetDistance(nearestFlightMaster) > bot->GetDistance(flightMaster)) - nearestFlightMaster = flightMaster; - } + Creature* nearestFlightMaster = sFlightMasterCache->GetNearestFlightMaster(bot); if (!nearestFlightMaster || bot->GetDistance(nearestFlightMaster) > 500.0f) return false; diff --git a/src/Bot/RandomPlayerbotMgr.cpp b/src/Bot/RandomPlayerbotMgr.cpp index 0e579fb4..4d589ef1 100644 --- a/src/Bot/RandomPlayerbotMgr.cpp +++ b/src/Bot/RandomPlayerbotMgr.cpp @@ -26,6 +26,7 @@ #include "DatabaseEnv.h" #include "Define.h" #include "FleeManager.h" +#include "FlightMasterCache.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "GuildMgr.h" @@ -2002,14 +2003,12 @@ void RandomPlayerbotMgr::PrepareTeleportCache() bool forAlliance = !(entry->hostileMask & 2); if (tNpcflag & UNIT_NPC_FLAG_FLIGHTMASTER) { + WorldPosition pos(mapId, x, y, z, orient); if (forHorde) - { - hordeFlightMasterCache.push_back(guid); - } + sFlightMasterCache->AddHordeFlightMaster(guid, pos); + if (forAlliance) - { - allianceFlightMasterCache.push_back(guid); - } + sFlightMasterCache->AddAllianceFlightMaster(guid, pos); } const AreaTableEntry* area = sAreaTableStore.LookupEntry(map->GetAreaId(PHASEMASK_NORMAL, x, y, z)); uint32 zoneId = area->zone ? area->zone : area->ID; diff --git a/src/Bot/RandomPlayerbotMgr.h b/src/Bot/RandomPlayerbotMgr.h index d3178345..26d09d45 100644 --- a/src/Bot/RandomPlayerbotMgr.h +++ b/src/Bot/RandomPlayerbotMgr.h @@ -171,8 +171,7 @@ public: std::map> locsPerLevelCache; std::map> allianceStarterPerLevelCache; std::map> hordeStarterPerLevelCache; - std::vector allianceFlightMasterCache; - std::vector hordeFlightMasterCache; + struct LevelBracket { uint32 low; uint32 high; diff --git a/src/Db/FlightMasterCache.cpp b/src/Db/FlightMasterCache.cpp new file mode 100644 index 00000000..c708e09c --- /dev/null +++ b/src/Db/FlightMasterCache.cpp @@ -0,0 +1,39 @@ +#include "FlightMasterCache.h" + +void FlightMasterCache::AddHordeFlightMaster(uint32 entry, WorldPosition pos) +{ + hordeFlightMasterCache[entry] = pos; +} + +void FlightMasterCache::AddAllianceFlightMaster(uint32 entry, WorldPosition pos) +{ + allianceFlightMasterCache[entry] = pos; +} + +Creature* FlightMasterCache::GetNearestFlightMaster(Player* bot) +{ + std::map& flightMasterCache = + (bot->GetTeamId() == ALLIANCE) ? allianceFlightMasterCache : hordeFlightMasterCache; + + Creature* nearestFlightMaster = nullptr; + float nearestDistance = std::numeric_limits::max(); + + for (auto const& [entry, pos] : flightMasterCache) + { + if (pos.GetMapId() == bot->GetMapId()) + { + float distance = bot->GetExactDist2dSq(pos); + if (distance < nearestDistance) + { + Creature* flightMaster = ObjectAccessor::GetSpawnedCreatureByDBGUID(bot->GetMapId(), entry); + if (flightMaster) + { + nearestDistance = distance; + nearestFlightMaster = flightMaster; + } + } + } + } + + return nearestFlightMaster; +} diff --git a/src/Db/FlightMasterCache.h b/src/Db/FlightMasterCache.h new file mode 100644 index 00000000..519d6fc7 --- /dev/null +++ b/src/Db/FlightMasterCache.h @@ -0,0 +1,27 @@ +#ifndef _PLAYERBOT_FLIGHTMASTER_H +#define _PLAYERBOT_FLIGHTMASTER_H + +#include "Creature.h" +#include "Player.h" +#include "TravelMgr.h" + +class FlightMasterCache +{ +public: + static FlightMasterCache* Instance() + { + static FlightMasterCache instance; + return &instance; + } + + Creature* GetNearestFlightMaster(Player* bot); + void AddHordeFlightMaster(uint32 entry, WorldPosition pos); + void AddAllianceFlightMaster(uint32 entry, WorldPosition pos); + +private: + std::map allianceFlightMasterCache; + std::map hordeFlightMasterCache; +}; + +#define sFlightMasterCache FlightMasterCache::Instance() +#endif