working on the game

This commit is contained in:
Vladislav Khorev 2026-04-19 23:25:18 +03:00
parent 3622f2b888
commit fd098e8346
11 changed files with 224 additions and 11 deletions

View File

@ -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"
}
}
]
}
}

View File

@ -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"
},
{

BIN
resources/e/car002_police.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/e/car003_police.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/e/menu/hint1.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/e/menu/hint2.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/e/menu/hint3.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/loading.png (Stored with Git LFS)

Binary file not shown.

View File

@ -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;

View File

@ -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<Texture>(CreateTextureDataFromPng("resources/e/car_black001.png", CONST_ZIP_FILE));
npcCar.texture = std::make_shared<Texture>(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<float>(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;
}

View File

@ -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;