From 57a780bff3fddeea4f558c6f244d4da3cf586b97 Mon Sep 17 00:00:00 2001 From: demenik Date: Wed, 26 Nov 2025 22:14:32 +0100 Subject: [PATCH] feat: Load hard-coded savegame file (#37) --- src/features/savegame/components.rs | 2 +- src/features/savegame/messages.rs | 3 ++ src/features/savegame/mod.rs | 57 ++++++++++++++++++++++++++++- src/features/start_screen/mod.rs | 8 +++- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/features/savegame/components.rs b/src/features/savegame/components.rs index 2bccd54..6452f22 100644 --- a/src/features/savegame/components.rs +++ b/src/features/savegame/components.rs @@ -6,7 +6,7 @@ use std::path::PathBuf; pub struct SavegamePath(pub PathBuf); impl SavegamePath { - fn get_project_path() -> Option { + pub fn get_project_path() -> Option { let project_dirs = ProjectDirs::from("de", "demenik", "pomomon-garden"); if let Some(dirs) = project_dirs { diff --git a/src/features/savegame/messages.rs b/src/features/savegame/messages.rs index a67f4c2..3c03fad 100644 --- a/src/features/savegame/messages.rs +++ b/src/features/savegame/messages.rs @@ -2,3 +2,6 @@ use crate::prelude::*; #[derive(Message)] pub struct SavegameDumpMessage; + +#[derive(Message)] +pub struct SavegameLoadMessage; diff --git a/src/features/savegame/mod.rs b/src/features/savegame/mod.rs index b0d1cef..c76362d 100644 --- a/src/features/savegame/mod.rs +++ b/src/features/savegame/mod.rs @@ -2,7 +2,7 @@ use crate::features::phase::components::{SessionTracker, TimerSettings}; use crate::prelude::*; use messages::*; use std::fs::File; -use std::io::Write; +use std::io::{Read, Write}; pub mod components; pub mod messages; @@ -12,8 +12,10 @@ pub struct SavegamePlugin; impl Plugin for SavegamePlugin { fn build(&self, app: &mut App) { app.add_message::(); + app.add_message::(); app.add_systems(Update, dump_savegame.run_if(in_state(AppState::GameScreen))); + app.add_systems(Update, load_savegame.run_if(in_state(AppState::GameScreen))); } } @@ -30,13 +32,13 @@ struct SaveData { fn dump_savegame( mut messages: MessageReader, + save_path: Res, grid: Res, tile_query: Query<&TileState>, phase: Res, tracker: Res, settings: Res, pom_query: Query<&GridPosition, With>, - save_path: Res, ) { for _ in messages.read() { let mut tile_states = Vec::new(); @@ -87,3 +89,54 @@ fn dump_savegame( } } } + +fn load_savegame( + mut messages: MessageReader, + save_path: Res, + grid: Res, + mut tile_query: Query<&mut TileState>, + mut phase: ResMut, + mut tracker: ResMut, + mut settings: ResMut, + mut pom_query: Query<&mut GridPosition, With>, +) { + for _ in messages.read() { + if let Ok(mut file) = File::open(&save_path.0) { + let mut content = String::new(); + if let Err(e) = file.read_to_string(&mut content) { + eprintln!("Failed to read save file: {}", e); + continue; + } + + match serde_json::from_str::(&content) { + Ok(save_data) => { + *phase = save_data.current_phase; + *tracker = save_data.session_tracker; + *settings = save_data.timer_settings; + + if let Ok(mut pom_pos) = pom_query.single_mut() { + *pom_pos = save_data.pom_position; + } + + for x in 0..save_data.grid_width { + for y in 0..save_data.grid_height { + if x < grid.width && y < grid.height { + if let Ok(entity) = grid.get_tile((x, y)) { + if let Ok(mut state) = tile_query.get_mut(entity) { + *state = save_data.tiles[x as usize][y as usize]; + } + } + } + } + } + println!("Game loaded from {}", save_path.0.display()); + } + Err(e) => { + eprintln!("Failed to parse save data: {}", e); + } + } + } else { + eprintln!("Failed to open save file at {}", save_path.0.display()); + } + } +} diff --git a/src/features/start_screen/mod.rs b/src/features/start_screen/mod.rs index 1860931..9be4c8b 100644 --- a/src/features/start_screen/mod.rs +++ b/src/features/start_screen/mod.rs @@ -1,4 +1,4 @@ -use crate::prelude::*; +use crate::{features::savegame::messages::SavegameLoadMessage, prelude::*}; pub struct StartScreenPlugin; @@ -120,6 +120,7 @@ fn menu( (&Interaction, &ButtonType, &mut BackgroundColor), (Changed, With