Kelsidavis-WoWee/include/pipeline/wowee_quest_sorts.hpp
Kelsi 23ba7ed6a0 feat(pipeline): add WQSO (Wowee Quest Sort) catalog
67th open format — replaces QuestSort.dbc plus the quest-log
categorization fields in QuestInfo.dbc. Defines the
categories that quests fall into for the quest-log UI:
class quests (Warrior trial, etc), profession quests, daily
quests, holiday events, reputation grinds, dungeon /
heroic / raid quests, repeatables, PvP, tournament.

12 sort kinds (General / ClassQuest / Profession / Daily /
Holiday / Reputation / Dungeon / Raid / Heroic / Repeatable
/ PvP / Tournament). Each WQT (quest) entry can reference
a sortId here to be grouped under the right header in the
quest log. Sorts can be class-restricted (Warrior quests
only show for warriors), profession-restricted, or
faction-reputation-gated.

Cross-references with prior formats — targetClassMask uses
WCHC.classId bit positions (matches WGLY/WSET/WGTP
convention), targetProfessionId points at WTSK.profession
enum, targetFactionId points at WFAC.factionId.

CLI: --gen-qso (3 generic sorts — General catch-all, Daily
reset, Repeatable non-daily), --gen-qso-class (10 class-
specific sorts with proper bit masks for Warrior 0x02
through Druid 0x800), --gen-qso-profession (8 profession
sorts with WTSK profession enum cross-refs), --info-wqso,
--validate-wqso with --json variants. Validator catches
id+name+displayName required, kind 0..11, ClassQuest with
classMask=0 (not actually class-restricted), Profession
with profId=0 + non-Blacksmithing-name (likely typo since
0=Blacksmithing in WTSK), and Reputation with factionId=0
(no faction to grind).

Format graph: 66 → 67 binary formats. CLI flag count: 877
→ 882.
2026-05-09 21:23:38 -07:00

112 lines
4.1 KiB
C++

#pragma once
#include <cstdint>
#include <string>
#include <vector>
namespace wowee {
namespace pipeline {
// Wowee Open Quest Sort catalog (.wqso) — novel
// replacement for Blizzard's QuestSort.dbc plus the quest-
// log categorization fields in QuestInfo.dbc. Defines the
// categories that quests fall into for the quest-log UI:
// Class quests / Profession quests / Daily quests / PvP /
// Holiday / Reputation / Dungeon / Raid / Heroic /
// Repeatable / Tournament etc.
//
// Each WQT (quest) entry references a sortId here to be
// grouped under the right header in the quest log. Sorts
// can be class-restricted (Warrior class quests only show
// for warriors), profession-restricted, or faction-
// reputation-gated.
//
// Cross-references with previously-added formats:
// WQSO.entry.targetClassMask uses WCHC.classId bit
// positions (matches WGLY/WSET
// convention).
// WQSO.entry.targetProfessionId → WTSK.profession enum
// (Blacksmithing=0, etc).
// WQSO.entry.targetFactionId → WFAC.factionId
//
// Binary layout (little-endian):
// magic[4] = "WQSO"
// version (uint32) = current 1
// nameLen + name (catalog label)
// entryCount (uint32)
// entries (each):
// sortId (uint32)
// nameLen + name
// displayLen + displayName
// descLen + description
// iconLen + iconPath
// sortKind (uint8) / displayPriority (uint8) /
// targetProfessionId (uint8) / pad[1]
// targetClassMask (uint32)
// targetFactionId (uint32)
struct WoweeQuestSort {
enum SortKind : uint8_t {
General = 0, // catch-all / area-quest
ClassQuest = 1, // class-specific (Warrior trial)
Profession = 2, // profession recipe / quest
Daily = 3, // daily reset quest
Holiday = 4, // seasonal event quest
Reputation = 5, // faction grind quest
Dungeon = 6, // 5-man dungeon quest
Raid = 7, // 10/25-man raid quest
Heroic = 8, // dungeon heroic-mode quest
Repeatable = 9, // non-daily repeatable
PvP = 10, // battleground / arena quest
Tournament = 11, // Argent Tournament style
};
struct Entry {
uint32_t sortId = 0;
std::string name;
std::string displayName; // shown in quest log UI
std::string description;
std::string iconPath;
uint8_t sortKind = General;
uint8_t displayPriority = 0;
uint8_t targetProfessionId = 0; // WTSK profession enum
uint32_t targetClassMask = 0; // WCHC bit mask (0 = any)
uint32_t targetFactionId = 0; // WFAC cross-ref (0 = any)
};
std::string name;
std::vector<Entry> entries;
bool isValid() const { return !entries.empty(); }
const Entry* findById(uint32_t sortId) const;
static const char* sortKindName(uint8_t k);
};
class WoweeQuestSortLoader {
public:
static bool save(const WoweeQuestSort& cat,
const std::string& basePath);
static WoweeQuestSort load(const std::string& basePath);
static bool exists(const std::string& basePath);
// Preset emitters used by --gen-qso* variants.
//
// makeStarter — 3 generic sorts (General catch-all,
// Daily reset, Repeatable non-daily).
// makeClass — 10 class-specific sorts (Warrior /
// Paladin / Hunter / Rogue / Priest /
// DK / Shaman / Mage / Warlock / Druid)
// each with the matching WCHC class
// bit set.
// makeProfession — 8 profession sorts (Blacksmithing,
// Tailoring, Engineering, Alchemy,
// Enchanting, Leatherworking,
// Jewelcrafting, Inscription).
static WoweeQuestSort makeStarter(const std::string& catalogName);
static WoweeQuestSort makeClass(const std::string& catalogName);
static WoweeQuestSort makeProfession(const std::string& catalogName);
};
} // namespace pipeline
} // namespace wowee