diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 77862560..458858cb 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -482,6 +482,7 @@ public: uint32_t cost = 0; }; const std::unordered_map& getTaxiNodes() const { return taxiNodes_; } + uint32_t getTaxiCostTo(uint32_t destNodeId) const; // Vendor void openVendor(uint64_t npcGuid); @@ -856,6 +857,8 @@ private: bool onTaxiFlight_ = false; uint32_t knownTaxiMask_[12] = {}; // Track previously known nodes for discovery alerts bool taxiMaskInitialized_ = false; // First SMSG_SHOWTAXINODES seeds mask without alerts + std::unordered_map taxiCostMap_; // destNodeId -> total cost in copper + void buildTaxiCostMap(); // Vendor bool vendorWindowOpen = false; diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index cf7989dd..0e870b2d 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -4016,7 +4016,7 @@ void GameHandler::loadTaxiDbc() { auto* am = core::Application::getInstance().getAssetManager(); if (!am || !am->isInitialized()) return; - // Load TaxiNodes.dbc: 0=ID, 1=mapId, 2=x, 3=y, 4=z, 6=name + // Load TaxiNodes.dbc: 0=ID, 1=mapId, 2=x, 3=y, 4=z, 5=name(enUS locale) auto nodesDbc = am->loadDBC("TaxiNodes.dbc"); if (nodesDbc && nodesDbc->isLoaded()) { for (uint32_t i = 0; i < nodesDbc->getRecordCount(); i++) { @@ -4026,7 +4026,7 @@ void GameHandler::loadTaxiDbc() { node.x = nodesDbc->getFloat(i, 2); node.y = nodesDbc->getFloat(i, 3); node.z = nodesDbc->getFloat(i, 4); - node.name = nodesDbc->getString(i, 6); + node.name = nodesDbc->getString(i, 5); if (node.id > 0) { taxiNodes_[node.id] = std::move(node); } @@ -4089,6 +4089,7 @@ void GameHandler::handleShowTaxiNodes(network::Packet& packet) { taxiNpcGuid_ = data.npcGuid; taxiWindowOpen_ = true; gossipWindowOpen = false; + buildTaxiCostMap(); LOG_INFO("Taxi window opened, nearest node=", data.nearestNode); } @@ -4113,6 +4114,42 @@ void GameHandler::closeTaxi() { taxiWindowOpen_ = false; } +void GameHandler::buildTaxiCostMap() { + taxiCostMap_.clear(); + uint32_t startNode = currentTaxiData_.nearestNode; + if (startNode == 0) return; + + // Build adjacency list with costs from known edges + struct AdjEntry { uint32_t node; uint32_t cost; }; + std::unordered_map> adj; + for (const auto& edge : taxiPathEdges_) { + if (currentTaxiData_.isNodeKnown(edge.fromNode) && currentTaxiData_.isNodeKnown(edge.toNode)) { + adj[edge.fromNode].push_back({edge.toNode, edge.cost}); + } + } + + // BFS from startNode, accumulating costs along the path + std::deque queue; + queue.push_back(startNode); + taxiCostMap_[startNode] = 0; + + while (!queue.empty()) { + uint32_t cur = queue.front(); + queue.pop_front(); + for (const auto& next : adj[cur]) { + if (taxiCostMap_.find(next.node) == taxiCostMap_.end()) { + taxiCostMap_[next.node] = taxiCostMap_[cur] + next.cost; + queue.push_back(next.node); + } + } + } +} + +uint32_t GameHandler::getTaxiCostTo(uint32_t destNodeId) const { + auto it = taxiCostMap_.find(destNodeId); + return (it != taxiCostMap_.end()) ? it->second : 0; +} + void GameHandler::activateTaxi(uint32_t destNodeId) { if (!socket || state != WorldState::IN_WORLD) return; diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 93393518..4fd01cc5 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -3393,8 +3393,21 @@ void GameScreen::renderTaxiWindow(game::GameHandler& gameHandler) { if (node.mapId != currentMapId) continue; if (!taxiData.isNodeKnown(nodeId)) continue; + uint32_t costCopper = gameHandler.getTaxiCostTo(nodeId); + uint32_t gold = costCopper / 10000; + uint32_t silver = (costCopper / 100) % 100; + uint32_t copper = costCopper % 100; + ImGui::PushID(static_cast(nodeId)); ImGui::Text("%s", node.name.c_str()); + ImGui::SameLine(); + if (gold > 0) { + ImGui::TextColored(ImVec4(0.9f, 0.8f, 0.3f, 1.0f), "(%ug %us %uc)", gold, silver, copper); + } else if (silver > 0) { + ImGui::TextColored(ImVec4(0.75f, 0.75f, 0.75f, 1.0f), "(%us %uc)", silver, copper); + } else { + ImGui::TextColored(ImVec4(0.72f, 0.45f, 0.2f, 1.0f), "(%uc)", copper); + } ImGui::SameLine(ImGui::GetWindowWidth() - 60); if (ImGui::SmallButton("Fly")) { gameHandler.activateTaxi(nodeId);