feat(editor): add WSRG (Spell Range Index) open catalog format

Open replacement for Blizzard's SpellRange.dbc plus the per-spell
range-bucket fields in Spell.dbc. Defines the categorical range
buckets that spells reference instead of carrying their own min/max
yards (every Frostbolt shares one 30y bucket; every Heal shares
one 40y friendly bucket). Each entry carries separate min/max for
hostile vs friendly targets so heals can reach further on allies
than nukes do on enemies, plus an icon color for HUD range
indicators.

Three preset emitters: --gen-srg (3 baseline buckets:
Self/Melee/Spell), --gen-srg-ranged (5 ranged spell buckets:
Short/Medium/Long/VeryLong/Unlimited), --gen-srg-friendly (3
friendly-only buckets where hostile range is 0). --info-wsrg and
--validate-wsrg round out the per-format surface; validation
catches negative ranges, min>max, duplicate ids, out-of-range
rangeKind, and warns on Self+nonzero range or Melee>8y.

Wired through the cross-format table so WSRG appears automatically
in --list-formats, --info-magic, --diff-headers, --summary-dir,
--rename-by-magic, --catalog-grep, --tree-summary-md, and
--touch-tree. Format count 67 -> 68; CLI flag count 885 -> 890.
This commit is contained in:
Kelsi 2026-05-09 21:33:17 -07:00
parent 99a952299b
commit ede2d9918a
10 changed files with 620 additions and 0 deletions

View file

@ -0,0 +1,106 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
namespace wowee {
namespace pipeline {
// Wowee Open Spell Range Index catalog (.wsrg) — novel
// replacement for Blizzard's SpellRange.dbc plus the per-
// spell range-bucket fields in Spell.dbc. Defines the
// categorical range buckets that spells use ("Combat Range"
// 0-5y for melee, "Long Range" 0-40y for ranged casts,
// "Vision Range" 0-100y for area effects).
//
// Each spell references a rangeId here rather than carrying
// its own min/max yards. This lets the engine share range
// metadata across thousands of spells (every Frostbolt
// references the same 30y bucket) and lets the UI draw
// consistent range indicators (color-coded per-bucket).
//
// Friendly vs hostile range can differ — Heal might reach
// 40y on allies but Smite only 30y on enemies — so each
// entry carries separate min/max pairs for each affiliation.
//
// Cross-references with previously-added formats:
// None — this catalog is consumed directly by the spell
// engine and HUD. WSPL spell entries reference rangeId.
//
// Binary layout (little-endian):
// magic[4] = "WSRG"
// version (uint32) = current 1
// nameLen + name (catalog label)
// entryCount (uint32)
// entries (each):
// rangeId (uint32)
// nameLen + name
// descLen + description
// rangeKind (uint8) / pad[3]
// minRange (float)
// maxRange (float)
// minRangeFriendly (float)
// maxRangeFriendly (float)
// iconColorRGBA (uint32)
struct WoweeSpellRange {
enum RangeKind : uint8_t {
Self = 0, // 0-0 yards (caster only)
Melee = 1, // 0-5 yards (white attack range)
ShortRanged = 2, // 0-20 yards (close-quarters spell)
Ranged = 3, // 0-30 yards (standard cast)
LongRanged = 4, // 0-40 yards (rifle / long-cast spell)
VeryLong = 5, // 0-100 yards (vision / aura range)
Unlimited = 6, // any range (server-tracked global)
};
struct Entry {
uint32_t rangeId = 0;
std::string name;
std::string description;
uint8_t rangeKind = Ranged;
float minRange = 0.0f;
float maxRange = 30.0f;
float minRangeFriendly = 0.0f;
float maxRangeFriendly = 30.0f;
uint32_t iconColorRGBA = 0xFFFFFFFFu;
};
std::string name;
std::vector<Entry> entries;
bool isValid() const { return !entries.empty(); }
const Entry* findById(uint32_t rangeId) const;
static const char* rangeKindName(uint8_t k);
};
class WoweeSpellRangeLoader {
public:
static bool save(const WoweeSpellRange& cat,
const std::string& basePath);
static WoweeSpellRange load(const std::string& basePath);
static bool exists(const std::string& basePath);
// Preset emitters used by --gen-srg* variants.
//
// makeStarter — 3 baseline buckets (Self 0-0,
// Melee 0-5, Spell 0-30) covering
// the most common range categories.
// makeRanged — 5 ranged spell buckets (Short 0-20,
// Medium 0-30, Long 0-40, VeryLong
// 0-100, Unlimited) for varied
// ranged-class spell ranges.
// makeFriendly — 3 buckets where friendly-target
// range exceeds hostile-target range
// (Heal 40y friendly / 0 hostile,
// Cleanse 30y friendly / 0 hostile,
// Buff 30y friendly / 0 hostile).
static WoweeSpellRange makeStarter(const std::string& catalogName);
static WoweeSpellRange makeRanged(const std::string& catalogName);
static WoweeSpellRange makeFriendly(const std::string& catalogName);
};
} // namespace pipeline
} // namespace wowee