diff --git a/resources/dialogue/dorm_dialogues.json b/resources/dialogue/dorm_dialogues.json index 48b0e90..b587321 100644 --- a/resources/dialogue/dorm_dialogues.json +++ b/resources/dialogue/dorm_dialogues.json @@ -611,6 +611,60 @@ "type": "End" } ] + }, + { + "id": "dialog_video001", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Бекзат", + "portrait": "resources/dialogue/portrait_hero_neutral.png", + "text": "Ого, пока я залипал в телефоне, уже наступила ночь!", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] + }, + { + "id": "dialog_video002", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Бекзат", + "portrait": "resources/dialogue/portrait_hero_neutral.png", + "text": "Я не буду сейчас смотреть видеоролики, давай лучше пойдем спать.", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] + }, + { + "id": "dialog_video003", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Бекзат", + "portrait": "resources/dialogue/portrait_hero_neutral.png", + "text": "Мне некогда деградировать, мне нужно сегодня 100% быть на лекции!", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] } ], "cutscenes": [{ diff --git a/resources/dialogue/uni_exterior_dialogues.json b/resources/dialogue/uni_exterior_dialogues.json index 70bfbb0..23747a4 100644 --- a/resources/dialogue/uni_exterior_dialogues.json +++ b/resources/dialogue/uni_exterior_dialogues.json @@ -141,6 +141,60 @@ "type": "End" } ] + }, + { + "id": "dialog_video001", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Бекзат", + "portrait": "resources/dialogue/portrait_hero_neutral.png", + "text": "Ого, пока я залипал в приложении, уже наступила ночь!", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] + }, + { + "id": "dialog_video002", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Бекзат", + "portrait": "resources/dialogue/portrait_hero_neutral.png", + "text": "Я не буду сейчас смотреть видеоролики, давай лучше вернемся в общагу и пойдем спать.", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] + }, + { + "id": "dialog_video003", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Бекзат", + "portrait": "resources/dialogue/portrait_hero_neutral.png", + "text": "Мне некогда деградировать, мне нужно сегодня 100% быть на лекции!", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] } ], "cutscenes": [ diff --git a/resources/dialogue/uni_interior_dialogues.json b/resources/dialogue/uni_interior_dialogues.json index fb5e372..cbfa0f5 100644 --- a/resources/dialogue/uni_interior_dialogues.json +++ b/resources/dialogue/uni_interior_dialogues.json @@ -1101,6 +1101,60 @@ "type": "End" } ] + }, + { + "id": "dialog_video001", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Бекзат", + "portrait": "resources/dialogue/portrait_hero_neutral.png", + "text": "Ого, пока я залипал в приложении, уже наступила ночь!", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] + }, + { + "id": "dialog_video002", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Бекзат", + "portrait": "resources/dialogue/portrait_hero_neutral.png", + "text": "Я не буду сейчас смотреть видеоролики, давай лучше вернемся в общагу и пойдем спать.", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] + }, + { + "id": "dialog_video003", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Бекзат", + "portrait": "resources/dialogue/portrait_hero_neutral.png", + "text": "Мне некогда деградировать сейчас!", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] } ], "cutscenes": [ diff --git a/resources/shaders/darklands_flash_desktop.fragment b/resources/shaders/darklands_flash_desktop.fragment index 636c618..f7af9f2 100644 --- a/resources/shaders/darklands_flash_desktop.fragment +++ b/resources/shaders/darklands_flash_desktop.fragment @@ -1,6 +1,7 @@ uniform float uAlpha; +uniform vec3 uFlashColor; void main() { - gl_FragColor = vec4(1.0, 1.0, 1.0, uAlpha); + gl_FragColor = vec4(uFlashColor, uAlpha); } diff --git a/resources/shaders/darklands_flash_web.fragment b/resources/shaders/darklands_flash_web.fragment index bddf49e..a6270e1 100644 --- a/resources/shaders/darklands_flash_web.fragment +++ b/resources/shaders/darklands_flash_web.fragment @@ -1,7 +1,8 @@ precision mediump float; uniform float uAlpha; +uniform vec3 uFlashColor; void main() { - gl_FragColor = vec4(1.0, 1.0, 1.0, uAlpha); + gl_FragColor = vec4(uFlashColor, uAlpha); } diff --git a/resources/start_dorm.lua b/resources/start_dorm.lua index a35c4cc..fbbc7da 100644 --- a/resources/start_dorm.lua +++ b/resources/start_dorm.lua @@ -90,10 +90,7 @@ game_api.set_trigger_zone_callbacks("ladder_zone001", ) function on_bed_sleep() -local need_sleep = game_api.getIntValue("need_sleep") -print("Lua script need sleep =") -print(need_sleep) -if (need_sleep==0) then +if (not game_api.is_night()) then game_api.start_dialogue("dialog_no_sleep001") else game_api.start_cutscene("sleep_cutscene001") diff --git a/src/Game.cpp b/src/Game.cpp index e769107..24de8f7 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -312,7 +312,7 @@ namespace ZL params_dorm.npcsJsonPath = "resources/config2/npcs_dorm.json"; params_dorm.dialoguesJsonPath = "resources/dialogue/dorm_dialogues.json"; - /* + params_dorm.navigationJsonPaths = { "resources/navigation/dorm3_bca.json", "resources/navigation/dorm3_ca.json", @@ -320,7 +320,7 @@ namespace ZL "resources/navigation/dorm3_a.json", "resources/navigation/dorm3_b.json", "resources/navigation/dorm3_all_open.json", - };*/ + }; /* params_dorm.navigationJsonPaths = { "resources/navigation/dorm2_bca2.json", @@ -341,16 +341,14 @@ namespace ZL "resources/navigation/dorm2_b.txt", "resources/navigation/dorm2_all_open.txt", };*/ - - params_dorm.navigationJsonPaths = { + /* params_dorm.navigationJsonPaths = { "resources/navigation/dorm0_large.json", "resources/navigation/dorm0_large.json", "resources/navigation/dorm0_large.json", "resources/navigation/dorm0_large.json", "resources/navigation/dorm0_large.json", "resources/navigation/dorm0_large.json", - }; - + };*/ params_dorm.teleportsJsonPath = "resources/config2/teleports_dorm.json"; params_dorm.triggerZonesJsonPath = "resources/config2/trigger_zones_dorm.json"; @@ -422,6 +420,10 @@ namespace ZL startDarklandsTransition(); }; + menuManager.startNightTransitionFunc = [this]() { + startNightTransition(); + }; + // Wire bubble-slot callback so chat bubbles appear as dialogue lines are shown. for (auto& [name, loc] : locations) { loc->dialogueSystem.setOnBubbleSlotReady([this](const std::string& bubbleSlot) { @@ -760,11 +762,12 @@ namespace ZL if (editorMode == EditorMode::InteractiveObjects && currentLocation) { currentLocation->editor.selectInteractiveObject(9); } else { - if (menuManager.isDawn) { + startNightTransition(); + /*if (menuManager.isDawn) { menuManager.isDawn = false; // step back: dawn → plain night } else { menuManager.isNight = !menuManager.isNight; - } + }*/ } break; case SDLK_0: @@ -1163,6 +1166,17 @@ namespace ZL darklandsFlashActive = true; darklandsFlashFadingIn = true; darklandsFlashAlpha = 0.0f; + isNightTransition = false; + return true; + } + + bool Game::startNightTransition() + { + if (darklandsFlashActive) return false; + darklandsFlashActive = true; + darklandsFlashFadingIn = true; + darklandsFlashAlpha = 0.0f; + isNightTransition = true; return true; } @@ -1175,16 +1189,21 @@ namespace ZL if (darklandsFlashFadingIn) { darklandsFlashAlpha = min(darklandsFlashAlpha + step, 1.0f); if (darklandsFlashAlpha >= 1.0f) { - isDarklands = !isDarklands; + if (isNightTransition) { + menuManager.isNight = !menuManager.isNight; + if (currentLocation) currentLocation->dialogueSystem.startDialogue("dialog_video001"); + } else { + isDarklands = !isDarklands; - // Change HUD - menuManager.setDarklandsMode(isDarklands); + // Change HUD + menuManager.setDarklandsMode(isDarklands); - if (currentLocation) { - if (isDarklands) - currentLocation->scriptEngine.callDarklandsEnterCallback(); - else - currentLocation->scriptEngine.callDarklandsExitCallback(); + if (currentLocation) { + if (isDarklands) + currentLocation->scriptEngine.callDarklandsEnterCallback(); + else + currentLocation->scriptEngine.callDarklandsExitCallback(); + } } darklandsFlashFadingIn = false; } @@ -1193,6 +1212,7 @@ namespace ZL if (darklandsFlashAlpha <= 0.0f) { darklandsFlashAlpha = 0.0f; darklandsFlashActive = false; + isNightTransition = false; } } } @@ -1229,6 +1249,9 @@ namespace ZL renderer.LoadIdentity(); renderer.RenderUniform1f("uAlpha", darklandsFlashAlpha); + static const float kWhite[3] = { 1.f, 1.f, 1.f }; + static const float kBlack[3] = { 0.f, 0.f, 0.f }; + renderer.RenderUniform3fv("uFlashColor", isNightTransition ? kBlack : kWhite); renderer.DrawVertexRenderStruct(darklandsFlashQuad); renderer.PopMatrix(); diff --git a/src/Game.h b/src/Game.h index 5e7dc84..ca30589 100644 --- a/src/Game.h +++ b/src/Game.h @@ -51,6 +51,7 @@ namespace ZL { bool isDarklands = false; // Returns false if a transition is already in progress. bool startDarklandsTransition(); + bool startNightTransition(); Inventory inventory; InteractiveObject* pickedUpObject = nullptr; @@ -118,10 +119,11 @@ namespace ZL { static void onResourcesZipError(const char* filename); #endif - // White-flash transition state + // Screen-flash transition state (shared by darklands and night transitions) float darklandsFlashAlpha = 0.0f; bool darklandsFlashActive = false; bool darklandsFlashFadingIn = true; + bool isNightTransition = false; // true → black flash toggling isNight; false → white flash toggling isDarklands VertexRenderStruct darklandsFlashQuad; float darklandsFlashQuadW = -1.0f; float darklandsFlashQuadH = -1.0f; diff --git a/src/MenuManager.cpp b/src/MenuManager.cpp index d9af896..ad53d5d 100644 --- a/src/MenuManager.cpp +++ b/src/MenuManager.cpp @@ -384,8 +384,15 @@ namespace ZL { uiManager.popMenu(); }); uiManager.setButtonCallback("videoSkip", [this](const std::string&) { - // TODO: trigger time-skip game feature closePhoneEntirely(); + if (isNight) + { + startDialogueFunc("dialog_video002"); + } + else + { + startNightTransitionFunc(); + } }); } diff --git a/src/MenuManager.h b/src/MenuManager.h index 5ab3433..2764579 100644 --- a/src/MenuManager.h +++ b/src/MenuManager.h @@ -69,6 +69,7 @@ namespace ZL { std::function startDialogueFunc; std::function startDarklandsTransitionFunc; + std::function startNightTransitionFunc; void setDarklandsMode(bool enabled); void advanceTutorialStep(); diff --git a/src/ScriptEngine.cpp b/src/ScriptEngine.cpp index 9e21665..0c0825f 100644 --- a/src/ScriptEngine.cpp +++ b/src/ScriptEngine.cpp @@ -222,6 +222,12 @@ namespace ZL { std::cout << "Set dawn called" << std::endl; }); + + api.set_function("is_night", + [game]() { + return game->isNight; + }); + // advance_darklands_hud() // Advances the uni_interior darklands HUD from step12 to step13. // Call when the player enters the ghost trigger zone in darklands.