use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GameSave {
pub player_data: PlayerData,
pub game_progress: GameProgress,
pub settings: GameSettings,
pub timestamp: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PlayerData {
pub name: String,
pub level: u32,
pub experience: u32,
pub health: i32,
pub max_health: i32,
pub position: (f32, f32),
pub inventory: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GameProgress {
pub current_level: String,
pub completed_levels: Vec<String>,
pub unlocked_abilities: Vec<String>,
pub score: u32,
pub playtime_seconds: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GameSettings {
pub music_volume: f32,
pub sfx_volume: f32,
pub fullscreen: bool,
pub difficulty: String,
}
impl GameSave {
pub fn new() -> Self {
Self {
player_data: PlayerData::default(),
game_progress: GameProgress::default(),
settings: GameSettings::default(),
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs(),
}
}
pub fn save_json<P: AsRef<Path>>(&self, path: P) -> Result<(), String> {
let json = serde_json::to_string_pretty(self)
.map_err(|e| format!("Erro ao serializar: {}", e))?;
fs::write(path, json).map_err(|e| format!("Erro ao escrever arquivo: {}", e))?;
Ok(())
}
pub fn load_json<P: AsRef<Path>>(path: P) -> Result<Self, String> {
let content =
fs::read_to_string(path).map_err(|e| format!("Erro ao ler arquivo: {}", e))?;
let save: GameSave = serde_json::from_str(&content)
.map_err(|e| format!("Erro ao deserializar: {}", e))?;
Ok(save)
}
pub fn save_binary<P: AsRef<Path>>(&self, path: P) -> Result<(), String> {
let bytes =
bincode::serialize(self).map_err(|e| format!("Erro ao serializar: {}", e))?;
fs::write(path, bytes).map_err(|e| format!("Erro ao escrever arquivo: {}", e))?;
Ok(())
}
pub fn load_binary<P: AsRef<Path>>(path: P) -> Result<Self, String> {
let bytes = fs::read(path).map_err(|e| format!("Erro ao ler arquivo: {}", e))?;
let save: GameSave =
bincode::deserialize(&bytes).map_err(|e| format!("Erro ao deserializar: {}", e))?;
Ok(save)
}
pub fn autosave(&self) -> Result<(), String> {
self.save_json("saves/autosave.json")
}
pub fn load_autosave() -> Result<Self, String> {
Self::load_json("saves/autosave.json")
}
pub fn list_saves() -> Result<Vec<String>, String> {
let saves_dir = Path::new("saves");
if !saves_dir.exists() {
return Ok(Vec::new());
}
let mut saves = Vec::new();
for entry in fs::read_dir(saves_dir).map_err(|e| format!("Erro ao ler diretório: {}", e))? {
let entry = entry.map_err(|e| format!("Erro ao ler entrada: {}", e))?;
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) == Some("json") {
if let Some(name) = path.file_stem().and_then(|s| s.to_str()) {
saves.push(name.to_string());
}
}
}
Ok(saves)
}
}
impl Default for PlayerData {
fn default() -> Self {
Self {
name: "Player".to_string(),
level: 1,
experience: 0,
health: 100,
max_health: 100,
position: (0.0, 0.0),
inventory: Vec::new(),
}
}
}
impl Default for GameProgress {
fn default() -> Self {
Self {
current_level: "level1".to_string(),
completed_levels: Vec::new(),
unlocked_abilities: Vec::new(),
score: 0,
playtime_seconds: 0,
}
}
}
impl Default for GameSettings {
fn default() -> Self {
Self {
music_volume: 0.7,
sfx_volume: 0.8,
fullscreen: false,
difficulty: "Normal".to_string(),
}
}
}
impl Default for GameSave {
fn default() -> Self {
Self::new()
}
}