mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-10 02:53:51 +00:00
feat(pipeline): add WTAX (Wowee Taxi catalog) format
Novel open replacement for Blizzard's TaxiNodes.dbc +
TaxiPath.dbc + TaxiPathNode.dbc. The 24th open format
added to the editor.
Defines the flight-master network: a set of named nodes
(positions on the world map) plus the paths between them
(sequences of waypoints with per-segment delay and a
per-path gold cost). The same file holds both node and
path lists — flat arrays keyed by id, with intra-format
references from path.fromNodeId / toNodeId to node.nodeId.
Cross-references:
WCRT.entry (with FlightMaster npcFlag) ~= WTAX.nodeId
(matched by world
position; flight
master NPCs stand
at their nodes)
WTAX.path.fromNodeId / toNodeId -> WTAX.entry.nodeId
(intra-format graph)
Format:
• magic "WTAX", version 1, little-endian
• nodes (each): nodeId / mapId / name / iconPath /
position / faction restrictions
• paths (each): pathId / from+toNodeId / moneyCostCopper /
waypoints[] each with position + per-waypoint delaySec
API: WoweeTaxiLoader::save / load / exists +
WoweeTaxi::findNode / findPath / findPathBetween.
Three preset emitters showcase different graph shapes:
• makeStarter — 2 nodes + 2 paths (round-trip)
• makeRegion — 4 nodes at a 500m square + 4-path
directed ring (NW->NE->SE->SW->NW)
• makeContinent — 6 nodes hub-spoke + 3 perimeter
shortcuts; intermediate waypoints
climb to altitude 120m for visual
arc effect
CLI added (5 flags, 564 documented total now):
--gen-taxi / --gen-taxi-region / --gen-taxi-continent
--info-wtax / --validate-wtax
Validator catches: nodeId/pathId=0 + duplicates, empty node
name, non-finite positions, fromNodeId == toNodeId
(self-loop path), path references to non-existent nodes
(intra-format cross-reference resolution), negative
waypoint delays.
This commit is contained in:
parent
efc27ba7d2
commit
3b107459b2
8 changed files with 752 additions and 0 deletions
113
include/pipeline/wowee_taxi.hpp
Normal file
113
include/pipeline/wowee_taxi.hpp
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace wowee {
|
||||
namespace pipeline {
|
||||
|
||||
// Wowee Open Taxi catalog (.wtax) — novel replacement for
|
||||
// Blizzard's TaxiNodes.dbc + TaxiPath.dbc + TaxiPathNode.dbc.
|
||||
// The 24th open format added to the editor.
|
||||
//
|
||||
// Defines the flight-master network: a set of named nodes
|
||||
// (positions on the world map) plus the paths between them
|
||||
// (sequences of waypoints with per-segment delay and a
|
||||
// per-path gold cost). The same file holds both node and
|
||||
// path lists — flat arrays keyed by id.
|
||||
//
|
||||
// Cross-references with previously-added formats:
|
||||
// WCRT.entry (with FlightMaster npcFlag) ≈ WTAX.entry.nodeId
|
||||
// (matched by world
|
||||
// position, not by
|
||||
// direct ID — the
|
||||
// flight-master NPC
|
||||
// stands at the node)
|
||||
// WTAX.path.fromNodeId / toNodeId → WTAX.entry.nodeId
|
||||
// (intra-format graph)
|
||||
//
|
||||
// Binary layout (little-endian):
|
||||
// magic[4] = "WTAX"
|
||||
// version (uint32) = current 1
|
||||
// nameLen + name (catalog label)
|
||||
// nodeCount (uint32)
|
||||
// nodes (each):
|
||||
// nodeId (uint32)
|
||||
// mapId (uint32)
|
||||
// nameLen + name
|
||||
// iconLen + iconPath
|
||||
// position (3 × float)
|
||||
// factionAlliance (uint32) / factionHorde (uint32)
|
||||
// pathCount (uint32)
|
||||
// paths (each):
|
||||
// pathId (uint32)
|
||||
// fromNodeId (uint32) / toNodeId (uint32)
|
||||
// moneyCostCopper (uint32)
|
||||
// waypointCount (uint32)
|
||||
// waypoints (waypointCount × {
|
||||
// position (3 × float)
|
||||
// delaySec (float)
|
||||
// })
|
||||
struct WoweeTaxi {
|
||||
struct Node {
|
||||
uint32_t nodeId = 0;
|
||||
uint32_t mapId = 0;
|
||||
std::string name;
|
||||
std::string iconPath;
|
||||
glm::vec3 position{0};
|
||||
uint32_t factionAlliance = 0; // 0 = available to all
|
||||
uint32_t factionHorde = 0;
|
||||
};
|
||||
|
||||
struct Waypoint {
|
||||
glm::vec3 position{0};
|
||||
float delaySec = 0.0f; // pause at this waypoint
|
||||
};
|
||||
|
||||
struct Path {
|
||||
uint32_t pathId = 0;
|
||||
uint32_t fromNodeId = 0;
|
||||
uint32_t toNodeId = 0;
|
||||
uint32_t moneyCostCopper = 0;
|
||||
std::vector<Waypoint> waypoints;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::vector<Node> nodes;
|
||||
std::vector<Path> paths;
|
||||
|
||||
bool isValid() const { return !nodes.empty(); }
|
||||
|
||||
// Lookup helpers.
|
||||
const Node* findNode(uint32_t nodeId) const;
|
||||
const Path* findPath(uint32_t pathId) const;
|
||||
// First path matching a from→to pair, or nullptr.
|
||||
const Path* findPathBetween(uint32_t fromNodeId, uint32_t toNodeId) const;
|
||||
};
|
||||
|
||||
class WoweeTaxiLoader {
|
||||
public:
|
||||
static bool save(const WoweeTaxi& cat,
|
||||
const std::string& basePath);
|
||||
static WoweeTaxi load(const std::string& basePath);
|
||||
static bool exists(const std::string& basePath);
|
||||
|
||||
// Preset emitters used by --gen-taxi* variants.
|
||||
//
|
||||
// makeStarter — 2 nodes + 1 path (round-trip 2 cities,
|
||||
// 3 waypoints, 50 silver each way).
|
||||
// makeRegion — 4 nodes around a square (~500m apart) +
|
||||
// 4 paths forming a connected ring
|
||||
// (each path is 2 waypoints).
|
||||
// makeContinent — 6 nodes + 8 paths covering a small
|
||||
// continent's flight network with
|
||||
// cross-route shortcuts.
|
||||
static WoweeTaxi makeStarter(const std::string& catalogName);
|
||||
static WoweeTaxi makeRegion(const std::string& catalogName);
|
||||
static WoweeTaxi makeContinent(const std::string& catalogName);
|
||||
};
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue