From eedc379c8d3e9cb53f59efa7f77b84fadae7a146 Mon Sep 17 00:00:00 2001 From: yuni Date: Thu, 13 Jun 2024 02:18:22 +0200 Subject: [PATCH] save/load many of the game settings to/from config file --- src/data/outfly.toml | 11 +++++++++-- src/game.rs | 24 +++++++++++++++++++++++- src/var.rs | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/data/outfly.toml b/src/data/outfly.toml index ee916d5..6f0c2dd 100644 --- a/src/data/outfly.toml +++ b/src/data/outfly.toml @@ -14,8 +14,15 @@ # fullscreen_mode may be "borderless", "legacy", or "sized" fullscreen_mode = "borderless" -# window_mode may be "windowed", or "fullscreen" -window_mode = "fullscreen" +# fullscreen_on may be true or false +fullscreen_on = true # render_mode may be "vulkan" or "gl" render_mode = "vulkan" + +# The following options are booleans (may be true or false) +augmented_reality = true +music = true +sound = true +third_person = true +shadows_sun = true diff --git a/src/game.rs b/src/game.rs index fe6df2a..57102d6 100644 --- a/src/game.rs +++ b/src/game.rs @@ -25,6 +25,7 @@ pub const CHEAT_WARP_3: &str = "busstopclippy3"; pub struct GamePlugin; impl Plugin for GamePlugin { fn build(&self, app: &mut App) { + app.add_systems(Startup, setup); app.add_systems(Update, handle_cheats.run_if(in_control)); app.add_systems(Update, debug); app.add_systems(PostUpdate, handle_game_event); @@ -106,6 +107,14 @@ impl Turn { } } +pub fn setup(mut settings: ResMut, prefs: Res) { + settings.hud_active = prefs.augmented_reality; + settings.mute_music = !prefs.music; + settings.mute_sfx = !prefs.sound; + settings.third_person = prefs.third_person; + settings.shadows_sun = prefs.shadows_sun; +} + pub fn handle_game_event( mut settings: ResMut, mut er_game: EventReader, @@ -118,6 +127,7 @@ pub fn handle_game_event( mut mapcam: ResMut, mut log: ResMut, opt: Res, + mut prefs: ResMut, ) { for event in er_game.read() { match event { @@ -125,16 +135,22 @@ pub fn handle_game_event( settings.hud_active = turn.to_bool(settings.hud_active); ew_togglemusic.send(audio::ToggleMusicEvent()); ew_updateoverlays.send(hud::UpdateOverlayVisibility); + prefs.augmented_reality = settings.hud_active; + prefs.save(); } GameEvent::SetMusic(turn) => { // TODO invert "mute_music" to "music_active" settings.mute_music = turn.to_bool(settings.mute_music); ew_togglemusic.send(audio::ToggleMusicEvent()); + prefs.music = !settings.mute_music; + prefs.save(); } GameEvent::SetSound(turn) => { // TODO invert "mute_sfx" to "sfx_active" settings.mute_sfx = turn.to_bool(settings.mute_sfx); ew_togglemusic.send(audio::ToggleMusicEvent()); + prefs.sound = !settings.mute_sfx; + prefs.save(); } GameEvent::SetMap(turn) => { settings.map_active = turn.to_bool(settings.map_active); @@ -147,10 +163,12 @@ pub fn handle_game_event( GameEvent::SetFullscreen(turn) => { for mut window in &mut q_window { let current_state = window.mode != WindowMode::Windowed; - window.mode = match turn.to_bool(current_state) { + prefs.fullscreen_on = turn.to_bool(current_state); + window.mode = match prefs.fullscreen_on { true => opt.window_mode_fullscreen, false => WindowMode::Windowed, }; + prefs.save(); } } GameEvent::SetMenu(turn) => { @@ -159,6 +177,8 @@ pub fn handle_game_event( } GameEvent::SetThirdPerson(turn) => { settings.third_person = turn.to_bool(settings.third_person); + prefs.third_person = settings.third_person; + prefs.save(); } GameEvent::SetRotationStabilizer(turn) => { settings.rotation_stabilizer_active = @@ -169,6 +189,8 @@ pub fn handle_game_event( for mut light in &mut q_light { light.shadows_enabled = settings.shadows_sun; } + prefs.shadows_sun = settings.shadows_sun; + prefs.save(); } GameEvent::Achievement(name) => { ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Achieve)); diff --git a/src/var.rs b/src/var.rs index d7dee31..98a71ee 100644 --- a/src/var.rs +++ b/src/var.rs @@ -14,7 +14,7 @@ use crate::prelude::*; use bevy::prelude::*; use bevy::window::WindowMode; -use serde::Deserialize; +use serde::{Serialize, Deserialize}; use std::collections::{HashMap, HashSet}; use std::env; use std::fs; @@ -410,12 +410,17 @@ impl AchievementTracker { } } -#[derive(Resource, Deserialize, Debug, Default)] +#[derive(Resource, Serialize, Deserialize, Debug, Default)] #[serde(default)] pub struct Preferences { pub fullscreen_mode: String, - pub window_mode: String, + pub fullscreen_on: bool, pub render_mode: String, + pub augmented_reality: bool, + pub music: bool, + pub sound: bool, + pub third_person: bool, + pub shadows_sun: bool, #[serde(skip)] pub source_file: Option, @@ -430,14 +435,35 @@ impl Preferences { } } pub fn get_window_mode(&self) -> WindowMode { - match self.window_mode.as_str() { - "fullscreen" => self.get_fullscreen_mode(), - _ => WindowMode::Windowed, + match self.fullscreen_on { + true => self.get_fullscreen_mode(), + false => WindowMode::Windowed, } } pub fn render_mode_is_gl(&self) -> bool { return self.render_mode == "gl"; } + + pub fn save(&self) { + if let Some(path) = get_prefs_path() { + match toml_edit::ser::to_document::(self) { + Ok(doc) => { + dbg!(&doc); + match fs::write(path.clone(), doc.to_string()) { + Ok(_) => { + info!("Saved preferences to {path}."); + } + Err(error) => { + error!("Error while writing preferences: {:?}", error); + } + } + } + Err(error) => { + error!("Error while writing preferences: {:?}", error); + } + } + } + } } fn file_is_readable(file_path: &str) -> bool {