From 61f33357a4dc9f149733b97c457578dbc4518a74 Mon Sep 17 00:00:00 2001 From: Franklin Date: Sun, 12 Nov 2023 14:36:37 -0400 Subject: [PATCH] Integrated trait objects and made modular spawn points --- Cargo.lock | 26 +++++++++++++++ Cargo.toml | 3 +- src/comps/core/events/mod.rs | 2 +- src/comps/core/events/pickup_item.rs | 6 +++- src/comps/core/inventory/any_inventory.rs | 10 +++--- src/comps/core/inventory/inventory_item.rs | 6 ++-- src/comps/core/inventory/item_inventory.rs | 8 ++--- src/comps/core/inventory/mod.rs | 4 +-- src/comps/core/inventory/player_inventory.rs | 16 ++++----- src/comps/core/items/item.rs | 3 +- src/comps/core/markers/interactable.rs | 6 ++-- src/logic/core/player/hands.rs | 15 +++++---- src/main.rs | 6 +++- src/scenes/scene1/obstacles.rs | 8 ++--- src/scenes/scene1/spawn_points.rs | 18 ++++------ src/setup/spawn.rs | 12 ++----- src/setup/spawners/guns/m4a1_spawner.rs | 18 ++++++++++ src/setup/spawners/guns/mod.rs | 1 + src/setup/spawners/item.rs | 35 ++++++++++++++------ src/setup/spawners/mod.rs | 2 ++ src/setup/spawners/player.rs | 20 ++++++++--- src/setup/spawners/spawn_point.rs | 18 ++++++++++ src/ui/game/inventory/menu.rs | 8 ++--- src/ui/game/inventory/plugin.rs | 4 +-- 24 files changed, 168 insertions(+), 87 deletions(-) create mode 100644 src/setup/spawners/guns/m4a1_spawner.rs create mode 100644 src/setup/spawners/guns/mod.rs create mode 100644 src/setup/spawners/spawn_point.rs diff --git a/Cargo.lock b/Cargo.lock index 7d53470..3d4a672 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -390,6 +390,31 @@ dependencies = [ "syn 2.0.32", ] +[[package]] +name = "bevy-trait-query" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c0e3cf09569de8478a06f958a0df02cb12ecbda4d77059d8e4dc3e5a072126" +dependencies = [ + "bevy-trait-query-impl", + "bevy_app", + "bevy_core", + "bevy_ecs", + "tracing", +] + +[[package]] +name = "bevy-trait-query-impl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9d5d3e9b4854feb8b622ceaa36e84cb4a14e30ef8b12231db681a04f545748" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "bevy_a11y" version = "0.12.0" @@ -1885,6 +1910,7 @@ version = "0.1.0" dependencies = [ "bevy", "bevy-inspector-egui", + "bevy-trait-query", "bevy_editor_pls", "bevy_hanabi", "bevy_rapier3d", diff --git a/Cargo.toml b/Cargo.toml index c2dd9f3..4b593af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,4 +19,5 @@ bevy = { version = "0.12", features = ["dynamic_linking"]} bevy-inspector-egui = "0.21.0" bevy_editor_pls = "0.6" bevy_rapier3d = { path = "../bevy_rapier/bevy_rapier3d", features = ["debug-render-3d"] } -bevy_hanabi = { version = "0.8", default-features = false, features = [ "3d" ] } \ No newline at end of file +bevy_hanabi = { version = "0.8", default-features = false, features = [ "3d" ] } +bevy-trait-query = "0.4.0" \ No newline at end of file diff --git a/src/comps/core/events/mod.rs b/src/comps/core/events/mod.rs index 11ba1cd..c39b28d 100644 --- a/src/comps/core/events/mod.rs +++ b/src/comps/core/events/mod.rs @@ -1,2 +1,2 @@ -pub mod loot_container; +//pub mod loot_container; pub mod pickup_item; diff --git a/src/comps/core/events/pickup_item.rs b/src/comps/core/events/pickup_item.rs index 4765ddf..a555971 100644 --- a/src/comps/core/events/pickup_item.rs +++ b/src/comps/core/events/pickup_item.rs @@ -1,4 +1,8 @@ +use std::sync::Arc; + use bevy::prelude::*; +use crate::comps::core::items::item::Item; + #[derive(Event)] -pub struct PickupItemEvent(); +pub struct PickupItemEvent(pub Arc); diff --git a/src/comps/core/inventory/any_inventory.rs b/src/comps/core/inventory/any_inventory.rs index dead03b..e432799 100644 --- a/src/comps/core/inventory/any_inventory.rs +++ b/src/comps/core/inventory/any_inventory.rs @@ -1,5 +1,3 @@ -use bevy::ecs::component::SparseStorage; - use crate::comps::core::{grid::UGrid, items::item::Item}; use super::inventory_item::InventoryItem; @@ -19,7 +17,7 @@ impl AnyInventory { items: Vec::new(), } } - pub fn add_item_at(&mut self, position: UGrid, item: impl Item) { + pub fn add_item_at(&mut self, position: UGrid, item: impl Item) { // Is Item bigger than inventory? // Does position + item size exceed bounds? if !self.valid_item_and_size_for_inventory(position, &item) { @@ -33,7 +31,7 @@ impl AnyInventory { 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) -> bool { + pub fn item_fits_at(&self, position: UGrid, item: &impl Item) -> 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) { @@ -44,7 +42,7 @@ impl AnyInventory { } pub fn get_spots_from_item_at_pos( position: UGrid, - item: &impl Item, + item: &impl Item, ) -> Vec { let end_position = position + item.inventory_size(); let mut spots = Vec::new(); @@ -61,7 +59,7 @@ impl AnyInventory { pub fn valid_item_and_size_for_inventory( &self, position: UGrid, - item: &impl Item, + item: &impl Item, ) -> bool { let item_bounds = position + item.inventory_size(); !(item_bounds.width > self.size.width || item_bounds.height > self.size.height) diff --git a/src/comps/core/inventory/inventory_item.rs b/src/comps/core/inventory/inventory_item.rs index c3c9ed6..fd0219b 100644 --- a/src/comps/core/inventory/inventory_item.rs +++ b/src/comps/core/inventory/inventory_item.rs @@ -6,7 +6,7 @@ use crate::comps::core::{grid::UGrid, items::item::Item}; #[derive(Clone)] pub struct InventoryItem { - item: Arc>, + item: Arc, /// Coordinates that this InventoryItem occupies inside an AnyInventory occupied_spots: Vec, rotated: Option, @@ -14,13 +14,13 @@ pub struct InventoryItem { #[allow(unused)] impl InventoryItem { - pub fn item(&self) -> &dyn Item { + pub fn item(&self) -> &dyn Item { self.item.as_ref() } pub fn rotated(&self) -> Option { self.rotated } - pub fn new(item: impl Item, occupied_spots: Vec) -> Self { + pub fn new(item: impl Item, occupied_spots: Vec) -> Self { let size = item.inventory_size(); let rotated = item.inventory_rotatable().then(|| false); Self { diff --git a/src/comps/core/inventory/item_inventory.rs b/src/comps/core/inventory/item_inventory.rs index 8867677..a631c8c 100644 --- a/src/comps/core/inventory/item_inventory.rs +++ b/src/comps/core/inventory/item_inventory.rs @@ -1,12 +1,10 @@ -use std::sync::Arc; - -use bevy::{ecs::component::SparseStorage, prelude::*}; +use bevy::prelude::*; use crate::comps::core::items::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>>, +pub struct ItemInventory<'a> { + pub item: Option<&'a dyn Item>, } diff --git a/src/comps/core/inventory/mod.rs b/src/comps/core/inventory/mod.rs index 1ea89c8..648fd30 100644 --- a/src/comps/core/inventory/mod.rs +++ b/src/comps/core/inventory/mod.rs @@ -1,4 +1,4 @@ -pub mod any_inventory; -pub mod inventory_item; +//pub mod any_inventory; +//pub mod inventory_item; pub mod item_inventory; pub mod player_inventory; diff --git a/src/comps/core/inventory/player_inventory.rs b/src/comps/core/inventory/player_inventory.rs index e9c20a5..59787b7 100644 --- a/src/comps/core/inventory/player_inventory.rs +++ b/src/comps/core/inventory/player_inventory.rs @@ -1,22 +1,20 @@ use bevy::prelude::*; -use crate::comps::core::grid::UGrid; - -use super::{any_inventory::AnyInventory, item_inventory::ItemInventory}; +use super::item_inventory::ItemInventory; #[derive(Component)] -pub struct PlayerInventory { - pub primary: ItemInventory, - pub secondary: ItemInventory, - pub backpack: AnyInventory, +pub struct PlayerInventory<'a> { + pub primary: ItemInventory<'a>, + pub secondary: ItemInventory<'a>, + //pub backpack: AnyInventory, } -impl Default for PlayerInventory { +impl<'a> Default for PlayerInventory<'a> { fn default() -> Self { Self { primary: Default::default(), secondary: Default::default(), - backpack: AnyInventory::new(UGrid::new_square(10)), + //backpack: AnyInventory::new(UGrid::new_square(10)), } } } diff --git a/src/comps/core/items/item.rs b/src/comps/core/items/item.rs index 31a52f7..3b64ce6 100644 --- a/src/comps/core/items/item.rs +++ b/src/comps/core/items/item.rs @@ -16,7 +16,8 @@ pub enum ItemType { Consumable, } -pub trait Item: Component { +#[bevy_trait_query::queryable] +pub trait Item { fn get_type(&self) -> ItemType; fn asset_path(&self) -> &str; /// Optional Stackable. If value is Some(x) x is the max quantity per stack diff --git a/src/comps/core/markers/interactable.rs b/src/comps/core/markers/interactable.rs index 7181bc9..111ee83 100644 --- a/src/comps/core/markers/interactable.rs +++ b/src/comps/core/markers/interactable.rs @@ -2,13 +2,13 @@ use std::fmt::Display; use bevy::prelude::Component; -use crate::comps::core::inventory::any_inventory::AnyInventory; +//use crate::comps::core::inventory::any_inventory::AnyInventory; #[allow(unused)] #[derive(Component)] pub enum Interactable { Holdable, - Lootable(AnyInventory), + //Lootable(AnyInventory), Item, } @@ -16,7 +16,7 @@ impl Display for Interactable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Interactable::Holdable => write!(f, "Holdable"), - Interactable::Lootable(_) => write!(f, "Lootable"), + //Interactable::Lootable(_) => write!(f, "Lootable"), Interactable::Item => write!(f, "Item"), } } diff --git a/src/logic/core/player/hands.rs b/src/logic/core/player/hands.rs index 64ae37e..6b63b5f 100644 --- a/src/logic/core/player/hands.rs +++ b/src/logic/core/player/hands.rs @@ -3,7 +3,7 @@ use bevy_rapier3d::prelude::*; use crate::{ comps::core::{ - events::loot_container::LootContainerEvent, + //events::loot_container::LootContainerEvent, markers::{ camera::MainCamera, firearm::{FirearmData, MagazineData}, @@ -225,7 +225,7 @@ pub fn interact_action( keyboard_input: Res>, rapier_context: Res, mut hud_state: ResMut, - mut loot_container_event_writer: EventWriter, + //mut loot_container_event_writer: EventWriter, ) { for (player_entity, transform) in player_query.iter() { for global_transform in camera_query.iter() { @@ -250,17 +250,18 @@ pub fn interact_action( if interactable_entity == entity { hud_state.interaction_clue_shown = true; hud_state.interaction_clue_text = interactable.to_string(); - println!("{interactable}"); if keyboard_input.just_pressed(KeyCode::F) { // TODO: Move this key to Controls state global - println!("Interacted with interactable"); match interactable { Interactable::Holdable => todo!(), - Interactable::Lootable(any_inventory) => { + /*Interactable::Lootable(any_inventory) => { loot_container_event_writer .send(LootContainerEvent(any_inventory.clone())) - } - Interactable::Item => todo!(), + }*/ + Interactable::Item => { + //loot_container_event_writer + // .send() + }, } } return; diff --git a/src/main.rs b/src/main.rs index 0c0acee..157415f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,10 @@ #![feature(step_trait)] +#![feature(trivial_bounds)] +#![feature(return_position_impl_trait_in_trait)] use bevy::prelude::*; use bevy_rapier3d::prelude::*; use scenes::scene1; +use setup::spawners::{spawn_point::SpawnPointPlugin, item::ItemSpawnPointPlugin}; use ui::{editor::plugin::MainEditorUiPlugin, game::plugin::MainGameUIPlugin}; mod comps; @@ -30,7 +33,8 @@ fn setup_plugins(application: &mut App) { //.add_plugins(bevy_egui::EguiPlugin) //.add_plugins(WorldInspectorPlugin::new()) .add_plugins(MainGameUIPlugin) - .add_plugins(MainEditorUiPlugin); + .add_plugins(MainEditorUiPlugin) + .add_plugins((SpawnPointPlugin, ItemSpawnPointPlugin)); } fn load(application: &mut App) { diff --git a/src/scenes/scene1/obstacles.rs b/src/scenes/scene1/obstacles.rs index 8769d8b..2ae55d6 100644 --- a/src/scenes/scene1/obstacles.rs +++ b/src/scenes/scene1/obstacles.rs @@ -1,10 +1,6 @@ use bevy::prelude::*; use bevy_rapier3d::prelude::*; -use crate::comps::core::{ - grid::UGrid, inventory::any_inventory::AnyInventory, markers::interactable::Interactable, -}; - pub fn spawn_obstacles( mut commands: Commands, mut meshes: ResMut>, @@ -101,7 +97,7 @@ pub fn spawn_obstacles( transform: Transform::from_xyz(20.0, 2.0, 20.0), ..default() }) - .insert(Interactable::Lootable(AnyInventory::new( + /*.insert(Interactable::Lootable(AnyInventory::new( UGrid::new_square(10), - ))); + )))*/; } diff --git a/src/scenes/scene1/spawn_points.rs b/src/scenes/scene1/spawn_points.rs index 845feb9..e6f380f 100644 --- a/src/scenes/scene1/spawn_points.rs +++ b/src/scenes/scene1/spawn_points.rs @@ -1,20 +1,16 @@ use bevy::prelude::*; use crate::{ - comps::core::{ - items::guns::m4a1::M4a1GunItem, - markers::player::{Player, PlayerData}, - }, - setup::spawn::SpawnPoint, + comps::core::markers::player::{Player, PlayerData}, + setup::spawners::{player::PlayerSpawnPoint, guns::m4a1_spawner::M4a1SpawnPoint}, }; pub fn set_spawn_points(mut commands: Commands) { - commands.spawn(SpawnPoint { - at: Transform::from_xyz(3.0, 5.0, 2.0), - what: Player(PlayerData::default()), + commands.spawn(PlayerSpawnPoint { + transform: Transform::from_xyz(3.0, 5.0, 2.0), + player: Player(PlayerData::default()), }); - commands.spawn(SpawnPoint { - at: Transform::from_xyz(20.0, 10.0, 10.0), - what: M4a1GunItem, + commands.spawn(M4a1SpawnPoint { + transform: Transform::from_xyz(20.0, 10.0, 10.0), }); } diff --git a/src/setup/spawn.rs b/src/setup/spawn.rs index a1605c3..a0f50cd 100644 --- a/src/setup/spawn.rs +++ b/src/setup/spawn.rs @@ -1,22 +1,16 @@ use bevy::prelude::*; -use crate::comps::core::items::{guns::m4a1::M4a1GunItem, item::Item}; - -use super::{ - equipment::change_equipment, - spawners::{item::item_spawner, player::player_spawner}, -}; +use super::spawners::{item::item_spawner, player::player_spawner}; /// Where some Bundle T will replace this. #[derive(Component, Reflect)] -pub struct SpawnPoint { +pub struct SpawnPoint { pub at: Transform, - pub what: T, } pub fn add_all_spawners(application: &mut App) { application.add_systems( Update, - (player_spawner, item_spawner::).after(change_equipment), + (player_spawner, item_spawner), ); } diff --git a/src/setup/spawners/guns/m4a1_spawner.rs b/src/setup/spawners/guns/m4a1_spawner.rs new file mode 100644 index 0000000..59043dd --- /dev/null +++ b/src/setup/spawners/guns/m4a1_spawner.rs @@ -0,0 +1,18 @@ +use bevy::prelude::*; + +use crate::{setup::spawners::item::ItemSpawnPoint, comps::core::items::{guns::m4a1::M4a1GunItem, item::Item}}; + +#[derive(Component)] +pub struct M4a1SpawnPoint { + pub transform: Transform, +} + +impl ItemSpawnPoint for M4a1SpawnPoint { + fn get_transform(&self) -> Transform { + self.transform + } + + fn get_item(&self) -> Box { + Box::new(M4a1GunItem) + } +} \ No newline at end of file diff --git a/src/setup/spawners/guns/mod.rs b/src/setup/spawners/guns/mod.rs new file mode 100644 index 0000000..9cc5dbc --- /dev/null +++ b/src/setup/spawners/guns/mod.rs @@ -0,0 +1 @@ +pub mod m4a1_spawner; \ No newline at end of file diff --git a/src/setup/spawners/item.rs b/src/setup/spawners/item.rs index f7bce3a..70fc4a9 100644 --- a/src/setup/spawners/item.rs +++ b/src/setup/spawners/item.rs @@ -1,22 +1,37 @@ -use bevy::{gltf::Gltf, prelude::*}; +use bevy::{prelude::*, gltf::Gltf}; -use crate::{ - comps::core::items::{guns::m4a1::M4a1GunItem, item::Item}, - setup::{assets::GltfAssets, load_state::GameLoadState, spawn::SpawnPoint}, -}; +use crate::{setup::{load_state::GameLoadState, assets::GltfAssets, spawners::guns::m4a1_spawner::M4a1SpawnPoint}, comps::core::items::item::Item}; -pub fn item_spawner( +#[bevy_trait_query::queryable] +pub trait ItemSpawnPoint { + fn get_transform(&self) -> Transform; + fn get_item(&self) -> Box; +} + +pub fn item_spawner( mut commands: Commands, - item_sp_query: Query<(Entity, &SpawnPoint)>, + item_sp_query: Query<(Entity, &dyn ItemSpawnPoint)>, game_load_state: ResMut, assets_gltf: Res, loaded_gltf_assets: Res>, ) { if game_load_state.is_everything_except_player_loaded() { - for (entity, item_sp) in item_sp_query.iter() { - let m4 = M4a1GunItem; - m4.spawn(&mut commands, item_sp.at, &assets_gltf, &loaded_gltf_assets); + for (entity, item_sp_entity) in item_sp_query.iter() { + for component_sp in item_sp_entity { + println!("Spawning item"); + component_sp.get_item().spawn(&mut commands, component_sp.get_transform(), &assets_gltf, &loaded_gltf_assets) + } + //m4.spawn(&mut commands, item_sp.at, &assets_gltf, &loaded_gltf_assets); commands.entity(entity).despawn(); } } } + +pub struct ItemSpawnPointPlugin; +impl Plugin for ItemSpawnPointPlugin { + fn build(&self, app: &mut App) { + use bevy_trait_query::RegisterExt; + app + .register_component_as::(); + } +} \ No newline at end of file diff --git a/src/setup/spawners/mod.rs b/src/setup/spawners/mod.rs index 1bbbb34..8518499 100644 --- a/src/setup/spawners/mod.rs +++ b/src/setup/spawners/mod.rs @@ -1,2 +1,4 @@ pub mod item; pub mod player; +pub mod spawn_point; +pub mod guns; \ No newline at end of file diff --git a/src/setup/spawners/player.rs b/src/setup/spawners/player.rs index 0afc24f..2b8155f 100644 --- a/src/setup/spawners/player.rs +++ b/src/setup/spawners/player.rs @@ -16,13 +16,25 @@ use crate::{ setup::{equipment::EquipmentChangeEvent, load_state::GameLoadState}, }; -use crate::setup::spawn::SpawnPoint; +use super::spawn_point::SpawnPoint; + +#[derive(Component)] +pub struct PlayerSpawnPoint { + pub transform: Transform, + pub player: Player, +} + +impl SpawnPoint for PlayerSpawnPoint { + fn get_transform(&self) -> Transform { + self.transform + } +} /// System that runs every fame checking if player has been spawned. /// For player to spawn, everything inside GameLoadState must be loaded Except player. pub fn player_spawner( mut commands: Commands, - player_sp_query: Query<(Entity, &SpawnPoint)>, + player_sp_query: Query<(Entity, &PlayerSpawnPoint)>, mut game_load_state: ResMut, mut equipment_change_event_writer: EventWriter, player_values_state: Res, @@ -72,7 +84,7 @@ pub fn player_spawner( combine_rule: CoefficientCombineRule::Multiply, }) .insert(TransformBundle { - local: player_spawn_point.at, + local: player_spawn_point.get_transform(), ..Default::default() }) .insert(Velocity::zero()) @@ -106,7 +118,7 @@ pub fn player_spawner( game_load_state.player_loaded = true; equipment_change_event_writer.send(EquipmentChangeEvent( - player_spawn_point.what.0.equipment.clone(), + player_spawn_point.player.0.equipment.clone() )); commands.entity(player_spawn_point_entity).despawn(); } diff --git a/src/setup/spawners/spawn_point.rs b/src/setup/spawners/spawn_point.rs new file mode 100644 index 0000000..1ab0082 --- /dev/null +++ b/src/setup/spawners/spawn_point.rs @@ -0,0 +1,18 @@ +use bevy::prelude::*; + +use crate::setup::spawners::player::PlayerSpawnPoint; + + +#[bevy_trait_query::queryable] +pub trait SpawnPoint { + fn get_transform(&self) -> Transform; +} + +pub struct SpawnPointPlugin; +impl Plugin for SpawnPointPlugin { + fn build(&self, app: &mut App) { + use bevy_trait_query::RegisterExt; + app. + register_component_as::(); + } +} \ No newline at end of file diff --git a/src/ui/game/inventory/menu.rs b/src/ui/game/inventory/menu.rs index bbf4373..0b6dd1f 100644 --- a/src/ui/game/inventory/menu.rs +++ b/src/ui/game/inventory/menu.rs @@ -1,6 +1,6 @@ use bevy::prelude::*; -use crate::comps::core::events::loot_container::LootContainerEvent; +//use crate::comps::core::events::loot_container::LootContainerEvent; /// # Inventory Screen /// Should contain player inventory and if player is looting something as well @@ -8,9 +8,7 @@ pub fn setup_inventory_screen(mut commands: Commands) {} pub fn update_inventory_screen( mut commands: Commands, - mut event_reader: EventReader, + //mut event_reader: EventReader, ) { - for loot_container_event in event_reader.read() { - //let a = loot_container_event.0.clone(); - } + } diff --git a/src/ui/game/inventory/plugin.rs b/src/ui/game/inventory/plugin.rs index d8c9b9b..dae2602 100644 --- a/src/ui/game/inventory/plugin.rs +++ b/src/ui/game/inventory/plugin.rs @@ -1,6 +1,6 @@ use bevy::prelude::*; -use crate::comps::core::events::loot_container::LootContainerEvent; +//use crate::comps::core::events::loot_container::LootContainerEvent; use super::menu::{setup_inventory_screen, update_inventory_screen}; @@ -8,7 +8,7 @@ pub struct InventoryMenuPlugin; impl Plugin for InventoryMenuPlugin { fn build(&self, app: &mut App) { - app.add_event::(); + //app.add_event::(); app.add_systems(Startup, setup_inventory_screen); app.add_systems(Update, update_inventory_screen); }