save/load many of the game settings to/from config file

This commit is contained in:
yuni 2024-06-13 02:18:22 +02:00
parent 2eb68e94f7
commit eedc379c8d
3 changed files with 64 additions and 9 deletions

View file

@ -14,8 +14,15 @@
# fullscreen_mode may be "borderless", "legacy", or "sized" # fullscreen_mode may be "borderless", "legacy", or "sized"
fullscreen_mode = "borderless" fullscreen_mode = "borderless"
# window_mode may be "windowed", or "fullscreen" # fullscreen_on may be true or false
window_mode = "fullscreen" fullscreen_on = true
# render_mode may be "vulkan" or "gl" # render_mode may be "vulkan" or "gl"
render_mode = "vulkan" 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

View file

@ -25,6 +25,7 @@ pub const CHEAT_WARP_3: &str = "busstopclippy3";
pub struct GamePlugin; pub struct GamePlugin;
impl Plugin for GamePlugin { impl Plugin for GamePlugin {
fn build(&self, app: &mut App) { 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, handle_cheats.run_if(in_control));
app.add_systems(Update, debug); app.add_systems(Update, debug);
app.add_systems(PostUpdate, handle_game_event); app.add_systems(PostUpdate, handle_game_event);
@ -106,6 +107,14 @@ impl Turn {
} }
} }
pub fn setup(mut settings: ResMut<Settings>, prefs: Res<var::Preferences>) {
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( pub fn handle_game_event(
mut settings: ResMut<Settings>, mut settings: ResMut<Settings>,
mut er_game: EventReader<GameEvent>, mut er_game: EventReader<GameEvent>,
@ -118,6 +127,7 @@ pub fn handle_game_event(
mut mapcam: ResMut<camera::MapCam>, mut mapcam: ResMut<camera::MapCam>,
mut log: ResMut<hud::Log>, mut log: ResMut<hud::Log>,
opt: Res<var::CommandLineOptions>, opt: Res<var::CommandLineOptions>,
mut prefs: ResMut<var::Preferences>,
) { ) {
for event in er_game.read() { for event in er_game.read() {
match event { match event {
@ -125,16 +135,22 @@ pub fn handle_game_event(
settings.hud_active = turn.to_bool(settings.hud_active); settings.hud_active = turn.to_bool(settings.hud_active);
ew_togglemusic.send(audio::ToggleMusicEvent()); ew_togglemusic.send(audio::ToggleMusicEvent());
ew_updateoverlays.send(hud::UpdateOverlayVisibility); ew_updateoverlays.send(hud::UpdateOverlayVisibility);
prefs.augmented_reality = settings.hud_active;
prefs.save();
} }
GameEvent::SetMusic(turn) => { GameEvent::SetMusic(turn) => {
// TODO invert "mute_music" to "music_active" // TODO invert "mute_music" to "music_active"
settings.mute_music = turn.to_bool(settings.mute_music); settings.mute_music = turn.to_bool(settings.mute_music);
ew_togglemusic.send(audio::ToggleMusicEvent()); ew_togglemusic.send(audio::ToggleMusicEvent());
prefs.music = !settings.mute_music;
prefs.save();
} }
GameEvent::SetSound(turn) => { GameEvent::SetSound(turn) => {
// TODO invert "mute_sfx" to "sfx_active" // TODO invert "mute_sfx" to "sfx_active"
settings.mute_sfx = turn.to_bool(settings.mute_sfx); settings.mute_sfx = turn.to_bool(settings.mute_sfx);
ew_togglemusic.send(audio::ToggleMusicEvent()); ew_togglemusic.send(audio::ToggleMusicEvent());
prefs.sound = !settings.mute_sfx;
prefs.save();
} }
GameEvent::SetMap(turn) => { GameEvent::SetMap(turn) => {
settings.map_active = turn.to_bool(settings.map_active); settings.map_active = turn.to_bool(settings.map_active);
@ -147,10 +163,12 @@ pub fn handle_game_event(
GameEvent::SetFullscreen(turn) => { GameEvent::SetFullscreen(turn) => {
for mut window in &mut q_window { for mut window in &mut q_window {
let current_state = window.mode != WindowMode::Windowed; 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, true => opt.window_mode_fullscreen,
false => WindowMode::Windowed, false => WindowMode::Windowed,
}; };
prefs.save();
} }
} }
GameEvent::SetMenu(turn) => { GameEvent::SetMenu(turn) => {
@ -159,6 +177,8 @@ pub fn handle_game_event(
} }
GameEvent::SetThirdPerson(turn) => { GameEvent::SetThirdPerson(turn) => {
settings.third_person = turn.to_bool(settings.third_person); settings.third_person = turn.to_bool(settings.third_person);
prefs.third_person = settings.third_person;
prefs.save();
} }
GameEvent::SetRotationStabilizer(turn) => { GameEvent::SetRotationStabilizer(turn) => {
settings.rotation_stabilizer_active = settings.rotation_stabilizer_active =
@ -169,6 +189,8 @@ pub fn handle_game_event(
for mut light in &mut q_light { for mut light in &mut q_light {
light.shadows_enabled = settings.shadows_sun; light.shadows_enabled = settings.shadows_sun;
} }
prefs.shadows_sun = settings.shadows_sun;
prefs.save();
} }
GameEvent::Achievement(name) => { GameEvent::Achievement(name) => {
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Achieve)); ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Achieve));

View file

@ -14,7 +14,7 @@
use crate::prelude::*; use crate::prelude::*;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::window::WindowMode; use bevy::window::WindowMode;
use serde::Deserialize; use serde::{Serialize, Deserialize};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::env; use std::env;
use std::fs; use std::fs;
@ -410,12 +410,17 @@ impl AchievementTracker {
} }
} }
#[derive(Resource, Deserialize, Debug, Default)] #[derive(Resource, Serialize, Deserialize, Debug, Default)]
#[serde(default)] #[serde(default)]
pub struct Preferences { pub struct Preferences {
pub fullscreen_mode: String, pub fullscreen_mode: String,
pub window_mode: String, pub fullscreen_on: bool,
pub render_mode: String, pub render_mode: String,
pub augmented_reality: bool,
pub music: bool,
pub sound: bool,
pub third_person: bool,
pub shadows_sun: bool,
#[serde(skip)] #[serde(skip)]
pub source_file: Option<String>, pub source_file: Option<String>,
@ -430,14 +435,35 @@ impl Preferences {
} }
} }
pub fn get_window_mode(&self) -> WindowMode { pub fn get_window_mode(&self) -> WindowMode {
match self.window_mode.as_str() { match self.fullscreen_on {
"fullscreen" => self.get_fullscreen_mode(), true => self.get_fullscreen_mode(),
_ => WindowMode::Windowed, false => WindowMode::Windowed,
} }
} }
pub fn render_mode_is_gl(&self) -> bool { pub fn render_mode_is_gl(&self) -> bool {
return self.render_mode == "gl"; return self.render_mode == "gl";
} }
pub fn save(&self) {
if let Some(path) = get_prefs_path() {
match toml_edit::ser::to_document::<Preferences>(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 { fn file_is_readable(file_path: &str) -> bool {