From de2e18e38f073804a3ae9122220f58487e55dc4b Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Wed, 15 Apr 2026 10:34:55 +0300 Subject: [PATCH] Fixing rotation issues in battle mode --- src/Character.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++++ src/Character.h | 2 ++ src/Game.cpp | 65 +++------------------------------------ src/Game.h | 1 - 4 files changed, 84 insertions(+), 61 deletions(-) diff --git a/src/Character.cpp b/src/Character.cpp index 45e6011..a512c3a 100644 --- a/src/Character.cpp +++ b/src/Character.cpp @@ -67,6 +67,11 @@ void Character::update(int64_t deltaMs) { } } + if (battle_state == 1 && attack == 1 && attackTarget != nullptr) + { + targetFacingAngle = atan2(attackTarget->position.x() - position.x(), -(attackTarget->position.z() - position.z())); + } + // Rotate toward target facing angle at constant angular speed float angleDiff = targetFacingAngle - facingAngle; while (angleDiff > static_cast(M_PI)) angleDiff -= 2.f * static_cast(M_PI); @@ -78,6 +83,78 @@ void Character::update(int64_t deltaMs) { facingAngle += (angleDiff > 0.f ? rotStep : -rotStep); } + if (canAttack && attackTarget != nullptr) + { + float distToGhost = (attackTarget->position - position).norm(); + if (distToGhost >= 10.f) + { + if (isPlayer) + { + setTarget(attackTarget->position); + } + if (battle_state != 0) + { + battle_state = 0; + } + } + else if (distToGhost < 10.0f && distToGhost >= 1.f) { + setTarget(attackTarget->position); + if (battle_state != 0) + { + battle_state = 0; + } + } + else + { + setTarget(position); + if (battle_state != 1) + { + battle_state = 1; + } + } + } + + if (attackTarget == nullptr) + { + if (battle_state != 0) + { + battle_state = 0; + attack = 0; + } + } + + /* + if (isPlayer) //Player should decide only by himself + { + if (attackTarget != nullptr) + { + auto pos = attackTarget->position; + float distToTarget = (position - pos).norm(); + + if (distToTarget > 1.0) + { + setTarget(Eigen::Vector3f(pos.x(), 0.f, pos.z())); + } + else + { + if (battle_state != 1) + { + setTarget(position); + battle_state = 1; + //player->attack = 1; + } + } + } + else + { + if (battle_state != 0) + { + battle_state = 0; + attack = 0; + } + } + }*/ + if (battle_state == 1) { if (currentState == AnimationState::STAND || currentState == AnimationState::WALK) { diff --git a/src/Character.h b/src/Character.h index 82a4705..58c44f8 100644 --- a/src/Character.h +++ b/src/Character.h @@ -57,6 +57,8 @@ public: AnimationState currentState = AnimationState::STAND; float attack_cooldown = 0.f; bool canAttack = false; + Character* attackTarget = nullptr; + bool isPlayer = false; private: struct AnimationData { diff --git a/src/Game.cpp b/src/Game.cpp index 151a75d..8565cf2 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -176,6 +176,7 @@ namespace ZL /*Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitZ()));*/ player->canAttack = true; + player->isPlayer = true; std::cout << "Load resurces step 9" << std::endl; // Load NPCs from JSON @@ -227,6 +228,7 @@ namespace ZL npc02->position = Eigen::Vector3f(0.f, 0.f, -20.f); npc02->setTarget(npc02->position); npc02->canAttack = true; + npc02->attackTarget = player.get(); npcs.push_back(std::move(npc02)); @@ -507,64 +509,7 @@ namespace ZL if (player) player->update(delta); for (auto& npc : npcs) npc->update(delta); - for (auto& npc : npcs) - { - if (npc->canAttack) - { - float distToGhost = (player->position - npc->position).norm(); - if (distToGhost >= 10.f) - { - if (npc->battle_state != 0) - { - npc->battle_state = 0; - } - } - else if (distToGhost < 10.0f && distToGhost >= 1.f) { - npc->setTarget(player->position); - if (npc->battle_state != 0) - { - npc->battle_state = 0; - } - } - else - { - npc->setTarget(npc->position); - if (npc->battle_state != 1) - { - npc->battle_state = 1; - } - - } - } - } - - if (playerAttackTarget != nullptr) - { - auto pos = playerAttackTarget->position; - float distToTarget = (player->position - pos).norm(); - - if (distToTarget > 1.0) - { - player->setTarget(Eigen::Vector3f(pos.x(), 0.f, pos.z())); - } - else - { - if (player->battle_state != 1) - { - player->setTarget(player->position); - player->battle_state = 1; - //player->attack = 1; - } - } - } - if (playerAttackTarget == nullptr) - { - if (player->battle_state != 0) - { - player->battle_state = 0; - player->attack = 0; - } - } + // Check if player reached target interactive object if (targetInteractiveObject && player) { @@ -691,7 +636,7 @@ namespace ZL std::cout << "\n========== MOUSE DOWN EVENT ==========" << std::endl; handleDown(ZL::UiManager::MOUSE_FINGER_ID, mx, my); - playerAttackTarget = nullptr; + player->attackTarget = nullptr; // Calculate ray for picking if (dialogueSystem.blocksGameplayInput()) { @@ -749,7 +694,7 @@ namespace ZL if (clickedNpc->canAttack) { - playerAttackTarget = clickedNpc; + player->attackTarget = clickedNpc; } } diff --git a/src/Game.h b/src/Game.h index f05dd8e..81535ed 100644 --- a/src/Game.h +++ b/src/Game.h @@ -84,7 +84,6 @@ namespace ZL { // Public access for ScriptEngine MenuManager menuManager; ScriptEngine scriptEngine; - Character* playerAttackTarget = nullptr; private: bool rightMouseDown = false;