feat(pipeline): add WTIT (Wowee Title catalog) format

Novel open replacement for Blizzard's CharTitles.dbc + the
AzerothCore-style character_title SQL table. The 30th open
format added to the editor.

Defines the player-display titles awarded for completing
achievements ("the Versatile"), reaching PvP ranks
("Sergeant Major" / "Stone Guard"), participating in raids
("Champion of the Naaru"), levelling a profession ("Master
Locksmith"), or seasonal events ("Brewmaster", "the
Hallowed").

Closes a long-standing gap: WACH.entry.titleReward has been
a free-form string since batch 116 with no formal catalog
to resolve against. WTIT systematizes those strings into a
real catalog — the runtime resolves WACH.titleReward to a
WTIT entry by name, then displays the titleId in the player
title selector.

Cross-references:
  WACH.entry.titleReward (string) ~= WTIT.entry.name
                                     (string match — runtime
                                      resolves achievement-
                                      granted titles by
                                      looking up matching WTIT
                                      entry by name)

Format:
  • magic "WTIT", version 1, little-endian
  • per title: titleId / name / nameMale / nameFemale /
    iconPath / prefix (suffix vs prefix display) /
    category / sortOrder

Enums:
  • Category (8): Achievement / Pvp / Raid / ClassTitle /
                   Event / Profession / Lore / Custom

API: WoweeTitleLoader::save / load / exists +
WoweeTitle::findById / findByName.

Three preset emitters showcase typical title catalogs:
  • makeStarter     — 4 titles (Versatile / Sergeant /
                       Champion / Hallowed) covering 4
                       categories
  • makePvp         — 28-title classic Honor System ladder
                       (14 Alliance ranks Private->Grand
                       Marshal + 14 Horde ranks Scout->High
                       Warlord)
  • makeAchievement — 8 achievement titles including "the
                       Versatile" matching WACH.makeMeta's
                       achievement 250 titleReward + capstone
                       profession titles

CLI added (5 flags, 608 documented total now):
  --gen-titles / --gen-titles-pvp / --gen-titles-achievement
  --info-wtit / --validate-wtit

Validator catches: titleId=0 + duplicates, empty name,
unknown category, gender variants set on only one side
(causes mixed-gender display when the runtime falls back to
canonical for the unset side).
This commit is contained in:
Kelsi 2026-05-09 17:07:56 -07:00
parent 1f808ca78b
commit eefaa5653b
8 changed files with 580 additions and 0 deletions

View file

@ -0,0 +1,105 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
namespace wowee {
namespace pipeline {
// Wowee Open Title catalog (.wtit) — novel replacement for
// Blizzard's CharTitles.dbc + the AzerothCore-style
// character_title SQL table. The 30th open format added to
// the editor.
//
// Defines the player-display titles awarded for completing
// achievements ("the Versatile"), reaching PvP ranks
// ("Sergeant Major"), participating in raids ("Champion of
// the Naaru"), levelling a class ("Master Locksmith"), or
// participating in seasonal events ("Brewmaster", "the
// Hallowed").
//
// Cross-references with previously-added formats:
// WACH.entry.titleReward (string) ≈ WTIT.entry.name
// (string match — the
// runtime resolves
// achievement-granted
// titles by looking up
// the matching WTIT
// entry by name)
//
// Binary layout (little-endian):
// magic[4] = "WTIT"
// version (uint32) = current 1
// nameLen + name (catalog label)
// entryCount (uint32)
// entries (each):
// titleId (uint32)
// nameLen + name -- canonical / English form
// maleLen + nameMale -- empty = use canonical
// femaleLen + nameFemale -- empty = use canonical
// iconLen + iconPath
// prefix (uint8) -- 0=suffix, 1=prefix
// category (uint8)
// sortOrder (uint16)
struct WoweeTitle {
enum Category : uint8_t {
Achievement = 0,
Pvp = 1,
Raid = 2,
ClassTitle = 3,
Event = 4,
Profession = 5,
Lore = 6,
Custom = 7,
};
struct Entry {
uint32_t titleId = 0;
std::string name; // canonical (genderless)
std::string nameMale; // empty = use canonical
std::string nameFemale;
std::string iconPath;
uint8_t prefix = 0; // 0 = "Name the Versatile"
uint8_t category = Achievement;
uint16_t sortOrder = 0; // display order in UI
};
std::string name;
std::vector<Entry> entries;
bool isValid() const { return !entries.empty(); }
const Entry* findById(uint32_t titleId) const;
// String match against the canonical name — used to
// resolve WACH.titleReward references.
const Entry* findByName(const std::string& name) const;
static const char* categoryName(uint8_t c);
};
class WoweeTitleLoader {
public:
static bool save(const WoweeTitle& cat,
const std::string& basePath);
static WoweeTitle load(const std::string& basePath);
static bool exists(const std::string& basePath);
// Preset emitters used by --gen-titles* variants.
//
// makeStarter — 4 titles covering Achievement / Pvp /
// Raid / Event categories.
// makePvp — 14-rank Honor System ladder
// (Private/Corporal/...Knight-Lieutenant/
// ...Field Marshal) with both Alliance
// and Horde titles where they differ.
// makeAchievement — titles granted by the WACH meta
// preset including "the Versatile"
// from achievement 250.
static WoweeTitle makeStarter(const std::string& catalogName);
static WoweeTitle makePvp(const std::string& catalogName);
static WoweeTitle makeAchievement(const std::string& catalogName);
};
} // namespace pipeline
} // namespace wowee