feat: weapon swapping
This commit is contained in:
parent
6b7a092961
commit
7a13823c97
|
@ -39,7 +39,9 @@ public:
|
||||||
|
|
||||||
virtual bool allows_running() const { return false; }
|
virtual bool allows_running() const { return false; }
|
||||||
virtual bool allows_jumping() const { return true; }
|
virtual bool allows_jumping() const { return true; }
|
||||||
|
virtual bool allows_swapping() const { return true; }
|
||||||
virtual void notify_selected() {}
|
virtual void notify_selected() {}
|
||||||
|
virtual void notify_deselected() {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PlayerInput *input{ nullptr };
|
PlayerInput *input{ nullptr };
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "weapon_inventory.h"
|
#include "weapon_inventory.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
#include "player_input.h"
|
||||||
#include "weapon_base.h"
|
#include "weapon_base.h"
|
||||||
|
|
||||||
void WeaponInventory::_bind_methods() {
|
void WeaponInventory::_bind_methods() {
|
||||||
|
@ -10,13 +11,18 @@ void WeaponInventory::_bind_methods() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeaponInventory::on_switch_input() {
|
void WeaponInventory::on_switch_input() {
|
||||||
this->current = (this->current + 1) % 1;
|
unsigned next{ (this->current + 1) % 2 };
|
||||||
this->select_weapon(this->weapons[this->current]);
|
if (this->weapons[next] != nullptr) {
|
||||||
|
this->select_weapon(this->weapons[next]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeaponInventory::ready() {
|
void WeaponInventory::ready() {
|
||||||
callable_mp(this, &self_type::pickup_weapon).call_deferred(this->starting_weapon);
|
callable_mp(this, &self_type::pickup_weapon).call_deferred(this->starting_weapon);
|
||||||
this->weapon_parent = cast_to<Node3D>(get_node(NodePath("%PlayerCamera")));
|
this->weapon_parent = cast_to<Node3D>(get_node(NodePath("%PlayerCamera")));
|
||||||
|
if (PlayerInput * input{ cast_to<PlayerInput>(get_node(NodePath("%PlayerInput"))) }) {
|
||||||
|
input->connect(PlayerInput::sig_switch_weapon, callable_mp(this, &self_type::on_switch_input));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeaponInventory::_notification(int what) {
|
void WeaponInventory::_notification(int what) {
|
||||||
|
@ -37,6 +43,9 @@ void WeaponInventory::select_weapon(WeaponBase *new_weapon) {
|
||||||
print_error("WeaponInventory::select_weapon: Weapon invalid, returning before taking any action.");
|
print_error("WeaponInventory::select_weapon: Weapon invalid, returning before taking any action.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this->current_weapon != nullptr && !this->current_weapon->allows_swapping()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (new_weapon == this->weapons[0]) {
|
if (new_weapon == this->weapons[0]) {
|
||||||
this->current = 0;
|
this->current = 0;
|
||||||
} else if (new_weapon == this->weapons[1]) {
|
} else if (new_weapon == this->weapons[1]) {
|
||||||
|
@ -48,6 +57,7 @@ void WeaponInventory::select_weapon(WeaponBase *new_weapon) {
|
||||||
if (this->current_weapon != nullptr) {
|
if (this->current_weapon != nullptr) {
|
||||||
this->current_weapon->set_process_mode(PROCESS_MODE_DISABLED);
|
this->current_weapon->set_process_mode(PROCESS_MODE_DISABLED);
|
||||||
this->current_weapon->set_visible(false);
|
this->current_weapon->set_visible(false);
|
||||||
|
this->current_weapon->notify_deselected();
|
||||||
}
|
}
|
||||||
this->current_weapon = new_weapon;
|
this->current_weapon = new_weapon;
|
||||||
if (this->current_weapon != nullptr) {
|
if (this->current_weapon != nullptr) {
|
||||||
|
@ -63,7 +73,7 @@ WeaponBase *WeaponInventory::get_current_weapon() const {
|
||||||
|
|
||||||
void WeaponInventory::pickup_weapon(Ref<PackedScene> weapon_scene) {
|
void WeaponInventory::pickup_weapon(Ref<PackedScene> weapon_scene) {
|
||||||
if (!weapon_scene.is_valid()) {
|
if (!weapon_scene.is_valid()) {
|
||||||
print_error("WeaponInventory::pickup_weapon: passed weapon scene");
|
print_error("WeaponInventory::pickup_weapon: passed weapon scene is invalid");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Node *weapon_as_node{ weapon_scene->instantiate() };
|
Node *weapon_as_node{ weapon_scene->instantiate() };
|
||||||
|
@ -73,22 +83,18 @@ void WeaponInventory::pickup_weapon(Ref<PackedScene> weapon_scene) {
|
||||||
// Where to put the new weapon, consider empty slot 1, then empty slot 2, then replace current.
|
// Where to put the new weapon, consider empty slot 1, then empty slot 2, then replace current.
|
||||||
if (this->weapons[0] == nullptr) {
|
if (this->weapons[0] == nullptr) {
|
||||||
this->weapons[0] = weapon;
|
this->weapons[0] = weapon;
|
||||||
select_weapon(weapon);
|
|
||||||
return;
|
|
||||||
} else if (this->weapons[1] == nullptr) {
|
} else if (this->weapons[1] == nullptr) {
|
||||||
this->weapons[1] = weapon;
|
this->weapons[1] = weapon;
|
||||||
select_weapon(weapon);
|
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
// replace current weapon, assign the slot
|
// replace current weapon, assign the slot
|
||||||
this->weapons[this->current] = weapon;
|
this->weapons[this->current] = weapon;
|
||||||
// free the current weapon
|
// free the current weapon
|
||||||
this->current_weapon->queue_free();
|
this->current_weapon->queue_free();
|
||||||
// set the point to null, so select_weapon will skip dropping the current weapon.
|
// set the current to null, so select_weapon will skip dropping it
|
||||||
this->current_weapon = nullptr;
|
this->current_weapon = nullptr;
|
||||||
// equip new weapon
|
|
||||||
select_weapon(weapon);
|
|
||||||
}
|
}
|
||||||
|
// equip new weapon
|
||||||
|
select_weapon(weapon);
|
||||||
} else if (weapon_as_node != nullptr) {
|
} else if (weapon_as_node != nullptr) {
|
||||||
print_error(vformat("WeaponInventory::pickup_weapon: weapon scene '%s' instantiated a node of type '%s', which does not inherit from 'WeaponBase'", weapon_scene->get_path(), weapon_as_node->get_class()));
|
print_error(vformat("WeaponInventory::pickup_weapon: weapon scene '%s' instantiated a node of type '%s', which does not inherit from 'WeaponBase'", weapon_scene->get_path(), weapon_as_node->get_class()));
|
||||||
weapon_as_node->queue_free();
|
weapon_as_node->queue_free();
|
||||||
|
|
|
@ -141,10 +141,6 @@ void Revolver::ready() {
|
||||||
this->muzzle = cast_to<HitscanMuzzle>(get_node(NodePath("%HitscanMuzzle")));
|
this->muzzle = cast_to<HitscanMuzzle>(get_node(NodePath("%HitscanMuzzle")));
|
||||||
get_anim()->connect("animation_changed", callable_mp(this, &self_type::on_animation_changed));
|
get_anim()->connect("animation_changed", callable_mp(this, &self_type::on_animation_changed));
|
||||||
get_anim()->connect("animation_finished", callable_mp(this, &self_type::on_animation_finished));
|
get_anim()->connect("animation_finished", callable_mp(this, &self_type::on_animation_finished));
|
||||||
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));
|
|
||||||
get_input()->connect(PlayerInput::sig_reload, callable_mp(this, &self_type::on_reload));
|
|
||||||
play_equip_anim();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Revolver::process(double delta) {
|
void Revolver::process(double delta) {
|
||||||
|
@ -187,9 +183,18 @@ void Revolver::_notification(int what) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Revolver::notify_selected() {
|
void Revolver::notify_selected() {
|
||||||
|
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));
|
||||||
|
get_input()->connect(PlayerInput::sig_reload, callable_mp(this, &self_type::on_reload));
|
||||||
play_equip_anim();
|
play_equip_anim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Revolver::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));
|
||||||
|
}
|
||||||
|
|
||||||
bool Revolver::allows_running() const {
|
bool Revolver::allows_running() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ class Revolver : public WeaponBase {
|
||||||
protected:
|
protected:
|
||||||
void _notification(int what);
|
void _notification(int what);
|
||||||
virtual void notify_selected() override;
|
virtual void notify_selected() override;
|
||||||
|
virtual void notify_deselected() override;
|
||||||
virtual bool allows_running() const override;
|
virtual bool allows_running() const override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -102,10 +102,6 @@ void Rifle::on_animation_changed(String new_animation) {
|
||||||
void Rifle::ready() {
|
void Rifle::ready() {
|
||||||
this->muzzle = cast_to<HitscanMuzzle>(get_node(NodePath("%HitscanMuzzle")));
|
this->muzzle = cast_to<HitscanMuzzle>(get_node(NodePath("%HitscanMuzzle")));
|
||||||
get_anim()->connect("current_animation_changed", callable_mp(this, &self_type::on_animation_changed));
|
get_anim()->connect("current_animation_changed", callable_mp(this, &self_type::on_animation_changed));
|
||||||
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));
|
|
||||||
get_input()->connect(PlayerInput::sig_reload, callable_mp(this, &self_type::on_reload));
|
|
||||||
play_equip_anim();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rifle::process(double delta) {
|
void Rifle::process(double delta) {
|
||||||
|
@ -173,6 +169,11 @@ PackedStringArray Rifle::get_configuration_warnings() const {
|
||||||
return warnings;
|
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 {
|
bool Rifle::allows_running() const {
|
||||||
String const animation{ get_anim()->get_current_animation() };
|
String const animation{ get_anim()->get_current_animation() };
|
||||||
return animation == "run" && !this->request_alt_mode;
|
return animation == "run" && !this->request_alt_mode;
|
||||||
|
@ -183,9 +184,18 @@ bool Rifle::run_requested() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rifle::notify_selected() {
|
void Rifle::notify_selected() {
|
||||||
|
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));
|
||||||
|
get_input()->connect(PlayerInput::sig_reload, callable_mp(this, &self_type::on_reload));
|
||||||
play_equip_anim();
|
play_equip_anim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
void Rifle::reload_full() {
|
void Rifle::reload_full() {
|
||||||
int const available = get_inventory()->withdraw_rifle_ammo(get_max_ammo());
|
int const available = get_inventory()->withdraw_rifle_ammo(get_max_ammo());
|
||||||
reload_num(available);
|
reload_num(available);
|
||||||
|
|
|
@ -27,9 +27,11 @@ public:
|
||||||
void _notification(int what);
|
void _notification(int what);
|
||||||
virtual PackedStringArray get_configuration_warnings() const override;
|
virtual PackedStringArray get_configuration_warnings() const override;
|
||||||
|
|
||||||
|
virtual bool allows_swapping() const override;
|
||||||
virtual bool allows_running() const override;
|
virtual bool allows_running() const override;
|
||||||
bool run_requested() const;
|
bool run_requested() const;
|
||||||
virtual void notify_selected() override;
|
virtual void notify_selected() override;
|
||||||
|
virtual void notify_deselected() override;
|
||||||
void reload_full();
|
void reload_full();
|
||||||
|
|
||||||
void set_ads_factor(float value);
|
void set_ads_factor(float value);
|
||||||
|
|
Loading…
Reference in a new issue