Dialog fixing
This commit is contained in:
1 parent
8c200974c2
commit
84c8a7a27a
13 files changed
+169
-43
No files matched your search
+13
-5
@@ -104,6 +104,19 @@ void Character::stopInPlace()
|
||||
onArrivedCallback = nullptr;
|
||||
}
|
||||
|
||||
void Character::resetPlayerAfterDeath()
|
||||
{
|
||||
if (!isPlayer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
currentState = AnimationState::STAND;
|
||||
resetAnim = true;
|
||||
showWeapon = false;
|
||||
battle_state = 0;
|
||||
attack = 0;
|
||||
}
|
||||
|
||||
void Character::forceReplan()
|
||||
{
|
||||
if (!pathPlanner) {
|
||||
@@ -456,11 +469,6 @@ void Character::update(int64_t deltaMs) {
|
||||
//onDeathAnimComplete = nullptr;
|
||||
onDeathAnimComplete();
|
||||
//TODO: need to add some delay here
|
||||
currentState = AnimationState::STAND;
|
||||
resetAnim = true;
|
||||
showWeapon = false;
|
||||
battle_state = 0;
|
||||
attack = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ public:
|
||||
// character and we don't want it to walk back to where it was.
|
||||
void stopInPlace();
|
||||
|
||||
void resetPlayerAfterDeath();
|
||||
|
||||
|
||||
// attackDirection is a world-space horizontal vector pointing from the
|
||||
// attacker toward this character — i.e. the direction the hit pushes
|
||||
|
||||
@@ -195,7 +195,6 @@ namespace ZL
|
||||
uniInteriorParams.npcsJsonPath = "resources/config2/npcs_uni_interior.json";
|
||||
uniInteriorParams.dialoguesJsonPath = "resources/dialogue/uni_interior_dialogues.json";
|
||||
|
||||
|
||||
uniInteriorParams.navigationJsonPaths = {
|
||||
"resources/navigation/uni_interior0_all_locked.txt",
|
||||
"resources/navigation/uni_interior0_hall.txt",
|
||||
|
||||
@@ -146,6 +146,25 @@ namespace ZL
|
||||
scriptEngine.callCutsceneCompleteCallback(cutsceneId);
|
||||
});
|
||||
|
||||
dialogueSystem.setOnDialogueLineStarted([this](const std::string& fn) {
|
||||
try { scriptEngine.callActivateFunction(fn); }
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "[dialogue] line callback error: " << e.what() << "\n";
|
||||
}
|
||||
});
|
||||
dialogueSystem.setOnCutsceneLineStarted([this](const std::string& fn) {
|
||||
try { scriptEngine.callActivateFunction(fn); }
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "[cutscene] line callback error: " << e.what() << "\n";
|
||||
}
|
||||
});
|
||||
dialogueSystem.setOnCutsceneFadeInComplete([this](const std::string& fn) {
|
||||
try { scriptEngine.callActivateFunction(fn); }
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "[cutscene] fade-in callback error: " << e.what() << "\n";
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void Location::loadTeleportZones(const std::string& jsonPath, const char* zipFile)
|
||||
|
||||
@@ -460,6 +460,11 @@ namespace ZL {
|
||||
std::cerr << "[script] scale_object: object '" << name << "' not found\n";
|
||||
});
|
||||
|
||||
api.set_function("resetPlayerAfterDeath",
|
||||
[game]() {
|
||||
if (game->player) game->player->resetPlayerAfterDeath();
|
||||
});
|
||||
|
||||
// player_stop() — cancels the player's current walk target and stops them immediately.
|
||||
api.set_function("player_stop",
|
||||
[game]() {
|
||||
|
||||
@@ -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"]) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user