#pragma once #include "quest/QuestTypes.h" #include "ISaveable.h" #include "external/nlohmann/json.hpp" #include #include #include namespace FRG::Quest { enum class QuestEventType { Unlocked, Completed, Failed, ObjectiveCompleted }; struct QuestEvent { QuestEventType type; std::string questId; std::string objectiveId; }; struct QuestMutationResult { bool success = false; std::vector events; }; class QuestJournal : public FRG::ISaveable { public: bool loadFromFile(const std::string& path, const std::string& zipFile = ""); // Reloads quest definitions (e.g. after a language switch) while // preserving current progress: snapshots status/objective state, reloads // definitions from path, then re-applies the snapshot. bool reloadDefinitionsPreservingState(const std::string& path, const std::string& zipFile = ""); void save(nlohmann::json& out) const override; void load(const nlohmann::json& in) override; QuestMutationResult unlockQuest(const std::string& questId); QuestMutationResult completeQuest(const std::string& questId); QuestMutationResult failQuest(const std::string& questId); QuestMutationResult setObjectiveCompleted(const std::string& questId, const std::string& objectiveId, bool completed = true); QuestMutationResult setObjectiveVisible(const std::string& questId, const std::string& objectiveId, bool visible = true); QuestMutationResult setActiveObjective(const std::string& questId, int objectiveIndex); QuestState* findQuest(const std::string& questId); const QuestState* findQuest(const std::string& questId) const; std::vector getVisibleQuests(); std::vector getVisibleQuests() const; private: std::unordered_map quests; std::vector questOrder; bool setStatus(const std::string& questId, QuestStatus status); }; } // namespace FRG::Quest