From 45845fcd6c8195732b024e22a38b318c15a275a7 Mon Sep 17 00:00:00 2001 From: Franklin Date: Mon, 20 Nov 2023 16:01:13 -0400 Subject: [PATCH] Gun state gets persisted on drop and equip --- src/comps/core/events/pickup_item.rs | 10 ++- src/comps/core/inventory/inventory_item.rs | 2 +- src/comps/core/inventory/item_inventory.rs | 4 +- src/comps/core/inventory/player_inventory.rs | 19 ++-- src/comps/core/items/guns/ak105.rs | 22 ++++- src/comps/core/items/guns/glock17.rs | 13 ++- src/comps/core/items/item.rs | 11 ++- src/comps/core/markers/interactable.rs | 2 +- .../core/markers/proxy/weapons/firearm.rs | 12 +-- src/comps/core/spawners/guns/ak105_spawner.rs | 3 +- src/comps/core/weapons/firearm.rs | 7 +- src/logic/core/player/hands.rs | 86 ++++++++++++------- src/logic/core/player/inventory.rs | 21 ++--- src/setup/equipment.rs | 12 ++- 14 files changed, 145 insertions(+), 79 deletions(-) diff --git a/src/comps/core/events/pickup_item.rs b/src/comps/core/events/pickup_item.rs index 959bd15..2924f28 100644 --- a/src/comps/core/events/pickup_item.rs +++ b/src/comps/core/events/pickup_item.rs @@ -9,6 +9,15 @@ pub enum ItemState { Weapon(FirearmState), } +impl ItemState { + pub fn as_firearm_state(self) -> FirearmState { + match self { + ItemState::Weapon(firearm_state) => firearm_state, + _ => panic!("Not a weapon ItemState variant...") + } + } +} + /// When an item gets picked up in the game world, this event should handle all the physical properties on the game world. /// Mainly, removing the item from the game world, triggering inventory events, changing the player's equipment, etc... #[derive(Event)] @@ -17,5 +26,4 @@ pub struct PickupItemEvent { pub entity: Entity, pub item: Arc, pub player: Entity, - pub state: Option } diff --git a/src/comps/core/inventory/inventory_item.rs b/src/comps/core/inventory/inventory_item.rs index fd0219b..a00fd71 100644 --- a/src/comps/core/inventory/inventory_item.rs +++ b/src/comps/core/inventory/inventory_item.rs @@ -15,7 +15,7 @@ pub struct InventoryItem { #[allow(unused)] impl InventoryItem { pub fn item(&self) -> &dyn Item { - self.item.as_ref() + self.item } pub fn rotated(&self) -> Option { self.rotated diff --git a/src/comps/core/inventory/item_inventory.rs b/src/comps/core/inventory/item_inventory.rs index d0bbf09..c1a40da 100644 --- a/src/comps/core/inventory/item_inventory.rs +++ b/src/comps/core/inventory/item_inventory.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use bevy::reflect::Reflect; use crate::comps::core::items::item::Item; @@ -7,5 +9,5 @@ use crate::comps::core::items::item::Item; #[derive(Default, Reflect)] pub struct ItemInventory { #[reflect(ignore)] - pub item: Option>, + pub item: Option>, } diff --git a/src/comps/core/inventory/player_inventory.rs b/src/comps/core/inventory/player_inventory.rs index 2ab979b..3161368 100644 --- a/src/comps/core/inventory/player_inventory.rs +++ b/src/comps/core/inventory/player_inventory.rs @@ -1,6 +1,8 @@ +use std::sync::Arc; + use bevy::{prelude::*, gltf::Gltf}; -use crate::{comps::core::{items::item::Item, events::inventory_changed::PlayerInventoryChangedEvent, weapons::firearm_data::FirearmType}, setup::assets::GltfAssets}; +use crate::{comps::core::{items::item::Item, events::{inventory_changed::PlayerInventoryChangedEvent, pickup_item::ItemState}, weapons::firearm_data::FirearmType}, setup::assets::GltfAssets}; use super::{item_inventory::ItemInventory, slot::PlayerInventorySlotType}; @@ -34,10 +36,10 @@ impl PlayerInventory { self.secondary.item.is_some() } - pub fn get_primary(&self) -> &Option> { + pub fn get_primary(&self) -> &Option> { &self.primary.item } - pub fn get_secondary(&self) -> &Option> { + pub fn get_secondary(&self) -> &Option> { &self.secondary.item } @@ -48,14 +50,15 @@ impl PlayerInventory { &mut self.secondary } /// This comes from a PickupItemEvent usually - pub fn pickup_item(&mut self, item: &dyn Item, slot: PlayerInventorySlotType) { + pub fn pickup_item(&mut self, item: Arc, slot: PlayerInventorySlotType) { let mut inventory_slot = match slot { PlayerInventorySlotType::Primary => &mut self.primary, PlayerInventorySlotType::Secondary => &mut self.secondary, _ => unimplemented!(), }; let Some(firearm) = item.get_firearm() else { return; }; - inventory_slot.item = Some(firearm.get_item_box()); + println!("Pickup item: {:?}", item.get_state()); + inventory_slot.item = Some(item); } pub fn drop_item(&mut self, slot: PlayerInventorySlotType) { match slot { @@ -76,6 +79,7 @@ pub fn drop_slot_in_game_world( assets_gltf: &Res, loaded_gltf_assets: &Res>, slot: PlayerInventorySlotType, + item_state: Option, ) { let drop_position = Transform::from_translation( player_transform.translation @@ -104,6 +108,7 @@ pub fn drop_slot_in_game_world( FirearmType::Primary => { // Send equipment_changed_event if let Some(primary_item) = player_inventory.get_primary() { + println!("drop_slot_in_game_world {:?}", primary_item.get_state()); // Drop this one primary_item.spawn( commands, @@ -111,7 +116,7 @@ pub fn drop_slot_in_game_world( &assets_gltf, &loaded_gltf_assets, drop_impulse, - None + primary_item.get_state() ); } player_inventory.drop_item(PlayerInventorySlotType::Primary); @@ -125,7 +130,7 @@ pub fn drop_slot_in_game_world( &assets_gltf, &loaded_gltf_assets, drop_impulse, - None + item_state ); } player_inventory.drop_item(PlayerInventorySlotType::Secondary); diff --git a/src/comps/core/items/guns/ak105.rs b/src/comps/core/items/guns/ak105.rs index 3ec86c1..8bd24a6 100644 --- a/src/comps/core/items/guns/ak105.rs +++ b/src/comps/core/items/guns/ak105.rs @@ -1,4 +1,7 @@ +use std::sync::Arc; + use bevy::{prelude::*, gltf::Gltf}; +use bevy_inspector_egui::egui::mutex::Mutex; use bevy_rapier3d::{dynamics::{RigidBody, GravityScale, ExternalImpulse}, geometry::{ColliderMassProperties, Collider}}; use crate::{comps::core::{ @@ -7,8 +10,10 @@ use crate::{comps::core::{ markers::{holdable::HoldableObjectType, interactable::Interactable}, inventory::slot::PlayerInventorySlotType, weapons::{firearm::Firearm, firearm_data::FirearmData}, events::pickup_item::ItemState, }, setup::assets::{GltfAssets, GltfAssetType}, utils}; -#[derive(Component, Reflect)] -pub struct Ak105GunItem; +#[derive(Component)] +pub struct Ak105GunItem { + pub state: Mutex> +} impl Item for Ak105GunItem { fn get_type(&self) -> ItemType { @@ -88,7 +93,7 @@ impl Item for Ak105GunItem { )) .id(); match item_state { - Some(state) => { commands.entity(firearm_asset_entity).insert(state); }, + Some(ref state) => { commands.entity(firearm_asset_entity).insert(state.clone()); }, None => {}, }; let firearm_size = firearm.get_size(); @@ -116,10 +121,19 @@ impl Item for Ak105GunItem { impulse: with_impulse, ..Default::default() }, - Interactable::Item(firearm.get_item_arc()), + Interactable::Item(Arc::new(Ak105GunItem { state: Mutex::new(item_state) })), )) .push_children(&[firearm_asset_entity]); } } } + + + fn get_state(&self) -> Option { + self.state.lock().clone() + } + + fn set_state(&self, state: Option) { + *self.state.lock() = state + } } diff --git a/src/comps/core/items/guns/glock17.rs b/src/comps/core/items/guns/glock17.rs index 671fb3d..2989ab7 100644 --- a/src/comps/core/items/guns/glock17.rs +++ b/src/comps/core/items/guns/glock17.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use bevy::{prelude::*, gltf::Gltf}; use bevy_rapier3d::{geometry::{ColliderMassProperties, Collider}, dynamics::{RigidBody, GravityScale, ExternalImpulse}}; @@ -116,10 +118,19 @@ impl Item for Glock17GunItem { impulse: with_impulse, ..Default::default() }, - Interactable::Item(firearm.get_item_arc()), + Interactable::Item(Arc::new(Glock17GunItem) ), )) .push_children(&[firearm_asset_entity]); } } } + + fn get_state(&self) -> Option { + todo!() + } + + fn set_state(&self, state: Option) { + todo!() + } + } diff --git a/src/comps/core/items/item.rs b/src/comps/core/items/item.rs index 7f329ca..e2702d2 100644 --- a/src/comps/core/items/item.rs +++ b/src/comps/core/items/item.rs @@ -17,7 +17,7 @@ pub enum ItemType { } #[bevy_trait_query::queryable] -pub trait Item: Sync + Send + Reflect { +pub trait Item: Sync + Send { fn get_type(&self) -> ItemType; fn asset_path(&self) -> &str; /// Optional Stackable. If value is Some(x) x is the max quantity per stack @@ -26,8 +26,11 @@ pub trait Item: Sync + Send + Reflect { fn inventory_rotatable(&self) -> bool; fn inventory_title(&self) -> String; fn inventory_description(&self) -> String; + fn set_state(&self, state: Option); + fn get_state(&self) -> Option; /// Spawn an item on the game world. Every item should implement this /// The transform passed to this function should be a GlobalTransform.into() + /// fn spawn( &self, commands: &mut Commands, @@ -36,7 +39,7 @@ pub trait Item: Sync + Send + Reflect { loaded_gltf_assets: &Assets, with_impulse: Vec3, item_state: Option, - ) { + ) ;/*{ match self.get_type() { ItemType::Holdable(object_type) => { match object_type { @@ -96,7 +99,7 @@ pub trait Item: Sync + Send + Reflect { impulse: with_impulse, ..Default::default() }, - Interactable::Item(firearm.get_item_arc()), + Interactable::Item(firearm.get), )) .push_children(&[firearm_asset_entity]); } @@ -107,7 +110,7 @@ pub trait Item: Sync + Send + Reflect { ItemType::Equippable => todo!(), ItemType::Consumable => todo!(), }; - } + }*/ fn get_firearm(&self) -> Option { match self.get_type() { ItemType::Holdable(holdable) => match holdable { diff --git a/src/comps/core/markers/interactable.rs b/src/comps/core/markers/interactable.rs index 7028303..3877185 100644 --- a/src/comps/core/markers/interactable.rs +++ b/src/comps/core/markers/interactable.rs @@ -7,7 +7,7 @@ use crate::comps::core::items::item::Item; //use crate::comps::core::inventory::any_inventory::AnyInventory; #[allow(unused)] -#[derive(Component)] +#[derive(Component, Clone)] pub enum Interactable { Holdable, //Lootable(AnyInventory), diff --git a/src/comps/core/markers/proxy/weapons/firearm.rs b/src/comps/core/markers/proxy/weapons/firearm.rs index 21c3025..b280a6d 100644 --- a/src/comps/core/markers/proxy/weapons/firearm.rs +++ b/src/comps/core/markers/proxy/weapons/firearm.rs @@ -1,10 +1,10 @@ -use bevy::{prelude::*, gltf::Gltf, ecs::system::SystemParam}; +use bevy::{prelude::*, gltf::Gltf, ecs::system::SystemParam, scene::SceneInstance}; use crate::{comps::core::{weapons::{firearm::Firearm, firearm_state::FirearmState, slot::slot::WeaponSlot, attachment_slot::AttachmentSlot, attachments::weapon_attachment::WeaponAttachment}, events::pickup_item::ItemState}, setup::assets::{GltfAssets, GltfAssetType}}; #[derive(SystemParam)] pub struct InsertFirearmStateIntoFirearmsParams<'w, 's> { - firearm_scene_bundle: Query<'w, 's, (Entity, Option<&'static ItemState>, &'static Children)>, + firearm_scene_bundle: Query<'w, 's, (Entity, Option<&'static ItemState>, &'static Children), With>, firearm_query: Query<'w, 's, (Entity, &'static Firearm, &'static Parent, Option<&'static FirearmState>), Or<(Without, Changed)>>, slots_query: Query<'w, 's, (Entity, &'static WeaponSlot, &'static Parent)>, attachments_query: Query<'w, 's, (Entity, &'static WeaponAttachment, &'static Parent)>, @@ -31,8 +31,7 @@ pub fn insert_firearm_state_to_firearms( commands .entity(firearm_entity) .insert(firearm_state.clone()); - //TODO: spawn in attachments - println!("Reused firearm_state"); + spawn_attachments_in_firearm(&mut commands, firearm_entity, firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets); return; } } @@ -40,7 +39,7 @@ pub fn insert_firearm_state_to_firearms( match firearm_state_opt { Some(firearm_state) => { // Change the Slots - spawn_attachments_in_firearm(&mut commands, firearm_entity, firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets) + spawn_attachments_in_firearm(&mut commands, firearm_entity, firearm_state, &queries.slots_query, &assets_gltf, &loaded_gltf_assets); }, None => { // Create the firearm_state @@ -59,9 +58,10 @@ pub fn insert_firearm_state_to_firearms( }); } } + let firearm_state = FirearmState::new(firearm_slots); commands .entity(firearm_entity) - .insert(FirearmState::new(firearm_slots)); + .insert(firearm_state.clone()); }, }; } diff --git a/src/comps/core/spawners/guns/ak105_spawner.rs b/src/comps/core/spawners/guns/ak105_spawner.rs index 29ec6a4..42c5bf4 100644 --- a/src/comps/core/spawners/guns/ak105_spawner.rs +++ b/src/comps/core/spawners/guns/ak105_spawner.rs @@ -1,4 +1,5 @@ use bevy::prelude::*; +use bevy_inspector_egui::egui::mutex::Mutex; use crate::comps::core::{ items::{guns::ak105::Ak105GunItem, item::Item}, @@ -16,6 +17,6 @@ impl ItemSpawnPoint for Ak105SpawnPoint { } fn get_item(&self) -> Box { - Box::new(Ak105GunItem) + Box::new(Ak105GunItem { state: Mutex::new(None) }) } } diff --git a/src/comps/core/weapons/firearm.rs b/src/comps/core/weapons/firearm.rs index d6af92e..310ce86 100644 --- a/src/comps/core/weapons/firearm.rs +++ b/src/comps/core/weapons/firearm.rs @@ -1,6 +1,7 @@ -use std::sync::Arc; +use std::sync::{Arc}; use bevy::prelude::*; +use bevy_inspector_egui::egui::mutex::Mutex; use crate::comps::core::{markers::holdable::HoldableObjectData, items::{item::Item, guns::{glock17::Glock17GunItem, ak105::Ak105GunItem}}}; @@ -157,14 +158,14 @@ impl Firearm { match self { //Firearm::M4A1 => Arc::new(M4a1GunItem), Firearm::Glock17 => Arc::new(Glock17GunItem), - Firearm::Ak105 => Arc::new(Ak105GunItem), + Firearm::Ak105 => Arc::new(Ak105GunItem { state: Mutex::new(None) }), } } pub fn get_item_box(&self) -> Box { match self { //Firearm::M4A1 => Box::new(M4a1GunItem), Firearm::Glock17 => Box::new(Glock17GunItem), - Firearm::Ak105 => Box::new(Ak105GunItem), + Firearm::Ak105 => Box::new(Ak105GunItem { state: Mutex::new(None) }), } } } \ No newline at end of file diff --git a/src/logic/core/player/hands.rs b/src/logic/core/player/hands.rs index c4c143f..b897754 100644 --- a/src/logic/core/player/hands.rs +++ b/src/logic/core/player/hands.rs @@ -3,22 +3,22 @@ use bevy_rapier3d::prelude::*; use crate::{ comps::core::{ - events::{pickup_item::PickupItemEvent, inventory_changed::PlayerInventoryChangedEvent}, + events::{pickup_item::{PickupItemEvent, ItemState}, inventory_changed::PlayerInventoryChangedEvent}, inventory::{player_inventory::{PlayerInventory, self}, slot::PlayerInventorySlotType}, markers::{ camera::MainCamera, holdable::InPlayerHands, interactable::Interactable, player::Player, proxy::{character::in_player_hands_parent::InPlayerHandsParent, physics::rapier::LinkToPlayer}, - }, + }, weapons::{firearm::Firearm, firearm_state::FirearmState}, }, - logic::core::guns::{player_firing::PlayerFiringInfo, shoot::shoot_bullet}, + logic::core::guns::{player_firing::PlayerFiringInfo}, setup::{ equipment::{Equipment, EquipmentChangeEvent}, load_state::GameLoadState, assets::GltfAssets, //animations::AllAnimations, }, ui::game::{game_ui_state::GameUiState, hud::hud::HudState}, - utils::rad_deg::radians_from_degrees, + utils::{rad_deg::radians_from_degrees, hierarchy::find_child_in_parent_children}, }; #[derive(SystemParam)] @@ -41,18 +41,18 @@ pub fn capture_hand_usage( mut resources: CaptureHandUsageResourcesParams, mut commands: Commands, - mut hand_query: Query<&mut Transform, (With, Without)>, - mut firearm_query: Query< + mut hand_query: Query<(&mut Transform, Entity), (With, Without)>, + mut firearms_query: Query< ( Entity, + &Firearm, + &FirearmState, &GlobalTransform, ), - (With, Without), >, mut player_query: Query<(&Player, &mut PlayerInventory, Entity, &Transform, &mut PlayerFiringInfo)>, - //mut animation_players: Query<(Entity, &mut AnimationPlayer)>, - //children: Query<&Children>, + children: Query<&Children>, mut equipment_change_event_writer: EventWriter, mut inventory_changed_events: EventWriter, @@ -66,18 +66,19 @@ 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() { + 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() && !player_firing_info.is_reloading { if resources.keyboard_input.just_pressed(KeyCode::Key1) { if let Some(primary_item) = player_inventory.get_primary() { if let Some(primary_firearm) = primary_item.get_firearm() { - if Equipment::Firearm(primary_firearm.clone()) + if Equipment::Firearm(primary_firearm.clone(), primary_item.get_state().expect("No item state in an equipped Item.").as_firearm_state()) != player.0.equipment { + println!("CaptureHandUsage {:?}", primary_item.get_state().expect("No item state in an equipped Item.").as_firearm_state()); equipment_change_event_writer - .send(EquipmentChangeEvent(Equipment::Firearm(primary_firearm))); + .send(EquipmentChangeEvent(Equipment::Firearm(primary_firearm, primary_item.get_state().expect("No item state in an equipped Item.").as_firearm_state()))); player_inventory.current_slot = Some(PlayerInventorySlotType::Primary); } } @@ -85,11 +86,11 @@ pub fn capture_hand_usage( } else if resources.keyboard_input.just_pressed(KeyCode::Key2) { if let Some(secondary_item) = player_inventory.get_secondary() { if let Some(secondary_firearm) = secondary_item.get_firearm() { - if Equipment::Firearm(secondary_firearm.clone()) + if Equipment::Firearm(secondary_firearm.clone(), secondary_item.get_state().expect("No item state in an equipped Item.").as_firearm_state()) != player.0.equipment { equipment_change_event_writer - .send(EquipmentChangeEvent(Equipment::Firearm(secondary_firearm))); + .send(EquipmentChangeEvent(Equipment::Firearm(secondary_firearm, secondary_item.get_state().expect("No item state in an equipped Item.").as_firearm_state()))); player_inventory.current_slot = Some(PlayerInventorySlotType::Secondary); } } @@ -102,9 +103,15 @@ pub fn capture_hand_usage( } 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)); - player_inventory.current_slot = None; + for (_, in_player_hands_entity) in hand_query.iter() { + for (firearm_entity, _, firearm_state, _) in firearms_query.iter() { + if find_child_in_parent_children(&mut commands, in_player_hands_entity, firearm_entity, &children) { + 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, Some(ItemState::Weapon(firearm_state.clone()))); + equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing)); + player_inventory.current_slot = None; + } + } + } }, None => {}, } @@ -112,13 +119,13 @@ pub fn capture_hand_usage( } // Firearm stuff - if let Equipment::Firearm(_f) = player.0.equipment.clone() { + if let Equipment::Firearm(_f, _) = player.0.equipment.clone() { player_firing_info .full_auto_timer .tick(resources.time.delta()); - for (_f, firearm_transform) in - firearm_query.iter_mut() + for (_f, firearm_transform, _, _) in + firearms_query.iter_mut() { for mut hand_transform in hand_query.iter_mut() { if player_firing_info.is_reloading { @@ -290,28 +297,35 @@ pub fn capture_hand_usage( } +#[derive(SystemParam)] +pub struct InteractActionParams<'w, 's> { + player_query: Query<'w, 's, Entity, (With, Without)>, + player_collider_query: Query<'w, 's, Entity, (With, With, Without)>, + camera_query: Query<'w, 's, &'static GlobalTransform, (With, Without)>, + interactables_query: Query<'w, 's, (Entity, &'static Interactable)>, + firearms_query: Query<'w, 's, (Entity, &'static Firearm, &'static FirearmState)> +} + /// Method that is run when player hits interact button. /// Should raycast where the player is looking and scan for interactable pub fn interact_action( - //mut commands: Commands, - player_query: Query, Without)>, - player_collider_query: Query, With, Without)>, - camera_query: Query<&GlobalTransform, (With, Without)>, - interactables_query: Query<(Entity, &Interactable)>, + mut commands: Commands, + children: Query<&Children>, + query: InteractActionParams, keyboard_input: Res>, rapier_context: Res, mut hud_state: ResMut, mut pickup_item_event_writer: EventWriter, game_ui_state: Res, ) { - for player_entity in player_query.iter() { - for global_transform in camera_query.iter() { + for player_entity in query.player_query.iter() { + for global_transform in query.camera_query.iter() { let ray_pos = global_transform.translation(); let ray_dir = global_transform.forward() * 2.0; // TODO: Move this into global Resource state let max_toi = 4.0; let solid = true; - for player_collider_entity in player_collider_query.iter() { + for player_collider_entity in query.player_collider_query.iter() { if let Some((entity, _)) = rapier_context.cast_ray( ray_pos, ray_dir, @@ -319,24 +333,32 @@ pub fn interact_action( solid, QueryFilter::default().exclude_collider(player_collider_entity), ) { - for (interactable_entity, interactable) in interactables_query.iter() { + for (interactable_entity, interactable) in query.interactables_query.iter() { if interactable_entity == entity { hud_state.interaction_clue_shown = true; hud_state.interaction_clue_text = interactable.to_string(); if keyboard_input.just_pressed(KeyCode::F) && !game_ui_state.any_window() { // TODO: Move this key to Controls state global - match interactable { + match interactable.clone() { Interactable::Holdable => todo!(), /*Interactable::Lootable(any_inventory) => { loot_container_event_writer .send(LootContainerEvent(any_inventory.clone())) }*/ Interactable::Item(item) => { + let mut item_state = None; + for (firearm_entity, _, firearm_state) in query.firearms_query.iter() { + if find_child_in_parent_children(&mut commands, interactable_entity, firearm_entity, &children) { + item_state = Some(ItemState::Weapon(firearm_state.clone())); + } + } + println!("Setting item state: {:?}", item_state); + item.set_state(item_state); + pickup_item_event_writer.send(PickupItemEvent { entity: interactable_entity, - item: item.clone(), + item, player: player_entity, - state: None }); } } diff --git a/src/logic/core/player/inventory.rs b/src/logic/core/player/inventory.rs index 3d25022..3e80378 100644 --- a/src/logic/core/player/inventory.rs +++ b/src/logic/core/player/inventory.rs @@ -1,26 +1,19 @@ -use bevy::{gltf::Gltf, prelude::*}; +use bevy::prelude::*; -use crate::{ - comps::core::{ +use crate::comps::core::{ events::{pickup_item::PickupItemEvent, inventory_changed::PlayerInventoryChangedEvent}, - inventory::player_inventory::{PlayerInventory, self}, + inventory::player_inventory::PlayerInventory, markers::player::Player, - }, - setup::assets::GltfAssets, -}; + }; pub fn update_player_inventory_system( mut commands: Commands, mut pickup_item_events: EventReader, mut inventory_changed_events: EventWriter, mut player_query: Query<(Entity, &mut PlayerInventory, &Transform), With>, - assets_gltf: Res, - loaded_gltf_assets: Res>, ) { for event in pickup_item_events.read() { - println!("Pickup Item Event received"); - for (player_entity, mut player_inventory, player_transform) in player_query.iter_mut() { - println!("Player found"); + for (player_entity, mut player_inventory, _) in player_query.iter_mut() { if player_entity == event.player { // Get item type and where it should go commands @@ -28,8 +21,8 @@ pub fn update_player_inventory_system( .despawn_descendants() .despawn(); - 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()); + //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(), event.item.get_state().clone()); + player_inventory.pickup_item(event.item.clone(), event.item.get_item_slot()); inventory_changed_events.send(PlayerInventoryChangedEvent { item: Some(event.item.clone()), slot_type: event.item.get_item_slot() }); println!("Inventory Changed Event sent"); } diff --git a/src/setup/equipment.rs b/src/setup/equipment.rs index f621060..690e17a 100644 --- a/src/setup/equipment.rs +++ b/src/setup/equipment.rs @@ -6,7 +6,7 @@ use crate::{ comps::core::{markers::{ holdable::InPlayerHands, player::Player, proxy::character::in_player_hands_parent::InPlayerHandsParent, - }, weapons::{firearm::Firearm, firearm_data::FirearmData}}, + }, weapons::{firearm::Firearm, firearm_data::FirearmData, firearm_state::FirearmState}, events::pickup_item::ItemState}, logic::core::guns::player_firing::PlayerFiringInfo, utils, }; @@ -18,7 +18,7 @@ pub struct EquipmentChangeEvent(pub Equipment); /// Foundation for inventory System. #[derive(Component, Clone, Default, Reflect, PartialEq, PartialOrd)] pub enum Equipment { - Firearm(Firearm), + Firearm(Firearm, FirearmState), #[default] Nothing, } @@ -42,7 +42,10 @@ pub fn change_equipment( let player_hands = player_hands_query.single_mut(); commands.entity(player_hands).despawn_descendants(); // TODO: Don't do this without keeping the state from the last mag - if let Equipment::Firearm(new_firearm) = equipment_change_event.0.clone() { + println!(""); + + if let Equipment::Firearm(new_firearm, firearm_state) = equipment_change_event.0.clone() { + println!("Equipping: {:?}", firearm_state); spawn_firearm_on_player_hands( &mut commands, player_firing_info, @@ -50,6 +53,7 @@ pub fn change_equipment( &assets_gltf, &loaded_gltf_assets, new_firearm, + firearm_state, ); } @@ -66,6 +70,7 @@ fn spawn_firearm_on_player_hands( assets_gltf: &GltfAssets, loaded_gltf_assets: &Assets, firearm: Firearm, + firearm_state: FirearmState, ) { if let Some(asset_handle) = assets_gltf .assets @@ -90,6 +95,7 @@ fn spawn_firearm_on_player_hands( transform: firearm_transform, ..default() }, + ItemState::Weapon(firearm_state), Name::new("Firearm Gltf Asset"), )) .id();