feat(editor): add WTBD (Tabard Design / Heraldry) — 103rd open format

Novel replacement for the GuildBankTabard / TabardConfig
blob that vanilla WoW stores per-guild in guild_member
SQL. Each entry is one tabard design: triplet of
(background pattern + color, border pattern + color,
emblem glyph + color), plus optional guild and creator
attribution and a server-approval flag for tabard-
moderation policies.

Five background patterns (Solid / Gradient / Chevron /
Quartered / Starburst), four border patterns (None /
Thin / Thick / Decorative), and 1024 possible emblem
glyph IDs. Three preset emitters demonstrate the
convention: makeAllianceClassic (4 Alliance-themed
system tabards: Lion, DwarvenHammer, KulTirasAnchor,
HighlordSword), makeHordeClassic (4 Horde: Wolfhead,
CrossedAxes, Skull, Pyramid), makeFactionVendor (6
faction-rep tabards spanning Argent Crusade, Ebon
Blade, Sons of Hodir, Wyrmrest Accord, Kalu'ak,
Frenzyheart Tribe).

Validator's most novel check is a color-similarity
heuristic — squared RGB distance between background and
emblem colors. If under 1500 (empirically derived
threshold for visual readability), warns the operator
that the emblem won't be readable against its
background. Also catches alpha=0 on any color layer
(would render fully transparent), pattern enum out-of-
range, and emblemId>1023 (beyond canonical glyph
range).

Also added per-magic explicit primary-key override to
--catalog-pluck and --catalog-find so they pick the
right field for catalogs where the heuristic fails.
WTBD has creatorPlayerId/emblemId/guildId all
alphabetically before tabardId, and guildId can't be
filtered globally because WGLD uses it as a primary
key. The override table is small (1 entry currently —
WTBD->tabardId) and grows only when a new format
catches the same conflict.

Format count 102 -> 103. CLI flag count 1141 -> 1146.
This commit is contained in:
Kelsi 2026-05-10 01:24:46 -07:00
parent 2d78dd57a7
commit 0f4c619b49
12 changed files with 863 additions and 2 deletions

View file

@ -2195,6 +2195,16 @@ void printUsage(const char* argv0) {
std::printf(" Export binary .wbab to a human-editable JSON sidecar (defaults to <base>.wbab.json; emits statBonusKind as int+name and targetTypeMask as both int AND \"self+party+raid\" join string)\n");
std::printf(" --import-wbab-json <json-path> [out-base]\n");
std::printf(" Import a .wbab.json sidecar back into binary .wbab (statBonusKind int OR \"stamina\"/\"intellect\"/\"spirit\"/\"allstats\"/\"armor\"/\"spellpower\"/\"attackpower\"/\"critrating\"/\"hasterating\"/\"manaregen\"/\"other\"; targetTypeMask int OR \"+\"-joined tokens \"self\"/\"party\"/\"raid\"/\"friendly\")\n");
std::printf(" --gen-tbd <wtbd-base> [name]\n");
std::printf(" Emit .wtbd 4 Alliance-themed system tabards (Lion / DwarvenHammer / KulTirasAnchor / HighlordSword)\n");
std::printf(" --gen-tbd-horde <wtbd-base> [name]\n");
std::printf(" Emit .wtbd 4 Horde-themed system tabards (OrgrimmarWolfhead / BarrensCrossedAxes / ForsakenSkull / SilvermoonPyramid)\n");
std::printf(" --gen-tbd-faction <wtbd-base> [name]\n");
std::printf(" Emit .wtbd 6 faction-rep tabards (Argent Crusade / Ebon Blade / Sons of Hodir / Wyrmrest / Kalu'ak / Frenzyheart)\n");
std::printf(" --info-wtbd <wtbd-base> [--json]\n");
std::printf(" Print WTBD entries (id / bg-pattern / border / emblem / guild / approval state / name)\n");
std::printf(" --validate-wtbd <wtbd-base> [--json]\n");
std::printf(" Static checks: id+name required, backgroundPattern 0..4, borderPattern 0..3, no duplicate ids; warns on emblemId>1023, alpha=0 on any color layer (transparent), and emblem-vs-background color similarity (squared RGB distance < 1500 — emblem unreadable)\n");
std::printf(" --catalog-pluck <wXXX-file> <id> [--json]\n");
std::printf(" Extract one entry by id from any registered catalog format. Auto-detects magic, dispatches to the per-format --info-* handler internally, then prints just the matching entry. Primary-key field is auto-detected (first *Id field, or first numeric)\n");
std::printf(" --catalog-find <directory> <id> [--magic <WXXX>] [--json]\n");