shadow-over-bishkek001/src/dialogue/DialogueRuntime.h
2026-07-05 21:52:37 +03:00

96 lines
3.2 KiB
C++

#pragma once
#include "dialogue/DialogueDatabase.h"
#include "dialogue/TranslationDatabase.h"
#include "quest/QuestJournal.h"
#include "external/nlohmann/json.hpp"
#include "ISaveable.h"
#include <functional>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
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<void(const std::string& cutsceneId, const std::string& nextNodeId)> cb);
void setOnDialogueLineStarted(std::function<void(const std::string&)> cb);
void setOnChatBubbleReady(std::function<void(const std::string&, bool)> 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<std::string, int>* 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<void(const std::string&, const std::string&)> onCutsceneStartNeeded;
std::function<void(const std::string&)> onDialogueLineStarted;
std::function<void(const std::string&, bool)> onChatBubbleReady;
const DialogueDatabase* database = nullptr;
const TranslationDatabase* translations = nullptr;
Quest::QuestJournal* questJournal = nullptr;
const DialogueDefinition* activeDialogue = nullptr;
std::unordered_map<std::string, int>* flagStore = nullptr;
std::unordered_set<std::string> consumedChoices;
std::string currentNodeId;
std::vector<Choice> visibleChoices;
PresentationModel presentation;
Mode mode = Mode::Inactive;
int selectedChoice = -1;
float revealCharacters = 0.0f;
float revealSpeedCharsPerSecond = 52.0f;
bool evaluateConditions(const std::vector<Condition>& conditions) const;
void applyEffects(const std::vector<Effect>& 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