feat: implemented basics for weapons

This commit is contained in:
Sara 2025-07-17 12:49:32 +02:00
parent 6fa9d11af5
commit aecc40ed6e
15 changed files with 163 additions and 51 deletions

View file

@ -88,5 +88,9 @@ PlayerBody *PlayerBody::get_singleton() {
}
bool PlayerBody::get_is_running() const {
return this->try_running && this->movement_input.y > 0.f && this->weapons->get_current_weapon()->allows_running();
return get_wants_to_run() && this->weapons->get_current_weapon()->allows_running();
}
bool PlayerBody::get_wants_to_run() const {
return this->try_running && this->movement_input.y > 0.f && this->is_on_floor();
}

View file

@ -25,6 +25,7 @@ protected:
public:
static PlayerBody *get_singleton();
bool get_is_running() const;
bool get_wants_to_run() const;
private:
bool try_running{ false };

View file

@ -9,6 +9,9 @@ class PlayerInput : public Node {
void _notification(int what);
virtual void unhandled_input(Ref<InputEvent> const &event) override;
public:
bool run_input_down() const;
public:
static String sig_movement_input;
static String sig_look_input;

View file

@ -1,6 +1,8 @@
#include "weapon_base.h"
#include "macros.h"
#include "player_body.h"
#include "player_camera.h"
#include "player_input.h"
#include "scene/animation/animation_player.h"
void WeaponBase::_bind_methods() {
@ -8,7 +10,9 @@ void WeaponBase::_bind_methods() {
}
void WeaponBase::ready() {
this->camera = cast_to<PlayerCamera>(get_node(NodePath("%PlayerCamera")));
this->input = cast_to<PlayerInput>(get_parent()->get_node(NodePath("%PlayerInput")));
this->camera = cast_to<PlayerCamera>(get_parent());
this->body = cast_to<PlayerBody>(get_parent()->get_owner());
if (this->anim) {
this->anim->play("RESET");
}
@ -34,6 +38,10 @@ AnimationPlayer *WeaponBase::get_anim() const {
return this->anim;
}
PlayerInput *WeaponBase::get_input() const {
return this->input;
}
PlayerCamera *WeaponBase::get_camera() const {
return this->camera;
}

View file

@ -5,6 +5,7 @@
class AnimationPlayer;
class PlayerCamera;
class PlayerBody;
class PlayerInput;
class WeaponBase : public Node3D {
GDCLASS(WeaponBase, Node3D);
@ -17,6 +18,7 @@ protected:
public:
void set_anim(AnimationPlayer *player);
AnimationPlayer *get_anim() const;
PlayerInput *get_input() const;
PlayerCamera *get_camera() const;
void set_body(PlayerBody *body);
@ -27,6 +29,7 @@ public:
virtual void notify_selected() {}
private:
PlayerInput *input{ nullptr };
AnimationPlayer *anim{ nullptr };
PlayerCamera *camera{ nullptr };
PlayerBody *body{ nullptr };

View file

@ -19,7 +19,7 @@ void WeaponInventory::ready() {
this->weapon_parent->add_child(fallback_as_node);
if ((this->fallback_weapon = cast_to<WeaponBase>(fallback_as_node))) {
this->select_weapon(this->fallback_weapon);
} else if(fallback_as_node != nullptr) {
} else if (fallback_as_node != nullptr) {
fallback_as_node->queue_free();
}
}
@ -78,7 +78,7 @@ WeaponBase *WeaponInventory::get_current_weapon() const {
void WeaponInventory::pickup_weapon(Ref<PackedScene> weapon_scene) {
Node *weapon_as_node{ weapon_scene->instantiate() };
if (WeaponBase *weapon{ cast_to<WeaponBase>(weapon_as_node) }) {
if (WeaponBase * weapon{ cast_to<WeaponBase>(weapon_as_node) }) {
if (this->weapons[0] == nullptr) {
this->weapons[0] = weapon;
select_weapon(weapon);

View file

@ -5,8 +5,44 @@
void Rifle::_bind_methods() {}
void Rifle::on_primary_fire(bool pressed) {
if (pressed && get_anim()->get_queue().size() == 0) {
void Rifle::queue_start_aim() {
get_anim()->queue("hip_to_aim");
get_anim()->queue("aim");
}
void Rifle::queue_stop_ads_anim() {
if (run_requested()) {
this->running = true;
get_anim()->clear_queue();
get_anim()->queue("aim_to_run");
get_anim()->queue("run");
} else {
get_anim()->queue("aim_to_hip");
get_anim()->queue("hip");
}
}
void Rifle::queue_start_run_anim() {
this->running = true;
get_anim()->clear_queue();
get_anim()->queue("hip_to_run");
get_anim()->queue("run");
}
void Rifle::stop_run_anim() {
this->running = false;
get_anim()->clear_queue();
if (this->request_alt_mode) {
get_anim()->play("run_to_aim", 0.0);
get_anim()->queue("aim");
} else {
get_anim()->play("run_to_hip", 0.0);
get_anim()->queue("hip");
}
}
void Rifle::shoot() {
if (get_anim()->get_queue().size() == 0 && get_anim()->get_current_animation() == "") {
if (this->request_alt_mode) {
get_anim()->queue("fire_aim");
} else if (get_anim()->get_current_animation() == "") {
@ -15,6 +51,17 @@ void Rifle::on_primary_fire(bool pressed) {
}
}
void Rifle::play_equip_anim() {
get_anim()->play("equip", 0.0);
get_anim()->queue("hip");
}
void Rifle::on_primary_fire(bool pressed) {
if (pressed) {
shoot();
}
}
void Rifle::on_alt_mode(bool alt_mode) {
this->request_alt_mode = alt_mode;
}
@ -23,24 +70,23 @@ 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);
} else if (new_animation == "RESET") {
} else if (new_animation == "hip") {
this->in_alt_mode = false;
get_camera()->set_fov_factor(1.f);
get_camera()->set_fov_factor(1.0);
} else if (new_animation == "run") {
get_camera()->set_fov_factor(this->run_factor);
}
print_line(vformat("playing %s", new_animation));
Vector<String> queue{ get_anim()->get_queue() };
print_line(queue);
}
void Rifle::ready() {
get_anim()->connect("current_animation_changed", callable_mp(this, &self_type::on_animation_changed));
PlayerInput *input{ cast_to<PlayerInput>(get_node(NodePath("%PlayerInput"))) };
input->connect(PlayerInput::sig_primary_fire, callable_mp(this, &self_type::on_primary_fire));
input->connect(PlayerInput::sig_alt_mode, callable_mp(this, &self_type::on_alt_mode));
get_anim()->animation_set_next("hip_to_aim", "aim");
get_anim()->animation_set_next("fire_aim", "aim");
get_anim()->animation_set_next("aim_to_hip", "RESET");
get_anim()->animation_set_next("fire_hip", "RESET");
get_anim()->animation_set_next("equip", "RESET");
get_anim()->play("equip");
get_input()->connect(PlayerInput::sig_primary_fire, callable_mp(this, &self_type::on_primary_fire));
get_input()->connect(PlayerInput::sig_alt_mode, callable_mp(this, &self_type::on_alt_mode));
play_equip_anim();
}
void Rifle::process(double delta) {
@ -50,12 +96,27 @@ void Rifle::process(double delta) {
get_camera()->set_fov_factor(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 == "aim_to_run") {
get_camera()->set_fov_factor(Math::lerp(this->ads_factor, this->run_factor, 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));
} else if (this->request_alt_mode != this->in_alt_mode && current.is_empty()) {
get_anim()->clear_queue();
if (this->request_alt_mode) {
get_anim()->queue("hip_to_aim");
queue_start_aim();
} else {
get_anim()->queue("aim_to_hip");
queue_stop_ads_anim();
}
}
bool run_requested{ this->run_requested() };
if (this->running != run_requested) {
if (run_requested) {
queue_start_run_anim();
} else {
stop_run_anim();
}
}
}
@ -79,7 +140,11 @@ void Rifle::_notification(int what) {
bool Rifle::allows_running() const {
String const animation{ get_anim()->get_current_animation() };
return animation.is_empty();
return animation == "run" && !this->request_alt_mode;
}
bool Rifle::run_requested() const {
return get_body()->get_wants_to_run() && !this->request_alt_mode;
}
void Rifle::notify_selected() {

View file

@ -8,9 +8,16 @@ class PlayerBody;
class Rifle : public WeaponBase {
GDCLASS(Rifle, WeaponBase);
static void _bind_methods();
void queue_start_aim();
void queue_stop_ads_anim();
void queue_start_run_anim();
void stop_run_anim();
void shoot();
void play_equip_anim();
void on_primary_fire(bool down);
void on_alt_mode(bool alt_mode);
void on_animation_changed(String new_anim);
void on_run_input(bool run);
void ready();
void process(double delta);
@ -18,12 +25,15 @@ public:
void _notification(int what);
virtual bool allows_running() const override;
bool run_requested() const;
virtual void notify_selected() override;
private:
float ads_factor{ 0.5f };
float run_factor{ 1.5f };
bool request_alt_mode{ false };
bool in_alt_mode{ false };
bool running{ false };
};
#endif // !WEAPONS_RIFLE_H