feat: Show achievement progress in savegame load menu (#47)

This commit is contained in:
demenik
2025-12-11 20:21:46 +01:00
parent 52dd300ca0
commit 2857f59a85
3 changed files with 32 additions and 3 deletions

View File

@@ -1,3 +1,4 @@
use crate::features::achievement::components::AchievementProgress;
use crate::prelude::*; use crate::prelude::*;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
@@ -7,18 +8,20 @@ use std::path::PathBuf;
pub struct SavegamePath(pub PathBuf); pub struct SavegamePath(pub PathBuf);
/// Metadata about a savegame. /// Metadata about a savegame.
#[derive(Debug)] #[derive(Debug, Clone)]
pub struct SavegameInfo { pub struct SavegameInfo {
pub path: SavegamePath, pub path: SavegamePath,
pub index: u32, pub index: u32,
pub total_berries: u32, pub total_berries: u32,
pub completed_focus: u32, pub completed_focus: u32,
pub achievement_progress: AchievementProgress,
} }
/// Helper for partial JSON deserialization. /// Helper for partial JSON deserialization.
#[derive(Deserialize)] #[derive(Deserialize)]
struct PartialSaveData { struct PartialSaveData {
session_tracker: PartialSessionTracker, session_tracker: PartialSessionTracker,
achievement_progress: AchievementProgress,
} }
/// Helper for partial JSON deserialization of session stats. /// Helper for partial JSON deserialization of session stats.
@@ -87,6 +90,7 @@ impl SavegamePath {
index, index,
total_berries: data.session_tracker.total_berries_earned, total_berries: data.session_tracker.total_berries_earned,
completed_focus: data.session_tracker.completed_focus_phases, completed_focus: data.session_tracker.completed_focus_phases,
achievement_progress: data.achievement_progress,
}); });
} }
@@ -113,4 +117,5 @@ pub enum RootMarker {
pub enum ButtonType { pub enum ButtonType {
SavegameLoad { savegame_path: SavegamePath }, SavegameLoad { savegame_path: SavegamePath },
SavegameDelete { savegame_path: SavegamePath }, SavegameDelete { savegame_path: SavegamePath },
Achievements { savegame: SavegameInfo },
} }

View File

@@ -1,8 +1,9 @@
use super::super::components::{ButtonType, RootMarker}; use super::super::components::{ButtonType, RootMarker};
use crate::features::achievement::ui::open_achievements_menu;
use crate::{features::savegame::messages::SavegameLoadMessage, prelude::*}; use crate::{features::savegame::messages::SavegameLoadMessage, prelude::*};
/// Spawns the "Load Game" popup. /// Spawns the "Load Game" popup.
pub fn spawn_load_popup(commands: &mut Commands) { pub fn spawn_load_popup(commands: &mut Commands, asset_server: &AssetServer) {
spawn_popup( spawn_popup(
commands, commands,
RootMarker::PopupSavegameLoad, RootMarker::PopupSavegameLoad,
@@ -78,6 +79,25 @@ pub fn spawn_load_popup(commands: &mut Commands) {
..default() ..default()
}, },
|color| text("X", 24.0, color) |color| text("X", 24.0, color)
),
button(
ButtonType::Achievements {
savegame: savegame.clone()
},
ButtonVariant::Primary,
Node {
width: px(40),
height: px(40),
..default()
},
|_| (
ImageNode::default(),
AseSlice {
aseprite: asset_server
.load("achievement.aseprite"),
name: "Achievement".into()
}
)
) )
], ],
) )
@@ -111,6 +131,9 @@ pub fn load_popup_handler(
println!("Error while deleting savegame: {:?}", e); println!("Error while deleting savegame: {:?}", e);
} }
} }
ButtonType::Achievements { savegame } => {
open_achievements_menu(&mut commands, &savegame.achievement_progress);
}
}; };
for (entity, root) in root_query.iter() { for (entity, root) in root_query.iter() {

View File

@@ -80,12 +80,13 @@ fn menu(
mut commands: Commands, mut commands: Commands,
mut next_state: ResMut<NextState<AppState>>, mut next_state: ResMut<NextState<AppState>>,
mut interaction_query: Query<(&Interaction, &ButtonType), (Changed<Interaction>, With<Button>)>, mut interaction_query: Query<(&Interaction, &ButtonType), (Changed<Interaction>, With<Button>)>,
asset_server: Res<AssetServer>,
) { ) {
for (interaction, button_type) in &mut interaction_query { for (interaction, button_type) in &mut interaction_query {
match *interaction { match *interaction {
Interaction::Pressed => match button_type { Interaction::Pressed => match button_type {
ButtonType::LoadGame => { ButtonType::LoadGame => {
spawn_load_popup(&mut commands); spawn_load_popup(&mut commands, &asset_server);
} }
ButtonType::NewGame => { ButtonType::NewGame => {
commands.insert_resource(SavegamePath::next()); commands.insert_resource(SavegamePath::next());