Fix taxi node names and add flight path cost display

TaxiNodes.dbc name was read from field 6 (Korean locale, empty) instead
of field 5 (enUS). Add BFS-based cost computation from TaxiPath.dbc
edges and display gold/silver/copper next to each destination.
This commit is contained in:
Kelsi 2026-02-07 19:04:15 -08:00
parent 0d94bca896
commit 8bdf0a2e79
3 changed files with 55 additions and 2 deletions

View file

@ -482,6 +482,7 @@ public:
uint32_t cost = 0;
};
const std::unordered_map<uint32_t, TaxiNode>& 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<uint32_t, uint32_t> taxiCostMap_; // destNodeId -> total cost in copper
void buildTaxiCostMap();
// Vendor
bool vendorWindowOpen = false;

View file

@ -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<uint32_t, std::vector<AdjEntry>> 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<uint32_t> 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;

View file

@ -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<int>(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);