From 80133aa8c8eb9d7ca117a5bc72045ad7033ee7a7 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Tue, 9 Jun 2026 17:20:03 +0300 Subject: [PATCH] Working on main menu and tutorials --- resources/config2/npcs_uni_interior.json | 4 +- resources/dialogue/cutscenes004.json | 2 +- .../dialogue/uni_interior_dialogues_004.json | 198 ------------------ resources/start_uni_interior.lua | 17 +- src/Game.cpp | 12 +- src/Location.cpp | 1 + src/Location.h | 1 + src/ScriptEngine.cpp | 6 + src/UiManager.cpp | 13 +- 9 files changed, 43 insertions(+), 211 deletions(-) diff --git a/resources/config2/npcs_uni_interior.json b/resources/config2/npcs_uni_interior.json index 832da21..fe2e011 100644 --- a/resources/config2/npcs_uni_interior.json +++ b/resources/config2/npcs_uni_interior.json @@ -28,9 +28,9 @@ "meshTextures": { "Girl_Low": "resources/w/girlfriend/Girl_Base_color.png" }, - "positionX": 0.764049, + "positionX": 1.0, "positionY": 0.0, - "positionZ": -8.53475, + "positionZ": -7.525, "facingAngle" : 180, "walkSpeed": 1.66, "rotationSpeed": 8.0, diff --git a/resources/dialogue/cutscenes004.json b/resources/dialogue/cutscenes004.json index d7a5c41..99f1622 100644 --- a/resources/dialogue/cutscenes004.json +++ b/resources/dialogue/cutscenes004.json @@ -657,7 +657,7 @@ ] }, { - "id": "cutscene_final001", + "id": "game_complete_cutscene001", "skippable": true, "durationMs": 5000, "fadeOutMs": 0, diff --git a/resources/dialogue/uni_interior_dialogues_004.json b/resources/dialogue/uni_interior_dialogues_004.json index c06d136..7afa36d 100644 --- a/resources/dialogue/uni_interior_dialogues_004.json +++ b/resources/dialogue/uni_interior_dialogues_004.json @@ -1970,203 +1970,5 @@ } ] } - ], - "cutscenes": [ - { - "id": "test_cutscene_01", - "background": "resources/test_cutscene001.png", - "durationMs": 5000, - "fadeOutMs": 500, - "fadeInMs": 500, - "endFadeOutMs": 500, - "endFadeInMs": 500, - "cameraTrack": [ - { - "durationMs": 3000, - "from": { - "focusX": 0.3, - "focusY": 0.5, - "zoom": 1.1, - "rotationDeg": 0 - }, - "to": { - "focusX": 0.7, - "focusY": 0.5, - "zoom": 1, - "rotationDeg": 0 - }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 3000, - "from": { - "focusX": 0.3, - "focusY": 0.5, - "zoom": 1, - "rotationDeg": 0 - }, - "to": { - "focusX": 0.7, - "focusY": 0.5, - "zoom": 1.1, - "rotationDeg": 0 - }, - "easing": "EaseInOutCubic" - } - ], - "lines": [ - { - "speaker": "Аида Дженибековна", - "portrait": "resources/dialogue/portrait_teacher.png", - "text": "Здравствуйте, студенты. Кого я вижу, где вы были весь семестр?", - "durationMs": 3000 - }, - { - "speaker": "Аида Дженибековна", - "portrait": "resources/dialogue/portrait_teacher.png", - "text": "В эпизоде \"Семетей\" трилогии \"Манас\", изменники Канчоро и Кыяз захватывают власть над кыргызами.", - "durationMs": 3000 - }, - { - "speaker": "Аида Дженибековна", - "portrait": "resources/dialogue/portrait_teacher.png", - "text": "На сегодня лекция завершена. Домашнее задание - к практическому занятию вы должны подготовить презентации, каждый по своей теме.", - "durationMs": 2000, - "background": "resources/test_cutscene001.png" - } - ] - }, - { - "id": "computer_cutscene001", - "onFadeInCallback": "on_sleep_cutscene", - "background": "resources/test_cutscene001.png", - "durationMs": 5000, - "fadeOutMs": 500, - "fadeInMs": 500, - "endFadeOutMs": 500, - "endFadeInMs": 500, - "cameraTrack": [ - { - "durationMs": 3000, - "from": { - "focusX": 0.3, - "focusY": 0.5, - "zoom": 1.1, - "rotationDeg": 0 - }, - "to": { - "focusX": 0.7, - "focusY": 0.5, - "zoom": 1, - "rotationDeg": 0 - }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 3000, - "from": { - "focusX": 0.3, - "focusY": 0.5, - "zoom": 1, - "rotationDeg": 0 - }, - "to": { - "focusX": 0.7, - "focusY": 0.5, - "zoom": 1.1, - "rotationDeg": 0 - }, - "easing": "EaseInOutCubic" - } - ], - "lines": [ - { - "speaker": "Бекзат", - "portrait": "resources/dialogue/portrait_hero_neutral.png", - "text": "Я начал делать презентацию по книге.", - "durationMs": 3000 - }, - { - "speaker": "Бекзат", - "portrait": "resources/dialogue/portrait_hero_neutral.png", - "text": "Книга была такая скучная что я уснул.", - "durationMs": 3000 - }, - { - "speaker": "Бекзат", - "portrait": "resources/dialogue/portrait_hero_neutral.png", - "text": "И я проснулся уже ночью", - "durationMs": 2000, - "background": "resources/test_cutscene001.png" - } - ] - }, - { - "id": "darklands_exit001", - "onFadeInCallback": "on_darklands_over", - "background": "resources/test_cutscene001.png", - "durationMs": 5000, - "fadeOutMs": 0, - "fadeInMs": 500, - "endFadeOutMs": 500, - "endFadeInMs": 500, - "cameraTrack": [ - { - "durationMs": 3000, - "from": { - "focusX": 0.3, - "focusY": 0.5, - "zoom": 1.1, - "rotationDeg": 0 - }, - "to": { - "focusX": 0.7, - "focusY": 0.5, - "zoom": 1, - "rotationDeg": 0 - }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 3000, - "from": { - "focusX": 0.3, - "focusY": 0.5, - "zoom": 1, - "rotationDeg": 0 - }, - "to": { - "focusX": 0.7, - "focusY": 0.5, - "zoom": 1.1, - "rotationDeg": 0 - }, - "easing": "EaseInOutCubic" - } - ], - "lines": [ - { - "portrait": "resources/dialogue/portrait_hero_neutral.png", - "text": "Мгновенно как я упал без сил, что-то сверкнуло.", - "durationMs": 3000 - }, - { - "portrait": "resources/dialogue/portrait_hero_neutral.png", - "text": "Я открыл глаза и понял, что я по-прежнему в универе.", - "durationMs": 3000 - }, - { - "portrait": "resources/dialogue/portrait_hero_neutral.png", - "text": "Все тело болело, как будто я всю ночь таскал мешки с цементом.", - "durationMs": 3000 - }, - { - "portrait": "resources/dialogue/portrait_hero_neutral.png", - "text": "А еще мне сильно хотелось спать...", - "durationMs": 2000, - "background": "resources/test_cutscene001.png" - } - ] - } ] } \ No newline at end of file diff --git a/resources/start_uni_interior.lua b/resources/start_uni_interior.lua index bbf7b1d..2d8c305 100644 --- a/resources/start_uni_interior.lua +++ b/resources/start_uni_interior.lua @@ -12,12 +12,9 @@ night_time = false player_left_darklands = false - morning_can_open_door_index = 0 morning_did_open_door_index = 0 ---player_ghost_aware = false - ghost_gone = false function dialog_aiperi_give_key() @@ -171,7 +168,7 @@ function on_npc_interact(npc_index) end end if npc_index == 0 then - if (player_ghost_aware) then + if (player_ghost_aware == 1) then --game_api.setIntValue("player_has_coursework", 1) local player_has_coursework = game_api.getIntValue("player_has_coursework") local player_has_report_card = game_api.getIntValue("player_has_report_card") @@ -209,6 +206,8 @@ function on_quest_over() game_api.set_npc_enabled(4, false) game_api.set_npc_enabled(5, false) game_api.quest_set_objective_completed("ghost_release", "ghost_release_show") + + game_api.start_cutscene("game_complete_cutscene001") end --[[ @@ -605,7 +604,7 @@ end function on_report_card_pickup() local player_ghost_aware = game_api.getIntValue("ghost_aware") - if player_ghost_aware then + if player_ghost_aware == 1 then local player_has_report_card = game_api.getIntValue("player_has_report_card") local report_card_signed = game_api.getIntValue("report_card_signed") @@ -1077,7 +1076,7 @@ function on_aiperi_opens_door() end function on_aiperi_morning_dialog_finished() - game_api.npc_walk_to(1, 0.764049, 0, -8.5, nil) + game_api.npc_walk_to(1, 0.98998, 0, -7.525, nil) end game_api.set_location_callbacks( @@ -1127,6 +1126,12 @@ function debugAllOpen() end +game_api.set_cutscene_callback("game_complete_cutscene001", function() + print("---Cutscene done!") + game_api.return_to_main_menu() +end) + + setDay0setup() game_api.switch_navigation(0) diff --git a/src/Game.cpp b/src/Game.cpp index 22809ba..2953217 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -210,7 +210,7 @@ namespace ZL "resources/navigation/uni_interior4_n2_lr_hall.txt", "resources/navigation/uni_interior4_n2_lr_tr_hall.txt", "resources/navigation/uni_interior3_n2_lr_tr_hall_aiperi.txt", - "resources/navigation/uni_interior3_darklands_all_open.txt", + "resources/navigation/uni_interior3_darklands_all_open.txt", //5 "resources/navigation/uni_interior3_unlocked_hall.txt", "resources/navigation/uni_interior3_unlocked_n3.txt", "resources/navigation/uni_interior3_unlocked_s1.txt", @@ -223,9 +223,9 @@ namespace ZL "resources/navigation/uni_interior4_unlocked_s3_s2.txt", "resources/navigation/uni_interior4_unlocked_s3_s1.txt", "resources/navigation/uni_interior4_locked.txt" //17 - };*/ + }; + */ - uniInteriorParams.navigationJsonPaths = { "resources/navigation/uni_interior4_unlocked_n2_new.json", //0 "resources/navigation/uni_interior3_n2_hall.json", @@ -280,6 +280,10 @@ namespace ZL locations["uni_interior"]->requestDarklandsTransition = [this]() { return startDarklandsTransition(); }; locations["uni_interior"]->requestAdvanceDarklandsHud = [this]() { menuManager.advanceUniIntDarklandsHud(); }; locations["uni_interior"]->requestClosePhone = [this]() { menuManager.closePhoneEntirely(); }; + locations["uni_interior"]->requestReturnToMainMenu = [this]() { + this->currentLocation = nullptr; + menuManager.showMainMenu(); + }; if (locations["uni_interior"]->player) locations["uni_interior"]->player->onDeathAnimComplete = [this]() { startDarklandsTransition(); }; for (auto& npc : locations["uni_interior"]->npcs) { @@ -309,6 +313,7 @@ namespace ZL locations["uni_exterior"]->requestNightDayTransition = [this](bool isNight, bool isDawn) { this->menuManager.isNight = isNight; this->menuManager.isDawn = isDawn; }; locations["uni_exterior"]->requestDarklandsTransition = [this]() { return startDarklandsTransition(); }; locations["uni_exterior"]->requestClosePhone = [this]() { menuManager.closePhoneEntirely(); }; + locations["uni_exterior"]->requestReturnToMainMenu = [this]() { menuManager.showMainMenu(); }; if (locations["uni_exterior"]->player) locations["uni_exterior"]->player->onDeathAnimComplete = [this]() { startDarklandsTransition(); }; @@ -352,6 +357,7 @@ namespace ZL locations["location_dorm"]->requestNightDayTransition = [this](bool isNight, bool isDawn) { this->menuManager.isNight = isNight; this->menuManager.isDawn = isDawn; }; locations["location_dorm"]->requestDarklandsTransition = [this]() { return startDarklandsTransition(); }; locations["location_dorm"]->requestClosePhone = [this]() { menuManager.closePhoneEntirely(); }; + locations["location_dorm"]->requestReturnToMainMenu = [this]() { menuManager.showMainMenu(); }; if (locations["location_dorm"]->player) locations["location_dorm"]->player->onDeathAnimComplete = [this]() { startDarklandsTransition(); }; diff --git a/src/Location.cpp b/src/Location.cpp index 0affede..0add3be 100644 --- a/src/Location.cpp +++ b/src/Location.cpp @@ -127,6 +127,7 @@ namespace ZL std::cout << "Shadow map initialized" << std::endl; //#endif + setupNavigation(params.navigationJsonPaths); dialogueSystem.init(renderer, CONST_ZIP_FILE); diff --git a/src/Location.h b/src/Location.h index 87f4487..7bc1ff1 100644 --- a/src/Location.h +++ b/src/Location.h @@ -121,6 +121,7 @@ namespace ZL std::function requestAdvanceDarklandsHud; std::function requestClosePhone; + std::function requestReturnToMainMenu; // Navigation editor — toggle with 'N', save with 'B', right-click to finalize polygon EditorMode editorMode = EditorMode::None; diff --git a/src/ScriptEngine.cpp b/src/ScriptEngine.cpp index 36bd547..d8989db 100644 --- a/src/ScriptEngine.cpp +++ b/src/ScriptEngine.cpp @@ -370,6 +370,12 @@ namespace ZL { game->requestClosePhone(); }); + api.set_function("return_to_main_menu", + [game]() { + if (game->requestReturnToMainMenu) + game->requestReturnToMainMenu(); + }); + api.set_function("set_chat_callbacks", [this_impl = impl.get()](sol::object cb0, sol::object cb1, sol::object cb2) { if (cb0.is()) this_impl->chatOpenCallbacks[0] = cb0.as(); diff --git a/src/UiManager.cpp b/src/UiManager.cpp index 851ccfa..f976b54 100644 --- a/src/UiManager.cpp +++ b/src/UiManager.cpp @@ -11,6 +11,8 @@ namespace ZL { using json = nlohmann::json; + extern float x; + static int countWrappedLines(const std::string& text) { if (text.empty()) return 0; @@ -2170,7 +2172,16 @@ namespace ZL { } else { - node->localX = node->width * 0.5-110 - (UiChatBubble::MAX_WIDTH - node->width);// -(425.f - node->width); + /*if (node->width == UiChatBubble::MAX_WIDTH) + { + node->localX = node->width * 0.5 - 110 - (UiChatBubble::MAX_WIDTH - node->width);// -(425.f - node->width); + } + else + {*/ + //node->localX = node->width * 0.5 - 110; + //node->localX = - 110 +x; + node->localX = 210 - node->width * 0.5; + //} } //430 //1280