feat(editor): add WEMO (Emote Definition) — 101st open format

Novel replacement for the EmotesText.dbc + EmotesTextSound
+ EmotesTextData trio that maps /slash-emote commands
(/dance, /wave, /laugh, etc.) to their visible chat text,
animation ID, and per-race voice clip. Each entry binds
one slashCommand to an animationId (refs WANI), soundId
(refs WSND), targetMessage / noTargetMessage formats,
emote kind (Social / Combat / RolePlay / System), sex
filter (Both / Male / Female), required race bit, and a
TTS hint (Talk / Whisper / Yell / Silent) for accessibility
text-to-speech engines.

Three preset emitters covering the canonical emote
buckets: makeBasic (8 universal social emotes — wave /
bow / laugh / cheer / cry / sleep / kneel / applaud),
makeCombat (5 combat-themed — roar / threaten / charge /
victory / surrender), makeRolePlay (6 RP-focused — bonk
/ ponder / soothe / plead / shoo / scoff). Animation IDs
match AnimationData.dbc convention so existing WoW client
mods continue to play the right anims.

Validator catches authoring bugs unique to slash-command
parsing: leading '/' on slashCommand (chat parser strips
it before lookup so the entry would be doubly-prefixed),
uppercase letters (parser case-folds before lookup so the
entry is unreachable), duplicate slash commands (parser
dispatches by exact match — ambiguity would crash the
chat input handler), %s token counts that don't match
target/no-target distinction.

Also expanded --catalog-pluck's foreign-key filter to
include animationId / soundId / particleId / ribbonId /
vehicleId / seatId / currencyId / trainerId / vendorId /
mailTemplateId — caught during smoke-test where pluck
mis-identified WEMO entries by animationId instead of
emoteId. Same class of bug as the WHRT areaId fix.

Format count 100 -> 101. CLI flag count 1126 -> 1131.
This commit is contained in:
Kelsi 2026-05-10 00:53:33 -07:00
parent 4aa7b56e13
commit c9b822002f
11 changed files with 827 additions and 0 deletions

View file

@ -2167,6 +2167,16 @@ void printUsage(const char* argv0) {
std::printf(" Export binary .wmsp to a human-editable JSON sidecar (defaults to <base>.wmsp.json; emits all 4 enums as both int AND name string + a versionString \"x.y.z\" convenience field)\n");
std::printf(" --import-wmsp-json <json-path> [out-base]\n");
std::printf(" Import a .wmsp.json sidecar back into binary .wmsp (realmType int OR \"normal\"/\"pvp\"/\"rp\"/\"rppvp\"/\"test\"; realmCategory \"public\"/\"private\"/\"beta\"/\"dev\"; expansion \"vanilla\"/\"tbc\"/\"wotlk\"/\"cata\"; population \"low\"/\"medium\"/\"high\"/\"full\"/\"locked\")\n");
std::printf(" --gen-emo <wemo-base> [name]\n");
std::printf(" Emit .wemo 8 universal social emotes (wave / bow / laugh / cheer / cry / sleep / kneel / applaud)\n");
std::printf(" --gen-emo-combat <wemo-base> [name]\n");
std::printf(" Emit .wemo 5 combat-themed emotes (roar / threaten / charge / victory / surrender)\n");
std::printf(" --gen-emo-rp <wemo-base> [name]\n");
std::printf(" Emit .wemo 6 roleplay emotes (bonk / ponder / soothe / plead / shoo / scoff)\n");
std::printf(" --info-wemo <wemo-base> [--json]\n");
std::printf(" Print WEMO entries (id / slash command / kind / animation / sound / sex filter / TTS hint)\n");
std::printf(" --validate-wemo <wemo-base> [--json]\n");
std::printf(" Static checks: id+name+slashCommand required, slash must be lowercase + no leading '/' (chat parser case-folds before lookup), emoteKind 0..3, sex 0..2, ttsHint 0..3, no duplicate ids OR commands; warns on targetMessage with !=2 %s tokens, noTargetMessage with !=1\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(" --gen-weather-temperate <wow-base> [zoneName]\n");