feat: replace 'fallback weapon' with 'starting weapon'
This commit is contained in:
parent
a93e79cd1c
commit
01b69df872
12 changed files with 233 additions and 57 deletions
|
|
@ -4,6 +4,7 @@ String PlayerInput::sig_movement_input{ "movement_input" };
|
|||
String PlayerInput::sig_look_input{ "look_input" };
|
||||
String PlayerInput::sig_primary_fire{ "primary_fire" };
|
||||
String PlayerInput::sig_alt_mode{ "alt_mode" };
|
||||
String PlayerInput::sig_switch_weapon{ "switch_weapon" };
|
||||
String PlayerInput::sig_run{ "run" };
|
||||
String PlayerInput::sig_jump{ "jump" };
|
||||
String PlayerInput::sig_crouch{ "crouch" };
|
||||
|
|
@ -13,6 +14,7 @@ void PlayerInput::_bind_methods() {
|
|||
ADD_SIGNAL(MethodInfo(sig_look_input, PropertyInfo(Variant::VECTOR2, "axes")));
|
||||
ADD_SIGNAL(MethodInfo(sig_primary_fire, PropertyInfo(Variant::BOOL, "is_pressed")));
|
||||
ADD_SIGNAL(MethodInfo(sig_alt_mode, PropertyInfo(Variant::BOOL, "is_active")));
|
||||
ADD_SIGNAL(MethodInfo(sig_switch_weapon));
|
||||
ADD_SIGNAL(MethodInfo(sig_run, PropertyInfo(Variant::BOOL, "is_running")));
|
||||
ADD_SIGNAL(MethodInfo(sig_jump));
|
||||
ADD_SIGNAL(MethodInfo(sig_crouch, PropertyInfo(Variant::BOOL, "is_crouching")));
|
||||
|
|
@ -57,4 +59,7 @@ void PlayerInput::unhandled_input(Ref<InputEvent> const &event) {
|
|||
if (event->is_pressed() && event->is_action("jump") && input->is_action_just_pressed("jump")) {
|
||||
emit_signal(sig_jump);
|
||||
}
|
||||
if (event->is_action("switch_weapon") && event->is_pressed()) {
|
||||
emit_signal(sig_switch_weapon);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public:
|
|||
static String sig_look_input;
|
||||
static String sig_primary_fire;
|
||||
static String sig_alt_mode;
|
||||
static String sig_switch_weapon;
|
||||
static String sig_run;
|
||||
static String sig_jump;
|
||||
static String sig_crouch;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include "weapon_base.h"
|
||||
|
||||
void WeaponInventory::_bind_methods() {
|
||||
BIND_HPROPERTY(Variant::OBJECT, fallback_weapon, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
|
||||
BIND_HPROPERTY(Variant::OBJECT, starting_weapon, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
|
||||
}
|
||||
|
||||
void WeaponInventory::on_switch_input() {
|
||||
|
|
@ -12,20 +12,8 @@ void WeaponInventory::on_switch_input() {
|
|||
}
|
||||
|
||||
void WeaponInventory::ready() {
|
||||
// initialize the fallback weapon
|
||||
callable_mp(this, &self_type::pickup_weapon).call_deferred(this->starting_weapon);
|
||||
this->weapon_parent = cast_to<Node3D>(get_node(NodePath("%PlayerCamera")));
|
||||
if (this->fallback_weapon_scene.is_valid()) {
|
||||
Node *fallback_as_node{ this->fallback_weapon_scene->instantiate() };
|
||||
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) {
|
||||
fallback_as_node->queue_free();
|
||||
}
|
||||
}
|
||||
if (this->fallback_weapon == nullptr) {
|
||||
print_error("WeaponInventory::ready(): fallback weapon is invalid, expect unintended behaviour.");
|
||||
}
|
||||
}
|
||||
|
||||
void WeaponInventory::_notification(int what) {
|
||||
|
|
@ -41,34 +29,28 @@ void WeaponInventory::_notification(int what) {
|
|||
}
|
||||
}
|
||||
|
||||
void WeaponInventory::set_fallback_weapon(Ref<PackedScene> scene) {
|
||||
this->fallback_weapon_scene = scene;
|
||||
}
|
||||
|
||||
Ref<PackedScene> WeaponInventory::get_fallback_weapon() const {
|
||||
return this->fallback_weapon_scene;
|
||||
}
|
||||
|
||||
void WeaponInventory::select_weapon(WeaponBase *new_weapon) {
|
||||
if (new_weapon == nullptr) {
|
||||
new_weapon = this->fallback_weapon;
|
||||
print_error("WeaponInventory::select_weapon: Weapon invalid, returning before taking any action.");
|
||||
return;
|
||||
}
|
||||
if (new_weapon == this->weapons[0]) {
|
||||
this->current = 0;
|
||||
} else if (new_weapon == this->weapons[1]) {
|
||||
this->current = 1;
|
||||
} else {
|
||||
print_error("WeaponInventory::select_weapon: Attempt to select weapon that is not in inventory. Exiting with no current weapon.");
|
||||
return;
|
||||
}
|
||||
if (this->current_weapon != nullptr) {
|
||||
this->current_weapon->set_process_mode(PROCESS_MODE_DISABLED);
|
||||
this->current_weapon->set_visible(false);
|
||||
}
|
||||
this->current_weapon = new_weapon;
|
||||
if (new_weapon != nullptr) {
|
||||
if (this->current_weapon != nullptr) {
|
||||
this->current_weapon->set_process_mode(PROCESS_MODE_PAUSABLE);
|
||||
this->current_weapon->set_visible(true);
|
||||
this->current_weapon->notify_selected();
|
||||
if (new_weapon == this->weapons[0]) {
|
||||
this->current = 0;
|
||||
} else if (new_weapon == this->weapons[1]) {
|
||||
this->current = 1;
|
||||
} else {
|
||||
print_error("WeaponInventory::select_weapon: Attempt to select weapon that is not in inventory");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -77,8 +59,14 @@ WeaponBase *WeaponInventory::get_current_weapon() const {
|
|||
}
|
||||
|
||||
void WeaponInventory::pickup_weapon(Ref<PackedScene> weapon_scene) {
|
||||
if (!weapon_scene.is_valid()) {
|
||||
print_error("WeaponInventory::pickup_weapon: passed weapon scene");
|
||||
return;
|
||||
}
|
||||
Node *weapon_as_node{ weapon_scene->instantiate() };
|
||||
if (WeaponBase * weapon{ cast_to<WeaponBase>(weapon_as_node) }) {
|
||||
this->weapon_parent->add_child(weapon_as_node);
|
||||
// Where to put the new weapon, consider empty slot 1, then empty slot 2, then replace current.
|
||||
if (this->weapons[0] == nullptr) {
|
||||
this->weapons[0] = weapon;
|
||||
select_weapon(weapon);
|
||||
|
|
@ -88,12 +76,27 @@ void WeaponInventory::pickup_weapon(Ref<PackedScene> weapon_scene) {
|
|||
select_weapon(weapon);
|
||||
return;
|
||||
} else {
|
||||
this->current_weapon->queue_free();
|
||||
// replace current weapon, assign the slot
|
||||
this->weapons[this->current] = weapon;
|
||||
// free the current weapon
|
||||
this->current_weapon->queue_free();
|
||||
// set the point to null, so select_weapon will skip dropping the current weapon.
|
||||
this->current_weapon = nullptr;
|
||||
// equip new weapon
|
||||
select_weapon(weapon);
|
||||
}
|
||||
} 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()));
|
||||
weapon_as_node->queue_free();
|
||||
} else {
|
||||
print_error(vformat("WeaponInventory::pickup_weapon: passed weapon scene '%s' did not instantiate a valid node", weapon_scene->get_path()));
|
||||
}
|
||||
}
|
||||
|
||||
void WeaponInventory::set_starting_weapon(Ref<PackedScene> scene) {
|
||||
this->starting_weapon = scene;
|
||||
}
|
||||
|
||||
Ref<PackedScene> WeaponInventory::get_starting_weapon() const {
|
||||
return this->starting_weapon;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,22 +17,21 @@ protected:
|
|||
void _notification(int what);
|
||||
|
||||
public:
|
||||
void set_fallback_weapon(Ref<PackedScene> scene);
|
||||
Ref<PackedScene> get_fallback_weapon() const;
|
||||
|
||||
void select_weapon(WeaponBase *next);
|
||||
WeaponBase *get_current_weapon() const;
|
||||
|
||||
void pickup_weapon(Ref<PackedScene> weapon_scene);
|
||||
|
||||
void set_starting_weapon(Ref<PackedScene> weapon_scene);
|
||||
Ref<PackedScene> get_starting_weapon() const;
|
||||
|
||||
private:
|
||||
Node3D *weapon_parent{ nullptr };
|
||||
unsigned current{ 0 };
|
||||
LocalVector<WeaponBase *> weapons{ nullptr, nullptr };
|
||||
WeaponBase *current_weapon{ nullptr };
|
||||
WeaponBase *fallback_weapon{ nullptr };
|
||||
|
||||
Ref<PackedScene> fallback_weapon_scene{};
|
||||
Ref<PackedScene> starting_weapon{};
|
||||
};
|
||||
|
||||
#endif // !WEAPON_INVENTORY_H
|
||||
|
|
|
|||
|
|
@ -11,15 +11,8 @@ void Rifle::queue_start_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");
|
||||
}
|
||||
get_anim()->queue("aim_to_hip");
|
||||
get_anim()->queue("hip");
|
||||
}
|
||||
|
||||
void Rifle::queue_start_run_anim() {
|
||||
|
|
@ -42,10 +35,10 @@ void Rifle::stop_run_anim() {
|
|||
}
|
||||
|
||||
void Rifle::shoot() {
|
||||
if (get_anim()->get_queue().size() == 0 && get_anim()->get_current_animation() == "") {
|
||||
if (!is_animating()) {
|
||||
if (this->request_alt_mode) {
|
||||
get_anim()->queue("fire_aim");
|
||||
} else if (get_anim()->get_current_animation() == "") {
|
||||
} else {
|
||||
get_anim()->queue("fire_hip");
|
||||
}
|
||||
}
|
||||
|
|
@ -91,31 +84,28 @@ void Rifle::ready() {
|
|||
|
||||
void Rifle::process(double delta) {
|
||||
String const current{ get_anim()->get_current_animation() };
|
||||
bool run_requested{ this->run_requested() };
|
||||
float const progress{ float(CLAMP(get_anim()->get_current_animation_position() / get_anim()->get_current_animation_length(), 0.0, 1.0)) };
|
||||
if (current == "hip_to_aim") {
|
||||
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()) {
|
||||
} else if (this->request_alt_mode != this->in_alt_mode && !is_animating()) {
|
||||
if (this->request_alt_mode) {
|
||||
queue_start_aim();
|
||||
} else {
|
||||
queue_stop_ads_anim();
|
||||
}
|
||||
}
|
||||
bool run_requested{ this->run_requested() };
|
||||
if (this->running != run_requested) {
|
||||
if (run_requested) {
|
||||
} else if (this->running != run_requested) {
|
||||
if (run_requested && !is_animating()) {
|
||||
queue_start_run_anim();
|
||||
} else {
|
||||
} else if (!run_requested) {
|
||||
stop_run_anim();
|
||||
}
|
||||
}
|
||||
|
|
@ -150,3 +140,7 @@ bool Rifle::run_requested() const {
|
|||
void Rifle::notify_selected() {
|
||||
get_anim()->play("equip");
|
||||
}
|
||||
|
||||
bool Rifle::is_animating() const {
|
||||
return !get_anim()->get_current_animation().is_empty() || !get_anim()->get_queue().is_empty();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public:
|
|||
virtual bool allows_running() const override;
|
||||
bool run_requested() const;
|
||||
virtual void notify_selected() override;
|
||||
bool is_animating() const;
|
||||
|
||||
private:
|
||||
float ads_factor{ 0.5f };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue