Dialog fixing

This commit is contained in:
Vladislav Khorev committed 2026-05-22 22:32:05 +03:00
1 parent 8c200974c2
commit 84c8a7a27a
13 files changed
+169 -43

No files matched your search

+4
View File
@@ -104,6 +104,7 @@ Node DialogueDatabase::parseNode(const json& j) {
node.trueNext = j.value("trueNext", "");
node.falseNext = j.value("falseNext", "");
node.cutsceneId = j.value("cutsceneId", "");
node.luaCallback = j.value("luaCallback", "");
if (j.contains("conditions") && j["conditions"].is_array()) {
for (const auto& item : j["conditions"]) {
@@ -129,6 +130,7 @@ DialogueDefinition DialogueDatabase::parseDialogue(const json& j) {
result.id = j.value("id", "");
result.displayName = j.value("displayName", result.id);
result.startNode = j.value("start", "");
result.uninterruptible = j.value("uninterruptible", false);
if (j.contains("nodes") && j["nodes"].is_array()) {
for (const auto& item : j["nodes"]) {
@@ -151,6 +153,7 @@ CutsceneLine DialogueDatabase::parseCutsceneLine(const json& j) {
line.background = j.value("background", "");
line.backgroundWidth = j.value("backgroundWidth", 0);
line.backgroundHeight = j.value("backgroundHeight", 0);
line.luaCallback = j.value("luaCallback", "");
line.durationMs = j.value("durationMs", 0);
line.waitForConfirm = j.value("waitForConfirm", false);
return line;
@@ -205,6 +208,7 @@ StaticCutsceneDefinition DialogueDatabase::parseCutscene(const json& j) {
cutscene.fadeInMs = j.value("fadeInMs", 0);
cutscene.endFadeOutMs = j.value("endFadeOutMs", 0);
cutscene.endFadeInMs = j.value("endFadeInMs", 0);
cutscene.onFadeInCallback = j.value("onFadeInCallback", "");
if (j.contains("cameraTrack") && j["cameraTrack"].is_array()) {
for (const auto& item : j["cameraTrack"]) {
+47
View File
@@ -16,6 +16,11 @@ bool DialogueRuntime::startDialogue(const std::string& dialogueId) {
return false;
}
if (mode != Mode::Inactive && activeDialogue && activeDialogue->uninterruptible) {
std::cerr << "[dialogue] Blocked: '" << activeDialogue->id << "' is uninterruptible\n";
return false;
}
const DialogueDefinition* dialogue = database->findDialogue(dialogueId);
if (!dialogue) {
std::cerr << "[dialogue] Dialogue not found: " << dialogueId << "\n";
@@ -35,6 +40,7 @@ bool DialogueRuntime::startDialogue(const std::string& dialogueId) {
cutsceneTotalDurationMs = 0;
cutsceneContentDurationMs = 0;
currentCutsceneBackground.clear();
fadeInCallbackFired = false;
presentation = {};
presentation.dialogueId = dialogue->id;
@@ -53,6 +59,7 @@ bool DialogueRuntime::startStandaloneCutscene(const std::string& cutsceneId) {
}
activeDialogue = nullptr;
activeCutsceneId = cutsceneId;
fadeInCallbackFired = false;
presentation = {};
startCutscene(cutsceneId, "");
return true;
@@ -62,6 +69,18 @@ void DialogueRuntime::setOnCutsceneFinished(std::function<void(const std::string
onCutsceneFinished = std::move(cb);
}
void DialogueRuntime::setOnDialogueLineStarted(std::function<void(const std::string&)> cb) {
onDialogueLineStarted = std::move(cb);
}
void DialogueRuntime::setOnCutsceneLineStarted(std::function<void(const std::string&)> cb) {
onCutsceneLineStarted = std::move(cb);
}
void DialogueRuntime::setOnCutsceneFadeInComplete(std::function<void(const std::string&)> cb) {
onCutsceneFadeInComplete = std::move(cb);
}
void DialogueRuntime::stop() {
activeDialogue = nullptr;
activeCutscene = nullptr;
@@ -76,6 +95,7 @@ void DialogueRuntime::stop() {
cutsceneTotalDurationMs = 0;
cutsceneContentDurationMs = 0;
currentCutsceneBackground.clear();
fadeInCallbackFired = false;
mode = Mode::Inactive;
presentation = {};
}
@@ -128,6 +148,18 @@ void DialogueRuntime::update(int deltaMs) {
return;
}
if (!fadeInCallbackFired && onCutsceneFadeInComplete && activeCutscene) {
const int fadeInCompleteMs = activeCutscene->fadeOutMs + activeCutscene->fadeInMs;
if (cutsceneElapsedMs >= fadeInCompleteMs && !activeCutscene->onFadeInCallback.empty()) {
fadeInCallbackFired = true;
onCutsceneFadeInComplete(activeCutscene->onFadeInCallback);
}
}
if (!activeCutscene || mode != Mode::PlayingCutscene) {
return;
}
const bool subtitlesFinished =
activeCutscene->lines.empty() ||
currentCutsceneLine >= static_cast<int>(activeCutscene->lines.size());
@@ -395,6 +427,10 @@ void DialogueRuntime::presentLine(const Node& node) {
presentation.visibleText = node.text;
revealCharacters = static_cast<float>(node.text.size());
}
if (!node.luaCallback.empty() && onDialogueLineStarted) {
onDialogueLineStarted(node.luaCallback);
}
}
void DialogueRuntime::presentChoices(const Node& node) {
@@ -464,6 +500,7 @@ void DialogueRuntime::startCutscene(const std::string& cutsceneId, const std::st
mode = Mode::PlayingCutscene;
cutsceneElapsedMs = 0;
cutsceneTimerMs = 0;
fadeInCallbackFired = false;
currentCutsceneLine = activeCutscene->lines.empty() ? -1 : 0;
int imageTrackDurationMs = 0;
for (size_t i = 0; i < activeCutscene->images.size(); ++i) {
@@ -486,6 +523,11 @@ void DialogueRuntime::startCutscene(const std::string& cutsceneId, const std::st
cutsceneTotalDurationMs = cutsceneContentDurationMs + activeCutscene->endFadeOutMs + activeCutscene->endFadeInMs;
refreshCutscenePresentation();
if (!activeCutscene->lines.empty() && onCutsceneLineStarted) {
const std::string& cb = activeCutscene->lines[0].luaCallback;
if (!cb.empty()) onCutsceneLineStarted(cb);
}
std::cout << "[CUTSCENE] start id=" << cutsceneId
<< " lines=" << activeCutscene->lines.size()
<< " totalDuration=" << cutsceneTotalDurationMs
@@ -572,6 +614,11 @@ void DialogueRuntime::advanceCutsceneLine() {
return;
}
if (onCutsceneLineStarted) {
const std::string& cb = activeCutscene->lines[currentCutsceneLine].luaCallback;
if (!cb.empty()) onCutsceneLineStarted(cb);
}
refreshCutscenePresentation();
}
+7
View File
@@ -19,6 +19,9 @@ public:
bool startDialogue(const std::string& dialogueId);
bool startStandaloneCutscene(const std::string& cutsceneId);
void setOnCutsceneFinished(std::function<void(const std::string&)> cb);
void setOnDialogueLineStarted(std::function<void(const std::string&)> cb);
void setOnCutsceneLineStarted(std::function<void(const std::string&)> cb);
void setOnCutsceneFadeInComplete(std::function<void(const std::string&)> cb);
void stop();
void update(int deltaMs);
@@ -50,7 +53,11 @@ private:
};
std::function<void(const std::string&)> onCutsceneFinished;
std::function<void(const std::string&)> onDialogueLineStarted;
std::function<void(const std::string&)> onCutsceneLineStarted;
std::function<void(const std::string&)> onCutsceneFadeInComplete;
std::string activeCutsceneId;
bool fadeInCallbackFired = false;
const DialogueDatabase* database = nullptr;
const DialogueDefinition* activeDialogue = nullptr;
+12
View File
@@ -127,6 +127,18 @@ void DialogueSystem::setOnCutsceneFinished(std::function<void(const std::string&
runtime.setOnCutsceneFinished(std::move(cb));
}
void DialogueSystem::setOnDialogueLineStarted(std::function<void(const std::string&)> cb) {
runtime.setOnDialogueLineStarted(std::move(cb));
}
void DialogueSystem::setOnCutsceneLineStarted(std::function<void(const std::string&)> cb) {
runtime.setOnCutsceneLineStarted(std::move(cb));
}
void DialogueSystem::setOnCutsceneFadeInComplete(std::function<void(const std::string&)> cb) {
runtime.setOnCutsceneFadeInComplete(std::move(cb));
}
void DialogueSystem::stopDialogue() {
runtime.stop();
}
+3
View File
@@ -24,6 +24,9 @@ public:
bool startDialogue(const std::string& dialogueId);
bool startCutscene(const std::string& cutsceneId);
void setOnCutsceneFinished(std::function<void(const std::string&)> cb);
void setOnDialogueLineStarted(std::function<void(const std::string&)> cb);
void setOnCutsceneLineStarted(std::function<void(const std::string&)> cb);
void setOnCutsceneFadeInComplete(std::function<void(const std::string&)> cb);
void stopDialogue();
bool isActive() const { return runtime.isActive(); }
+4
View File
@@ -83,6 +83,7 @@ struct Node {
std::string text;
std::string portrait;
std::string next;
std::string luaCallback;
// For Condition nodes
std::string trueNext;
@@ -101,6 +102,7 @@ struct DialogueDefinition {
std::string id;
std::string displayName;
std::string startNode;
bool uninterruptible = false;
std::unordered_map<std::string, Node> nodes;
};
@@ -110,6 +112,7 @@ struct CutsceneLine {
std::string portrait;
std::string sfx;
std::string background;
std::string luaCallback;
int backgroundWidth = 0; // 0 = inherit from cutscene
int backgroundHeight = 0; // 0 = inherit from cutscene
int durationMs = 0;
@@ -151,6 +154,7 @@ struct StaticCutsceneDefinition {
int backgroundWidth = 1280;
int backgroundHeight = 720;
std::string music;
std::string onFadeInCallback;
bool skippable = true;
int durationMs = 0;
int fadeOutMs = 0;