mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-11 11:33:52 +00:00
feat(pipeline): WTSC transit schedule catalog (128th open format)
Novel replacement for the implicit taxi/zeppelin/boat scheduling
that vanilla WoW drove from a tangle of TaxiNodes.dbc +
TaxiPath.dbc + per-zeppelin GameObject scripts + hard-coded
transport interval timers in the server's MapManager. Each WTSC
entry binds one scheduled passenger route to its origin /
destination coords, vehicle type (Taxi/Zeppelin/Boat/Mount),
departure interval, in-flight duration, capacity, and faction-
access gate.
Initially designed with magic 'WTRN' but discovered collision
with existing trainers catalog (also WTRN) — renamed to 'WTSC'
(Transit SChedule) and updated all CLI flags.
Three presets:
--gen-trn-zeppelins 3 vanilla Horde zeppelin routes
(OG<->UC 240s interval, OG<->Grom'Gol,
UC<->Grom'Gol)
--gen-trn-boats 3 vanilla boat routes (Auberdine<->
Stormwind Alliance, Menethil<->Theramore
Alliance, BootyBay<->Ratchet Neutral
cross-faction)
--gen-trn-taxis 3 taxi gryphon/wyvern routes — capacity=0
indicates solo gryphon ride
CRITICAL scheduling invariant validator catches: when capacity > 0
the departureInterval MUST be >= travelDuration. A zeppelin with
interval=60s + travel=90s with capacity=40 would overflow the
vehicle pool — next zeppelin departs before prior arrives. Solo
gryphon (capacity=0) is exempt because each ride is independent.
Validator also catches: id+name+origin+destination required,
vehicleType/factionAccess range, zero intervals/travel, duplicate
routeIds, duplicate route names. Warns on same-map routes
(originMapId == destinationMapId) — preset taxi route Crossroads
to Razor Hill triggered this warning in smoke-test (both in
Kalimdor mapId=1, intentional).
Format count 127 -> 128. CLI flag count 1346 -> 1353.
This commit is contained in:
parent
2a28d3c1cd
commit
12e77e69ce
10 changed files with 838 additions and 0 deletions
158
include/pipeline/wowee_transit_schedule.hpp
Normal file
158
include/pipeline/wowee_transit_schedule.hpp
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace wowee {
|
||||
namespace pipeline {
|
||||
|
||||
// Wowee Open Transit Schedule catalog (.wtsc) —
|
||||
// novel replacement for the implicit
|
||||
// taxi/zeppelin/boat scheduling that vanilla WoW
|
||||
// drove from a tangle of TaxiNodes.dbc +
|
||||
// TaxiPath.dbc + per-zeppelin GameObject scripts +
|
||||
// hard-coded transport interval timers in the
|
||||
// server's MapManager. Each WTRN entry binds one
|
||||
// scheduled passenger route to its origin /
|
||||
// destination coordinates, vehicle type
|
||||
// (Taxi/Zeppelin/Boat/Mount), departure interval,
|
||||
// in-flight duration, capacity, and faction-access
|
||||
// gate.
|
||||
//
|
||||
// Cross-references with previously-added formats:
|
||||
// WMS: originMapId / destinationMapId reference
|
||||
// the WMS map catalog.
|
||||
// WTAX: vehicleType=Taxi routes are derived from
|
||||
// (and extend) WTAX taxi-node catalog —
|
||||
// WTRN adds the scheduling layer that WTAX
|
||||
// lacked.
|
||||
//
|
||||
// Binary layout (little-endian):
|
||||
// magic[4] = "WTSC"
|
||||
// version (uint32) = current 1
|
||||
// nameLen + name (catalog label)
|
||||
// entryCount (uint32)
|
||||
// entries (each):
|
||||
// routeId (uint32)
|
||||
// nameLen + name
|
||||
// vehicleType (uint8) — 0=Taxi /
|
||||
// 1=Zeppelin /
|
||||
// 2=Boat /
|
||||
// 3=Mount
|
||||
// factionAccess (uint8) — 0=Both /
|
||||
// 1=Alliance /
|
||||
// 2=Horde /
|
||||
// 3=Neutral
|
||||
// pad0 (uint16)
|
||||
// originLen + originName
|
||||
// originX (float)
|
||||
// originY (float)
|
||||
// originMapId (uint32)
|
||||
// destinationLen + destinationName
|
||||
// destinationX (float)
|
||||
// destinationY (float)
|
||||
// destinationMapId (uint32)
|
||||
// departureIntervalSec (uint32) — period between
|
||||
// successive
|
||||
// departures from
|
||||
// origin
|
||||
// travelDurationSec (uint32) — in-flight time
|
||||
// origin->dest
|
||||
// capacity (uint16) — max simultaneous
|
||||
// riders (0 =
|
||||
// unlimited, e.g.
|
||||
// solo gryphon)
|
||||
// pad1 (uint16)
|
||||
struct WoweeTransitSchedule {
|
||||
enum VehicleType : uint8_t {
|
||||
Taxi = 0,
|
||||
Zeppelin = 1,
|
||||
Boat = 2,
|
||||
Mount = 3, // hired riding-mount
|
||||
// (e.g., kodo
|
||||
// caravan in vanilla
|
||||
// Barrens)
|
||||
};
|
||||
|
||||
enum FactionAccess : uint8_t {
|
||||
Both = 0,
|
||||
Alliance = 1,
|
||||
Horde = 2,
|
||||
Neutral = 3, // Booty Bay-style
|
||||
// cross-faction routes
|
||||
};
|
||||
|
||||
struct Entry {
|
||||
uint32_t routeId = 0;
|
||||
std::string name;
|
||||
uint8_t vehicleType = Taxi;
|
||||
uint8_t factionAccess = Both;
|
||||
uint16_t pad0 = 0;
|
||||
std::string originName;
|
||||
float originX = 0.f;
|
||||
float originY = 0.f;
|
||||
uint32_t originMapId = 0;
|
||||
std::string destinationName;
|
||||
float destinationX = 0.f;
|
||||
float destinationY = 0.f;
|
||||
uint32_t destinationMapId = 0;
|
||||
uint32_t departureIntervalSec = 0;
|
||||
uint32_t travelDurationSec = 0;
|
||||
uint16_t capacity = 0;
|
||||
uint16_t pad1 = 0;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::vector<Entry> entries;
|
||||
|
||||
bool isValid() const { return !entries.empty(); }
|
||||
|
||||
const Entry* findById(uint32_t routeId) const;
|
||||
|
||||
// Returns all routes accessible by a given faction
|
||||
// mask (Alliance/Horde/Neutral all see Both routes;
|
||||
// a faction-specific call also includes that
|
||||
// faction's exclusive routes).
|
||||
std::vector<const Entry*> findAccessibleByFaction(
|
||||
uint8_t faction) const;
|
||||
|
||||
// Returns all routes departing from a given
|
||||
// origin map. Used by the boat-dock UI to
|
||||
// populate the "next departure" widget.
|
||||
std::vector<const Entry*> findDeparturesFromMap(
|
||||
uint32_t mapId) const;
|
||||
};
|
||||
|
||||
class WoweeTransitScheduleLoader {
|
||||
public:
|
||||
static bool save(const WoweeTransitSchedule& cat,
|
||||
const std::string& basePath);
|
||||
static WoweeTransitSchedule load(const std::string& basePath);
|
||||
static bool exists(const std::string& basePath);
|
||||
|
||||
// Preset emitters used by --gen-trn* variants.
|
||||
//
|
||||
// makeZeppelins — 3 vanilla zeppelin routes
|
||||
// (Orgrimmar<->Undercity 240s
|
||||
// interval / OG<->Grom'gol /
|
||||
// UC<->Grom'gol). All Horde-only.
|
||||
// makeBoats — 3 vanilla boat routes
|
||||
// (Auberdine<->Stormwind /
|
||||
// Menethil<->Theramore /
|
||||
// BootyBay<->Ratchet — last is
|
||||
// Neutral, both factions can
|
||||
// board).
|
||||
// makeTaxis — 3 taxi gryphon/wyvern routes
|
||||
// (Stormwind<->Ironforge
|
||||
// Alliance / Crossroads<->
|
||||
// Razor Hill Horde /
|
||||
// Booty Bay<->Stormwind
|
||||
// Neutral).
|
||||
static WoweeTransitSchedule makeZeppelins(const std::string& catalogName);
|
||||
static WoweeTransitSchedule makeBoats(const std::string& catalogName);
|
||||
static WoweeTransitSchedule makeTaxis(const std::string& catalogName);
|
||||
};
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue