2026-05-09 19:14:55 -07:00
|
|
|
#include "cli_list_formats.hpp"
|
|
|
|
|
#include "cli_arg_parse.hpp"
|
|
|
|
|
|
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
|
|
|
|
|
|
#include <cstdio>
|
|
|
|
|
#include <cstring>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
namespace wowee {
|
|
|
|
|
namespace editor {
|
|
|
|
|
namespace cli {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
// Static catalog of every novel open format the editor can
|
|
|
|
|
// currently emit, parse, and round-trip. Adding a new format
|
|
|
|
|
// requires appending one row here so --list-formats stays
|
|
|
|
|
// authoritative. The list is intentionally kept in
|
|
|
|
|
// introduction order so users can correlate against the
|
|
|
|
|
// commit history.
|
|
|
|
|
struct FormatRow {
|
|
|
|
|
const char* magic; // 4-char binary magic
|
|
|
|
|
const char* extension; // file suffix (with dot)
|
|
|
|
|
const char* category; // grouping label
|
|
|
|
|
const char* replaces; // proprietary source(s)
|
|
|
|
|
const char* description;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr FormatRow kFormats[] = {
|
|
|
|
|
// World / asset / pipeline foundations.
|
|
|
|
|
{"WOM ", ".wom", "asset", "M2", "M2 model — bones / vertices / animations"},
|
|
|
|
|
{"WOB ", ".wob", "asset", "WMO", "WMO building — groups / portals / collision"},
|
|
|
|
|
{"WHM ", ".whm", "world", "ADT heightmap", "ADT terrain heightmap tile"},
|
|
|
|
|
{"WOT ", ".wot", "world", "ADT textures", "ADT terrain texture splats + alpha layers"},
|
|
|
|
|
{"WOW ", ".wow", "world", "WDT/WDL", "Per-zone world manifest + weather"},
|
|
|
|
|
|
|
|
|
|
// Catalog / DBC replacements.
|
|
|
|
|
{"WITM", ".wit", "items", "Item.dbc + item_template", "Item catalog (gear, consumables, quest items)"},
|
|
|
|
|
{"WCRT", ".wcrt", "creatures", "creature_template", "Creature catalog (NPCs, mobs, vendors)"},
|
|
|
|
|
{"WSPN", ".wspn", "wspn", "creature SQL", "Creature/object spawns by zone+coord"},
|
|
|
|
|
{"WLOT", ".wlot", "loot", "creature_loot_template", "Loot tables and drop chances"},
|
|
|
|
|
{"WGOT", ".wgot", "objects", "gameobject_template", "GameObject catalog (chests / doors)"},
|
|
|
|
|
{"WSND", ".wsnd", "audio", "SoundEntries.dbc", "Sound entry catalog"},
|
|
|
|
|
{"WSPL", ".wspl", "spells", "Spell.dbc + spell_template", "Spell catalog (effects, durations, costs)"},
|
|
|
|
|
{"WQTM", ".wqt", "quests", "quest_template + Quest*.dbc", "Quest catalog (objectives, rewards)"},
|
|
|
|
|
{"WMSX", ".wms", "maps", "Map.dbc + AreaTable.dbc", "Map and area catalog"},
|
|
|
|
|
{"WCHC", ".wchc", "chars", "ChrClasses.dbc + ChrRaces.dbc", "Class + race catalog"},
|
|
|
|
|
{"WACH", ".wach", "achieve", "Achievement.dbc + Criteria.dbc", "Achievement catalog with criteria"},
|
|
|
|
|
{"WTRN", ".wtrr", "trainers", "npc_trainer + Spell.dbc", "Trainer catalog (spell teaching)"},
|
|
|
|
|
{"WGSP", ".wgoss", "gossip", "gossip_menu + npc_gossip", "Gossip menu / dialog tree catalog"},
|
|
|
|
|
{"WTAX", ".wtax", "taxi", "TaxiNodes.dbc + TaxiPath.dbc", "Flight path catalog (taxi network)"},
|
|
|
|
|
{"WTAL", ".wtal", "talents", "Talent.dbc + TalentTab.dbc", "Talent tree catalog"},
|
|
|
|
|
{"WTKN", ".wtkn", "tokens", "ItemExtendedCost + currency", "Token / currency catalog"},
|
|
|
|
|
{"WTRG", ".wtrg", "triggers", "AreaTrigger.dbc + areatrigger", "Area trigger catalog"},
|
|
|
|
|
{"WTIT", ".wttl", "titles", "CharTitles.dbc", "Player title catalog"},
|
|
|
|
|
{"WSEA", ".wevt", "events", "GameEvent + spell_script", "Scripted event catalog"},
|
|
|
|
|
{"WMOU", ".wmnt", "mounts", "Mount.dbc + spell_mount", "Mount catalog (ground+flying)"},
|
|
|
|
|
{"WBGD", ".wbgd", "battle", "BattlemasterList.dbc + bg_*", "Battleground definition catalog"},
|
|
|
|
|
{"WMAL", ".wmal", "mail", "mail + mail_external", "In-game mail message catalog"},
|
|
|
|
|
{"WGEM", ".wgem", "gems", "GemProperties.dbc + Enchant.dbc", "Gem + enchantment catalog"},
|
|
|
|
|
{"WGLD", ".wgld", "guilds", "guild + guild_member", "Guild catalog (charters, ranks)"},
|
|
|
|
|
{"WPCD", ".wcnd", "cond", "Conditions + spell_proc_event", "Reusable condition rule catalog"},
|
|
|
|
|
{"WPET", ".wpet", "pets", "CreatureFamily.dbc + pet SQL", "Hunter pet + warlock minion catalog"},
|
|
|
|
|
{"WAUC", ".wauc", "auction", "auctionhouse + npc_auctioneer", "Auction house rules catalog"},
|
|
|
|
|
{"WCHN", ".wchn", "channels", "ChatChannels.dbc + chat_channel", "Chat channel catalog"},
|
|
|
|
|
{"WCMS", ".wcms", "cinematic", "Movie.dbc + CinematicCamera.dbc", "Cinematic catalog (videos, cutscenes)"},
|
|
|
|
|
{"WGLY", ".wgly", "glyphs", "GlyphProperties.dbc + GlyphSlot", "WotLK glyph catalog"},
|
|
|
|
|
{"WVHC", ".wvhc", "vehicles", "Vehicle.dbc + VehicleSeat.dbc", "Vehicle + seat-layout catalog"},
|
|
|
|
|
{"WHOL", ".whol", "holiday", "Holidays.dbc + game_event", "Calendar holiday + event catalog"},
|
|
|
|
|
{"WLIQ", ".wliq", "liquids", "LiquidType.dbc", "Liquid material catalog (water/lava/slime)"},
|
feat(pipeline): add WANI (Wowee Animation) catalog
46th open format — replaces AnimationData.dbc plus the
hard-coded animation-id tables in M2 model loaders. Defines
named animations (Stand, Walk, Run, Cast, Death, MountIdle,
Fly, ...) with fallback chains, behavior tier (default /
mounted / sitting / aerial / swimming), and weapon-flag
bitmasks that select the correct animation variant when the
model wields 1H / 2H / dual / bow / rifle / wand / etc.
Cross-references with prior formats — fallbackId resolves
within the same WANI catalog (graceful degradation when the
requested animation is absent: Run falls back to Walk,
Attack2H falls back to Attack1H).
10 weapon-flag constants + 6 behavior flags (Looped,
BlendableCycle, Interruptable, MovementSync, OneShot,
PreserveAtEnd). 5 behavior tiers. CLI: --gen-animations
(5 essentials), --gen-animations-combat (8 weapon-typed
attacks + parry + channel), --gen-animations-movement (6
locomotion anims with tier transitions). Validator catches
id-uniqueness, fallback-self-loop, looped-without-duration,
mutually-exclusive Looped+OneShot flags, weaponFlags=0
warning, and unresolved fallback warnings.
Also extends --list-formats and --info-magic with WANI.
2026-05-09 19:19:13 -07:00
|
|
|
{"WANI", ".wani", "anim", "AnimationData.dbc", "Animation ID + fallback + weapon-flag catalog"},
|
feat(pipeline): add WSVK (Wowee Spell Visual Kit) catalog
47th open format — replaces SpellVisualKit.dbc +
SpellVisualEffectName.dbc plus the AzerothCore-style spell
visual SQL data. Defines per-spell visual presentations:
cast-bar effect model, projectile model + travel speed +
arc gravity, impact effect model, hand effect on the caster,
and the animations + sounds that fire at cast / channel /
impact time.
Cross-references with prior formats — castAnimId / impactAnimId
/ precastAnimId point at WANI.animationId, castSoundId /
impactSoundId point at WSND.soundId. Spell catalogs (WSPL)
will reference visualKitId here to bind "what mechanically
happens" to "what plays visually."
CLI: --gen-svk (3-kit Frostbolt/Fireball/HealingTouch starter
showing projectile + AoE + heal patterns), --gen-svk-combat
(5 melee/ranged with WANI animation refs), --gen-svk-utility
(4 portal/hearth/mount/resurrect with no projectile),
--info-wsvk, --validate-wsvk with --json variants. Validator
catches id=0/duplicates, missing name, negative speeds/radii,
projectile-model + speed coherence (model without speed =
never travels; speed without model = invisible), and a
no-effect catch-all (no models + no anims + no sounds).
2026-05-09 19:23:36 -07:00
|
|
|
{"WSVK", ".wsvk", "spellfx", "SpellVisualKit.dbc + SpellVisFx", "Spell visual kit (cast/proj/impact effects)"},
|
feat(pipeline): add WWUI (Wowee World-State UI) catalog
48th open format — replaces WorldStateUI.dbc plus the
AzerothCore-style world_state SQL data. Defines on-screen UI
elements that surface server-side world-state variables: BG
scoreboards (flag captures, base controls), Wintergrasp tank
counters, Eye of the Storm flag-carrier indicator, dungeon
boss progress, world-event collection trackers.
Each entry binds a server-side variableIndex to a UI panel
kind (counter / timer / flag-icon / progress-bar / two-sided
score / custom) gated by mapId+areaId, with optional
alwaysVisible and hideWhenZero flags and a chosen panel
position (top / bottom / top-left / top-right / center).
Cross-references with prior formats — mapId points at
WMS.mapId and areaId points at WMS.areaId.
CLI: --gen-wsui (3-entry BG scoreboard starter for WSG/AB/
EotS), --gen-wsui-wintergrasp (4-entry full Wintergrasp UI),
--gen-wsui-dungeon (3-entry boss/keys/treasure hunt UI),
--info-wwui, --validate-wwui with --json variants. Validator
catches id=0/duplicates, kind/position out of range,
variableIndex=0 warning, alwaysVisible+hideWhenZero conflict
warning, and (mapId, variableIndex) collision warning when
two entries would read the same server slot on the same map.
Also extends --list-formats and --info-magic with WWUI.
2026-05-09 19:32:15 -07:00
|
|
|
{"WWUI", ".wwui", "ui", "WorldStateUI.dbc + world_state", "World-state UI (BG scoreboards / siege counters)"},
|
feat(pipeline): add WPCN (Wowee Player Condition) catalog
49th open format — replaces PlayerCondition.dbc plus the
AzerothCore-style condition resolver. Defines reusable
boolean checks that other catalogs reference by conditionId
to gate gossip options, vendor items, quest availability,
achievement criteria, spell trainer offerings.
16 condition kinds (Always, Race, Class, Level, Zone, Map,
Reputation, AchievementWon, QuestComplete, QuestActive,
SpellKnown, ItemEquipped, Faction, InCombat, Mounted,
Resting), 8 comparison ops (==, !=, >, >=, <, <=, in-set,
not-in-set), and 4 chain ops (none, and, or, not) — chain
multiple conditions via chainNextId to express arbitrary
boolean trees.
Cross-references with prior formats — targetIdA is
polymorphic by conditionKind: resolves to WCHC raceId/classId,
WMS areaId/mapId, WFAC factionId, WACH achievementId, WQT
questId, WSPL spellId, or WIT itemId. chainNextId resolves
within the same WPCN catalog.
CLI: --gen-pcn (3 single-check starters), --gen-pcn-quest-gates
(4 cross-format quest gates with real WQT/WFAC/WACH/WMS IDs),
--gen-pcn-composite (3 leaves + 3 chained roots showing AND/
OR/NOT). Validator catches id=0/duplicates, kind/op out of
range, chain self-loop (infinite recursion), chainOp set
without chainNextId (dangling chain), chainNextId set without
chainOp (dead pointer warning), and unresolved chainNextId
references.
2026-05-09 19:36:56 -07:00
|
|
|
{"WPCN", ".wpcn", "logic", "PlayerCondition.dbc + conditions", "Player condition (gates, AND/OR/NOT chains)"},
|
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
|
|
|
{"WTSK", ".wtsk", "crafting", "SkillLineAbility.dbc + recipes", "Trade skill recipes (per-profession crafts)"},
|
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
|
|
|
{"WCEQ", ".wceq", "creatures", "creature_equip_template", "Creature equipment loadout (visible weapons)"},
|
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
|
|
|
{"WSET", ".wset", "items", "ItemSet.dbc + ItemSetSpell.dbc", "Item set + tier-bonus catalog"},
|
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
|
|
|
{"WGTP", ".wgtp", "ui", "GameTips.dbc + tutorial hints", "Game tips / tutorial / loading-screen catalog"},
|
2026-05-09 19:14:55 -07:00
|
|
|
|
|
|
|
|
// Additional pipeline catalogs without the alternating
|
|
|
|
|
// gen/info/validate CLI surface (loaded by the engine
|
|
|
|
|
// directly).
|
|
|
|
|
{"WFAC", ".wfac", "factions", "Faction.dbc + FactionTemplate", "Faction + reputation catalog"},
|
|
|
|
|
{"WLCK", ".wlck", "locks", "Lock.dbc", "Lock + key requirement catalog"},
|
|
|
|
|
{"WSKL", ".wskl", "skills", "SkillLine.dbc + SkillLineAbility","Skill / profession catalog"},
|
|
|
|
|
{"WOLA", ".wola", "light", "Light.dbc + LightParams.dbc", "Outdoor lighting / sky color catalog"},
|
|
|
|
|
{"WOWA", ".wowa", "weather", "weather + LightParams", "Per-zone weather schedule catalog"},
|
|
|
|
|
{"WMPX", ".wmpx", "worldmap", "WorldMapArea.dbc", "World map / minimap zone catalog"},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr size_t kFormatsCount =
|
|
|
|
|
sizeof(kFormats) / sizeof(kFormats[0]);
|
|
|
|
|
|
|
|
|
|
int handleList(int& i, int argc, char** argv) {
|
|
|
|
|
bool jsonOut = consumeJsonFlag(i, argc, argv);
|
|
|
|
|
if (jsonOut) {
|
|
|
|
|
nlohmann::json j;
|
|
|
|
|
j["count"] = kFormatsCount;
|
|
|
|
|
nlohmann::json arr = nlohmann::json::array();
|
|
|
|
|
for (const auto& row : kFormats) {
|
|
|
|
|
arr.push_back({
|
|
|
|
|
{"magic", row.magic},
|
|
|
|
|
{"extension", row.extension},
|
|
|
|
|
{"category", row.category},
|
|
|
|
|
{"replaces", row.replaces},
|
|
|
|
|
{"description", row.description},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
j["formats"] = arr;
|
|
|
|
|
std::printf("%s\n", j.dump(2).c_str());
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
std::printf("Wowee open formats: %zu total\n", kFormatsCount);
|
|
|
|
|
std::printf("\n");
|
|
|
|
|
std::printf(" magic ext category replaces description\n");
|
|
|
|
|
std::printf(" ------- ------- ----------- -------------------------------- -----------\n");
|
|
|
|
|
for (const auto& row : kFormats) {
|
|
|
|
|
std::printf(" %-7s %-7s %-11s %-32s %s\n",
|
|
|
|
|
row.magic, row.extension, row.category,
|
|
|
|
|
row.replaces, row.description);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
bool handleListFormats(int& i, int argc, char** argv, int& outRc) {
|
|
|
|
|
if (std::strcmp(argv[i], "--list-formats") == 0) {
|
|
|
|
|
outRc = handleList(i, argc, argv); return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace cli
|
|
|
|
|
} // namespace editor
|
|
|
|
|
} // namespace wowee
|