Working on quest system
This commit is contained in:
1 parent
aaae368a07
commit
e7ae148ead
22 files changed
+357
-103
No files matched your search
@@ -106,6 +106,11 @@ Node DialogueDatabase::parseNode(const json& j) {
|
||||
node.cutsceneId = j.value("cutsceneId", "");
|
||||
node.luaCallback = j.value("luaCallback", "");
|
||||
node.bubbleSlot = j.value("bubbleSlot", "");
|
||||
node.questUnlock = j.value("questUnlock", "");
|
||||
node.questComplete = j.value("questComplete", "");
|
||||
node.questFail = j.value("questFail", "");
|
||||
node.objectiveComplete = j.value("objectiveComplete", "");
|
||||
node.objectiveVisible = j.value("objectiveVisible", "");
|
||||
|
||||
if (j.contains("conditions") && j["conditions"].is_array()) {
|
||||
for (const auto& item : j["conditions"]) {
|
||||
@@ -157,6 +162,11 @@ CutsceneLine DialogueDatabase::parseCutsceneLine(const json& j) {
|
||||
line.luaCallback = j.value("luaCallback", "");
|
||||
line.durationMs = j.value("durationMs", 0);
|
||||
line.waitForConfirm = j.value("waitForConfirm", false);
|
||||
line.questUnlock = j.value("questUnlock", "");
|
||||
line.questComplete = j.value("questComplete", "");
|
||||
line.questFail = j.value("questFail", "");
|
||||
line.objectiveComplete = j.value("objectiveComplete", "");
|
||||
line.objectiveVisible = j.value("objectiveVisible", "");
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,13 @@
|
||||
#include <iostream>
|
||||
|
||||
namespace ZL::Dialogue {
|
||||
|
||||
|
||||
static std::pair<std::string, std::string> splitDot(const std::string& s) {
|
||||
const auto dot = s.find('.');
|
||||
if (dot == std::string::npos) return {s, ""};
|
||||
return {s.substr(0, dot), s.substr(dot + 1)};
|
||||
}
|
||||
|
||||
void DialogueRuntime::setDatabase(const DialogueDatabase* value) {
|
||||
database = value;
|
||||
}
|
||||
@@ -309,6 +315,29 @@ int DialogueRuntime::getFlag(const std::string& name) const {
|
||||
return (it != flags.end()) ? it->second : 0;
|
||||
}
|
||||
|
||||
void DialogueRuntime::setQuestJournal(Quest::QuestJournal* journal) {
|
||||
questJournal = journal;
|
||||
}
|
||||
|
||||
void DialogueRuntime::applyQuestActions(
|
||||
const std::string& questUnlock, const std::string& questComplete,
|
||||
const std::string& questFail, const std::string& objectiveComplete,
|
||||
const std::string& objectiveVisible)
|
||||
{
|
||||
if (!questJournal) return;
|
||||
if (!questUnlock.empty()) questJournal->unlockQuest(questUnlock);
|
||||
if (!questComplete.empty()) questJournal->completeQuest(questComplete);
|
||||
if (!questFail.empty()) questJournal->failQuest(questFail);
|
||||
if (!objectiveComplete.empty()) {
|
||||
auto [qId, oId] = splitDot(objectiveComplete);
|
||||
questJournal->setObjectiveCompleted(qId, oId);
|
||||
}
|
||||
if (!objectiveVisible.empty()) {
|
||||
auto [qId, oId] = splitDot(objectiveVisible);
|
||||
questJournal->setObjectiveVisible(qId, oId);
|
||||
}
|
||||
}
|
||||
|
||||
bool DialogueRuntime::evaluateConditions(const std::vector<Condition>& conditions) const {
|
||||
for (const Condition& condition : conditions) {
|
||||
const int currentValue = getFlag(condition.flag);
|
||||
@@ -432,6 +461,8 @@ void DialogueRuntime::presentLine(const Node& node) {
|
||||
revealCharacters = static_cast<float>(node.text.size());
|
||||
}
|
||||
|
||||
applyQuestActions(node.questUnlock, node.questComplete, node.questFail,
|
||||
node.objectiveComplete, node.objectiveVisible);
|
||||
if (!node.luaCallback.empty() && onDialogueLineStarted) {
|
||||
onDialogueLineStarted(node.luaCallback);
|
||||
}
|
||||
@@ -530,9 +561,12 @@ 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);
|
||||
if (!activeCutscene->lines.empty()) {
|
||||
const CutsceneLine& firstLine = activeCutscene->lines[0];
|
||||
applyQuestActions(firstLine.questUnlock, firstLine.questComplete,
|
||||
firstLine.questFail, firstLine.objectiveComplete, firstLine.objectiveVisible);
|
||||
if (onCutsceneLineStarted && !firstLine.luaCallback.empty())
|
||||
onCutsceneLineStarted(firstLine.luaCallback);
|
||||
}
|
||||
|
||||
std::cout << "[CUTSCENE] start id=" << cutsceneId
|
||||
@@ -621,10 +655,11 @@ void DialogueRuntime::advanceCutsceneLine() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (onCutsceneLineStarted) {
|
||||
const std::string& cb = activeCutscene->lines[currentCutsceneLine].luaCallback;
|
||||
if (!cb.empty()) onCutsceneLineStarted(cb);
|
||||
}
|
||||
const CutsceneLine& newLine = activeCutscene->lines[currentCutsceneLine];
|
||||
applyQuestActions(newLine.questUnlock, newLine.questComplete,
|
||||
newLine.questFail, newLine.objectiveComplete, newLine.objectiveVisible);
|
||||
if (onCutsceneLineStarted && !newLine.luaCallback.empty())
|
||||
onCutsceneLineStarted(newLine.luaCallback);
|
||||
|
||||
refreshCutscenePresentation();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "dialogue/DialogueDatabase.h"
|
||||
#include "quest/QuestJournal.h"
|
||||
#include "external/nlohmann/json.hpp"
|
||||
#include <functional>
|
||||
#include <string>
|
||||
@@ -42,6 +43,8 @@ public:
|
||||
void setFlag(const std::string& name, int value);
|
||||
int getFlag(const std::string& name) const;
|
||||
|
||||
void setQuestJournal(Quest::QuestJournal* journal);
|
||||
|
||||
json buildSaveState() const;
|
||||
bool restoreSaveState(const json& state);
|
||||
|
||||
@@ -62,6 +65,7 @@ private:
|
||||
bool fadeInCallbackFired = false;
|
||||
|
||||
const DialogueDatabase* database = nullptr;
|
||||
Quest::QuestJournal* questJournal = nullptr;
|
||||
const DialogueDefinition* activeDialogue = nullptr;
|
||||
const StaticCutsceneDefinition* activeCutscene = nullptr;
|
||||
|
||||
@@ -89,6 +93,9 @@ private:
|
||||
|
||||
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);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "dialogue/DialogueOverlay.h"
|
||||
#include "dialogue/DialogueRuntime.h"
|
||||
#include "quest/QuestJournal.h"
|
||||
#include <SDL.h>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
@@ -37,6 +38,8 @@ public:
|
||||
void setFlag(const std::string& name, int value) { runtime.setFlag(name, value); }
|
||||
int getFlag(const std::string& name) const { return runtime.getFlag(name); }
|
||||
|
||||
void setQuestJournal(Quest::QuestJournal* journal) { runtime.setQuestJournal(journal); }
|
||||
|
||||
private:
|
||||
DialogueDatabase database;
|
||||
DialogueRuntime runtime;
|
||||
|
||||
@@ -99,6 +99,13 @@ struct Node {
|
||||
|
||||
// Name of the UI node (StaticImage) to reveal in the phone chat when this line is shown
|
||||
std::string bubbleSlot;
|
||||
|
||||
// Quest actions fired when this line is presented (empty = no action)
|
||||
std::string questUnlock;
|
||||
std::string questComplete;
|
||||
std::string questFail;
|
||||
std::string objectiveComplete; // "quest_id.objective_id"
|
||||
std::string objectiveVisible; // "quest_id.objective_id"
|
||||
};
|
||||
|
||||
struct DialogueDefinition {
|
||||
@@ -120,6 +127,13 @@ struct CutsceneLine {
|
||||
int backgroundHeight = 0; // 0 = inherit from cutscene
|
||||
int durationMs = 0;
|
||||
bool waitForConfirm = false;
|
||||
|
||||
// Quest actions fired when this line is shown (empty = no action)
|
||||
std::string questUnlock;
|
||||
std::string questComplete;
|
||||
std::string questFail;
|
||||
std::string objectiveComplete; // "quest_id.objective_id"
|
||||
std::string objectiveVisible; // "quest_id.objective_id"
|
||||
};
|
||||
|
||||
struct CutsceneCameraPose {
|
||||
|
||||
Reference in new issue
Block a user