diff --git a/modules/wave_survival/macros.h b/modules/wave_survival/macros.h index 0721b5c0..c1e1987a 100644 --- a/modules/wave_survival/macros.h +++ b/modules/wave_survival/macros.h @@ -35,4 +35,11 @@ set_##m_value(m_value); \ } +#define GETSETM(m_from, m_value, ...) \ + { \ + auto m_value{ m_from->get_##m_value() }; \ + __VA_ARGS__ \ + m_from->set_##m_value(m_value); \ + } + #endif // !GODOT_EXTRA_MACROS_H diff --git a/modules/wave_survival/player_body.cpp b/modules/wave_survival/player_body.cpp index e7d03b7d..59902322 100644 --- a/modules/wave_survival/player_body.cpp +++ b/modules/wave_survival/player_body.cpp @@ -1,6 +1,7 @@ #include "player_body.h" #include "health_status.h" #include "macros.h" +#include "player_camera.h" #include "player_input.h" #include "weapon_base.h" #include "weapon_inventory.h" @@ -11,6 +12,7 @@ void PlayerBody::_bind_methods() { } void PlayerBody::on_child_entered(Node *node) { + node->connect("child_entered_tree", callable_mp(this, &self_type::on_child_entered)); if (PlayerInput * input{ cast_to(node) }) { input->connect(PlayerInput::sig_movement_input, callable_mp(this, &self_type::set_movement_input)); input->connect(PlayerInput::sig_look_input, callable_mp(this, &self_type::on_look_input)); @@ -23,6 +25,16 @@ void PlayerBody::on_child_entered(Node *node) { if (HealthStatus * health{ cast_to(node) }) { this->health = health; } + if (PlayerCamera * camera{ cast_to(node) }) { + this->camera = camera; + } +} + +void PlayerBody::process(double delta) { + GETSETM(this->camera, fov_factor, { + float const target_fov{ get_is_running() ? 1.2f : 1.0f }; + fov_factor = Math::move_toward(fov_factor, target_fov, float(delta)); + }); } void PlayerBody::physics_process(double delta) { @@ -78,6 +90,9 @@ void PlayerBody::_notification(int what) { set_process(true); set_physics_process(true); return; + case NOTIFICATION_PROCESS: + process(get_process_delta_time()); + return; case NOTIFICATION_PHYSICS_PROCESS: physics_process(get_physics_process_delta_time()); return; diff --git a/modules/wave_survival/player_body.h b/modules/wave_survival/player_body.h index 8cda8920..8369549c 100644 --- a/modules/wave_survival/player_body.h +++ b/modules/wave_survival/player_body.h @@ -4,6 +4,7 @@ #include "scene/3d/physics/character_body_3d.h" class WeaponInventory; class HealthStatus; +class PlayerCamera; class PlayerBody : public CharacterBody3D { GDCLASS(PlayerBody, CharacterBody3D); @@ -11,6 +12,7 @@ class PlayerBody : public CharacterBody3D { static PlayerBody *singleton_instance; void on_child_entered(Node *node); + void process(double delta); void physics_process(double delta); void set_movement_input(Vector2 state); @@ -36,7 +38,8 @@ private: float jump_strength{ 4.f }; Vector2 movement_input{ 0, 0 }; - WeaponInventory *weapons; + PlayerCamera *camera{ nullptr }; + WeaponInventory *weapons{ nullptr }; HealthStatus *health{ nullptr }; }; diff --git a/modules/wave_survival/player_camera.cpp b/modules/wave_survival/player_camera.cpp index b790470d..737f58a2 100644 --- a/modules/wave_survival/player_camera.cpp +++ b/modules/wave_survival/player_camera.cpp @@ -23,19 +23,31 @@ void PlayerCamera::ready() { this->base_fov = get_fov(); } +void PlayerCamera::process(double delta) { + this->fov_factor = 1.0; + update_fov(); +} + void PlayerCamera::_notification(int what) { if (Engine::get_singleton()->is_editor_hint()) { return; } switch (what) { + default: + return; case NOTIFICATION_READY: + set_process(true); + set_process_priority(-1); ready(); return; + case NOTIFICATION_PROCESS: + process(get_process_delta_time()); + return; } } void PlayerCamera::set_fov_factor(float value) { - this->fov_factor = value; + this->fov_factor *= value; update_fov(); } diff --git a/modules/wave_survival/weapons/rifle.cpp b/modules/wave_survival/weapons/rifle.cpp index 4763653b..cc6a76e4 100644 --- a/modules/wave_survival/weapons/rifle.cpp +++ b/modules/wave_survival/weapons/rifle.cpp @@ -9,7 +9,6 @@ void Rifle::_bind_methods() { BIND_PROPERTY(Variant::FLOAT, ads_factor); - BIND_PROPERTY(Variant::FLOAT, run_factor); BIND_PROPERTY(Variant::FLOAT, recoil_force); BIND_PROPERTY(Variant::FLOAT, recoil_time); ClassDB::bind_method(D_METHOD("reload_full"), &self_type::reload_full); @@ -18,13 +17,11 @@ void Rifle::_bind_methods() { void Rifle::queue_enter_alt() { get_anim()->queue("hip_to_aim"); get_anim()->queue("aim"); - HeadsUpDisplay::get_singleton()->set_reticle_visibility(false); } void Rifle::queue_exit_alt() { get_anim()->queue("aim_to_hip"); get_anim()->queue("hip"); - HeadsUpDisplay::get_singleton()->set_reticle_visibility(true); } void Rifle::queue_enter_run() { @@ -90,12 +87,15 @@ void Rifle::on_reload() { void Rifle::on_animation_changed(String new_animation) { if (new_animation == "aim") { this->in_alt_mode = true; - get_camera()->set_fov_factor(this->ads_factor); + this->fov = this->ads_factor; + HeadsUpDisplay::get_singleton()->set_reticle_visibility(false); } else if (new_animation == "hip") { this->in_alt_mode = false; - get_camera()->set_fov_factor(1.0); - } else if (new_animation == "run") { - get_camera()->set_fov_factor(this->run_factor); + this->fov = 1.0; + HeadsUpDisplay::get_singleton()->set_reticle_visibility(true); + } + if (new_animation == "reload") { + HeadsUpDisplay::get_singleton()->set_reticle_visibility(false); } } @@ -109,22 +109,13 @@ void Rifle::process(double delta) { bool run_requested{ this->run_requested() }; // track animation progress double const animation_time{ get_anim()->get_current_animation_position() }; - // percentually + // animation progress percentually float const progress{ float(CLAMP(animation_time / get_anim()->get_current_animation_length(), 0.0, 1.0)) }; - // lerp the current FOV factor depending on the ongoing animation - if (current == "hip_to_aim") { - get_camera()->set_fov_factor(Math::lerp(1.f, this->ads_factor, progress)); + if (current == "hip_to_aim" || current == "run_to_aim") { // lerp the current FOV factor depending on the ongoing animation + this->fov = Math::lerp(1.f, this->ads_factor, progress); } else if (current == "aim_to_hip") { - get_camera()->set_fov_factor(Math::lerp(this->ads_factor, 1.f, progress)); - } else if (current == "run_to_aim") { - get_camera()->set_fov_factor(Math::lerp(this->run_factor, this->ads_factor, progress)); - } else if (current == "hip_to_run") { - get_camera()->set_fov_factor(Math::lerp(1.f, this->run_factor, progress)); - } else if (current == "run_to_hip") { - get_camera()->set_fov_factor(Math::lerp(this->run_factor, 1.f, progress)); - // animation is not one of the transitory ones ( x_to_y ), - // check if there is a request for a transitory animation - } else if (this->request_alt_mode != this->in_alt_mode && !is_animating()) { + this->fov = Math::lerp(this->ads_factor, 1.f, progress); + } else if (this->request_alt_mode != this->in_alt_mode && !is_animating()) { // act on request flags that have yet to be fulfilled if (this->request_alt_mode) { queue_enter_alt(); } else { @@ -136,12 +127,13 @@ void Rifle::process(double delta) { } else if (!run_requested) { exit_run(); } - } - // apply fire recoil - else if (current == "fire_hip" || current == "fire_aim") { + } else if (current == "fire_hip" || current == "fire_aim") { // apply fire recoil double t{ animation_time / this->recoil_time }; get_camera()->recoil(Math::lerp((double)this->recoil_force, 0.0, CLAMP(t, 0.0, 1.0)) * delta); } + if (this->fov != 1.0) { + get_camera()->set_fov_factor(this->fov); + } } void Rifle::_notification(int what) { @@ -169,11 +161,6 @@ PackedStringArray Rifle::get_configuration_warnings() const { return warnings; } -bool Rifle::allows_swapping() const { - String const current{ get_anim()->get_current_animation() }; - return !this->in_alt_mode && (current == "reload" || !is_animating()); -} - bool Rifle::allows_running() const { String const animation{ get_anim()->get_current_animation() }; return animation == "run" && !this->request_alt_mode; @@ -194,6 +181,10 @@ void Rifle::notify_deselected() { get_input()->disconnect(PlayerInput::sig_primary_fire, callable_mp(this, &self_type::on_primary_fire)); get_input()->disconnect(PlayerInput::sig_alt_mode, callable_mp(this, &self_type::on_alt_mode)); get_input()->disconnect(PlayerInput::sig_reload, callable_mp(this, &self_type::on_reload)); + get_camera()->set_fov_factor(1.0); + if (HeadsUpDisplay * hud{ HeadsUpDisplay::get_singleton() }) { + hud->set_reticle_visibility(true); + } } void Rifle::reload_full() { @@ -209,14 +200,6 @@ float Rifle::get_ads_factor() const { return this->ads_factor; } -void Rifle::set_run_factor(float value) { - this->run_factor = value; -} - -float Rifle::get_run_factor() const { - return this->run_factor; -} - void Rifle::set_recoil_force(float value) { this->recoil_force = value; } diff --git a/modules/wave_survival/weapons/rifle.h b/modules/wave_survival/weapons/rifle.h index 16ad2f98..1877c5b5 100644 --- a/modules/wave_survival/weapons/rifle.h +++ b/modules/wave_survival/weapons/rifle.h @@ -27,7 +27,6 @@ public: void _notification(int what); virtual PackedStringArray get_configuration_warnings() const override; - virtual bool allows_swapping() const override; virtual bool allows_running() const override; bool run_requested() const; virtual void notify_selected() override; @@ -36,8 +35,6 @@ public: void set_ads_factor(float value); float get_ads_factor() const; - void set_run_factor(float value); - float get_run_factor() const; void set_recoil_force(float value); float get_recoil_force() const; void set_recoil_time(float value); @@ -45,7 +42,6 @@ public: private: float ads_factor{ 0.5f }; - float run_factor{ 1.5f }; bool request_alt_mode{ false }; bool in_alt_mode{ false }; bool running{ false }; @@ -53,6 +49,8 @@ private: float recoil_force{ 3.f }; float recoil_time{ 0.05f }; + double fov{ 1.0 }; + HitscanMuzzle *muzzle{ nullptr }; }; diff --git a/project/objects/player.tscn b/project/objects/player.tscn index 4d01da7e..9fa04406 100644 --- a/project/objects/player.tscn +++ b/project/objects/player.tscn @@ -23,6 +23,7 @@ wall_min_slide_angle = 0.0 [node name="PlayerCamera" type="PlayerCamera" parent="."] unique_name_in_owner = true +process_priority = -1 transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0.27450943, 0) fov = 60.0