Work on interaction system, re enabled weapon switching and noticed that Meshes are down to the bone, meaning creating a hitreg system will be relatively easy later on. Focus on the inventory definition, honestly I would just go for static primary, secondary, body armor and helmet inventory spaces. Later, add backpacks with the tetris system you just created. For the moment make everything pickupable

This commit is contained in:
Franklin 2023-11-12 00:43:54 -04:00
parent 7685caf99f
commit cdf1d573cf
14 changed files with 94 additions and 19 deletions

View File

@ -2,7 +2,8 @@ use bevy::ecs::component::SparseStorage;
use super::{item::Item, inventory_item::InventoryItem, grid::UGrid}; use super::{item::Item, inventory_item::InventoryItem, grid::UGrid};
#[allow(unused)]
#[derive(Clone)]
pub struct AnyInventory { pub struct AnyInventory {
size: UGrid, size: UGrid,
items: Vec<InventoryItem> items: Vec<InventoryItem>

View File

@ -0,0 +1,6 @@
use bevy::prelude::*;
use crate::comps::core::any_inventory::AnyInventory;
#[derive(Event)]
pub struct LootContainerEvent(pub AnyInventory);

View File

@ -0,0 +1 @@
pub mod loot_container;

View File

@ -1,10 +1,13 @@
use std::sync::Arc;
use bevy::ecs::component::SparseStorage; use bevy::ecs::component::SparseStorage;
use super::{item::Item, grid::UGrid}; use super::{item::Item, grid::UGrid};
#[derive(Clone)]
pub struct InventoryItem { pub struct InventoryItem {
item: Box<dyn Item<Storage = SparseStorage>>, item: Arc<dyn Item<Storage = SparseStorage>>,
/// Coordinates that this InventoryItem occupies inside an AnyInventory /// Coordinates that this InventoryItem occupies inside an AnyInventory
occupied_spots: Vec<UGrid>, occupied_spots: Vec<UGrid>,
rotated: Option<bool>, rotated: Option<bool>,
@ -24,7 +27,7 @@ impl InventoryItem {
) -> Self { ) -> Self {
let size = item.inventory_size(); let size = item.inventory_size();
let rotated = item.inventory_rotatable().then(|| false); let rotated = item.inventory_rotatable().then(|| false);
Self { item: Box::new(item), occupied_spots, rotated } Self { item: Arc::new(item), occupied_spots, rotated }
} }
/// Returns true if there is overlap between both /// Returns true if there is overlap between both
pub fn is_in_range(&self, spots_to_occupy: &Vec<UGrid>) -> bool { pub fn is_in_range(&self, spots_to_occupy: &Vec<UGrid>) -> bool {

View File

@ -9,7 +9,7 @@ pub enum ItemType {
Consumable, Consumable,
} }
pub trait Item: Component { pub trait Item: Component {
fn get_type(&self) -> ItemType; fn get_type(&self) -> ItemType;
fn asset_path(&self) -> &str; fn asset_path(&self) -> &str;
/// Optional Stackable. If value is Some(x) x is the max quantity per stack /// Optional Stackable. If value is Some(x) x is the max quantity per stack

View File

@ -0,0 +1,12 @@
use std::sync::Arc;
use bevy::{prelude::*, ecs::component::SparseStorage};
use super::item::Item;
/// # ItemInventory
/// Specifically made to hold single items such as Guns, Pieces of armor.
#[derive(Component, Clone, Default)]
pub struct ItemInventory {
pub item: Option<Arc<dyn Item<Storage = SparseStorage>>>,
}

View File

@ -5,7 +5,6 @@ use bevy::prelude::Component;
use crate::comps::core::any_inventory::AnyInventory; use crate::comps::core::any_inventory::AnyInventory;
#[allow(unused)] #[allow(unused)]
#[derive(Component)] #[derive(Component)]
pub enum Interactable { pub enum Interactable {

View File

@ -3,4 +3,7 @@ pub mod markers;
pub mod any_inventory; pub mod any_inventory;
pub mod item; pub mod item;
pub mod grid; pub mod grid;
pub mod inventory_item; pub mod inventory_item;
pub mod events;
pub mod item_inventory;
pub mod player_inventory;

View File

@ -0,0 +1,16 @@
use bevy::prelude::*;
use super::{item_inventory::ItemInventory, any_inventory::AnyInventory, grid::UGrid};
#[derive(Component)]
pub struct PlayerInventory {
pub primary: ItemInventory,
pub secondary: ItemInventory,
pub backpack: AnyInventory,
}
impl Default for PlayerInventory {
fn default() -> Self {
Self { primary: Default::default(), secondary: Default::default(), backpack: AnyInventory::new(UGrid::new_square(10)) }
}
}

View File

@ -2,8 +2,8 @@ use bevy::prelude::*;
use bevy_rapier3d::prelude::*; use bevy_rapier3d::prelude::*;
use crate::{ use crate::{
comps::core::markers::{firearm::{FirearmData, MagazineData}, holdable::InPlayerHands, player::{PlayerHand, Player}, camera::MainCamera, interactable::Interactable}, comps::core::{markers::{firearm::{FirearmData, MagazineData}, holdable::InPlayerHands, player::{PlayerHand, Player}, camera::MainCamera, interactable::Interactable}, events::loot_container::LootContainerEvent},
logic::core::guns::{player_firing::PlayerFiringInfo, shoot::shoot_bullet}, utils::rad_deg::radians_from_degrees, setup::{animations::AllFirearmAnimations, load_state::GameLoadState, equipment::{EquipmentChangeEvent, Equipment}}, ui::game::{settings::SettingsScreenUIConfiguration, hud::hud::HudState}, logic::core::guns::{player_firing::PlayerFiringInfo, shoot::shoot_bullet, firearm::Firearm}, utils::rad_deg::radians_from_degrees, setup::{animations::AllFirearmAnimations, load_state::GameLoadState, equipment::{EquipmentChangeEvent, Equipment}}, ui::game::{settings::SettingsScreenUIConfiguration, hud::hud::HudState},
}; };
pub fn capture_hand_usage( pub fn capture_hand_usage(
@ -42,15 +42,15 @@ pub fn capture_hand_usage(
// Equipping gun // Equipping gun
/*if !settings_screen_config.settings_menu_shown { if !settings_screen_config.settings_menu_shown {
if keyboard_input.just_pressed(KeyCode::Key1) { if keyboard_input.just_pressed(KeyCode::Key1) {
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment { primary_firearm: Some(Firearm::M4A1) } )); equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Firearm(Firearm::M4A1)));
} else if keyboard_input.just_pressed(KeyCode::Key2) { } else if keyboard_input.just_pressed(KeyCode::Key2) {
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment { primary_firearm: Some(Firearm::Glock17) } )); equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Firearm(Firearm::Glock17) ));
} else if keyboard_input.just_pressed(KeyCode::Key3) { } else if keyboard_input.just_pressed(KeyCode::Key3) {
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment { primary_firearm: None } )); equipment_change_event_writer.send(EquipmentChangeEvent(Equipment::Nothing ));
} }
}*/ }
// Firearm stuff // Firearm stuff
if let Equipment::Firearm(player_firearm) = player_query.single().0.equipment.clone() { if let Equipment::Firearm(player_firearm) = player_query.single().0.equipment.clone() {
@ -172,6 +172,7 @@ pub fn interact_action(
keyboard_input: Res<Input<KeyCode>>, keyboard_input: Res<Input<KeyCode>>,
rapier_context: Res<RapierContext>, rapier_context: Res<RapierContext>,
mut hud_state: ResMut<HudState>, mut hud_state: ResMut<HudState>,
mut loot_container_event_writer: EventWriter<LootContainerEvent>,
) { ) {
for transform in player_query.iter() { for transform in player_query.iter() {
for global_transform in camera_query.iter() { for global_transform in camera_query.iter() {
@ -183,12 +184,16 @@ pub fn interact_action(
if let Some((entity, _toi)) = rapier_context.cast_ray( if let Some((entity, _toi)) = rapier_context.cast_ray(
ray_pos, ray_dir, max_toi, solid, QueryFilter::only_fixed() ray_pos, ray_dir, max_toi, solid, QueryFilter::only_fixed()
) { ) {
for (interactable_entity, _interactable) in interactables_query.iter() { for (interactable_entity, interactable) in interactables_query.iter() {
if interactable_entity == entity { if interactable_entity == entity {
hud_state.interaction_clue_shown = true; hud_state.interaction_clue_shown = true;
if keyboard_input.just_pressed(KeyCode::F) { // TODO: Move this key to Controls state global if keyboard_input.just_pressed(KeyCode::F) { // TODO: Move this key to Controls state global
println!("Interacted with interactable"); println!("Interacted with interactable");
match interactable {
Interactable::Holdable => todo!(),
Interactable::Lootable(any_inventory) => loot_container_event_writer.send(LootContainerEvent(any_inventory.clone())),
Interactable::Item => todo!(),
}
} }
} }
return; return;

View File

@ -1,11 +1,22 @@
use bevy::prelude::*; use bevy::prelude::*;
//use crate::comps::core::any_inventory::AnyInventory; use crate::comps::core::events::loot_container::LootContainerEvent;
#[allow(unused)] /// # Inventory Screen
/// Should contain player inventory and if player is looting something as well
pub fn setup_inventory_screen( pub fn setup_inventory_screen(
mut commands: Commands, mut commands: Commands,
) {
) {
}
pub fn update_inventory_screen(
mut commands: Commands,
mut event_reader: EventReader<LootContainerEvent>,
) {
for loot_container_event in event_reader.read() {
//let a = loot_container_event.0.clone();
}
} }

View File

@ -1 +1,2 @@
pub mod menu; pub mod menu;
pub mod plugin;

View File

@ -0,0 +1,16 @@
use bevy::prelude::*;
use crate::comps::core::events::loot_container::LootContainerEvent;
use super::menu::{setup_inventory_screen, update_inventory_screen};
pub struct InventoryMenuPlugin;
impl Plugin for InventoryMenuPlugin {
fn build(&self, app: &mut App) {
app.add_event::<LootContainerEvent>();
app.add_systems(Startup, setup_inventory_screen);
app.add_systems(Update, update_inventory_screen);
}
}

View File

@ -9,6 +9,7 @@ pub struct MainGameUIPlugin;
impl Plugin for MainGameUIPlugin { impl Plugin for MainGameUIPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugins(hud::plugin::HudOverlayPlugin); app.add_plugins(hud::plugin::HudOverlayPlugin);
app.add_plugins(inventory::plugin::InventoryMenuPlugin);
app.insert_resource(GameConfiguration::default()); app.insert_resource(GameConfiguration::default());
app.insert_resource(SettingsScreenUIConfiguration::default()); app.insert_resource(SettingsScreenUIConfiguration::default());
app.add_systems(Startup, ( app.add_systems(Startup, (