From 570f05128180a1e32e55bcd886da59deb14fba76 Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Tue, 27 Oct 2026 20:24:33 +0600 Subject: [PATCH] Fixing bugs --- src/Character.cpp | 3 +-- src/Character.h | 2 ++ src/Location.cpp | 19 +++++++++++++++++++ src/render/PathVisualization.cpp | 24 ++++++++++++++++++------ src/render/PathVisualization.h | 10 +++++++++- 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/Character.cpp b/src/Character.cpp index dffe04e..fbf0e6a 100644 --- a/src/Character.cpp +++ b/src/Character.cpp @@ -15,7 +15,6 @@ namespace FRG { const float ATTACK_COOLDOWN_TIME = 1.6f; extern float x; extern float y; - const float ATTACK_RANGE = 1.25f; Dialogue::TranslationDatabase Character::nameTranslations; @@ -256,7 +255,7 @@ void Character::update(int64_t deltaMs, const CharacterResolver& resolver) { setTarget(attackTarget->state.position); } state.battle_state = 0; - } else if (distToGhost < state.visibleRange && distToGhost >= ATTACK_RANGE) { + } else if (distToGhost < state.visibleRange && distToGhost >= kAttackRange) { setTarget(attackTarget->state.position); state.battle_state = 0; } else { diff --git a/src/Character.h b/src/Character.h index 39c0af7..4a3472f 100644 --- a/src/Character.h +++ b/src/Character.h @@ -20,6 +20,8 @@ class TextRenderer; class Character { public: + static constexpr float kAttackRange = 1.25f; + // Resolves a character index to a live Character pointer. // kNoTarget (-1) → nullptr, kPlayerIndex (-2) → Location::player, 0..n → npcs[n]. using CharacterResolver = std::function; diff --git a/src/Location.cpp b/src/Location.cpp index 0783de2..617c8d9 100644 --- a/src/Location.cpp +++ b/src/Location.cpp @@ -2059,6 +2059,16 @@ namespace FRG player->state.attackTargetIndex = npcIndex; state.targetInteractNpcIndex = -1; + if (distance >= Character::kAttackRange) { + player->setTarget(clickedNpc->state.position); + if (!player->state.pathWaypoints.empty()) { + pathVisualization.start( + *player, + clickedNpc->state.position, + PathVisualization::Style::Hostile); + } + } + if (distance <= clickedNpc->state.interactionRadius) { //logger() << "[CLICK] Hostile NPC " << npcIndex << " in range; firing on_npc_interact" << std::endl; scriptEngine.callNpcInteractCallback(npcIndex); @@ -2080,6 +2090,9 @@ namespace FRG //logger() << "[CLICK] NPC " << npcIndex << " out of talk range (distance " << distance // << " > " << NPC_TALK_DISTANCE << "); walking to NPC..." << std::endl; player->setTarget(clickedNpc->state.position); + if (!player->state.pathWaypoints.empty()) { + pathVisualization.start(*player, clickedNpc->state.position); + } state.targetInteractNpcIndex = npcIndex; } } @@ -2105,6 +2118,12 @@ namespace FRG state.targetInteractiveObjectIndex = -1; state.targetInteractNpcIndex = -1; player->setTarget(clickedTeleport->position); + if (!player->state.pathWaypoints.empty()) { + pathVisualization.start( + *player, + clickedTeleport->position, + PathVisualization::Style::Teleport); + } player->state.attackTargetIndex = CharacterState::kNoTarget; } else { const Eigen::Vector3f clickedDestination(hit.x(), 0.f, hit.z()); diff --git a/src/render/PathVisualization.cpp b/src/render/PathVisualization.cpp index 6fbeff3..c41d9e5 100644 --- a/src/render/PathVisualization.cpp +++ b/src/render/PathVisualization.cpp @@ -82,11 +82,24 @@ namespace FRG { dots.clear(); } - void PathVisualization::start(const Character& player, const Eigen::Vector3f& clickedDestination) + void PathVisualization::start(const Character& player, const Eigen::Vector3f& clickedDestination, + Style style) { cancel(); if (!enabled) return; + switch (style) { + case Style::Hostile: + color = Eigen::Vector3f(1.0f, 0.20f, 0.03f); + break; + case Style::Teleport: + color = Eigen::Vector3f(1.0f, 0.90f, 0.05f); + break; + default: + color = Eigen::Vector3f(0.08f, 1.0f, 0.25f); + break; + } + std::vector route; route.reserve(player.state.pathWaypoints.size() + 1); route.push_back(Eigen::Vector3f(player.state.position.x(), 0.0f, player.state.position.z())); @@ -181,7 +194,6 @@ namespace FRG { renderer.shaderManager.PushShader("path_visualization"); renderer.SetMatrix(); constexpr float kMaxOpacity = 0.45f; - const float green[3] = { 0.08f, 1.0f, 0.25f }; for (const Dot& dot : dots) { const float localAge = elapsedMs - dot.delayMs; @@ -189,8 +201,8 @@ namespace FRG { if (alpha <= 0.001f) continue; const float scale = 0.65f + 0.35f * smoothStep(localAge / 55.0f); - const float color[4] = { green[0], green[1], green[2], alpha }; - renderer.RenderUniform4fv("uColor", color); + const float rgba[4] = { color.x(), color.y(), color.z(), alpha }; + renderer.RenderUniform4fv("uColor", rgba); renderer.PushMatrix(); renderer.TranslateMatrix(dot.position + Eigen::Vector3f(0.0f, 0.025f, 0.0f)); renderer.ScaleMatrix(scale); @@ -207,8 +219,8 @@ namespace FRG { } if (markerAlpha > 0.001f) { const float markerScale = 0.72f + 0.28f * smoothStep(elapsedMs / kMarkerFadeInMs); - const float color[4] = { green[0], green[1], green[2], markerAlpha * kMaxOpacity }; - renderer.RenderUniform4fv("uColor", color); + const float rgba[4] = { color.x(), color.y(), color.z(), markerAlpha * kMaxOpacity }; + renderer.RenderUniform4fv("uColor", rgba); renderer.PushMatrix(); renderer.TranslateMatrix(destination + Eigen::Vector3f(0.0f, 0.05f, 0.0f)); renderer.ScaleMatrix(markerScale); diff --git a/src/render/PathVisualization.h b/src/render/PathVisualization.h index 77b753a..5088adb 100644 --- a/src/render/PathVisualization.h +++ b/src/render/PathVisualization.h @@ -12,11 +12,18 @@ namespace FRG { class PathVisualization { public: + enum class Style { + Movement, + Hostile, + Teleport + }; + void initialize(); void setEnabled(bool enabled); bool isEnabled() const { return enabled; } - void start(const Character& player, const Eigen::Vector3f& clickedDestination); + void start(const Character& player, const Eigen::Vector3f& clickedDestination, + Style style = Style::Movement); void cancel(); void update(int64_t deltaMs); void draw(Renderer& renderer); @@ -33,6 +40,7 @@ namespace FRG { float elapsedMs = 0.0f; float durationMs = 0.0f; Eigen::Vector3f destination = Eigen::Vector3f::Zero(); + Eigen::Vector3f color = Eigen::Vector3f(0.08f, 1.0f, 0.25f); std::vector dots; VertexRenderStruct dotMesh; VertexRenderStruct destinationMesh;