diff --git a/assets/models/weapons/rifle.blend b/assets/models/weapons/rifle.blend index c81f0c8a..696e65fc 100644 Binary files a/assets/models/weapons/rifle.blend and b/assets/models/weapons/rifle.blend differ diff --git a/assets/models/weapons/rifle.blend1 b/assets/models/weapons/rifle.blend1 index c969a47c..f300367d 100644 Binary files a/assets/models/weapons/rifle.blend1 and b/assets/models/weapons/rifle.blend1 differ diff --git a/modules/wave_survival/player_input.cpp b/modules/wave_survival/player_input.cpp index 38bde740..e6f279d1 100644 --- a/modules/wave_survival/player_input.cpp +++ b/modules/wave_survival/player_input.cpp @@ -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 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); + } } diff --git a/modules/wave_survival/player_input.h b/modules/wave_survival/player_input.h index 18b8aaa2..9d737edc 100644 --- a/modules/wave_survival/player_input.h +++ b/modules/wave_survival/player_input.h @@ -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; diff --git a/modules/wave_survival/weapon_inventory.cpp b/modules/wave_survival/weapon_inventory.cpp index 0eafb27a..a338dc47 100644 --- a/modules/wave_survival/weapon_inventory.cpp +++ b/modules/wave_survival/weapon_inventory.cpp @@ -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(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(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 scene) { - this->fallback_weapon_scene = scene; -} - -Ref 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 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(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 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 scene) { + this->starting_weapon = scene; +} + +Ref WeaponInventory::get_starting_weapon() const { + return this->starting_weapon; +} diff --git a/modules/wave_survival/weapon_inventory.h b/modules/wave_survival/weapon_inventory.h index 3c4f572f..3905f35b 100644 --- a/modules/wave_survival/weapon_inventory.h +++ b/modules/wave_survival/weapon_inventory.h @@ -17,22 +17,21 @@ protected: void _notification(int what); public: - void set_fallback_weapon(Ref scene); - Ref get_fallback_weapon() const; - void select_weapon(WeaponBase *next); WeaponBase *get_current_weapon() const; void pickup_weapon(Ref weapon_scene); + void set_starting_weapon(Ref weapon_scene); + Ref get_starting_weapon() const; + private: Node3D *weapon_parent{ nullptr }; unsigned current{ 0 }; LocalVector weapons{ nullptr, nullptr }; WeaponBase *current_weapon{ nullptr }; - WeaponBase *fallback_weapon{ nullptr }; - Ref fallback_weapon_scene{}; + Ref starting_weapon{}; }; #endif // !WEAPON_INVENTORY_H diff --git a/modules/wave_survival/weapons/rifle.cpp b/modules/wave_survival/weapons/rifle.cpp index 576450fb..44eee370 100644 --- a/modules/wave_survival/weapons/rifle.cpp +++ b/modules/wave_survival/weapons/rifle.cpp @@ -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(); +} diff --git a/modules/wave_survival/weapons/rifle.h b/modules/wave_survival/weapons/rifle.h index 18984cf4..da442083 100644 --- a/modules/wave_survival/weapons/rifle.h +++ b/modules/wave_survival/weapons/rifle.h @@ -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 }; diff --git a/project/assets/models/weapons/rifle.glb b/project/assets/models/weapons/rifle.glb index 83b1eb26..a5fcc598 100644 Binary files a/project/assets/models/weapons/rifle.glb and b/project/assets/models/weapons/rifle.glb differ diff --git a/project/maps/testmap.tscn b/project/maps/testmap.tscn index 29a04d56..c2aa69fb 100644 --- a/project/maps/testmap.tscn +++ b/project/maps/testmap.tscn @@ -218,3 +218,171 @@ operation = 2 use_collision = true size = Vector3(1.43066, 2.25876, 1.43037) material = ExtResource("1_ng1ul") + +[node name="CSGBox3D28" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 8.115168, 1.13, -10.086953) +operation = 2 +use_collision = true +size = Vector3(9.8421, 3.074, 7.48355) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D29" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 8.115167, 1.13, -1.3881226) +operation = 2 +use_collision = true +size = Vector3(9.8421, 3.074, 9.25056) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D30" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 8.115166, 1.13, 7.136897) +operation = 2 +use_collision = true +size = Vector3(9.8421, 3.074, 7.48355) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D31" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 8.115168, 4.73767, -10.086953) +operation = 2 +use_collision = true +size = Vector3(9.8421, 3.074, 7.48355) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D32" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 8.115167, 4.73767, -1.3881226) +operation = 2 +use_collision = true +size = Vector3(9.8421, 3.074, 9.25056) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D33" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 8.115166, 4.73767, 7.136897) +operation = 2 +use_collision = true +size = Vector3(9.8421, 3.074, 7.48355) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D34" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1598587, 0.8431771, -9.042843) +operation = 2 +use_collision = true +size = Vector3(1.5039063, 2.81146, 1.43037) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D35" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 9.913068, 3.00782, -12.247253) +operation = 2 +use_collision = true +size = Vector3(4.11031, 1.01367, 3.05259) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D36" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837177, 5.15978, -12.238723) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 1.75998) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D37" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837177, 5.15978, -8.678133) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 3.01134) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D38" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837168, 5.15978, 0.8449067) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 1.75998) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D39" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837158, 1.63843, 9.061197) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 1.75998) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D40" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837168, 1.63843, 0.42633712) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 1.75998) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D41" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837168, 1.63843, -3.8672872) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 1.75998) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D42" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837177, 1.63843, -12.144593) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 1.75998) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D43" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837163, 5.15978, 5.070767) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 1.75998) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D44" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837168, 5.15978, -2.9607549) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 3.46446) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D45" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 3.1837158, 5.15978, 8.549497) +operation = 2 +use_collision = true +size = Vector3(1.64708, 1.47165, 3.46446) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D46" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-1, 0, 8.742278e-08, 0, 1, 0, -8.742278e-08, 0, -1, 2.8529863, 0.8431771, 6.304547) +operation = 2 +use_collision = true +size = Vector3(1.20117, 2.81146, 1.43037) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D47" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-4.3711378e-08, 0, -1, 0, 1, 0, 1, 0, -4.3711378e-08, 11.327666, 0.8431771, 3.6254973) +operation = 2 +use_collision = true +size = Vector3(1.71875, 2.81146, 1.43037) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D48" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-4.3711378e-08, 0, -1, 0, 1, 0, 1, 0, -4.3711378e-08, 5.6189175, 1.11953, -6.384443) +operation = 2 +use_collision = true +size = Vector3(1.43066, 2.25876, 1.43037) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D49" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-4.3711378e-08, 0, -1, 0, 1, 0, 1, 0, -4.3711378e-08, 5.6189175, 4.34085, -6.384443) +operation = 2 +use_collision = true +size = Vector3(1.43066, 2.25876, 1.43037) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D50" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(1, 0, 1.4210855e-14, 0, 1, 0, -1.4210855e-14, 0, 1, 13.222718, 4.340849, 5.694529) +operation = 2 +use_collision = true +size = Vector3(1.43066, 2.25876, 1.43037) +material = ExtResource("1_ng1ul") + +[node name="CSGBox3D51" type="CSGBox3D" parent="CSGCombiner3D"] +transform = Transform3D(-4.3711378e-08, 0, -1, 0, 1, 0, 1, 0, -4.3711378e-08, 11.184867, 4.34085, 3.3299174) +operation = 2 +use_collision = true +size = Vector3(1.43066, 2.25876, 1.43037) +material = ExtResource("1_ng1ul") diff --git a/project/objects/player.tscn b/project/objects/player.tscn index 5dd4c3d5..7da776e2 100644 --- a/project/objects/player.tscn +++ b/project/objects/player.tscn @@ -20,4 +20,4 @@ fov = 60.0 [node name="WeaponInventory" type="WeaponInventory" parent="."] unique_name_in_owner = true -fallback_weapon = ExtResource("1_eqqp1") +starting_weapon = ExtResource("1_eqqp1") diff --git a/project/project.godot b/project/project.godot index d047f4a3..a704bb1d 100644 --- a/project/project.godot +++ b/project/project.godot @@ -62,3 +62,8 @@ jump={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null) ] } +switch_weapon={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194306,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +}