mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-11 03:23:51 +00:00
feat(editor): add WSPV (Spell Variant) — 113th open format
Novel replacement for the implicit context-conditional spell substitution rules vanilla WoW encoded across SpellSpecificType, SpellEffect.EffectMechanic override fields, and the proc-modified spell tables in SpellProcEvent. Each entry binds one base spell to a variant spell that activates when a runtime condition is met (player in a specific stance, talent talented, racial buff active, weapon equipped, aura present). Six conditionKind values cover the full substitution surface: Stance / Form / Talent / Race / EquippedWeapon / AuraActive. The conditionValue field is polymorphic — its semantics depend on conditionKind (a stance spellId, a talentId, a race bit, etc.). The spell-cast pipeline iterates findByBaseSpell at cast time and picks the highest-priority variant whose condition is satisfied, falling through to the base spell if none matches. Three preset emitters demonstrating the pattern: makeWarriorStance (4 stance-conditional Warrior variants — Heroic Strike Berserker damage bonus, Battle baseline, Mocking Blow Defensive AoE taunt, Pummel Berserker-only gate), makeTalentMod (4 talent- modified variants — Frostbolt + Brain Freeze instant, Lava Burst + Flame Shock auto-crit, Earth Shield + Improved bonus heal, Ferocious Bite + Berserk), makeRacial (4 race-gated racials — Stoneform Dwarf, War Stomp Tauren, Berserking Troll, Will of the Forsaken). Validator's most novel check is the (baseSpell, conditionKind, conditionValue, priority) 4-tuple uniqueness — two variants with all four matching would tie at runtime and resolve non-deterministically (the spell-cast pipeline's std::sort by priority is stable but the underlying iteration order is undefined when priorities tie). Packs the tuple into 64 bits (base 32 | value 16 | kind 8 | prio 8) for set lookup. Format count 112 -> 113. CLI flag count 1213 -> 1218.
This commit is contained in:
parent
81eb854709
commit
6403d84a28
10 changed files with 725 additions and 0 deletions
132
include/pipeline/wowee_spell_variants.hpp
Normal file
132
include/pipeline/wowee_spell_variants.hpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace wowee {
|
||||
namespace pipeline {
|
||||
|
||||
// Wowee Open Spell Variant catalog (.wspv) — novel
|
||||
// replacement for the implicit context-conditional
|
||||
// spell substitution rules vanilla WoW encoded across
|
||||
// SpellSpecificType, SpellEffect.EffectMechanic
|
||||
// override fields, and the proc-modified spell tables
|
||||
// in SpellProcEvent. Each entry binds one base spell
|
||||
// to a variant spell that activates when a runtime
|
||||
// condition is met (player in a specific stance,
|
||||
// talent talented, racial buff active, etc.).
|
||||
//
|
||||
// The spell-cast pipeline consults this catalog at the
|
||||
// moment of cast: if any variant whose condition is
|
||||
// satisfied has higher priority than the base, the
|
||||
// variant spell ID is substituted for the cast.
|
||||
//
|
||||
// Cross-references with previously-added formats:
|
||||
// WSPL: baseSpellId and variantSpellId both reference
|
||||
// the WSPL spell catalog.
|
||||
// WCMG: when conditionKind=Stance/Form, conditionValue
|
||||
// is a WCMG spellId (the stance/form active
|
||||
// on the caster).
|
||||
// WTAL: when conditionKind=Talent, conditionValue is
|
||||
// a WTAL talent ID (the talented passive that
|
||||
// enables the variant).
|
||||
// WCHC: when conditionKind=Race, conditionValue is a
|
||||
// WCHC race bit.
|
||||
//
|
||||
// Binary layout (little-endian):
|
||||
// magic[4] = "WSPV"
|
||||
// version (uint32) = current 1
|
||||
// nameLen + name (catalog label)
|
||||
// entryCount (uint32)
|
||||
// entries (each):
|
||||
// variantId (uint32)
|
||||
// nameLen + name
|
||||
// descLen + description
|
||||
// baseSpellId (uint32)
|
||||
// variantSpellId (uint32)
|
||||
// conditionKind (uint8) — Stance / Form /
|
||||
// Talent / Race /
|
||||
// EquippedWeapon /
|
||||
// AuraActive
|
||||
// priority (uint8) — higher overrides
|
||||
// lower; 0 = base
|
||||
// spell baseline
|
||||
// pad0 (uint8) / pad1 (uint8)
|
||||
// conditionValue (uint32) — polymorphic — see
|
||||
// conditionKind
|
||||
// iconColorRGBA (uint32)
|
||||
struct WoweeSpellVariants {
|
||||
enum ConditionKind : uint8_t {
|
||||
Stance = 0, // value = stance spellId
|
||||
Form = 1, // value = druid form
|
||||
// spellId
|
||||
Talent = 2, // value = talentId
|
||||
Race = 3, // value = WCHC race bit
|
||||
EquippedWeapon = 4, // value = weapon-type
|
||||
// bitmask (sword=2,
|
||||
// mace=4, etc.)
|
||||
AuraActive = 5, // value = aura spellId
|
||||
// currently on caster
|
||||
};
|
||||
|
||||
struct Entry {
|
||||
uint32_t variantId = 0;
|
||||
std::string name;
|
||||
std::string description;
|
||||
uint32_t baseSpellId = 0;
|
||||
uint32_t variantSpellId = 0;
|
||||
uint8_t conditionKind = Stance;
|
||||
uint8_t priority = 1;
|
||||
uint8_t pad0 = 0;
|
||||
uint8_t pad1 = 0;
|
||||
uint32_t conditionValue = 0;
|
||||
uint32_t iconColorRGBA = 0xFFFFFFFFu;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::vector<Entry> entries;
|
||||
|
||||
bool isValid() const { return !entries.empty(); }
|
||||
|
||||
const Entry* findById(uint32_t variantId) const;
|
||||
|
||||
// Returns all variants of one base spell, sorted by
|
||||
// descending priority. The spell-cast pipeline
|
||||
// iterates this list at cast time and picks the
|
||||
// highest-priority variant whose condition is
|
||||
// satisfied (or falls through to the base spell).
|
||||
std::vector<const Entry*> findByBaseSpell(uint32_t baseSpellId) const;
|
||||
};
|
||||
|
||||
class WoweeSpellVariantsLoader {
|
||||
public:
|
||||
static bool save(const WoweeSpellVariants& cat,
|
||||
const std::string& basePath);
|
||||
static WoweeSpellVariants load(const std::string& basePath);
|
||||
static bool exists(const std::string& basePath);
|
||||
|
||||
// Preset emitters used by --gen-spv* variants.
|
||||
//
|
||||
// makeWarriorStance — 4 stance-conditional Warrior
|
||||
// spell variants (Heroic Strike
|
||||
// Battle vs Berserker damage
|
||||
// bonus, Mocking Blow
|
||||
// Defensive AoE, Pummel
|
||||
// Berserker silence).
|
||||
// makeTalentMod — 4 talent-modified spell
|
||||
// variants (Frostbolt + Brain
|
||||
// Freeze proc, Lava Burst +
|
||||
// Flame Shock auto-crit,
|
||||
// Earth Shield + Improved,
|
||||
// Ferocious Bite + Berserk).
|
||||
// makeRacial — 4 racial spell variants
|
||||
// (Stoneform / War Stomp /
|
||||
// Berserking / WoTF).
|
||||
static WoweeSpellVariants makeWarriorStance(const std::string& catalogName);
|
||||
static WoweeSpellVariants makeTalentMod(const std::string& catalogName);
|
||||
static WoweeSpellVariants makeRacial(const std::string& catalogName);
|
||||
};
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue