Dropping weapons with G. Updates on inventory and slots
This commit is contained in:
parent
a81b2f340e
commit
9538f73075
|
@ -1,5 +1,13 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
use crate::comps::core::{items::item::Item, inventory::slot::PlayerInventorySlotType};
|
||||
|
||||
/// This will be what is triggered after picking up an item or dropping an item.
|
||||
#[derive(Event)]
|
||||
pub struct InventoryChangedEvent {}
|
||||
pub struct PlayerInventoryChangedEvent {
|
||||
/// A None value will remove the item from the inventory slot
|
||||
pub item: Option<Arc<dyn Item>>,
|
||||
pub slot_type: PlayerInventorySlotType
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
use bevy::reflect::Reflect;
|
||||
|
||||
use crate::comps::core::items::item::Item;
|
||||
|
||||
/// # ItemInventory
|
||||
/// Specifically made to hold single items such as Guns, Pieces of armor.
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Reflect)]
|
||||
pub struct ItemInventory {
|
||||
#[reflect(ignore)]
|
||||
pub item: Option<Box<dyn Item>>,
|
||||
}
|
||||
|
|
|
@ -3,3 +3,4 @@
|
|||
pub mod item_inventory;
|
||||
pub mod player_inventory;
|
||||
pub mod plugin;
|
||||
pub mod slot;
|
|
@ -1,14 +1,16 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy::{prelude::*, gltf::Gltf};
|
||||
|
||||
use crate::comps::core::items::item::Item;
|
||||
use crate::{comps::core::{items::item::Item, events::inventory_changed::PlayerInventoryChangedEvent, markers::firearm::FirearmType}, setup::assets::GltfAssets};
|
||||
|
||||
use super::item_inventory::ItemInventory;
|
||||
use super::{item_inventory::ItemInventory, slot::PlayerInventorySlotType};
|
||||
|
||||
#[derive(Component)]
|
||||
#[derive(Component, Reflect)]
|
||||
pub struct PlayerInventory {
|
||||
pub primary: ItemInventory,
|
||||
pub secondary: ItemInventory,
|
||||
//pub backpack: AnyInventory,
|
||||
|
||||
pub current_slot: Option<PlayerInventorySlotType>,
|
||||
}
|
||||
|
||||
impl Default for PlayerInventory {
|
||||
|
@ -17,10 +19,13 @@ impl Default for PlayerInventory {
|
|||
primary: Default::default(),
|
||||
secondary: Default::default(),
|
||||
//backpack: AnyInventory::new(UGrid::new_square(10)),
|
||||
|
||||
current_slot: None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
impl PlayerInventory {
|
||||
pub fn primary_occupied(&self) -> bool {
|
||||
self.primary.item.is_some()
|
||||
|
@ -35,4 +40,98 @@ impl PlayerInventory {
|
|||
pub fn get_secondary(&self) -> &Option<Box<dyn Item>> {
|
||||
&self.secondary.item
|
||||
}
|
||||
|
||||
pub fn get_primary_mut(&mut self) -> &mut ItemInventory {
|
||||
&mut self.primary
|
||||
}
|
||||
pub fn get_secondary_mut(&mut self) -> &mut ItemInventory {
|
||||
&mut self.secondary
|
||||
}
|
||||
/// This comes from a PickupItemEvent usually
|
||||
pub fn pickup_item(&mut self, item: &dyn Item, slot: PlayerInventorySlotType) {
|
||||
let mut inventory_slot = match slot {
|
||||
PlayerInventorySlotType::Primary => &mut self.primary,
|
||||
PlayerInventorySlotType::Secondary => &mut self.secondary,
|
||||
};
|
||||
let Some(firearm) = item.get_firearm() else { return; };
|
||||
inventory_slot.item = Some(firearm.get_item_box());
|
||||
}
|
||||
pub fn drop_item(&mut self, slot: PlayerInventorySlotType) {
|
||||
match slot {
|
||||
PlayerInventorySlotType::Primary => self.primary.item = None,
|
||||
PlayerInventorySlotType::Secondary => self.secondary.item = None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Drop item from a specific slot.
|
||||
/// This fn does not equip an item
|
||||
pub fn drop_slot_in_game_world(
|
||||
commands: &mut Commands,
|
||||
player_transform: &Transform,
|
||||
inventory_changed_events: &mut EventWriter<PlayerInventoryChangedEvent>,
|
||||
player_inventory: &mut PlayerInventory,
|
||||
assets_gltf: &Res<GltfAssets>,
|
||||
loaded_gltf_assets: &Res<Assets<Gltf>>,
|
||||
slot: PlayerInventorySlotType,
|
||||
) {
|
||||
let drop_position = Transform::from_translation(
|
||||
player_transform.translation
|
||||
+ player_transform.up() * 3.0
|
||||
+ player_transform.forward() * 2.0,
|
||||
);
|
||||
let drop_impulse = player_transform.translation
|
||||
+ player_transform.up() * 100.0
|
||||
+ player_transform.forward() * 30.0;
|
||||
|
||||
let item_inventory_slot = match slot {
|
||||
PlayerInventorySlotType::Primary => {
|
||||
player_inventory.get_primary_mut()
|
||||
},
|
||||
PlayerInventorySlotType::Secondary => {
|
||||
player_inventory.get_secondary_mut()
|
||||
},
|
||||
};
|
||||
|
||||
match &item_inventory_slot.item {
|
||||
Some(ref item) => {
|
||||
match item.get_firearm() {
|
||||
Some(firearm) => {
|
||||
match firearm.firearm_data().firearm_type {
|
||||
FirearmType::Primary => {
|
||||
// Send equipment_changed_event
|
||||
if let Some(primary_item) = player_inventory.get_primary() {
|
||||
// Drop this one
|
||||
primary_item.spawn(
|
||||
commands,
|
||||
drop_position,
|
||||
&assets_gltf,
|
||||
&loaded_gltf_assets,
|
||||
drop_impulse,
|
||||
);
|
||||
}
|
||||
player_inventory.drop_item(PlayerInventorySlotType::Primary);
|
||||
inventory_changed_events.send(PlayerInventoryChangedEvent { item: Some(firearm.get_item_arc()), slot_type: PlayerInventorySlotType::Primary });
|
||||
}
|
||||
FirearmType::Secondary => {
|
||||
if let Some(secondary) = player_inventory.get_secondary() {
|
||||
secondary.spawn(
|
||||
commands,
|
||||
drop_position,
|
||||
&assets_gltf,
|
||||
&loaded_gltf_assets,
|
||||
drop_impulse,
|
||||
);
|
||||
}
|
||||
player_inventory.drop_item(PlayerInventorySlotType::Secondary);
|
||||
inventory_changed_events.send(PlayerInventoryChangedEvent { item: Some(firearm.get_item_arc()), slot_type: PlayerInventorySlotType::Secondary });
|
||||
}
|
||||
}
|
||||
},
|
||||
None => { unimplemented!("Item being dropped from inventory is not a Firearm. This still isn't implemented") } // Item isn't a firearm. Unimplemented
|
||||
}
|
||||
},
|
||||
None => { return; }, // No item to drop
|
||||
};
|
||||
|
||||
}
|
|
@ -1,15 +1,20 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
use crate::{
|
||||
comps::core::events::pickup_item::PickupItemEvent,
|
||||
comps::core::events::{pickup_item::PickupItemEvent, inventory_changed::PlayerInventoryChangedEvent},
|
||||
logic::core::player::inventory::update_player_inventory_system,
|
||||
};
|
||||
|
||||
use super::player_inventory::PlayerInventory;
|
||||
|
||||
pub struct InventoryPlugin;
|
||||
|
||||
impl Plugin for InventoryPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.register_type::<PlayerInventory>();
|
||||
|
||||
app.add_event::<PickupItemEvent>();
|
||||
app.add_event::<PlayerInventoryChangedEvent>();
|
||||
app.add_systems(Update, update_player_inventory_system);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
use bevy::reflect::Reflect;
|
||||
|
||||
|
||||
|
||||
#[derive(Clone, Copy, Reflect, Default)]
|
||||
pub enum PlayerInventorySlotType {
|
||||
#[default]
|
||||
Primary,
|
||||
Secondary,
|
||||
//Slots, // TODO: Pass which slot
|
||||
}
|
|
@ -4,12 +4,12 @@ use crate::{
|
|||
comps::core::{
|
||||
grid::UGrid,
|
||||
items::item::{Item, ItemType},
|
||||
markers::holdable::HoldableObjectType,
|
||||
markers::holdable::HoldableObjectType, inventory::slot::PlayerInventorySlotType,
|
||||
},
|
||||
logic::core::guns::firearm::Firearm,
|
||||
};
|
||||
|
||||
#[derive(Component)]
|
||||
#[derive(Component, Reflect)]
|
||||
pub struct Glock17GunItem;
|
||||
|
||||
impl Item for Glock17GunItem {
|
||||
|
@ -44,4 +44,8 @@ impl Item for Glock17GunItem {
|
|||
fn inventory_description(&self) -> String {
|
||||
String::from("Pistol chambered in 9x19mm.")
|
||||
}
|
||||
|
||||
fn get_item_slot(&self) -> PlayerInventorySlotType {
|
||||
PlayerInventorySlotType::Secondary
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,12 +4,12 @@ use crate::{
|
|||
comps::core::{
|
||||
grid::UGrid,
|
||||
items::item::{Item, ItemType},
|
||||
markers::holdable::HoldableObjectType,
|
||||
markers::holdable::HoldableObjectType, inventory::slot::PlayerInventorySlotType,
|
||||
},
|
||||
logic::core::guns::firearm::Firearm,
|
||||
};
|
||||
|
||||
#[derive(Component)]
|
||||
#[derive(Component, Reflect)]
|
||||
pub struct M4a1GunItem;
|
||||
|
||||
impl Item for M4a1GunItem {
|
||||
|
@ -43,4 +43,8 @@ impl Item for M4a1GunItem {
|
|||
fn inventory_description(&self) -> String {
|
||||
String::from("Rifle chambered in 5.56x45mm NATO, shoots 800 rounds per minute.")
|
||||
}
|
||||
|
||||
fn get_item_slot(&self) -> PlayerInventorySlotType {
|
||||
PlayerInventorySlotType::Primary
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
comps::core::{
|
||||
grid::UGrid,
|
||||
markers::{firearm::FirearmData, holdable::HoldableObjectType, interactable::Interactable},
|
||||
markers::{firearm::FirearmData, holdable::HoldableObjectType, interactable::Interactable}, inventory::slot::PlayerInventorySlotType,
|
||||
},
|
||||
logic::core::guns::firearm::Firearm,
|
||||
setup::assets::{GltfAssetType, GltfAssets},
|
||||
|
@ -18,7 +18,7 @@ pub enum ItemType {
|
|||
}
|
||||
|
||||
#[bevy_trait_query::queryable]
|
||||
pub trait Item: Sync + Send {
|
||||
pub trait Item: Sync + Send + Reflect {
|
||||
fn get_type(&self) -> ItemType;
|
||||
fn asset_path(&self) -> &str;
|
||||
/// Optional Stackable. If value is Some(x) x is the max quantity per stack
|
||||
|
@ -114,4 +114,5 @@ pub trait Item: Sync + Send {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
fn get_item_slot(&self) -> PlayerInventorySlotType;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use bevy::{ecs::system::SystemParam, prelude::*};
|
||||
use bevy::{ecs::system::SystemParam, prelude::*, gltf::Gltf};
|
||||
use bevy_rapier3d::prelude::*;
|
||||
|
||||
use crate::{
|
||||
comps::core::{
|
||||
events::pickup_item::PickupItemEvent,
|
||||
inventory::player_inventory::PlayerInventory,
|
||||
events::{pickup_item::PickupItemEvent, inventory_changed::PlayerInventoryChangedEvent},
|
||||
inventory::{player_inventory::{PlayerInventory, self}, slot::PlayerInventorySlotType},
|
||||
markers::{
|
||||
camera::MainCamera,
|
||||
firearm::{FirearmData, MagazineData},
|
||||
|
@ -17,7 +17,7 @@ use crate::{
|
|||
setup::{
|
||||
animations::AllFirearmAnimations,
|
||||
equipment::{Equipment, EquipmentChangeEvent},
|
||||
load_state::GameLoadState,
|
||||
load_state::GameLoadState, assets::GltfAssets,
|
||||
},
|
||||
ui::game::{game_ui_state::GameUiState, hud::hud::HudState},
|
||||
utils::{self, rad_deg::radians_from_degrees},
|
||||
|
@ -34,6 +34,8 @@ pub struct CaptureHandUsageResourcesParams<'w> {
|
|||
animation_clips: Res<'w, Assets<AnimationClip>>,
|
||||
all_firearm_animations: Res<'w, AllFirearmAnimations>,
|
||||
time: Res<'w, Time>,
|
||||
assets_gltf: Res<'w, GltfAssets>,
|
||||
loaded_gltf_assets: Res<'w, Assets<Gltf>>,
|
||||
}
|
||||
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
|
@ -41,7 +43,7 @@ pub fn capture_hand_usage(
|
|||
mut resources: CaptureHandUsageResourcesParams,
|
||||
mut commands: Commands,
|
||||
|
||||
mut hand_query: Query<&mut Transform, With<PlayerHand>>,
|
||||
mut hand_query: Query<&mut Transform, (With<PlayerHand>, Without<Player>)>,
|
||||
mut firearm_query: Query<
|
||||
(
|
||||
Entity,
|
||||
|
@ -51,13 +53,13 @@ pub fn capture_hand_usage(
|
|||
),
|
||||
(With<InPlayerHands>, Without<PlayerHand>),
|
||||
>,
|
||||
player_query: Query<(&Player, &PlayerInventory, Entity)>,
|
||||
mut player_firing_info_query: Query<&mut PlayerFiringInfo, With<Player>>,
|
||||
mut player_query: Query<(&Player, &mut PlayerInventory, Entity, &Transform, &mut PlayerFiringInfo)>,
|
||||
mut animation_players: Query<(Entity, &mut AnimationPlayer)>,
|
||||
|
||||
children: Query<&Children>,
|
||||
|
||||
mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
||||
mut inventory_changed_events: EventWriter<PlayerInventoryChangedEvent>,
|
||||
) {
|
||||
if !resources.game_load_state.player_loaded {
|
||||
return;
|
||||
|
@ -68,41 +70,54 @@ pub fn capture_hand_usage(
|
|||
|
||||
// Equipping stuff
|
||||
|
||||
for (player, mut player_inventory, _player_entity, player_transform, mut player_firing_info) in player_query.iter_mut() {
|
||||
// Equipping gun
|
||||
// Validate player has primary item, and secondary item in inventory
|
||||
if !resources.game_ui_state.any_window() {
|
||||
if resources.keyboard_input.just_pressed(KeyCode::Key1) {
|
||||
if let Some(primary_item) = player_query.single().1.get_primary() {
|
||||
if let Some(primary_item) = player_inventory.get_primary() {
|
||||
if let Some(primary_firearm) = primary_item.get_firearm() {
|
||||
if Equipment::Firearm(primary_firearm.clone())
|
||||
!= player_query.single().0 .0.equipment
|
||||
!= player.0.equipment
|
||||
{
|
||||
equipment_change_event_writer
|
||||
.send(EquipmentChangeEvent(Equipment::Firearm(primary_firearm)));
|
||||
player_inventory.current_slot = Some(PlayerInventorySlotType::Primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if resources.keyboard_input.just_pressed(KeyCode::Key2) {
|
||||
if let Some(secondary_item) = player_query.single().1.get_secondary() {
|
||||
if let Some(secondary_item) = player_inventory.get_secondary() {
|
||||
if let Some(secondary_firearm) = secondary_item.get_firearm() {
|
||||
if Equipment::Firearm(secondary_firearm.clone())
|
||||
!= player_query.single().0 .0.equipment
|
||||
!= player.0.equipment
|
||||
{
|
||||
equipment_change_event_writer
|
||||
.send(EquipmentChangeEvent(Equipment::Firearm(secondary_firearm)));
|
||||
player_inventory.current_slot = Some(PlayerInventorySlotType::Secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if resources.keyboard_input.just_pressed(KeyCode::Key3) {
|
||||
if Equipment::Nothing != player_query.single().0 .0.equipment {
|
||||
if Equipment::Nothing != player.0.equipment {
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing));
|
||||
player_inventory.current_slot = None;
|
||||
}
|
||||
} else if resources.keyboard_input.just_pressed(KeyCode::G) {
|
||||
match player_inventory.current_slot {
|
||||
Some(current_slot) => {
|
||||
player_inventory::drop_slot_in_game_world(&mut commands, player_transform, &mut inventory_changed_events, &mut player_inventory, &resources.assets_gltf, &resources.loaded_gltf_assets, current_slot);
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing));
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Firearm stuff
|
||||
if let Equipment::Firearm(player_firearm) = player_query.single().0 .0.equipment.clone() {
|
||||
for mut player_firing_info in player_firing_info_query.iter_mut() {
|
||||
if let Equipment::Firearm(player_firearm) = player.0.equipment.clone() {
|
||||
player_firing_info
|
||||
.full_auto_timer
|
||||
.tick(resources.time.delta());
|
||||
|
@ -268,9 +283,13 @@ pub fn capture_hand_usage(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// Method that is run when player hits interact button.
|
||||
|
|
|
@ -2,10 +2,9 @@ use bevy::{gltf::Gltf, prelude::*};
|
|||
|
||||
use crate::{
|
||||
comps::core::{
|
||||
events::pickup_item::PickupItemEvent,
|
||||
inventory::player_inventory::PlayerInventory,
|
||||
items::item::ItemType,
|
||||
markers::{firearm::FirearmType, holdable::HoldableObjectType, player::Player},
|
||||
events::{pickup_item::PickupItemEvent, inventory_changed::PlayerInventoryChangedEvent},
|
||||
inventory::player_inventory::{PlayerInventory, self},
|
||||
markers::player::Player,
|
||||
},
|
||||
setup::assets::GltfAssets,
|
||||
};
|
||||
|
@ -13,6 +12,7 @@ use crate::{
|
|||
pub fn update_player_inventory_system(
|
||||
mut commands: Commands,
|
||||
mut pickup_item_events: EventReader<PickupItemEvent>,
|
||||
mut inventory_changed_events: EventWriter<PlayerInventoryChangedEvent>,
|
||||
mut player_query: Query<(Entity, &mut PlayerInventory, &Transform), With<Player>>,
|
||||
assets_gltf: Res<GltfAssets>,
|
||||
loaded_gltf_assets: Res<Assets<Gltf>>,
|
||||
|
@ -21,64 +21,15 @@ pub fn update_player_inventory_system(
|
|||
for (player_entity, mut player_inventory, player_transform) in player_query.iter_mut() {
|
||||
if player_entity == event.player {
|
||||
// Get item type and where it should go
|
||||
match event.item.get_type() {
|
||||
ItemType::Holdable(holdable_object) => {
|
||||
match holdable_object {
|
||||
HoldableObjectType::Firearm(firearm) => {
|
||||
commands
|
||||
.entity(event.entity)
|
||||
.despawn_descendants()
|
||||
.despawn();
|
||||
let drop_position = Transform::from_translation(
|
||||
player_transform.translation
|
||||
+ player_transform.up() * 3.0
|
||||
+ player_transform.forward() * 2.0,
|
||||
);
|
||||
let drop_impulse = player_transform.translation
|
||||
+ player_transform.up() * 100.0
|
||||
+ player_transform.forward() * 30.0;
|
||||
match firearm.firearm_data().firearm_type {
|
||||
FirearmType::Primary => {
|
||||
// Send equipment_changed_event
|
||||
if let Some(primary_item) = player_inventory.get_primary() {
|
||||
// Drop this one
|
||||
primary_item.spawn(
|
||||
&mut commands,
|
||||
drop_position,
|
||||
&assets_gltf,
|
||||
&loaded_gltf_assets,
|
||||
drop_impulse,
|
||||
);
|
||||
player_inventory.primary.item =
|
||||
Some(firearm.get_item_box())
|
||||
} else {
|
||||
player_inventory.primary.item =
|
||||
Some(firearm.get_item_box())
|
||||
}
|
||||
}
|
||||
FirearmType::Secondary => {
|
||||
if let Some(secondary) = player_inventory.get_secondary() {
|
||||
secondary.spawn(
|
||||
&mut commands,
|
||||
drop_position,
|
||||
&assets_gltf,
|
||||
&loaded_gltf_assets,
|
||||
drop_impulse,
|
||||
);
|
||||
player_inventory.secondary.item =
|
||||
Some(firearm.get_item_box())
|
||||
} else {
|
||||
player_inventory.secondary.item =
|
||||
Some(firearm.get_item_box())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemType::Equippable => todo!(),
|
||||
ItemType::Consumable => todo!(),
|
||||
}
|
||||
|
||||
player_inventory::drop_slot_in_game_world(&mut commands, player_transform, &mut inventory_changed_events, &mut player_inventory, &assets_gltf, &loaded_gltf_assets, event.item.get_item_slot());
|
||||
player_inventory.pickup_item(event.item.as_ref(), event.item.get_item_slot());
|
||||
// TODO: Equip
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue