Inventory backend
This commit is contained in:
parent
26d03de52e
commit
3f95e2cd5a
|
@ -0,0 +1,61 @@
|
|||
use bevy::{prelude::*, ecs::component::SparseStorage};
|
||||
|
||||
use super::{item::Item, inventory_item::InventoryItem, grid::UGrid};
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct AnyInventory {
|
||||
size: UGrid,
|
||||
items: Vec<InventoryItem>
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
impl AnyInventory {
|
||||
pub fn new(size: UGrid) -> Self {
|
||||
Self { size, items: Vec::new() }
|
||||
}
|
||||
pub fn add_item_at(
|
||||
&mut self,
|
||||
position: UGrid,
|
||||
item: impl Item<Storage = SparseStorage>,
|
||||
) {
|
||||
// Is Item bigger than inventory?
|
||||
// Does position + item size exceed bounds?
|
||||
if !self.valid_item_and_size_for_inventory(position, &item) {
|
||||
return;
|
||||
}
|
||||
// Is there an item in any of those places already?
|
||||
if !self.item_fits_at(position, &item) {
|
||||
return;
|
||||
}
|
||||
let spots_to_occupy = Self::get_spots_from_item_at_pos(position, &item);
|
||||
self.items.push(InventoryItem::new(item, spots_to_occupy));
|
||||
}
|
||||
// Is there any items in inventory that are in any of the spots that this new item will be in
|
||||
pub fn item_fits_at(&self, position: UGrid, item: &impl Item<Storage = SparseStorage>) -> bool {
|
||||
let spots_to_occupy = Self::get_spots_from_item_at_pos(position, item);
|
||||
for inventory_item in self.items.iter() {
|
||||
if inventory_item.is_in_range(&spots_to_occupy) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
pub fn get_spots_from_item_at_pos(position: UGrid, item: &impl Item<Storage = SparseStorage>) -> Vec<UGrid> {
|
||||
let end_position = position + item.inventory_size();
|
||||
let mut spots = Vec::new();
|
||||
for pos_width in position.width..end_position.width {
|
||||
for pos_height in position.height..end_position.height {
|
||||
spots.push(UGrid { width: pos_width, height: pos_height });
|
||||
}
|
||||
}
|
||||
spots
|
||||
}
|
||||
pub fn valid_item_and_size_for_inventory(
|
||||
&self,
|
||||
position: UGrid,
|
||||
item: &impl Item<Storage = SparseStorage>,
|
||||
) -> bool {
|
||||
let item_bounds = position + item.inventory_size();
|
||||
!(item_bounds.width > self.size.width || item_bounds.height > self.size.height)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct UGrid {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl std::ops::Add for UGrid {
|
||||
type Output = UGrid;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self { width: self.width + rhs.width, height: self.height + rhs.height }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub for UGrid {
|
||||
type Output = UGrid;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self { width: self.width - rhs.width, height: self.height - rhs.height }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
use bevy::ecs::component::SparseStorage;
|
||||
|
||||
use super::{item::Item, grid::UGrid};
|
||||
|
||||
|
||||
//#[derive()]
|
||||
pub struct InventoryItem {
|
||||
item: Box<dyn Item<Storage = SparseStorage>>,
|
||||
/// Coordinates that this InventoryItem occupies inside an AnyInventory
|
||||
occupied_spots: Vec<UGrid>,
|
||||
rotated: Option<bool>,
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
impl InventoryItem {
|
||||
pub fn item(&self) -> &dyn Item<Storage = SparseStorage> {
|
||||
self.item.as_ref()
|
||||
}
|
||||
pub fn rotated(&self) -> Option<bool> {
|
||||
self.rotated
|
||||
}
|
||||
pub fn new(
|
||||
item: impl Item<Storage = SparseStorage>,
|
||||
occupied_spots: Vec<UGrid>,
|
||||
) -> Self {
|
||||
let size = item.inventory_size();
|
||||
let rotated = item.inventory_rotatable().then(|| false);
|
||||
Self { item: Box::new(item), occupied_spots, rotated }
|
||||
}
|
||||
/// Returns true if there is overlap between both
|
||||
pub fn is_in_range(&self, spots_to_occupy: &Vec<UGrid>) -> bool {
|
||||
for occupied_spot in self.occupied_spots.iter() {
|
||||
if spots_to_occupy.contains(occupied_spot) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
use super::grid::UGrid;
|
||||
|
||||
|
||||
pub enum ItemType {
|
||||
Holdable,
|
||||
Equippable,
|
||||
Consumable,
|
||||
}
|
||||
|
||||
pub trait Item: Component {
|
||||
fn get_type(&self) -> ItemType;
|
||||
fn asset_path(&self) -> &str;
|
||||
/// Optional Stackable. If value is Some(x) x is the max quantity per stack
|
||||
fn stackable(&self) -> Option<u32>;
|
||||
fn inventory_size(&self) -> UGrid;
|
||||
fn inventory_rotatable(&self) -> bool;
|
||||
fn inventory_title(&self) -> String;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
use bevy::prelude::Component;
|
||||
|
||||
|
||||
|
||||
#[allow(unused)]
|
||||
#[derive(Component)]
|
||||
pub enum Interactable {
|
||||
Holdable,
|
||||
Lootable,
|
||||
}
|
|
@ -3,4 +3,5 @@ pub mod firearm;
|
|||
pub mod holdable;
|
||||
pub mod player;
|
||||
pub mod muzzle_flash;
|
||||
pub mod bullet;
|
||||
pub mod bullet;
|
||||
pub mod interactable;
|
|
@ -1,2 +1,6 @@
|
|||
pub mod controller;
|
||||
pub mod markers;
|
||||
pub mod any_inventory;
|
||||
pub mod item;
|
||||
pub mod grid;
|
||||
pub mod inventory_item;
|
|
@ -2,7 +2,7 @@ use bevy::prelude::*;
|
|||
|
||||
use crate::{
|
||||
comps::core::markers::{firearm::{FirearmData, MagazineData}, holdable::InPlayerHands, player::{PlayerHand, Player}},
|
||||
logic::core::guns::{player_firing::PlayerFiringInfo, firearm::Firearm, shoot::shoot_bullet}, utils::rad_deg::radians_from_degrees, setup::{animations::AllFirearmAnimations, load_state::GameLoadState, equipment::{EquipmentChangeEvent, Equipment}}, ui::game::settings::SettingsScreenUIConfiguration,
|
||||
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,
|
||||
};
|
||||
|
||||
pub fn capture_hand_usage(
|
||||
|
@ -23,7 +23,7 @@ pub fn capture_hand_usage(
|
|||
animation_clips: Res<Assets<AnimationClip>>,
|
||||
|
||||
game_load_state: Res<GameLoadState>,
|
||||
|
||||
#[allow(unused)]
|
||||
mut equipment_change_event_writer: EventWriter<EquipmentChangeEvent>,
|
||||
settings_screen_config: Res<SettingsScreenUIConfiguration>,
|
||||
|
||||
|
@ -36,7 +36,23 @@ pub fn capture_hand_usage(
|
|||
if player_query.iter().len() == 0 {
|
||||
return;
|
||||
}
|
||||
if let Some(player_firearm) = player_query.single().0.equipment.primary_firearm.clone() {
|
||||
|
||||
// Equipping stuff
|
||||
|
||||
|
||||
// Equipping gun
|
||||
/*if !settings_screen_config.settings_menu_shown {
|
||||
if keyboard_input.just_pressed(KeyCode::Key1) {
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment { primary_firearm: Some(Firearm::M4A1) } ));
|
||||
} else if keyboard_input.just_pressed(KeyCode::Key2) {
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment { primary_firearm: Some(Firearm::Glock17) } ));
|
||||
} else if keyboard_input.just_pressed(KeyCode::Key3) {
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment { primary_firearm: None } ));
|
||||
}
|
||||
}*/
|
||||
|
||||
// Firearm stuff
|
||||
if let Equipment::Firearm(player_firearm) = player_query.single().0.equipment.clone() {
|
||||
for mut player_firing_info in player_firing_info_query.iter_mut() {
|
||||
player_firing_info.full_auto_timer.tick(time.delta());
|
||||
|
||||
|
@ -87,12 +103,7 @@ pub fn capture_hand_usage(
|
|||
(time.delta_seconds() / firearm_data.rebound_time_seconds).clamp(0.0, 1.0),
|
||||
);
|
||||
}
|
||||
// Equipping gun
|
||||
if keyboard_input.just_pressed(KeyCode::Key1) && !settings_screen_config.settings_menu_shown {
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment{ primary_firearm: Some(Firearm::M4A1) }));
|
||||
} else if keyboard_input.just_pressed(KeyCode::Key2) && !settings_screen_config.settings_menu_shown {
|
||||
equipment_change_event_writer.send(EquipmentChangeEvent(Equipment{ primary_firearm: Some(Firearm::Glock17) }));
|
||||
}
|
||||
|
||||
// SHOOTING & RECOIL
|
||||
if mouse_buttons.pressed(MouseButton::Left) && !settings_screen_config.settings_menu_shown {
|
||||
if player_firing_info.full_auto_timer.finished() {
|
||||
|
@ -149,3 +160,12 @@ pub fn capture_hand_usage(
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
/// Method that is run when player hits interact button.
|
||||
/// Should raycast where the player is looking and scan for interactable
|
||||
pub fn interact_action(
|
||||
|
||||
) {
|
||||
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(step_trait)]
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier3d::prelude::*;
|
||||
use scenes::scene1;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
use crate::{setup::{spawn::SpawnPoint, equipment::Equipment}, comps::core::markers::player::{Player, PlayerData}, logic::core::guns::firearm::Firearm};
|
||||
use crate::{setup::{spawn::SpawnPoint, equipment::Equipment}, comps::core::markers::player::{Player, PlayerData}};
|
||||
|
||||
pub fn set_spawn_points(mut commands: Commands) {
|
||||
commands.spawn(SpawnPoint { at: Transform::from_xyz(3.0, 5.0, 2.0), what: Player(PlayerData{ equipment: Equipment { primary_firearm: Some(Firearm::Glock17) }}) });
|
||||
commands.spawn(SpawnPoint { at: Transform::from_xyz(3.0, 5.0, 2.0), what: Player(PlayerData { equipment: Equipment::Nothing }) });
|
||||
|
||||
}
|
|
@ -9,9 +9,11 @@ use super::assets::{GltfAssets, GltfAssetType};
|
|||
#[derive(Event)]
|
||||
pub struct EquipmentChangeEvent(pub Equipment);
|
||||
/// Foundation for inventory System.
|
||||
#[derive(Component, Clone, Default, Reflect)]
|
||||
pub struct Equipment {
|
||||
pub primary_firearm: Option<Firearm>,
|
||||
#[derive(Component, Clone, Default, Reflect, PartialEq, PartialOrd)]
|
||||
pub enum Equipment {
|
||||
Firearm(Firearm),
|
||||
#[default]
|
||||
Nothing,
|
||||
}
|
||||
|
||||
/// Called whenever player wants to change equipment
|
||||
|
@ -25,22 +27,21 @@ pub fn change_equipment(
|
|||
loaded_gltf_assets: Res<Assets<Gltf>>,
|
||||
) {
|
||||
for equipment_change_event in equipment_change_event_reader.read() {
|
||||
// TODO: Equipment change
|
||||
let Ok((mut player, player_firing_info)) = player_query.get_single_mut() else {
|
||||
return;
|
||||
} ;
|
||||
// Primary firearm change
|
||||
if equipment_change_event.0.primary_firearm != player.0.equipment.primary_firearm {
|
||||
if equipment_change_event.0 != player.0.equipment {
|
||||
|
||||
let player_hands = player_hands_query.single_mut();
|
||||
|
||||
commands.entity(player_hands).despawn_descendants(); // Don't do this without keeping the state from the last mag
|
||||
if let Some(new_firearm) = equipment_change_event.0.primary_firearm.clone() {
|
||||
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() {
|
||||
spawn_firearm_on_player_hands(&mut commands, player_firing_info, player_hands, &assets_gltf, &loaded_gltf_assets, new_firearm);
|
||||
}
|
||||
|
||||
|
||||
// Set the player's equipment to the newly spawned equipment
|
||||
player.0.equipment.primary_firearm = equipment_change_event.0.primary_firearm.clone();
|
||||
player.0.equipment = equipment_change_event.0.clone();
|
||||
println!("Equipment change done");
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
//use crate::comps::core::any_inventory::AnyInventory;
|
||||
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn setup_inventory_screen(
|
||||
mut commands: Commands,
|
||||
|
||||
) {
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
pub mod menu;
|
|
@ -2,4 +2,5 @@
|
|||
pub mod plugin;
|
||||
pub mod fps_counter;
|
||||
pub mod settings;
|
||||
pub mod settings_screen;
|
||||
pub mod settings_screen;
|
||||
pub mod inventory;
|
|
@ -2,7 +2,7 @@ use bevy::prelude::*;
|
|||
|
||||
use crate::ui::game::settings::GameConfiguration;
|
||||
|
||||
use super::{fps_counter, settings_screen, settings::SettingsScreenUIConfiguration};
|
||||
use super::{fps_counter, settings_screen, settings::SettingsScreenUIConfiguration, inventory};
|
||||
|
||||
pub struct MainGameUIPlugin;
|
||||
|
||||
|
@ -12,7 +12,9 @@ impl Plugin for MainGameUIPlugin {
|
|||
app.insert_resource(SettingsScreenUIConfiguration::default());
|
||||
app.add_systems(Startup, (
|
||||
settings_screen::setup_settings_screen,
|
||||
fps_counter::setup_fps_counter));
|
||||
fps_counter::setup_fps_counter,
|
||||
inventory::menu::setup_inventory_screen,
|
||||
));
|
||||
app.add_systems(Update, (
|
||||
settings_screen::toggle_settings_screen,
|
||||
settings_screen::handle_settings_button_click,
|
||||
|
|
Loading…
Reference in New Issue