feat(editor): add WSCD (Spell Cooldown Category) open catalog format

Open replacement for SpellCooldown.dbc plus the per-spell
category-cooldown fields in Spell.dbc. Defines the shared-cooldown
buckets that related spells reference: casting one spell triggers
a cooldown on every other spell in the same bucket. Mage Polymorph
variants (Sheep / Pig / Turtle / Cat) all share one bucket so
morphing a target locks all variants at once. Healing potions and
mana potions share the SharedWithItems bucket so consuming one
locks the other.

Distinct from WSDR (which times how long an aura stays on a
target) — WSCD times how long before a spell can be cast again.
The global cooldown (GCD) is itself just one bucket of this kind,
flagged with OnGCDStart so the engine triggers it at cast start
rather than cast finish.

Three preset emitters: --gen-cdb (4 baseline buckets including
GCD), --gen-cdb-class (5 mage-specific class cooldowns including
the Polymorph family), --gen-cdb-items (5 item cooldowns
including the heal/mana potion shared bucket and the 60min
Hearthstone family). Validation enforces id+name presence,
bucketKind 0..4, no duplicate ids, and warns on Global without
OnGCDStart (engine wouldn't trigger on cast start) and Spell
kind with SharedWithItems (contradictory).

categoryFlags is a bitfield (AffectedByHaste / SharedWithItems /
OnGCDStart / IgnoresCooldownReduction); --info-wscd decodes the
bits to label list. Wired through the cross-format table; WSCD
appears automatically in all 9 cross-format utilities. Format
count 70 -> 71; CLI flag count 907 -> 912.
This commit is contained in:
Kelsi 2026-05-09 21:49:13 -07:00
parent 824b6ebf53
commit 493db026dd
10 changed files with 645 additions and 0 deletions

View file

@ -1731,6 +1731,16 @@ void printUsage(const char* argv0) {
std::printf(" Export binary .wsdr to a human-editable JSON sidecar (defaults to <base>.wsdr.json)\n");
std::printf(" --import-wsdr-json <json-path> [out-base]\n");
std::printf(" Import a .wsdr.json sidecar back into binary .wsdr (accepts durationKind int OR durationKindName string)\n");
std::printf(" --gen-cdb <wscd-base> [name]\n");
std::printf(" Emit .wscd starter: 4 baseline cooldown buckets (GlobalCooldown 1.5s / ShortItem 5s / MediumItem 30s / LongItem 60s shared)\n");
std::printf(" --gen-cdb-class <wscd-base> [name]\n");
std::printf(" Emit .wscd 5 mage class buckets (Polymorph family / AlterTime 90s / Counterspell 24s / Blink 15s / IceBlock 5min)\n");
std::printf(" --gen-cdb-items <wscd-base> [name]\n");
std::printf(" Emit .wscd 5 item buckets (HealingPot+ManaPot 60s shared / ManaJade GCD-only / EngineerTrinket 60s / Hearthstone 60min)\n");
std::printf(" --info-wscd <wscd-base> [--json]\n");
std::printf(" Print WSCD entries (id / kind / cooldownMs / category flags / name) — flags decoded as label list\n");
std::printf(" --validate-wscd <wscd-base> [--json]\n");
std::printf(" Static checks: id+name required, bucketKind 0..4, no duplicate ids; warns on Global without OnGCDStart and Spell with SharedWithItems\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");