feat(editor): add WSTC (Hunter Stable Slot) open catalog format

Open replacement for the hardcoded hunter pet stable slot
progression. Defines each stable slot's display order in the
stable UI, the character level at which the slot becomes
available, the gold cost to unlock, and whether it's a premium
/ donator-only slot.

In WoW 3.3.5a hunters get 5 stable slots total: the active pet
plus 4 stabled (slots 1-4 unlocking at hunter levels 10/20/30/40
with escalating gold costs 0/10s/50s/2g/10g). Cataclysm raised
the cap to 5 stabled slots, and server-custom expansions go
higher with donator-only "premium" slots that bypass the level
gate. This catalog parameterizes the entire progression instead
of editing engine source.

Consumed directly by the StableMaster service in WBKD entries.
unlockedSlotCount(characterLevel) is the engine helper used by
the stable master frame to decide how many slot tabs to render.

Three preset emitters: --gen-stc (5 canonical slots matching
WoW 3.3.5a), --gen-stc-cata (6 Cata-style slots with slot 5
unlocking at lvl 60 for 25g), --gen-stc-premium (4 server-custom
donator slots with no level/gold gate).

The info renderer pretty-prints copperCost as "free" / "10s 0c" /
"2g 0s 0c" — matches how server admins think about pricing.

Validation enforces id+name presence, no duplicate ids; warns
on:
  - minLevelToUnlock > 80 (unreachable at WotLK cap)
  - Premium slot with non-zero copperCost (donor slots are
    typically free; the gate is donor status, not gold)
  - duplicate displayOrder (stable UI position collision —
    only the first slot would render)

Wired through the cross-format table; WSTC appears in all 18
cross-format utilities. Format count 92 -> 93; CLI flag count
1069 -> 1074.
This commit is contained in:
Kelsi 2026-05-09 23:58:49 -07:00
parent 3f65e63ca1
commit 8f6f6ac91e
10 changed files with 603 additions and 0 deletions

View file

@ -2055,6 +2055,16 @@ void printUsage(const char* argv0) {
std::printf(" Export binary .whld to a human-editable JSON sidecar (defaults to <base>.whld.json)\n");
std::printf(" --import-whld-json <json-path> [out-base]\n");
std::printf(" Import a .whld.json sidecar back into binary .whld (accepts raidLockoutKind int OR raidLockoutKindName string)\n");
std::printf(" --gen-stc <wstc-base> [name]\n");
std::printf(" Emit .wstc 5 canonical hunter stable slots (Active + 4 stabled, unlocking lvl 10/20/30/40/50 with 0/10s/50s/2g/10g costs)\n");
std::printf(" --gen-stc-cata <wstc-base> [name]\n");
std::printf(" Emit .wstc 6 Cata-style slots (Active + 5 stabled), with slot 5 unlocking at lvl 60 for 25g\n");
std::printf(" --gen-stc-premium <wstc-base> [name]\n");
std::printf(" Emit .wstc 4 server-custom donator-only slots (premium=1, no level/gold gate)\n");
std::printf(" --info-wstc <wstc-base> [--json]\n");
std::printf(" Print WSTC entries (id / displayOrder / minLevelToUnlock / cost (formatted) / premium flag / name)\n");
std::printf(" --validate-wstc <wstc-base> [--json]\n");
std::printf(" Static checks: id+name required, no duplicate ids; warns on lvl>80 (unreachable), Premium+nonzero cost (donor slots are free), duplicate displayOrder (UI collision)\n");
std::printf(" --gen-weather-temperate <wow-base> [zoneName]\n");
std::printf(" Emit .wow weather schedule: clear-dominant + occasional rain + fog (forest / grassland)\n");
std::printf(" --gen-weather-arctic <wow-base> [zoneName]\n");