feat(editor): add WSCT (Spell Cast Time Index) open catalog format

Companion to WSRG: open replacement for SpellCastTimes.dbc plus
the per-spell castTime fields in Spell.dbc. Defines categorical
cast-time buckets (Instant 0ms / FastCast 1s / MediumCast 1.5s /
LongCast 3s) that thousands of spells reference instead of each
embedding their own ms count. Together WSRG and WSCT let the
spell engine resolve "Frostbolt's range bucket = id 3" and
"Frostbolt's cast time bucket = id 5" with two table reads
instead of duplicating per-rank data.

Cast time can scale with character level via perLevelMs (a rank-1
spell at 1000ms can grow to 2200ms at lvl 60), then the bucket
result is clamped to [minCastMs, maxCastMs] before haste is
applied. resolveAtLevel() does the math for engine consumers.

Three preset emitters: --gen-sct (4 baseline buckets),
--gen-sct-channel (3 channeled-spell durations), --gen-sct-ramp
(4 level-scaled buckets with non-zero perLevelMs). Validation
catches negative baseCastMs, min>max, duplicate ids, warns on
Instant kind with non-zero base (cast bar would still show), and
errors on Channel kind with zero base (would tick once and end).

Wired through the cross-format table; WSCT appears automatically
in all 9 cross-format utilities. Format count 68 -> 69; CLI flag
count 892 -> 897.
This commit is contained in:
Kelsi 2026-05-09 21:37:42 -07:00
parent 53611be09d
commit 8dcbd08a16
10 changed files with 649 additions and 0 deletions

View file

@ -93,6 +93,7 @@ constexpr FormatRow kFormats[] = {
{"WUMV", ".wumv", "stats", "UnitMovement.dbc + speed mods", "Unit movement type / speed catalog"},
{"WQSO", ".wqso", "quests", "QuestSort.dbc + QuestInfo cats", "Quest sort / category catalog"},
{"WSRG", ".wsrg", "spells", "SpellRange.dbc + per-spell range", "Spell range bucket catalog"},
{"WSCT", ".wsct", "spells", "SpellCastTimes.dbc + cast scaling","Spell cast time bucket catalog"},
// Additional pipeline catalogs without the alternating
// gen/info/validate CLI surface (loaded by the engine