Kelsidavis-WoWee/include/pipeline/wowee_action_bars.hpp
Kelsi 48dbf72f11 feat(editor): add WACT (Action Bar Layout) open catalog format
Open replacement for the hardcoded per-class default action bar
bindings. Defines which abilities auto-populate which action
button slots when a new character is created or a class is
reset. A Warrior's button 1 binds Heroic Strike, button 2
Charge, button 3 Rend, etc. — new characters of that class get
those buttons pre-populated so the action bar isn't empty on
first login.

Distinct from WKBD (Keybindings) which maps physical keys to
action button slots — WACT maps action button slots to
abilities. The two together complete the default-control
configuration: Key 1 -> Action Slot 1 (WKBD) -> Heroic Strike
(WACT).

Seven barMode values cover the major action bar contexts:
  - Main (slots 0-11, standard 12-button bar)
  - Pet (hunter/warlock pet action bar)
  - Vehicle (mounted/vehicle action bar)
  - Stance1/2/3 (warrior battle/defensive/berserker; druid
    bear/cat/tree)
  - Custom (server-custom bar overlay)

Cross-references back to WCHC (classMask layout), WSPL (spellId
for the bound ability), and WIT (itemId for item-macro bindings
like Hearthstone in slot 12). findByClass(classBit, barMode)
returns the bindings sorted by buttonSlot — used directly by
character creation to populate action bars.

Three preset emitters: --gen-act (10 Warrior starter bindings on
Main bar with canonical 3.3.5a abilities), --gen-act-mage (10
Mage starter bindings including Counterspell + Polymorph),
--gen-act-pet (10 Hunter pet-bar bindings using barMode=Pet for
Attack/Stance/Bite/Claw/Dismiss).

Validation enforces id+name+classMask presence, barMode 0..6,
no duplicate ids; warns on:
  - buttonSlot > 143 (max is 12 bars × 12 slots = 144)
  - both spellId and itemId set (engine prefers spellId, item
    is silently ignored)
  - both spellId=0 AND itemId=0 (button will render empty)
  - (classMask + barMode + buttonSlot) collisions for
    overlapping classes — multiple bindings fighting for the
    same physical slot

Wired through the cross-format table; WACT appears in all 18
cross-format utilities. Format count 94 -> 95; CLI flag count
1083 -> 1088.
2026-05-10 00:11:53 -07:00

117 lines
4.3 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 Action Bar Layout catalog (.wact) — novel
// replacement for the hardcoded per-class default action
// bar bindings in the WoW client. Defines which abilities
// auto-populate which action button slots when a new
// character is created or a class is reset.
//
// Each entry binds one (classMask, buttonSlot) pair to a
// spell or item. A Warrior's button 1 might bind Heroic
// Strike, button 2 Charge, button 3 Battle Shout, etc.
// New characters of that class get those buttons pre-
// populated so the action bar isn't empty on first login.
//
// Distinct from WKBD (Keybindings) which maps physical
// keys to action button slots — WACT maps action button
// slots to abilities. The two together complete the
// default-control configuration: Key 1 -> Action Slot 1
// (WKBD) -> Heroic Strike (WACT).
//
// Cross-references with previously-added formats:
// WCHC: classMask uses the same bit layout as WCHC
// class IDs (Warrior=0x01, Paladin=0x02, ...).
// WSPL: spellId references the WSPL spell entry that
// the button casts when triggered.
// WIT: itemId references a WIT item entry for item
// macro bindings (Hearthstone in slot 12, etc.).
//
// Binary layout (little-endian):
// magic[4] = "WACT"
// version (uint32) = current 1
// nameLen + name (catalog label)
// entryCount (uint32)
// entries (each):
// bindingId (uint32)
// nameLen + name
// descLen + description
// classMask (uint32)
// spellId (uint32)
// itemId (uint32)
// buttonSlot (uint8) / barMode (uint8) / pad[2]
// iconColorRGBA (uint32)
struct WoweeActionBar {
enum BarMode : uint8_t {
Main = 0, // standard 12-button main bar (slots 0-11)
Pet = 1, // hunter/warlock pet action bar
Vehicle = 2, // mounted/vehicle action bar
Stance1 = 3, // warrior battle / druid bear stance
Stance2 = 4, // warrior defensive / druid cat
Stance3 = 5, // warrior berserker / druid tree
Custom = 6, // server-custom bar overlay
};
struct Entry {
uint32_t bindingId = 0;
std::string name;
std::string description;
uint32_t classMask = 0;
uint32_t spellId = 0;
uint32_t itemId = 0; // 0 if spell-only
uint8_t buttonSlot = 0; // 0..143 (12 bars × 12 slots)
uint8_t barMode = Main;
uint8_t pad0 = 0;
uint8_t pad1 = 0;
uint32_t iconColorRGBA = 0xFFFFFFFFu;
};
std::string name;
std::vector<Entry> entries;
bool isValid() const { return !entries.empty(); }
const Entry* findById(uint32_t bindingId) const;
// Return all entries for a given class on a specific
// bar mode, in buttonSlot order. Used by character
// creation to populate the action bar with defaults.
std::vector<const Entry*> findByClass(uint32_t classBit,
uint8_t barMode) const;
static const char* barModeName(uint8_t m);
};
class WoweeActionBarLoader {
public:
static bool save(const WoweeActionBar& cat,
const std::string& basePath);
static WoweeActionBar load(const std::string& basePath);
static bool exists(const std::string& basePath);
// Preset emitters used by --gen-act* variants.
//
// makeWarrior — 10 Warrior starter bindings on the
// Main bar (Heroic Strike, Charge,
// Rend, Thunder Clap, Battle Shout,
// Sunder Armor, Mocking Blow, etc).
// makeMage — 10 Mage starter bindings on the Main
// bar (Fireball, Frostbolt, Frost
// Nova, Polymorph, Mage Armor, etc).
// makeHunterPet — 10 Hunter Pet-bar bindings using
// barMode=Pet (Attack, Follow, Stay,
// Aggressive/Defensive/Passive
// stances, Bite, Claw, etc).
static WoweeActionBar makeWarrior(const std::string& catalogName);
static WoweeActionBar makeMage(const std::string& catalogName);
static WoweeActionBar makeHunterPet(const std::string& catalogName);
};
} // namespace pipeline
} // namespace wowee