Kelsidavis-WoWee/tools/editor/cli_list_formats.cpp
Kelsi 62a10937e0 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

189 lines
14 KiB
C++

#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)"},
{"WANI", ".wani", "anim", "AnimationData.dbc", "Animation ID + fallback + weapon-flag catalog"},
{"WSVK", ".wsvk", "spellfx", "SpellVisualKit.dbc + SpellVisFx", "Spell visual kit (cast/proj/impact effects)"},
{"WWUI", ".wwui", "ui", "WorldStateUI.dbc + world_state", "World-state UI (BG scoreboards / siege counters)"},
{"WPCN", ".wpcn", "logic", "PlayerCondition.dbc + conditions", "Player condition (gates, AND/OR/NOT chains)"},
{"WTSK", ".wtsk", "crafting", "SkillLineAbility.dbc + recipes", "Trade skill recipes (per-profession crafts)"},
{"WCEQ", ".wceq", "creatures", "creature_equip_template", "Creature equipment loadout (visible weapons)"},
{"WSET", ".wset", "items", "ItemSet.dbc + ItemSetSpell.dbc", "Item set + tier-bonus catalog"},
{"WGTP", ".wgtp", "ui", "GameTips.dbc + tutorial hints", "Game tips / tutorial / loading-screen catalog"},
{"WCMP", ".wcmp", "pets", "CreatureFamily + companion SQL", "Companion / vanity pet catalog"},
{"WSMC", ".wsmc", "spells", "SpellMechanic.dbc + DR tables", "Spell mechanic / CC category catalog"},
{"WKBD", ".wkbd", "input", "KeyBinding.dbc + default binds", "Default keybinding catalog"},
{"WSCH", ".wsch", "spells", "SpellSchools.dbc + Resistances", "Spell school / damage type catalog"},
{"WLFG", ".wlfg", "social", "LFGDungeons.dbc + LFG rewards", "LFG / Dungeon Finder catalog"},
{"WMAC", ".wmac", "ui", "(client-side macro storage)", "Macro / slash command catalog"},
{"WCHF", ".wchf", "chars", "CharHairGeosets + CharFacialHair", "Character hair / face customization catalog"},
{"WPVP", ".wpvp", "pvp", "honor / arena rank tables", "PvP honor rank + arena tier catalog"},
{"WBNK", ".wbnk", "items", "ItemBag.dbc + bank slots", "Bag / bank / special slot catalog"},
{"WRUN", ".wrun", "spells", "RuneCost.dbc + ChrPowerType DK", "Death Knight rune cost catalog"},
{"WLDS", ".wlds", "ui", "LoadingScreens.dbc", "Per-zone loading screen catalog"},
{"WSUF", ".wsuf", "items", "ItemRandomProperties + Suffix", "Item random-suffix bonus catalog"},
{"WCRR", ".wcrr", "stats", "gtCombatRatings.dbc + curves", "Combat rating conversion catalog"},
{"WUMV", ".wumv", "stats", "UnitMovement.dbc + speed mods", "Unit movement type / speed catalog"},
{"WQSO", ".wqso", "quests", "QuestSort.dbc + QuestInfo cats", "Quest sort / category catalog"},
{"WSRG", ".wsrg", "spells", "SpellRange.dbc + per-spell range", "Spell range bucket catalog"},
{"WSCT", ".wsct", "spells", "SpellCastTimes.dbc + cast scaling","Spell cast time bucket catalog"},
{"WSDR", ".wsdr", "spells", "SpellDuration.dbc + per-spell dur","Spell duration bucket catalog"},
{"WSCD", ".wscd", "spells", "SpellCooldown.dbc + shared cd grp","Spell cooldown category catalog"},
{"WCEF", ".wcef", "creatures", "CreatureFamily.dbc + pet trees", "Creature / pet family catalog"},
{"WSPC", ".wspc", "spells", "Spell.dbc power-cost fields", "Spell power cost bucket catalog"},
{"WGFS", ".wgfs", "glyphs", "GlyphSlot.dbc", "Glyph slot layout catalog"},
{"WCDF", ".wcdf", "creatures", "CreatureDifficulty.dbc", "Creature difficulty variant catalog"},
{"WMAT", ".wmat", "items", "Material.dbc + ItemDisplayInfo", "Item material catalog"},
{"WPSP", ".wpsp", "chars", "playercreateinfo SQL + StartOutfit","Player spawn profile catalog"},
{"WTLE", ".wtle", "talents", "TalentTab.dbc", "Talent tab / tree catalog"},
{"WCTR", ".wctr", "currency", "CurrencyTypes.dbc + caps", "Currency type catalog"},
{"WSPR", ".wspr", "spells", "Spell.dbc Reagent[8]+Count[8]", "Spell reagent set catalog"},
{"WACR", ".wacr", "achieve", "Achievement_Criteria.dbc", "Achievement criteria catalog"},
{"WSEF", ".wsef", "spells", "SpellEffect.Effect dispatch", "Spell effect type catalog"},
{"WAUR", ".waur", "spells", "SpellEffect.EffectAuraType", "Spell aura type catalog"},
{"WIQR", ".wiqr", "items", "Item quality tier colors+rules", "Item quality tier catalog"},
{"WSCS", ".wscs", "skills", "SkillCostsData.dbc + train tiers", "Skill cost / training tier catalog"},
{"WIFS", ".wifs", "items", "Item.dbc Flags bit meanings", "Item flag bit catalog"},
{"WBKD", ".wbkd", "npcs", "npc_vendor + npc_trainer SQL", "NPC service definition catalog"},
{"WTBR", ".wtbr", "tokens", "currency_token_reward SQL", "Token reward redemption catalog"},
{"WSPS", ".wsps", "spells", "spell_proc_event SQL + Spell.dbc", "Spell proc trigger catalog"},
{"WCMR", ".wcmr", "creatures", "creature_movement waypoints SQL", "Creature patrol path catalog"},
{"WBOS", ".wbos", "raid", "instance_encounter SQL", "Boss encounter definition catalog"},
{"WHLD", ".whld", "raid", "InstanceTemplate.dbc reset fields","Instance lockout schedule catalog"},
{"WSTC", ".wstc", "pets", "stable_slot SQL + hunter UI", "Hunter stable slot catalog"},
{"WSTM", ".wstm", "stats", "gtChanceTo*.dbc + gtRegen*.dbc", "Stat modifier curve catalog"},
{"WACT", ".wact", "ui", "Hardcoded class default action bar","Action bar layout catalog"},
{"WGRP", ".wgrp", "social", "LFG group-composition rules", "Group composition catalog (role quotas)"},
{"WHRT", ".whrt", "social", "SMSG_BINDPOINTUPDATE bind list", "Hearthstone bind point catalog"},
{"WSCB", ".wscb", "server", "MOTD + scheduled SMSG_NOTIFICATION","Server channel broadcast catalog"},
{"WCMG", ".wcmg", "spells", "Stance/Form/Aspect mutex tables", "Combat maneuver group catalog (mutex spells)"},
{"WMSP", ".wmsp", "server", "realmlist + SMSG_REALM_LIST data", "Master server profile / realmlist catalog"},
{"WEMO", ".wemo", "social", "EmotesText.dbc + EmotesTextSound", "Emote definition catalog (/dance, /wave, etc.)"},
{"WBAB", ".wbab", "spells", "Spell.dbc nextRank/prevRank ptrs", "Buff & Aura book — long-duration class buffs with rank chains"},
{"WTBD", ".wtbd", "guilds", "guild_member tabard config blob", "Tabard design / heraldry catalog (3-color)"},
{"WSPM", ".wspm", "spellfx", "AreaTrigger.dbc + decal blob", "Spell persistent marker catalog (AoE ground decals)"},
// 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