#pragma once #include "dialogue/DialogueDatabase.h" #include "dialogue/TranslationDatabase.h" #include "quest/QuestJournal.h" #include "external/nlohmann/json.hpp" #include "ISaveable.h" #include #include #include #include #include namespace ZL::Dialogue { class DialogueRuntime : public ZL::ISaveable { public: void setDatabase(const DialogueDatabase* value); void setTranslationDatabase(const TranslationDatabase* value); bool startDialogue(const std::string& dialogueId); void stop(); // Called by DialogueSystem after the inline cutscene finishes. void resumeFromNode(const std::string& nodeId); void setOnCutsceneStartNeeded(std::function cb); void setOnDialogueLineStarted(std::function cb); void setOnChatBubbleReady(std::function cb); void update(int deltaMs); bool isActive() const { return mode != Mode::Inactive; } bool isInChoice() const { return mode == Mode::WaitingForChoice; } void confirmAdvance(); void moveSelection(int delta); void selectChoice(int index); const PresentationModel& getPresentation() const { return presentation; } void setFlag(const std::string& name, int value); int getFlag(const std::string& name) const; void setGlobalFlagStore(std::unordered_map* store); void setQuestJournal(Quest::QuestJournal* journal); // Saves whether a dialogue is active, its id, and current node. // Cutscene state is not saved. void save(nlohmann::json& out) const override; // Restores saved dialogue state. Text reveal snaps to completion so the // typing animation doesn't replay. No callbacks are fired on restore. void load(const nlohmann::json& in) override; private: enum class Mode { Inactive, PresentingLine, WaitingForChoice, WaitingForCutscene // paused while an inline cutscene plays }; std::function onCutsceneStartNeeded; std::function onDialogueLineStarted; std::function onChatBubbleReady; const DialogueDatabase* database = nullptr; const TranslationDatabase* translations = nullptr; Quest::QuestJournal* questJournal = nullptr; const DialogueDefinition* activeDialogue = nullptr; std::unordered_map* flagStore = nullptr; std::unordered_set consumedChoices; std::string currentNodeId; std::vector visibleChoices; PresentationModel presentation; Mode mode = Mode::Inactive; int selectedChoice = -1; float revealCharacters = 0.0f; float revealSpeedCharsPerSecond = 52.0f; bool evaluateConditions(const std::vector& conditions) const; void applyEffects(const std::vector& effects); void applyQuestActions(const std::string& questUnlock, const std::string& questComplete, const std::string& questFail, const std::string& objectiveComplete, const std::string& objectiveVisible); bool enterNode(const std::string& nodeId); void presentLine(const Node& node); void presentChoices(const Node& node); std::string tr(const std::string& s) const; }; } // namespace ZL::Dialogue