feat: Load hard-coded savegame file (#37)

This commit is contained in:
demenik
2025-11-26 22:14:32 +01:00
parent 2b7f0b39be
commit 57a780bff3
4 changed files with 66 additions and 4 deletions

View File

@@ -6,7 +6,7 @@ use std::path::PathBuf;
pub struct SavegamePath(pub PathBuf);
impl SavegamePath {
fn get_project_path() -> Option<PathBuf> {
pub fn get_project_path() -> Option<PathBuf> {
let project_dirs = ProjectDirs::from("de", "demenik", "pomomon-garden");
if let Some(dirs) = project_dirs {

View File

@@ -2,3 +2,6 @@ use crate::prelude::*;
#[derive(Message)]
pub struct SavegameDumpMessage;
#[derive(Message)]
pub struct SavegameLoadMessage;

View File

@@ -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::<SavegameDumpMessage>();
app.add_message::<SavegameLoadMessage>();
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<SavegameDumpMessage>,
save_path: Res<SavegamePath>,
grid: Res<Grid>,
tile_query: Query<&TileState>,
phase: Res<CurrentPhase>,
tracker: Res<SessionTracker>,
settings: Res<TimerSettings>,
pom_query: Query<&GridPosition, With<Pom>>,
save_path: Res<SavegamePath>,
) {
for _ in messages.read() {
let mut tile_states = Vec::new();
@@ -87,3 +89,54 @@ fn dump_savegame(
}
}
}
fn load_savegame(
mut messages: MessageReader<SavegameLoadMessage>,
save_path: Res<SavegamePath>,
grid: Res<Grid>,
mut tile_query: Query<&mut TileState>,
mut phase: ResMut<CurrentPhase>,
mut tracker: ResMut<SessionTracker>,
mut settings: ResMut<TimerSettings>,
mut pom_query: Query<&mut GridPosition, With<Pom>>,
) {
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::<SaveData>(&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());
}
}
}

View File

@@ -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<Interaction>, With<Button>),
>,
mut load_messages: MessageWriter<SavegameLoadMessage>,
) {
for (interaction, button_type, mut color) in &mut interaction_query {
match *interaction {
@@ -127,6 +128,11 @@ fn menu(
*color = PRESSED_BUTTON.into();
match button_type {
ButtonType::LoadGame => {
commands.insert_resource(SavegamePath::new("savegame.json"));
next_state.set(AppState::GameScreen);
load_messages.write(SavegameLoadMessage);
}
ButtonType::NewGame => {
commands.insert_resource(SavegamePath::new("savegame.json"));
next_state.set(AppState::GameScreen);