mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-11 11:33:52 +00:00
feat(pipeline): add WACH (Wowee Achievement Catalog) format
Novel open replacement for Blizzard's Achievement.dbc +
AchievementCriteria.dbc + AchievementCategory.dbc + the
AzerothCore-style character_achievement /
character_achievement_progress SQL tables. The 21st open
format added to the editor.
Each achievement carries display metadata (name, description,
icon, points, faction restriction) plus a list of criteria
the player must satisfy. Criteria mirror the WQT objective
model (kind + targetId + quantity), so the runtime can
reuse the same progress-tracking machinery for both quests
and achievements.
Cross-references with previously-added formats — every
criterion kind has a real format target:
WACH.criteria.targetId (kind=KillCreature) -> WCRT.creatureId
WACH.criteria.targetId (kind=CompleteQuest) -> WQT.questId
WACH.criteria.targetId (kind=LootItem) -> WIT.itemId
WACH.criteria.targetId (kind=CastSpell) -> WSPL.spellId
WACH.criteria.targetId (kind=ReachSkillLevel) -> WSKL.skillId
WACH.criteria.targetId (kind=EarnReputation) -> WFAC.factionId
WACH.criteria.targetId (kind=CompleteAchievement) -> WACH.achievementId
(meta-achievements)
Format:
• magic "WACH", version 1, little-endian
• per achievement: id / categoryId / name / description /
iconPath / titleReward / points / minLevel / faction /
flags / criteria[]
• per criterion: criteriaId / kind / targetId / quantity /
description
Enums:
• CriteriaKind (9): KillCreature / CompleteQuest / LootItem /
ReachLevel / EarnReputation / CastSpell /
ReachSkillLevel / VisitArea /
CompleteAchievement
• Faction: Both / Alliance / Horde
• Flags: HiddenUntilEarned / ServerFirst / RealmFirst /
Tracking / Counter / Account
API: WoweeAchievementLoader::save / load / exists /
findById; presets makeStarter (3 simple kill/quest/level
demos), makeBandit (3 with WCRT/WGOT/WQT cross-refs),
makeMeta (3 base + 1 meta-achievement granting "the
Versatile" title, exercising CompleteAchievement criterion
kind that lets achievements depend on other achievements).
CLI added (5 flags, 542 documented total now):
--gen-achievements / --gen-achievements-bandit / --gen-achievements-meta
--info-wach / --validate-wach
Validator catches: achievementId=0 + duplicates, empty name,
faction out of range, no criteria (achievement can never
be earned), criterion quantity=0, unknown criterion kind,
targetId=0 on criterion kinds that need a real resource
reference (everything except ReachLevel which uses the
quantity field for the level number).
The bandit preset's cross-references close the gameplay
graph end-to-end: kill 50 creatureId=1000 (matches WCRT/
WSPN/WLOT bandit), loot objectId=2000 (matches WGOT bandit
strongbox), complete questId=1 (matches WQT Bandit Trouble).
The meta preset closes a separate loop: 3 sub-achievements
covering Mining (skillId=186), Lockpicking (skillId=633),
and Frostbolt cast count (spellId=116) — each pointing at
a real WSKL/WSPL entry that already exists in the demo
content stack.
This commit is contained in:
parent
f4f9804000
commit
e5eaf13866
8 changed files with 763 additions and 0 deletions
140
include/pipeline/wowee_achievements.hpp
Normal file
140
include/pipeline/wowee_achievements.hpp
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace wowee {
|
||||
namespace pipeline {
|
||||
|
||||
// Wowee Open Achievement Catalog (.wach) — novel replacement
|
||||
// for Blizzard's Achievement.dbc + AchievementCriteria.dbc +
|
||||
// AchievementCategory.dbc + the AzerothCore-style
|
||||
// character_achievement / character_achievement_progress
|
||||
// SQL tables. The 21st open format added to the editor.
|
||||
//
|
||||
// Each achievement carries display metadata (name, description,
|
||||
// icon, points, faction restriction) plus a list of criteria
|
||||
// the player must satisfy. Criteria mirror the WQT objective
|
||||
// model (kind + targetId + quantity), which means the runtime
|
||||
// can reuse the same progress-tracking machinery for both.
|
||||
//
|
||||
// Cross-references with previously-added formats:
|
||||
// WACH.criteria.targetId (kind=KillCreature) → WCRT.creatureId
|
||||
// WACH.criteria.targetId (kind=CompleteQuest) → WQT.questId
|
||||
// WACH.criteria.targetId (kind=LootItem) → WIT.itemId
|
||||
// WACH.criteria.targetId (kind=CastSpell) → WSPL.spellId
|
||||
// WACH.criteria.targetId (kind=ReachSkillLevel) → WSKL.skillId
|
||||
// WACH.criteria.targetId (kind=EarnReputation) → WFAC.factionId
|
||||
// WACH.entry.categoryId → WACH.entry.achievementId (for header
|
||||
// rows; achievements can be parented
|
||||
// to other achievements as headers)
|
||||
//
|
||||
// Binary layout (little-endian):
|
||||
// magic[4] = "WACH"
|
||||
// version (uint32) = current 1
|
||||
// nameLen + name (catalog label)
|
||||
// entryCount (uint32)
|
||||
// entries (each):
|
||||
// achievementId (uint32)
|
||||
// categoryId (uint32)
|
||||
// nameLen + name
|
||||
// descLen + description
|
||||
// iconLen + iconPath
|
||||
// titleLen + titleReward
|
||||
// points (uint32)
|
||||
// minLevel (uint16) / faction (uint8) / criteriaCount (uint8)
|
||||
// flags (uint32)
|
||||
// criteria (criteriaCount × {
|
||||
// criteriaId (uint32)
|
||||
// kind (uint8) + pad[3]
|
||||
// targetId (uint32)
|
||||
// quantity (uint32)
|
||||
// descLen + description
|
||||
// })
|
||||
struct WoweeAchievement {
|
||||
enum CriteriaKind : uint8_t {
|
||||
KillCreature = 0,
|
||||
CompleteQuest = 1,
|
||||
LootItem = 2,
|
||||
ReachLevel = 3,
|
||||
EarnReputation = 4,
|
||||
CastSpell = 5,
|
||||
ReachSkillLevel = 6,
|
||||
VisitArea = 7,
|
||||
CompleteAchievement = 8, // meta-achievements
|
||||
};
|
||||
|
||||
enum Faction : uint8_t {
|
||||
FactionBoth = 0,
|
||||
FactionAlliance = 1,
|
||||
FactionHorde = 2,
|
||||
};
|
||||
|
||||
enum Flags : uint32_t {
|
||||
HiddenUntilEarned = 0x01, // not shown in panel until completed
|
||||
ServerFirst = 0x02, // first-on-server rewards a global tag
|
||||
RealmFirst = 0x04,
|
||||
Tracking = 0x08, // shows progress UI in the panel
|
||||
Counter = 0x10, // counts up forever (Pet Battles wins)
|
||||
Account = 0x20, // account-wide, not per-character
|
||||
};
|
||||
|
||||
struct Criterion {
|
||||
uint32_t criteriaId = 0;
|
||||
uint8_t kind = KillCreature;
|
||||
uint32_t targetId = 0;
|
||||
uint32_t quantity = 1;
|
||||
std::string description;
|
||||
};
|
||||
|
||||
struct Entry {
|
||||
uint32_t achievementId = 0;
|
||||
uint32_t categoryId = 0; // 0 = top-level
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string iconPath;
|
||||
std::string titleReward; // empty = no title
|
||||
uint32_t points = 10;
|
||||
uint16_t minLevel = 1;
|
||||
uint8_t faction = FactionBoth;
|
||||
uint32_t flags = 0;
|
||||
std::vector<Criterion> criteria;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::vector<Entry> entries;
|
||||
|
||||
bool isValid() const { return !entries.empty(); }
|
||||
|
||||
// Lookup by achievementId — nullptr if not present.
|
||||
const Entry* findById(uint32_t achievementId) const;
|
||||
|
||||
static const char* criteriaKindName(uint8_t k);
|
||||
static const char* factionName(uint8_t f);
|
||||
};
|
||||
|
||||
class WoweeAchievementLoader {
|
||||
public:
|
||||
static bool save(const WoweeAchievement& cat,
|
||||
const std::string& basePath);
|
||||
static WoweeAchievement load(const std::string& basePath);
|
||||
static bool exists(const std::string& basePath);
|
||||
|
||||
// Preset emitters used by --gen-achievements* variants.
|
||||
//
|
||||
// makeStarter — 3 demo achievements covering kill / quest
|
||||
// completion / level reached criteria.
|
||||
// makeBandit — bandit-themed: "Slay 50 Defias Bandits"
|
||||
// + "Loot the Bandit Strongbox" + "Complete
|
||||
// Bandit Trouble" — all referencing the
|
||||
// WCRT/WGOT/WQT/WIT cross-referenced demo IDs.
|
||||
// makeMeta — 3 base achievements + 1 meta-achievement
|
||||
// that requires completing the others.
|
||||
static WoweeAchievement makeStarter(const std::string& catalogName);
|
||||
static WoweeAchievement makeBandit(const std::string& catalogName);
|
||||
static WoweeAchievement makeMeta(const std::string& catalogName);
|
||||
};
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue