added dialog start radius and background by time in cutscenes

This commit is contained in:
Vlad 2026-04-14 18:07:46 +06:00
parent db8b9b7a18
commit f7e6f063d1
10 changed files with 35 additions and 10 deletions

View File

@ -37,6 +37,7 @@
"modelCorrectionRotX": 0.0, "modelCorrectionRotX": 0.0,
"modelCorrectionRotY": 180.0, "modelCorrectionRotY": 180.0,
"modelCorrectionRotZ": 0.0, "modelCorrectionRotZ": 0.0,
"interactionRadius": 1.0,
"gift": { "gift": {
"id": "ghost_essence", "id": "ghost_essence",
"name": "Ghost's Essence", "name": "Ghost's Essence",

View File

@ -160,7 +160,8 @@
"speaker": "Ghost", "speaker": "Ghost",
"portrait": "resources/ghost_avatar.png", "portrait": "resources/ghost_avatar.png",
"text": "Some memories never fade.", "text": "Some memories never fade.",
"durationMs": 2600 "durationMs": 2600,
"background": "resources/loading.png"
} }
] ]
} }

View File

@ -47,6 +47,8 @@ public:
std::string npcName; std::string npcName;
bool giftReceived = false; bool giftReceived = false;
float interactionRadius = 0.0f;
private: private:
struct AnimationData { struct AnimationData {
BoneSystem model; BoneSystem model;

View File

@ -656,6 +656,8 @@ namespace ZL
// Check if we clicked on an NPC // Check if we clicked on an NPC
Character* clickedNpc = raycastNpcs(camPos, rayDir); Character* clickedNpc = raycastNpcs(camPos, rayDir);
if (clickedNpc && player) { if (clickedNpc && player) {
float distance = (player->position - clickedNpc->position).norm();
if (distance <= clickedNpc->interactionRadius) {
int npcIndex = -1; int npcIndex = -1;
for (size_t i = 0; i < npcs.size(); ++i) { for (size_t i = 0; i < npcs.size(); ++i) {
if (npcs[i].get() == clickedNpc) { if (npcs[i].get() == clickedNpc) {
@ -664,10 +666,15 @@ namespace ZL
} }
} }
if (npcIndex != -1) { if (npcIndex != -1) {
std::cout << "[CLICK] *** SUCCESS: Clicked on NPC index: " << npcIndex << " ***" << std::endl; std::cout << "[CLICK] NPC interaction (distance " << distance << ")" << std::endl;
scriptEngine.callNpcInteractCallback(npcIndex); scriptEngine.callNpcInteractCallback(npcIndex);
} }
} }
else {
std::cout << "[CLICK] Too far from NPC (distance " << distance
<< " > " << clickedNpc->interactionRadius << ")" << std::endl;
}
}
else if (rayDir.y() < -0.001f && player) { else if (rayDir.y() < -0.001f && player) {
// Otherwise, unproject click to ground plane for Viola's walk target // Otherwise, unproject click to ground plane for Viola's walk target
float t = -camPos.y() / rayDir.y(); float t = -camPos.y() / rayDir.y();

View File

@ -121,6 +121,7 @@ CutsceneLine DialogueDatabase::parseCutsceneLine(const json& j) {
line.text = j.value("text", ""); line.text = j.value("text", "");
line.portrait = j.value("portrait", ""); line.portrait = j.value("portrait", "");
line.sfx = j.value("sfx", ""); line.sfx = j.value("sfx", "");
line.background = j.value("background", "");
line.durationMs = j.value("durationMs", 0); line.durationMs = j.value("durationMs", 0);
line.waitForConfirm = j.value("waitForConfirm", false); line.waitForConfirm = j.value("waitForConfirm", false);
return line; return line;

View File

@ -325,6 +325,7 @@ void DialogueRuntime::startCutscene(const std::string& cutsceneId, const std::st
activeCutscene = cutscene; activeCutscene = cutscene;
pendingNodeAfterCutscene = nextNodeAfterCutscene; pendingNodeAfterCutscene = nextNodeAfterCutscene;
currentCutsceneBackground = cutscene->background;
mode = Mode::PlayingCutscene; mode = Mode::PlayingCutscene;
currentCutsceneLine = -1; currentCutsceneLine = -1;
cutsceneTimerMs = 0; cutsceneTimerMs = 0;
@ -363,12 +364,18 @@ void DialogueRuntime::refreshCutscenePresentation() {
} }
const CutsceneLine& line = activeCutscene->lines[currentCutsceneLine]; const CutsceneLine& line = activeCutscene->lines[currentCutsceneLine];
if (!line.background.empty()) {
currentCutsceneBackground = line.background;
}
presentation.mode = PresentationMode::Cutscene; presentation.mode = PresentationMode::Cutscene;
presentation.speaker = line.speaker; presentation.speaker = line.speaker;
presentation.fullText = line.text; presentation.fullText = line.text;
presentation.visibleText = line.text; presentation.visibleText = line.text;
presentation.portraitPath = line.portrait; presentation.portraitPath = line.portrait;
presentation.backgroundPath = activeCutscene->background; //presentation.backgroundPath = activeCutscene->background;
presentation.backgroundPath = currentCutsceneBackground;
presentation.choices.clear(); presentation.choices.clear();
presentation.selectedChoice = 0; presentation.selectedChoice = 0;
presentation.revealCompleted = true; presentation.revealCompleted = true;

View File

@ -64,6 +64,8 @@ private:
int currentCutsceneLine = -1; int currentCutsceneLine = -1;
int cutsceneTimerMs = 0; int cutsceneTimerMs = 0;
std::string currentCutsceneBackground;
bool evaluateConditions(const std::vector<Condition>& conditions) const; bool evaluateConditions(const std::vector<Condition>& conditions) const;
void applyEffects(const std::vector<Effect>& effects); void applyEffects(const std::vector<Effect>& effects);

View File

@ -87,6 +87,7 @@ struct CutsceneLine {
std::string text; std::string text;
std::string portrait; std::string portrait;
std::string sfx; std::string sfx;
std::string background;
int durationMs = 0; int durationMs = 0;
bool waitForConfirm = false; bool waitForConfirm = false;
}; };

View File

@ -280,6 +280,7 @@ namespace ZL {
data.id = item.value("id", "npc_unknown"); data.id = item.value("id", "npc_unknown");
data.name = item.value("name", "Unknown NPC"); data.name = item.value("name", "Unknown NPC");
data.texturePath = item.value("texturePath", ""); data.texturePath = item.value("texturePath", "");
data.interactionRadius = item.value("interactionRadius", 0.0f);
data.animationIdlePath = item.value("animationIdlePath", ""); data.animationIdlePath = item.value("animationIdlePath", "");
data.animationWalkPath = item.value("animationWalkPath", ""); data.animationWalkPath = item.value("animationWalkPath", "");
@ -364,6 +365,7 @@ namespace ZL {
npc->rotationSpeed = npcData.rotationSpeed; npc->rotationSpeed = npcData.rotationSpeed;
npc->modelScale = npcData.modelScale; npc->modelScale = npcData.modelScale;
npc->position = Eigen::Vector3f(npcData.positionX, npcData.positionY, npcData.positionZ); npc->position = Eigen::Vector3f(npcData.positionX, npcData.positionY, npcData.positionZ);
npc->interactionRadius = npcData.interactionRadius;
// Set NPC metadata // Set NPC metadata
npc->npcId = npcData.id; npc->npcId = npcData.id;

View File

@ -57,6 +57,7 @@ namespace ZL {
float modelCorrectionRotY = 0.0f; float modelCorrectionRotY = 0.0f;
float modelCorrectionRotZ = 0.0f; float modelCorrectionRotZ = 0.0f;
GiftData gift; GiftData gift;
float interactionRadius = 0.0f;
}; };
struct LoadedGameObject { struct LoadedGameObject {