From afe3b978942df782f1d4dc3588a142a2506bb7c6 Mon Sep 17 00:00:00 2001 From: demenik Date: Thu, 27 Nov 2025 17:47:10 +0100 Subject: [PATCH 1/3] feat: Add inventory and item components (#48) --- src/features/inventory/components.rs | 9 +++++++++ src/features/inventory/mod.rs | 11 +++++++++++ src/features/mod.rs | 2 ++ src/main.rs | 1 + src/prelude.rs | 1 + 5 files changed, 24 insertions(+) create mode 100644 src/features/inventory/components.rs create mode 100644 src/features/inventory/mod.rs diff --git a/src/features/inventory/components.rs b/src/features/inventory/components.rs new file mode 100644 index 0000000..009269f --- /dev/null +++ b/src/features/inventory/components.rs @@ -0,0 +1,9 @@ +use crate::prelude::*; + +#[derive(Component)] +pub struct Item; + +#[derive(Resource, Default)] +pub struct Inventory { + pub items: Vec, +} diff --git a/src/features/inventory/mod.rs b/src/features/inventory/mod.rs new file mode 100644 index 0000000..128d7c5 --- /dev/null +++ b/src/features/inventory/mod.rs @@ -0,0 +1,11 @@ +use crate::prelude::*; + +pub mod components; + +pub struct InventoryPlugin; + +impl Plugin for InventoryPlugin { + fn build(&self, app: &mut App) { + app.init_resource::(); + } +} diff --git a/src/features/mod.rs b/src/features/mod.rs index 3cd19db..d426610 100644 --- a/src/features/mod.rs +++ b/src/features/mod.rs @@ -3,6 +3,7 @@ pub mod core; pub mod game_screen; pub mod grid; pub mod input; +pub mod inventory; pub mod phase; pub mod pom; pub mod savegame; @@ -14,6 +15,7 @@ pub use core::CorePlugin; pub use game_screen::GameScreenPlugin; pub use grid::GridPlugin; pub use input::InputPlugin; +pub use inventory::InventoryPlugin; pub use phase::PhasePlugin; pub use pom::PomPlugin; pub use savegame::SavegamePlugin; diff --git a/src/main.rs b/src/main.rs index 8b26ce0..5c07bfc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,6 +32,7 @@ fn main() { features::StatusPlugin, features::SavegamePlugin, features::UiPlugin, + features::InventoryPlugin, )) .insert_resource(config) .run(); diff --git a/src/prelude.rs b/src/prelude.rs index 15a1fc2..5bfe8e3 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -7,6 +7,7 @@ pub use crate::features::{ consts::TILE_SIZE, utils::{grid_to_world_coords, world_to_grid_coords}, }, + inventory::components::{Inventory, Item}, phase::components::{CurrentPhase, Phase}, pom::{ components::{GridPosition, MovingState, Pom}, From 78997acf3175449f1e42bd06fdbee109d0d16b02 Mon Sep 17 00:00:00 2001 From: demenik Date: Thu, 27 Nov 2025 18:08:35 +0100 Subject: [PATCH 2/3] feat: Add inventory savegame loading (#48) --- src/features/inventory/components.rs | 13 ++++++++++++- src/features/savegame/mod.rs | 20 ++++++++++++++++++++ src/prelude.rs | 2 +- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/features/inventory/components.rs b/src/features/inventory/components.rs index 009269f..bbb5ff5 100644 --- a/src/features/inventory/components.rs +++ b/src/features/inventory/components.rs @@ -3,7 +3,18 @@ use crate::prelude::*; #[derive(Component)] pub struct Item; -#[derive(Resource, Default)] +#[derive(Serialize, Deserialize, Clone)] +pub enum ItemType { + Berry, +} + +#[derive(Component, Serialize, Deserialize, Clone)] +pub struct ItemStack { + pub item_type: ItemType, + pub amount: u32, +} + +#[derive(Resource, Default, Serialize, Deserialize)] pub struct Inventory { pub items: Vec, } diff --git a/src/features/savegame/mod.rs b/src/features/savegame/mod.rs index d52d6b6..a492b1c 100644 --- a/src/features/savegame/mod.rs +++ b/src/features/savegame/mod.rs @@ -28,6 +28,7 @@ struct SaveData { session_tracker: SessionTracker, timer_settings: TimerSettings, pom_position: GridPosition, + inventory: Vec, } fn dump_savegame( @@ -39,6 +40,8 @@ fn dump_savegame( tracker: Res, settings: Res, pom_query: Query<&GridPosition, With>, + inventory: Res, + item_query: Query<&ItemStack>, ) { for _ in messages.read() { let mut tile_states = Vec::new(); @@ -61,6 +64,12 @@ fn dump_savegame( let pom_pos = pom_query.single().unwrap(); + let item_stacks: Vec = inventory + .items + .iter() + .filter_map(|entity| item_query.get(*entity).ok().cloned()) + .collect(); + let save_data = SaveData { grid_width: grid.width, grid_height: grid.height, @@ -69,6 +78,7 @@ fn dump_savegame( session_tracker: tracker.clone(), timer_settings: settings.clone(), pom_position: *pom_pos, + inventory: item_stacks, }; match serde_json::to_string_pretty(&save_data) { @@ -91,6 +101,7 @@ fn dump_savegame( } fn load_savegame( + mut commands: Commands, mut messages: MessageReader, save_path: Res, grid: Res, @@ -99,6 +110,7 @@ fn load_savegame( mut tracker: ResMut, mut settings: ResMut, mut pom_query: Query<(&mut GridPosition, &mut Transform), With>, + mut inventory: ResMut, ) { for _ in messages.read() { if let Ok(mut file) = File::open(&save_path.0) { @@ -136,6 +148,14 @@ fn load_savegame( } } } + + let stack_entities: Vec = save_data + .inventory + .iter() + .map(|stack| commands.spawn(stack.clone()).id()) + .collect(); + inventory.items = stack_entities; + println!("Game loaded from {}", save_path.0.display()); } Err(e) => { diff --git a/src/prelude.rs b/src/prelude.rs index 5bfe8e3..51be80d 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -7,7 +7,7 @@ pub use crate::features::{ consts::TILE_SIZE, utils::{grid_to_world_coords, world_to_grid_coords}, }, - inventory::components::{Inventory, Item}, + inventory::components::{Inventory, Item, ItemStack, ItemType}, phase::components::{CurrentPhase, Phase}, pom::{ components::{GridPosition, MovingState, Pom}, From 8be97265eed846afadece0898683b713b7bc24d7 Mon Sep 17 00:00:00 2001 From: demenik Date: Thu, 27 Nov 2025 23:12:07 +0100 Subject: [PATCH 3/3] feat: Add inventory display popup (#48) --- src/features/hud/components.rs | 1 - src/features/hud/mod.rs | 16 ++++- src/features/inventory/components.rs | 37 +++++++++++- src/features/inventory/mod.rs | 31 +++++++++- src/features/inventory/ui/inventory.rs | 83 ++++++++++++++++++++++++++ src/features/inventory/ui/item.rs | 53 ++++++++++++++++ src/features/inventory/ui/mod.rs | 5 ++ src/prelude.rs | 2 +- 8 files changed, 219 insertions(+), 9 deletions(-) create mode 100644 src/features/inventory/ui/inventory.rs create mode 100644 src/features/inventory/ui/item.rs create mode 100644 src/features/inventory/ui/mod.rs diff --git a/src/features/hud/components.rs b/src/features/hud/components.rs index 547dfae..6d93783 100644 --- a/src/features/hud/components.rs +++ b/src/features/hud/components.rs @@ -14,7 +14,6 @@ pub enum TextType { #[derive(Component)] pub enum ButtonType { - SavegameDump, SettingsOpen, SettingsClose, SettingsExit, diff --git a/src/features/hud/mod.rs b/src/features/hud/mod.rs index a248c1e..92f5bbe 100644 --- a/src/features/hud/mod.rs +++ b/src/features/hud/mod.rs @@ -1,3 +1,4 @@ +use crate::features::inventory; use crate::features::phase::components::TimerSettings; use crate::features::savegame::messages::SavegameDumpMessage; use crate::prelude::*; @@ -50,15 +51,25 @@ fn setup(mut commands: Commands) { TextFont::from_font_size(16.0), TextColor(Color::WHITE) ), + ( + Button, + inventory::components::ButtonType::InventoryOpen, + Node::default(), + children![( + Text::new("Inventar"), + TextFont::from_font_size(16.0), + TextColor(Color::WHITE) + )] + ), ( Button, ButtonType::SettingsOpen, Node::default(), - children![ + children![( Text::new("Einstellungen"), TextFont::from_font_size(16.0), TextColor(Color::WHITE) - ] + )] ) ], )); @@ -115,7 +126,6 @@ fn buttons( timer_settings.change(timer_type, *amount) } }, - _ => {} }, _ => {} } diff --git a/src/features/inventory/components.rs b/src/features/inventory/components.rs index bbb5ff5..bf2e418 100644 --- a/src/features/inventory/components.rs +++ b/src/features/inventory/components.rs @@ -1,13 +1,33 @@ use crate::prelude::*; -#[derive(Component)] -pub struct Item; - #[derive(Serialize, Deserialize, Clone)] pub enum ItemType { Berry, } +impl ItemType { + pub fn singular(&self) -> String { + match self { + ItemType::Berry => "Beere", + } + .into() + } + + pub fn plural(&self) -> String { + match self { + ItemType::Berry => "Beeren", + } + .into() + } + + pub fn description(&self) -> String { + match self { + ItemType::Berry => "Von Pflanzen erntbar. Kann im Shop zum Einkaufen benutzt werden.", + } + .into() + } +} + #[derive(Component, Serialize, Deserialize, Clone)] pub struct ItemStack { pub item_type: ItemType, @@ -18,3 +38,14 @@ pub struct ItemStack { pub struct Inventory { pub items: Vec, } + +#[derive(Component)] +pub enum RootMarker { + Inventory, +} + +#[derive(Component)] +pub enum ButtonType { + InventoryOpen, + InventoryClose, +} diff --git a/src/features/inventory/mod.rs b/src/features/inventory/mod.rs index 128d7c5..1b60ee8 100644 --- a/src/features/inventory/mod.rs +++ b/src/features/inventory/mod.rs @@ -1,11 +1,40 @@ -use crate::prelude::*; +use crate::{features::inventory::ui::open_inventory, prelude::*}; +use components::*; pub mod components; +pub mod ui; pub struct InventoryPlugin; impl Plugin for InventoryPlugin { fn build(&self, app: &mut App) { app.init_resource::(); + + app.add_systems(Update, buttons.run_if(in_state(AppState::GameScreen))); + } +} + +fn buttons( + mut commands: Commands, + mut interaction_query: Query<(&Interaction, &ButtonType), (Changed, With