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)"},
|
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
|