From fd098e83468453ed9998e116c0fa6e1874253812 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sun, 19 Apr 2026 23:25:18 +0300 Subject: [PATCH] working on the game --- resources/config2/menu_hint1.json | 26 +++++++ resources/dialogue/sample_dialogues.json | 88 +++++++++++++++++++++++- resources/e/car002_police.png | 3 + resources/e/car003_police.png | 3 + resources/e/menu/hint1.png | 3 + resources/e/menu/hint2.png | 3 + resources/e/menu/hint3.png | 3 + resources/loading.png | 4 +- src/Game.cpp | 11 ++- src/Location.cpp | 87 +++++++++++++++++++++-- src/Location.h | 4 ++ 11 files changed, 224 insertions(+), 11 deletions(-) create mode 100644 resources/config2/menu_hint1.json create mode 100644 resources/e/car002_police.png create mode 100644 resources/e/car003_police.png create mode 100644 resources/e/menu/hint1.png create mode 100644 resources/e/menu/hint2.png create mode 100644 resources/e/menu/hint3.png diff --git a/resources/config2/menu_hint1.json b/resources/config2/menu_hint1.json new file mode 100644 index 0000000..0051d18 --- /dev/null +++ b/resources/config2/menu_hint1.json @@ -0,0 +1,26 @@ +{ + "root": { + "type": "LinearLayout", + "orientation": "vertical", + "horizontal_align": "center", + "vertical_align": "center", + "spacing": 20, + "x": 0, + "y": 0, + "width": "match_parent", + "height": "match_parent", + "children": [ + { + "type": "Button", + "name": "backButton", + "width": 512, + "height": 256, + "textures": { + "normal": "resources/e/menu/hint1.png", + "hover": "resources/e/menu/hint1.png", + "pressed": "resources/e/menu/hint1.png" + } + } + ] + } +} \ No newline at end of file diff --git a/resources/dialogue/sample_dialogues.json b/resources/dialogue/sample_dialogues.json index 2d5fe1c..cc5cf2b 100644 --- a/resources/dialogue/sample_dialogues.json +++ b/resources/dialogue/sample_dialogues.json @@ -255,9 +255,17 @@ { "id": "line_1", "type": "Line", - "speaker": "Алексей", + "speaker": "Алтынай", "portrait": "resources/girlfriend.png", "text": "До Таласской области осталось ехать примерно 7 километров.", + "next": "line_2" + }, + { + "id": "line_2", + "type": "Line", + "speaker": "Алексей", + "portrait": "resources/hero.png", + "text": "Этот туман меня пугает.", "next": "end_1" }, { @@ -273,9 +281,17 @@ { "id": "line_1", "type": "Line", - "speaker": "Алексей", + "speaker": "Алтынай", "portrait": "resources/girlfriend.png", "text": "До Таласской области осталось ехать примерно 5 километров.", + "next": "line_2" + }, + { + "id": "line_2", + "type": "Line", + "speaker": "Алексей", + "portrait": "resources/hero.png", + "text": "У меня нехорошие предчувствия...", "next": "end_1" }, { @@ -294,6 +310,74 @@ "speaker": "Алтынай", "portrait": "resources/girlfriend.png", "text": "До Таласской области осталось ехать примерно 2 километра.", + "next": "line_2" + }, + { + "id": "line_2", + "type": "Line", + "speaker": "Алтынай", + "portrait": "resources/girlfriend.png", + "text": "Еще чуть-чуть, поднажми!", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] + }, + { + "id": "driving_dialogue_chase1", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Алтынай", + "portrait": "resources/girlfriend.png", + "text": "Черт, нас преследует черная машина!", + "next": "line_2" + }, + { + "id": "line_2", + "type": "Line", + "speaker": "Алтынай", + "portrait": "resources/girlfriend.png", + "text": "Это бандиты Нурланбая! Алексей, быстрее!", + "next": "end_1" + }, + { + "id": "end_1", + "type": "End" + } + ] + }, + { + "id": "driving_dialogue_final", + "start": "line_1", + "nodes": [ + { + "id": "line_1", + "type": "Line", + "speaker": "Алтынай", + "portrait": "resources/girlfriend.png", + "text": "Смотри, таласские менты их стопанули!", + "next": "line_2" + }, + { + "id": "line_2", + "type": "Line", + "speaker": "Алтынай", + "portrait": "resources/girlfriend.png", + "text": "Поздравляю Алексей, нам удалось сбежать от бандитов!", + "next": "line_3" + }, + { + "id": "line_3", + "type": "Line", + "speaker": "Алтынай", + "portrait": "resources/girlfriend.png", + "text": "Ты мой герой, спасибо тебе за помощь!", "next": "end_1" }, { diff --git a/resources/e/car002_police.png b/resources/e/car002_police.png new file mode 100644 index 0000000..d90ca5c --- /dev/null +++ b/resources/e/car002_police.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fea3a8663d45f08403221410bb35f63074871e0be4aeb4871ff500d9a28ab0d3 +size 131878 diff --git a/resources/e/car003_police.png b/resources/e/car003_police.png new file mode 100644 index 0000000..c611309 --- /dev/null +++ b/resources/e/car003_police.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:584413eb18c5196e7e63c2c3057bcc2dabbfd86360a62b9e193f3887524e9dbe +size 130613 diff --git a/resources/e/menu/hint1.png b/resources/e/menu/hint1.png new file mode 100644 index 0000000..7f8fec9 --- /dev/null +++ b/resources/e/menu/hint1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d302f9d26d7e78c49eba5e484432af5d92e0de92f2c6d954b605415d95577c7 +size 17596 diff --git a/resources/e/menu/hint2.png b/resources/e/menu/hint2.png new file mode 100644 index 0000000..2e0f715 --- /dev/null +++ b/resources/e/menu/hint2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4c72ca78cc36f8598fe82f35d28ad2aa3c502bb573494b3c9240ca617bf90d0 +size 28059 diff --git a/resources/e/menu/hint3.png b/resources/e/menu/hint3.png new file mode 100644 index 0000000..0ebe4d7 --- /dev/null +++ b/resources/e/menu/hint3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41756486b3b30af445f7e8630b033be22d49768f7f2600f108fe4bc811aa6c71 +size 37881 diff --git a/resources/loading.png b/resources/loading.png index 3ce1a98..3d467ae 100644 --- a/resources/loading.png +++ b/resources/loading.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:61036ed35e803aa301c605f226189ab86a9d2af65168535197a0b4b700effa3a -size 45484 +oid sha256:b4bf28f67eb6bfe976ca3b954bb85b5340721e43c1708f4df857d516a58d5d13 +size 61722 diff --git a/src/Game.cpp b/src/Game.cpp index d1529fb..0de18a9 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -560,8 +560,8 @@ namespace ZL else if (event.wheel.y < 0) { Environment::zoom += zoomstep; } - if (Environment::zoom < zoomstep) { - Environment::zoom = zoomstep; + if (Environment::zoom < 4.f) { + Environment::zoom = 4.f; } } } @@ -589,7 +589,12 @@ namespace ZL break; } case SDLK_f: - if (currentLocation) currentLocation->dialogueSystem.startDialogue("dialogue_gas1"); + //if (currentLocation) currentLocation->dialogueSystem.startDialogue("dialogue_gas1"); + /*menuManager.uiManager.loadFromFile("resources/config2/help.json", renderer, CONST_ZIP_FILE); + + menuManager.uiManager.setButtonCallback("backButton", [this](const std::string&) { + menuManager.uiManager.clearMenuStack(); + });*/ break; diff --git a/src/Location.cpp b/src/Location.cpp index ec19d40..9409295 100644 --- a/src/Location.cpp +++ b/src/Location.cpp @@ -421,7 +421,7 @@ void Location::setup() carWheelMesh.data.RotateByMatrix(Eigen::Quaternionf(Eigen::AngleAxisf(M_PI * 0.5, Eigen::Vector3f::UnitY())).toRotationMatrix()); carWheelMesh.RefreshVBO(); - npcCar.texture = std::make_shared(CreateTextureDataFromPng("resources/e/car_black001.png", CONST_ZIP_FILE)); + npcCar.texture = std::make_shared(CreateTextureDataFromPng("resources/e/car003_police.png", CONST_ZIP_FILE)); //npcCar.position = carPosition + Eigen::Vector3f(0, 0.f, 14.f);//Eigen::Vector3f(-12.f, 0.f, 8.f); npcCar.rotation = 0.f; npcCar.mode = NpcCar::Mode::NONE; @@ -433,8 +433,9 @@ void Location::setup() npcBanditCar.mode = NpcCar::Mode::NONE; npcBanditCar.maxSpeed = 26.0f; npcBanditCar.maxReverseSpeed = 8.0f; - npcBanditCar.followMinDistance = 10.5f; - npcBanditCar.followMaxDistance = 12.5f; + npcBanditCar.followMinDistance = 10.f; + npcBanditCar.followMaxDistance = 11.5f; + npcBanditCar.position = Vector3f(-1000, 0, -1000); /*npcCar.mode = NpcCar::Mode::FOLLOW_WAYPOINTS; npcCar.waypoints = { @@ -1409,6 +1410,26 @@ void Location::setup() policeDrivingDialogueTimer = 8.0f; } } + + // Ramp the chase: every meter the player puts down while being + // followed makes the police slightly faster and trims the gap + // they want to keep. Eventually the gap hits zero, the cop + // rams the player car and the run ends in a crash. + const float chaseDt = static_cast(delta) / 1000.0f; + policeChaseDistance += std::abs(carVelocity) * chaseDt; + + constexpr float crashDistance = 2000.0f; + constexpr float baseSpeed = 24.0f; + constexpr float peakSpeed = 30.0f; + constexpr float baseFollowMin = 15.0f; + constexpr float baseFollowMax = 25.0f; + constexpr float crashFollowMin = 0.0f; + constexpr float crashFollowMax = 4.0f; + + const float t = min(1.0f, policeChaseDistance / crashDistance); + npcCar.maxSpeed = baseSpeed + (peakSpeed - baseSpeed) * t; + npcCar.followMinDistance = baseFollowMin + (crashFollowMin - baseFollowMin) * t; + npcCar.followMaxDistance = baseFollowMax + (crashFollowMax - baseFollowMax) * t; } } @@ -1626,7 +1647,8 @@ void Location::setup() // spawn the NPC (police) car at its staged position. Fires once. if (dialoguePhone1Finished && !npcCarSpawnedAfterPhone) { if (carPosition.z() > -350.f && carPosition.z() < -340.f) { - npcCar.position = Eigen::Vector3f(9.f, 0.f, -325.f); + npcCar.position = Eigen::Vector3f(9.f, 0.f, -480.f); + npcCar.mode = NpcCar::Mode::NONE_STAY; npcCarSpawnedAfterPhone = true; } } @@ -1680,6 +1702,18 @@ void Location::setup() } } + // Once the bandit car is within 100 m of the player's car, the chase + // barb plays — fires exactly once. + if (npcBanditCarSpawned && !dialoguePlayedDrivingChase1 && !dialogueSystem.isActive()) { + Eigen::Vector3f delta = npcBanditCar.position - carPosition; + delta.y() = 0.f; + if (delta.norm() < 100.0f) { + if (dialogueSystem.startDialogue("driving_dialogue_chase1")) { + dialoguePlayedDrivingChase1 = true; + } + } + } + // Once the bandit car is alongside the player and the player is on foot, // the bandit hops out and the dialog plays. Fires exactly once. if (npcBanditCarSpawned && !banditExitedNpcBanditCar && bandit && player && !inCar) { @@ -1713,6 +1747,45 @@ void Location::setup() } } } + + // --- Final ambush: re-spawn the police car after the distance-0 line --- + // + // Once the distance-0 dialogue has finished, the police car is parked + // 50 m ahead of the player and stays put — unlike the post-phone spawn + // it never enters FOLLOW_PLAYER. The bandit car keeps chasing as + // before; when it reaches the parked police car, the chase ends with + // the final driving dialogue and both cars stay in NONE_STAY. + if (dialoguePlayedDistance0 + && !npcCarSpawnedAfterDistance0 + && !dialogueSystem.isActive()) + { + const Eigen::Vector3f anchor = inCar + ? carPosition + : (player ? player->position : Eigen::Vector3f::Zero()); + npcCar.position = Eigen::Vector3f(9.0f, 0.0f, anchor.z() - 250.0f); + npcCar.rotation = 0.f; + npcCar.velocity = 0.f; + npcCar.steeringAngle = 0.f; + npcCar.mode = NpcCar::Mode::NONE_STAY; + npcCarSpawnedAfterDistance0 = true; + } + + if (npcCarSpawnedAfterDistance0 + && npcBanditCarSpawned + && !dialoguePlayedDrivingFinal) + { + Eigen::Vector3f delta = npcBanditCar.position - npcCar.position; + delta.y() = 0.f; + if (delta.norm() < 10.0f && !dialogueSystem.isActive()) { + npcBanditCar.mode = NpcCar::Mode::NONE_STAY; + npcBanditCar.velocity = 0.f; + npcCar.mode = NpcCar::Mode::NONE_STAY; + npcCar.velocity = 0.f; + if (dialogueSystem.startDialogue("driving_dialogue_final")) { + dialoguePlayedDrivingFinal = true; + } + } + } } if (locationId == "default") @@ -2304,10 +2377,16 @@ void Location::setup() dialoguePlayedOffroad = false; dialoguePlayedCrash = false; + policeChaseDistance = 0.f; + playerOnFootSeconds = 0.f; npcBanditCarSpawned = false; dialoguePlayedBandit1 = false; banditExitedNpcBanditCar = false; + dialoguePlayedDrivingChase1 = false; + + npcCarSpawnedAfterDistance0 = false; + dialoguePlayedDrivingFinal = false; std::cout << "[LOCATION] Cleanup complete" << std::endl; } diff --git a/src/Location.h b/src/Location.h index 1c857a3..8928f25 100644 --- a/src/Location.h +++ b/src/Location.h @@ -128,6 +128,8 @@ namespace ZL bool dialoguePlayedDistance5000 = false; bool dialoguePlayedDistance2000 = false; bool dialoguePlayedDistance0 = false; + bool npcCarSpawnedAfterDistance0 = false; + bool dialoguePlayedDrivingFinal = false; bool policeFollow = false; @@ -137,6 +139,7 @@ namespace ZL PoliceEncounterStage policeEncounterStage = PoliceEncounterStage::Idle; bool playerFrozen = false; float policeDrivingDialogueTimer = 8.0f; + float policeChaseDistance = 0.f; bool banditFollowingPlayer = false; bool dialoguePlayedBanditCaught1 = false; @@ -149,6 +152,7 @@ namespace ZL bool npcBanditCarSpawned = false; bool dialoguePlayedBandit1 = false; bool banditExitedNpcBanditCar = false; + bool dialoguePlayedDrivingChase1 = false; bool dialoguePlayedVillageRescue1 = false; bool dialoguePlayedVillageIntro1 = false;