Files
moonwell-core/modules/mod-individual-progression/src/playerGuide/PlayerGuideMgr.h
T

160 lines
5.3 KiB
C++

/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>,
* released under GNU AGPL v3 license:
* https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
*/
#ifndef MOONWELL_PLAYER_GUIDE_MGR_H
#define MOONWELL_PLAYER_GUIDE_MGR_H
#include "Define.h"
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>
class Player;
namespace MoonWell::PlayerGuide
{
enum : uint32 { PAYLOAD_VERSION = 1 };
struct Objective
{
uint32 id = 0;
std::string type; // level | quest | quest_chain | dungeon |
// raid | boss | achievement |
// reputation | profession | item |
// currency | custom
std::string title;
std::string description;
bool completed = false;
uint32 progress = 0;
uint32 required = 0;
uint32 targetId = 0;
uint32 order = 0;
// Optional type-specific helpers. Zero means "not set" and
// serialiser omits it.
uint32 questId = 0;
uint32 questChainId = 0;
// ej_instanceID: key into client's JOURNALINSTANCE table.
// Consumed by EncounterJournal_DisplayInstance / EJ_SelectInstance.
uint32 ejInstanceId = 0;
// WoW map id (for telemetry / teleport / fallback). NOT used by
// the client to open EJ.
uint32 mapId = 0;
uint32 encounterId = 0;
uint32 achievementId = 0;
uint32 factionId = 0;
uint32 professionId = 0;
uint32 itemId = 0;
uint32 currencyId = 0;
};
struct Recommendation
{
uint32 id = 0;
std::string type;
std::string title;
std::string description;
uint32 ejInstanceId = 0; // JOURNALINSTANCE key
uint32 mapId = 0; // WoW map id (auxiliary)
uint32 encounterId = 0;
uint32 questId = 0;
uint32 itemId = 0;
uint32 priority = 0;
};
struct Reward
{
std::string type;
uint32 itemId = 0;
uint32 count = 1;
uint32 currencyId = 0;
uint32 amount = 0;
};
struct Payload
{
uint32 version = PAYLOAD_VERSION;
uint64 characterGuid = 0;
uint32 stageId = 0;
std::string stageName;
std::string stageDescription;
uint32 progress = 0; // 0..100
std::vector<Objective> objectives;
std::vector<Recommendation> recommendations;
std::vector<Reward> rewards;
};
class Mgr
{
public:
static Mgr* instance();
// Reads configuration. Safe to call multiple times.
void LoadConfig();
// Builds the per-character guide payload from IPP state.
// The function is read-only with respect to the player.
Payload BuildFor(Player* player) const;
// Serialises a payload to a single JSON string.
// Validates uniqueness of objective ids and clamps progress.
std::string SerializeJson(Payload const& payload) const;
std::string SerializeJson(Objective const& objective) const;
bool IsEnabled() const { return _enabled; }
bool LogPayloads() const { return _logPayloads; }
uint32 ChunkSize() const { return _chunkSize; }
// Reloads (map_id -> ej_instance.id/name) cache from
// custom_ej_instance. Called from LoadConfig() and from the
// OnLoadCustomDatabaseTable world hook.
void ReloadEncounterJournalCache();
private:
Mgr() = default;
// Stage helpers based on ProgressionState.
std::string StageName(uint32 stage) const;
std::string StageDescription(uint32 stage) const;
// Filling helpers.
void AppendLevelObjective(Payload& out, Player* player,
uint32 requiredLevel, uint32 order) const;
void AppendQuestObjective(Payload& out, Player* player,
uint32 questId, std::string const& title,
uint32 order) const;
void AppendDungeonObjective(Payload& out, uint32 mapId,
std::string const& title,
uint32 order) const;
void AppendRaidObjective(Payload& out, uint32 mapId,
std::string const& title,
uint32 order) const;
void AppendRecommendations(Payload& out, Player* player) const;
struct EjInstanceRef
{
uint32 ejId = 0; // custom_ej_instance.id
std::string name; // custom_ej_instance.name
};
// mapId -> EJ instance ref. Filled at config load.
std::unordered_map<uint32, EjInstanceRef> _ejByMapId;
bool _enabled = true;
bool _logPayloads = false;
uint32 _chunkSize = 230; // per-frame body capacity (addon channel)
};
}
#define sPlayerGuideMgr ::MoonWell::PlayerGuide::Mgr::instance()
#endif // MOONWELL_PLAYER_GUIDE_MGR_H