Merge branch '61-show-total-berries-for-save-games' into 'dev'

Show total berries for save games

See merge request softwaregrundprojekt/2025-2026/einzelprojekt/tutorium-moritz/bernroider-dominik/bernroider-dominik!35
This commit is contained in:
Dominik Bernroider
2025-12-09 18:32:23 +00:00
10 changed files with 45 additions and 9 deletions

View File

@@ -1,4 +1,5 @@
use crate::{features::inventory::ui::open_inventory, prelude::*}; use crate::{features::inventory::ui::open_inventory, prelude::*};
use crate::features::phase::components::SessionTracker;
use components::*; use components::*;
pub mod components; pub mod components;
@@ -42,11 +43,14 @@ fn debug_modify_berries(
mut inventory: ResMut<Inventory>, mut inventory: ResMut<Inventory>,
mut items: Query<&mut ItemStack>, mut items: Query<&mut ItemStack>,
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
mut session_tracker: ResMut<SessionTracker>,
) { ) {
if keys.any_pressed([KeyCode::ShiftLeft, KeyCode::ShiftRight]) { if keys.any_pressed([KeyCode::ShiftLeft, KeyCode::ShiftRight]) {
if keys.just_pressed(KeyCode::ArrowUp) { if keys.just_pressed(KeyCode::ArrowUp) {
println!("Adding 1 berry using debug bind"); println!("Adding 1 berry using debug bind");
inventory.update_item_stack(&mut commands, &mut items, ItemType::Berry, 1); if inventory.update_item_stack(&mut commands, &mut items, ItemType::Berry, 1) {
session_tracker.total_berries_earned += 1;
}
} else if keys.just_pressed(KeyCode::ArrowDown) { } else if keys.just_pressed(KeyCode::ArrowDown) {
println!("Removing 1 berry using debug bind"); println!("Removing 1 berry using debug bind");
inventory.update_item_stack(&mut commands, &mut items, ItemType::Berry, -1); inventory.update_item_stack(&mut commands, &mut items, ItemType::Berry, -1);

View File

@@ -62,4 +62,5 @@ impl Default for TimerSettings {
#[derive(Resource, Debug, Default, Serialize, Deserialize, Clone)] #[derive(Resource, Debug, Default, Serialize, Deserialize, Clone)]
pub struct SessionTracker { pub struct SessionTracker {
pub completed_focus_phases: u32, pub completed_focus_phases: u32,
pub total_berries_earned: u32,
} }

View File

@@ -1,4 +1,4 @@
use crate::prelude::*; use crate::{features::phase::components::SessionTracker, prelude::*};
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum InteractionAction { pub enum InteractionAction {
@@ -88,6 +88,7 @@ impl InteractionAction {
item_stack_query: &mut Query<&mut ItemStack>, item_stack_query: &mut Query<&mut ItemStack>,
commands: &mut Commands, commands: &mut Commands,
game_config: &GameConfig, game_config: &GameConfig,
session_tracker: &mut SessionTracker,
) { ) {
let Ok(tile_entity) = grid.get_tile(pos) else { let Ok(tile_entity) = grid.get_tile(pos) else {
println!("Error during interaction: Couldn't get tile_entity"); println!("Error during interaction: Couldn't get tile_entity");
@@ -165,6 +166,7 @@ impl InteractionAction {
ItemType::Berry, ItemType::Berry,
config.grants as i32, config.grants as i32,
); );
session_tracker.total_berries_earned += config.grants;
} }
} }
} }

View File

@@ -192,6 +192,7 @@ fn perform_interaction(
mut item_stack_query: Query<&mut ItemStack>, mut item_stack_query: Query<&mut ItemStack>,
mut commands: Commands, mut commands: Commands,
config: Res<GameConfig>, config: Res<GameConfig>,
mut session_tracker: ResMut<crate::features::phase::components::SessionTracker>,
) { ) {
for (pos, mut target_component, path_queue) in pom_query.iter_mut() { for (pos, mut target_component, path_queue) in pom_query.iter_mut() {
if let Some(target) = target_component.target { if let Some(target) = target_component.target {
@@ -215,6 +216,7 @@ fn perform_interaction(
&mut item_stack_query, &mut item_stack_query,
&mut commands, &mut commands,
&config, &config,
&mut session_tracker,
); );
} }
} }

View File

@@ -21,6 +21,8 @@ struct PartialSaveData {
#[derive(Deserialize)] #[derive(Deserialize)]
struct PartialSessionTracker { struct PartialSessionTracker {
completed_focus_phases: u32, completed_focus_phases: u32,
#[serde(default)]
total_berries_earned: u32,
} }
impl SavegamePath { impl SavegamePath {
@@ -77,7 +79,7 @@ impl SavegamePath {
savegames.push(SavegameInfo { savegames.push(SavegameInfo {
path: SavegamePath(path), path: SavegamePath(path),
index, index,
total_berries: 0, // TODO: add total_berries total_berries: data.session_tracker.total_berries_earned,
completed_focus: data.session_tracker.completed_focus_phases, completed_focus: data.session_tracker.completed_focus_phases,
}); });
} }

View File

@@ -2,6 +2,7 @@ use bevy::prelude::*;
use pomomon_garden::features::config::components::{BerrySeedConfig, GameConfig}; use pomomon_garden::features::config::components::{BerrySeedConfig, GameConfig};
use pomomon_garden::features::grid::components::{Grid, Tile, TileState}; use pomomon_garden::features::grid::components::{Grid, Tile, TileState};
use pomomon_garden::features::inventory::components::{Inventory, ItemStack, ItemType}; use pomomon_garden::features::inventory::components::{Inventory, ItemStack, ItemType};
use pomomon_garden::features::phase::components::SessionTracker;
pub fn setup_app( pub fn setup_app(
grid_width: u32, grid_width: u32,
@@ -65,5 +66,7 @@ pub fn setup_app(
..Default::default() ..Default::default()
}); });
app.init_resource::<SessionTracker>();
app app
} }

View File

@@ -2,6 +2,7 @@ use bevy::ecs::system::RunSystemOnce;
use pomomon_garden::features::config::components::{BerrySeedConfig, GameConfig}; use pomomon_garden::features::config::components::{BerrySeedConfig, GameConfig};
use pomomon_garden::features::grid::components::{Grid, TileState}; use pomomon_garden::features::grid::components::{Grid, TileState};
use pomomon_garden::features::inventory::components::{Inventory, ItemStack, ItemType}; use pomomon_garden::features::inventory::components::{Inventory, ItemStack, ItemType};
use pomomon_garden::features::phase::components::SessionTracker;
use pomomon_garden::features::pom::actions::InteractionAction; use pomomon_garden::features::pom::actions::InteractionAction;
use pomomon_garden::prelude::*; use pomomon_garden::prelude::*;
@@ -41,7 +42,8 @@ fn test_harvest_fully_grown() {
mut tile_query: Query<&mut TileState>, mut tile_query: Query<&mut TileState>,
mut inventory: ResMut<Inventory>, mut inventory: ResMut<Inventory>,
mut item_stack_query: Query<&mut ItemStack>, mut item_stack_query: Query<&mut ItemStack>,
config: Res<GameConfig>| { config: Res<GameConfig>,
mut session_tracker: ResMut<SessionTracker>| {
InteractionAction::Harvest.execute( InteractionAction::Harvest.execute(
(0, 0), (0, 0),
&grid, &grid,
@@ -50,6 +52,7 @@ fn test_harvest_fully_grown() {
&mut item_stack_query, &mut item_stack_query,
&mut commands, &mut commands,
&config, &config,
&mut session_tracker,
); );
}, },
); );
@@ -70,6 +73,10 @@ fn test_harvest_fully_grown() {
let stack = app.world().entity(stack_entity).get::<ItemStack>().unwrap(); let stack = app.world().entity(stack_entity).get::<ItemStack>().unwrap();
assert_eq!(stack.item_type, ItemType::Berry); assert_eq!(stack.item_type, ItemType::Berry);
assert_eq!(stack.amount, 5); assert_eq!(stack.amount, 5);
// Check Session Tracker
let tracker = app.world().resource::<SessionTracker>();
assert_eq!(tracker.total_berries_earned, 5);
} }
#[test] #[test]
@@ -105,7 +112,8 @@ fn test_harvest_withered() {
mut tile_query: Query<&mut TileState>, mut tile_query: Query<&mut TileState>,
mut inventory: ResMut<Inventory>, mut inventory: ResMut<Inventory>,
mut item_stack_query: Query<&mut ItemStack>, mut item_stack_query: Query<&mut ItemStack>,
config: Res<GameConfig>| { config: Res<GameConfig>,
mut session_tracker: ResMut<SessionTracker>| {
InteractionAction::Harvest.execute( InteractionAction::Harvest.execute(
(0, 0), (0, 0),
&grid, &grid,
@@ -114,6 +122,7 @@ fn test_harvest_withered() {
&mut item_stack_query, &mut item_stack_query,
&mut commands, &mut commands,
&config, &config,
&mut session_tracker,
); );
}, },
); );
@@ -164,7 +173,8 @@ fn test_cannot_harvest_growing() {
mut tile_query: Query<&mut TileState>, mut tile_query: Query<&mut TileState>,
mut inventory: ResMut<Inventory>, mut inventory: ResMut<Inventory>,
mut item_stack_query: Query<&mut ItemStack>, mut item_stack_query: Query<&mut ItemStack>,
config: Res<GameConfig>| { config: Res<GameConfig>,
mut session_tracker: ResMut<SessionTracker>| {
InteractionAction::Harvest.execute( InteractionAction::Harvest.execute(
(0, 0), (0, 0),
&grid, &grid,
@@ -173,6 +183,7 @@ fn test_cannot_harvest_growing() {
&mut item_stack_query, &mut item_stack_query,
&mut commands, &mut commands,
&config, &config,
&mut session_tracker,
); );
}, },
); );

View File

@@ -2,6 +2,7 @@ use bevy::ecs::system::RunSystemOnce;
use pomomon_garden::features::config::components::GameConfig; use pomomon_garden::features::config::components::GameConfig;
use pomomon_garden::features::grid::components::{Grid, TileState}; use pomomon_garden::features::grid::components::{Grid, TileState};
use pomomon_garden::features::inventory::components::{Inventory, ItemStack, ItemType}; use pomomon_garden::features::inventory::components::{Inventory, ItemStack, ItemType};
use pomomon_garden::features::phase::components::SessionTracker;
use pomomon_garden::features::pom::actions::InteractionAction; use pomomon_garden::features::pom::actions::InteractionAction;
use pomomon_garden::prelude::*; use pomomon_garden::prelude::*;
@@ -27,7 +28,8 @@ fn test_plant_seed_interaction() {
mut inventory: ResMut<Inventory>, mut inventory: ResMut<Inventory>,
mut item_stack_query: Query<&mut ItemStack>, mut item_stack_query: Query<&mut ItemStack>,
mut commands: Commands, mut commands: Commands,
game_config: Res<GameConfig>| { game_config: Res<GameConfig>,
mut session_tracker: ResMut<SessionTracker>| {
let action = InteractionAction::Plant(seed_type.clone()); let action = InteractionAction::Plant(seed_type.clone());
action.execute( action.execute(
(1, 1), (1, 1),
@@ -37,6 +39,7 @@ fn test_plant_seed_interaction() {
&mut item_stack_query, &mut item_stack_query,
&mut commands, &mut commands,
&game_config, &game_config,
&mut session_tracker,
); );
}, },
); );
@@ -98,7 +101,8 @@ fn test_plant_seed_no_inventory() {
mut inventory: ResMut<Inventory>, mut inventory: ResMut<Inventory>,
mut item_stack_query: Query<&mut ItemStack>, mut item_stack_query: Query<&mut ItemStack>,
mut commands: Commands, mut commands: Commands,
game_config: Res<GameConfig>| { game_config: Res<GameConfig>,
mut session_tracker: ResMut<SessionTracker>| {
let action = InteractionAction::Plant(seed_type.clone()); let action = InteractionAction::Plant(seed_type.clone());
action.execute( action.execute(
(1, 1), (1, 1),
@@ -108,6 +112,7 @@ fn test_plant_seed_no_inventory() {
&mut item_stack_query, &mut item_stack_query,
&mut commands, &mut commands,
&game_config, &game_config,
&mut session_tracker,
); );
}, },
); );

View File

@@ -39,6 +39,7 @@ fn test_session_tracker_focus_to_long_break() {
let timer_settings = TimerSettings::default(); let timer_settings = TimerSettings::default();
let mut session_tracker = SessionTracker { let mut session_tracker = SessionTracker {
completed_focus_phases: timer_settings.long_break_interval - 1, completed_focus_phases: timer_settings.long_break_interval - 1,
total_berries_earned: 0,
}; // To trigger long break on next phase }; // To trigger long break on next phase
next_phase(&mut current_phase, &mut session_tracker, &timer_settings); next_phase(&mut current_phase, &mut session_tracker, &timer_settings);
@@ -66,6 +67,7 @@ fn test_session_tracker_break_to_focus() {
}); });
let mut session_tracker = SessionTracker { let mut session_tracker = SessionTracker {
completed_focus_phases: 1, completed_focus_phases: 1,
total_berries_earned: 0,
}; // Arbitrary value, should not change }; // Arbitrary value, should not change
let timer_settings = TimerSettings::default(); let timer_settings = TimerSettings::default();
@@ -91,6 +93,7 @@ fn test_session_tracker_not_finished_phase_no_change() {
let mut current_phase = CurrentPhase(Phase::Focus { duration: 100.0 }); let mut current_phase = CurrentPhase(Phase::Focus { duration: 100.0 });
let mut session_tracker = SessionTracker { let mut session_tracker = SessionTracker {
completed_focus_phases: 0, completed_focus_phases: 0,
total_berries_earned: 0,
}; };
let timer_settings = TimerSettings::default(); let timer_settings = TimerSettings::default();

View File

@@ -2,6 +2,7 @@ use bevy::ecs::system::RunSystemOnce;
use pomomon_garden::features::config::components::GameConfig; use pomomon_garden::features::config::components::GameConfig;
use pomomon_garden::features::grid::components::{Grid, TileState}; use pomomon_garden::features::grid::components::{Grid, TileState};
use pomomon_garden::features::inventory::components::{Inventory, ItemStack, ItemType}; use pomomon_garden::features::inventory::components::{Inventory, ItemStack, ItemType};
use pomomon_garden::features::phase::components::SessionTracker;
use pomomon_garden::features::pom::actions::InteractionAction; use pomomon_garden::features::pom::actions::InteractionAction;
use pomomon_garden::prelude::*; use pomomon_garden::prelude::*;
@@ -57,7 +58,8 @@ fn test_water_crop() {
mut inventory: ResMut<Inventory>, mut inventory: ResMut<Inventory>,
mut item_stack_query: Query<&mut ItemStack>, mut item_stack_query: Query<&mut ItemStack>,
mut commands: Commands, mut commands: Commands,
game_config: Res<GameConfig>| { game_config: Res<GameConfig>,
mut session_tracker: ResMut<SessionTracker>| {
let action = InteractionAction::Water; let action = InteractionAction::Water;
action.execute( action.execute(
(1, 1), (1, 1),
@@ -67,6 +69,7 @@ fn test_water_crop() {
&mut item_stack_query, &mut item_stack_query,
&mut commands, &mut commands,
&game_config, &game_config,
&mut session_tracker,
); );
}, },
); );