diff --git a/solitaire_engine/src/game_plugin.rs b/solitaire_engine/src/game_plugin.rs index 15d05bc..bbe6c51 100644 --- a/solitaire_engine/src/game_plugin.rs +++ b/solitaire_engine/src/game_plugin.rs @@ -202,6 +202,8 @@ impl Plugin for GamePlugin { .add_message::() .add_message::() .add_message::() + // add_message is idempotent; SettingsPlugin also registers this. + .add_message::() .add_systems( Update, poll_pending_new_game_seed.before(GameMutation), @@ -228,6 +230,7 @@ impl Plugin for GamePlugin { // GameMutation flow. .add_systems(Update, spawn_restore_prompt_if_pending) .add_systems(Update, handle_restore_prompt.before(GameMutation)) + .add_systems(Update, sync_settings_to_game.before(GameMutation)) .init_resource::() .add_systems(Update, tick_elapsed_time) .add_systems(Update, auto_save_game_state) @@ -235,6 +238,23 @@ impl Plugin for GamePlugin { } } +/// Forwards `take_from_foundation` from [`SettingsResource`] to the live +/// [`GameStateResource`] every time [`SettingsChangedEvent`] fires. +/// +/// This covers two cases that the new-game path misses: +/// 1. The initial settings load at startup: saves on disk default to `false` +/// but `Settings` defaults to `true`; the event fires once when the +/// settings file is first read. +/// 2. A user toggling the setting mid-session in the Settings panel. +fn sync_settings_to_game( + mut events: MessageReader, + mut game: ResMut, +) { + for ev in events.read() { + game.0.take_from_foundation = ev.0.take_from_foundation; + } +} + /// Pure, testable helper. Updates `elapsed_seconds` and drains the /// fractional accumulator into whole-second ticks. No-op when `is_won`. pub fn advance_elapsed( @@ -614,6 +634,7 @@ fn handle_restore_prompt( new_game_buttons: Query<&Interaction, (With, Changed)>, mut pending: ResMut, mut game: ResMut, + settings: Option>, mut changed: MessageWriter, mut new_game: MessageWriter, mut launch_home_shown: Option>, @@ -639,6 +660,10 @@ fn handle_restore_prompt( let resolved = if key_continue || click_continue { if let Some(restored) = pending.0.take() { game.0 = restored; + // Patch setting that serialized with the old core default of `false`. + if let Some(s) = settings.as_ref() { + game.0.take_from_foundation = s.0.take_from_foundation; + } changed.write(StateChangedEvent); } for entity in &screens {