Kelsidavis-WoWee/include/pipeline/wowee_spell_pack.hpp
Kelsi 6d9d00fbb9 feat(pipeline): WSPK spell pack catalog (126th open format)
Novel replacement for the implicit per-class spellbook layout
that vanilla WoW derived from SkillLineAbility.dbc + the hard-
coded per-spec tab order baked into the client UI. Each WSPK
entry binds one (classId, tabIndex) pair to an ordered list of
spellIds shown in that spellbook tab.

Three presets seeded with canonical vanilla low-rank spellIds:
  --gen-spk-warrior  4 tabs (General + Arms/Fury/Protection)
                     including Charge, Mortal Strike,
                     Bloodthirst, Shield Block
  --gen-spk-mage     4 tabs (General + Arcane/Fire/Frost)
                     including Frostbolt rank 1 (spellId 116)
                     — the canonical "every mage starts here"
  --gen-spk-rogue    4 tabs (General + Assassination/Combat/
                     Subtlety) with poison + lethality picks

Validator catches: packId+tabName required, classId in 1..11,
tabIndex in 0..3, no duplicate packIds, no duplicate
(classId,tabIndex) pairs (spellbook UI dispatch tie), no zero
spellIds, no duplicate spellIds within any single tab (would
render twice in spellbook). Warns on classId 6 and 10 (vanilla
PlayerClass DBC gaps) and on empty tabs (player would see a
blank spellbook tab).

Format count 125 -> 126. CLI flag count 1328 -> 1335.
2026-05-10 03:37:36 -07:00

100 lines
3.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <cstdint>
#include <string>
#include <vector>
namespace wowee {
namespace pipeline {
// Wowee Open Spell Pack catalog (.wspk) — novel
// replacement for the implicit per-class spellbook
// layout that vanilla WoW derived from
// SkillLineAbility.dbc + SpellTabIcon mappings + the
// hard-coded per-spec tab order baked into the client
// UI. Each WSPK entry binds one (classId, tabIndex)
// pair to an ordered list of spellIds shown in that
// spellbook tab.
//
// Cross-references with previously-added formats:
// WSPL: spellIds in the ordered list are looked up
// against WSPL spell catalog at runtime.
// WCDB: classId references the playable-class
// catalog (currently 1..11 in vanilla:
// Warrior=1 ... Druid=11).
//
// Binary layout (little-endian):
// magic[4] = "WSPK"
// version (uint32) = current 1
// nameLen + name (catalog label)
// entryCount (uint32)
// entries (each):
// packId (uint32) — surrogate primary key
// for cross-format
// --catalog-find lookups
// classId (uint8) — 1..11 vanilla class
// tabIndex (uint8) — 0=General/3 spec tabs
// iconIndex (uint8) — SpellIcon row id for
// the tab header glyph
// pad0 (uint8)
// tabNameLen + tabName — display label for the
// spellbook tab
// spellCount (uint32)
// spellIds (uint32 × count) — ordered display
// list (top-to-
// bottom in tab)
struct WoweeSpellPack {
struct Entry {
uint32_t packId = 0;
uint8_t classId = 0;
uint8_t tabIndex = 0;
uint8_t iconIndex = 0;
uint8_t pad0 = 0;
std::string tabName;
std::vector<uint32_t> spellIds;
};
std::string name;
std::vector<Entry> entries;
bool isValid() const { return !entries.empty(); }
const Entry* findById(uint32_t packId) const;
const Entry* findByClassTab(uint8_t classId,
uint8_t tabIndex) const;
// Returns all packs for a class (typically 4: General
// + 3 spec tabs). Used by the spellbook-screen UI to
// populate per-class tab order.
std::vector<const Entry*> findByClass(uint8_t classId) const;
};
class WoweeSpellPackLoader {
public:
static bool save(const WoweeSpellPack& cat,
const std::string& basePath);
static WoweeSpellPack load(const std::string& basePath);
static bool exists(const std::string& basePath);
// Preset emitters used by --gen-spk* variants.
//
// makeWarriorPack — 4 tabs (General + 3 trees:
// Arms/Fury/Protection). Each
// tab seeded with canonical
// vanilla spellIds.
// makeMagePack — 4 tabs (General + Arcane/
// Fire/Frost). Frost tab
// includes Frostbolt rank-1
// spellId 116 — the canonical
// "every mage starts here" spell.
// makeRoguePack — 4 tabs (General + Assassin/
// Combat/Subtlety). Combat tab
// seeded with poison-application
// and lethality picks.
static WoweeSpellPack makeWarriorPack(const std::string& catalogName);
static WoweeSpellPack makeMagePack(const std::string& catalogName);
static WoweeSpellPack makeRoguePack(const std::string& catalogName);
};
} // namespace pipeline
} // namespace wowee