mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-11 11:33:52 +00:00
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.
118 lines
4.1 KiB
C++
118 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace wowee {
|
|
namespace pipeline {
|
|
|
|
// Wowee Open Stat Modifier Curve catalog (.wstm) —
|
|
// novel 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 simple 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 (Combat Ratings) live in the dedicated WCRR
|
|
// catalog with cubic spline support.
|
|
//
|
|
// Distinct from WCRR (Combat Rating conversion) which
|
|
// converts integer rating points to percentages, and
|
|
// distinct from WSPC (Spell Power Cost buckets) which
|
|
// scales per-spell costs. WSTM is for the generic
|
|
// engine-side stat curves that aren't per-spell or
|
|
// per-rating.
|
|
//
|
|
// Cross-references with previously-added formats:
|
|
// None — this catalog is consumed directly by the
|
|
// character stat resolver. Engines look up curves by
|
|
// curveId or by name.
|
|
//
|
|
// Binary layout (little-endian):
|
|
// magic[4] = "WSTM"
|
|
// version (uint32) = current 1
|
|
// nameLen + name (catalog label)
|
|
// entryCount (uint32)
|
|
// entries (each):
|
|
// curveId (uint32)
|
|
// nameLen + name
|
|
// descLen + description
|
|
// curveKind (uint8) / minLevel (uint8) / maxLevel (uint8) / pad (uint8)
|
|
// baseValue (float)
|
|
// perLevelDelta (float)
|
|
// multiplier (float)
|
|
// iconColorRGBA (uint32)
|
|
struct WoweeStatCurve {
|
|
enum CurveKind : uint8_t {
|
|
Crit = 0, // crit chance scaling per level
|
|
Hit = 1, // hit chance scaling
|
|
Power = 2, // attack power / spell power growth
|
|
Regen = 3, // mana / health regen rates
|
|
Resist = 4, // resistance scaling
|
|
Mitigation = 5, // armor / damage reduction
|
|
Misc = 6, // catch-all
|
|
};
|
|
|
|
struct Entry {
|
|
uint32_t curveId = 0;
|
|
std::string name;
|
|
std::string description;
|
|
uint8_t curveKind = Misc;
|
|
uint8_t minLevel = 1;
|
|
uint8_t maxLevel = 80;
|
|
uint8_t pad0 = 0;
|
|
float baseValue = 0.0f;
|
|
float perLevelDelta = 0.0f;
|
|
float multiplier = 1.0f;
|
|
uint32_t iconColorRGBA = 0xFFFFFFFFu;
|
|
};
|
|
|
|
std::string name;
|
|
std::vector<Entry> entries;
|
|
|
|
bool isValid() const { return !entries.empty(); }
|
|
|
|
const Entry* findById(uint32_t curveId) const;
|
|
|
|
// Resolve the curve at the given character level,
|
|
// applying the linear formula then scaling by the
|
|
// multiplier and clamping to [minLevel..maxLevel].
|
|
// Returns 0.0 if the level is below minLevel.
|
|
float resolveAtLevel(uint32_t curveId, uint8_t level) const;
|
|
|
|
static const char* curveKindName(uint8_t k);
|
|
};
|
|
|
|
class WoweeStatCurveLoader {
|
|
public:
|
|
static bool save(const WoweeStatCurve& cat,
|
|
const std::string& basePath);
|
|
static WoweeStatCurve load(const std::string& basePath);
|
|
static bool exists(const std::string& basePath);
|
|
|
|
// Preset emitters used by --gen-stm* variants.
|
|
//
|
|
// makeCrit — 5 crit-related curves (MeleeCritChance,
|
|
// RangedCritChance, SpellCritChance,
|
|
// ParryChance, DodgeChance) covering
|
|
// the standard crit-tier scaling.
|
|
// makeRegen — 4 regen curves (ManaPerSpirit,
|
|
// HpPerSpirit, EnergyPerSec, RageDecay)
|
|
// with the canonical Vanilla/TBC/WotLK
|
|
// stock formulas.
|
|
// makeArmor — 3 armor / mitigation curves
|
|
// (BaseArmorPerLevel, ArmorMitigation,
|
|
// ResistancePerLevel).
|
|
static WoweeStatCurve makeCrit(const std::string& catalogName);
|
|
static WoweeStatCurve makeRegen(const std::string& catalogName);
|
|
static WoweeStatCurve makeArmor(const std::string& catalogName);
|
|
};
|
|
|
|
} // namespace pipeline
|
|
} // namespace wowee
|