mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-10 02:53:51 +00:00
Novel open replacement for AzerothCore-style gossip_menu +
gossip_menu_option + npc_text SQL tables PLUS the Blizzard
NpcText.dbc family. The 23rd open format added to the
editor.
An NPC's dialogue tree: a menu of options the player can
pick from when right-clicking the NPC. Each option may
bridge to another menu, trigger a vendor / trainer
interaction, offer a quest, etc. The simplified per-option
model (kind + actionTarget + flags + moneyCost) covers the
common cases without needing separate npc_text condition
tables.
Closes a major cross-format gap: WCRT.entry.gossipId has
existed since batch 116 (when WCRT was added) but pointed
to a format that didn't exist yet. The innkeeper preset's
menuId=4001 deliberately matches WCRT's Bartleby NPC so
the demo content stack can wire WCRT.gossipId = 4001 once
that field is plumbed through the runtime.
Cross-references:
WCRT.entry.gossipId -> WGSP.entry.menuId
WGSP.option.actionTarget (Submenu) -> WGSP.entry.menuId
WGSP.option.actionTarget (Vendor / Trainer)
-> WTRN.entry.npcId
WGSP.option.actionTarget (Quest) -> WQT.entry.questId
Format:
• magic "WGSP", version 1, little-endian
• per menu: menuId / titleText + options[]
• per option: optionId / text / kind / actionTarget /
requiredFlags / moneyCostCopper
Enums:
• OptionKind (13): Close / Submenu / Vendor / Trainer /
Quest / Tabard / Banker / Innkeeper /
FlightMaster / TextOnly / Script /
Battlemaster / Auctioneer
• OptionFlags: AllianceOnly / HordeOnly / Coinpouch /
QuestGated / Closes
API: WoweeGossipLoader::save / load / exists / findById;
presets makeStarter (1 menu with vendor + trainer + close),
makeInnkeeper (2-menu tree: main menu 4001 with hearth /
vendor / flight / submenu options + lore submenu 4002 that
links back), makeQuestGiver (1 menu with 2 quest options
referencing WQT 1 and 100, plus a paid respec script
exercising the Coinpouch flag with a 10g cost).
CLI added (5 flags, 558 documented total now):
--gen-gossip / --gen-gossip-innkeeper / --gen-gossip-questgiver
--info-wgsp / --validate-wgsp
Validator catches: menuId=0 + duplicates, empty title /
options, unknown option kind, empty option text, Submenu
options pointing at non-existent menuIds (intra-format
cross-reference resolution), Coinpouch flag without
moneyCost (misleading UI), AllianceOnly+HordeOnly conflict.
123 lines
4.3 KiB
C++
123 lines
4.3 KiB
C++
#pragma once
|
||
|
||
#include <cstdint>
|
||
#include <string>
|
||
#include <vector>
|
||
|
||
namespace wowee {
|
||
namespace pipeline {
|
||
|
||
// Wowee Open Gossip Menu catalog (.wgsp) — novel replacement
|
||
// for AzerothCore-style gossip_menu + gossip_menu_option +
|
||
// npc_text SQL tables PLUS the Blizzard NpcText.dbc family.
|
||
// The 23rd open format added to the editor.
|
||
//
|
||
// An NPC's dialogue tree: a menu of options the player can
|
||
// pick from when right-clicking the NPC. Each option may
|
||
// bridge to another menu, trigger a vendor / trainer
|
||
// interaction, offer a quest, etc.
|
||
//
|
||
// This format closes the WCRT.gossipId cross-reference gap
|
||
// from batch 116 — until now WCRT had a gossipId field that
|
||
// pointed to a format that didn't exist yet.
|
||
//
|
||
// Cross-references with previously-added formats:
|
||
// WCRT.entry.gossipId → WGSP.entry.menuId
|
||
// WGSP.option.actionTarget (kind=Submenu) → WGSP.entry.menuId
|
||
// (intra-format chain)
|
||
// WGSP.option.actionTarget (kind=Vendor / Trainer)
|
||
// → WTRN.entry.npcId
|
||
// WGSP.option.actionTarget (kind=Quest) → WQT.entry.questId
|
||
//
|
||
// Binary layout (little-endian):
|
||
// magic[4] = "WGSP"
|
||
// version (uint32) = current 1
|
||
// nameLen + name (catalog label)
|
||
// entryCount (uint32)
|
||
// entries (each):
|
||
// menuId (uint32)
|
||
// titleLen + titleText
|
||
// optionCount (uint8) + pad[3]
|
||
// options (optionCount × {
|
||
// optionId (uint32)
|
||
// textLen + text
|
||
// kind (uint8) + pad[3]
|
||
// actionTarget (uint32)
|
||
// requiredFlags (uint32)
|
||
// moneyCostCopper (uint32)
|
||
// })
|
||
struct WoweeGossip {
|
||
enum OptionKind : uint8_t {
|
||
Close = 0, // closes the menu, no action
|
||
Submenu = 1, // jumps to another menuId
|
||
Vendor = 2, // opens vendor inventory window
|
||
Trainer = 3, // opens trainer spell window
|
||
Quest = 4, // opens quest dialog
|
||
Tabard = 5, // opens tabard customization
|
||
Banker = 6, // opens bank
|
||
Innkeeper = 7, // sets hearth + opens vendor
|
||
FlightMaster = 8, // opens taxi node
|
||
TextOnly = 9, // dialogue only, no action
|
||
Script = 10, // triggers a server-side script
|
||
Battlemaster = 11,
|
||
Auctioneer = 12,
|
||
};
|
||
|
||
enum OptionFlags : uint32_t {
|
||
AllianceOnly = 0x01,
|
||
HordeOnly = 0x02,
|
||
Coinpouch = 0x04, // shows the coin icon when paid
|
||
QuestGated = 0x08, // visible only with matching quest
|
||
Closes = 0x10, // closes the menu after the action
|
||
};
|
||
|
||
struct Option {
|
||
uint32_t optionId = 0;
|
||
std::string text;
|
||
uint8_t kind = TextOnly;
|
||
uint32_t actionTarget = 0; // submenu / NPC / quest id
|
||
uint32_t requiredFlags = 0;
|
||
uint32_t moneyCostCopper = 0;
|
||
};
|
||
|
||
struct Entry {
|
||
uint32_t menuId = 0;
|
||
std::string titleText;
|
||
std::vector<Option> options;
|
||
};
|
||
|
||
std::string name;
|
||
std::vector<Entry> entries;
|
||
|
||
bool isValid() const { return !entries.empty(); }
|
||
|
||
// Lookup by menuId — nullptr if not present.
|
||
const Entry* findById(uint32_t menuId) const;
|
||
|
||
static const char* optionKindName(uint8_t k);
|
||
};
|
||
|
||
class WoweeGossipLoader {
|
||
public:
|
||
static bool save(const WoweeGossip& cat,
|
||
const std::string& basePath);
|
||
static WoweeGossip load(const std::string& basePath);
|
||
static bool exists(const std::string& basePath);
|
||
|
||
// Preset emitters used by --gen-gossip* variants.
|
||
//
|
||
// makeStarter — single menu with greeting + 3 options
|
||
// (vendor / trainer / close).
|
||
// makeInnkeeper — menu 4001 (matches WCRT.gossipId on
|
||
// Bartleby): set hearth + browse goods
|
||
// + bind to flight + close.
|
||
// makeQuestGiver — branching menu: greeting + 2 quests +
|
||
// submenu "tell me about the area"
|
||
// leading to lore text + close.
|
||
static WoweeGossip makeStarter(const std::string& catalogName);
|
||
static WoweeGossip makeInnkeeper(const std::string& catalogName);
|
||
static WoweeGossip makeQuestGiver(const std::string& catalogName);
|
||
};
|
||
|
||
} // namespace pipeline
|
||
} // namespace wowee
|