diff --git a/src/player_character.cpp b/src/player_character.cpp index cc5bdd9..76c3411 100644 --- a/src/player_character.cpp +++ b/src/player_character.cpp @@ -1,5 +1,6 @@ #include "player_character.hpp" #include "projectile_pool.hpp" +#include "state_machine.hpp" #include "utils/godot_macros.h" #include #include @@ -16,12 +17,14 @@ void PlayerCharacter::_enter_tree() { GDGAMEONLY(); this->target_rotation = this->get_global_transform().get_basis().get_quaternion(); this->health = this->get_node("Health"); this->primary_weapon_pool = this->get_node("ProjectilePool"); + this->state_machine = this->get_node("StateMachine"); } void PlayerCharacter::_process(double delta_time) { GDGAMEONLY(); this->process_rotation(delta_time); - if(!this->mode_manual) + if(!this->mode_manual) { this->process_ai(delta_time); + } if(this->firing) this->try_fire_weapon(); } @@ -41,7 +44,7 @@ void PlayerCharacter::move(Vector3 world_vector) { } void PlayerCharacter::aim(Vector3 at) { - // calculate the forward vector by normalized difference between player character and the target + // calculate the forward vector by normalized difference between player character and the target on the XZ plane Vector3 const position{this->weapon_muzzle->get_global_position()}; Vector3 const forward{(Vector3{at.x, 0.f, at.z} - Vector3{position.x, 0.f, position.z}).normalized()}; // we always want up to be the global unit up @@ -50,13 +53,27 @@ void PlayerCharacter::aim(Vector3 at) { this->target_rotation = Basis{up.cross(forward), up, forward}; } +void PlayerCharacter::move_to(Vector3 to, float target_distance) { + this->nav_agent->set_target_desired_distance(target_distance); + this->nav_agent->set_target_position(this->get_global_position().distance_squared_to(to) < target_distance * target_distance + ? this->get_global_position() + : to); +} + +void PlayerCharacter::shoot_at(Vector3 at) { + this->aim(at); + this->set_firing(true); +} + void PlayerCharacter::set_firing(bool firing) { this->firing = firing; } void PlayerCharacter::set_manual_mode(bool value) { this->mode_manual = value; - this->nav_agent->set_process_mode(value ? ProcessMode::PROCESS_MODE_PAUSABLE : ProcessMode::PROCESS_MODE_DISABLED); + ProcessMode const mode = value ? ProcessMode::PROCESS_MODE_DISABLED : ProcessMode::PROCESS_MODE_PAUSABLE; + this->nav_agent->set_process_mode(mode); + this->state_machine->set_process_mode(mode); } void PlayerCharacter::set_rotation_speed_curve(Ref curve) { @@ -77,9 +94,6 @@ Health const *PlayerCharacter::get_health() const { void PlayerCharacter::set_character_data(Ref data) { this->data = data; - UtilityFunctions::print("PlayerCharacter::set_character_data"); - UtilityFunctions::print(" - data: ", data->get_path()); - UtilityFunctions::print(" - weapon: ", data->get_weapon()->get_path()); this->fire_interval = 1.f / this->data->get_weapon()->get_rounds_per_second(); this->primary_weapon_pool->set_data(this->data->get_weapon()); } @@ -89,7 +103,13 @@ void PlayerCharacter::set_weapon_muzzle(Node3D *node) { } void PlayerCharacter::process_ai(double delta_time) { - this->velocity_target = this->nav_agent->get_velocity(); + if(this->nav_agent->is_navigation_finished()) { + this->move(Vector3()); + } else { + Vector3 const target_position = this->nav_agent->get_next_path_position(); + Vector3 const direction = (target_position - this->get_global_position()).normalized(); + this->move(direction); + } } void PlayerCharacter::process_rotation(double delta_time) { diff --git a/src/player_character.hpp b/src/player_character.hpp index d7d1517..f5e8e2e 100644 --- a/src/player_character.hpp +++ b/src/player_character.hpp @@ -9,6 +9,8 @@ namespace godot { class NavigationAgent3D; +class StateMachine; +class TunnelsPlayer; class PlayerCharacter : public CharacterBody3D, public IHealthEntity { @@ -20,6 +22,8 @@ public: virtual void _physics_process(double delta_time) override; void move(Vector3 world_vector); void aim(Vector3 at); + void move_to(Vector3 to, float target_distance = 0.5f); + void shoot_at(Vector3 at); void set_firing(bool firing); void set_manual_mode(bool value); @@ -38,6 +42,7 @@ protected: void try_fire_weapon(); private: Vector3 velocity_target{0.f,0.f,0.f}; + StateMachine *state_machine{nullptr}; Basis target_rotation{}; NavigationAgent3D *nav_agent{nullptr}; bool mode_manual{false};