diff --git a/godot/player_character.tscn b/godot/player_character.tscn index 309d7cd..f4cd098 100644 --- a/godot/player_character.tscn +++ b/godot/player_character.tscn @@ -25,9 +25,6 @@ collision_layer = 7 [node name="Health" type="Health" parent="."] max_health = 5 -[node name="StateMachine" type="StateMachine" parent="."] -initial_state = &"FollowingPlayer" - [node name="ProjectilePool" type="ProjectilePool" parent="."] [node name="NavigationAgent3D" type="NavigationAgent3D" parent="."] diff --git a/src/player_character.cpp b/src/character_actor.cpp similarity index 75% rename from src/player_character.cpp rename to src/character_actor.cpp index eecc955..e22fb60 100644 --- a/src/player_character.cpp +++ b/src/character_actor.cpp @@ -1,4 +1,4 @@ -#include "player_character.hpp" +#include "character_actor.hpp" #include "projectile_pool.hpp" #include "utils/godot_macros.h" #include @@ -8,13 +8,13 @@ #include namespace godot { -void PlayerCharacter::_bind_methods() { -#define CLASSNAME PlayerCharacter +void CharacterActor::_bind_methods() { +#define CLASSNAME CharacterActor GDPROPERTY_HINTED(rotation_speed_curve, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Curve"); GDFUNCTION_ARGS(set_velocity_target, "value"); } -void PlayerCharacter::_enter_tree() { GDGAMEONLY(); +void CharacterActor::_enter_tree() { GDGAMEONLY(); this->nav_agent = this->get_node("NavigationAgent3D"); this->nav_agent->connect("velocity_computed", Callable(this, "set_velocity_target")); this->target_rotation = this->get_global_transform().get_basis().get_quaternion(); @@ -22,7 +22,7 @@ void PlayerCharacter::_enter_tree() { GDGAMEONLY(); this->primary_weapon_pool = this->get_node("ProjectilePool"); } -void PlayerCharacter::_process(double delta_time) { GDGAMEONLY(); +void CharacterActor::_process(double delta_time) { GDGAMEONLY(); this->process_rotation(delta_time); if(!this->mode_manual) { this->process_ai(delta_time); @@ -31,9 +31,9 @@ void PlayerCharacter::_process(double delta_time) { GDGAMEONLY(); this->try_fire_weapon(); } -void PlayerCharacter::_physics_process(double delta_time) { GDGAMEONLY(); +void CharacterActor::_physics_process(double delta_time) { GDGAMEONLY(); // accelerate towards velocity target - Vector3 const new_velocity = this->get_velocity().move_toward(this->velocity_target, delta_time * PlayerCharacter::ACCELERATION); + Vector3 const new_velocity = this->get_velocity().move_toward(this->velocity_target, delta_time * CharacterActor::ACCELERATION); // only apply velocity if not grounded Vector3 const gravity{this->is_on_floor() ? Vector3() : Vector3{0.f, this->get_velocity().y - 9.8f, 0.f}}; this->set_velocity(new_velocity + gravity); @@ -41,18 +41,18 @@ void PlayerCharacter::_physics_process(double delta_time) { GDGAMEONLY(); this->move_and_slide(); } -void PlayerCharacter::move(Vector3 world_vector) { - this->velocity_target = world_vector * PlayerCharacter::WALK_SPEED; +void CharacterActor::move(Vector3 world_vector) { + this->velocity_target = world_vector * CharacterActor::WALK_SPEED; } -void PlayerCharacter::aim(Vector3 at) { +void CharacterActor::aim(Vector3 at) { // 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}}; this->aim_direction(forward.normalized()); } -void PlayerCharacter::aim_direction(Vector3 direction) { +void CharacterActor::aim_direction(Vector3 direction) { if(!direction.is_normalized()) { UtilityFunctions::push_error("'", this->get_path(), "' Cannot aim along a non-normalized direction vector", direction.length_squared()); return; @@ -63,77 +63,77 @@ void PlayerCharacter::aim_direction(Vector3 direction) { this->target_rotation = Basis{up.cross(direction), up, direction}; } -void PlayerCharacter::move_to(Vector3 to, float target_distance) { +void CharacterActor::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) { +void CharacterActor::shoot_at(Vector3 at) { this->aim(at); this->set_firing(true); } -void PlayerCharacter::set_firing(bool firing) { +void CharacterActor::set_firing(bool firing) { this->firing = firing; } -void PlayerCharacter::set_manual_mode(bool value) { +void CharacterActor::set_manual_mode(bool value) { this->mode_manual = value; ProcessMode const mode = value ? ProcessMode::PROCESS_MODE_DISABLED : ProcessMode::PROCESS_MODE_PAUSABLE; //this->nav_agent->set_process_mode(mode); this->nav_agent->set_avoidance_priority(value ? 1.f : 0.9f); } -void PlayerCharacter::set_rotation_speed_curve(Ref curve) { +void CharacterActor::set_rotation_speed_curve(Ref curve) { this->rotation_speed_curve = curve; } -Ref PlayerCharacter::get_rotation_speed_curve() const { +Ref CharacterActor::get_rotation_speed_curve() const { return this->rotation_speed_curve; } -Health *PlayerCharacter::get_health() { +Health *CharacterActor::get_health() { return this->health; } -Health const *PlayerCharacter::get_health() const { +Health const *CharacterActor::get_health() const { return this->health; } -void PlayerCharacter::set_character_data(Ref data) { +void CharacterActor::set_character_data(Ref data) { this->data = data; this->fire_interval = 1.f / this->data->get_weapon()->get_rounds_per_second(); this->primary_weapon_pool->set_data(this->data->get_weapon()); } -void PlayerCharacter::set_weapon_muzzle(Node3D *node) { +void CharacterActor::set_weapon_muzzle(Node3D *node) { this->weapon_muzzle = node; } -void PlayerCharacter::set_velocity_target(Vector3 value) { +void CharacterActor::set_velocity_target(Vector3 value) { this->velocity_target = value; } -Vector3 PlayerCharacter::get_velocity_target() const { +Vector3 CharacterActor::get_velocity_target() const { return this->velocity_target; } -void PlayerCharacter::process_ai(double delta_time) { +void CharacterActor::process_ai(double delta_time) { float const distance = this->nav_agent->get_target_position().distance_squared_to(this->get_global_position()); float const target_distance_sqr = std::pow(this->nav_agent->get_target_desired_distance(), 2.f); if(!this->nav_agent->is_navigation_finished() && distance >= target_distance_sqr) { Vector3 const target_position = this->nav_agent->get_next_path_position(); Vector3 const direction = (target_position - this->get_global_position()).normalized(); if(this->nav_agent->get_avoidance_enabled()) - this->nav_agent->set_velocity(direction * PlayerCharacter::WALK_SPEED); + this->nav_agent->set_velocity(direction * CharacterActor::WALK_SPEED); else this->move(direction); } } -void PlayerCharacter::process_rotation(double delta_time) { +void CharacterActor::process_rotation(double delta_time) { // copy the current transform and basis matrix Transform3D trans{this->get_global_transform()}; Basis basis = trans.get_basis(); @@ -144,7 +144,7 @@ void PlayerCharacter::process_rotation(double delta_time) { // calculate the angle that still needs to be traveled float const angle = current_quaternion.angle_to(target_quaternion); // calculate the angle amount that can be moved this frame - float const angle_step{float(this->rotation_speed_curve->sample(angle) * PlayerCharacter::ROTATION_SPEED * delta_time)}; + float const angle_step{float(this->rotation_speed_curve->sample(angle) * CharacterActor::ROTATION_SPEED * delta_time)}; // update this object's global transform with the new rotation basis.set_quaternion(angle < angle_step ? target_quaternion // to avoid overshooting, check if the max step is smaller than the angle distance : current_quaternion.slerp(target_quaternion, angle_step / angle)); // convert the angle step to a lerp t value between current and target rotations @@ -152,7 +152,7 @@ void PlayerCharacter::process_rotation(double delta_time) { this->set_global_transform(trans); } -void PlayerCharacter::try_fire_weapon() { +void CharacterActor::try_fire_weapon() { if(float(Time::get_singleton()->get_ticks_msec()) / 1000.f < this->fire_timer) return; if(!this->data->get_weapon()->get_allow_automatic()) @@ -163,8 +163,8 @@ void PlayerCharacter::try_fire_weapon() { node->set_global_transform(this->weapon_muzzle->get_global_transform()); } -float const PlayerCharacter::ACCELERATION{20.f}; -float const PlayerCharacter::WALK_SPEED{3.f}; -float const PlayerCharacter::SPRINT_SPEED{5.f}; -float const PlayerCharacter::ROTATION_SPEED{10.f}; +float const CharacterActor::ACCELERATION{20.f}; +float const CharacterActor::WALK_SPEED{3.f}; +float const CharacterActor::SPRINT_SPEED{5.f}; +float const CharacterActor::ROTATION_SPEED{10.f}; } diff --git a/src/player_character.hpp b/src/character_actor.hpp similarity index 92% rename from src/player_character.hpp rename to src/character_actor.hpp index e140c7b..686964b 100644 --- a/src/player_character.hpp +++ b/src/character_actor.hpp @@ -11,9 +11,9 @@ namespace godot { class NavigationAgent3D; class TunnelsPlayer; -class PlayerCharacter : public CharacterBody3D, - public IHealthEntity { - GDCLASS(PlayerCharacter, CharacterBody3D); +class CharacterActor : public CharacterBody3D, + public IHealthEntity { + GDCLASS(CharacterActor, CharacterBody3D); static void _bind_methods(); public: virtual void _enter_tree() override; diff --git a/src/enemy.cpp b/src/enemy.cpp index dbfc8bd..004e3e1 100644 --- a/src/enemy.cpp +++ b/src/enemy.cpp @@ -1,8 +1,7 @@ #include "enemy.hpp" #include "godot_cpp/classes/time.hpp" -#include "godot_cpp/variant/utility_functions.hpp" #include "health.hpp" -#include "player_character.hpp" +#include "character_actor.hpp" #include "utils/godot_macros.h" #include @@ -45,7 +44,7 @@ void Enemy::process_navigation(double delta_time) { } void Enemy::body_entered_vision_area(Node3D *body) { - PlayerCharacter *player = Object::cast_to(body); + CharacterActor *player = Object::cast_to(body); if(player == nullptr) return; // TODO: replace this with some condition deciding wether to attack the new character or the current target diff --git a/src/enemy.hpp b/src/enemy.hpp index af23bbb..23aad27 100644 --- a/src/enemy.hpp +++ b/src/enemy.hpp @@ -6,7 +6,7 @@ #include namespace godot { -class PlayerCharacter; +class CharacterActor; class NavigationAgent3D; class Enemy : public CharacterBody3D, @@ -31,7 +31,7 @@ public: private: float renav_time{0.f}; - PlayerCharacter *target_player{nullptr}; + CharacterActor *target_player{nullptr}; Health *health{nullptr}; NavigationAgent3D *nav_agent{nullptr}; Area3D *vision_area{nullptr}; diff --git a/src/register_types.cpp b/src/register_types.cpp index f54187a..d2ce3f3 100644 --- a/src/register_types.cpp +++ b/src/register_types.cpp @@ -1,9 +1,9 @@ #include "register_types.h" #include "character_data.hpp" +#include "character_actor.hpp" #include "enemy.hpp" #include "health.hpp" #include "pellet_projectile.hpp" -#include "player_character.hpp" #include "projectile_pool.hpp" #include "tunnels_game_mode.hpp" #include "tunnels_game_state.hpp" @@ -42,7 +42,7 @@ void initialize_gdextension_types(ModuleInitializationLevel p_level) ClassDB::register_class(); ClassDB::register_class(); - ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); diff --git a/src/tunnels_player.cpp b/src/tunnels_player.cpp index 843f9f8..9653b55 100644 --- a/src/tunnels_player.cpp +++ b/src/tunnels_player.cpp @@ -2,8 +2,7 @@ #include "character_data.hpp" #include "godot_cpp/variant/plane.hpp" #include "godot_cpp/variant/projection.hpp" -#include "godot_cpp/variant/utility_functions.hpp" -#include "player_character.hpp" +#include "character_actor.hpp" #include "tunnels_game_state.hpp" #include "utils/game_root.hpp" #include "utils/godot_macros.h" @@ -122,10 +121,10 @@ void TunnelsPlayer::initialize_character() { // check if the player scene is a valid player character if(player_scene.is_null() || !player_scene.is_valid()) return; - if(player_scene->get_state()->get_node_type(0) != StringName("PlayerCharacter")) + if(player_scene->get_state()->get_node_type(0) != StringName("CharacterActor")) return; // instantiate and store the player character - this->character = Object::cast_to(player_scene->instantiate()); + this->character = Object::cast_to(player_scene->instantiate()); this->get_parent()->add_child(this->character); this->character->set_global_transform(this->get_global_transform()); Ref game_state = GameRoot::get_singleton()->get_game_state(); @@ -169,7 +168,7 @@ Ref TunnelsPlayer::get_camera_rotation_ramp() const { return this->camera_rotation_ramp; } -PlayerCharacter *TunnelsPlayer::get_character() const { +CharacterActor *TunnelsPlayer::get_character() const { return this->character; } diff --git a/src/tunnels_player.hpp b/src/tunnels_player.hpp index 41e3ad6..3e47485 100644 --- a/src/tunnels_player.hpp +++ b/src/tunnels_player.hpp @@ -9,7 +9,7 @@ #include namespace godot { -class PlayerCharacter; +class CharacterActor; class TunnelsPlayer : public Node3D, public IPlayer { GDCLASS(TunnelsPlayer, Node3D); @@ -44,14 +44,14 @@ public: void set_camera_rotation_ramp(Ref curve); Ref get_camera_rotation_ramp() const; - PlayerCharacter *get_character() const; + CharacterActor *get_character() const; private: Vector2 move_input{0,0}; Vector2 mouse_location{0,0}; Vector3 mouse_world_ray_normal{0.f,0.f,0.f}; TunnelsPlayer::State state{State::ManualControl}; - PlayerCharacter *character{nullptr}; + CharacterActor *character{nullptr}; Node3D *reticle{nullptr}; Camera3D *camera{nullptr}; diff --git a/src/weapon_muzzle.cpp b/src/weapon_muzzle.cpp index cb7d932..288d183 100644 --- a/src/weapon_muzzle.cpp +++ b/src/weapon_muzzle.cpp @@ -1,5 +1,5 @@ #include "weapon_muzzle.hpp" -#include "player_character.hpp" +#include "character_actor.hpp" #include "utils/godot_macros.h" namespace godot { @@ -8,7 +8,7 @@ void WeaponMuzzle::_bind_methods() { } void WeaponMuzzle::_enter_tree() { GDGAMEONLY(); - PlayerCharacter *owner = Object::cast_to(this->get_owner()); + CharacterActor *owner = Object::cast_to(this->get_owner()); if(!owner) return; owner->set_weapon_muzzle(this);