Kelsidavis-WoWee/tools/editor/cli_arg_required.cpp

573 lines
28 KiB
C++
Raw Normal View History

#include "cli_arg_required.hpp"
namespace wowee {
namespace editor {
namespace cli {
const char* const kArgRequired[] = {
"--data", "--info", "--info-batches", "--info-textures", "--info-doodads",
"--info-attachments", "--info-particles", "--info-sequences",
"--info-bones", "--export-bones-dot",
"--list-zone-meshes", "--list-zone-audio", "--list-zone-textures",
"--list-project-meshes", "--list-project-audio",
"--list-project-textures",
"--info-zone-models-total", "--info-project-models-total",
"--list-zone-meshes-detail", "--list-project-meshes-detail", "--info-mesh",
"--info-mesh-storage-budget", "--info-mesh-stats",
"--info-wob", "--info-wob-stats", "--info-woc", "--info-wot",
"--info-wol", "--info-wol-at", "--validate-wol", "--gen-light",
"--gen-light-cave", "--gen-light-dungeon", "--gen-light-night",
"--export-wol-json", "--import-wol-json",
"--export-wow-json", "--import-wow-json",
"--info-wow", "--validate-wow",
"--validate-wom",
"--gen-world-map", "--gen-world-map-instance",
"--gen-world-map-arena",
"--info-womx", "--validate-womx",
"--export-womx-json", "--import-womx-json",
"--gen-sound-catalog", "--gen-sound-catalog-ambient",
"--gen-sound-catalog-tavern",
"--info-wsnd", "--validate-wsnd",
"--export-wsnd-json", "--import-wsnd-json",
feat(pipeline): add WSPN (Wowee Spawn Point catalog) format Novel open replacement for AzerothCore-style scattered creature_template / gameobject SQL spawn tables PLUS the ADT MDDF / MODF doodad-placement chunks. The 11th open format, and the first that covers the live world-content side (atmosphere + sounds + spawns now form the runtime "what fills this zone" picture). A WSPN file holds all spawn points for a zone in a single table, with kind discriminating creature vs game object vs static doodad. The same format powers: • server runtime — knows what NPCs / objects to spawn • editor — draws spawn markers • renderer — reads the doodad subset directly to draw static props without going through a server roundtrip Format: • magic "WSPN", version 1, little-endian • per entry: kind / entryId / position(3f) / rotation(3f) / scale / flags / respawnSec / factionId / questIdRequired / wanderRadius / label Flags packed: disabled (0x01), event-only (0x02), quest-phased (0x04). Reserved bits for future per-entry encoding extensions. API: WoweeSpawnsLoader::save / load / exists; presets makeStarter (1 each kind), makeCamp (4-bandit ring + chest + 2 tents), makeVillage (6 NPCs + 2 signs + 4 corner trees). CLI added (5 flags, 473 documented total now): --gen-spawns / --gen-spawns-camp / --gen-spawns-village --info-wspn / --validate-wspn Validator catches: out-of-range kind, NaN/inf coords, non-positive scale, doodad with non-zero respawn (static prop misuse), creature with respawn=0 (won't respawn after kill), entryId=0 (orphan reference). All 3 presets save / load / re-validate clean. Doodad and game-object entries explicitly set wanderRadius=0 so the generated catalogs are noise-free.
2026-05-09 14:57:53 -07:00
"--gen-spawns", "--gen-spawns-camp", "--gen-spawns-village",
"--info-wspn", "--validate-wspn",
"--export-wspn-json", "--import-wspn-json",
feat(pipeline): add WIT (Wowee Item Template) format Novel open replacement for Blizzard's Item.dbc + ItemDisplayInfo.dbc + the SQL item_template tables that AzerothCore-style servers store item definitions in. The 12th open format added to the editor. A WIT file holds the catalog of all items in a content pack: weapons, armor, consumables, quest items, trade goods. Each entry pairs gameplay metadata (stats, level reqs, flags, weapon damage / speed) with display metadata (displayId for icon / model, quality color), so the runtime can render inventory tooltips and equip slots from a single load. Format: • magic "WITM", version 1, little-endian • per item: itemId / displayId / quality / itemClass / itemSubClass / inventoryType / flags / requiredLevel / itemLevel / sellPrice / buyPrice / maxStack / durability / damageMin / damageMax / attackSpeedMs / statCount + stats[] / name / description Enums: • Quality: Poor..Heirloom (8 levels) • Class: Consumable, Weapon, Armor, Quest, ... (13) • InventoryType: Head..Cloak..Weapon2H (18 slots) • Flags: Unique, BoP, BoE, QuestItem, Conjured, ... • StatType: Stamina, Strength, Intellect, Defense, ... API: WoweeItemLoader::save / load / exists / findById; presets makeStarter (4-item demo), makeWeapons (5 items common -> legendary), makeArmor (6-piece mail set with BoE flag). CLI added (5 flags, 480 documented total now): --gen-items / --gen-items-weapons / --gen-items-armor --info-wit / --validate-wit Validator catches: itemId=0, duplicate itemIds, weapons with 0 damage or attackSpeed, weapons with non-weapon slot, equippables with durability=0 or maxStack>1, sell price >= buy price (vendor would lose money), out-of-range quality. All 3 presets save / load / re-validate clean. Info-table output includes a gold/silver/copper price formatter for hand-readability.
2026-05-09 15:04:48 -07:00
"--gen-items", "--gen-items-weapons", "--gen-items-armor",
"--info-wit", "--validate-wit",
"--export-wit-json", "--import-wit-json",
feat(pipeline): add WLOT (Wowee Loot Table) format Novel open replacement for AzerothCore-style creature_loot_template / gameobject_loot_template SQL tables. The 13th open format added to the editor. Pairs naturally with the WIT item catalog from the preceding commit: each loot drop's itemId references an entry in a WIT file, so a content pack ships both the item definitions and the loot tables that reference them. The runtime composes WIT + WLOT + WSPN to drive the full "creature dies, drops items" flow without any SQL. Format: • magic "WLOT", version 1, little-endian • per table: creatureId / flags / dropCount / moneyMin..Max / itemDropCount + drops[] • per drop: itemId / chancePercent (float, 0..100) / minQty / maxQty / drop_flags Table flags: QuestOnly, GroupOnly, Pickpocket Drop flags: QuestRequired, GroupRollOnly, AlwaysDrop dropCount is the slot budget — how many distinct drops to roll per kill. Each item drop is rolled independently against its chancePercent (so dropCount=2 with 4 candidate drops at varying chances gives the classic "up to 2 distinct items per kill" behavior). Drops with the AlwaysDrop flag bypass the slot budget — used for guaranteed quest items. API: WoweeLootLoader::save / load / exists / findByCreatureId; presets makeStarter (1 table, 1 drop), makeBandit (4 candidates, dropCount=2, matches the camp spawns from WSPN at creatureId=1000), makeBoss (6 candidates including guaranteed quest item via AlwaysDrop and a group-only epic at 5%). CLI added (5 flags, 486 documented total now): --gen-loot / --gen-loot-bandit / --gen-loot-boss --info-wlot / --validate-wlot Validator catches: creatureId=0, duplicates, chance not in 0..100, NaN chance, money min > max, minQty > maxQty, dropCount=0 with non-empty drops list (silent dead config). All 3 presets save / load / re-validate clean. The bandit table's creatureId=1000 deliberately matches WSPN's makeCamp creatureId so the open-format demo content pack already has working cross-references.
2026-05-09 15:11:08 -07:00
"--gen-loot", "--gen-loot-bandit", "--gen-loot-boss",
"--info-wlot", "--validate-wlot",
"--export-wlot-json", "--import-wlot-json",
feat(pipeline): add WCRT (Wowee Creature Template) format Novel open replacement for the AzerothCore-style creature_template SQL table PLUS the Blizzard CreatureTemplate / CreatureFamily / CreatureType.dbc trio. The 14th open format added to the editor. This is the canonical metadata side of creatures shared across every spawn instance: HP, level range, faction, behavior flags, NPC role bits (vendor / trainer / quest-giver / innkeeper), base damage, equipped gear references. Cross-references with the previously-added formats: WSPN.entry.entryId -> WCRT.entry.creatureId WLOT.entry.creatureId -> WCRT.entry.creatureId WCRT.entry.equipped* -> WIT.entry.itemId The 4-format set (WIT + WLOT + WSPN + WCRT) now lets a content pack define a complete RPG zone's creature ecosystem: what creatures are, where they spawn, what they drop, and what gear they carry — entirely in open formats with no SQL dependencies. Format: • magic "WCRT", version 1, little-endian • per entry: creatureId / displayId / name / subname / minLevel..maxLevel / baseHealth + healthPerLevel / baseMana + manaPerLevel / factionId / npcFlags / typeId / familyId / damageMin..Max / attackSpeedMs / baseArmor / walkSpeed + runSpeed / gossipId / equippedMain + equippedOffhand + equippedRanged / aiFlags Enums: • TypeId: Beast / Dragon / Demon / Elemental / Giant / Undead / Humanoid / Critter / Mechanical • FamilyId: Wolf / Cat / Bear / Boar / Raptor / Hyena / Spider / Gorilla / Crab (for Beast types) • NpcFlags: Vendor / QuestGiver / Trainer / Banker / Innkeeper / FlightMaster / Auctioneer / Repair / Stable • Behavior: Passive / Aggressive / FleeLowHp / CallHelp / NoLeash API: WoweeCreatureLoader::save / load / exists / findById; presets makeStarter (1 innkeeper), makeBandit (creatureId=1000 matches WSPN/WLOT bandit references, equips WIT itemId=1001 sword), makeMerchants (creatureIds 4001/4002/4003 match WSPN village labels). CLI added (5 flags, 493 documented total): --gen-creatures / --gen-creatures-bandit / --gen-creatures-merchants --info-wcrt / --validate-wcrt Validator catches: creatureId=0, duplicates, level=0, minLevel>maxLevel, baseHealth=0, damageMin>damageMax, attackSpeed=0, non-positive walk/runSpeed, behavior flag contradictions (passive+aggressive), vendor with aggressive behavior (player can't trade).
2026-05-09 15:18:44 -07:00
"--gen-creatures", "--gen-creatures-bandit", "--gen-creatures-merchants",
"--info-wcrt", "--validate-wcrt",
"--export-wcrt-json", "--import-wcrt-json",
feat(pipeline): add WQT (Wowee Quest Template) format Novel open replacement for AzerothCore-style quest_template SQL tables PLUS the Blizzard Quest.dbc / QuestObjective.dbc trio. The 15th open format added to the editor — and the last gameplay-graph piece the catalog needed. Cross-references with previously-added formats: WQT.giverCreatureId -> WCRT.entry.creatureId WQT.turninCreatureId -> WCRT.entry.creatureId WQT.objective.targetId -> WCRT (kill) / WIT (collect) / WOB (interact) WQT.rewardItem.itemId -> WIT.entry.itemId WQT.prevQuestId -> WQT.entry.questId (intra-format) WQT.nextQuestId -> WQT.entry.questId Together with WIT / WCRT / WLOT / WSPN / WOMX / WOL / WOW / WSND, a content pack can now ship a complete RPG zone (terrain + props + atmosphere + sounds + creatures + items + loot + spawns + quests) entirely in open formats with no SQL or .dbc dependencies. 15 of 15 expected slots filled. Format: • magic "WQTM", version 1, little-endian • per quest: questId / title / objective / description / minLevel..maxLevel + questLevel / requiredClass+RaceMask / prev+nextQuestId / giver+turninCreatureId / objectives[] / xpReward + moneyCopperReward / rewardItems[] / flags Per-objective: kind (kill/collect/interact/visit/escort/cast), targetId, quantity Per-reward: itemId, qty, pickFlags (AutoGiven / PlayerChoice) Quest flags: Daily / Weekly / Raid / Group / AutoComplete / AutoAccept / Repeatable / ClassQuest / Pvp API: WoweeQuestLoader::save / load / exists / findById; presets makeStarter (1 simple kill quest, references the bandit creatureId=1000), makeChain (3-quest chain with prev/next links + AutoComplete bridge + player-choice rewards), makeDaily (Daily+Repeatable+AutoAccept combo). CLI added (5 flags, 500 documented total — round milestone): --gen-quests / --gen-quests-chain / --gen-quests-daily --info-wqt / --validate-wqt Validator catches: questId=0+duplicates, level=0, maxLevel<minLevel, empty title, no objectives without AutoComplete (player can't finish), no rewards at all, Daily without Repeatable (incoherent), targetId=0, quantity=0, unknown objective kind, reward itemId=0 or qty=0. The 3-quest chain demo exercises every major feature: • multiple objective kinds (visit / collect / kill) • prev/next chain links • AutoComplete dialogue-bridge quest • PlayerChoice reward (1 of 2 weapons)
2026-05-09 15:25:02 -07:00
"--gen-quests", "--gen-quests-chain", "--gen-quests-daily",
"--info-wqt", "--validate-wqt",
"--export-wqt-json", "--import-wqt-json",
feat(pipeline): add WGOT (Wowee Game Object Template) format Novel open replacement for AzerothCore-style gameobject_template SQL tables PLUS the Blizzard GameObjectDisplayInfo.dbc / GameObject types metadata. The 16th open format added to the editor. Game objects are the non-creature interactable scenery: chests (with loot), doors, buttons, mailboxes, herb / ore gathering nodes, fishing pools, signposts, mounts. Each has a displayId for the model, a typeId driving its interaction logic, and optional cross-references to a lock (future WLCK) and loot table (existing WLOT). Cross-references with previously-added formats: WSPN.entry.entryId (kind=GameObject) -> WGOT.entry.objectId WGOT.entry.lootTableId -> WLOT.entry.creatureId (loot tables are universal — chests and creatures both key by ID) The dungeon preset's Bandit Strongbox uses lootTableId=2000 to match WLOT's bandit chest table id, so the demo content stack already wires together: spawn (WSPN object kind 2000) -> object template (WGOT 2000) -> loot table (WLOT 2000). Format: • magic "WGOT", version 1, little-endian • per object: objectId / displayId / name / typeId / size / castBarCaption / requiredSkill + requiredSkillValue / lockId / lootTableId / minOpenTimeMs..maxOpenTimeMs / flags Enums: • TypeId (16): Door / Button / Chest / Container / QuestGiver / Text / Trap / Goober / Transport / Mailbox / MineralNode / HerbNode / FishingNode / Mount / Sign / Bonfire • Flags: Disabled / ScriptOnly / UsableFromMount / Despawn / Frozen / QuestGated API: WoweeGameObjectLoader::save / load / exists / findById; presets makeStarter (chest + mailbox + sign), makeDungeon (door + button + 2 chests + trap with proper WLOT cross-references), makeGather (Peacebloom herb + Tin Vein ore + fishing pool with skill requirements). CLI added (5 flags, 507 documented total now): --gen-objects / --gen-objects-dungeon / --gen-objects-gather --info-wgot / --validate-wgot Validator catches: objectId=0 + duplicates, size<=0, minOpenTime>maxOpenTime, gathering node without skill requirement (anyone can harvest — usually a typo), chest without loot table (script must populate), requiredSkillValue set without requiredSkill (incoherent).
2026-05-09 15:31:49 -07:00
"--gen-objects", "--gen-objects-dungeon", "--gen-objects-gather",
"--info-wgot", "--validate-wgot",
"--export-wgot-json", "--import-wgot-json",
feat(pipeline): add WFAC (Wowee Faction Catalog) format Novel open replacement for Blizzard's Faction.dbc + FactionTemplate.dbc + the AzerothCore-style reputation_reward / reputation_spillover SQL tables. The 17th open format added to the editor. Combines the "displayable Faction" (player-facing name + reputation thresholds for friendly/honored/revered/exalted) with the "FactionTemplate matrix" (which factions are hostile to which) into one entry. The runtime walks the catalog to answer two questions: • "Will faction A attack faction B on sight?" -> enemy list • "What rep tier is the player with X?" -> thresholds Cross-references with previously-added formats: WCRT.entry.factionId -> WFAC.entry.factionId WFAC.entry.parentFactionId -> WFAC.entry.factionId WFAC.entry.enemies[] -> WFAC.entry.factionId WFAC.entry.friends[] -> WFAC.entry.factionId The starter preset's factionId 35 (Friendly) and 14 (Hostile) deliberately match the WCRT preset defaults, so the demo content stack is consistent: WCRT.makeBandit's factionId=14 has a real entry in WFAC.makeStarter that declares it hostile to friendly NPCs (35) and players (1). Format: • magic "WFAC", version 1, little-endian • per faction: factionId / parentFactionId / name / description / reputationFlags / baseReputation / 7 ascending tier thresholds (hostile..exalted) / enemies[] / friends[] Enums: • ReputationFlags: VisibleOnTab / AtWarDefault / Hidden / NoReputation / IsHeader (group label) • Tier (canonical): Hated / Hostile / Unfriendly / Neutral / Friendly / Honored / Revered / Exalted API: WoweeFactionLoader::save / load / exists / findById + WoweeFaction::isHostile(a, b); presets makeStarter (3-faction demo matching WCRT defaults), makeAlliance (header + Stormwind / Darnassus / Ironforge with reciprocal friend lists + Defias enemy), makeWildlife (4 beast factions, each hostile to player but ignoring other beasts). CLI added (5 flags, 514 documented total now): --gen-factions / --gen-factions-alliance / --gen-factions-wildlife --info-wfac / --validate-wfac Validator catches: factionId=0 + duplicates, empty name, threshold ordering violations (hostile must be < unfriendly < neutral < ... < exalted), self-listed as enemy or friend, faction in both enemies and friends (incoherent).
2026-05-09 15:37:59 -07:00
"--gen-factions", "--gen-factions-alliance", "--gen-factions-wildlife",
"--info-wfac", "--validate-wfac",
"--export-wfac-json", "--import-wfac-json",
feat(pipeline): add WLCK (Wowee Lock Template) format Novel open replacement for Blizzard's Lock.dbc. The 18th open format added to the editor. Closes the cross-reference gap from WGOT.entry.lockId — until now that field pointed to a format that didn't exist yet. A lock is a multi-channel security check. Each lock has up to 5 independent channels; a player can open the lock by satisfying ANY ONE channel: • Item — requires a specific key item (WIT cross-ref) • Lockpick — requires the lockpicking skill at minimum rank (rogue / engineering profession) • Spell — requires casting a specific spell • Damage — can be forced open with attack damage Cross-references with previously-added formats: WGOT.entry.lockId -> WLCK.entry.lockId WLCK.channel.targetId (Item) -> WIT.entry.itemId WLCK.channel.targetId (Lockpick) -> future WSKL skillId WLCK.channel.targetId (Spell) -> future WSPL spellId The starter and dungeon presets' lockIds (1 and 2) deliberately match WGOT.makeDungeon's iron-door lockId=1 and bandit-strongbox lockId=2, so the demo content stack already wires together: WSPN spawn -> WGOT object template -> WLCK lock template -> WIT key items. Format: • magic "WLCK", version 1, little-endian • per lock: lockId / name / flags / 5 fixed channel slots • per channel: kind / skillRequired / targetId • all 5 slots written even when unused (kind=None + zeroed fields), keeping the per-entry size constant for fast random access Enums: • ChannelKind: None / Item / Lockpick / Spell / Damage • Flags: DestructOnOpen / RespawnOnKey / TrapOnFail API: WoweeLockLoader::save / load / exists / findById; presets makeStarter (Iron Door + Wooden Chest), makeDungeon (matches WGOT cross-references; light/heavy lockpicks + boss-key-only seal), makeProfessions (4-tier rogue lockpick progression at ranks 1/100/175/250). CLI added (5 flags, 521 documented total now): --gen-locks / --gen-locks-dungeon / --gen-locks-professions --info-wlck / --validate-wlck Validator catches: lockId=0 + duplicates, all-None channels (lock can never open), Item/Spell/Lockpick channels with targetId=0 (no resource referenced), unknown channel kind, skillRequired set on non-Lockpick channel (silently ignored at runtime — flag as warning).
2026-05-09 15:44:26 -07:00
"--gen-locks", "--gen-locks-dungeon", "--gen-locks-professions",
"--info-wlck", "--validate-wlck",
"--export-wlck-json", "--import-wlck-json",
feat(pipeline): add WSKL (Wowee Skill Catalog) format Novel open replacement for Blizzard's SkillLine.dbc + SkillLineCategory.dbc + the AzerothCore-style player skill base tables. The 19th open format added to the editor. Defines every player-trackable skill: weapon proficiencies (Swords, Axes, Bows), professions (Mining, Alchemy, Cooking), languages (Common, Dwarvish), class specializations (Fire, Frost, Holy, Protection), armor proficiencies (Mail, Plate), and secondary skills (First Aid, Lockpicking, Riding). Cross-references with previously-added formats: WLCK.channel.targetId (kind=Lockpick) -> WSKL.entry.skillId WGOT.entry.requiredSkill -> WSKL.entry.skillId The starter preset's skillIds 186 (Mining) and 633 (Lockpicking) deliberately match the canonical IDs already referenced by WGOT.makeGather and WLCK.makeDungeon — so the demo content stack now wires together end-to-end: WGOT herb-node requires skill 186 -> WSKL Mining at rank 1+; WLCK bandit-strongbox channel requires skill 633 -> WSKL Lockpicking at rank 1+. Format: • magic "WSKL", version 1, little-endian • per skill: skillId / name / description / categoryId / canTrain / maxRank / rankPerLevel / iconPath Enums: • CategoryId (8): Weapon / Class / Profession / SecondaryProfession / Language / ArmorProficiency / Riding / WeaponSpec API: WoweeSkillLoader::save / load / exists / findById; presets makeStarter (5-skill demo with cross-referenced canonical IDs), makeProfessions (12 classic professions: 9 primary + 3 secondary), makeWeapons (16 weapon skills with canonical SkillLine IDs and rankPerLevel=5 auto-grow). CLI added (5 flags, 528 documented total now): --gen-skills / --gen-skills-professions / --gen-skills-weapons --info-wskl / --validate-wskl Validator catches: skillId=0 + duplicates, empty name, maxRank=0, unknown categoryId, suspicious maxRank=1 on non-Language skill (only languages cap at 1), weapon skill with rankPerLevel=0 (won't auto-grow on use).
2026-05-09 15:50:25 -07:00
"--gen-skills", "--gen-skills-professions", "--gen-skills-weapons",
"--info-wskl", "--validate-wskl",
"--export-wskl-json", "--import-wskl-json",
feat(pipeline): add WSPL (Wowee Spell Catalog) format Novel open replacement for Blizzard's Spell.dbc + SpellEffect.dbc + the AzerothCore-style spell_dbc / spell_proc tables. The 20th open format added to the editor — completes the canonical-data side of the gameplay graph. Each entry holds the metadata side of a spell: name, description, school, range, mana / cast / cooldown times, plus a single primary effect. The simplified effect model (one effectKind + min/max value + misc field) covers the common cases (damage / heal / buff / debuff / teleport / summon / dispel) without needing to reproduce the full multi-effect graph that classic Spell.dbc carries. Cross-references with previously-added formats: WLCK.channel.targetId (kind=Spell) -> WSPL.entry.spellId WQT.objective.targetId (kind=SpellCast) -> WSPL.entry.spellId WCRT.equippedMain (item with on-use) -> WIT -> WSPL Format: • magic "WSPL", version 1, little-endian • per spell: spellId / name / description / iconPath / school / targetType / effectKind / cast & cooldown & GCD ms / manaCost / range min..max / minLevel / maxStacks / durationMs / effectValueMin..Max / effectMisc / flags Enums: • School (7): Physical / Holy / Fire / Nature / Frost / Shadow / Arcane • TargetType (6): Self / Single / Cone / AoeFromSelf / Line / Ground • EffectKind (7): Damage / Heal / Buff / Debuff / Teleport / Summon / Dispel • Flags: Passive / Hidden / Channeled / Ranged / AreaOfEffect / Triggered / UnitTargetOnly / FriendlyOnly / HostileOnly API: WoweeSpellLoader::save / load / exists / findById; presets makeStarter (Strike + Lesser Heal + Power Word: Fortitude + Hearthstone, one per major effect kind), makeMage (Frostbolt 116 + Fireball 133 + Arcane Intellect 1459 + Blink 1953, canonical Classic spellIds), makeWarrior (Heroic Strike 78 + Thunder Clap 6343 + Battle Shout 6673 + Mortal Strike 12294). CLI added (5 flags, 535 documented total now): --gen-spells / --gen-spells-mage / --gen-spells-warrior --info-wspl / --validate-wspl Validator catches: spellId=0 + duplicates, empty name, school out of range, effectKind out of range, NaN range, range/value min>max, FriendlyOnly+HostileOnly conflict (incoherent), friendly-only with damage/debuff effect (incoherent), hostile-only with heal/buff effect, buff/debuff effect with durationMs=0 (instant fade — almost certainly authoring oversight). The validator caught a real preset-emitter authoring error during initial smoke testing — buff spells were setting effectValueMin without effectValueMax (validator's range check immediately flagged it), prompting an in-batch fix to set both fields. This is exactly the catch-the-typo purpose validators serve.
2026-05-09 15:58:09 -07:00
"--gen-spells", "--gen-spells-mage", "--gen-spells-warrior",
"--info-wspl", "--validate-wspl",
"--export-wspl-json", "--import-wspl-json",
feat(pipeline): add WACH (Wowee Achievement Catalog) format Novel open replacement for Blizzard's Achievement.dbc + AchievementCriteria.dbc + AchievementCategory.dbc + the AzerothCore-style character_achievement / character_achievement_progress SQL tables. The 21st open format added to the editor. Each achievement carries display metadata (name, description, icon, points, faction restriction) plus a list of criteria the player must satisfy. Criteria mirror the WQT objective model (kind + targetId + quantity), so the runtime can reuse the same progress-tracking machinery for both quests and achievements. Cross-references with previously-added formats — every criterion kind has a real format target: WACH.criteria.targetId (kind=KillCreature) -> WCRT.creatureId WACH.criteria.targetId (kind=CompleteQuest) -> WQT.questId WACH.criteria.targetId (kind=LootItem) -> WIT.itemId WACH.criteria.targetId (kind=CastSpell) -> WSPL.spellId WACH.criteria.targetId (kind=ReachSkillLevel) -> WSKL.skillId WACH.criteria.targetId (kind=EarnReputation) -> WFAC.factionId WACH.criteria.targetId (kind=CompleteAchievement) -> WACH.achievementId (meta-achievements) Format: • magic "WACH", version 1, little-endian • per achievement: id / categoryId / name / description / iconPath / titleReward / points / minLevel / faction / flags / criteria[] • per criterion: criteriaId / kind / targetId / quantity / description Enums: • CriteriaKind (9): KillCreature / CompleteQuest / LootItem / ReachLevel / EarnReputation / CastSpell / ReachSkillLevel / VisitArea / CompleteAchievement • Faction: Both / Alliance / Horde • Flags: HiddenUntilEarned / ServerFirst / RealmFirst / Tracking / Counter / Account API: WoweeAchievementLoader::save / load / exists / findById; presets makeStarter (3 simple kill/quest/level demos), makeBandit (3 with WCRT/WGOT/WQT cross-refs), makeMeta (3 base + 1 meta-achievement granting "the Versatile" title, exercising CompleteAchievement criterion kind that lets achievements depend on other achievements). CLI added (5 flags, 542 documented total now): --gen-achievements / --gen-achievements-bandit / --gen-achievements-meta --info-wach / --validate-wach Validator catches: achievementId=0 + duplicates, empty name, faction out of range, no criteria (achievement can never be earned), criterion quantity=0, unknown criterion kind, targetId=0 on criterion kinds that need a real resource reference (everything except ReachLevel which uses the quantity field for the level number). The bandit preset's cross-references close the gameplay graph end-to-end: kill 50 creatureId=1000 (matches WCRT/ WSPN/WLOT bandit), loot objectId=2000 (matches WGOT bandit strongbox), complete questId=1 (matches WQT Bandit Trouble). The meta preset closes a separate loop: 3 sub-achievements covering Mining (skillId=186), Lockpicking (skillId=633), and Frostbolt cast count (spellId=116) — each pointing at a real WSKL/WSPL entry that already exists in the demo content stack.
2026-05-09 16:04:30 -07:00
"--gen-achievements", "--gen-achievements-bandit", "--gen-achievements-meta",
"--info-wach", "--validate-wach",
"--export-wach-json", "--import-wach-json",
feat(pipeline): add WTRN (Wowee Trainer / Vendor catalog) format Novel open replacement for AzerothCore-style npc_trainer + npc_vendor SQL tables PLUS the Blizzard TrainerSpells.dbc family. The 22nd open format added to the editor. Unifies trainer spell lists and vendor item inventories into one per-NPC entry. A creature flagged Trainer or Vendor in WCRT references a WTRN entry that lists what they teach / sell. The same NPC can be both — kindMask is a bitmask covering the Trainer (0x01) and Vendor (0x02) kinds. This format closes a major cross-format gap: WCRT.npcFlags already had Vendor / Trainer bits, but until now there was no format defining what a vendor sells or what a trainer teaches. Now an NPC marked Vendor in WCRT has a real inventory, and an NPC marked Trainer has a real spell list. Cross-references — every WTRN field has a real format target: WTRN.entry.npcId -> WCRT.entry.creatureId WTRN.spell.spellId -> WSPL.entry.spellId WTRN.spell.requiredSkillId -> WSKL.entry.skillId WTRN.item.itemId -> WIT.entry.itemId Format: • magic "WTRN", version 1, little-endian • per NPC: npcId / kindMask / greeting + spells[] + items[] • per spell offer: spellId / moneyCostCopper / requiredSkillId / requiredSkillRank / requiredLevel • per item offer: itemId / stockCount (0xFFFFFFFF = unlimited) / restockSec / extendedCost / moneyCostCopper (0 = inherit from WIT.buyPrice) API: WoweeTrainerLoader::save / load / exists / findByNpc; presets makeStarter (innkeeper 4001 as both trainer + vendor: teaches First Aid + sells starter items), makeMageTrainer (NPC 4003 teaches the WSPL mage spells at scaling cost), makeWeaponVendor (NPC 4002 sells WIT weapons with mixed unlimited/finite stock + restock timers). CLI added (5 flags, 551 documented total now): --gen-trainers / --gen-trainers-mage / --gen-trainers-weapons --info-wtrn / --validate-wtrn Validator catches: npcId=0 + duplicates, kindMask=0 (NPC offers nothing), Trainer flag without spells, Vendor flag without items, spells/items present without the matching kind bit (silently ignored at runtime), spellId=0 / itemId=0 in offers, finite stock with restockSec=0 (single-fill — usually intentional but worth surfacing). The 3 presets deliberately use npcIds matching WCRT village merchants (4001/4002/4003) so the demo content stack is self-consistent: WCRT 4001 has the Vendor + Trainer flag, and WTRN 4001 actually defines what they sell and teach.
2026-05-09 16:12:58 -07:00
"--gen-trainers", "--gen-trainers-mage", "--gen-trainers-weapons",
"--info-wtrn", "--validate-wtrn",
"--export-wtrn-json", "--import-wtrn-json",
feat(pipeline): add WGSP (Wowee Gossip Menu) format Novel open replacement for AzerothCore-style gossip_menu + gossip_menu_option + npc_text SQL tables PLUS the Blizzard NpcText.dbc family. The 23rd open format added to the editor. An NPC's dialogue tree: a menu of options the player can pick from when right-clicking the NPC. Each option may bridge to another menu, trigger a vendor / trainer interaction, offer a quest, etc. The simplified per-option model (kind + actionTarget + flags + moneyCost) covers the common cases without needing separate npc_text condition tables. Closes a major cross-format gap: WCRT.entry.gossipId has existed since batch 116 (when WCRT was added) but pointed to a format that didn't exist yet. The innkeeper preset's menuId=4001 deliberately matches WCRT's Bartleby NPC so the demo content stack can wire WCRT.gossipId = 4001 once that field is plumbed through the runtime. Cross-references: WCRT.entry.gossipId -> WGSP.entry.menuId WGSP.option.actionTarget (Submenu) -> WGSP.entry.menuId WGSP.option.actionTarget (Vendor / Trainer) -> WTRN.entry.npcId WGSP.option.actionTarget (Quest) -> WQT.entry.questId Format: • magic "WGSP", version 1, little-endian • per menu: menuId / titleText + options[] • per option: optionId / text / kind / actionTarget / requiredFlags / moneyCostCopper Enums: • OptionKind (13): Close / Submenu / Vendor / Trainer / Quest / Tabard / Banker / Innkeeper / FlightMaster / TextOnly / Script / Battlemaster / Auctioneer • OptionFlags: AllianceOnly / HordeOnly / Coinpouch / QuestGated / Closes API: WoweeGossipLoader::save / load / exists / findById; presets makeStarter (1 menu with vendor + trainer + close), makeInnkeeper (2-menu tree: main menu 4001 with hearth / vendor / flight / submenu options + lore submenu 4002 that links back), makeQuestGiver (1 menu with 2 quest options referencing WQT 1 and 100, plus a paid respec script exercising the Coinpouch flag with a 10g cost). CLI added (5 flags, 558 documented total now): --gen-gossip / --gen-gossip-innkeeper / --gen-gossip-questgiver --info-wgsp / --validate-wgsp Validator catches: menuId=0 + duplicates, empty title / options, unknown option kind, empty option text, Submenu options pointing at non-existent menuIds (intra-format cross-reference resolution), Coinpouch flag without moneyCost (misleading UI), AllianceOnly+HordeOnly conflict.
2026-05-09 16:20:07 -07:00
"--gen-gossip", "--gen-gossip-innkeeper", "--gen-gossip-questgiver",
"--info-wgsp", "--validate-wgsp",
"--export-wgsp-json", "--import-wgsp-json",
feat(pipeline): add WTAX (Wowee Taxi catalog) format Novel open replacement for Blizzard's TaxiNodes.dbc + TaxiPath.dbc + TaxiPathNode.dbc. The 24th open format added to the editor. Defines the flight-master network: a set of named nodes (positions on the world map) plus the paths between them (sequences of waypoints with per-segment delay and a per-path gold cost). The same file holds both node and path lists — flat arrays keyed by id, with intra-format references from path.fromNodeId / toNodeId to node.nodeId. Cross-references: WCRT.entry (with FlightMaster npcFlag) ~= WTAX.nodeId (matched by world position; flight master NPCs stand at their nodes) WTAX.path.fromNodeId / toNodeId -> WTAX.entry.nodeId (intra-format graph) Format: • magic "WTAX", version 1, little-endian • nodes (each): nodeId / mapId / name / iconPath / position / faction restrictions • paths (each): pathId / from+toNodeId / moneyCostCopper / waypoints[] each with position + per-waypoint delaySec API: WoweeTaxiLoader::save / load / exists + WoweeTaxi::findNode / findPath / findPathBetween. Three preset emitters showcase different graph shapes: • makeStarter — 2 nodes + 2 paths (round-trip) • makeRegion — 4 nodes at a 500m square + 4-path directed ring (NW->NE->SE->SW->NW) • makeContinent — 6 nodes hub-spoke + 3 perimeter shortcuts; intermediate waypoints climb to altitude 120m for visual arc effect CLI added (5 flags, 564 documented total now): --gen-taxi / --gen-taxi-region / --gen-taxi-continent --info-wtax / --validate-wtax Validator catches: nodeId/pathId=0 + duplicates, empty node name, non-finite positions, fromNodeId == toNodeId (self-loop path), path references to non-existent nodes (intra-format cross-reference resolution), negative waypoint delays.
2026-05-09 16:26:27 -07:00
"--gen-taxi", "--gen-taxi-region", "--gen-taxi-continent",
"--info-wtax", "--validate-wtax",
"--export-wtax-json", "--import-wtax-json",
feat(pipeline): add WTAL (Wowee Talent catalog) format Novel open replacement for Blizzard's TalentTab.dbc + Talent.dbc + the AzerothCore-style talent_progression SQL tables. The 25th open format added to the editor. Defines class talent specialization trees: per-class set of named tabs (Arms / Fury / Protection for warrior, Fire / Frost / Arcane for mage), each with talents arranged in a row/column grid, each talent having up to 5 ranks and an optional prerequisite chain. Cross-references with previously-added formats: WTAL.talent.prereqTalentId -> WTAL.talent.talentId (intra-format chain) WTAL.talent.rankSpellIds[] -> WSPL.entry.spellId (spell granted at each rank) Format: • magic "WTAL", version 1, little-endian • per tree: treeId / name / iconPath / requiredClassMask / talents[] (row, col, maxRank, prereqTalentId+rank, rankSpellIds[5] zero-padded for unused ranks) Enums: • ClassMask: bit positions match canonical CharClasses.dbc classIds — Warrior / Paladin / Hunter / Rogue / Priest / DK / Shaman / Mage / Warlock / Druid API: WoweeTalentLoader::save / load / exists + WoweeTalent::findTree / findTalent (global lookup across all trees in the catalog). Three preset emitters showcase tree shapes: • makeStarter — 1 small tree (3-talent vertical chain) • makeWarrior — 3 trees (Arms 4 / Fury 4 / Protection 3) with WSPL cross-refs at capstones (Mortal Strike -> WSPL 12294, Battle Shout -> WSPL 6673, Thunder Clap -> WSPL 6343) • makeMage — 3 trees (Arcane / Fire / Frost) with capstones referencing Frostbolt 116 / Fireball 133 / Blink 1953 from WSPL CLI added (5 flags, 571 documented total now): --gen-talents / --gen-talents-warrior / --gen-talents-mage --info-wtal / --validate-wtal Validator catches: tree+talent ids=0 or duplicates, empty tree name, requiredClassMask=0 (every class would see this tree — usually a typo), maxRank not in 1..5, talent listing itself as prerequisite, prereqTalentId pointing at a talent that doesn't exist in this catalog (intra-format cross-reference resolution), prereqRank=0 or > the prereq talent's maxRank (catches off-by-one references), gaps in rankSpellIds progression (rank N has spell but rank N-1 doesn't — usually a typo). The validator caught a real authoring bug in the makeMage / makeWarrior presets during smoke testing — initial check was comparing prereqRank against the WRONG talent's maxRank (this talent's rather than the prereq's). Fixed in the same commit by hoisting the check into the cross-reference resolution pass where the prereq talent is in hand.
2026-05-09 16:33:45 -07:00
"--gen-talents", "--gen-talents-warrior", "--gen-talents-mage",
"--info-wtal", "--validate-wtal",
"--export-wtal-json", "--import-wtal-json",
feat(pipeline): add WMS (Wowee Map / Area) catalog format Novel open replacement for Blizzard's Map.dbc + AreaTable.dbc + the AzerothCore-style world_zone SQL tables. The 26th open format added to the editor. Defines two related kinds of locator in one catalog: • Maps — top-level worlds (continents / instances / raids / battlegrounds / arenas) with a friendly name, type, expansion tag, and player-count cap. • Areas — sub-zones within maps with friendly names, parent- area chain, recommended level range, faction- territory marker (alliance / horde / contested / both), exploration XP, and an ambient-sound cross-reference into WSND. The runtime uses Areas for minimap labels, location strings under the player frame, "Discover Sub-zone" XP gains, and ambient-music selection on zone entry. Cross-references with previously-added formats: WMS.area.ambienceSoundId -> WSND.entry.soundId WMS.area.parentAreaId -> WMS.area.areaId (intra-format sub-zone hierarchy) WSPN entries are tied to WMS.area boundaries by world position (no direct ID — the runtime resolves position -> area at lookup time) Format: • magic "WMSX", version 1, little-endian • maps[] (each): mapId / name / shortName / mapType / expansionId / maxPlayers • areas[] (each): areaId / mapId / parentAreaId / name / minLevel..maxLevel / factionGroup / explorationXP / ambienceSoundId Enums: • MapType (5): Continent / Instance / Raid / Battleground / Arena • ExpansionId (5): Classic / Tbc / Wotlk / Cata / Mop • FactionGroup: Both / Alliance / Horde / Contested (PvP-flagging zone) API: WoweeMapsLoader::save / load / exists + WoweeMaps::findMap / findArea. Three preset emitters showcase the catalog shape: • makeStarter — 1 continent + 3 areas with parent chain (Goldshire is a sub-zone of Elwynn Forest) • makeClassic — 2 continents + Deadmines instance + 6 areas (Stormwind/Elwynn/Goldshire/Westfall/ Duskwood/Teldrassil/Deadmines) with WSND ambient-sound refs • makeBgArena — Alterac Valley (40-player BG) + Nagrand Arena (5v5 with maxPlayers=10) CLI added (5 flags, 578 documented total now): --gen-maps / --gen-maps-classic / --gen-maps-bgarena --info-wms / --validate-wms Validator catches: empty map name, unknown mapType / expansion, BG/Arena with maxPlayers=0 (no participant cap), area ids=0 + duplicates, empty area name, maxLevel < minLevel, areas referencing non-existent maps, parentAreaId chains crossing maps (sub-zones must be on the same world), self-parent.
2026-05-09 16:40:00 -07:00
"--gen-maps", "--gen-maps-classic", "--gen-maps-bgarena",
"--info-wms", "--validate-wms",
"--export-wms-json", "--import-wms-json",
feat(pipeline): add WCHC (Wowee Character Classes/Races) format Novel open replacement for Blizzard's CharClasses.dbc + CharRaces.dbc + CharStartOutfit.dbc trio. The 27th open format added to the editor — completes the foundational character-creation surface. One file holds three flat arrays: • classes — playable classes (Warrior / Mage / etc.) with power type (mana/rage/focus/energy/runic), base HP+power scaling, faction availability • races — playable races with faction (Alliance/Horde/ Neutral), starting map+zone, default language spell, base stats, racial mount spell • outfits — starting gear loadout per (class, race, gender) triple, listing item IDs and display slots Cross-references with previously-added formats: WCHC.race.startingMapId -> WMS.map.mapId WCHC.race.startingZoneAreaId -> WMS.area.areaId WCHC.race.defaultLanguageSpellId -> WSPL.entry.spellId WCHC.race.mountSpellId -> WSPL.entry.spellId WCHC.outfit.items.itemId -> WIT.entry.itemId The starter preset's outfits use real WIT itemIds (1=Worn Shortsword, 2=Linen Vest, 3=Healing Potion) so the demo content stack is consistent: a freshly created Human Warrior in WCHC starts with WIT items 1/2/3, drops them on death into a WLOT-tracked corpse loot, and can be respawned via WSPN, etc. Format: • magic "WCHC", version 1, little-endian • classes[]: classId / name / icon / powerType / display / baseHP+perLevel / basePower+perLevel / factionAvailability • races[]: raceId / name / icon / factionId / male+female displayId / 5 base stats / startingMap+zone / defaultLanguage+mount spell IDs • outfits[]: classId+raceId+gender + items[] (each: itemId + displaySlot) Enums: • PowerType (6): Mana / Rage / Focus / Energy / RunicPower / Runes • RaceFaction (3): Alliance / Horde / Neutral • Gender: Male / Female • FactionAvailability bitmask: AvailableAlliance, AvailableHorde API: WoweeCharsLoader::save / load / exists + WoweeChars::findClass / findRace / findOutfit (by class+race+gender). CLI added (5 flags, 585 documented total now): --gen-chars / --gen-chars-alliance / --gen-chars-allraces --info-wchc / --validate-wchc Validator catches: ids unique, baseHealth=0 (instant-death character), factionAvailability=0 (no faction can pick), empty names, factionId out of range, outfit references to non-existent class/race ids (cross-format resolution), gender > 1, outfit items with itemId=0, outfit with no items (warning — naked character).
2026-05-09 16:47:04 -07:00
"--gen-chars", "--gen-chars-alliance", "--gen-chars-allraces",
"--info-wchc", "--validate-wchc",
"--export-wchc-json", "--import-wchc-json",
feat(pipeline): add WTKN (Wowee Token catalog) format Novel open replacement for Blizzard's Currency.dbc + CurrencyCategory.dbc + CurrencyTypes.dbc + the AzerothCore- style player_currency SQL tables. The 28th open format added to the editor. Defines secondary currency tokens beyond gold: Honor Points (PvP), Arena Points (rated PvP), Marks of Honor (per battleground), faction reputation tokens, holiday-event currencies. Each token has a balance cap, optional weekly cap (regenerating earnings limit), and a category for grouping in the player's currency tab. Cross-references: WTRN.item.extendedCost -> WTKN.entry.tokenId (vendors can charge in tokens instead of copper — when extendedCost > 0 the runtime looks up the matching token) Format: • magic "WTKN", version 1, little-endian • per token: tokenId / name / description / iconPath / category / maxBalance / weeklyCap / flags Enums: • Category (6): Misc / Pvp / Reputation / Crafting / Seasonal / Holiday • Flags: AccountWide / Tradeable / HiddenUntilEarned / ResetsOnLogout / ConvertsToGold API: WoweeTokenLoader::save / load / exists / findById. Three preset emitters showcase typical token shapes: • makeStarter — 3 tokens (Honor / Marks / Stormwind Guard rep) covering Pvp + Reputation categories • makePvp — full PvP set: Honor (75k) + Arena (5k + weekly 1500) + 6 BG marks of honor for classic + TBC + WotLK battlegrounds • makeSeasonal — 4 holiday tokens (Tricky Treats / Brewfest / Coin of Ancestry / Stranger's Gift) all flagged ResetsOnLogout to make them event-bound CLI added (5 flags, 592 documented total now): --gen-tokens / --gen-tokens-pvp / --gen-tokens-seasonal --info-wtkn / --validate-wtkn Validator catches: tokenId=0 + duplicates, empty name, unknown category, weeklyCap > maxBalance (cap unreachable), ResetsOnLogout + AccountWide combo (incoherent — account state survives logout by definition).
2026-05-09 16:53:11 -07:00
"--gen-tokens", "--gen-tokens-pvp", "--gen-tokens-seasonal",
"--info-wtkn", "--validate-wtkn",
"--export-wtkn-json", "--import-wtkn-json",
feat(pipeline): add WTRG (Wowee Area Trigger) format Novel open replacement for Blizzard's AreaTrigger.dbc + AreaTriggerTeleport.dbc + the AzerothCore-style areatrigger_template / areatrigger_teleport SQL tables. The 29th open format added to the editor. Defines proximity-based event zones — when a player enters a defined region (box or sphere), the runtime fires the trigger's action: teleport to another map, award exploration XP for a quest, run a server script, gate an instance entrance behind a key item, mark a PvP boundary, or simply display a "Discovered: {area name}" banner. Cross-references with previously-added formats — every trigger field has a real format target: WTRG.entry.mapId / areaId -> WMS.map.mapId / WMS.area.areaId WTRG.actionTarget (Teleport) -> WMS.mapId WTRG.actionTarget (QuestExploration) -> WQT.questId WTRG.requiredQuestId -> WQT.entry.questId WTRG.requiredItemId -> WIT.entry.itemId (key) Format: • magic "WTRG", version 1, little-endian • per trigger: triggerId / mapId / areaId / name / center vec3 / shape / kind / boxDims vec3 / radius / actionTarget / dest vec3 / destOrientation / requiredQuestId / requiredItemId / minLevel Enums: • Shape (2): Box / Sphere • Kind (7): Teleport / QuestExploration / Script / InstanceEntrance / AreaName / CombatStartZone / Waypoint API: WoweeTriggerLoader::save / load / exists / findById. Three preset emitters showcase common trigger shapes: • makeStarter — area-name + quest-exploration with cross-ref to WQT 100 ("Investigate the Camp") • makeDungeon — outdoor area-name + portal-style InstanceEntrance with Deadmines key gate (WIT itemId 5200, matches WLCK.makeDungeon's Boss Vault Seal) + interior exit teleport back outdoors • makeFlightPath — 2 sphere waypoints near flight masters so the runtime can auto-open the flight UI on proximity (matches WTAX starter node positions) CLI added (5 flags, 601 documented total now): --gen-triggers / --gen-triggers-dungeon / --gen-triggers-flightpath --info-wtrg / --validate-wtrg Validator catches: triggerId=0 + duplicates, unknown shape / kind, non-finite center, sphere with radius<=0, box with all-zero half-extents, teleport / instance with dest=(0,0,0) (silently does nothing — usually a typo), QuestExploration without an actionTarget questId.
2026-05-09 17:01:43 -07:00
"--gen-triggers", "--gen-triggers-dungeon", "--gen-triggers-flightpath",
"--info-wtrg", "--validate-wtrg",
"--export-wtrg-json", "--import-wtrg-json",
feat(pipeline): add WTIT (Wowee Title catalog) format Novel open replacement for Blizzard's CharTitles.dbc + the AzerothCore-style character_title SQL table. The 30th open format added to the editor. Defines the player-display titles awarded for completing achievements ("the Versatile"), reaching PvP ranks ("Sergeant Major" / "Stone Guard"), participating in raids ("Champion of the Naaru"), levelling a profession ("Master Locksmith"), or seasonal events ("Brewmaster", "the Hallowed"). Closes a long-standing gap: WACH.entry.titleReward has been a free-form string since batch 116 with no formal catalog to resolve against. WTIT systematizes those strings into a real catalog — the runtime resolves WACH.titleReward to a WTIT entry by name, then displays the titleId in the player title selector. Cross-references: WACH.entry.titleReward (string) ~= WTIT.entry.name (string match — runtime resolves achievement- granted titles by looking up matching WTIT entry by name) Format: • magic "WTIT", version 1, little-endian • per title: titleId / name / nameMale / nameFemale / iconPath / prefix (suffix vs prefix display) / category / sortOrder Enums: • Category (8): Achievement / Pvp / Raid / ClassTitle / Event / Profession / Lore / Custom API: WoweeTitleLoader::save / load / exists + WoweeTitle::findById / findByName. Three preset emitters showcase typical title catalogs: • makeStarter — 4 titles (Versatile / Sergeant / Champion / Hallowed) covering 4 categories • makePvp — 28-title classic Honor System ladder (14 Alliance ranks Private->Grand Marshal + 14 Horde ranks Scout->High Warlord) • makeAchievement — 8 achievement titles including "the Versatile" matching WACH.makeMeta's achievement 250 titleReward + capstone profession titles CLI added (5 flags, 608 documented total now): --gen-titles / --gen-titles-pvp / --gen-titles-achievement --info-wtit / --validate-wtit Validator catches: titleId=0 + duplicates, empty name, unknown category, gender variants set on only one side (causes mixed-gender display when the runtime falls back to canonical for the unset side).
2026-05-09 17:07:56 -07:00
"--gen-titles", "--gen-titles-pvp", "--gen-titles-achievement",
"--info-wtit", "--validate-wtit",
"--export-wtit-json", "--import-wtit-json",
feat(pipeline): add WSEA (Wowee Seasonal Event) format Novel open replacement for Blizzard's GameEvents.dbc + the AzerothCore-style game_event / game_event_creature / game_event_gameobject SQL tables. The 31st open format added to the editor. Calendar-based content: holidays (Hallow's End, Winter's Veil), recurring promotional events (Children's Week, Lunar Festival, Brewfest), one-time anniversaries, and XP-bonus weekends. Each event has a start date, duration, optional recurrence (yearly / monthly / weekly), faction restriction, optional XP bonus, and a reward currency cross-reference into WTKN. Cross-references with previously-added formats: WSEA.entry.tokenIdReward -> WTKN.entry.tokenId (the seasonal currency the event hands out — Tricky Treats during Hallow's End, Brewfest Tokens during Brewfest, etc.) The yearly preset's tokenIdReward values (200/201/202/203) deliberately match WTKN.makeSeasonal's seasonal token ids so the demo content stack already wires together: WSEA yearly events grant WTKN tokens that vendors can charge in via WTRN.item.extendedCost. Format: • magic "WSEA", version 1, little-endian • per event: eventId / name / description / iconPath / announceMessage / startDate (Unix epoch seconds) / duration_seconds / recurrenceDays (0=one-shot, 365=yearly) / holidayKind / factionGroup / bonusXpPercent / tokenIdReward Enums: • HolidayKind (7): Combat / Collection / Racial / Anniversary / Fishing / Cosmetic / WorldEvent • FactionGroup (3): Both / Alliance / Horde API: WoweeEventLoader::save / load / exists / findById. Three preset emitters showcase typical event shapes: • makeStarter — 3 events covering Combat / Fishing / Anniversary kinds • makeYearly — 4 yearly holidays with full WTKN cross-refs (Hallow's End / Brewfest / Lunar Festival / Winter's Veil) • makeBonusWeekends — 3 monthly Fri-Sun bonus tiers (50% / 100% / 200% RAF-style) CLI added (5 flags, 614 documented total now): --gen-events / --gen-events-yearly / --gen-events-weekends --info-wsea / --validate-wsea Validator catches: eventId=0 + duplicates, empty name, unknown holidayKind / factionGroup, duration_seconds=0 (event never runs), duration > recurrence period (events would overlap themselves on next iteration), bonusXpPercent > 200 (very high — verify intentional).
2026-05-09 17:14:46 -07:00
"--gen-events", "--gen-events-yearly", "--gen-events-weekends",
"--info-wsea", "--validate-wsea",
"--export-wsea-json", "--import-wsea-json",
feat(pipeline): add WMOU (Wowee Mount catalog) format Novel open replacement for Blizzard's Mount.dbc + MountCapability.dbc + MountType.dbc + the mount-related subsets of Spell.dbc / Item.dbc. The 32nd open format added to the editor. Defines all summonable steeds: ground mounts, flying mounts, swimming mounts, racial mounts (Tauren Plainsrunner for druids), and class mounts (Warlock dreadsteed, Paladin charger). Each mount has a summon spell, optional teach item, riding skill prerequisite, speed bonus, and faction / race availability mask. Cross-references with previously-added formats: WMOU.entry.summonSpellId -> WSPL.entry.spellId WMOU.entry.itemIdToLearn -> WIT.entry.itemId WMOU.entry.requiredSkillId -> WSKL.entry.skillId (Riding skill ID 762) WCHC.race.mountSpellId ~= WMOU.entry.summonSpellId (loose match by spellId) Format: • magic "WMOU", version 1, little-endian • per mount: mountId / name / description / icon / displayId / summonSpellId / itemIdToLearn / requiredSkillId+Rank / speedPercent / mountKind / factionId / categoryId / raceMask Enums: • Kind (5): Ground / Flying / Swimming / Hybrid / Aquatic • Faction (3): Both / Alliance / Horde • Category (8): Common / Epic / Racial / Event / Achievement / Pvp / Quest / ClassMount API: WoweeMountLoader::save / load / exists / findById. Three preset emitters showcase typical mount catalogs: • makeStarter — 3 mounts (ground horse + epic flying gryphon + aquatic riding turtle) • makeRacial — 6 racial mounts (4 Alliance: Pinto / Ram / Frostsaber / Mechanostrider; 2 Horde: Dire Wolf / Skeletal Horse) with raceMask gating per WCHC race bit positions • makeFlying — 4 flying mounts spanning Common (60%) -> Epic (100%) -> Achievement (280%) -> Pvp (310%) speed tiers CLI added (5 flags, 621 documented total now): --gen-mounts / --gen-mounts-racial / --gen-mounts-flying --info-wmou / --validate-wmou Validator catches: mountId=0 + duplicates, empty name, summonSpellId=0 (mount cannot be cast), unknown enum values, speedPercent=0 (no speed bonus), flying mount with requiredSkillRank<150 (player can't fly), Racial category without raceMask (any race could use — usually a typo).
2026-05-09 17:23:00 -07:00
"--gen-mounts", "--gen-mounts-racial", "--gen-mounts-flying",
"--info-wmou", "--validate-wmou",
"--export-wmou-json", "--import-wmou-json",
feat(pipeline): add WBGD (Wowee Battleground Definition) format Novel open replacement for Blizzard's BattlemasterList.dbc + PvpDifficulty.dbc + the AzerothCore-style battleground_template SQL tables. The 33rd open format added to the editor. Defines per-BG gameplay rules: player count brackets, score-to-win, time limit, objective type (annihilation / capture flag / control nodes / king of hill / resource race / carry object), per-team start positions, respawn timer, and the WTKN currency token awarded on win. Cross-references with previously-added formats: WBGD.entry.mapId -> WMS.map.mapId (where mapType=Battleground) WBGD.entry.markTokenId -> WTKN.entry.tokenId (Mark of Honor for that BG) The classic preset's markTokenId fields (102/103/104) deliberately match WTKN.makePvp's "Mark of Honor: Warsong Gulch / Arathi Basin / Alterac Valley" token ids — so the demo content stack already wires together: WBGD.scoreToWin reached → grant WTKN mark → which a vendor in WTRN can charge in via item.extendedCost. Format: • magic "WBGD", version 1, little-endian • per BG: battlegroundId / mapId / name / description / objectiveKind / min+maxPlayersPerSide / minLevel..maxLevel / scoreToWin / timeLimitSeconds / bracketSize / allianceStart vec3 + facing / hordeStart vec3 + facing / respawnTimeSeconds / markTokenId Enums: • ObjectiveKind (6): Annihilation / CaptureFlag / ControlNodes / KingOfHill / ResourceRace / CarryObject API: WoweeBattlegroundLoader::save / load / exists / findById. Three preset emitters showcase typical BG shapes: • makeStarter — 1 king-of-hill BG (10v10, 3-cap to win) • makeClassic — 3 classic BGs with authentic player counts, level brackets, scoring, and WTKN cross-refs (Warsong Gulch CTF / Arathi Basin nodes / Alterac Valley resource race) • makeArena — 3 arena formats (Nagrand 2v2 / Blade's Edge 3v3 / Lordaeron 5v5) — annihilation objective + no respawn + 25 min cap CLI added (5 flags, 628 documented total now): --gen-bg / --gen-bg-classic / --gen-bg-arena --info-wbgd / --validate-wbgd Validator catches: bgId=0 + duplicates, empty name, unknown objectiveKind, player count=0, min>max counts/levels, scoreToWin=0 (no win condition), non-annihilation BG with respawnTimeSeconds=0 (losing side cannot recover).
2026-05-09 17:30:59 -07:00
"--gen-bg", "--gen-bg-classic", "--gen-bg-arena",
"--info-wbgd", "--validate-wbgd",
"--export-wbgd-json", "--import-wbgd-json",
feat(pipeline): add WMAL (Wowee Mail Template) format Novel open replacement for AzerothCore-style mail_loot_template SQL + the in-game mail subset of the inventory + currency systems. The 34th open format added to the editor. Defines templated mail messages with currency + item attachments. Triggered by quest reward delivery (overflow when bag is full), auction house bid wins / sales, achievement reward attachments, GM correspondence, holiday event mailings (Brewfest samples, Hallow's End candy), and returned-mail-on-rejection. Cross-references with previously-added formats: WMAL.entry.senderNpcId -> WCRT.entry.creatureId WMAL.entry.attachments.itemId -> WIT.entry.itemId Format: • magic "WMAL", version 1, little-endian • per template: templateId / senderNpcId / subject / body / senderName / moneyCopperAttached / categoryId / cod / returnable / expiryDays / attachments[] (each: itemId + quantity) Enums: • Category (8): QuestReward / Auction / GmCorrespondence / AchievementReward / EventMailing / Raffle / ScriptDelivery / ReturnedMail API: WoweeMailLoader::save / load / exists / findById. Three preset emitters showcase typical mail templates: • makeStarter — 3 templates (quest overflow / auction won / GM gift) covering the 3 most common categories • makeHoliday — 4 holiday samples that cross-reference the WTKN seasonal token IDs (200=Tricky Treats, 201=Brewfest, 202=Coin of Ancestry, 203=Stranger's Gift) so the demo content stack ships a full holiday onboarding experience • makeAuction — 5-template auction-house family (outbid / won / sold / expired / cancelled) — runtime fills in actual bid amounts / sold items at send time CLI added (5 flags, 635 documented total now): --gen-mail / --gen-mail-holiday / --gen-mail-auction --info-wmal / --validate-wmal Validator catches: templateId=0 + duplicates, empty subject, neither senderNpcId nor senderName set (no displayable sender), unknown category, expiryDays=0 (mail expires immediately), cod=1 with no money attached (free COD), empty mail in categories where the runtime doesn't fill in content (skips Auction / GmCorrespondence / ReturnedMail where empty templates are intentional). Two bugs caught + fixed during smoke-test on the auction preset: • print formatting glued the `0` from senderNpcId after the senderName when no NPC was set (rendered as "Postmaster0" instead of "Postmaster") — fixed with an explicit if/else split • validator's "no money + no items" warning was too aggressive for the Auction category, where templates are intentionally informational and the runtime fills in the real values — added Auction + ReturnedMail to the skip list
2026-05-09 17:41:03 -07:00
"--gen-mail", "--gen-mail-holiday", "--gen-mail-auction",
"--info-wmal", "--validate-wmal",
"--export-wmal-json", "--import-wmal-json",
feat(pipeline): add WGEM (Wowee Gem / Enchantment) format Novel open replacement for Blizzard's ItemEnchantment.dbc + GemProperties.dbc + SpellItemEnchantment.dbc. The 35th open format added to the editor. Defines two related kinds of item enhancement in one catalog: • Gems — socketable jewelry pieces with color (red / blue / yellow / meta) that fit into gear sockets, granting stats or triggering passive spells when socketed • Enchantments — persistent buffs applied to weapon / armor pieces, either by an enchanter spell or by an item proc (Mongoose, Crusader, Berserking) Cross-references with previously-added formats: WGEM.gem.itemIdToInsert -> WIT.entry.itemId WGEM.gem.spellId -> WSPL.entry.spellId WGEM.enchantment.spellId -> WSPL.entry.spellId Format: • magic "WGEM", version 1, little-endian • gems[]: gemId / itemIdToInsert / name / color / statType + statValue / requiredItemQuality / spellId • enchantments[]: enchantId / name / description / iconPath / enchantSlot / statType + statValue / spellId / durationSeconds / chargeCount Enums: • Color (8): Meta / Red / Yellow / Blue / Purple / Green / Orange / Prismatic • EnchantSlot (5): Permanent / Temporary / SocketColor / Ring / Cloak API: WoweeGemLoader::save / load / exists + WoweeGem::findGem / findEnchant. Three preset emitters showcase common shapes: • makeStarter — 3 gems (one per primary color) + 2 enchantments (proc + stat) • makeGemSet — 6-gem full color palette covering primary + secondary combinations • makeEnchants — 5 enchant variants spanning slots (Mongoose / Deadly Poison / stats ring / cloak / Berserking) CLI added (5 flags, 642 documented total now): --gen-gems / --gen-gems-set / --gen-gems-enchants --info-wgem / --validate-wgem Validator catches: ids=0 + duplicates, empty name, color / slot out of range, stat-only entries with statValue=0 (gem provides nothing), chargeCount > 0 on non-Temporary enchant slots (charges silently ignored at runtime). The validator caught a real preset issue on first run — the proc enchants (Mongoose / Deadly Poison / Berserking) had spellId=0 and statValue=0, providing nothing. Fixed by adding placeholder spellIds in the 28000-29000 range, with a comment noting they resolve to real WSPL proc spells when the spell catalog is extended.
2026-05-09 18:01:48 -07:00
"--gen-gems", "--gen-gems-set", "--gen-gems-enchants",
"--info-wgem", "--validate-wgem",
"--export-wgem-json", "--import-wgem-json",
feat(pipeline): add WGLD (Wowee Guild) catalog format Novel open replacement for AzerothCore-style guild + guild_member + guild_rank + guild_bank_tab + guild_perk SQL tables. The 36th open format added to the editor. Each guild entry holds the complete social-organization state: header (name, leader, faction, MOTD, info, creation date, level + experience, bank money, packed emblem), rank ladder with permissions bitmask + daily withdraw caps, member roster with rank + join date + public/officer notes, bank tabs with per-tab and per-rank deposit / withdraw / view permission masks, and purchased guild perks referencing WSPL spell IDs. Cross-references with previously-added formats: WGLD.entry.factionId ~ WCHC.race.factionId (guilds are faction-locked) WGLD.entry.perks.spellId -> WSPL.entry.spellId Format: • magic "WGLD", version 1, little-endian • per guild: header (12 scalar fields + 4 strings) + ranks[] + members[] + bankTabs[] + perks[] • per rank: rankIndex / name / permissionsMask / moneyPerDayCopper • per member: characterName / rankIndex / joinedDate / publicNote / officerNote • per bankTab: tabIndex / name / iconPath / deposit+withdraw+view permission masks • per perk: perkId / name / spellId / requiredGuildLevel Enums: • Faction (2): Alliance / Horde • RankPermissionFlags (14): GuildChat / OfficerChat / Invite / Remove / Promote / Demote / SetMotd / EditPublicNote / EditOfficerNote / ViewBank / Deposit / Withdraw / Disband / RepairFromBank API: WoweeGuildLoader::save / load / exists / findById + shared addDefaultRanks helper used by both starter and faction-pair presets. Three preset emitters: • makeStarter — 1 small guild, default 5-rank ladder (GM/Officer/Veteran/Member/Initiate), 3 members borrowing names from WCRT merchants for cross-format consistency • makeFull — 1 fleshed-out guild: 6 ranks (with Recruit added) + 8 members + 4 bank tabs (officer-only withdraw on tabs 3+4) + 3 perks referencing WSPL spell IDs (Heroic Strike / Battle Shout / Thunder Clap as placeholder perk procs) • makeFactionPair — 2 parallel guilds, one Alliance + one Horde, with identical rank structures CLI added (5 flags, 649 documented total now): --gen-guilds / --gen-guilds-full / --gen-guilds-pair --info-wgld / --validate-wgld Validator catches: guildId=0 + duplicates, empty name / leaderName, factionId out of range, no ranks (members can't exist without a rank ladder), member.rankIndex exceeding the highest defined rank (intra-format cross-reference resolution), duplicate bank tabIndices, perks with spellId=0 (perk does nothing).
2026-05-09 18:10:45 -07:00
"--gen-guilds", "--gen-guilds-full", "--gen-guilds-pair",
"--info-wgld", "--validate-wgld",
"--export-wgld-json", "--import-wgld-json",
feat(pipeline): add WPCD (Wowee Player Condition) format Novel open replacement for Blizzard's PlayerCondition.dbc + the AzerothCore-style condition_template SQL tables. The 37th open format added to the editor. Defines reusable boolean conditions that other formats can reference for gating: "player has quest X completed", "player level >= N", "player class is mage", "player has item Y in inventory", "WSEA event Z is active". Conditions can be grouped and combined with AND/OR aggregators on a per-group basis: a quest-giver gossip option that says "show only to level 60 alliance mages who completed quest 1234" composes 4 conditions sharing the same groupId with AND aggregation. The runtime walks each group, applies the group's aggregator, and returns the boolean result to the caller. Cross-references with previously-added formats — the targetId field has a polymorphic interpretation by kind: WPCD.targetId (kind=QuestCompleted/Active) -> WQT.questId WPCD.targetId (kind=HasItem) -> WIT.itemId WPCD.targetId (kind=HasSpell) -> WSPL.spellId WPCD.targetId (kind=HasAchievement) -> WACH.achievementId WPCD.targetId (kind=AreaId) -> WMS.areaId WPCD.targetId (kind=EventActive) -> WSEA.eventId WPCD.targetId (kind=HasTitle) -> WTIT.titleId WPCD.targetId (kind=FactionRep) -> WFAC.factionId WPCD.targetId (kind=Class/Race) -> WCHC class/race id Future format extensions can reference WPCD.conditionId in their own gating fields — WTRG triggers gated by player state, WGSP options visible only when conditions are met, WMOU summon spells condition-gated by quest progress, etc. Format: • magic "WPCD", version 1, little-endian • per condition: conditionId / groupId (0 = standalone) / name / description / kind / aggregator / negated / targetId / minValue / maxValue Enums: • Kind (17): AlwaysTrue / AlwaysFalse / QuestCompleted / QuestActive / HasItem / HasSpell / MinLevel / MaxLevel / ClassMatch / RaceMatch / FactionRep / HasAchievement / TeamSize / GuildLevel / EventActive / AreaId / HasTitle • Aggregator (2): And / Or API: WoweeConditionLoader::save / load / exists / findById. Three preset emitters showcase typical usage: • makeStarter — 4 standalone conditions covering the most common kinds (quest-done / has-item / min-level / class) • makeGated — 5 conditions in 2 groups demonstrating AND-aggregation (alliance + mage + lvl 60) and OR-aggregation (did quest 1 OR quest 100) • makeEvent — 3 event-gated conditions cross-referencing WSEA event IDs (Hallow's End / Brewfest / Winter's Veil) CLI added (5 flags, 656 documented total now): --gen-conditions / --gen-conditions-gated / --gen-conditions-event --info-wpcd / --validate-wpcd Validator catches: conditionId=0 + duplicates, kind / aggregator out of range, kinds requiring targetId having target=0 (skips AlwaysTrue/False, MinLevel/MaxLevel, TeamSize, GuildLevel which use min/max instead), TeamSize with min > max.
2026-05-09 18:18:27 -07:00
"--gen-conditions", "--gen-conditions-gated", "--gen-conditions-event",
"--info-wpcd", "--validate-wpcd",
"--export-wpcd-json", "--import-wpcd-json",
feat(pipeline): add WPET (Wowee Pet System) catalog Novel open replacement for AzerothCore-style pet_template + pet_levelstats SQL + the pet-related subsets of CreatureFamily.dbc + SpellFamilyName.dbc. The 38th open format added to the editor. Defines two related kinds of player-controlled NPCs in one catalog: • Pet families — hunter pet families (Wolf / Cat / Bear / Boar / Raptor / Spider / etc.) with per-family ability sets, base stat multipliers, and diet preferences • Warlock minions — Imp / Voidwalker / Succubus / Felhunter / Felguard, each with their own summon spell, creature template, and ability list Cross-references with previously-added formats: WPET.family.familyId -> WCRT.entry.familyId (matches creature family) WPET.family.abilities.spellId -> WSPL.entry.spellId WPET.minion.summonSpellId -> WSPL.entry.spellId WPET.minion.creatureId -> WCRT.entry.creatureId (used for stat scaling) WPET.minion.abilities.spellId -> WSPL.entry.spellId The starter preset's familyIds (1=Wolf, 2=Cat) match WCRT::FamilyId enum values, so a hunter taming a wolf via WCRT links straight through to WPET ability sets. Format: • magic "WPET", version 1, little-endian • families[]: familyId / name / description / icon / petType / baseAttackSpeed / damageMultiplier / armorMultiplier / dietMask / abilities[] • minions[]: minionId / name / summonSpellId / creatureId / abilities[] (each: spellId / rank / autocastDefault) Enums: • PetType (3): Cunning / Ferocity / Tenacity (WotLK+ talent tree categorization) • DietFlags: Meat / Fish / Bread / Cheese / Fruit / Fungus API: WoweePetLoader::save / load / exists + WoweePet::findFamily / findMinion + dietMaskName helper that decodes a dietMask into a "meat+fish" string. Three preset emitters showcase typical pet catalogs: • makeStarter — 2 hunter families (Wolf + Cat) with full 3-ability sets + 1 warlock Imp • makeHunter — 8 classic hunter families covering all 3 petType categories with appropriate diet masks • makeWarlock — 5 warlock minions each with summon spell ID and creatureId pointing into WCRT CLI added (5 flags, 663 documented total now): --gen-pets / --gen-pets-hunter / --gen-pets-warlock --info-wpet / --validate-wpet Validator catches: ids=0 + duplicates, empty name, petType out of range, baseAttackSpeed<=0 (would divide by zero in DPS calc), dietMask=0 (pet cannot be fed for happiness), minion missing summonSpellId / creatureId.
2026-05-09 18:27:02 -07:00
"--gen-pets", "--gen-pets-hunter", "--gen-pets-warlock",
"--info-wpet", "--validate-wpet",
"--export-wpet-json", "--import-wpet-json",
feat(pipeline): add WAUC (Wowee Auction House) catalog Novel open replacement for Blizzard's AuctionHouse.dbc + the AzerothCore-style auctionhouse / auctionhousebot SQL tables. The 39th open format added to the editor. Defines per-house rules for the auction system: faction access, deposit rate (basis points of buyout price), house cut on successful sale, three listing duration tiers with per-tier deposit multipliers, disallowed item-class bitmask, and the auctioneer NPC. Cross-references with previously-added formats: WAUC.entry.auctioneerNpcId -> WCRT.entry.creatureId (Auctioneer-flagged NPC) WAUC.entry.disallowedClassMask bitmask of WIT.Class values that may not be auctioned at this house The faction-pair preset captures the canonical asymmetry: faction houses charge 5% on a successful sale while neutral houses charge 15% — the cross-faction tax that makes neutral AHs profitable for goblins. Format: • magic "WAUC", version 1, little-endian • per house: houseId / auctioneerNpcId / name / factionAccess / baseDepositRateBp / houseCutRateBp / maxBidCopper / 3 duration hours + 3 deposit multipliers / disallowedClassMask Enums: • FactionAccess (4): Alliance / Horde / Neutral / Both • Rates use basis points: 10000 = 100% API: WoweeAuctionLoader::save / load / exists / findById. Three preset emitters showcase typical auction setups: • makeStarter — 1 neutral house with default 12h / 24h / 48h tiers • makeFactionPair — 3 houses (Stormwind / Orgrimmar / Booty Bay) with auctioneer NPC IDs + canonical faction-vs-neutral cut rates • makeRestricted — 1 house disallowing Containers (1) + Quest items (12) + Keys (13) with tighter durations + 1000g bid cap CLI added (5 flags, 670 documented total now): --gen-auction / --gen-auction-pair / --gen-auction-restricted --info-wauc / --validate-wauc Validator catches: houseId=0 + duplicates, empty name, factionAccess out of range, duration tier=0, durations not in short<=medium<=long order, houseCutRateBp >= 100% (seller loses money on a sale), warns on >50% cut.
2026-05-09 18:34:54 -07:00
"--gen-auction", "--gen-auction-pair", "--gen-auction-restricted",
"--info-wauc", "--validate-wauc",
"--export-wauc-json", "--import-wauc-json",
feat(pipeline): add WCHN (Wowee Chat Channel) catalog Novel open replacement for Blizzard's ChatChannels.dbc + the AzerothCore-style chat_channel SQL tables. The 40th open format added to the editor. Defines the world chat channel system: General, Trade, LookingForGroup, GuildRecruitment, LocalDefense, plus per-zone area channels and custom user-created channels. Each channel has access rules (faction / level), join behavior (auto vs opt-in), broadcast policy (announce / moderated), and optional area / map gating that auto-joins or auto-leaves the channel as the player moves. Cross-references with previously-added formats: WCHN.entry.areaIdGate -> WMS.area.areaId (channel auto-attaches in this area) WCHN.entry.mapIdGate -> WMS.map.mapId (channel auto-attaches on this map) Format: • magic "WCHN", version 1, little-endian • per channel: channelId / name / description / channelType / factionAccess / autoJoin / announce / moderated / minLevel / areaIdGate / mapIdGate Enums: • ChannelType (10): AreaLocal / Zone / Continent / World / Trade / LookingForGroup / GuildRecruit / LocalDefense / Custom / Pvp • FactionAccess (3): Alliance / Horde / Both API: WoweeChannelLoader::save / load / exists / findById. Three preset emitters: • makeStarter — 4 stock channels (General Zone + Trade + LFG + GuildRecruit) with default autoJoin policies • makeCity — 5 city-specific channels (3 Stormwind + 2 Orgrimmar) with mapId / areaId gates so they auto-attach on entry • makeModerated — 3 moderated / restricted channels (LocalDefense level 10+, WorldDefense moderated, RaidCoordination level 60+) CLI added (5 flags, 677 documented total now): --gen-channels / --gen-channels-city / --gen-channels-moderated --info-wchn / --validate-wchn Validator catches: channelId=0 + duplicates, empty name, unknown channelType / factionAccess, world / continent channel with area or map gate (gate is silently ignored at runtime — usually a typo), minLevel=0 (no level gate at all).
2026-05-09 18:43:26 -07:00
"--gen-channels", "--gen-channels-city", "--gen-channels-moderated",
"--info-wchn", "--validate-wchn",
"--export-wchn-json", "--import-wchn-json",
"--gen-cinematics", "--gen-cinematics-intros", "--gen-cinematics-quests",
"--info-wcms", "--validate-wcms",
"--export-wcms-json", "--import-wcms-json",
"--gen-glyphs", "--gen-glyphs-warrior", "--gen-glyphs-universal",
"--info-wgly", "--validate-wgly",
"--export-wgly-json", "--import-wgly-json",
"--gen-vehicles", "--gen-vehicles-siege", "--gen-vehicles-flying",
"--info-wvhc", "--validate-wvhc",
"--export-wvhc-json", "--import-wvhc-json",
"--gen-holidays", "--gen-holidays-weekly", "--gen-holidays-special",
"--info-whol", "--validate-whol",
"--export-whol-json", "--import-whol-json",
"--gen-liquids", "--gen-liquids-magical", "--gen-liquids-hazardous",
"--info-wliq", "--validate-wliq",
"--export-wliq-json", "--import-wliq-json",
"--info-magic", "--summary-dir", "--rename-by-magic",
"--bulk-rename-by-magic", "--touch-tree", "--tree-summary-md",
"--catalog-grep", "--diff-headers", "--audit-tree",
"--catalog-pluck", "--catalog-find", "--catalog-by-name",
"--catalog-id-range",
"--magic-fix", "--bulk-validate",
"--bulk-export-json", "--bulk-import-json",
"--diff-tree", "--orphan-jsons", "--list-by-magic",
"--catalog-stats",
"--gen-animations", "--gen-animations-combat", "--gen-animations-movement",
"--info-wani", "--validate-wani",
"--export-wani-json", "--import-wani-json",
"--gen-svk", "--gen-svk-combat", "--gen-svk-utility",
"--info-wsvk", "--validate-wsvk",
"--export-wsvk-json", "--import-wsvk-json",
"--gen-wsui", "--gen-wsui-wintergrasp", "--gen-wsui-dungeon",
"--info-wwui", "--validate-wwui",
"--export-wwui-json", "--import-wwui-json",
"--gen-pcn", "--gen-pcn-quest-gates", "--gen-pcn-composite",
"--info-wpcn", "--validate-wpcn",
"--export-wpcn-json", "--import-wpcn-json",
feat(pipeline): add WTSK (Wowee Trade Skill / Recipe) catalog New open format — replaces SkillLineAbility.dbc plus the recipe portions of SkillLine.dbc plus the AzerothCore trade_skill SQL tables. Closes the crafting gap left by WSKL (which carries skill lines but not the recipes that bind to them). 14 professions (Blacksmithing, Tailoring, Engineering, Alchemy, Enchanting, Leatherworking, Jewelcrafting, Inscription, Mining, Skinning, Herbalism, Cooking, FirstAid, Fishing). Each recipe has 4 skill-up bracket thresholds (orange / yellow / green / gray) for skill-up probability, a craft spell cross-ref (WSPL), produced item cross-ref (WIT) with min/max quantity range, an optional tool item, and up to 4 reagent slots (itemId + count). Cross-references with prior formats — craftSpellId points at WSPL.spellId, producedItemId / toolItemId / reagent[].itemId all point at WIT.itemId, and skillId points at WSKL.skillId. CLI: --gen-tsk (3-recipe entry-tier starter), --gen-tsk- blacksmithing (5-recipe progression rough sharpening through truesilver champion), --gen-tsk-alchemy (5-recipe progression minor healing through flask of titans), --info-wtsk, --validate-wtsk with --json variants. Validator catches id=0/duplicates, profession out of range, missing craft spell or produced item, monotonic-bracket check (must be orange <= yellow <= green <= gray), reagent itemId-without-count mismatch, and free-recipe warning (no reagents and no tool). Format graph now exposes 49 distinct binary formats. CLI flag count: 747 → 752.
2026-05-09 19:41:49 -07:00
"--gen-tsk", "--gen-tsk-blacksmithing", "--gen-tsk-alchemy",
"--info-wtsk", "--validate-wtsk",
"--export-wtsk-json", "--import-wtsk-json",
feat(pipeline): add WCEQ (Wowee Creature Equipment) — 50th open format Replaces the AzerothCore-style creature_equip_template SQL tables plus the visible-weapon / shield / ranged-slot data that was traditionally embedded in creature templates. Closes a long-standing gap in the creature subsystem: until now WCRT defined a creature's stats, WSPN placed it in the world, and WLOT defined what it drops — but nothing defined what items it visibly equips. Each entry binds a creatureId to up to three equipped items (main hand / off hand / ranged) plus the visual kit that fires when the main-hand weapon is brandished. equipFlags bits encode hidden / dual-wield / shield-offhand / thrown-ranged / 2H polearm to drive the renderer's attachment-point selection. Cross-references with prior formats — creatureId points at WCRT.creatureId, mainHandItemId / offHandItemId / rangedItemId all point at WIT.itemId, and mainHandVisualId points at WSVK.visualKitId so brandished weapons can play their signature glow / aura. CLI: --gen-ceq (3 generic guard/hunter/rogue starters), --gen-ceq-bosses (4 iconic loadouts incl. Frostmourne and Illidan's warglaives, with WSVK visual cross-refs), --gen-ceq-ranged (3 ranged-only rifle/bow/crossbow loadouts), --info-wceq, --validate-wceq with --json variants. Validator catches id=0/duplicates, missing creatureId, all-empty-slots warning, kFlagDualWield without both hand items, kFlagShield without offhand item, mutually-exclusive dual-wield + shield, and 2H polearm with offhand item filled. Format graph milestone: 50 distinct binary formats. CLI flag count: 754 → 760.
2026-05-09 19:48:13 -07:00
"--gen-ceq", "--gen-ceq-bosses", "--gen-ceq-ranged",
"--info-wceq", "--validate-wceq",
"--export-wceq-json", "--import-wceq-json",
feat(pipeline): add WSET (Wowee Item Set / Tier Bonus) catalog 51st open format — replaces ItemSet.dbc + ItemSetSpell.dbc plus the AzerothCore-style item_set_spell SQL data. Closes the tier-bonus gap left by WIT (which describes individual items but not the set bonuses they grant when worn together). Each entry binds up to 8 piece item IDs to up to 4 bonus thresholds — at N pieces worn, the matching bonus spell activates as an aura. Standard 2/4/6/8-piece tier set pattern is the canonical case; 5-piece PvP sets with 2/4 bonuses are also supported. Cross-references with prior formats — itemIds[] point at WIT.itemId, bonusSpellIds[] point at WSPL.spellId, and requiredSkillId points at WSKL.skillId. requiredClassMask is a 32-bit field (uint32_t) so bit positions match WCHC's classId enum directly — Druid (bit 11 = 0x800) and Mage (bit 8 = 0x100) wouldn't fit in a uint8_t. CLI: --gen-itset (2 raid sets — Battlegear of Wrath + Stormrage Raiment, real WoW item/spell IDs), --gen-itset-tier (4 tier-1 progression sets covering plate / cloth / leather / holy plate), --gen-itset-pvp (3 PvP gladiator 5-piece sets with honor-rank skill thresholds), --info-wset, --validate-wset with --json variants. Validator catches id+name+pieceCount required, pieceCount/bonusCount within array bounds, piece- slot drift (0 IDs within count or non-0 IDs past count), bonus thresholds strictly ascending, no bonus threshold exceeding pieceCount (would never trigger), and spellId=0 in any populated bonus slot. Format graph: 50 → 51 binary formats. CLI flag count: 762 → 767.
2026-05-09 19:54:36 -07:00
"--gen-itset", "--gen-itset-tier", "--gen-itset-pvp",
"--info-wset", "--validate-wset",
"--export-wset-json", "--import-wset-json",
feat(pipeline): add WGTP (Wowee Game Tips) catalog 52nd open format — replaces GameTips.dbc plus loading-screen tutorial hint tables. Defines the rotating tips shown during world loads, the contextual tutorial hints that fire on first gameplay events (first quest accept, first death, first dungeon entry), and the persistent tooltip-help strings that explain UI elements. 4 display kinds (LoadingScreen / Tutorial / TooltipHelp / Hint), 7 audience-filter bits (Alliance / Horde / NewPlayer / Hardcore / PvE / PvP / Roleplay) for pool selection, level range gating (minLevel + maxLevel), displayWeight for relative frequency within the pool, optional WPCN condition cross-ref for further gating, and class-mask restriction matching WCHC bit positions. Cross-references with prior formats — conditionId points at WPCN.conditionId for advanced gating; requiredClassMask uses the same WCHC.classId bit layout as WGLY/WSET. CLI: --gen-tips (3 generic loading-screen tips), --gen-tips- new-player (5 onboarding Tutorial-kind tips for level 1-15, weighted higher for new players), --gen-tips-advanced (4 endgame tips for level 70+ covering raid mechanics / arena / daily professions / dungeon finder), --info-wgtp, --validate-wgtp with --json variants. Validator catches id/name/text required, kind 0..3, audienceFilter=0 (tip never shown), invalid level range, displayWeight=0 (in pool but never picked) warning, and brevity check (>280 chars) on Tutorial / Hint kinds that need to fit on screen. Format graph: 51 → 52 binary formats. CLI flag count: 770 → 775.
2026-05-09 20:00:56 -07:00
"--gen-tips", "--gen-tips-new-player", "--gen-tips-advanced",
"--info-wgtp", "--validate-wgtp",
"--export-wgtp-json", "--import-wgtp-json",
2026-05-09 20:05:06 -07:00
"--gen-cmp", "--gen-cmp-rare", "--gen-cmp-faction",
"--info-wcmp", "--validate-wcmp",
"--export-wcmp-json", "--import-wcmp-json",
feat(pipeline): add WSMC (Wowee Spell Mechanic) catalog 54th open format — replaces SpellMechanic.dbc plus the AzerothCore-style diminishing-returns (DR) tables. Defines crowd-control mechanic categories that spells reference: Stun, Silence, Polymorph, Sleep, Fear, Root, Snare, Slow, Knockback, etc. Each mechanic carries gameplay metadata (breaks-on-damage, can-be-dispelled, default duration, max stacks) plus DR category and dispel type. 8 DR categories (DRNone / DRStun / DRDisorient / DRSilence / DRRoot / DRPolymorph / DRControlled / DRMisc) — the runtime uses these to gate repeated CC on the same target. 7 dispel types (DispelNone / Magic / Curse / Disease / Poison / Enrage / Stealth) bind which dispel spells can remove the mechanic. conflictsMask is a bitmask of OTHER mechanic IDs — only one mechanic from a conflict-group can apply to a target simultaneously. Cross-references with prior formats — mechanicId is referenced by WSPL.spellId entries that apply this CC; this catalog is referenced from spell tags rather than referencing out. CLI: --gen-smc (3 baseline Stun/Silence/Snare), --gen-smc- hard (5 hard-CC: Stun/Polymorph/Sleep/Fear/Knockback with conflictsMask wiring), --gen-smc-roots (4 movement-impair: Root/Snare/Slow stacking 5x/GroundPin breaks-on-damage), --info-wsmc, --validate-wsmc with --json variants. Validator catches id+name required, DR category 0..7, dispel type 0..6, maxStacks=0 (mechanic could never apply), canBeDispelled+DispelNone inconsistency, and self-conflict bit set in conflictsMask (mechanic blocking itself). Format graph: 53 → 54 binary formats. CLI flag count: 784 → 789.
2026-05-09 20:09:44 -07:00
"--gen-smc", "--gen-smc-hard", "--gen-smc-roots",
"--info-wsmc", "--validate-wsmc",
"--export-wsmc-json", "--import-wsmc-json",
"--gen-kbd", "--gen-kbd-movement", "--gen-kbd-ui",
"--info-wkbd", "--validate-wkbd",
"--export-wkbd-json", "--import-wkbd-json",
feat(pipeline): add WSCH (Wowee Spell School) catalog 56th open format — replaces SpellSchools.dbc plus the Resistances.dbc resistance-cap tables. Defines damage schools spells use: Physical, Holy, Fire, Nature, Frost, Shadow, Arcane, plus combined / hybrid schools that count as multiple types simultaneously (Spellfire, Spellshadow, Spellfrost — relevant for resistance-bypass mechanics). 7 canonical schools with single-bit IDs (1, 2, 4, 8, 16, 32, 64) so combinedSchoolMask values line up directly with the spell engine's school-bit enum. Hybrid schools use high-bit IDs (0x80000001+) and their combinedSchoolMask references the canonical bits they qualify as. Each school carries visual identity (color tint, icon), gameplay rules (canBeImmune / canBeAbsorbed / canBeReflected / canCrit), resistance cap at max level, and cast / impact sound IDs. Cross-references with prior formats — castSoundId and impactSoundId point at WSND.soundId; combinedSchoolMask is a bitmask of OTHER WSCH.schoolId values within the same catalog. CLI: --gen-sch (3 base — Physical / Fire / Holy showing non-resistable Holy + non-reflectable Physical), --gen-sch- magical (6 canonical magical schools with proper colors + 365 max-level resistance caps), --gen-sch-combined (3 hybrids — Spellfire / Spellshadow / Spellfrost with multi-bit combinedSchoolMask), --info-wsch, --validate-wsch with --json variants. Validator catches id+name required, reflected-without-absorbed warning (reflected damage should be absorbable), self-referential combinedSchoolMask (school qualifying as itself), and combined-mask references to bits not defined in the same catalog (resolved at runtime across catalogs). Format graph: 55 → 56 binary formats. CLI flag count: 798 → 804.
2026-05-09 20:19:34 -07:00
"--gen-sch", "--gen-sch-magical", "--gen-sch-combined",
"--info-wsch", "--validate-wsch",
"--export-wsch-json", "--import-wsch-json",
feat(pipeline): add WLFG (Wowee Looking-for-Group) catalog 57th open format — replaces LFGDungeons.dbc plus the AzerothCore-style dungeon-finder reward tables. Defines the dungeons / raids that the Dungeon Finder / Raid Browser presents to players, with their level brackets, group-size requirements, role requirements (tank / heal / DPS), and queue-completion rewards. 4 difficulty levels (Normal / Heroic / Mythic / Hardmode — the latter for Ulduar-style toggleable boss difficulty), 4 expansion gates (Classic / TBC / WotLK / TurtleWoW), and 3 role-requirement bits (Tank / Heal / DPS — typically all three for queue-formed groups). Cross-references with prior formats — mapId points at WMS.mapId (the instance map), queueRewardItemId points at WIT.itemId (the random reward bag), firstClearAchievement points at WACH.achievementId. CLI: --gen-lfg (3 classic 5-mans Ragefire/Wailing/Deadmines with real WoW mapIds + level brackets), --gen-lfg-heroic (5 WotLK 80-level heroic 5-mans with emblem rewards + real first-clear achievement IDs from Halls of Lightning through Old Kingdom), --gen-lfg-raid (3 raid entries — Naxx-25, Ulduar-25 Hardmode, ToC-25 Mythic), --info-wlfg, --validate-wlfg with --json variants. Validator catches id+name+mapId required, difficulty 0..3, expansion 0..3, minLevel<=maxLevel, recommended-level outside range warning, unusual groupSize warning (5/10/25/40 are canonical), and zero role mask (queue can't form a balanced group). Format graph: 56 → 57 binary formats. CLI flag count: 804 → 811.
2026-05-09 20:24:21 -07:00
"--gen-lfg", "--gen-lfg-heroic", "--gen-lfg-raid",
"--info-wlfg", "--validate-wlfg",
"--export-wlfg-json", "--import-wlfg-json",
feat(pipeline): add WMAC (Wowee Macro / Slash Command) catalog 58th open format — novel format with no direct DBC equivalent. WoW historically stored player macros client-side in the user profile and system slash commands as hardcoded engine handlers; WMAC unifies both into a single structured catalog so default macros, system slash commands, and shipped player presets can be authored, validated, and shipped as content alongside the rest of the open-format graph. 5 macro kinds (SystemSlash for engine /sit /dance handlers, DefaultMacro for shipped presets, PlayerTemplate for user templates, GuildMacro for guild-shared, SharedMacro for account-wide). Multi-line macro bodies are stored verbatim with literal '\n' separators — the client parses /cast / /target / /run lines at runtime. Cross-references with prior formats — requiredClassMask uses WCHC.classId bit positions (Warrior=0x02, etc, same as WGLY/ WSET/WGTP). CLI: --gen-mac (3 system slash — /sit, /dance, /target with [@mouseover] modifier), --gen-mac-combat (4 warrior combat templates — heroic strike spam, charge/intercept stance dance, intercept stance switch, victory rush+bloodthirst fallback — each with default key bindings), --gen-mac-utility (3 universal utility — /follow target, mass /inv with %targetN tokens, /releasecorpse via RepopMe()), --info-wmac, --validate-wmac with --json variants. Validator catches id+name+body required, kind 0..4, body within maxLength cap, body starting with '/' or '#' (slash command or showtooltip annotation), and SystemSlash + classMask warning (slash commands are class- agnostic — restricting them to a class makes no sense). Format graph: 57 → 58 binary formats. CLI flag count: 814 → 819.
2026-05-09 20:30:17 -07:00
"--gen-mac", "--gen-mac-combat", "--gen-mac-utility",
"--info-wmac", "--validate-wmac",
"--export-wmac-json", "--import-wmac-json",
feat(pipeline): add WCHF (Wowee Character Customization Feature) catalog 59th open format — replaces CharHairGeosets.dbc + CharFacialHairStyles.dbc plus the variation portions of CharSections.dbc. Defines per-(race, sex) customization options the character creation screen exposes: skin colors, face variations, hair styles, hair colors, facial hair (beards / mustaches), and race-specific markings (Tauren horns, Draenei tendrils, Blood Elf ears). 9 feature kinds (SkinColor / FaceVariation / HairStyle / HairColor / FacialHair / FacialColor / EarStyle / Horns / Markings) cover the full canonical customization surface. Each entry is one selectable carousel choice for one (race, sex, kind) tuple — variationIndex disambiguates. expansionGate enum gates Blood Elf / Draenei (TBC) and DK features (WotLK) behind the right expansion unlock. Cross-references with prior formats — raceId points at WCHC.race.raceId. requiresExpansion bit positions match the WLFG expansion enum (Classic=0, TBC=1, WotLK=2, Turtle=3) for consistency. CLI: --gen-chf (5 Human Male starter — skin / face / 2 hair styles / facial hair), --gen-chf-bloodelf (8 Blood Elf Female hair styles, requiresExpansion=TBC — the iconic TBC race feature), --gen-chf-tauren (6 Tauren Male features using race-specific Horns kind + 3 facial hair variations), --info-wchf, --validate-wchf with --json variants. Validator catches id+name+raceId+texturePath required, kind 0..8 / sex 0..1 / expansion 0..3, and the critical (race, sex, kind, variation) tuple-uniqueness check — duplicates would shadow each other in the create- character carousel. Format graph: 58 → 59 binary formats. CLI flag count: 819 → 826.
2026-05-09 20:35:21 -07:00
"--gen-chf", "--gen-chf-bloodelf", "--gen-chf-tauren",
"--info-wchf", "--validate-wchf",
"--export-wchf-json", "--import-wchf-json",
feat(pipeline): add WPVP (Wowee PvP Honor / Rank) — 60th open format 60th open format milestone — replaces the AzerothCore-style PvP rank tables plus the vanilla honor-rank reward chains. Defines PvP progression rungs: vanilla honor ranks (Private through Grand Marshal / High Warlord), arena rating brackets (Combatant / Challenger / Rival / Duelist / Gladiator), and battleground rated tiers. 5 rank kinds (VanillaHonor / ArenaRating / BattlegroundRated / WorldPvP / ConquestPoint) cover the canonical PvP progression surface. Each entry carries an alliance-specific name and a horde-specific name (Grand Marshal = High Warlord; arena tiers share the same name on both factions), an honor or rating threshold, and optional gear cross-refs (chest, gloves, shoulders) into WIT. Cross-references with prior formats — titleId points at WTTL.titleId (the unlock title), chest/gloves/shoulders point at WIT.itemId for the matching PvP set, bracketBgId points at WBGD.bgId for battleground-bracket gating. CLI: --gen-pvp (3 vanilla entry tiers Rank2-4 with alliance vs horde alternate names), --gen-pvp-alliance (9 vanilla ranks 6-14 with WTTL+WIT cross-refs and ramping honor thresholds 50k → 260k), --gen-pvp-arena (5 arena rating brackets 1500/1750/2000/2200/2400 with 10/20/40/80/160 emblem rewards), --info-wpvp, --validate-wpvp with --json variants. Validator catches id+name required, kind 0..4, level range valid, faction-name pairing (one set without the other is a typo), threshold monotonicity within a rankKind, arena rating below 1500 floor, and VanillaHonor with minHonor=0 baseline warning. Format graph: 59 → 60 binary formats (milestone). CLI flag count: 826 → 833.
2026-05-09 20:41:09 -07:00
"--gen-pvp", "--gen-pvp-alliance", "--gen-pvp-arena",
"--info-wpvp", "--validate-wpvp",
"--export-wpvp-json", "--import-wpvp-json",
feat(pipeline): add WBNK (Wowee Bag / Bank Slot) catalog 61st open format — replaces ItemBag.dbc plus the bank-storage and special-purpose container tables. Defines every slot the player has access to: equipped bags, bank bags, keyring, soul shard bag, quiver, reagent bag, hunter pet stable. 8 bag kinds (Inventory / Bank / Keyring / Quiver / SoulShard / Stable / Reagent / Wallet) cover the canonical container surface. Each entry has a fixed capacity (or 0 = variable, size set by equipped bag), a display order in the inventory UI, an unlock state with optional gold cost (bank bags ramp through 10s / 1g / 10g / 25g / 50g / 100g matching canonical WoW prices), and an accepts-bag-subclass mask gating which container kinds may be equipped (generic / herb / enchanting / engineer / gem / mining / leather / inscription / quiver / ammo pouch). Cross-references with prior formats — fixedBagItemId points at WIT.itemId for the bag item that always occupies a fixed slot (0 = player-equipable variable slot). CLI: --gen-bnk (5 inventory slots — 16-slot fixed main backpack + 4 player-equippable bag slots accepting generic containers + herb + enchanting bags), --gen-bnk-bank (8 bank bag slots with the canonical WoW unlock cost ramp), --gen-bnk-special (4 special-purpose: 32-slot Keyring fixed, warlock SoulShardBag, hunter ArrowQuiver, hunter HuntersStable for 5 pets), --info-wbnk, --validate-wbnk with --json variants. Validator catches id+name required, kind 0..7, locked-with-zero-cost (slot can never be unlocked), fixed-slot-with-non-zero-mask (equippable bag would be ignored), variable slot with empty mask (no bag can fit), and ambiguous (bagKind, displayOrder) tuples (UI sort would flicker). Format graph: 60 → 61 binary formats. CLI flag count: 833 → 840.
2026-05-09 20:46:06 -07:00
"--gen-bnk", "--gen-bnk-bank", "--gen-bnk-special",
"--info-wbnk", "--validate-wbnk",
"--export-wbnk-json", "--import-wbnk-json",
feat(pipeline): add WRUN (Wowee DK Rune Cost) catalog 62nd open format — replaces RuneCost.dbc plus the DK-specific portions of ChrPowerType. Defines per-spell rune costs (Blood / Frost / Unholy) and runic-power generation / consumption for the Death Knight class. 4 spell tree branches (BloodTree / FrostTree / UnholyTree / Generic) classify which spec uses each rune cost. Each entry binds a spell to its rune cost (how many of each rune kind the spell consumes), an optional anyDeathConvertCost (extra Death-rune-acceptable cost for procced abilities), and a runicPowerCost (negative = generator, positive = spender). Cross-references with prior formats — spellId points at WSPL.spellId (the spell that uses this rune cost). CLI: --gen-rune (3 baseline DK abilities — Death Strike 1F+1U + 20RP gen, Frost Strike pure 40 RP spender, Heart Strike 1B + 10RP gen), --gen-rune-blood (4 blood-tree DK abilities — Heart Strike, Death and Decay AoE, Vampiric Blood tank cooldown, Rune Tap self-heal), --gen-rune-frost (4 frost-tree — Frost Strike, Howling Blast AoE, Obliterate finisher, Icy Touch ranged opener applying Frost Fever), --info-wrun, --validate-wrun with --json variants. Validator catches id+name+spellId required, branch 0..3, no rune cost > 2 (DK only has 2 of each rune type so a higher cost can never be paid), runicPowerCost > 100 (DK RP cap), no-cost warning (spell consumes nothing — verify it's a passive/stance/form), and high-RP-generator warning (> 25 RP per cast is unusual). Format graph: 61 → 62 binary formats. CLI flag count: 840 → 847.
2026-05-09 20:52:19 -07:00
"--gen-rune", "--gen-rune-blood", "--gen-rune-frost",
"--info-wrun", "--validate-wrun",
"--export-wrun-json", "--import-wrun-json",
feat(pipeline): add WLDS (Wowee Loading Screen) catalog 63rd open format — replaces LoadingScreens.dbc plus the per-zone background-image tables. Defines the loading-screen images shown when the client crosses into a new map / instance, with optional level-bracket gating and expansion gating (TBC art only shown if expansion installed). When multiple screens match the player's current map + level + expansion, displayWeight selects randomly between them — a zone with 3 weighted variants gets a different image roughly proportional to weight. 4 expansion gates (Classic / TBC / WotLK / TurtleWoW), isAnimated flag for screens with subtle animation, isWideAspect flag for 16:9 raid intro art (vs 4:3 standard). Cross-references with prior formats — mapId points at WMS.map.mapId (which map triggers this loading screen); mapId=0 is the catch-all sentinel for screens shown when no map-specific screen matches. CLI: --gen-lds (3 base screens — Elwynn level 1-30, Orgrimmar, GenericFallback level 31-80 catch-all), --gen-lds-instances (5 WotLK dungeon screens with mapId+expansion cross-refs: Halls of Lightning/Stone, Utgarde Pinnacle, Violet Hold, Old Kingdom), --gen-lds-raid (3 raid intro screens — Naxxramas/Ulduar/ToC at isWideAspect=1 with weight=3), --info-wlds, --validate-wlds with --json variants. Validator catches id+name+texture required, expansion 0..3, level range valid, weight=0 (in pool but never picked), and the practical catch-all overlap warning when multiple mapId=0 screens share overlapping level brackets (random pick becomes non-deterministic). Format graph: 62 → 63 binary formats. CLI flag count: 847 → 854.
2026-05-09 20:59:25 -07:00
"--gen-lds", "--gen-lds-instances", "--gen-lds-raid",
"--info-wlds", "--validate-wlds",
"--export-wlds-json", "--import-wlds-json",
feat(pipeline): add WSUF (Wowee Item Random Suffix) catalog 64th open format — replaces ItemRandomProperties.dbc + ItemRandomSuffix.dbc plus the AzerothCore-style suffix-roll tables. Defines random "of the X" suffixes that roll on green and blue items at world drop ("Sturdy Cloth Cap of the Bear" = base item + STR + STA suffix). 5 suffix categories (Generic / Elemental / Defensive / PvPSuffix / Crafted), per-suffix item-quality bracket gating (only blue+ items can roll PvPSuffix), restricted-slot mask that limits which equipment slots a suffix can apply to (15 slot bits matching WCEQ slot enum), and up to 5 stat bonus slots per suffix matching WoW canonical max. statValuePoints isn't an absolute number — it's a scaling base that the runtime multiplies by an item-level coefficient to compute the final per-item bonus, so "of the Bear" gives proportionally more strength on a level-60 item than on a level-20 item. Cross-references with prior formats — statKind values match WIT.statType enum (STR=4, AGI=3, INT=5, SPI=6, STA=7) so item generators roll consistent stats with base items. CLI: --gen-suf (3 generic stat triads — Bear STR+STA, Eagle INT+SPI, Tiger STR+AGI), --gen-suf-magical (4 elemental spell-power suffixes restricted to caster-eligible slots), --gen-suf-pvp (3 PvPSuffix entries with resilience + offensive stats, blue+ quality only), --info-wsuf, --validate-wsuf with --json variants. Validator catches id+name required, category 0..4, quality range valid (0..7 covers heirloom), itemQuality floor<=ceiling, stat-kind/value pairing (kind=0 with value!=0 is a typo, vice versa), and no-stats warning (suffix renames item without changing it). Format graph: 63 → 64 binary formats. CLI flag count: 854 → 861.
2026-05-09 21:05:49 -07:00
"--gen-suf", "--gen-suf-magical", "--gen-suf-pvp",
"--info-wsuf", "--validate-wsuf",
"--export-wsuf-json", "--import-wsuf-json",
"--gen-crr", "--gen-crr-defensive", "--gen-crr-spell",
"--info-wcrr", "--validate-wcrr",
"--export-wcrr-json", "--import-wcrr-json",
feat(pipeline): add WUMV (Wowee Unit Movement Type) catalog 66th open format — replaces UnitMovement.dbc plus the movement-modifier portions of CreatureModelData.dbc. Defines movement speed types (walk / run / swim / flight / fly / pitch) with their canonical baseline speeds in yards-per- second, plus the temp speed buffs that stack on top (Sprint, Aspect of the Cheetah, Travel Form). 12 movement categories cover the canonical surface (Walk / Run / Backward / Swim / SwimBack / Turn / Flight / FlightBack / Pitch / Fly / FlyBack / TempBuff). baseSpeed is yards/second for baseline categories and ignored for TempBuff entries (which use baseMultiplier instead). maxMultiplier caps stacking — Sprint capped at 1.4 means Sprint + Aspect of Cheetah doesn't exceed 1.4× run speed. stackingPriority resolves conflicts when multiple buffs of equal multiplier compete (higher wins). CLI: --gen-umv (4 baseline at canonical WoW vanilla speeds: Walk 2.5y/s, Run 7.0y/s, Swim 4.7y/s, Turn π rad/s), --gen-umv-flight (5 flight entries — ground-rail Flight 7y/s, free Fly 14y/s, Pitch 1.5 rad/s, backward variants at slower 4.5y/s), --gen-umv-buffs (5 temp speed buffs matching real WoW spell auras with proper durations and stacking priorities), --info-wumv, --validate-wumv with --json variants. Validator catches id+name required, category 0..11, baseMultiplier > 0 (otherwise unit freezes in place), maxMultiplier >= baseMultiplier (cap below floor would clamp the base down), baseline categories need baseSpeed > 0, and Run < 3.0y/s warning (canonical is 7.0y/s). Format graph: 65 → 66 binary formats. CLI flag count: 870 → 875.
2026-05-09 21:18:03 -07:00
"--gen-umv", "--gen-umv-flight", "--gen-umv-buffs",
"--info-wumv", "--validate-wumv",
"--export-wumv-json", "--import-wumv-json",
feat(pipeline): add WQSO (Wowee Quest Sort) catalog 67th open format — replaces QuestSort.dbc plus the quest-log categorization fields in QuestInfo.dbc. Defines the categories that quests fall into for the quest-log UI: class quests (Warrior trial, etc), profession quests, daily quests, holiday events, reputation grinds, dungeon / heroic / raid quests, repeatables, PvP, tournament. 12 sort kinds (General / ClassQuest / Profession / Daily / Holiday / Reputation / Dungeon / Raid / Heroic / Repeatable / PvP / Tournament). Each WQT (quest) entry can reference a sortId here to be grouped under the right header in the quest log. Sorts can be class-restricted (Warrior quests only show for warriors), profession-restricted, or faction-reputation-gated. Cross-references with prior formats — targetClassMask uses WCHC.classId bit positions (matches WGLY/WSET/WGTP convention), targetProfessionId points at WTSK.profession enum, targetFactionId points at WFAC.factionId. CLI: --gen-qso (3 generic sorts — General catch-all, Daily reset, Repeatable non-daily), --gen-qso-class (10 class- specific sorts with proper bit masks for Warrior 0x02 through Druid 0x800), --gen-qso-profession (8 profession sorts with WTSK profession enum cross-refs), --info-wqso, --validate-wqso with --json variants. Validator catches id+name+displayName required, kind 0..11, ClassQuest with classMask=0 (not actually class-restricted), Profession with profId=0 + non-Blacksmithing-name (likely typo since 0=Blacksmithing in WTSK), and Reputation with factionId=0 (no faction to grind). Format graph: 66 → 67 binary formats. CLI flag count: 877 → 882.
2026-05-09 21:23:38 -07:00
"--gen-qso", "--gen-qso-class", "--gen-qso-profession",
"--info-wqso", "--validate-wqso",
"--export-wqso-json", "--import-wqso-json",
"--gen-srg", "--gen-srg-ranged", "--gen-srg-friendly",
"--info-wsrg", "--validate-wsrg",
"--export-wsrg-json", "--import-wsrg-json",
"--gen-sct", "--gen-sct-channel", "--gen-sct-ramp",
"--info-wsct", "--validate-wsct",
"--export-wsct-json", "--import-wsct-json",
feat(editor): add WSDR (Spell Duration Index) — completes WSRG/WSCT/WSDR triplet Open replacement for SpellDuration.dbc plus per-spell duration fields in Spell.dbc. Defines the categorical duration buckets that auras / DoTs / HoTs / buffs reference (5s / 30s / 5min / 1hr / UntilCancelled / UntilDeath). Together with WSRG (range) and WSCT (cast time), this completes a small triplet of spell-metadata catalogs: instead of every Frostbolt rank embedding its own range, cast time, and chill-debuff duration as duplicate fields, each spell holds three small integer ids that resolve through these three tables. The engine retunes thousands of spells at once by editing one bucket. Duration scales with caster level via perLevelMs (a rank-1 Renew at 9s grows to 12s at lvl 60), then is clamped to maxDurationMs. Negative baseDurationMs is the canonical sentinel for "no timer" (UntilCancelled / UntilDeath); resolveAtLevel returns -1 for those so HUD code can render the indefinite-duration glyph. Three preset emitters: --gen-sdr (5 baseline tiers from instant to one-hour), --gen-sdr-buffs (4 long-duration buffs including UntilDeath), --gen-sdr-dot (4 tick-based DoT/HoT buckets at 3s ticks). Validation enforces base>0 for Timed/TickBased, base<0 for permanent kinds, max>=base, durationKind 0..4, no duplicate ids, and warns on Instant+nonzero base. Wired through the cross-format table; WSDR appears automatically in all 9 cross-format utilities. Format count 69 -> 70; CLI flag count 899 -> 904.
2026-05-09 21:41:55 -07:00
"--gen-sdr", "--gen-sdr-buffs", "--gen-sdr-dot",
"--info-wsdr", "--validate-wsdr",
"--export-wsdr-json", "--import-wsdr-json",
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.
2026-05-09 21:49:13 -07:00
"--gen-cdb", "--gen-cdb-class", "--gen-cdb-items",
"--info-wscd", "--validate-wscd",
"--export-wscd-json", "--import-wscd-json",
feat(editor): add WCEF (Creature Family) open catalog format Open replacement for CreatureFamily.dbc plus the per-creature family fields in Creature.dbc. Defines the family categorization that pet-able beasts share (Bear / Cat / Wolf / Boar / Crab / Raptor / Devilsaur / etc), each with its own pet talent tree (Ferocity / Tenacity / Cunning), food preferences as a bitmask (Meat / Fish / Bread / Cheese / Fruit / Fungus / Raw), the skill line that family-specific abilities reference, and the minimum hunter level required to tame it. Used by the hunter pet system to decide which talent tree a tamed pet uses, validate that a hunter can tame a creature, match feeding-table food items to pet preferences, and gate exotic-beast families behind the Beast Master 51-point talent. Cross-references back to WCRT (creature.familyId points here) and WSPL (family-specific abilities reference WSPL spellId via the skillLine field). Three preset emitters: --gen-cef (5 baseline families covering both major talent trees), --gen-cef-ferocity (4 DPS-tree pets with bleed/howl/armor-shred mechanics), --gen-cef-exotic (4 exotic Beast Master families requiring 51-point talent). Validation enforces id+name presence, familyKind 0..5, talent tree 0..3, no duplicate ids, and warns on: - NotPet families with a non-None talent tree (irrelevant) - Exotic families with minLevelForTame > 80 (level-cap unreachable) - Beast/Exotic families with no food types set (pet would starve) Wired through the cross-format table; WCEF appears automatically in all 10 cross-format utilities. Format count 71 -> 72; CLI flag count 914 -> 919.
2026-05-09 21:54:00 -07:00
"--gen-cef", "--gen-cef-ferocity", "--gen-cef-exotic",
"--info-wcef", "--validate-wcef",
"--export-wcef-json", "--import-wcef-json",
feat(editor): add WSPC (Spell Power Cost) — completes spell-bucket five-pack Open replacement for the per-spell power-cost fields in Spell.dbc plus SpellPowerCost-related side tables. Defines categorical power-cost buckets that spells reference (LowMana 5% / MediumMana 15% / HighMana 30% of caster max mana; fixed Rage-30 / Energy-40 / Runic-30 / etc), so spells share cost metadata across ranks instead of embedding per-rank cost numbers. Completes the small lookup-bucket five-pack: WSRG — range bucket WSCT — cast time bucket WSDR — duration bucket WSCD — cooldown bucket WSPC — power cost bucket (this catalog) Five small integer ids per spell (range / cast / dur / cd / cost) replace the dozens of duplicate per-rank fields that Blizzard's Spell.dbc carries. Editing one bucket here retunes every spell that references it — change LowMana from 5% to 4% and every rank-1 bolt across every caster class becomes cheaper. Cost can be flat (baseCost), per-level scaled (perLevelCost), or percentage-of-max-power (percentOfBase) — the engine sums whichever fields are non-zero. resolveCost(id, level, maxPower) does the math. Twelve power types covering every WoW resource (Mana / Rage / Focus / Energy / Happiness / Runic Power / Runes / Soul Shards / Holy Power / Eclipse / Health / NoCost). Three preset emitters: --gen-spc (4 baseline mana tiers), --gen-spc-rage (4 fixed warrior rage costs including stance-locked Whirlwind), --gen-spc-mixed (5 cross-class costs covering every non-mana power type with refund-on-miss flag for energy). Validation enforces id+name presence, powerType 0..11, no duplicate ids; warns on percentOfBase outside [0,1] (would overflow), NoCost type with non-zero cost fields, and non-NoCost types with no cost set (would cast for free — easy bug to ship). Wired through the cross-format table; WSPC appears automatically in all 11 cross-format utilities. Format count 72 -> 73; CLI flag count 922 -> 927.
2026-05-09 22:00:55 -07:00
"--gen-spc", "--gen-spc-rage", "--gen-spc-mixed",
"--info-wspc", "--validate-wspc",
"--export-wspc-json", "--import-wspc-json",
feat(editor): add WGFS (Glyph Slot) open catalog format Open replacement for Blizzard's GlyphSlot.dbc. Defines the per-class glyph slot layout: which slots a class has (Major / Minor / Prime), in which display order they appear in the spellbook UI, and at which character level each slot becomes available for use. Distinct from WGLY (GlyphProperties) which defines the individual glyphs themselves. WGLY says "Glyph of Polymorph exists, costs 1 inscription dust, modifies Polymorph"; WGFS says "the slot that holds Glyph of Polymorph is the second Major Glyph Slot, unlocks at level 25, and only Mages have it". Layout grew across expansions, captured by the three presets: - --gen-gfs — 6 slots: 3 Major + 3 Minor all-class baseline (25/50/75 each) - --gen-gfs-wotlk — 6 slots: 3 Major (15/30/50) + 3 Minor (15/50/70) matching WotLK 3.3.5a - --gen-gfs-cata — 9 slots: 3 Prime + 3 Major + 3 Minor matching Cataclysm Cross-references back to WGLY (glyphs reference slotKind to constrain which glyph fits which slot) and WCHC (requiredClassMask uses the same bit layout as WCHC class IDs). Validation enforces id+name+classMask presence (classMask=0 means no class can use the slot — usually a config bug), slotKind 0..2, no duplicate ids; warns on minLevelToUnlock>80 (would never unlock at WotLK cap), displayOrder>4 (UI typically shows 3-4), and (kind+order) collisions for overlapping classMask (two slots claiming the same UI position would render on top of each other). isUnlockedFor(id, classBit, level) is the engine helper. Wired through the cross-format table; WGFS appears automatically in all 11 cross-format utilities. Format count 73 -> 74; CLI flag count 929 -> 934.
2026-05-09 22:05:05 -07:00
"--gen-gfs", "--gen-gfs-wotlk", "--gen-gfs-cata",
"--info-wgfs", "--validate-wgfs",
"--export-wgfs-json", "--import-wgfs-json",
feat(editor): add WCDF (Creature Difficulty) open catalog format Open replacement for Blizzard's CreatureDifficulty.dbc. Maps a base creature entry to its difficulty variants: Normal-10 / Normal-25 / Heroic-10 / Heroic-25 in WotLK raid format. Each variant is itself a separate WCRT creature entry with its own stats, abilities, and loot. When a 25-man party engages an instance, the engine looks up the encounter base creature's difficultyId, reads the normal25Id field, and spawns that variant instead. This is how Lord Marrowgar in 25-Heroic ICC has 30M HP and hits for 80k while the same encounter in 10-Normal has 5M HP and hits for 25k — same spawn point, different WCRT entries. 5-man dungeons typically use only normal10Id + heroic10Id (the 25-man fields stay 0 — engine falls through to the 10-man variant when 25-man is queried). World bosses don't scale at all (all 4 variant fields stay 0, engine falls back to the base entry). Cross-references back to WCRT — every non-zero variant id field points at a WCRT.creatureId entry; the base creature itself lives in WCRT too. Three preset emitters: --gen-cdf (4 example bosses with full 4-variant routing), --gen-cdf-wotlk-raid (4 ICC-style raid bosses Marrowgar/Deathwhisper/Saurfang/LK with all 4 difficulty variants), --gen-cdf-fiveman (4 5-man dungeon bosses with only Normal+Heroic 10-man set). resolveVariant(id, mode) is the engine helper. Validation enforces id+name+baseCreatureId presence, spawnGroupKind 0..5, no duplicate ids; warns on: - WorldBoss kind with non-zero variant ids (world bosses don't scale) - duplicate baseCreatureId across routes (only first honored) - all-self-reference non-WorldBoss (creature doesn't actually scale) - Boss with n25 but not n10 (raid sequencing typo — n10 always comes with n25) Wired through the cross-format table; WCDF appears automatically in all 11 cross-format utilities. Format count 74 -> 75; CLI flag count 936 -> 941.
2026-05-09 22:10:09 -07:00
"--gen-cdf", "--gen-cdf-wotlk-raid", "--gen-cdf-fiveman",
"--info-wcdf", "--validate-wcdf",
"--export-wcdf-json", "--import-wcdf-json",
feat(editor): add WMAT (Item Material) open catalog format Open replacement for Blizzard's Material.dbc plus the Material and SheatheType fields in ItemDisplayInfo.dbc. Defines the material categorization that items reference (Cloth / Leather / Mail / Plate / Wood / Steel / Crystal / Ethereal / etc), each with its own foley sound (played on item use), impact sound (played on drop / hit), weight category, and material-property flags (IsBreakable / IsMagical / IsFlammable / IsConductive / IsHolyCharged / IsCursed). The engine plays a sword's metallic clang from impactSoundId when it hits a stone wall, but a cloth tabard makes no such sound — the difference is exactly the material assigned by this catalog. Every armor and weapon item in WIT references a materialId here. Twelve materialKind values cover the standard armor classes (Cloth/Leather/Mail/Plate/Hide), structural materials (Wood / Stone / Metal), and special categories (Liquid / Organic / Crystal / Ethereal). Three weight tiers (Light / Medium / Heavy) control encumbrance UI hints. Cross-references back to WSND (foleySoundId / impactSoundId reference WSND sound entries) and forward to WIT (item entries reference materialId here). Three preset emitters: --gen-mat (5 armor materials matching WoW's armor classes), --gen-mat-weapon (5 weapon materials from breakable+flammable Wood through enchanted endgame steel), --gen-mat-magical (4 magical materials with special flags including the IsHolyCharged anti-undead property). Validation enforces id+name presence, materialKind 0..11, weightCategory 0..2, no duplicate ids; warns on: - IsHolyCharged + IsCursed both set (engine picks one, typically IsCursed wins) - Plate kind that's not Heavy weight (canonical violation) - Cloth kind that's not Light weight (canonical violation) Wired through the cross-format table; WMAT appears automatically in all 11 cross-format utilities. Format count 75 -> 76; CLI flag count 943 -> 948.
2026-05-09 22:14:44 -07:00
"--gen-mat", "--gen-mat-weapon", "--gen-mat-magical",
"--info-wmat", "--validate-wmat",
"--export-wmat-json", "--import-wmat-json",
feat(editor): add WPSP (Player Spawn Profile) open catalog format Open replacement for AzerothCore's playercreateinfo SQL table plus the per-class/race starting fields in CharStartOutfit.dbc. Defines the initial state for a newly created character: starting map / zone / position / facing, bind point (Hearthstone destination), up to 4 starting items with counts, and up to 4 starting spells. One entry per (race, class) combination — a Human Warrior spawns at Northshire Abbey with a Worn Shortsword and Heroic Strike already learned, while an Orc Hunter spawns in Valley of Trials with Aimed Shot and a starter rifle. Death Knights have their own preset spawning at lvl 55 in Acherus, the Ebon Hold. The race+class fields are bitmasks (mirroring WCHC layout) so one profile entry can cover multiple class/race combinations that share starting state. findByRaceClass(raceBit, classBit) is the engine helper used by character creation. Cross-references back to WCHC (race/class bit layouts), WMS (map ids), WIT (starting item ids), and WSPL (starting spell ids). Three preset emitters: --gen-psp (5 Alliance combos covering each starting zone from Northshire to Ammen Vale), --gen-psp-horde (5 Horde combos from Valley of Trials to Sunstrider Isle), --gen-psp-dk (2 DK combos at lvl 55 in Acherus with Death Coil / Plague Strike / Death Grip starter loadout). Validation enforces id+name+race+class+startingLevel presence, no duplicate ids; warns on (0,0,0) spawn (uninitialized entry), item id/count mismatch (granted item without count or vice versa), startingLevel > 80 (above WotLK cap), and Death Knight class with startingLevel < 55 (DKs canonically start at 55). Wired through the cross-format table; WPSP appears automatically in all 12 cross-format utilities. Format count 76 -> 77; CLI flag count 951 -> 956.
2026-05-09 22:22:57 -07:00
"--gen-psp", "--gen-psp-horde", "--gen-psp-dk",
"--info-wpsp", "--validate-wpsp",
"--export-wpsp-json", "--import-wpsp-json",
feat(editor): add WTLE (Talent Tab) open catalog format Open replacement for Blizzard's TalentTab.dbc plus the per-tab fields in Spell.dbc / Talent.dbc. Defines the three talent trees that each class has — Warrior: Arms / Fury / Protection; Mage: Arcane / Fire / Frost; Paladin: Holy / Protection / Retribution; etc. Each tab carries its own name, role hint (DPS / Tank / Healer / Hybrid / PetClass), display order in the talent UI, background artwork path (e.g. "WarriorArms" for the parchment background), icon path, and the class bitmask it belongs to. Distinct from WTAL (which defines individual talent points) — WTLE says "the Arms tree exists for Warriors, displays in tab 1, is a DPS spec"; WTAL says "Mortal Strike is a 1-point talent in the Arms tree, row 7, requires Improved Charge as a prerequisite". Cross-references back to WCHC (classMask uses the same bit layout) and forward to WTAL (talent entries reference tabId here). findByClass(classBit) returns all tabs for a class sorted by displayOrder — the talent UI uses this directly to populate its tab buttons. Three preset emitters: --gen-tle (Warrior 3 tabs with two DPS + one Tank), --gen-tle-mage (Mage 3 DPS tabs), --gen-tle-paladin (Paladin 3 tabs covering all three roles in one preset). Validation enforces id+name+classMask presence (classMask=0 means no class can use the tab — usually a config bug), roleHint 0..4, no duplicate ids; warns on empty iconPath (missing-texture render), empty backgroundFile (no panel art), displayOrder>3 (UI shows at most 4 tabs), and (classMask + displayOrder) collisions for overlapping classes (two tabs claiming the same UI slot for the same class). Wired through the cross-format table; WTLE appears automatically in all 12 cross-format utilities. Format count 77 -> 78; CLI flag count 958 -> 963.
2026-05-09 22:27:18 -07:00
"--gen-tle", "--gen-tle-mage", "--gen-tle-paladin",
"--info-wtle", "--validate-wtle",
"--export-wtle-json", "--import-wtle-json",
feat(editor): add WCTR (Currency Type) open catalog format Open replacement for Blizzard's CurrencyTypes.dbc plus the per-currency cap tables in CurrencyCategory.dbc. Defines the in-game currencies that are NOT regular item stacks: Honor Points, Arena Points, Justice Points, Valor Points, Conquest Points, plus the various faction tokens (Champion's Seal, Wintergrasp Mark of Honor, Emblem of Frost). Distinct from regular items in WIT — currencies are tracked per-character as scalar quantities with weekly + absolute caps, not as stackable inventory slots. Some currencies are still backed by a WIT item entry for the icon and tooltip text (itemId field), while others (Honor, Arena) live entirely in the currency system. The cap model captures both shapes: - maxQuantity = absolute lifetime cap (Honor Points 75k) - maxQuantityWeekly = weekly earn cap, no absolute cap (Conquest Points 1650/wk) - both 0 = uncapped (faction tokens, Emblem of Frost) earnableNow(id, current, weekly) is the engine helper that returns the smaller of (remaining absolute, remaining weekly). Cross-references back to WIT (itemId for tooltip art) and WFAC (categoryId references factionId for FactionToken kind — the rep gate that lets you spend the token). Three preset emitters: --gen-ctr (4 PvP currencies covering absolute, weekly-only, and uncapped tiers), --gen-ctr-pve (4 PvE raid currencies with same cap variety), --gen-ctr-faction (4 faction tokens with their categoryId pointing at WFAC faction ids). Validation enforces id+name presence, currencyKind 0..5, no duplicate ids; warns on: - maxQuantityWeekly > maxQuantity (weekly cap will never be reached, absolute cap blocks first) - FactionToken kind with categoryId=0 (rep gate breaks) - no caps + no itemId + no iconPath (currency has no display data and unbounded earn rate) Wired through the cross-format table; WCTR appears automatically in all 12 cross-format utilities. Format count 78 -> 79; CLI flag count 965 -> 970.
2026-05-09 22:31:42 -07:00
"--gen-ctr", "--gen-ctr-pve", "--gen-ctr-faction",
"--info-wctr", "--validate-wctr",
"--export-wctr-json", "--import-wctr-json",
feat(editor): add WSPR (Spell Reagent) — 80th open format milestone Open replacement for the per-spell reagent fields in Spell.dbc (Reagent[8] + ReagentCount[8]). Defines the item reagents that a spell consumes from the caster's inventory each time it's cast — Mage Portal needs a Rune of Portals, Resurrection needs a Holy Candle (focused, not consumed), Warlock summons consume Soul Shards. One entry per reagent-using spell — most spells have no reagents and are absent from this catalog. Each entry can list up to 8 (itemId, count) pairs which all must be present for the spell to cast. Five reagentKind values capture the variety of reagent semantics: - Standard — ordinary consumed reagent - SoulShard — warlock-specific shard tracking - FocusedItem — required to cast but NOT consumed (Symbol of Divinity for Resurrection) - Catalyst — enables a stronger version of the spell - Tradeable — crafting reagent for trade-skill recipes Cross-references back to WSPL (every entry references a spellId) and WIT (every reagent itemId references an item entry). findBySpell(spellId) is the primary engine lookup. Three preset emitters: --gen-spr (4 mage portal/teleport reagents using Rune of Teleportation 17031), --gen-spr-warlock (4 demon summons each consuming 1 Soul Shard 6265), --gen-spr-rez (3 resurrection variants demonstrating each ReagentKind including a no-reagent Druid Rebirth and a focused-item Priest Resurrection). Validation enforces id+name+spellId presence, reagentKind 0..4, no duplicate ids; warns on: - slot itemId/count mismatch (id without count or vice versa) - SoulShard kind with non-canonical reagent (not item 6265) - FocusedItem kind with no reagent slots set (focused-item gating has nothing to gate) - duplicate spellId across entries (engine honors only first) This is the 80th open format milestone. Wired through the cross-format table; WSPR appears automatically in all 14 cross-format utilities. Format count 79 -> 80; CLI flag count 974 -> 979.
2026-05-09 22:38:36 -07:00
"--gen-spr", "--gen-spr-warlock", "--gen-spr-rez",
"--info-wspr", "--validate-wspr",
"--export-wspr-json", "--import-wspr-json",
feat(editor): add WACR (Achievement Criteria) open catalog format Open replacement for Blizzard's Achievement_Criteria.dbc. Defines the individual progression criteria that a character must complete to earn an achievement. Each WACH achievement has a tree of WACR criteria — "Kill 100 boars" is one criteria entry with criteriaType=KillCreature, targetId=boarCreatureId, requiredCount=100. Multi-criteria achievements (e.g. "Visit all 3 capital cities") have one entry per sub-objective, all referencing the same achievementId, with progressOrder determining their display sequence in the achievement UI. Thirteen criteriaType values cover the full progression variety: KillCreature / ReachLevel / CompleteQuest / EarnGold / GainHonor / EarnReputation / ExploreZone / LootItem / UseItem / CastSpell / PvPKill / DungeonRun / Misc The targetId field is type-polymorphic — for KillCreature it references WCRT.creatureId, for CompleteQuest it references WQT.questId, for ExploreZone it's a WMS.zoneId, etc. The engine interprets it based on criteriaType. Cross-references back to WACH (achievementId), WCRT (KillCreature.targetId), WQT (CompleteQuest.targetId), WIT (LootItem/UseItem.targetId), WMS (ExploreZone.targetId), WSPL (CastSpell.targetId). findByAchievement(achId) returns all criteria for an achievement sorted by progressOrder — used directly by the achievement UI to render the progress checklist. Three preset emitters: --gen-acr (5 kill criteria under one composite achievement showing different creature targets), --gen-acr-quest (4-step quest progression), --gen-acr-mixed (5 cross-type criteria demonstrating the full CriteriaType variety). Validation enforces id+name+achievementId presence, criteriaType 0..12, no duplicate ids; warns on: - missing targetId for type-specific kinds (KillCreature, CompleteQuest, etc. — engine cannot track without it) - ReachLevel with requiredCount > 80 (above WotLK cap) - timeLimitMs set on non-time-sensitive types (engine ignores it for ReachLevel / EarnGold) - requiredCount=0 (criteria completes instantly on first progress event — usually a misconfig) Wired through the cross-format table; WACR appears automatically in all 14 cross-format utilities. Format count 80 -> 81; CLI flag count 981 -> 986.
2026-05-09 22:43:44 -07:00
"--gen-acr", "--gen-acr-quest", "--gen-acr-mixed",
"--info-wacr", "--validate-wacr",
"--export-wacr-json", "--import-wacr-json",
feat(editor): add WSEF (Spell Effect Type) open catalog format Open replacement for the SpellEffect.Effect field meanings in Spell.dbc plus the engine's hard-coded effect dispatch table. Defines what each spell-effect integer value actually does — SCHOOL_DAMAGE=2 deals magical damage, DUMMY=3 is a script hook, HEAL=10 restores health, ENERGIZE=30 restores power, APPLY_AURA=6 attaches a buff/debuff, etc. WotLK's Spell.dbc has 192+ effect type integers, each with its own resolver in the spell engine. This catalog lets the engine look up "given effect=10, what resolution behavior do I run?" via a single table lookup instead of a hard-coded switch statement, and lets server-custom spells reference new effect IDs without touching engine code. Ten effectKind values capture the major behavior families (Damage / Heal / Aura / Energize / Trigger / Movement / Summon / Dispel / Dummy / Misc), and a 6-bit behaviorFlags field captures targeting/gating semantics: - RequiresTarget — must have a target - RequiresLineOfSight — LoS check on target - IsHostileEffect — hostile only (PvP gating) - IsBeneficialEffect — friendly only - IgnoresImmunities — bypasses Bubble / IBF / etc - TriggersGCD — counts toward GCD Distinct from WAUR (Spell Aura Type, future format) which is the secondary classification used when effectType is APPLY_AURA. The two together cover the full spell-effect classification space. Three preset emitters: --gen-sef (5 damage effects covering typical Spell.dbc damage IDs), --gen-sef-healing (4 heal effects all flagged IsBeneficialEffect), --gen-sef-aura (5 aura-application effects covering single-target / pet / party-wide / area variants). Validation enforces name presence, effectKind 0..9, no duplicate ids; warns on: - both Hostile and Beneficial flags set (engine picks Hostile, contradiction suggests config bug) - Damage kind without TriggersGCD (most damage should be on GCD — env damage is the canonical exception) - Heal kind without IsBeneficialEffect (engine treats heal as ungated, may damage enemies) Wired through the cross-format table; WSEF appears automatically in all 15 cross-format utilities. Format count 81 -> 82; CLI flag count 989 -> 994.
2026-05-09 22:50:13 -07:00
"--gen-sef", "--gen-sef-healing", "--gen-sef-aura",
"--info-wsef", "--validate-wsef",
"--export-wsef-json", "--import-wsef-json",
feat(editor): add WAUR (Spell Aura Type) — companion to WSEF, CLI flag count breaks 1000 Open replacement for the SpellEffect.EffectAuraType field meanings used when SpellEffect.Effect=APPLY_AURA. Defines what each aura-type integer value actually does once an aura is attached to a unit — PERIODIC_DAMAGE ticks damage every N seconds, MOD_STAT adds a stat bonus, MOD_INCREASE_SPEED scales movement, MOD_DAMAGE_PERCENT_DONE scales spell power, etc. Companion to WSEF — together they cover the full spell-effect classification space: WSEF: outer effect ID — what does the effect DO? (APPLY_AURA, SCHOOL_DAMAGE, HEAL, etc) WAUR: inner aura type — when WSEF=APPLY_AURA, what KIND of aura is applied? (PERIODIC_DAMAGE, MOD_STAT, STUN, ROOT, etc) Nine auraKind values (Periodic / StatMod / DamageMod / Movement / Visual / Trigger / Resource / Control / Misc) classify the major behavior families. Periodic auras carry an updateFrequencyMs (canonical 3s for DoT/HoT, 2s for energize, 1s for fast triggers). Stackable auras carry a maxStackCount. Cross-references back to WSEF (this catalog is the secondary classification that WSEF entry id 6 (APPLY_AURA) dispatches into) and forward to WSPL (spell entries with effect=APPLY_AURA reference an auraTypeId here). Three preset emitters: --gen-aur (5 periodic auras with canonical tick intervals), --gen-aur-stats (5 stat-modifier auras instantly applied on attach), --gen-aur-movement (4 movement-impairing CC auras typical of crowd-control spells). Validation enforces name presence, auraKind 0..8, targetingHint 0..3, no duplicate ids; errors on Periodic kind without updateFrequencyMs (would never tick); warns on: - non-Periodic/Trigger kinds with updateFrequencyMs > 0 (engine ignores tick interval) - maxStackCount > 0 with isStackable=false (cap unreachable) Wired through the cross-format table; WAUR appears automatically in all 15 cross-format utilities. Format count 82 -> 83; CLI flag count 996 -> 1001 — broke the 1000-flag mark.
2026-05-09 22:54:53 -07:00
"--gen-aur", "--gen-aur-stats", "--gen-aur-movement",
"--info-waur", "--validate-waur",
"--export-waur-json", "--import-waur-json",
feat(editor): add WIQR (Item Quality) open catalog format Open replacement for the hardcoded item quality tiers in the WoW client (Poor / Common / Uncommon / Rare / Epic / Legendary / Artifact / Heirloom). Defines each tier's tooltip text color, inventory slot border color, vendor price multiplier, drop-level gating, and disenchant eligibility. The hardcoded client uses a fixed color table (gray/white/green/ blue/purple/orange/red/gold). This catalog lets server admins: - retune the colors (rename "Epic" to "Tier 1" with custom hex) - add server-custom tiers above Heirloom - change vendor markup per tier (legendary 50x base price) - gate quality drops by character level (Heirlooms unlock 80) The standard preset reproduces the canonical 8-tier scale with exact hex values from the live client (#9d9d9d through #00ccff) and standard disenchant rules (Common+ disenchantable, Legendary and Artifact aren't). The server-custom preset shows 4 tiers above the standard range with non-standard pricing (Junk 0.1x, QuestLocked 0.0x unsellable). The raid preset gates 4 progression tiers behind minLevelToDrop=60 with escalating vendor multipliers up to 50x for Legendary. Cross-references back to WIT — item entries reference qualityId here for tooltip color and sort order. canDropAtLevel(id, lvl) is the engine helper used by loot generation. Validation enforces name presence, no duplicate ids, vendorPriceMultiplier >= 0, minLevelToDrop <= maxLevelToDrop; warns on: - minLevelToDrop > 80 (unreachable at WotLK cap) - vendorPriceMultiplier > 100x (sanity check the economy) - nameColorRGBA with alpha=0 (text would be invisible in tooltips — common bug when copy-pasting RGB hex without alpha byte) Wired through the cross-format table; WIQR appears automatically in all 15 cross-format utilities. Format count 83 -> 84; CLI flag count 1003 -> 1008.
2026-05-09 22:59:27 -07:00
"--gen-iqr", "--gen-iqr-server", "--gen-iqr-raid",
"--info-wiqr", "--validate-wiqr",
"--export-wiqr-json", "--import-wiqr-json",
feat(editor): add WSCS (Skill Cost) open catalog format Open replacement for Blizzard's SkillCostsData.dbc plus the per-rank training cost tables. Defines the tiered progression of trainable skills: each rank unlocks a skill range, requires a minimum character level, and costs a fixed amount of gold to learn. The canonical 6-tier profession progression captured by the default preset: Apprentice skill 0-75 lvl 5 1s Journeyman skill 50-150 lvl 10 5s Expert skill 125-225 lvl 20 1g Artisan skill 200-300 lvl 35 5g Master skill 275-375 lvl 50 10g Grand Master skill 350-450 lvl 65 25g Same shape applies to weapon skills (free, level-gated, capped at 5x char level) and riding skills (canonical Vanilla / TBC / WotLK gold costs from 90g Apprentice through 5000g Artisan flying down to 1000g Cold Weather Flying). Five costKind values cover the full training-skill space (Profession / WeaponSkill / RidingSkill / ClassSkill / Misc). Each entry's copperCost stores the cost in copper (1g = 10000c) which the info renderer pretty-prints as "25g 0s 0c". Cross-references back to WSKL — skill entries reference costId here for the tiered training schedule. nextTrainable(currentSkill, characterLevel) is the engine helper that returns the lowest-rank tier a character qualifies for and hasn't capped yet — used by trainer NPCs to populate their offered-skill list. Three preset emitters: --gen-scs (6 profession tiers), --gen-scs- weapon (5 weapon skill tiers), --gen-scs-riding (5 riding tiers with canonical gold costs). Validation enforces id+name presence, costKind 0..4, no duplicate ids, min<max range; warns on: - requiredLevel > 80 (unreachable at WotLK cap) - RidingSkill with requiredLevel < 20 (Apprentice canonically unlocks at 20) - Profession kind with copperCost=0 (every standard tier costs at least a copper — usually a config bug) Wired through the cross-format table; WSCS appears automatically in all 15 cross-format utilities. Format count 84 -> 85; CLI flag count 1010 -> 1015.
2026-05-09 23:04:02 -07:00
"--gen-scs", "--gen-scs-weapon", "--gen-scs-riding",
"--info-wscs", "--validate-wscs",
"--export-wscs-json", "--import-wscs-json",
feat(editor): add WIFS (Item Flag Set) open catalog format Open replacement for the bit-flag meanings used in Item.dbc / item_template.Flags. Documents every individual bit of the 32-bit item flags field with a human-readable name, description, kind classification, and is-positive hint. WoW's Item.dbc Flags field packs ~25 bits of metadata like Heroic, Lootable, NoLoot, Conjured, BindOnPickup, BindOnEquip — each controlling a specific gameplay behavior. The hardcoded client knows what each bit means via a switch statement; this catalog exposes that table to data-driven editors so: - server admins can document custom flag bits - tooltip generators can decode "why is this item soulbound?" via flag-name lookup (decode(0x40240000) returns ["Heroic", "BindOnPickup", "Unique"]) - validators can warn about contradictory flag combinations Seven flagKind values classify the bit families (Quality / Drop / Trade / Magic / Account / Server / Misc), and an isPositive hint tells UIs whether the flag enhances the item (green) or restricts it (red). Cross-references back to WIT (decodes WIT.flags into the matching named flag list) and WIQR (validators can pair Heroic flag with WIQR Epic+ quality requirement). Three preset emitters: --gen-ifs (8 canonical Item.dbc bits matching the standard 3.3.5a constants), --gen-ifs-binding (5 binding-related flags BindOnPickup / BindOnEquip / etc — all restrictive so isPositive=0), --gen-ifs-server (5 server-custom bits in the upper range demonstrating how to overlay extra metadata without colliding with Blizzard's bits). Validation enforces id+name+bitMask presence, flagKind 0..6, no duplicate ids, no duplicate bitMasks (collision means engine would only honor first matching name when decoding); warns on multi-bit masks (unusual — usually want individual bits). decode(flagsValue) is the engine helper that expands a raw flags integer into its named flag list — used directly by the tooltip generator and item info renderers. Wired through the cross-format table; WIFS appears automatically in all 16 cross-format utilities. Format count 85 -> 86; CLI flag count 1018 -> 1023.
2026-05-09 23:10:35 -07:00
"--gen-ifs", "--gen-ifs-binding", "--gen-ifs-server",
"--info-wifs", "--validate-wifs",
"--export-wifs-json", "--import-wifs-json",
feat(editor): add WBKD (NPC Service Definition) open catalog format Open replacement for AzerothCore's npc_vendor / npc_trainer / npc_gossip / npc_options SQL tables plus the engine's hard-coded service-type dispatch. Defines the kinds of services NPCs can offer (Banker / Mailbox / Auctioneer / StableMaster / FlightMaster / Trainer / Innkeeper / Battlemaster / GuildBanker / ReagentVendor / TabardVendor / Misc) and the per-service metadata (gold cost, faction gating, gossip text id). When a player right-clicks an NPC, the engine looks at the NPC's serviceId list (from WCRT.npcFlags or equivalent) and dispatches to the appropriate service-frame handler — Banker opens the inventory expansion frame, Auctioneer opens the auction house, StableMaster opens the pet stable. This catalog defines what each service actually does and what preconditions it requires. Cross-references back to WCRT (creature.npcFlags decodes into a list of service ids defined here), WFAC (factionRequiredId references factionId for rep-gated services like Argent Tournament), and WGSP (gossipTextId references menuId for the "How can I help you?" dialogue line). Three preset emitters: --gen-bkd (5 city services typical of a capital city), --gen-bkd-battle (3 battlemaster services for each Vanilla BG queue), --gen-bkd-profession (4 profession services). findByKind(kind) is the engine helper used by NPC spawning to find e.g. all FlightMaster services configured for a server. Validation enforces id+name presence, serviceKind 0..11, no duplicate ids; warns on: - Mailbox kind with non-zero gossipTextId (mailboxes are gameobject services with no NPC dialogue; gossip won't show) - Innkeeper kind with gossipTextId=0 (no welcome/bind dialog; will silently bind the hearthstone) - Battlemaster kind with non-zero requiresGold (battle queue services are typically free) Wired through the cross-format table; WBKD appears automatically in all 16 cross-format utilities. Format count 86 -> 87; CLI flag count 1025 -> 1030.
2026-05-09 23:15:20 -07:00
"--gen-bkd", "--gen-bkd-battle", "--gen-bkd-profession",
"--info-wbkd", "--validate-wbkd",
"--export-wbkd-json", "--import-wbkd-json",
feat(editor): add WTBR (Token Reward) open catalog format Open replacement for AzerothCore's currency_token_reward SQL table plus the per-vendor token redemption rows in npc_vendor. Each entry says "spend N copies of token X to receive reward Y", with reward type polymorphism: Y can be an item, a spell (taught to the character), a title, a mount, a companion pet, a currency conversion, an heirloom unlock, or a cosmetic (tabard / pennant / fluff). The rewardId field's interpretation depends on the rewardKind enum. Distinct from WTKN (Token catalog) which defines the token currency items themselves. WTKN says "the Champion's Seal exists as item 44990"; WTBR says "spend 25 Champion's Seals at Argent Tournament for the Squire's Belt (item 45517)". Eight rewardKind values cover the full reward space (Item / Spell / Title / Mount / Pet / Currency / Heirloom / Cosmetic), and an 8-tier requiredFactionStanding gates by reputation (Hated / Hostile / Unfriendly / Neutral / Friendly / Honored / Revered / Exalted) when paired with a non-zero requiredFactionId. Cross-references back to WTKN (spentTokenItemId), WIT (Item rewards), WSPL (Spell rewards), WTIT (Title rewards), WMOU (Mount rewards), WCMP (Pet rewards), WCTR (Currency conversion rewards), and WFAC (faction-rep gating). findByToken(itemId) is the engine helper used by vendor frames to populate the "what can I buy with these?" list. Three preset emitters: --gen-tbr (5 raid tier-token redemptions consuming Trophy of the Crusade and Emblem of Frost), --gen-tbr-pvp (5 PvP rewards spanning honor / arena / conquest plus title and tabard kinds), --gen-tbr-faction (5 faction- gated rewards demonstrating each standing tier from Honored through Exalted). Validation enforces id+name+spentTokenItemId+spentTokenCount presence, rewardKind 0..7, requiredFactionStanding 0..7, no duplicate ids; warns on: - rewardId=0 (no actual reward, vendor offers entry but grants nothing) - requiredFactionStanding > Neutral with requiredFactionId=0 (rep gate has no faction to check) - Currency conversion item -> itself (typo / config bug) Wired through the cross-format table; WTBR appears automatically in all 18 cross-format utilities. Format count 87 -> 88; CLI flag count 1034 -> 1039.
2026-05-09 23:26:13 -07:00
"--gen-tbr", "--gen-tbr-pvp", "--gen-tbr-faction",
"--info-wtbr", "--validate-wtbr",
"--export-wtbr-json", "--import-wtbr-json",
feat(editor): add WSPS (Spell Proc Trigger) open catalog format Open replacement for AzerothCore's spell_proc_event SQL table plus the per-spell proc fields embedded in Spell.dbc. Defines when a "trigger" spell fires in response to other spell/combat events: Windfury Weapon procs on melee attack, Clearcasting on damaging cast, Judgement of Wisdom on melee hit, etc. Each entry says "when an event matching procFlags fires from a spell matching procFromSpellId (0 = any), at procChance probability with at most one trigger per internalCooldownMs window, fire triggerSpellId". The procPpm field provides an alternative procs-per-minute formula (when non-zero, supersedes procChance and scales with weapon speed for melee procs — the canonical WoW behavior for weapon imbues). 13-bit procFlags bitfield covers the standard event taxonomy: DealtMeleeAutoAttack / DealtMeleeSpell / TakenMeleeAutoAttack / TakenMeleeSpell / DealtRangedAutoAttack / DealtRangedSpell / DealtSpell / DealtSpellHeal / TakenSpell / OnKill / OnDeath / OnCastFinished / Critical (the last is a modifier — fires only on crit-tagged events). Cross-references back to WSPL (triggerSpellId references the spell that fires; procFromSpellId optionally restricts to a specific source spell). Three preset emitters: --gen-sps (4 weapon-imbue procs with canonical PPM rates and ICDs), --gen-sps-aura (4 aura-tied procs across multiple proc-flag combinations), --gen-sps-talent (4 talent procs including charge-consuming Clearcasting and Nightfall variants). Validation enforces id+name+triggerSpellId+procFlags presence, no duplicate ids; warns on: - procChance outside [0..1] (engine clamps) - procPpm < 0 (invalid PPM rate) - both procChance > 0 AND procPpm > 0 set (engine prefers PPM so procChance is silently ignored) - both procChance=0 AND procPpm=0 (proc never fires) Wired through the cross-format table; WSPS appears automatically in all 18 cross-format utilities. Format count 88 -> 89; CLI flag count 1041 -> 1046.
2026-05-09 23:32:25 -07:00
"--gen-sps", "--gen-sps-aura", "--gen-sps-talent",
"--info-wsps", "--validate-wsps",
"--export-wsps-json", "--import-wsps-json",
feat(editor): add WCMR (Creature Patrol Path) — 90th open format milestone Open replacement for AzerothCore's creature_movement / waypoints SQL tables plus the per-spawn waypoint arrays. Defines named waypoint paths that creatures patrol along: Stormwind guards walking the city perimeter, AQ40 trash rotating through the chamber, ICC patrols circling the spire. Each entry binds a creatureGuid to a sequence of (x, y, z, delayMs) waypoints. The pathKind controls cycling behavior (Loop / OneShot / Reverse / Random) and moveType controls the locomotion kind (Walk / Run / Fly / Swim) — a flying patrol ignores ground geometry, a swimming patrol stays underwater. This is the first open format with truly variable-length per-entry payload. Earlier formats with multi-slot fields (WSPR's 8-reagent slots, WPSP's 4-item arrays) used fixed-size caps padded with zeros. WCMR instead uses an inline length-prefixed waypoint array — entries can be 4 waypoints or 4000, with the loader advancing through the file by reading the count first then count*16 bytes of waypoint data. Cap of 64K waypoints per path keeps a corrupted file from allocating gigabytes. pathLengthYards(pathId) is the engine helper that sums segment distances between consecutive waypoints (closing the loop for Loop kind). Tested across 12-point and 16-point circular paths that geometrically resolve to the expected ~25y radius and ~60y radius totals. Cross-references back to WCRT — creatureGuid points at the spawned creature instance whose behavior mode follows this patrol. Three preset emitters: --gen-cmr (3 small paths showing each pathKind variant), --gen-cmr-city (4 capital-city guard 6-point loops with 2.0-2.5s waypoint dwell), --gen-cmr-boss (3 long raid-zone patrols up to 16 waypoints, demonstrating that variable-length payloads scale). Validation enforces id+name+creatureGuid+waypoints presence, pathKind 0..3, moveType 0..3, no duplicate ids; warns on 1-waypoint paths (creature would idle in place) and Loop with fewer than 3 waypoints (degenerate — indistinguishable from Reverse). This is the 90th open format milestone. Wired through the cross-format table; WCMR appears in all 18 cross-format utilities. Format count 89 -> 90; CLI flag count 1048 -> 1053.
2026-05-09 23:38:59 -07:00
"--gen-cmr", "--gen-cmr-city", "--gen-cmr-boss",
"--info-wcmr", "--validate-wcmr",
"--export-wcmr-json", "--import-wcmr-json",
feat(editor): add WBOS (Boss Encounter Definition) open catalog format Open replacement for AzerothCore's instance_encounter SQL table plus the per-boss script bindings. Defines raid boss encounter metadata: which creature is the boss, which map and difficulty variant it lives in, how many phases the encounter has, the soft-enrage timer and berserk spell, recommended group size, and item level. One entry per (boss × difficulty) combination. Lord Marrowgar in 10-Normal ICC is one entry; Lord Marrowgar in 25-Heroic ICC is a separate entry with a higher recommendedItemLevel and a different difficultyId pointing into WCDF. This format ties together five other catalogs into a coherent encounter description: - WCRT for the boss creature template - WMS for the instance map - WCDF for difficulty routing (10/25/H10/H25 variants) - WSPL for the berserk spell that fires at enrage - WACR for achievement criteria like "kill The Lich King in 25-Heroic" that point back via KillCreature targetId findByMap(mapId) returns all encounters in one raid instance, sorted by their catalog order — used by the Encounter Journal UI and instance lockout logic. findByBossCreature(bossId) returns all difficulty variants of one boss. Three preset emitters: --gen-bos (3 5-man dungeon bosses with no soft-enrage), --gen-bos-raid10 (4 ICC 10-Normal bosses including 5-phase Lich King with 15min hard enrage via Fury of Frostmourne 72546), --gen-bos-world (2 outdoor world bosses with 25-player size + no difficulty). Validation enforces id+name+boss+map+phases+size presence, no duplicate ids; warns on: - non-standard requiredPartySize (canonical sizes are 5/10/25/40) - berserkSpellId set without enrageTimerMs (spell never fires) - enrageTimerMs > 30 minutes (sanity check) Wired through the cross-format table; WBOS appears in all 18 cross-format utilities. Format count 90 -> 91; CLI flag count 1055 -> 1060.
2026-05-09 23:45:26 -07:00
"--gen-bos", "--gen-bos-raid10", "--gen-bos-world",
"--info-wbos", "--validate-wbos",
"--export-wbos-json", "--import-wbos-json",
feat(editor): add WHLD (Instance Lockout Schedule) open catalog format Open replacement for the engine-side instance reset timer logic plus the per-map InstanceTemplate.dbc reset fields. Defines how often each (map × difficulty) combination resets its lockout, how many boss kills each character can claim per lockout window, and the number of bonus rolls available (Cataclysm+ stub for forward compatibility). One entry per (map × difficulty × group size). Icecrown Citadel 10-Normal weekly, ICC 25-Normal weekly, ICC 10-Heroic weekly, and ICC 25-Heroic weekly are four separate entries with the same mapId but different difficultyId and resetIntervalMs. Cross-references back to WMS (mapId), WCDF (difficultyId), and forward to WBOS — the encounters bound to one lockout are the WBOS entries whose (mapId, difficultyId) pair matches. Four lockout kinds capture the canonical reset cadences: - Daily (24h, 86400000ms) — heroic dungeons, daily quests - Weekly (7d, 604800000ms) — raid lockouts - SemiWeekly (3.5d, 302400000ms) — Cata+ split lockouts - Custom (arbitrary intervalMs) — Wintergrasp 2.5h, holiday events with non-standard cadence nextResetMs(lockoutId, currentMs) is the engine helper that returns the next reset wall-clock millis after a given current time, rounded up to the nearest interval boundary. The engine overrides the epoch with its configured server reset time (typically Tuesday 8:00am server-local), but the catalog provides the interval shape. The info renderer pretty-prints intervals: 86400000ms reads as "1d", 9000000ms as "150m", which matches how server admins think about reset cadences. Three preset emitters: --gen-hld (4 ICC raid weekly lockouts), --gen-hld-dungeon (4 5-man heroic daily lockouts), --gen-hld-event (3 world-event lockouts including Wintergrasp's canonical Custom 2.5h interval). Validation enforces id+name+kind+resetIntervalMs presence, no duplicate ids; warns on non-standard raidGroupSize, kind/interval mismatches (Daily kind without 24h interval, Weekly kind without 7d interval), and 0 boss kill cap (instance grants no lockout-bound progress, every visit is fresh). Wired through the cross-format table; WHLD appears in all 18 cross-format utilities. Format count 91 -> 92; CLI flag count 1062 -> 1067.
2026-05-09 23:51:49 -07:00
"--gen-hld", "--gen-hld-dungeon", "--gen-hld-event",
"--info-whld", "--validate-whld",
"--export-whld-json", "--import-whld-json",
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.
2026-05-09 23:58:49 -07:00
"--gen-stc", "--gen-stc-cata", "--gen-stc-premium",
"--info-wstc", "--validate-wstc",
"--export-wstc-json", "--import-wstc-json",
feat(editor): add WSTM (Stat Modifier Curve) open catalog format Open replacement for the gtChanceTo*.dbc / gtRegen*.dbc / gtCombatRatings.dbc family of "1D level-keyed curve" tables. Each entry defines a single linear curve mapping character level to a stat value: melee crit chance per level, mana regen per spirit per level, base armor per level, etc. Curves are linear: value(level) = baseValue + perLevelDelta * (level - 1), with the result optionally scaled by a global multiplier and clamped to a level range. Most stock WoW curves fit this shape — the few that don't (cubic Combat Ratings) live in the dedicated WCRR catalog with spline support. Distinct from WCRR (Combat Rating conversion, integer ratings -> percentages) and WSPC (Spell Power Cost buckets, per-spell costs). WSTM is for the generic engine-side stat curves that aren't per-spell or per-rating. Seven curveKind values classify the major stat families (Crit / Hit / Power / Regen / Resist / Mitigation / Misc), and each curve carries its own [minLevel, maxLevel] applicability range plus a multiplier for global scaling without retuning each curve's slope. Three preset emitters: --gen-stm (5 crit-related curves with canonical 3.3.5a base+per-level scaling — MeleeCrit 5%+0.05/lvl resolves to 8.95% at lvl 80), --gen-stm-regen (4 regen curves including ManaPerSpirit and the Vanilla-era 3 rage/sec OOC decay), --gen-stm-armor (3 armor/mitigation/resistance curves). The info renderer demos resolveAtLevel(curveId, 80) inline as the @lvl80 column — server admins can sanity-check what each curve resolves to at character cap without writing test code. Validation enforces id+name presence, curveKind 0..6, minLevel<=maxLevel, no duplicate ids; warns on: - maxLevel > 80 (unreachable at WotLK cap) - multiplier=0 (curve always evaluates to 0) - multiplier<0 (inverts the curve — possibly intentional) - perLevelDelta<0 (curve shrinks with level — unusual) Wired through the cross-format table; WSTM appears in all 18 cross-format utilities. Format count 93 -> 94; CLI flag count 1076 -> 1081.
2026-05-10 00:05:07 -07:00
"--gen-stm", "--gen-stm-regen", "--gen-stm-armor",
"--info-wstm", "--validate-wstm",
"--export-wstm-json", "--import-wstm-json",
feat(editor): add WACT (Action Bar Layout) open catalog format Open replacement for the hardcoded per-class default action bar bindings. Defines which abilities auto-populate which action button slots when a new character is created or a class is reset. A Warrior's button 1 binds Heroic Strike, button 2 Charge, button 3 Rend, etc. — new characters of that class get those buttons pre-populated so the action bar isn't empty on first login. Distinct from WKBD (Keybindings) which maps physical keys to action button slots — WACT maps action button slots to abilities. The two together complete the default-control configuration: Key 1 -> Action Slot 1 (WKBD) -> Heroic Strike (WACT). Seven barMode values cover the major action bar contexts: - Main (slots 0-11, standard 12-button bar) - Pet (hunter/warlock pet action bar) - Vehicle (mounted/vehicle action bar) - Stance1/2/3 (warrior battle/defensive/berserker; druid bear/cat/tree) - Custom (server-custom bar overlay) Cross-references back to WCHC (classMask layout), WSPL (spellId for the bound ability), and WIT (itemId for item-macro bindings like Hearthstone in slot 12). findByClass(classBit, barMode) returns the bindings sorted by buttonSlot — used directly by character creation to populate action bars. Three preset emitters: --gen-act (10 Warrior starter bindings on Main bar with canonical 3.3.5a abilities), --gen-act-mage (10 Mage starter bindings including Counterspell + Polymorph), --gen-act-pet (10 Hunter pet-bar bindings using barMode=Pet for Attack/Stance/Bite/Claw/Dismiss). Validation enforces id+name+classMask presence, barMode 0..6, no duplicate ids; warns on: - buttonSlot > 143 (max is 12 bars × 12 slots = 144) - both spellId and itemId set (engine prefers spellId, item is silently ignored) - both spellId=0 AND itemId=0 (button will render empty) - (classMask + barMode + buttonSlot) collisions for overlapping classes — multiple bindings fighting for the same physical slot Wired through the cross-format table; WACT appears in all 18 cross-format utilities. Format count 94 -> 95; CLI flag count 1083 -> 1088.
2026-05-10 00:11:53 -07:00
"--gen-act", "--gen-act-mage", "--gen-act-pet",
"--info-wact", "--validate-wact",
"--export-wact-json", "--import-wact-json",
"--gen-grp", "--gen-grp-raid10", "--gen-grp-raid25",
"--info-wgrp", "--validate-wgrp",
"--export-wgrp-json", "--import-wgrp-json",
"--gen-hrt", "--gen-hrt-capitals", "--gen-hrt-inns",
"--info-whrt", "--validate-whrt",
"--export-whrt-json", "--import-whrt-json",
"--gen-scb", "--gen-scb-maintenance", "--gen-scb-helptips",
"--info-wscb", "--validate-wscb",
"--export-wscb-json", "--import-wscb-json",
"--gen-cmg", "--gen-cmg-druid", "--gen-cmg-all",
"--info-wcmg", "--validate-wcmg",
"--export-wcmg-json", "--import-wcmg-json",
feat(editor): add WMSP (Master Server Profile) — 100th open format Novel replacement for the hardcoded realmlist that the WoW client receives via SMSG_REALM_LIST during login. Each entry is one selectable realm: name, network address (host:port), realm type (Normal/PvP/RP/RPPvP/Test), realm category (Public/Private/Beta/Dev), expansion gating (Vanilla 1.12.1 / TBC 2.4.3 / WotLK 3.3.5a / Cata 4.3.4), population indicator (Low/Medium/High/Full/Locked), char- acter cap, GM-only flag, timezone hint, and per-realm version+build numbers. 100th open format — milestone marker for the catalog ecosystem. WMSP is a TOP-LEVEL bootstrap catalog (read by the login server before any character is loaded), so it deliberately has no cross-references to other catalogs; all other social/world/spell catalogs depend on a player session that doesn't exist until WMSP has been consulted. Three preset emitters covering common deployment shapes: makeSingleRealm (1 default WoweeMain WotLK Public), makePvPCluster (3 realms — PvE/PvP/RP — sharing one login address so players pick rule-set without changing servers), makeMultiExpansion (4 progression realms across all expansion gates with their canonical build numbers from the matching client). Validator catches several real misconfigurations: empty address (login server cannot route session), realmType out of {0,1,4,6,8} (the WoW client's RealmType enum is non-contiguous — 2/3/5/7 are unused values that crash the picker), characterCap=0 (players can't make characters), duplicate realm names (picker requires unique display names), missing port in address. Format count 99 -> 100. CLI flag count 1119 -> 1124.
2026-05-10 00:47:02 -07:00
"--gen-msp", "--gen-msp-cluster", "--gen-msp-multi",
"--info-wmsp", "--validate-wmsp",
"--export-wmsp-json", "--import-wmsp-json",
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.
2026-05-10 00:53:33 -07:00
"--gen-emo", "--gen-emo-combat", "--gen-emo-rp",
"--info-wemo", "--validate-wemo",
"--export-wemo-json", "--import-wemo-json",
feat(editor): add WBAB (Buff & Aura Book) — 102nd open format Novel replacement for the implicit rank-chain relationships that vanilla WoW encoded by burying nextRank/prevRank pointers inside Spell.dbc with no explicit graph structure. Each WBAB entry is one long- duration class buff at one specific rank, with explicit edges to adjacent ranks via previousRankId and nextRankId fields. The graph-shaped data is novel among the 100+ catalog set: most catalogs have flat rows; WBAB is genuinely a graph where rows are nodes and the rank fields are edges. Both directions are stored explicitly so the spellbook UI's "upgrade to next rank" button can traverse without scanning the full table. Helper methods walkChainBack- ToRoot() returns the full chain root->tip for the rank- picker widget; findChainTip() returns the highest rank for auto-cast logic. Three preset emitters demonstrating the pattern: makeMage (Arcane Intellect ranks 1-4 with chain edges), makeDruid (Mark of the Wild ranks 1-5 with chain edges), makeRaidMax (6 max-rank standalone raid buffs — one per buffing class — with no chain edges to show the standalone case). Validator catches several rank-chain-specific bugs: self-referencing edges (entry.next == entry.id would create a 1-element cycle), missing referenced entries (next/prev pointing to non-existent ids), and most importantly back-edge symmetry — if A.nextRankId=B then B.previousRankId MUST equal A.buffId or the spellbook upgrade traversal will derail. Symmetric back-edge check is unique to graph-shaped catalogs. Also fixed a crash in --catalog-find where the recursive directory iterator threw on permission-denied subdirs (common when walking /tmp). Now uses the skip_permission_denied directory_options + per-step error_code clearing for defensive resumption. Format count 101 -> 102. CLI flag count 1134 -> 1139.
2026-05-10 01:13:42 -07:00
"--gen-bab", "--gen-bab-druid", "--gen-bab-raid",
"--info-wbab", "--validate-wbab",
"--export-wbab-json", "--import-wbab-json",
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.
2026-05-10 01:24:46 -07:00
"--gen-tbd", "--gen-tbd-horde", "--gen-tbd-faction",
"--info-wtbd", "--validate-wtbd",
"--export-wtbd-json", "--import-wtbd-json",
feat(editor): add WSPM (Spell Persistent Marker) — 104th open format Novel replacement for the SpellAreaTrigger.dbc + AreaTriggerCreateProperties pair vanilla used for AoE ground decals. Each entry binds one spellId to a ground-tracked decal: texture path, radius (in yards), duration, damage tick interval, RGBA decal color, edge- fade rendering mode (Hard / SoftEdge / Pulse), stack flag, and destroy-on-cancel semantics for channeled spells. The catalog covers three distinct gameplay surfaces in one shape: player-cast AoE (Blizzard, Flamestrike, etc. that the visual effects pipeline spawns at cast time), boss-arena hazard zones (Putricide poison pool, Sindragosa frost tomb, Marrowgar Bone Storm radius that raid encounters need to render so players know to move), and persistent environmental effects (Wintergrasp lightning strike, Silithus sandstorm cone that the weather system spawns). Three preset emitters one per surface: makeMageAoE (Blizzard/Flamestrike/BlastWave/FrostNova), makeRaid- Hazards (5 ICC encounter zones), makeEnvironment (3 weather/world hazards). Hazard variants set destroyOnCancel=0 since they persist beyond any caster; environment variants additionally set stackable=1 since multiple lightning strikes can overlap. Validator's most novel check is spellId uniqueness — multiple WSPM entries binding the same spellId would make the spell-cast lookup ambiguous (which decal does the spell spawn?). Also catches empty texture paths (decal would render solid color), radius<=0 (zero area), tickIntervalMs<100ms (perf risk for stackable markers), decalColor alpha=0 (invisible), and edge-fade enum range. Format count 103 -> 104. CLI flag count 1148 -> 1153.
2026-05-10 01:29:56 -07:00
"--gen-spm", "--gen-spm-raid", "--gen-spm-env",
"--info-wspm", "--validate-wspm",
"--export-wspm-json", "--import-wspm-json",
feat(editor): add WLDN (Learning Notification) — 105th open format Novel replacement for the hardcoded server-side milestone messages that fire when a player crosses a progression threshold ("You can now learn Apprentice Riding" at level 20, "Dual specialization is now available", "You have unlocked the auction house"). Each entry binds one trigger condition (LevelReach / FactionStanding / ItemAcquired / QuestComplete / SpellLearned / ZoneEntered) to a delivery channel (RaidWarning banner / SystemMsg / Subtitle / Tutorial popup / MOTDAppend) and an optional fanfare sound. The triggerValue field is polymorphic — its semantics depend on triggerKind. The validator enforces per-kind ranges: LevelReach 1-80 (current cap), FactionStanding +/-42000 (Hated to Exalted bounds), ItemAcquired/ QuestComplete/SpellLearned/ZoneEntered must be a positive id (>0). This is the first format to use per-trigger discriminated value validation. Three preset emitters: makeLevelMilestones (5 LevelReach unlocks at canonical thresholds 20/30/40/60/ 80), makeAccountUnlocks (4 mixed-kind notifications: first-mail tutorial gated to <2hr playtime, Stormwind auction-house location subtitle, dual-spec activation on spell-learn, transmog vendor unlock on quest- complete), makeReputation (3 FactionStanding milestones at Honored/Revered/Exalted standings). minTotalTimePlayed gates first-time-only tutorials — the auction-house location subtitle fires only for characters with <2hr total time so veterans don't get spammed. Format count 104 -> 105. CLI flag count 1155 -> 1160.
2026-05-10 01:35:40 -07:00
"--gen-ldn", "--gen-ldn-account", "--gen-ldn-rep",
"--info-wldn", "--validate-wldn",
"--export-wldn-json", "--import-wldn-json",
feat(editor): add WCRE (Creature Resistance & Immunity) — 106th open format Novel replacement for the per-creature resistance columns that vanilla WoW buried inside creature_template (resistance1..6 fields) plus the SpellSchoolMask immunity and mechanic_immune_mask columns. Each entry is one creature's full defensive profile: 6 magic-school resist values (int16, with 32767 as the full-immunity sentinel), a physical-resistance percentage (0..75 game-engine cap), plus three immunity bitmasks (CC kinds, spell mechanics, magic schools). The CC-immunity mask uses 14 named bits: ImmuneRoot / Snare / Stun / Fear / Sleep / Silence / Charm / Disarm / Polymorph / Banish / Knockback / Interrupt / Taunt / Bleed. The info display renders the mask as a "+"-joined token list ("root+stun+fear") for readability; "all" for 0xFFFF (typical raid-boss CC profile) and "none" for 0. Three preset emitters: makeRaidBosses (5 canonical raid bosses with iconic single-school immunities — Ragnaros fire / Vael 50%-all / Hakkar arcane / Kel'Thuzad shadow / Onyxia fire+frost partial), makeElites (5 mid-tier elites with single-school resists), makeImmunities (4 selective CC-immunity test cases — root-immune treant, stun-immune worg, silence-immune acolyte, fear+charm+ poly-immune undead). Validator's most novel check is creatureEntry uniqueness — multiple WCRE entries binding the same creature would make the damage-calc lookup ambiguous (which profile applies?). Also catches negative resists < -100 (extreme >2x damage taken), physicalResistPct > 75 (clamped at runtime to game-engine armor cap), and reserved bits in schoolImmunityMask (only bits 0-5 are meaningful). Format count 105 -> 106. CLI flag count 1162 -> 1167.
2026-05-10 01:40:39 -07:00
"--gen-cre", "--gen-cre-elites", "--gen-cre-immune",
"--info-wcre", "--validate-wcre",
"--export-wcre-json", "--import-wcre-json",
feat(editor): add WPTT (Pet Talent Tree) — 107th open format Novel replacement for the PetTalent.dbc + PetTalentTab.dbc pair that defined the Hunter pet talent system added in WotLK. Each entry is one talent in one of the three pet trees (Cunning/utility, Ferocity/DPS, Tenacity/tank), placed at a (tier, column) grid position with a per-rank spell ID array, an optional prerequisite-talent edge, and a legacy loyalty-level requirement carried over from Vanilla pet happiness mechanics. Combines three patterns previously seen separately into one format: variable-length payload (spellIdsByRank[] mirroring WCMR's members[]), graph edge (prerequisiteTalentId mirroring WBAB's previousRankId), and grid placement (tier+column — first format with explicit 2D layout coordinates the renderer can use to draw the talent tree UI). Three preset emitters one per tree: makeFerocity (6 talents tiers 0-3 with prereq chain CobraReflexes -> SpikedCollar -> SpidersBite plus parallel Serpent -> Boars -> Rabid), makeCunning (5 talents Dash/Owls/ Recovery/Cornered/Phoenix), makeTenacity (5 talents Charge/Stamina/Stomp/Taunt/LastStand). Validator's most novel checks combine grid + graph constraints unique to talent-tree formats: - (tree, tier, column) cell uniqueness — two talents in the same cell would render on top of each other - prereq must resolve to an existing talent IN THE SAME TREE (cross-tree prereqs are illegal) - prereq tier must be STRICTLY LESS than this tier (talents only depend on earlier tiers, no same-tier or backward dependencies) - spellIdsByRank.size() must EQUAL maxRank exactly - no zero spell IDs within the rank array Plus the standard: id+name required, treeKind 0..2, tier 0..6 (7 tiers), column 0..2 (3 columns), maxRank 1..5, no duplicate talentIds, no self-referencing prereqs. Format count 106 -> 107. CLI flag count 1170 -> 1175.
2026-05-10 01:49:20 -07:00
"--gen-ptt", "--gen-ptt-cunning", "--gen-ptt-tenacity",
"--info-wptt", "--validate-wptt",
"--export-wptt-json", "--import-wptt-json",
feat(editor): add WHRD (Heroic Loot Scaling) — 108th open format Novel replacement for the implicit Heroic-mode loot rules vanilla WoW encoded in dungeon/raid script systems: a Normal-mode boss drops items from one loot table, the Heroic-mode version drops the same items at +N item levels with M× drop chance plus an optional Heroic-only currency token. Each WHRD entry binds one (mapId, difficultyId) combination to its scaling rules so the loot-roll engine can layer the modifiers over the base WLOT loot table at encounter death. Six tunable fields per scaling: itemLevelDelta (signed int16, typically +13 for 5-man Heroic, +13 to +26 for raid Heroic), bonusQualityChance (basis points 0..10000 for the probability of a +1-quality-tier bonus drop), dropChanceMultiplier (float, 1.0 = same rate, 1.5 = +50%), heroicTokenItemId (per-tier currency reward like Emblem of Frost), bonusEmblemCount (extra emblems on top of base 1× per boss). mapId=0 is a wildcard that applies the scaling to ANY map at the given difficultyId — used by the ChallengeMode preset to define generic Bronze/Silver/ Gold tier scalings without naming each instance. Three preset emitters: makeWotLK5manHeroic (5 WotLK 5-man Heroics: Utgarde Keep, Nexus, Azjol-Nerub, Ahn'kahet, Drak'Tharon — all +13/2× Emblem of Heroism), makeRaid25Heroic (4 25H raids: Naxx +13, EoE +13, Ulduar +26, ICC +26 with corresponding Conquest/Triumph/ Frost emblems), makeChallengeMode (3 anachronistic challenge-mode tiers as a template for custom servers backporting MoP-era systems). Validator's most novel checks are bounds-aware: bonusQualityChance capped at 10000 basis points (above that would guarantee multiple bonus drops), no negative itemLevelDelta (Heroic shouldn't be worse than Normal — warning, not error), no >50 ilvl delta (beyond canonical range — warning), no zero or excessive dropChance- Multiplier, AND (mapId, difficultyId) tuple uniqueness unless mapId=0 wildcard (multiple scalings binding the same instance+difficulty would make loot-roll lookup ambiguous). Format count 107 -> 108. CLI flag count 1175 -> 1180.
2026-05-10 01:52:58 -07:00
"--gen-hrd", "--gen-hrd-raid25", "--gen-hrd-cm",
"--info-whrd", "--validate-whrd",
"--export-whrd-json", "--import-whrd-json",
feat(editor): add WRPR (Reputation Reward tier) — 109th open format Novel replacement for the implicit reputation-tier rules vanilla WoW encoded across multiple SQL tables (npc_vendor with reqstanding columns, item_template faction gates, quest_template ReqMinRepFaction). Each WRPR entry binds one (factionId, minStanding) tier to its rewards: a vendor discount percentage, two variable- length arrays of unlocked content (item IDs + recipe IDs), and tabard + mount unlock boolean flags. First catalog with TWO variable-length payload arrays per entry (unlockedItemIds + unlockedRecipeIds) — previous variable-length formats used a single array (WCMR waypoints, WCMG members, WPTT spellIdsByRank, WBAB rank-chain pointers). The two-array shape is serialized as count1 + ids1[] + count2 + ids2[] for easy reader-side validation. Three preset emitters: makeArgentCrusade (4 tiers Friendly/Honored/Revered/Exalted with progressive items + recipes plus Argent Charger mount at Exalted), makeKaluak (4 fishing-themed tiers with cooking recipe unlocks plus Pygmy Suit cosmetic at Exalted), makeAccordTabard (3 tiers showcasing both grantsTabard and grantsMount flags via Wyrmrest Accord's iconic Reins of the Red Drake mount). Validator's most novel checks combine relational and domain logic: (factionId, minStanding) tuple uniqueness prevents ambiguous active-tier lookup, AND per-faction monotonic discount progression — sorts each faction's tiers by standing and verifies discountPct is non- decreasing. A higher reputation tier giving a worse vendor discount would be a content authoring bug. findActiveTierFor() helper picks the highest-standing tier the player meets — used by the vendor UI to compute the active discount without scanning the catalog. Format count 108 -> 109. CLI flag count 1184 -> 1189.
2026-05-10 01:59:03 -07:00
"--gen-rpr", "--gen-rpr-kaluak", "--gen-rpr-accord",
"--info-wrpr", "--validate-wrpr",
"--export-wrpr-json", "--import-wrpr-json",
feat(editor): add WMNL (Minimap Multi-Level) — 110th open format Novel replacement for the WorldMapTransforms.dbc + WorldMapOverlay.dbc pair vanilla used to describe zones with multiple vertical layers visible on the minimap (Stormwind has Old Town / Cathedral / Keep at three altitudes; Dalaran has Sewers / Street / Above Street / Floating; Undercity has 5 distinct levels Sewer to Throne Room). Each entry binds one (mapId, areaId, levelIndex) triplet to a Z-range, minimap layer texture, and display label. The catalog acts as a per-level overlay on top of WMPX world-map mappings: at every camera tick, the minimap renderer queries findContainingZ(playerZ) to swap the overlay layer when the player crosses a floor boundary. Three preset emitters one per layered city: makeStormwind (3 levels), makeDalaran (4 levels), makeUndercity (5 levels — deepest stack). Z-ranges abut precisely to ensure clean transitions: Sewer Z[-110, -85), Canal Z[-85, -65), Outer Ring Z[-65, -45), Inner Ring Z[-45, -20), Throne Z[-20, 30) — half-open intervals so the boundary Z value belongs to the upper level. Validator's most novel checks combine grouping + geometric constraints unique to multi-level layouts: - per-area levelIndex uniqueness (no two levels at the same index — picker UI would show duplicate slot) - per-area Z-range non-overlap (overlapping ranges would cause minimap-flicker as the player crosses the overlap region; the renderer can't decide which layer to display) Plus the standard: id+name+areaId required, minZ<maxZ (non-empty range), no duplicate levelIds. Format count 109 -> 110. CLI flag count 1191 -> 1196.
2026-05-10 02:03:43 -07:00
"--gen-mnl", "--gen-mnl-dalaran", "--gen-mnl-undercity",
"--info-wmnl", "--validate-wmnl",
"--export-wmnl-json", "--import-wmnl-json",
feat(editor): add WPCR (Pet Care & Action) — 111th open format Novel replacement for the implicit pet-management action rules vanilla WoW scattered across spell_template (Revive Pet / Mend Pet / Feed Pet / Dismiss Pet definitions), npc_text (stable master gossip), and per-class trainer SQL. Each entry binds one pet management action to its dispatching spell, gold cost, reagent requirement, cast time, cooldown, and pet/NPC pre-conditions. Eleven actionKind enum values cover the full pet management surface: Revive / Mend / Feed / Dismiss / Tame / BeastLore / Stable / Untrain / Rename / Abandon (Hunter), plus Summon (Warlock minion conjures). The classFilter field uses WCHC class-bit conventions (4=Hunter, 256=Warlock) so a single WPCR catalog can cover both class systems. Three preset emitters: makeHunterCare (5 Hunter pet care actions), makeStableActions (4 stable-master gold-cost actions), makeWarlockMinions (4 Warlock minion summons with shared 10s cooldown + Soul Shard reagent). Validator's most novel checks are PER-KIND constraints: Tame and Summon require requiresPet=0 (you can't tame or summon while another pet is active) — these are ERRORS, not warnings, since the action would simply fail at runtime. Stable kind without requiresStableNPC warns (stable-slot purchases are normally gated to stable-master conversation). Tame kind without cooldown warns (canonical 15s anti-macro-spam cooldown). The TameBeast preset originally omitted this cooldown — the validator caught and flagged it during smoke-test, fix applied before commit. Format count 110 -> 111. CLI flag count 1199 -> 1204.
2026-05-10 02:10:54 -07:00
"--gen-pcr", "--gen-pcr-stable", "--gen-pcr-warlock",
"--info-wpcr", "--validate-wpcr",
"--export-wpcr-json", "--import-wpcr-json",
feat(editor): add WMVC (Movie Credits Roll) — 112th open format Novel replacement for the embedded credit-roll text vanilla WoW carried inside the cinematic-renderer blob (the post-cinematic credits that scroll up the screen after each expansion intro). Each entry binds one credits category (Production / Music / Voice Acting / etc.) for one cinematic to its ordered list of credit lines. First catalog with a variable-length STRING array payload — previous variable-length formats used int arrays (WCMR waypoints / WCMG mutex spells / WPTT rank-spells / WBAB rank chains / WRPR unlocked items + recipes). The lines[] field serializes as count + (length + bytes)* per line, mirroring how strings work elsewhere in the catalog set just lifted into a per- entry array. Seven category enum values cover the full credit taxonomy: Production / Music / Audio / Engineering / Art / Voice / Special. Three preset emitters: makeWotLKIntro (5 blocks for the WotLK Arthas/Terenas cinematic with the actual canonical music credits — Brower/Duke/Stafford/Hayes), makeQuestCinema (3-block template for per-quest cinematics), makeStarterRoll (4-block generic template). orderHint sorts blocks within a single cinematic so the renderer can render Production -> Direction -> Music -> Voice -> Special Thanks in canonical order without depending on entry order in the binary. Validator's most novel checks combine string + grouping constraints unique to credit rolls: per-cinematic orderHint slot uniqueness — two blocks at the same (cinematicId, orderHint) would render in non- deterministic order due to the std::sort being stable but content-order undefined. Per-line: empty lines warn (would render as blank, intentional spacers should use a placeholder character), lines >80 chars warn (text-buffer wrap at the canonical 80-char credit-renderer width). Format count 111 -> 112. CLI flag count 1206 -> 1211.
2026-05-10 02:15:34 -07:00
"--gen-mvc", "--gen-mvc-quest", "--gen-mvc-starter",
"--info-wmvc", "--validate-wmvc",
"--export-wmvc-json", "--import-wmvc-json",
feat(editor): add WSPV (Spell Variant) — 113th open format Novel replacement for the implicit context-conditional spell substitution rules vanilla WoW encoded across SpellSpecificType, SpellEffect.EffectMechanic override fields, and the proc-modified spell tables in SpellProcEvent. Each entry binds one base spell to a variant spell that activates when a runtime condition is met (player in a specific stance, talent talented, racial buff active, weapon equipped, aura present). Six conditionKind values cover the full substitution surface: Stance / Form / Talent / Race / EquippedWeapon / AuraActive. The conditionValue field is polymorphic — its semantics depend on conditionKind (a stance spellId, a talentId, a race bit, etc.). The spell-cast pipeline iterates findByBaseSpell at cast time and picks the highest-priority variant whose condition is satisfied, falling through to the base spell if none matches. Three preset emitters demonstrating the pattern: makeWarriorStance (4 stance-conditional Warrior variants — Heroic Strike Berserker damage bonus, Battle baseline, Mocking Blow Defensive AoE taunt, Pummel Berserker-only gate), makeTalentMod (4 talent- modified variants — Frostbolt + Brain Freeze instant, Lava Burst + Flame Shock auto-crit, Earth Shield + Improved bonus heal, Ferocious Bite + Berserk), makeRacial (4 race-gated racials — Stoneform Dwarf, War Stomp Tauren, Berserking Troll, Will of the Forsaken). Validator's most novel check is the (baseSpell, conditionKind, conditionValue, priority) 4-tuple uniqueness — two variants with all four matching would tie at runtime and resolve non-deterministically (the spell-cast pipeline's std::sort by priority is stable but the underlying iteration order is undefined when priorities tie). Packs the tuple into 64 bits (base 32 | value 16 | kind 8 | prio 8) for set lookup. Format count 112 -> 113. CLI flag count 1213 -> 1218.
2026-05-10 02:20:19 -07:00
"--gen-spv", "--gen-spv-talent", "--gen-spv-racial",
"--info-wspv", "--validate-wspv",
"--export-wspv-json", "--import-wspv-json",
feat(editor): add WVOX (Voiceover Audio) — 114th open format Novel replacement for the implicit per-NPC voice dialog system vanilla WoW encoded across CreatureTextSounds (server-side aggro/death barks), npc_text (gossip audio cross-references), and per-quest dialog blobs. Each entry binds one NPC to one voice clip for one triggering event with metadata covering audio path, duration, volume, gender hint for randomized casts, variant index for multiple lines per event, and a transcript field for accessibility (TTS engines + chat- bubble subtitles). Nine eventKind values cover the full NPC dialog surface: Greeting / Aggro / Death / QuestStart / QuestProgress / QuestComplete / Goodbye / Special / Phase. The Phase kind specifically supports boss-fight percentage milestones (75%/50%/25% transitions) where multiple Phase entries with distinct variantIndex disambiguate the boss-encounter scripting. Three preset emitters: makeQuestgiver (5-clip canonical quest dialog flow), makeBoss (6-clip Lich King fight with phase milestones at 75/50/25%, special mechanic call at +5dB for raid audibility, death line), makeVendor (4-clip vendor interaction). Validator's most novel check is per-(npcId, eventKind, variantIndex) triple uniqueness — two clips with all three matching would be ambiguous when the trigger handler picks one randomly. The vendor preset originally bound both Buy and Sell to (Special, 0) which the validator caught and flagged before commit; fix uses variantIndex 0 for Buy and 1 for Sell so the trigger handler can distinguish. Validator also warns on durationMs=0 with non-empty audioPath (subtitle sync impossible), volumeDb outside [-20,+6] (clip risk), and empty transcript (TTS + chat-bubble subtitle would be blank). Format count 113 -> 114. CLI flag count 1220 -> 1225.
2026-05-10 02:25:34 -07:00
"--gen-vox", "--gen-vox-boss", "--gen-vox-vendor",
"--info-wvox", "--validate-wvox",
"--export-wvox-json", "--import-wvox-json",
feat(editor): add WTRD (Trade Window Rules) — 115th open format Novel replacement for the implicit player-to-player trade policy rules vanilla WoW hardcoded across the trade-window message handlers (CMSG_INITIATE_TRADE, CMSG_SET_TRADE_ITEM, CMSG_SET_TRADE_GOLD), the soulbound-item check, the cross-faction-trade rejection, and the GM-trade audit hooks. Each entry is one trade-policy rule the trade-window state machine consults at every state transition. Seven ruleKind values (Allowed / Forbidden / SoulboundException / CrossFactionAllowed / LevelGated / GoldEscrowMax / AuditLogged) and five targetingFilter values (AnyPlayer / SameRealmOnly / SameFactionOnly / SameAccountOnly / GMOnly) cover the full trade-policy surface. Priority field resolves rule conflicts — higher priority wins (Allowed at 100 overrides Forbidden at 10). Three preset emitters cover real-world deployment patterns: makeStandard (4 baseline rules — Soulbound Forbidden globally, Quest items Forbidden, 2hr Soul- boundException for raid trade-back, SameFactionOnly), makeServerAdmin (3 server-custom overrides — GM-only escrow at priority 100, AccountBound own-character transfer, CrossFactionAllowed at level 80 for RP servers), makeRMTPrevent (4 anti-RMT rules — 10g cap for low-level trades, 500g cap for accounts < 30 days, audit log for trades > 1000g, 24hr first-trade delay). Validator's most novel check is the GoldEscrowMax / goldEscrowMaxCopper consistency rule: a GoldEscrowMax- kind rule MUST specify a non-zero gold cap (zero would mean unlimited which contradicts the rule's purpose). Also warns on GMOnly targeting with priority < 50 (GM- mediated rules typically need high priority to override player-initiated rules) and levelRequirement > 80 (exceeds current cap, rule never applies). Format count 114 -> 115. CLI flag count 1227 -> 1232.
2026-05-10 02:30:32 -07:00
"--gen-trd", "--gen-trd-admin", "--gen-trd-rmt",
"--info-wtrd", "--validate-wtrd",
"--export-wtrd-json", "--import-wtrd-json",
feat(editor): add WWFL (Word Filter) — 116th open format Novel replacement for the implicit chat-moderation patterns vanilla WoW carried in the bad-word checker (the hardcoded substring list the CMSG_MESSAGECHAT handler walked before broadcasting). Each entry defines one pattern the chat preprocessor matches against outbound messages, the replacement to apply (or "drop"/"warn"/"mute" the sender), and a kind tag for analytics. Seven filterKind values (Spam / GoldSeller / AllCaps / RepeatChar / URL / AdvertReward / Misc) and four severity levels (Warn — log only, Replace — substitute matched span, Drop — silently discard, Mute — drop AND mute sender). Per-filter caseSensitive flag for context- specific rules (uppercase shouting detection vs lowercase RMT keyword detection). Intentionally non-profanity focused — the ecosystem distributes through CI / public PRs where embedded profanity creates reviewer-experience and licensing concerns. The presets cover the moderation surfaces server admins actually need: makeSpamRMT (5 RMT patterns: wts/wtb gold drops, g0ld typo-substitution replace, 1000g-for bulk-offer drop, free-gold mute), makeAllCaps (3 shouting patterns), makeURLDetect (3 URL-leakage patterns: http://, https://, www.). Profanity-list integration is left to deployment-time configuration where local laws and community standards apply. Validator's most novel check is per-pattern uniqueness — two filters with the same pattern would dispatch ambiguously through the chat preprocessor. Also warns on Replace severity with empty replacement (would silently lose match — use Drop explicitly if intended). Format count 115 -> 116. CLI flag count 1234 -> 1239.
2026-05-10 02:35:06 -07:00
"--gen-wfl", "--gen-wfl-caps", "--gen-wfl-url",
"--info-wwfl", "--validate-wwfl",
"--export-wwfl-json", "--import-wwfl-json",
"--gen-mar", "--gen-mar-world", "--gen-mar-party",
"--info-wmar", "--validate-wmar",
"--export-wmar-json", "--import-wmar-json",
feat(editor): add WLMA (Loot Mode Policy) — 118th open format Novel replacement for the implicit loot-distribution rules vanilla WoW encoded across the GroupLoot system (CMSG_LOOT_METHOD), the per-quality thresholds for Need-roll triggering, and the master-looter permission gates. Each entry binds one group-loot policy mode to its kind (FFA / RoundRobin / MasterLoot / Need-Before- Greed / Personal / Disenchant) plus quality threshold, master-looter requirement, idle-skip seconds, and disconnect-fallback policy. Six modeKind values cover the full loot-distribution surface. The thresholdQuality field uses the WIQR quality tier convention (0=Poor through 7=Heirloom) to gate Need-roll triggering — anything below threshold auto-distributes via FFA-equivalent semantics. The disconnect-fallback (timeoutFallbackKind) field is unique to MasterLoot policies — if the master looter disconnects mid-distribution, the policy auto-promotes to the fallback mode for democratic recovery. Common fallbacks: Need-Before-Greed (full roll system), FreeForAll (fastest unblock). Three preset emitters: makeStandard (4 5-man / casual modes covering FFA farming, RoundRobin trash, NBG Uncommon, MasterLoot Rare), makeRaidPolicies (3 raid loot policies including MasterLoot Epic with NBG fallback, Personal Loot, NBG Rare), makeAFKPrevention (3 AFK-mitigating modes with idleSkipSec gates). Validator's most novel check is per-kind consistency: MasterLoot kind REQUIRES masterLooterRequired=1 (else the policy contradicts itself — "Master Loot mode without requiring a master looter"). Personal kind warns if masterLooterRequired=1 (no-op flag). Tightened fallback-to-self warning to fire ONLY for MasterLoot where the field is meaningful — original version fired falsely for FFA/Personal/RoundRobin where the leader- disconnect scenario doesn't apply (caught + tightened during smoke-test). Format count 117 -> 118. CLI flag count 1248 -> 1253.
2026-05-10 02:46:26 -07:00
"--gen-lma", "--gen-lma-raid", "--gen-lma-afk",
"--info-wlma", "--validate-wlma",
"--export-wlma-json", "--import-wlma-json",
feat(editor): add WSKP (Sky Parameters) — 119th open format Novel replacement for the LightParams.dbc + Light.dbc pair vanilla WoW used to drive the per-zone diurnal sky cycle. Each entry binds one (mapId, areaId, timeOfDayHour) triplet to its sky-rendering parameters: sky-dome zenith and horizon colors, sun angle and color, fog start/end distances, cloud-layer opacity, and cloud drift speed in tenths-mph. The renderer interpolates between adjacent keyframes when the in-game clock crosses an hour boundary, so a 4-keyframe set (Dawn/Noon/Dusk/Midnight) produces the full diurnal cycle through linear interpolation. Servers can author finer-grained keyframes (e.g. every 3 hours) for smoother transitions. Three preset emitters demonstrating the catalog's range: makeStormwindDay (4 standard temperate keyframes from lavender dawn through bright noon to deep blue-black midnight), makeNorthrendArctic (4 cold steel-blue keyframes with high-density ice fog peaking at the midnight blizzard whiteout — minimum 30yd visibility), makeOutlandHellfire (3 keyframes — no midnight, since Outland's permanent gravitational anomaly from the Twisting Nether keeps the sky lit; iconic crimson + orange palette throughout). Validator's most novel checks: per-(mapId, areaId, timeOfDayHour) triple uniqueness — two keyframes at the same hour for the same area would render in unstable order during diurnal interpolation. Plus fogStartYards >= fogEndYards (inverted falloff) error, sunAngleDeg outside [0,360] warning (renderer wraps modulo but suggests authoring confusion). Format count 118 -> 119. CLI flag count 1255 -> 1260.
2026-05-10 02:51:23 -07:00
"--gen-skp", "--gen-skp-arctic", "--gen-skp-hellfire",
"--info-wskp", "--validate-wskp",
"--export-wskp-json", "--import-wskp-json",
feat(editor): add WCFG (Server Config) — 120th open format Novel replacement for the worldserver.conf / mangosd.conf flat-text configuration files vanilla server forks shipped. Each entry binds one configId to its polymorphic value via the valueKind enum (Float / Int / Bool / String) — only the matching value field is authoritative per entry. The polymorphic value is the novel data shape: each entry stores ALL three value carriers on disk (floatValue float / intValue int64 / strValue string), and valueKind picks which is meaningful at runtime. Bool folds into intValue with strict 0/1 semantics. JSON export reflects this: an activeValue derived field renders the right form per kind so operators editing JSON see only the relevant value. Nine configKind values cover the full server-tunable surface: XPRate / DropRate / HonorRate / RestedXP / RealmType / WorldFlag / Performance / Security / Misc. Each kind groups settings the server iterates by kind at startup (all XPRate entries seed the per-class experience matrix; all Security entries configure the anti-cheat thresholds). Three preset emitters: makeRates (4 vanilla baseline rate multipliers with valueKind=Float), makePerformance (4 server tuning configs mixing Int and Float kinds — max creatures per cell, view distance yards, GC interval seconds, etc.), makeSecurity (4 anti-cheat configs FIRST format using valueKind=String for the cheat-detection sensitivity preset name). Validator's most novel checks are per-valueKind cross- field consistency: Bool requires intValue strictly 0/1 (error), and warns on cross-field bleed (Float kind with non-zero intValue means the int is silently ignored at runtime but persists on disk). Plus name uniqueness — server name-based config lookups would be ambiguous otherwise. Format count 119 -> 120 (multiple-of-10 milestone). CLI flag count 1262 -> 1267.
2026-05-10 02:57:26 -07:00
"--gen-cfg", "--gen-cfg-perf", "--gen-cfg-sec",
"--info-wcfg", "--validate-wcfg",
"--export-wcfg-json", "--import-wcfg-json",
feat(editor): add WANV (Anniversary & Recurring Events) — 121st open format Novel replacement for the implicit recurring-event scheduler vanilla WoW encoded across the GameEvent SQL table + per-holiday script hooks. Each entry binds one calendar-driven recurring event (yearly holiday like Hallow's End, monthly tribute day, weekly Double XP Weekend, anniversary celebration) to its scheduling rule and its payload (a spell buff applied to all online players, a gift item granted on first event- window login). Eight eventKind values (Holiday / Anniversary / DoubleXP / DoubleHonor / PetBattleWeekend / BattlegroundBonus / SeasonalQuest / Misc) and four recurrenceKind values (Yearly / Monthly / Weekly / OneOff). The startDay field is polymorphic per recurrenceKind: Yearly/Monthly/OneOff use it as 1..31 day-of-month, Weekly uses it as 0..6 weekday (Sun..Sat) — the validator enforces both ranges per kind. Three preset emitters: makeStandardHolidays (5 yearly holidays with realistic spell+item payload bindings — Hallow's End spell 24710, Winter Veil 26157, Brewfest 42500, etc.), makeBonusEvents (4 weekly recurring bonuses — Friday triple-day weekends and Saturday- Sunday double-day pet-battle bonus), makeAnniversary (3 game-launch anniversaries — WoW Nov 23 / TBC Jan 16 / WotLK Nov 13 with overlapping celebration windows). Validator's most novel checks combine calendar + recurrence semantics: per-kind schedule validity (Weekly startDay 0..6 weekday, durationDays <= 7 to prevent self-overlap; Yearly/Monthly/OneOff startMonth 1..12, startDay 1..31 with calendar sanity — Feb cap at 29, Apr/Jun/Sep/Nov cap at 30 for "no Feb 30" / "no Apr 31" errors). Format count 120 -> 121. CLI flag count 1269 -> 1274.
2026-05-10 03:03:27 -07:00
"--gen-anv", "--gen-anv-bonus", "--gen-anv-launch",
"--info-wanv", "--validate-wanv",
"--export-wanv-json", "--import-wanv-json",
feat(editor): add WPRG (PvP Ranking grades) — 122nd open format Novel replacement for the hardcoded 14-rank vanilla WoW PvP ladder (Private through Grand Marshal Alliance, Scout through High Warlord Horde). Each entry binds one (factionFilter, tier) combination to its display name, weekly RP threshold to maintain rank, lifetime honor for first-time achievement, title prefix for player- name display, and tier-set gear reward. The vanilla rank-ladder system used a weekly RP-decay mechanic that punished any week without play with rank- loss; this catalog stores both the weekly threshold (maintenance) and the lifetime threshold (achievement) since both are needed for accurate rank-progression simulation. Three preset emitters spanning the rank ladder: makeAllianceRanks (7 lower-tier ranks Private through Knight-Lieutenant), makeHordeRanks (7 mirrored Horde titles Scout through Blood Guard with identical honor thresholds — factionFilter disambiguates the shared "Sergeant" title), makeHighRanks (8 high-tier ranks across both factions Knight-Captain through Lt. Commander, tiers 8-11 with the iconic legendary battlegear shoulder unlocks). Tier 14 (Grand Marshal / High Warlord) intentionally omitted from presets — it's the legendary top-rank that historically required dedicated 24/7 grinding. Catalog supports tiers 1..14 in the schema; consumers extend as needed. Validator's most novel checks: per-(faction, tier) tuple uniqueness — two ranks at the same tier for the same faction would tie at runtime when the rank- progression UI looks up "what's tier 5 for Alliance?" Plus per-faction honor-threshold monotonicity — a higher tier requiring less honor than a lower tier would let players "downrank" by gaining honor, which is a content authoring bug. Format count 121 -> 122. CLI flag count 1276 -> 1281.
2026-05-10 03:08:27 -07:00
"--gen-prg", "--gen-prg-horde", "--gen-prg-high",
"--info-wprg", "--validate-wprg",
"--export-wprg-json", "--import-wprg-json",
feat(editor): add WLAN (Localization) — 123rd open format Novel replacement for the per-language overlay tables vanilla WoW carried as Locale_*.MPQ patches plus the Spell.dbc / Item.dbc trailing 16-locale string columns. Each entry binds one (originalKey, languageCode, namespace) triple to its localized translation, forming a per-language overlay applied AFTER any per-format catalog has resolved its primary text. Eleven languageCode values cover the canonical WoW locales (enUS / enGB / deDE / esES / frFR / itIT / koKR / ptBR / ruRU / zhCN / zhTW) plus Unknown=255 as escape hatch. Eight namespace values segment the lookup space (UI / Quest / Item / Spell / Creature / Tooltip / Gossip / System) so a UI button "Cancel" doesn't collide with an item description containing the word "Cancel". UTF-8 multibyte support is the novel demonstration — the originalKey field is typically ASCII (English canonical key), but localizedText holds Korean (취소), Simplified Chinese (取消), or other non-Latin scripts. The string-length-prefixed binary serialization preserves byte-identical round-trip regardless of encoding. Three preset emitters: makeUIBasics (5 UI translations of the "Cancel" button across deDE/frFR/esES/koKR/zhCN including the Korean and Chinese multibyte UTF-8 strings), makeQuestSample (3 entries — one quest title in deDE/frFR/koKR illustrating the dotted-key convention "QUEST.123.title"), makeTooltipSet (4 item-tooltip strings in deDE+frFR — the high-volume client localization use case). Validator's most novel check is per-(originalKey, languageCode, namespace) triple uniqueness — two entries with all three matching would tie at runtime when the locale-aware text layer looks up an override. Plus the warning on empty localizedText (the override would render blank — possibly worse than fallback to the catalog default). Format count 122 -> 123. CLI flag count 1283 -> 1288.
2026-05-10 03:13:28 -07:00
"--gen-lan", "--gen-lan-quest", "--gen-lan-tooltip",
"--info-wlan", "--validate-wlan",
"--export-wlan-json", "--import-wlan-json",
"--gen-gch", "--gen-gch-rp", "--gen-gch-admin",
"--info-wgch", "--validate-wgch",
"--export-wgch-json", "--import-wgch-json",
"--gen-mod", "--gen-mod-ui", "--gen-mod-util",
"--info-wmod", "--validate-wmod",
"--export-wmod-json", "--import-wmod-json",
"--gen-spk-warrior", "--gen-spk-mage", "--gen-spk-rogue",
"--info-wspk", "--validate-wspk",
"--gen-weather-temperate", "--gen-weather-arctic",
"--gen-weather-desert", "--gen-weather-stormy",
"--gen-zone-atmosphere",
"--info-creatures", "--info-objects", "--info-quests",
"--info-extract", "--info-extract-tree", "--info-extract-budget",
"--list-missing-sidecars",
"--info-png", "--info-jsondbc", "--info-blp", "--info-pack-budget",
"--info-pack-tree",
"--info-m2", "--info-wmo", "--info-adt",
"--info-zone", "--info-zone-overview", "--info-project-overview",
"--copy-project", "--info-wcp", "--list-wcp",
"--list-creatures", "--list-objects", "--list-quests",
"--list-quest-objectives", "--list-quest-rewards",
"--info-creature", "--info-quest", "--info-object",
"--info-quest-graph-stats",
"--info-creatures-by-faction", "--info-creatures-by-level",
"--info-objects-by-path", "--info-objects-by-type",
"--info-quests-by-level", "--info-quests-by-xp",
"--unpack-wcp", "--pack-wcp",
"--validate", "--validate-wom", "--validate-wob", "--validate-woc",
"--validate-whm", "--validate-all", "--validate-project",
"--validate-project-open-only", "--audit-project", "--bench-audit-project",
"--bench-validate-project", "--bench-bake-project",
"--bench-migrate-data-tree", "--list-data-tree-largest",
"--export-data-tree-md", "--gen-texture", "--gen-mesh", "--gen-mesh-textured",
"--add-texture-to-mesh", "--add-texture-to-zone",
"--gen-mesh-stairs", "--gen-mesh-grid", "--gen-mesh-disc",
"--gen-mesh-tube", "--gen-mesh-capsule", "--gen-mesh-arch",
"--gen-mesh-pyramid", "--gen-mesh-fence", "--gen-mesh-tree",
"--gen-mesh-rock", "--gen-mesh-pillar", "--gen-mesh-bridge",
"--gen-mesh-tower", "--gen-mesh-house", "--gen-mesh-fountain",
"--gen-mesh-statue", "--gen-mesh-altar", "--gen-mesh-portal",
"--gen-mesh-archway", "--gen-mesh-barrel", "--gen-mesh-chest",
"--gen-mesh-anvil", "--gen-mesh-mushroom", "--gen-mesh-cart",
"--gen-mesh-banner", "--gen-mesh-grave", "--gen-mesh-bench",
"--gen-mesh-shrine", "--gen-mesh-totem", "--gen-mesh-cage",
"--gen-mesh-throne", "--gen-mesh-coffin", "--gen-mesh-bookshelf",
"--gen-mesh-tent", "--gen-mesh-firepit", "--gen-mesh-woodpile",
"--gen-mesh-canopy", "--gen-mesh-haystack", "--gen-mesh-dock",
"--gen-mesh-pergola", "--gen-mesh-chimney", "--gen-mesh-bedroll",
"--gen-mesh-workbench", "--gen-mesh-crate-stack",
"--gen-mesh-watchpost", "--gen-mesh-water-trough",
"--gen-mesh-training-dummy", "--gen-mesh-hitching-post",
"--gen-mesh-outhouse", "--gen-mesh-forge",
"--gen-mesh-archery-target", "--gen-mesh-gravel-pile",
"--gen-mesh-stone-bench", "--gen-mesh-mine-cart",
"--gen-mesh-hitching-rail", "--gen-mesh-pillar-row",
"--gen-mesh-statue-base", "--gen-mesh-bird-bath",
"--gen-mesh-planter-box", "--gen-mesh-urn", "--gen-mesh-candle",
"--gen-mesh-lantern", "--gen-mesh-chalice",
"--gen-mesh-standing-torch", "--gen-mesh-scroll-case",
"--gen-mesh-stove", "--gen-mesh-well-pail",
"--gen-mesh-mug", "--gen-mesh-mortar-pestle",
"--gen-mesh-rune-stone",
"--gen-camp-pack", "--gen-blacksmith-pack", "--gen-village-pack",
"--gen-temple-pack", "--gen-graveyard-pack",
"--gen-garden-pack", "--gen-dock-pack", "--gen-tavern-pack",
"--gen-mining-pack", "--gen-arena-pack",
"--gen-kitchen-pack",
"--gen-mesh-table", "--gen-mesh-lamppost", "--gen-mesh-bed",
"--gen-mesh-ladder", "--gen-mesh-well", "--gen-mesh-signpost",
"--gen-mesh-mailbox", "--gen-mesh-tombstone", "--gen-mesh-crate",
"--gen-mesh-stool", "--gen-mesh-cauldron", "--gen-mesh-gate",
"--gen-mesh-beehive", "--gen-mesh-weathervane",
"--gen-mesh-scarecrow", "--gen-mesh-sundial",
"--gen-mesh-podium", "--gen-mesh-brazier", "--gen-mesh-archway-double",
"--gen-texture-gradient",
"--gen-mesh-from-heightmap", "--export-mesh-heightmap",
"--displace-mesh",
"--scale-mesh", "--translate-mesh", "--strip-mesh",
"--gen-texture-noise", "--gen-texture-noise-color", "--rotate-mesh",
"--center-mesh", "--flip-mesh-normals", "--mirror-mesh",
"--smooth-mesh-normals",
"--merge-meshes",
"--gen-texture-radial", "--gen-texture-stripes", "--gen-texture-dots",
"--gen-texture-rings", "--gen-texture-checker", "--gen-texture-brick",
"--gen-texture-wood", "--gen-texture-grass", "--gen-texture-fabric",
"--gen-texture-cobble", "--gen-texture-marble", "--gen-texture-metal",
"--gen-texture-leather", "--gen-texture-sand", "--gen-texture-snow",
"--gen-texture-lava", "--gen-texture-tile", "--gen-texture-bark",
"--gen-texture-clouds", "--gen-texture-stars", "--gen-texture-vines",
"--gen-texture-mosaic", "--gen-texture-rust", "--gen-texture-circuit",
"--gen-texture-coral", "--gen-texture-flame", "--gen-texture-tartan",
"--gen-texture-argyle", "--gen-texture-herringbone",
"--gen-texture-scales", "--gen-texture-stained-glass",
"--gen-texture-shingles", "--gen-texture-frost",
"--gen-texture-parquet", "--gen-texture-bubbles",
"--gen-texture-spider-web", "--gen-texture-gingham",
"--gen-texture-lattice", "--gen-texture-honeycomb",
"--gen-texture-cracked", "--gen-texture-runes",
"--gen-texture-leopard", "--gen-texture-zebra",
"--gen-texture-knit", "--gen-texture-chainmail",
"--gen-texture-planks", "--gen-texture-corrugated",
"--gen-texture-rope", "--gen-texture-caustics",
"--gen-texture-starburst", "--gen-texture-studs",
"--gen-texture-moss", "--gen-texture-woodgrain",
"--gen-texture-carbon", "--gen-texture-pinstripe",
"--gen-texture-camo", "--gen-texture-snake-skin",
"--gen-texture-mesh-screen", "--gen-texture-bamboo",
"--gen-texture-blueprint", "--gen-texture-rust-streaks",
"--gen-texture-plaid", "--gen-texture-diamond-grid",
"--gen-texture-houndstooth", "--gen-texture-chevron",
"--gen-texture-dunes", "--gen-texture-swirl",
"--gen-texture-ironbark", "--gen-texture-mold",
"--gen-texture-embroidery", "--gen-texture-lightbeam",
"--gen-texture-dewdrops", "--gen-texture-pinwheel",
"--gen-texture-scratched-metal", "--gen-texture-crackle",
"--gen-texture-star", "--gen-texture-halftone",
"--gen-texture-bayer", "--gen-texture-moon",
"--gen-texture-damask", "--gen-texture-snowflake",
"--gen-texture-gear-cog",
"--validate-glb", "--info-glb", "--info-glb-tree", "--info-glb-bytes",
"--validate-jsondbc", "--check-glb-bounds", "--validate-stl",
"--validate-png", "--validate-blp",
"--zone-summary", "--info-zone-tree", "--info-project-tree",
"--info-zone-bytes", "--info-project-bytes",
"--info-zone-extents", "--info-project-extents",
"--info-zone-water", "--info-project-water",
"--info-zone-density", "--info-project-density",
"--export-zone-summary-md", "--export-quest-graph",
"--export-zone-csv", "--export-zone-html", "--export-project-html",
"--export-project-md", "--export-zone-checksum", "--export-project-checksum",
"--validate-project-checksum",
"--scaffold-zone", "--mvp-zone", "--add-tile", "--remove-tile", "--list-tiles",
"--for-each-zone", "--for-each-tile", "--zone-stats", "--info-tilemap",
"--list-zone-deps", "--list-project-orphans", "--remove-project-orphans",
"--check-zone-refs", "--check-zone-content",
"--check-project-content", "--check-project-refs",
"--export-zone-deps-md", "--export-zone-spawn-png",
"--add-creature", "--add-object", "--add-quest", "--add-item",
"--random-populate-zone", "--random-populate-items",
"--info-zone-audio", "--snap-zone-to-ground", "--audit-zone-spawns",
"--info-project-audio", "--snap-project-to-ground",
"--audit-project-spawns", "--list-zone-spawns", "--list-project-spawns",
"--gen-random-zone", "--gen-random-project", "--gen-zone-texture-pack",
"--gen-zone-mesh-pack", "--gen-zone-starter-pack",
"--gen-project-starter-pack", "--gen-audio-tone",
"--gen-audio-noise", "--gen-audio-sweep", "--gen-zone-audio-pack",
"--info-zone-summary", "--info-project-summary",
"--info-zone-deps", "--info-project-deps",
"--gen-zone-readme", "--gen-project-readme",
"--validate-zone-pack", "--validate-project-packs", "--info-spawn",
"--diff-zone-spawns",
"--list-items", "--info-item", "--set-item", "--export-zone-items-md",
"--export-project-items-md", "--export-project-items-csv",
"--add-quest-objective", "--add-quest-reward-item", "--set-quest-reward",
"--remove-quest-objective", "--clone-quest", "--clone-creature",
"--clone-item", "--validate-items", "--validate-project-items",
"--info-project-items",
"--clone-object",
"--remove-creature", "--remove-object", "--remove-quest", "--remove-item",
"--copy-zone-items",
"--copy-zone", "--rename-zone", "--remove-zone",
"--clear-zone-content", "--strip-zone", "--strip-project",
"--repair-zone", "--repair-project",
"--gen-makefile", "--gen-project-makefile",
"--build-woc", "--regen-collision", "--fix-zone",
"--export-png", "--export-obj", "--import-obj",
"--export-wob-obj", "--import-wob-obj",
"--export-woc-obj", "--export-whm-obj",
"--export-glb", "--export-wob-glb", "--export-whm-glb",
"--export-stl", "--import-stl",
"--bake-zone-glb", "--bake-zone-stl", "--bake-zone-obj",
"--bake-project-obj", "--bake-project-stl", "--bake-project-glb",
"--bake-wom-collision", "--bake-wob-collision", "--bake-zone-collision",
"--audit-watertight", "--audit-watertight-wob",
"--convert-m2", "--convert-m2-batch",
"--convert-wmo", "--convert-wmo-batch",
"--convert-dbc-json", "--convert-dbc-batch", "--convert-json-dbc",
"--convert-blp-png", "--convert-blp-batch",
"--migrate-wom", "--migrate-zone", "--migrate-project",
"--migrate-data-tree", "--info-data-tree", "--strip-data-tree",
"--audit-data-tree",
"--migrate-jsondbc",
};
const std::size_t kArgRequiredSize =
sizeof(kArgRequired) / sizeof(kArgRequired[0]);
} // namespace cli
} // namespace editor
} // namespace wowee