From 9f17d51fc8fb73fcf10efb4f8f99c06faf501578 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Wed, 15 Jul 2026 14:28:31 +0300 Subject: [PATCH] Fixing bugs, change dialogue translations --- resources/dialogue/cutscene_image_tests.json | 290 ---------- resources/dialogue/dorm_dialogues004.json | 2 +- resources/dialogue/sample_dialogues.json | 501 ------------------ resources/dialogue/translate_dialogues.json | 12 +- .../dialogue/uni_exterior_dialogues003.json | 2 +- resources/start_uni_interior.lua | 1 - src/Game.cpp | 2 - src/GameState.cpp | 2 + src/Location.cpp | 9 + src/ScriptEngine.cpp | 21 + src/main.cpp | 5 +- src/utils/Utils.cpp | 12 +- 12 files changed, 50 insertions(+), 809 deletions(-) delete mode 100644 resources/dialogue/cutscene_image_tests.json delete mode 100644 resources/dialogue/sample_dialogues.json diff --git a/resources/dialogue/cutscene_image_tests.json b/resources/dialogue/cutscene_image_tests.json deleted file mode 100644 index cb8c04d..0000000 --- a/resources/dialogue/cutscene_image_tests.json +++ /dev/null @@ -1,290 +0,0 @@ -{ - "dialogues": [ - { - "id": "test_cutscene_skip_hold_dialogue", - "start": "cutscene_start", - "nodes": [ - { - "id": "cutscene_start", - "type": "CutsceneStart", - "cutsceneId": "test_cutscene_skip_hold_01", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "test_cutscene_images_hardcut_dialogue", - "start": "cutscene_start", - "nodes": [ - { - "id": "cutscene_start", - "type": "CutsceneStart", - "cutsceneId": "test_cutscene_images_hardcut_01", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "test_cutscene_images_crossfade_dialogue", - "start": "cutscene_start", - "nodes": [ - { - "id": "cutscene_start", - "type": "CutsceneStart", - "cutsceneId": "test_cutscene_images_crossfade_01", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "test_cutscene_images_silent_dialogue", - "start": "cutscene_start", - "nodes": [ - { - "id": "cutscene_start", - "type": "CutsceneStart", - "cutsceneId": "test_cutscene_images_silent_01", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - } - ], - "cutscenes": [ - { - "id": "test_cutscene_skip_hold_01", - "background": "resources/first_cutscene.png", - "skippable": true, - "durationMs": 12000, - "cameraTrack": [ - { - "durationMs": 3000, - "from": { "anchor": "Center", "zoom": 1.0, "rotationDeg": 0.0 }, - "to": { "anchor": "TopLeft", "zoom": 1.45, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 3000, - "from": { "anchor": "TopLeft", "zoom": 1.45, "rotationDeg": 0.0 }, - "to": { "anchor": "TopRight", "zoom": 1.45, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 3000, - "from": { "anchor": "TopRight", "zoom": 1.45, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomRight", "zoom": 1.65, "rotationDeg": 0.0 }, - "easing": "EaseInCubic" - }, - { - "durationMs": 3000, - "from": { "anchor": "BottomRight", "zoom": 1.65, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomLeft", "zoom": 1.45, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - } - ], - "lines": [ - { - "speaker": "Narrator", - "portrait": "", - "text": "This cutscene is long enough to test hold-to-skip.", - "durationMs": 2600 - }, - { - "speaker": "Narrator", - "portrait": "", - "text": "A normal click must not skip it.", - "durationMs": 2600 - }, - { - "speaker": "Ghost", - "portrait": "resources/ghost_avatar.png", - "text": "Only the skip button with hold should work.", - "durationMs": 2600 - } - ] - }, - { - "id": "test_cutscene_images_hardcut_01", - "background": "resources/first_cutscene.png", - "skippable": true, - "durationMs": 9000, - "cameraTrack": [ - { - "durationMs": 4500, - "from": { "anchor": "Center", "zoom": 1.0, "rotationDeg": 0.0 }, - "to": { "anchor": "TopLeft", "zoom": 1.35, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 4500, - "from": { "anchor": "TopLeft", "zoom": 1.35, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomRight", "zoom": 1.55, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - } - ], - "images": [ - { - "path": "resources/first_cutscene.png", - "startMs": 0, - "endMs": 4500, - "fadeInMs": 0, - "fadeOutMs": 0 - }, - { - "path": "resources/second_cutscene.png", - "startMs": 4500, - "endMs": 9000, - "fadeInMs": 0, - "fadeOutMs": 0 - } - ], - "lines": [ - { - "speaker": "Narrator", - "portrait": "", - "text": "First image should switch sharply to the second one.", - "durationMs": 2800 - }, - { - "speaker": "Narrator", - "portrait": "", - "text": "No fade should be visible here.", - "durationMs": 2800 - } - ] - }, - { - "id": "test_cutscene_images_crossfade_01", - "background": "resources/first_cutscene.png", - "skippable": true, - "durationMs": 10000, - "cameraTrack": [ - { - "durationMs": 2500, - "from": { "anchor": "Center", "zoom": 1.0, "rotationDeg": 0.0 }, - "to": { "anchor": "Custom", "centerX": 0.35, "centerY": 0.30, "zoom": 1.45, "rotationDeg": 0.0 }, - "easing": "EaseInOutQuad" - }, - { - "durationMs": 2500, - "from": { "anchor": "Custom", "centerX": 0.35, "centerY": 0.30, "zoom": 1.45, "rotationDeg": 0.0 }, - "to": { "anchor": "Custom", "centerX": 0.70, "centerY": 0.32, "zoom": 1.45, "rotationDeg": 0.0 }, - "easing": "EaseOutCubic" - }, - { - "durationMs": 2500, - "from": { "anchor": "Custom", "centerX": 0.70, "centerY": 0.32, "zoom": 1.45, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomRight", "zoom": 1.70, "rotationDeg": 0.0 }, - "easing": "EaseInCubic" - }, - { - "durationMs": 2500, - "from": { "anchor": "BottomRight", "zoom": 1.70, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomLeft", "zoom": 1.55, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - } - ], - "images": [ - { - "path": "resources/first_cutscene.png", - "startMs": 0, - "endMs": 6000, - "fadeInMs": 0, - "fadeOutMs": 0 - }, - { - "path": "resources/second_cutscene.png", - "startMs": 4500, - "endMs": 10000, - "fadeInMs": 1500, - "fadeOutMs": 0 - } - ], - "lines": [ - { - "speaker": "Narrator", - "portrait": "", - "text": "The second image should fade over the first one.", - "durationMs": 2600 - }, - { - "speaker": "Ghost", - "portrait": "resources/ghost_avatar.png", - "text": "This test checks overlap and alpha blending.", - "durationMs": 2600 - } - ] - }, - { - "id": "test_cutscene_images_silent_01", - "background": "resources/first_cutscene.png", - "skippable": true, - "durationMs": 11000, - "cameraTrack": [ - { - "durationMs": 2500, - "from": { "anchor": "Center", "zoom": 1.0, "rotationDeg": 0.0 }, - "to": { "anchor": "TopLeft", "zoom": 1.35, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 3000, - "from": { "anchor": "TopLeft", "zoom": 1.35, "rotationDeg": 0.0 }, - "to": { "anchor": "TopRight", "zoom": 1.35, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 3000, - "from": { "anchor": "TopRight", "zoom": 1.35, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomRight", "zoom": 1.55, "rotationDeg": 0.0 }, - "easing": "EaseOutCubic" - }, - { - "durationMs": 2500, - "from": { "anchor": "BottomRight", "zoom": 1.55, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomLeft", "zoom": 1.45, "rotationDeg": 0.0 }, - "easing": "EaseInOutQuad" - } - ], - "images": [ - { - "path": "resources/first_cutscene.png", - "startMs": 0, - "endMs": 3500, - "fadeInMs": 0, - "fadeOutMs": 800 - }, - { - "path": "resources/second_cutscene.png", - "startMs": 3000, - "endMs": 7500, - "fadeInMs": 800, - "fadeOutMs": 1000 - }, - { - "path": "resources/loading.png", - "startMs": 7000, - "endMs": 11000, - "fadeInMs": 1000, - "fadeOutMs": 0 - } - ], - "lines": [] - } - ] -} diff --git a/resources/dialogue/dorm_dialogues004.json b/resources/dialogue/dorm_dialogues004.json index d8833dc..4497eff 100644 --- a/resources/dialogue/dorm_dialogues004.json +++ b/resources/dialogue/dorm_dialogues004.json @@ -368,7 +368,7 @@ "type": "Line", "speaker": "Бекзат", "portrait": "resources/dialogue/portrait_hero_neutral.png", - "text": "Я заказал такси до универа, машина уже ждет!", + "text": "Я заказал такси до универа, машина уже едет!", "next": "end_1" }, { diff --git a/resources/dialogue/sample_dialogues.json b/resources/dialogue/sample_dialogues.json deleted file mode 100644 index d31ce4d..0000000 --- a/resources/dialogue/sample_dialogues.json +++ /dev/null @@ -1,501 +0,0 @@ -{ - "dialogues": [ - { - "id": "dialog_student", - "start": "line_1", - "nodes": [ - { - "id": "line_1", - "type": "Line", - "speaker": "Студент", - "portrait": "resources/w/avatar_student.png", - "text": "В университете завелись призраки, мне страшно ходить на занятия.", - "next": "line_2" - }, - { - "id": "line_2", - "type": "Line", - "speaker": "Hero", - "portrait": "resources/w/gg/gg2_s_podsvetkoy5.png", - "text": "Можешь рассказать подробнее?", - "next": "line_3" - }, - { - "id": "line_3", - "type": "Line", - "speaker": "Студент", - "portrait": "resources/w/avatar_student.png", - "text": "Спроси у Мухтара байке, он все знает.", - "next": "line_4" - }, - { - "id": "line_4", - "type": "Line", - "speaker": "Hero", - "portrait": "resources/w/gg/gg2_s_podsvetkoy5.png", - "text": "Хорошо.", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "dialog_mukhtar", - "start": "line_1", - "nodes": [ - { - "id": "line_1", - "type": "Line", - "speaker": "Мухтар байке", - "portrait": "resources/w/avatar_unknown.png", - "text": "Здравствуй, мы давно тебя ждем! Ты поможешь нам избавиться от призраков?", - "next": "line_2" - }, - { - "id": "line_2", - "type": "Line", - "speaker": "Hero", - "portrait": "resources/w/gg/gg2_s_podsvetkoy5.png", - "text": "Где их найти?", - "next": "line_3" - }, - { - "id": "line_3", - "type": "Line", - "speaker": "Мухтар байке", - "portrait": "resources/w/avatar_unknown.png", - "text": "Заходи в здание универа и поднимайся на второй этаж.", - "next": "line_4" - }, - { - "id": "line_4", - "type": "Line", - "speaker": "Мухтар байке", - "portrait": "resources/w/avatar_unknown.png", - "text": "Ты их встретишь прямо там.", - "next": "line_5" - }, - { - "id": "line_4", - "type": "Line", - "speaker": "Hero", - "portrait": "resources/w/gg/gg2_s_podsvetkoy5.png", - "text": "Хорошо, я скоро вернусь!", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "dialog_female_student", - "start": "line_1", - "nodes": [ - { - "id": "line_1", - "type": "Line", - "speaker": "Студентка", - "portrait": "resources/w/avatar_girl.png", - "text": "С этими призраками совсем невозможно ходить на лекции!", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "test_line_dialogue", - "start": "line_1", - "nodes": [ - { - "id": "line_1", - "type": "Line", - "speaker": "Ghost", - "portrait": "resources/ghost_avatar.png", - "text": "Наконец-то ты пришел.", - "next": "line_2" - }, - { - "id": "line_2", - "type": "Line", - "speaker": "Hero", - "portrait": "resources/w/gg/gg2_s_podsvetkoy5.png", - "text": "Ты сделан из дыма?", - "next": "line_3" - }, - { - "id": "line_3", - "type": "Line", - "speaker": "Ghost", - "portrait": "resources/ghost_avatar.png", - "text": "Ты думаешь, это смешно?", - "next": "line_4" - }, - { - "id": "line_4", - "type": "Line", - "speaker": "Hero", - "portrait": "resources/w/gg/gg2_s_podsvetkoy5.png", - "text": "Я думаю что ты пахнешь как выхлоп от Камаза.", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "ghost_choice_dialogue", - "start": "line_1", - "nodes": [ - { - "id": "line_1", - "type": "Line", - "speaker": "Беспокойный Призрак", - "portrait": "resources/w/avatar_ghost.png", - "text": "Нечасто я вижу смертных, готовых разговаривать со мной.", - "next": "choice_1" - }, - { - "id": "choice_1", - "type": "Choice", - "speaker": "Hero", - "portrait": "resources/w/gg/gg2_s_podsvetkoy5.png", - "text": "", - "choices": [ - { - "id": "main_1", - "kind": "Main", - "text": "Не мешай студентам учиться!", - "next": "line_goods" - }, - { - "id": "optional_1", - "kind": "Optional", - "text": "Почему ты появился здесь?", - "next": "line_who" - } - ] - }, - { - "id": "line_goods", - "type": "Line", - "speaker": "Беспокойный Призрак", - "portrait": "resources/w/avatar_ghost.png", - "text": "Это моя месть студентам за то что они призвали меня.", - "next": "end_1" - }, - { - "id": "line_who", - "type": "Line", - "speaker": "Беспокойный Призрак", - "portrait": "resources/w/avatar_ghost.png", - "text": "Группа студентов совершила ритуал и призвала меня сюда. Пока проклятие не спадет, я всегда буду здесь обитать.", - "next": "choice_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "test_condition_dialogue", - "start": "set_flag_1", - "nodes": [ - { - "id": "set_flag_1", - "type": "SetFlag", - "effects": [ - { "flag": "met_ghost", "value": 1 } - ], - "next": "condition_1" - }, - { - "id": "condition_1", - "type": "Condition", - "conditions": [ - { "flag": "met_ghost", "op": "Equals", "value": 1 } - ], - "trueNext": "line_true", - "falseNext": "line_false" - }, - { - "id": "line_true", - "type": "Line", - "speaker": "Ghost", - "portrait": "resources/ghost_avatar.png", - "text": "Now you know who I am.", - "next": "end_1" - }, - { - "id": "line_false", - "type": "Line", - "speaker": "Ghost", - "portrait": "resources/ghost_avatar.png", - "text": "You should not hear this line.", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "test_cutscene_dialogue", - "start": "cutscene_start", - "nodes": [ - { - "id": "cutscene_start", - "type": "CutsceneStart", - "cutsceneId": "test_cutscene_01", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "test_silent_cutscene_dialogue", - "start": "cutscene_start", - "nodes": [ - { - "id": "cutscene_start", - "type": "CutsceneStart", - "cutsceneId": "test_cutscene_silent_01", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "test_cutscene_pan_dialogue", - "start": "cutscene_start", - "nodes": [ - { - "id": "cutscene_start", - "type": "CutsceneStart", - "cutsceneId": "test_cutscene_pan_01", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "test_cutscene_pan_dialogue_silent", - "start": "cutscene_start", - "nodes": [ - { - "id": "cutscene_start", - "type": "CutsceneStart", - "cutsceneId": "test_cutscene_pan_02", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - }, - { - "id": "dialog_aida", - "start": "line_1", - "nodes": [ - { - "id": "line_1", - "type": "Line", - "speaker": "Асель Дженибековна", - "portrait": "resources/w/avatar_teacher.png", - "text": "Молодой человек, у меня обед! Я принимаю лабораторные работы только после двух!", - "next": "line_2" - }, - { - "id": "line_2", - "type": "Line", - "speaker": "Hero", - "portrait": "resources/w/gg/gg2_s_podsvetkoy5.png", - "text": "Хорошо, Асель Дженибековна.", - "next": "end_1" - }, - { - "id": "end_1", - "type": "End" - } - ] - } - ], - "cutscenes": [ - { - "id": "test_cutscene_01", - "background": "resources/first_cutscene.png", - "durationMs": 6800, - "cameraTrack": [ - { - "durationMs": 2400, - "from": { "focusX": 0.50, "focusY": 0.55, "zoom": 1.00, "rotationDeg": 0.0 }, - "to": { "focusX": 0.63, "focusY": 0.58, "zoom": 1.16, "rotationDeg": -1.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 2200, - "from": { "focusX": 0.63, "focusY": 0.58, "zoom": 1.16, "rotationDeg": -1.0 }, - "to": { "focusX": 0.74, "focusY": 0.52, "zoom": 1.30, "rotationDeg": -2.4 }, - "easing": "EaseInOutCubic" - }, - { - "durationMs": 2200, - "from": { "focusX": 0.74, "focusY": 0.52, "zoom": 1.30, "rotationDeg": -2.4 }, - "to": { "focusX": 0.58, "focusY": 0.46, "zoom": 1.10, "rotationDeg": -0.6 }, - "easing": "EaseOutSine" - } - ], - "lines": [ - { - "speaker": "Narrator", - "portrait": "resources/hero.png", - "text": "The air in the room turned cold.", - "durationMs": 2200 - }, - { - "speaker": "Ghost", - "portrait": "resources/w/avatar_ghost.png", - "text": "Some memories never fade.", - "durationMs": 2600, - "background": "resources/loading.png" - } - ] - }, - { - "id": "test_cutscene_silent_01", - "background": "resources/first_cutscene.png", - "durationMs": 5200, - "cameraTrack": [ - { - "durationMs": 2600, - "from": { "focusX": 0.40, "focusY": 0.54, "zoom": 1.00, "rotationDeg": 0.0 }, - "to": { "focusX": 0.58, "focusY": 0.54, "zoom": 1.22, "rotationDeg": 0.8 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 2600, - "from": { "focusX": 0.58, "focusY": 0.54, "zoom": 1.22, "rotationDeg": 0.8 }, - "to": { "focusX": 0.72, "focusY": 0.48, "zoom": 1.34, "rotationDeg": -0.5 }, - "easing": "EaseOutCubic" - } - ], - "lines": [] - }, - { - "id": "test_cutscene_pan_01", - "background": "resources/first_cutscene.png", - "durationMs": 12000, - "cameraTrack": [ - { - "durationMs": 1200, - "from": { "anchor": "Center", "zoom": 1.00, "rotationDeg": 0.0 }, - "to": { "anchor": "Center", "zoom": 1.00, "rotationDeg": 0.0 }, - "easing": "Linear" - }, - { - "durationMs": 2500, - "from": { "anchor": "Center", "zoom": 1.00, "rotationDeg": 0.0 }, - "to": { "anchor": "TopLeft", "zoom": 1.55, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 2600, - "from": { "anchor": "TopLeft", "zoom": 1.55, "rotationDeg": 0.0 }, - "to": { "anchor": "TopRight", "zoom": 1.55, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 1800, - "from": { "anchor": "TopRight", "zoom": 1.55, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomRight", "zoom": 1.72, "rotationDeg": 0.0 }, - "easing": "EaseInCubic" - }, - { - "durationMs": 3900, - "from": { "anchor": "BottomRight", "zoom": 1.72, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomLeft", "zoom": 1.55, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - } - ], - "lines": [ - { - "speaker": "Narrator", - "portrait": "resources/hero.png", - "text": "The memory begins in silence.", - "durationMs": 2200 - }, - { - "speaker": "Narrator", - "portrait": "resources/hero.png", - "text": "Something is drawing your eyes across the whole scene.", - "durationMs": 2800 - }, - { - "speaker": "Ghost", - "portrait": "resources/ghost_avatar.png", - "text": "Do not look away.", - "durationMs": 2400 - } - ] - }, - { - "id": "test_cutscene_pan_02", - "background": "resources/first_cutscene.png", - "durationMs": 12000, - "cameraTrack": [ - { - "durationMs": 1200, - "from": { "anchor": "Center", "zoom": 1.00, "rotationDeg": 0.0 }, - "to": { "anchor": "Center", "zoom": 1.00, "rotationDeg": 0.0 }, - "easing": "Linear" - }, - { - "durationMs": 2500, - "from": { "anchor": "Center", "zoom": 1.00, "rotationDeg": 0.0 }, - "to": { "anchor": "TopLeft", "zoom": 1.55, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 2600, - "from": { "anchor": "TopLeft", "zoom": 1.55, "rotationDeg": 0.0 }, - "to": { "anchor": "TopRight", "zoom": 1.55, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - }, - { - "durationMs": 1800, - "from": { "anchor": "TopRight", "zoom": 1.55, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomRight", "zoom": 1.72, "rotationDeg": 0.0 }, - "easing": "EaseInCubic" - }, - { - "durationMs": 3900, - "from": { "anchor": "BottomRight", "zoom": 1.72, "rotationDeg": 0.0 }, - "to": { "anchor": "BottomLeft", "zoom": 1.55, "rotationDeg": 0.0 }, - "easing": "EaseInOutSine" - } - ], - "lines": [] - } - ] -} diff --git a/resources/dialogue/translate_dialogues.json b/resources/dialogue/translate_dialogues.json index 7f5a564..1f69117 100644 --- a/resources/dialogue/translate_dialogues.json +++ b/resources/dialogue/translate_dialogues.json @@ -136,9 +136,9 @@ "en": "Before going outside, I have to order a taxi to the university." }, { - "key": "Я заказал такси до универа, машина уже ждет!", - "ru": "Я заказал такси до универа, машина уже ждет!", - "en": "I ordered a taxi to the university, the car is already waiting!" + "key": "Я заказал такси до универа, машина уже едет!", + "ru": "Я заказал такси до универа, машина уже едет!", + "en": "I ordered a taxi to the university, the car is already on its way!" }, { "key": "Я уже заказал такси, машина уже ждет!", @@ -456,9 +456,9 @@ "en": "Before I leave the gate, I have to order a taxi to the dorm." }, { - "key": "Я заказал такси до общаги, машина уже ждет!", - "ru": "Я заказал такси до общаги, машина уже ждет!", - "en": "I ordered a taxi to the dorm, the car is already waiting!" + "key": "Я заказал такси до общаги, машина уже едет!", + "ru": "Я заказал такси до общаги, машина уже едет!", + "en": "I ordered a taxi to the dorm, the car is already on its way!" }, { "key": "Ого, пока я залипал в приложении, уже наступила ночь!", diff --git a/resources/dialogue/uni_exterior_dialogues003.json b/resources/dialogue/uni_exterior_dialogues003.json index 41871fe..d2fb8d1 100644 --- a/resources/dialogue/uni_exterior_dialogues003.json +++ b/resources/dialogue/uni_exterior_dialogues003.json @@ -134,7 +134,7 @@ "type": "Line", "speaker": "Бекзат", "portrait": "resources/dialogue/portrait_hero_neutral.png", - "text": "Я заказал такси до общаги, машина уже ждет!", + "text": "Я заказал такси до общаги, машина уже едет!", "next": "end_1" }, { diff --git a/resources/start_uni_interior.lua b/resources/start_uni_interior.lua index 6887ef0..afc44fd 100644 --- a/resources/start_uni_interior.lua +++ b/resources/start_uni_interior.lua @@ -45,7 +45,6 @@ end function lection_hall_zone001_enter_callback() local lection_is_over = game_api.getIntValue("lection_is_over") - if (lection_is_over == 0) then game_api.player_stop() game_api.start_cutscene("lection_cutscene001") diff --git a/src/Game.cpp b/src/Game.cpp index beb0779..5da49a6 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -776,8 +776,6 @@ namespace ZL void Game::createLocationsStep5() { - - rearmDormOneShotCallbacks(); menuManager.callTaxiFunc = [this]() diff --git a/src/GameState.cpp b/src/GameState.cpp index c0c7624..7bb85bc 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -95,10 +95,12 @@ void GameState::load(const nlohmann::json& in) money = in.value("money", money); // --- Script globals --- + globalInts.clear(); if (in.contains("globalInts") && in["globalInts"].is_object()) { for (const auto& [k, v] : in["globalInts"].items()) globalInts[k] = v.get(); } + globalFloats.clear(); if (in.contains("globalFloats") && in["globalFloats"].is_object()) { for (const auto& [k, v] : in["globalFloats"].items()) globalFloats[k] = v.get(); diff --git a/src/Location.cpp b/src/Location.cpp index ef6cf31..26366e6 100644 --- a/src/Location.cpp +++ b/src/Location.cpp @@ -2071,6 +2071,15 @@ namespace ZL { state.taxiCar.waypoints = state.taxiCarWaypoints; state.taxiCar.mode = NpcCar::Mode::FOLLOW_WAYPOINTS; + + // For the dorm - disable trigger zone because the player already ordered taxi + for (auto& tz : triggerZones) { + if (tz.id == "taxi_zone001") { + tz.enabled = false; + break; + } + } + } // ---- Save / Load ---- diff --git a/src/ScriptEngine.cpp b/src/ScriptEngine.cpp index 22ca1af..db666d2 100644 --- a/src/ScriptEngine.cpp +++ b/src/ScriptEngine.cpp @@ -5,6 +5,7 @@ #include #include "Location.h" #include "items/ItemRegistry.h" +#include "utils/Utils.h" #define SOL_ALL_SAFETIES_ON 1 #include @@ -87,6 +88,26 @@ namespace ZL { lua.open_libraries(sol::lib::base, sol::lib::math, sol::lib::string, sol::lib::table); + + // --- Переопределение функции print --- + lua.set_function("print", [](sol::this_state ts, sol::variadic_args va) { + sol::state_view lua_view(ts); + sol::function tostring = lua_view["tostring"]; + + auto& log = logger(); + log << "[script] "; + + bool first = true; + for (auto arg : va) { + if (!first) log << "\t"; // Разделяем аргументы табуляцией, как в стандартном Lua print + std::string str = tostring(arg); + log << str; + first = false; + } + log << std::endl; + }); + // ------------------------------------- + auto api = lua.create_named_table("game_api"); // npc_walk_to(index, x, y, z [, on_arrived]) diff --git a/src/main.cpp b/src/main.cpp index 7f663af..9360b7d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -262,7 +262,10 @@ int main(int argc, char* argv[]) { try { readSettings(); - ZL::initLogger(); + if (ZL::Environment::enableLogging) + { + ZL::initLogger(); + } ZL::logger() << "Log started!" << std::endl; diff --git a/src/utils/Utils.cpp b/src/utils/Utils.cpp index 20ad5d4..642a97f 100644 --- a/src/utils/Utils.cpp +++ b/src/utils/Utils.cpp @@ -364,21 +364,21 @@ namespace ZL // --- Инфраструктура для дублирования вывода (Tee-поток) --- class TeeBuffer : public std::streambuf { - std::streambuf* out1; - std::streambuf* out2; + std::streambuf* out1; // Буфер cout + std::streambuf* out2; // Буфер файла protected: int overflow(int c) override { if (c != EOF) { - int r1 = out1->sputc(c); + out1->sputc(c); // Игнорируем потенциальный EOF от отключенной консоли int r2 = out2->sputc(c); - if (r1 == EOF || r2 == EOF) return EOF; + if (r2 == EOF) return EOF; // Возвращаем ошибку только если сломалась запись в файл } return c; } int sync() override { - int r1 = out1->pubsync(); + out1->pubsync(); // Игнорируем ошибку сброса консоли int r2 = out2->pubsync(); - return (r1 == -1 || r2 == -1) ? -1 : 0; + return (r2 == -1) ? -1 : 0; // Сообщаем об ошибке потоку только если не удалось сбросить в файл } public: TeeBuffer(std::streambuf* sb1, std::streambuf* sb2) : out1(sb1), out2(sb2) {}