Adding quests

This commit is contained in:
Vladislav Khorev 2026-04-19 09:28:28 +03:00
parent 25bb79fb42
commit 60a1422232
3 changed files with 232 additions and 8 deletions

View File

@ -196,6 +196,167 @@
}
]
},
{
"id": "driving_dialogue_gas_out",
"start": "line_1",
"nodes": [
{
"id": "line_1",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Все, приехали! Бензин закончился!",
"next": "end_1"
},
{
"id": "end_1",
"type": "End"
}
]
},
{
"id": "driving_dialogue_distance7000",
"start": "line_1",
"nodes": [
{
"id": "line_1",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "До Таласской области осталось ехать примерно 7 километров.",
"next": "end_1"
},
{
"id": "end_1",
"type": "End"
}
]
},
{
"id": "driving_dialogue_distance5000",
"start": "line_1",
"nodes": [
{
"id": "line_1",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "До Таласской области осталось ехать примерно 5 километров.",
"next": "end_1"
},
{
"id": "end_1",
"type": "End"
}
]
},
{
"id": "driving_dialogue_distance2000",
"start": "line_1",
"nodes": [
{
"id": "line_1",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "До Таласской области осталось ехать примерно 2 километра.",
"next": "end_1"
},
{
"id": "end_1",
"type": "End"
}
]
},
{
"id": "driving_dialogue_distance0",
"start": "line_1",
"nodes": [
{
"id": "line_1",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Все, мы в Таласской области.",
"next": "line_2"
},
{
"id": "line_2",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Здесь должен быть сигнал, дай мне телефон.",
"next": "line_3"
},
{
"id": "line_3",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Я позвоню дяде.",
"next": "line_4"
},
{
"id": "line_4",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Держи.",
"next": "line_5"
},
{
"id": "line_5",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Ало, Акыл байке! Это Алтынай.",
"next": "line_6"
},{
"id": "line_6",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "У меня проблемы, меня преследуют бандиты.",
"next": "line_7"
},
{
"id": "line_7",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Я сейчас еду с другом в сторону Таласа.",
"next": "line_8"
},
{
"id": "line_8",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Пришли пожалуйста патруль мне на встречу.",
"next": "line_9"
},
{
"id": "line_9",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Белый седан, номер 256.",
"next": "line_10"
},
{
"id": "line_10",
"type": "Line",
"speaker": "Игрок",
"portrait": "resources/w/gg/gg2_s_podsvetkoy5.png",
"text": "Спасибо! Пока!",
"next": "end_1"
},
{
"id": "end_1",
"type": "End"
}
]
},
{
"id": "driving_dialogue_gas1",
"start": "line_1",

View File

@ -128,7 +128,7 @@ void Location::setup()
police->rotationSpeed = 8.0f;
police->modelScale = 0.01f;
police->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
police->position = Vector3f{ 10, -0, 10 };
police->position = Vector3f{ 1000, -0, 10 };
police->setTarget(police->position);
auto banditTexture0 = std::make_shared<Texture>(CreateTextureDataFromPng("resources/e/bandit_packed0_diffuse.png", CONST_ZIP_FILE));
@ -166,7 +166,7 @@ void Location::setup()
std::cout << "[LOCATION] Setting up FOREST location (custom models only)" << std::endl;
carPosition ={ 7, 0, -7 + 200 };
npcCar.position = Vector3f(9, 0, -235);
npcCar.position = Vector3f(9, 0, -335) + Vector3f(1000,0,0);
girlfriend->position = Vector3f{ 5, 0, 0.9 + 200 };
girlfriend->setTarget(girlfriend->position);
@ -1074,7 +1074,7 @@ void Location::setup()
constexpr float offRoadFrictionMultiplier = 4.0f;
const bool offRoad = std::abs(carPosition.x()) > roadHalfWidth;
if (!offRoad) {
if (!offRoad && !carOutOfGas) {
if (keyForward) {
carVelocity += carAcceleration * dt;
}
@ -1164,7 +1164,22 @@ void Location::setup()
}
}
if (!policeFollow && player->position.z() < -240)
// Ran out of gas: far south without having heard the girlfriend's gas
// reminder. Latches the stall, then plays the out-of-gas line once.
if (!carOutOfGas && !dialoguePlayedGas1 && player->position.z() < -300.f) {
carOutOfGas = true;
}
if (carOutOfGas && !dialoguePlayedDrivingGasOut && !dialogueSystem.isActive()) {
if (dialogueSystem.startDialogue("driving_dialogue_gas_out")) {
dialoguePlayedDrivingGasOut = true;
}
}
if (!policeFollow &&
player->position.z() - npcCar.position.z() > -10.f
&& player->position.z() < npcCar.position.z()
&& npcCar.position.x()<900
&& policeEncounterStage != PoliceEncounterStage::Done)
{
policeFollow = true;
npcCar.mode = NpcCar::Mode::FOLLOW_PLAYER;
@ -1208,6 +1223,33 @@ void Location::setup()
updateNpcCar(delta);
// Track remaining driving distance toward -Z. Computed from this frame's
// real movement (captured before the tile-shift below), so the teleport
// never contributes to the count.
if (player) {
distanceRemaining += player->position.z() - playerPosBefore.z();
}
if (!dialoguePlayedDistance7000 && distanceRemaining < 7000.f/5.f && !dialogueSystem.isActive()) {
if (dialogueSystem.startDialogue("driving_dialogue_distance7000")) {
dialoguePlayedDistance7000 = true;
}
}
if (!dialoguePlayedDistance5000 && distanceRemaining < 5000.f/5.f && !dialogueSystem.isActive()) {
if (dialogueSystem.startDialogue("driving_dialogue_distance5000")) {
dialoguePlayedDistance5000 = true;
}
}
if (!dialoguePlayedDistance2000 && distanceRemaining < 2000.f/5.f && !dialogueSystem.isActive()) {
if (dialogueSystem.startDialogue("driving_dialogue_distance2000")) {
dialoguePlayedDistance2000 = true;
}
}
if (!dialoguePlayedDistance0 && distanceRemaining < 0.f && !dialogueSystem.isActive()) {
if (dialogueSystem.startDialogue("driving_dialogue_distance0")) {
dialoguePlayedDistance0 = true;
}
}
{
constexpr float tileSize = 100.0f;
constexpr float teleportThreshold = tileSize * 3.5f;
@ -1232,7 +1274,7 @@ void Location::setup()
player->setTarget(player->position);
player->clearPath();
}
if (npcCar.mode == NpcCar::Mode::FOLLOW_PLAYER) {
if (npcCar.mode == NpcCar::Mode::FOLLOW_PLAYER || npcCar.mode == NpcCar::Mode::NONE_STAY) {
npcCar.position += shift;
}
}
@ -1307,7 +1349,7 @@ void Location::setup()
}
if (!police) {
policeFollow = false;
npcCar.mode = NpcCar::Mode::NONE;
npcCar.mode = NpcCar::Mode::NONE_STAY;
policeEncounterStage = PoliceEncounterStage::Done;
}
}
@ -1320,11 +1362,22 @@ void Location::setup()
const float dx = carPosition.x() - gasStationPos.x();
const float dz = carPosition.z() - gasStationPos.z();
if (std::hypot(dx, dz) > minDistance) {
if (dialogueSystem.startDialogue("dialogue_phone1")) {
if (dialogueSystem.startDialogue("dialogue_phone1", [this]() {
dialoguePhone1Finished = true;
})) {
dialoguePlayedPhone1 = true;
}
}
}
// After the phone dialogue, once the player's car enters the ambush zone,
// 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);
npcCarSpawnedAfterPhone = true;
}
}
}
void Location::updateNpcCar(int64_t deltaMs)

View File

@ -15,7 +15,7 @@ namespace ZL
struct NpcCar
{
enum class Mode { FOLLOW_WAYPOINTS, FOLLOW_PLAYER, NONE };
enum class Mode { FOLLOW_WAYPOINTS, FOLLOW_PLAYER, NONE, NONE_STAY };
Eigen::Vector3f position = Eigen::Vector3f::Zero();
float rotation = 0.f;
@ -113,6 +113,16 @@ namespace ZL
bool dialoguePlayedGas1 = false;
bool dialoguePlayedGirlfriend1 = false;
bool dialoguePlayedPhone1 = false;
bool dialoguePhone1Finished = false;
bool npcCarSpawnedAfterPhone = false;
bool carOutOfGas = false;
bool dialoguePlayedDrivingGasOut = false;
float distanceRemaining = 2000.f;//10000.0f;
bool dialoguePlayedDistance7000 = false;
bool dialoguePlayedDistance5000 = false;
bool dialoguePlayedDistance2000 = false;
bool dialoguePlayedDistance0 = false;
bool policeFollow = false;