feat: added revolver
This commit is contained in:
		
							parent
							
								
									3b22cd86f7
								
							
						
					
					
						commit
						6eba3b0454
					
				
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -19,6 +19,7 @@ | |||
| #include "wave_survival/state_machine.h" | ||||
| #include "wave_survival/weapon_base.h" | ||||
| #include "wave_survival/weapon_inventory.h" | ||||
| #include "wave_survival/weapons/revolver.h" | ||||
| #include "wave_survival/weapons/rifle.h" | ||||
| 
 | ||||
| void initialize_wave_survival_module(ModuleInitializationLevel p_level) { | ||||
|  | @ -47,6 +48,7 @@ void initialize_wave_survival_module(ModuleInitializationLevel p_level) { | |||
| 	GDREGISTER_CLASS(DamageBox); | ||||
| 	GDREGISTER_CLASS(PlayerInteractor); | ||||
| 	GDREGISTER_CLASS(Interactable); | ||||
| 	GDREGISTER_CLASS(Revolver); | ||||
| } | ||||
| 
 | ||||
| void uninitialize_wave_survival_module(ModuleInitializationLevel p_level) { | ||||
|  |  | |||
|  | @ -13,9 +13,6 @@ void WeaponBase::ready() { | |||
| 	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"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void WeaponBase::_notification(int what) { | ||||
|  | @ -30,6 +27,20 @@ void WeaponBase::_notification(int what) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| PackedStringArray WeaponBase::get_configuration_warnings() const { | ||||
| 	PackedStringArray warnings{ super_type::get_configuration_warnings() }; | ||||
| 
 | ||||
| 	if (this->anim == nullptr) { | ||||
| 		warnings.push_back("Weapons need something to animate them.\nRemember to configure the 'anim' property on this weapon"); | ||||
| 	} | ||||
| 
 | ||||
| 	return warnings; | ||||
| } | ||||
| 
 | ||||
| bool WeaponBase::is_animating() const { | ||||
| 	return !get_anim()->get_current_animation().is_empty() || !get_anim()->get_queue().is_empty(); | ||||
| } | ||||
| 
 | ||||
| void WeaponBase::set_anim(AnimationPlayer *anim) { | ||||
| 	this->anim = anim; | ||||
| } | ||||
|  |  | |||
|  | @ -14,8 +14,10 @@ class WeaponBase : public Node3D { | |||
| 
 | ||||
| protected: | ||||
| 	void _notification(int what); | ||||
| 	virtual PackedStringArray get_configuration_warnings() const override; | ||||
| 
 | ||||
| public: | ||||
| 	bool is_animating() const; | ||||
| 	void set_anim(AnimationPlayer *player); | ||||
| 	AnimationPlayer *get_anim() const; | ||||
| 	PlayerInput *get_input() const; | ||||
|  | @ -24,7 +26,7 @@ public: | |||
| 	void set_body(PlayerBody *body); | ||||
| 	PlayerBody *get_body() const; | ||||
| 
 | ||||
| 	virtual bool allows_running() const { return true; } | ||||
| 	virtual bool allows_running() const { return false; } | ||||
| 	virtual bool allows_jumping() const { return true; } | ||||
| 	virtual void notify_selected() {} | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										66
									
								
								modules/wave_survival/weapons/revolver.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								modules/wave_survival/weapons/revolver.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,66 @@ | |||
| #include "revolver.h" | ||||
| #include "scene/animation/animation_player.h" | ||||
| #include "wave_survival/player_input.h" | ||||
| 
 | ||||
| void Revolver::_bind_methods() { | ||||
| } | ||||
| 
 | ||||
| void Revolver::play_equip_anim() { | ||||
| 	get_anim()->play("equip", 0.0); | ||||
| 	get_anim()->queue("idle_double"); | ||||
| 	get_anim()->advance(0.0); | ||||
| } | ||||
| 
 | ||||
| void Revolver::shoot() { | ||||
| 	if (!is_animating()) { | ||||
| 		this->muzzle->shoot(); | ||||
| 		if (this->alt_requested) { | ||||
| 			get_anim()->queue("fire_single"); | ||||
| 			get_anim()->queue("idle_single"); | ||||
| 		} else { | ||||
| 			get_anim()->queue("fire_double"); | ||||
| 			get_anim()->queue("idle_double"); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void Revolver::on_primary_fire(bool pressed) { | ||||
| 	if (pressed) { | ||||
| 		shoot(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void Revolver::on_alt_mode(bool pressed) { | ||||
| 	this->alt_requested = pressed; | ||||
| } | ||||
| 
 | ||||
| void Revolver::ready() { | ||||
| 	this->muzzle = cast_to<HitscanMuzzle>(get_node(NodePath("%HitscanMuzzle"))); | ||||
| 	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 Revolver::process(double delta) { | ||||
| } | ||||
| 
 | ||||
| void Revolver::_notification(int what) { | ||||
| 	if (Engine::get_singleton()->is_editor_hint()) { | ||||
| 		return; | ||||
| 	} | ||||
| 	switch (what) { | ||||
| 		default: | ||||
| 			return; | ||||
| 		case NOTIFICATION_READY: | ||||
| 			set_process(true); | ||||
| 			ready(); | ||||
| 			return; | ||||
| 		case NOTIFICATION_PROCESS: | ||||
| 			process(get_process_delta_time()); | ||||
| 			return; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void Revolver::notify_selected() { | ||||
| 	play_equip_anim(); | ||||
| } | ||||
							
								
								
									
										27
									
								
								modules/wave_survival/weapons/revolver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								modules/wave_survival/weapons/revolver.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| #ifndef WEAPONS_REVOLVER_H | ||||
| #define WEAPONS_REVOLVER_H | ||||
| 
 | ||||
| #include "wave_survival/hitscan_muzzle.h" | ||||
| #include "wave_survival/weapon_base.h" | ||||
| 
 | ||||
| class Revolver : public WeaponBase { | ||||
| 	GDCLASS(Revolver, WeaponBase); | ||||
| 	static void _bind_methods(); | ||||
| 	void play_equip_anim(); | ||||
| 	void shoot(); | ||||
| 	void on_primary_fire(bool pressed); | ||||
| 	void on_alt_mode(bool pressed); | ||||
| 	void ready(); | ||||
| 	void process(double delta); | ||||
| 
 | ||||
| protected: | ||||
| 	void _notification(int what); | ||||
| 	virtual void notify_selected() override; | ||||
| 
 | ||||
| private: | ||||
| 	bool alt_requested{ false }; | ||||
| 	bool alt_active{ false }; | ||||
| 	HitscanMuzzle *muzzle{ nullptr }; | ||||
| }; | ||||
| 
 | ||||
| #endif // !WEAPONS_REVOLVER_H
 | ||||
|  | @ -12,24 +12,24 @@ void Rifle::_bind_methods() { | |||
| 	BIND_PROPERTY(Variant::FLOAT, recoil_time); | ||||
| } | ||||
| 
 | ||||
| void Rifle::queue_start_aim() { | ||||
| void Rifle::queue_enter_alt() { | ||||
| 	get_anim()->queue("hip_to_aim"); | ||||
| 	get_anim()->queue("aim"); | ||||
| } | ||||
| 
 | ||||
| void Rifle::queue_stop_ads_anim() { | ||||
| void Rifle::queue_exit_alt() { | ||||
| 	get_anim()->queue("aim_to_hip"); | ||||
| 	get_anim()->queue("hip"); | ||||
| } | ||||
| 
 | ||||
| void Rifle::queue_start_run_anim() { | ||||
| void Rifle::queue_enter_run() { | ||||
| 	this->running = true; | ||||
| 	get_anim()->clear_queue(); | ||||
| 	get_anim()->queue("hip_to_run"); | ||||
| 	get_anim()->queue("run"); | ||||
| } | ||||
| 
 | ||||
| void Rifle::stop_run_anim() { | ||||
| void Rifle::exit_run() { | ||||
| 	this->running = false; | ||||
| 	get_anim()->clear_queue(); | ||||
| 	if (this->request_alt_mode) { | ||||
|  | @ -55,6 +55,7 @@ void Rifle::shoot() { | |||
| void Rifle::play_equip_anim() { | ||||
| 	get_anim()->play("equip", 0.0); | ||||
| 	get_anim()->queue("hip"); | ||||
| 	get_anim()->advance(0.0); | ||||
| } | ||||
| 
 | ||||
| void Rifle::on_primary_fire(bool pressed) { | ||||
|  | @ -90,8 +91,11 @@ void Rifle::ready() { | |||
| void Rifle::process(double delta) { | ||||
| 	String const current{ get_anim()->get_current_animation() }; | ||||
| 	bool run_requested{ this->run_requested() }; | ||||
| 	// track animation progress
 | ||||
| 	double const animation_time{ get_anim()->get_current_animation_position() }; | ||||
| 	// 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)); | ||||
| 	} else if (current == "aim_to_hip") { | ||||
|  | @ -102,21 +106,23 @@ void Rifle::process(double delta) { | |||
| 		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()) { | ||||
| 		if (this->request_alt_mode) { | ||||
| 			queue_start_aim(); | ||||
| 			queue_enter_alt(); | ||||
| 		} else { | ||||
| 			queue_stop_ads_anim(); | ||||
| 			queue_exit_alt(); | ||||
| 		} | ||||
| 	} else if (this->running != run_requested) { | ||||
| 		if (run_requested && !is_animating()) { | ||||
| 			queue_start_run_anim(); | ||||
| 			queue_enter_run(); | ||||
| 		} else if (!run_requested) { | ||||
| 			stop_run_anim(); | ||||
| 			exit_run(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (current == "fire_hip" || current == "fire_aim") { | ||||
| 	// apply fire recoil
 | ||||
| 	else if (current == "fire_hip" || current == "fire_aim") { | ||||
| 		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); | ||||
| 	} | ||||
|  | @ -139,6 +145,14 @@ void Rifle::_notification(int what) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| PackedStringArray Rifle::get_configuration_warnings() const { | ||||
| 	PackedStringArray warnings{ super_type::get_configuration_warnings() }; | ||||
| 	if (get_node(NodePath("%HitscanMuzzle")) == nullptr) { | ||||
| 		warnings.push_back("Rifle needs a hitscan muzzle.\nConsider adding a node called '%HitscanMuzzle' of type HitscanMuzzle"); | ||||
| 	} | ||||
| 	return warnings; | ||||
| } | ||||
| 
 | ||||
| bool Rifle::allows_running() const { | ||||
| 	String const animation{ get_anim()->get_current_animation() }; | ||||
| 	return animation == "run" && !this->request_alt_mode; | ||||
|  | @ -149,11 +163,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(); | ||||
| 	play_equip_anim(); | ||||
| } | ||||
| 
 | ||||
| void Rifle::set_ads_factor(float value) { | ||||
|  |  | |||
|  | @ -9,10 +9,10 @@ class HitscanMuzzle; | |||
| 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 queue_enter_alt(); | ||||
| 	void queue_exit_alt(); | ||||
| 	void queue_enter_run(); | ||||
| 	void exit_run(); | ||||
| 	void shoot(); | ||||
| 	void play_equip_anim(); | ||||
| 	void on_primary_fire(bool down); | ||||
|  | @ -24,11 +24,11 @@ class Rifle : public WeaponBase { | |||
| 
 | ||||
| public: | ||||
| 	void _notification(int what); | ||||
| 	virtual PackedStringArray get_configuration_warnings() const override; | ||||
| 
 | ||||
| 	virtual bool allows_running() const override; | ||||
| 	bool run_requested() const; | ||||
| 	virtual void notify_selected() override; | ||||
| 	bool is_animating() const; | ||||
| 
 | ||||
| 	void set_ads_factor(float value); | ||||
| 	float get_ads_factor() const; | ||||
|  |  | |||
										
											Binary file not shown.
										
									
								
							|  | @ -37,7 +37,25 @@ import_script/path="" | |||
| materials/extract=0 | ||||
| materials/extract_format=0 | ||||
| materials/extract_path="" | ||||
| _subresources={} | ||||
| _subresources={ | ||||
| "materials": { | ||||
| "body": { | ||||
| "use_external/enabled": true, | ||||
| "use_external/fallback_path": "res://assets/materials/weapons/arms.tres", | ||||
| "use_external/path": "uid://dgl8ygpyta7b0" | ||||
| }, | ||||
| "metal": { | ||||
| "use_external/enabled": true, | ||||
| "use_external/fallback_path": "res://assets/materials/weapons/metal.tres", | ||||
| "use_external/path": "uid://cey2t4uje80f3" | ||||
| }, | ||||
| "wood": { | ||||
| "use_external/enabled": true, | ||||
| "use_external/fallback_path": "res://assets/materials/weapons/wood.tres", | ||||
| "use_external/path": "uid://bvy3xngb287wd" | ||||
| } | ||||
| } | ||||
| } | ||||
| blender/nodes/visible=0 | ||||
| blender/nodes/active_collection_only=false | ||||
| blender/nodes/punctual_lights=true | ||||
|  |  | |||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -1,6 +1,6 @@ | |||
| [gd_scene load_steps=6 format=3 uid="uid://snjgu4yp5swd"] | ||||
| 
 | ||||
| [ext_resource type="PackedScene" uid="uid://ce40pq785yoyi" path="res://objects/weapons/rifle.tscn" id="1_eqqp1"] | ||||
| [ext_resource type="PackedScene" uid="uid://cfgwif53qypko" path="res://objects/weapons/revolver.tscn" id="1_eqqp1"] | ||||
| 
 | ||||
| [sub_resource type="SphereShape3D" id="SphereShape3D_eqqp1"] | ||||
| radius = 0.2 | ||||
|  |  | |||
							
								
								
									
										29
									
								
								project/objects/weapons/revolver.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								project/objects/weapons/revolver.tscn
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| [gd_scene load_steps=2 format=3 uid="uid://cfgwif53qypko"] | ||||
| 
 | ||||
| [ext_resource type="PackedScene" uid="uid://bkw6pt33nbn2" path="res://assets/models/weapons/revolver.blend" id="1_5ynga"] | ||||
| 
 | ||||
| [node name="Revolver" type="Revolver" node_paths=PackedStringArray("anim")] | ||||
| anim = NodePath("revolver/AnimationPlayer") | ||||
| 
 | ||||
| [node name="revolver" parent="." instance=ExtResource("1_5ynga")] | ||||
| 
 | ||||
| [node name="Body" parent="revolver/Character/Skeleton3D" index="0"] | ||||
| layers = 2 | ||||
| 
 | ||||
| [node name="Cube" parent="revolver/Character/Skeleton3D" index="1"] | ||||
| layers = 2 | ||||
| 
 | ||||
| [node name="BoneAttachment3D" type="BoneAttachment3D" parent="revolver/Character/Skeleton3D" index="2"] | ||||
| transform = Transform3D(1, -6.350722e-17, 4.732016e-17, 4.732016e-17, 0.95822614, 0.28601173, -6.350722e-17, -0.28601173, 0.95822614, -1.1196792e-16, -0.03667751, 0.009908612) | ||||
| bone_name = "root" | ||||
| bone_idx = 39 | ||||
| 
 | ||||
| [node name="HitscanMuzzle" type="HitscanMuzzle" parent="revolver/Character/Skeleton3D/BoneAttachment3D"] | ||||
| unique_name_in_owner = true | ||||
| transform = Transform3D(1, 6.3507215e-17, 4.732015e-17, -6.350722e-17, 0.28601167, 0.958226, 4.7320157e-17, -0.958226, 0.28601167, 1.0408685e-17, 0.13487417, -0.03951955) | ||||
| target_position = Vector3(0, 200, 0) | ||||
| collision_mask = 6 | ||||
| collide_with_areas = true | ||||
| spread = 0.03 | ||||
| 
 | ||||
| [editable path="revolver"] | ||||
|  | @ -20,13 +20,14 @@ bone_idx = 39 | |||
| 
 | ||||
| [node name="HitscanMuzzle" type="HitscanMuzzle" parent="rifle/Character/Skeleton3D/BoneAttachment3D"] | ||||
| unique_name_in_owner = true | ||||
| transform = Transform3D(1, 0, 0, 0, 0.99999833, -0.0017453281, 0, 0.0017453281, 0.99999833, 1.4540284e-26, 0, 0.027612558) | ||||
| target_position = Vector3(0, 100, 0) | ||||
| transform = Transform3D(1, 0, 0, 0, 0.9999968, 0.0024609112, 0, -0.0024609112, 0.9999968, 1.1099746e-16, 0.053034816, 0.03427495) | ||||
| target_position = Vector3(0, 200, 0) | ||||
| collision_mask = 6 | ||||
| collide_with_areas = true | ||||
| spread = 0.003 | ||||
| damage = 3 | ||||
| 
 | ||||
| [node name="AnimationPlayer" parent="rifle" index="1"] | ||||
| [node name="AnimationPlayer" parent="rifle" index="2"] | ||||
| playback_default_blend_time = 0.1 | ||||
| 
 | ||||
| [editable path="rifle"] | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Sara
						Sara