feat: implementations of initial weapon inventory interface
This commit is contained in:
		
							parent
							
								
									6cdb2cbd4f
								
							
						
					
					
						commit
						6fa9d11af5
					
				
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -1,6 +1,8 @@
 | 
			
		|||
#include "player_body.h"
 | 
			
		||||
#include "macros.h"
 | 
			
		||||
#include "player_input.h"
 | 
			
		||||
#include "weapon_base.h"
 | 
			
		||||
#include "weapon_inventory.h"
 | 
			
		||||
 | 
			
		||||
PlayerBody *PlayerBody::singleton_instance{ nullptr };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +15,7 @@ void PlayerBody::ready() {
 | 
			
		|||
	input->connect(PlayerInput::sig_look_input, callable_mp(this, &self_type::on_look_input));
 | 
			
		||||
	input->connect(PlayerInput::sig_jump, callable_mp(this, &self_type::on_jump_input));
 | 
			
		||||
	input->connect(PlayerInput::sig_run, callable_mp(this, &self_type::on_run_input));
 | 
			
		||||
	this->weapons = cast_to<WeaponInventory>(get_node(NodePath("%WeaponInventory")));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PlayerBody::process(double delta) {
 | 
			
		||||
| 
						 | 
				
			
			@ -85,5 +88,5 @@ PlayerBody *PlayerBody::get_singleton() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
bool PlayerBody::get_is_running() const {
 | 
			
		||||
	return this->try_running && this->movement_input.y > 0.f;
 | 
			
		||||
	return this->try_running && this->movement_input.y > 0.f && this->weapons->get_current_weapon()->allows_running();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
#define PLAYER_BODY_H
 | 
			
		||||
 | 
			
		||||
#include "scene/3d/physics/character_body_3d.h"
 | 
			
		||||
class WeaponInventory;
 | 
			
		||||
 | 
			
		||||
class PlayerBody : public CharacterBody3D {
 | 
			
		||||
	GDCLASS(PlayerBody, CharacterBody3D);
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +33,8 @@ private:
 | 
			
		|||
	float acceleration{ 40.f };
 | 
			
		||||
	float jump_strength{ 3.5f };
 | 
			
		||||
	Vector2 movement_input{};
 | 
			
		||||
 | 
			
		||||
	WeaponInventory *weapons;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // !PLAYER_BODY_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
#include "wave_survival/player_camera.h"
 | 
			
		||||
#include "wave_survival/player_input.h"
 | 
			
		||||
#include "wave_survival/weapon_base.h"
 | 
			
		||||
#include "wave_survival/weapon_inventory.h"
 | 
			
		||||
#include "wave_survival/weapons/rifle.h"
 | 
			
		||||
 | 
			
		||||
void initialize_wave_survival_module(ModuleInitializationLevel p_level) {
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +17,7 @@ void initialize_wave_survival_module(ModuleInitializationLevel p_level) {
 | 
			
		|||
	GDREGISTER_CLASS(PlayerCamera);
 | 
			
		||||
	GDREGISTER_RUNTIME_CLASS(WeaponBase);
 | 
			
		||||
	GDREGISTER_CLASS(Rifle);
 | 
			
		||||
	GDREGISTER_CLASS(WeaponInventory);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void uninitialize_wave_survival_module(ModuleInitializationLevel p_level) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,10 @@ public:
 | 
			
		|||
	void set_body(PlayerBody *body);
 | 
			
		||||
	PlayerBody *get_body() const;
 | 
			
		||||
 | 
			
		||||
	virtual bool allows_running() const { return true; }
 | 
			
		||||
	virtual bool allows_jumping() const { return true; }
 | 
			
		||||
	virtual void notify_selected() {}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	AnimationPlayer *anim{ nullptr };
 | 
			
		||||
	PlayerCamera *camera{ nullptr };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,99 @@
 | 
			
		|||
#include "weapon_inventory.h"
 | 
			
		||||
#include "macros.h"
 | 
			
		||||
#include "weapon_base.h"
 | 
			
		||||
 | 
			
		||||
void WeaponInventory::_bind_methods() {}
 | 
			
		||||
void WeaponInventory::_bind_methods() {
 | 
			
		||||
	BIND_HPROPERTY(Variant::OBJECT, fallback_weapon, PROPERTY_HINT_RESOURCE_TYPE, "PackedScene");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WeaponInventory::on_switch_input() {
 | 
			
		||||
	this->current = (this->current + 1) % 1;
 | 
			
		||||
	this->select_weapon(this->weapons[this->current]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WeaponInventory::ready() {
 | 
			
		||||
	// initialize the fallback 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) {
 | 
			
		||||
	if (Engine::get_singleton()->is_editor_hint()) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	switch (what) {
 | 
			
		||||
		default:
 | 
			
		||||
			return;
 | 
			
		||||
		case NOTIFICATION_READY:
 | 
			
		||||
			ready();
 | 
			
		||||
			return;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
	}
 | 
			
		||||
	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) {
 | 
			
		||||
		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");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WeaponBase *WeaponInventory::get_current_weapon() const {
 | 
			
		||||
	return this->current_weapon;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 (this->weapons[0] == nullptr) {
 | 
			
		||||
			this->weapons[0] = weapon;
 | 
			
		||||
			select_weapon(weapon);
 | 
			
		||||
			return;
 | 
			
		||||
		} else if (this->weapons[1] == nullptr) {
 | 
			
		||||
			this->weapons[1] = weapon;
 | 
			
		||||
			select_weapon(weapon);
 | 
			
		||||
			return;
 | 
			
		||||
		} else {
 | 
			
		||||
			this->current_weapon->queue_free();
 | 
			
		||||
			this->weapons[this->current] = weapon;
 | 
			
		||||
			this->current_weapon = nullptr;
 | 
			
		||||
			select_weapon(weapon);
 | 
			
		||||
		}
 | 
			
		||||
	} else if (weapon_as_node != nullptr) {
 | 
			
		||||
		weapon_as_node->queue_free();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,8 +10,9 @@ class WeaponInventory : public Node {
 | 
			
		|||
	GDCLASS(WeaponInventory, Node);
 | 
			
		||||
	static void _bind_methods();
 | 
			
		||||
	void on_switch_input();
 | 
			
		||||
	void stow_current_weapon();
 | 
			
		||||
	void ready();
 | 
			
		||||
	void select_weapon(WeaponBase *next);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	void _notification(int what);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,15 +20,19 @@ 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);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	Node3D *weapon_parent{ nullptr };
 | 
			
		||||
	unsigned current{ 0 };
 | 
			
		||||
	LocalVector<WeaponBase *> weapons{ nullptr, nullptr };
 | 
			
		||||
	WeaponBase *current_weapon{ nullptr };
 | 
			
		||||
	WeaponBase *fallback_weapon{ nullptr };
 | 
			
		||||
 | 
			
		||||
	Ref<PackedScene> default_weapon_scene{};
 | 
			
		||||
	Ref<PackedScene> fallback_weapon_scene{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // !WEAPON_INVENTORY_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,8 @@ void Rifle::ready() {
 | 
			
		|||
	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");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Rifle::process(double delta) {
 | 
			
		||||
| 
						 | 
				
			
			@ -74,3 +76,12 @@ void Rifle::_notification(int what) {
 | 
			
		|||
			return;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Rifle::allows_running() const {
 | 
			
		||||
	String const animation{ get_anim()->get_current_animation() };
 | 
			
		||||
	return animation.is_empty();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Rifle::notify_selected() {
 | 
			
		||||
	get_anim()->play("equip");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,9 @@ class Rifle : public WeaponBase {
 | 
			
		|||
public:
 | 
			
		||||
	void _notification(int what);
 | 
			
		||||
 | 
			
		||||
	virtual bool allows_running() const override;
 | 
			
		||||
	virtual void notify_selected() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	float ads_factor{ 0.5f };
 | 
			
		||||
	bool request_alt_mode{ false };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -1,6 +1,4 @@
 | 
			
		|||
[gd_scene load_steps=3 format=3 uid="uid://snjgu4yp5swd"]
 | 
			
		||||
 | 
			
		||||
[ext_resource type="PackedScene" uid="uid://ce40pq785yoyi" path="res://objects/weapons/rifle.tscn" id="1_eqqp1"]
 | 
			
		||||
[gd_scene load_steps=2 format=3 uid="uid://snjgu4yp5swd"]
 | 
			
		||||
 | 
			
		||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_bxedw"]
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +16,4 @@ unique_name_in_owner = true
 | 
			
		|||
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 1.60811, 0)
 | 
			
		||||
fov = 60.0
 | 
			
		||||
 | 
			
		||||
[node name="Rifle" parent="PlayerCamera" instance=ExtResource("1_eqqp1")]
 | 
			
		||||
 | 
			
		||||
[editable path="PlayerCamera/Rifle"]
 | 
			
		||||
[editable path="PlayerCamera/Rifle/rifle"]
 | 
			
		||||
[node name="WeaponInventory" type="WeaponInventory" parent="."]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue