Fixing minor bugs
This commit is contained in:
parent
c7b3f04cd4
commit
3495d28edf
@ -38,27 +38,6 @@
|
|||||||
"positionZ": -7.9,
|
"positionZ": -7.9,
|
||||||
"scale": 3.0,
|
"scale": 3.0,
|
||||||
"interactive": false
|
"interactive": false
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "medik",
|
|
||||||
"texturePath": "resources/w/red.png",
|
|
||||||
"meshPath": "resources/w/firebox.txt",
|
|
||||||
"rotationX": 0.0,
|
|
||||||
"rotationY": -1.5707963267948966,
|
|
||||||
"rotationZ": 0.0,
|
|
||||||
"positionX": 0.0,
|
|
||||||
"positionY": 0.0,
|
|
||||||
"positionZ": 4.0,
|
|
||||||
"scale": 1.0,
|
|
||||||
"interactive": true,
|
|
||||||
"item": {
|
|
||||||
"id": "health_potion",
|
|
||||||
"name": "Health Potion",
|
|
||||||
"description": "Restores 50 HP",
|
|
||||||
"icon": "resources/w/red.png",
|
|
||||||
"radius": 2.0
|
|
||||||
},
|
|
||||||
"activateFunction" : "on_health_pickup"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -19,6 +19,7 @@
|
|||||||
"positionX": 2.95,
|
"positionX": 2.95,
|
||||||
"positionY": 0.0,
|
"positionY": 0.0,
|
||||||
"positionZ": 16.65,
|
"positionZ": 16.65,
|
||||||
|
"facingAngle" : 3.141592,
|
||||||
"walkSpeed": 1.5,
|
"walkSpeed": 1.5,
|
||||||
"rotationSpeed": 8.0,
|
"rotationSpeed": 8.0,
|
||||||
"modelScale": 0.0001,
|
"modelScale": 0.0001,
|
||||||
@ -50,6 +51,7 @@
|
|||||||
"positionX": 19.5,
|
"positionX": 19.5,
|
||||||
"positionY": 0.0,
|
"positionY": 0.0,
|
||||||
"positionZ": 32.0,
|
"positionZ": 32.0,
|
||||||
|
"facingAngle" : 3.141592,
|
||||||
"walkSpeed": 1.5,
|
"walkSpeed": 1.5,
|
||||||
"rotationSpeed": 8.0,
|
"rotationSpeed": 8.0,
|
||||||
"modelScale": 0.0001,
|
"modelScale": 0.0001,
|
||||||
@ -76,6 +78,7 @@
|
|||||||
"positionX": -1.94774,
|
"positionX": -1.94774,
|
||||||
"positionY": 0.0,
|
"positionY": 0.0,
|
||||||
"positionZ": 16.2712,
|
"positionZ": 16.2712,
|
||||||
|
"facingAngle" : 3.141592,
|
||||||
"walkSpeed": 1.5,
|
"walkSpeed": 1.5,
|
||||||
"rotationSpeed": 8.0,
|
"rotationSpeed": 8.0,
|
||||||
"modelScale": 0.001,
|
"modelScale": 0.001,
|
||||||
|
|||||||
BIN
resources/w/gg/avatar_unknown.png
(Stored with Git LFS)
Normal file
BIN
resources/w/gg/avatar_unknown.png
(Stored with Git LFS)
Normal file
Binary file not shown.
30
src/Game.cpp
30
src/Game.cpp
@ -169,6 +169,8 @@ namespace ZL
|
|||||||
params1.scriptPath = "resources/start.lua";
|
params1.scriptPath = "resources/start.lua";
|
||||||
params1.playerPosition = Eigen::Vector3f::Zero();
|
params1.playerPosition = Eigen::Vector3f::Zero();
|
||||||
params1.ghostPosition = Eigen::Vector3f(0.f, 0.f, -20.f);
|
params1.ghostPosition = Eigen::Vector3f(0.f, 0.f, -20.f);
|
||||||
|
params1.teleportPosition = Eigen::Vector3f(-2.03001f, 0.f, -4.95618f);
|
||||||
|
params1.teleportRadius = 1.5f;
|
||||||
|
|
||||||
location1 = std::make_shared<Location>(renderer, inventory);
|
location1 = std::make_shared<Location>(renderer, inventory);
|
||||||
location1->setup(params1);
|
location1->setup(params1);
|
||||||
@ -184,11 +186,35 @@ namespace ZL
|
|||||||
|
|
||||||
params2.npcsJsonPath = "resources/config2/npcs2.json";
|
params2.npcsJsonPath = "resources/config2/npcs2.json";
|
||||||
params2.ghostPosition = Eigen::Vector3f(700.f, 0.f, 700.f);
|
params2.ghostPosition = Eigen::Vector3f(700.f, 0.f, 700.f);
|
||||||
|
params2.teleportPosition = Eigen::Vector3f(-6.45, 0.0, 7.82);
|
||||||
|
params2.teleportRadius = 1.5f;
|
||||||
location2 = std::make_shared<Location>(renderer, inventory);
|
location2 = std::make_shared<Location>(renderer, inventory);
|
||||||
location2->setup(params2);
|
location2->setup(params2);
|
||||||
|
|
||||||
currentLocation = location1;
|
// Teleport callbacks: stepping into a location's zone hands the player
|
||||||
|
// to the other location at *its* teleport position. We pre-arm the
|
||||||
|
// destination's playerInTeleportZone so the player must walk out and
|
||||||
|
// back in before they can teleport again.
|
||||||
|
location1->onTeleport = [this]() {
|
||||||
|
std::cout << "[TELEPORT] location 1 -> location 2" << std::endl;
|
||||||
|
currentLocation = location2;
|
||||||
|
if (currentLocation->player) {
|
||||||
|
currentLocation->player->position = currentLocation->teleportPosition;
|
||||||
|
currentLocation->player->setTarget(currentLocation->teleportPosition);
|
||||||
|
}
|
||||||
|
currentLocation->playerInTeleportZone = true;
|
||||||
|
};
|
||||||
|
location2->onTeleport = [this]() {
|
||||||
|
std::cout << "[TELEPORT] location 2 -> location 1" << std::endl;
|
||||||
|
currentLocation = location1;
|
||||||
|
if (currentLocation->player) {
|
||||||
|
currentLocation->player->position = currentLocation->teleportPosition;
|
||||||
|
currentLocation->player->setTarget(currentLocation->teleportPosition);
|
||||||
|
}
|
||||||
|
currentLocation->playerInTeleportZone = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
currentLocation = location2;
|
||||||
|
|
||||||
std::cout << "Load resurces step 5" << std::endl;
|
std::cout << "Load resurces step 5" << std::endl;
|
||||||
|
|
||||||
|
|||||||
@ -141,6 +141,35 @@ namespace ZL
|
|||||||
|
|
||||||
npcs.push_back(std::move(npc02));
|
npcs.push_back(std::move(npc02));
|
||||||
|
|
||||||
|
// Teleport zone visuals: an upward fountain of sparks parked at the
|
||||||
|
// teleport position, so the player can spot the zone from a distance.
|
||||||
|
teleportPosition = params.teleportPosition;
|
||||||
|
teleportRadius = params.teleportRadius;
|
||||||
|
if (teleportRadius > 0.0f) {
|
||||||
|
teleportSparks = std::make_unique<SparkEmitter>();
|
||||||
|
std::vector<Vector3f> teleportEmitPoints;
|
||||||
|
teleportEmitPoints.push_back(Vector3f{ teleportPosition.x(), teleportPosition.y(), teleportPosition.z() });
|
||||||
|
teleportSparks->setEmissionPoints(teleportEmitPoints);
|
||||||
|
teleportSparks->setTexture(sparkTexture);
|
||||||
|
teleportSparks->setEmissionRate(50.0f);
|
||||||
|
teleportSparks->setMaxParticles(80);
|
||||||
|
teleportSparks->setParticleSize(0.15f);
|
||||||
|
teleportSparks->setBiasX(0.0f);
|
||||||
|
teleportSparks->setEmissionDirection(Vector3f{ 0.0f, 1.0f, 0.0f });
|
||||||
|
teleportSparks->setSpeedRange(0.5f, 1.0f);
|
||||||
|
teleportSparks->setZSpeedRange(0.5f, 1.5f);
|
||||||
|
teleportSparks->setScaleRange(0.5f, 1.0f);
|
||||||
|
teleportSparks->setLifeTimeRange(1500.0f, 2500.0f);
|
||||||
|
teleportSparks->setUseWorldSpace(true);
|
||||||
|
teleportSparks->markConfigured();
|
||||||
|
|
||||||
|
// If the player happens to spawn already inside the zone, treat them
|
||||||
|
// as in-zone so they don't immediately teleport on the first update.
|
||||||
|
if (player && (player->position - teleportPosition).norm() <= teleportRadius) {
|
||||||
|
playerInTeleportZone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create shadow map (2048x2048, ortho size 40, near 0.1, far 100)
|
// Create shadow map (2048x2048, ortho size 40, near 0.1, far 100)
|
||||||
shadowMap = std::make_unique<ShadowMap>(2048, 40.0f, 0.1f, 100.0f);
|
shadowMap = std::make_unique<ShadowMap>(2048, 40.0f, 0.1f, 100.0f);
|
||||||
shadowMap->setLightDirection(Eigen::Vector3f(-0.5f, -1.0f, -0.3f));
|
shadowMap->setLightDirection(Eigen::Vector3f(-0.5f, -1.0f, -0.3f));
|
||||||
@ -403,10 +432,15 @@ namespace ZL
|
|||||||
const Eigen::Matrix4f currentView = renderer.GetCurrentModelViewMatrix();
|
const Eigen::Matrix4f currentView = renderer.GetCurrentModelViewMatrix();
|
||||||
if (player) player->prepareHitSparksForDraw(currentView);
|
if (player) player->prepareHitSparksForDraw(currentView);
|
||||||
for (auto& npc : npcs) npc->prepareHitSparksForDraw(currentView);
|
for (auto& npc : npcs) npc->prepareHitSparksForDraw(currentView);
|
||||||
|
if (teleportSparks) teleportSparks->prepareForDraw(currentView);
|
||||||
|
|
||||||
if (player) player->draw(renderer);
|
if (player) player->draw(renderer);
|
||||||
for (auto& npc : npcs) npc->draw(renderer);
|
for (auto& npc : npcs) npc->draw(renderer);
|
||||||
|
|
||||||
|
if (teleportSparks) {
|
||||||
|
teleportSparks->draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SHOW_PATH
|
#ifdef SHOW_PATH
|
||||||
drawDebugNavigation();
|
drawDebugNavigation();
|
||||||
#endif
|
#endif
|
||||||
@ -592,11 +626,16 @@ namespace ZL
|
|||||||
|
|
||||||
if (player) player->prepareHitSparksForDraw(cameraViewMatrix);
|
if (player) player->prepareHitSparksForDraw(cameraViewMatrix);
|
||||||
for (auto& npc : npcs) npc->prepareHitSparksForDraw(cameraViewMatrix);
|
for (auto& npc : npcs) npc->prepareHitSparksForDraw(cameraViewMatrix);
|
||||||
|
if (teleportSparks) teleportSparks->prepareForDraw(cameraViewMatrix);
|
||||||
|
|
||||||
if (player) player->drawWithShadow(renderer, lightFromCamera, shadowMap->getDepthTexture(), lightDirCamera);
|
if (player) player->drawWithShadow(renderer, lightFromCamera, shadowMap->getDepthTexture(), lightDirCamera);
|
||||||
CheckGlError(__FILE__, __LINE__);
|
CheckGlError(__FILE__, __LINE__);
|
||||||
|
|
||||||
for (auto& npc : npcs) npc->drawWithShadow(renderer, lightFromCamera, shadowMap->getDepthTexture(), lightDirCamera);
|
for (auto& npc : npcs) npc->drawWithShadow(renderer, lightFromCamera, shadowMap->getDepthTexture(), lightDirCamera);
|
||||||
|
|
||||||
|
if (teleportSparks) {
|
||||||
|
teleportSparks->draw(renderer, Environment::zoom, Environment::width, Environment::height);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
CheckGlError(__FILE__, __LINE__);
|
CheckGlError(__FILE__, __LINE__);
|
||||||
|
|
||||||
@ -681,6 +720,29 @@ namespace ZL
|
|||||||
targetInteractNpcIndex = -1;
|
targetInteractNpcIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Drive teleport spark animation regardless of whether the zone is armed.
|
||||||
|
if (teleportSparks) {
|
||||||
|
teleportSparks->update(static_cast<float>(delta));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Teleport zone: rising-edge trigger only. The destination location's
|
||||||
|
// callback is responsible for placing the player back inside its own
|
||||||
|
// zone and setting playerInTeleportZone = true so we don't bounce.
|
||||||
|
if (player && onTeleport && teleportRadius > 0.0f) {
|
||||||
|
float distToZone = (player->position - teleportPosition).norm();
|
||||||
|
if (distToZone <= teleportRadius) {
|
||||||
|
if (!playerInTeleportZone) {
|
||||||
|
playerInTeleportZone = true;
|
||||||
|
std::cout << "[TELEPORT] Player entered teleport zone" << std::endl;
|
||||||
|
onTeleport();
|
||||||
|
return; // active location may have changed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
playerInTeleportZone = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Location::handleDown(int64_t fingerId, int eventX, int eventY, int mx, int my)
|
void Location::handleDown(int64_t fingerId, int eventX, int eventY, int mx, int my)
|
||||||
@ -742,7 +804,7 @@ namespace ZL
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (npcIndex != -1) {
|
if (npcIndex != -1 && clickedNpc->hp > 0) {
|
||||||
targetInteractiveObject = nullptr;
|
targetInteractiveObject = nullptr;
|
||||||
|
|
||||||
if (clickedNpc->canAttack) {
|
if (clickedNpc->canAttack) {
|
||||||
|
|||||||
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include "ScriptEngine.h"
|
#include "ScriptEngine.h"
|
||||||
#include "dialogue/DialogueSystem.h"
|
#include "dialogue/DialogueSystem.h"
|
||||||
|
#include "SparkEmitter.h"
|
||||||
|
#include <functional>
|
||||||
namespace ZL
|
namespace ZL
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -25,6 +27,8 @@ namespace ZL
|
|||||||
std::string scriptPath;
|
std::string scriptPath;
|
||||||
Eigen::Vector3f playerPosition = Eigen::Vector3f::Zero();
|
Eigen::Vector3f playerPosition = Eigen::Vector3f::Zero();
|
||||||
Eigen::Vector3f ghostPosition = Eigen::Vector3f::Zero();
|
Eigen::Vector3f ghostPosition = Eigen::Vector3f::Zero();
|
||||||
|
Eigen::Vector3f teleportPosition = Eigen::Vector3f::Zero();
|
||||||
|
float teleportRadius = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Location
|
class Location
|
||||||
@ -64,6 +68,15 @@ namespace ZL
|
|||||||
ScriptEngine scriptEngine;
|
ScriptEngine scriptEngine;
|
||||||
Dialogue::DialogueSystem dialogueSystem;
|
Dialogue::DialogueSystem dialogueSystem;
|
||||||
|
|
||||||
|
// Teleport zone: when the player crosses into the radius of teleportPosition,
|
||||||
|
// onTeleport() is invoked once. Re-triggering requires leaving the zone first
|
||||||
|
// (rising-edge detection via playerInTeleportZone).
|
||||||
|
Eigen::Vector3f teleportPosition = Eigen::Vector3f::Zero();
|
||||||
|
float teleportRadius = 0.0f;
|
||||||
|
bool playerInTeleportZone = false;
|
||||||
|
std::function<void()> onTeleport;
|
||||||
|
std::unique_ptr<SparkEmitter> teleportSparks;
|
||||||
|
|
||||||
#ifdef SHOW_PATH
|
#ifdef SHOW_PATH
|
||||||
std::vector<VertexRenderStruct> debugNavMeshes;
|
std::vector<VertexRenderStruct> debugNavMeshes;
|
||||||
void buildDebugNavMeshes();
|
void buildDebugNavMeshes();
|
||||||
|
|||||||
@ -112,7 +112,7 @@ void DialogueOverlay::drawDialogue(Renderer& renderer, const PresentationModel&
|
|||||||
// const float H = Environment::projectionHeight;
|
// const float H = Environment::projectionHeight;
|
||||||
|
|
||||||
const UiRect portraitRect{ 24.0f, 24.0f, 182.0f, 182.0f };
|
const UiRect portraitRect{ 24.0f, 24.0f, 182.0f, 182.0f };
|
||||||
const UiRect textboxRect{ 220.0f, 24.0f, max(200.0f, W - 244.0f), 182.0f };
|
const UiRect textboxRect{ 220.0f, 24.0f, max(300.0f, W - 244.0f), 182.0f };
|
||||||
lastDialogueAdvanceRect = { portraitRect.x, portraitRect.y, textboxRect.x + textboxRect.w - portraitRect.x, textboxRect.h };
|
lastDialogueAdvanceRect = { portraitRect.x, portraitRect.y, textboxRect.x + textboxRect.w - portraitRect.x, textboxRect.h };
|
||||||
lastCutsceneAdvanceRect = {};
|
lastCutsceneAdvanceRect = {};
|
||||||
cutsceneAdvanceEnabled = false;
|
cutsceneAdvanceEnabled = false;
|
||||||
|
|||||||
@ -368,6 +368,8 @@ namespace ZL {
|
|||||||
data.modelCorrectionRotY = item.value("modelCorrectionRotY", 0.0f) * static_cast<float>(M_PI) / 180.0f;
|
data.modelCorrectionRotY = item.value("modelCorrectionRotY", 0.0f) * static_cast<float>(M_PI) / 180.0f;
|
||||||
data.modelCorrectionRotZ = item.value("modelCorrectionRotZ", 0.0f) * static_cast<float>(M_PI) / 180.0f;
|
data.modelCorrectionRotZ = item.value("modelCorrectionRotZ", 0.0f) * static_cast<float>(M_PI) / 180.0f;
|
||||||
|
|
||||||
|
data.facingAngle = item.value("facingAngle", 0.0f);
|
||||||
|
|
||||||
// Load gift data if available
|
// Load gift data if available
|
||||||
if (item.contains("gift") && item["gift"].is_object()) {
|
if (item.contains("gift") && item["gift"].is_object()) {
|
||||||
const auto& giftData = item["gift"];
|
const auto& giftData = item["gift"];
|
||||||
@ -471,6 +473,7 @@ namespace ZL {
|
|||||||
npc->rotationSpeed = npcData.rotationSpeed;
|
npc->rotationSpeed = npcData.rotationSpeed;
|
||||||
npc->modelScale = npcData.modelScale;
|
npc->modelScale = npcData.modelScale;
|
||||||
npc->position = Eigen::Vector3f(npcData.positionX, npcData.positionY, npcData.positionZ);
|
npc->position = Eigen::Vector3f(npcData.positionX, npcData.positionY, npcData.positionZ);
|
||||||
|
npc->facingAngle = npcData.facingAngle;
|
||||||
npc->interactionRadius = npcData.interactionRadius;
|
npc->interactionRadius = npcData.interactionRadius;
|
||||||
|
|
||||||
// Set NPC metadata
|
// Set NPC metadata
|
||||||
|
|||||||
@ -60,6 +60,7 @@ namespace ZL {
|
|||||||
float modelCorrectionRotX = 0.0f;
|
float modelCorrectionRotX = 0.0f;
|
||||||
float modelCorrectionRotY = 0.0f;
|
float modelCorrectionRotY = 0.0f;
|
||||||
float modelCorrectionRotZ = 0.0f;
|
float modelCorrectionRotZ = 0.0f;
|
||||||
|
float facingAngle = 0.0f;
|
||||||
GiftData gift;
|
GiftData gift;
|
||||||
float interactionRadius = 0.0f;
|
float interactionRadius = 0.0f;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user