From 4f543d7298e9e3a5051f384f69defd1084320ae8 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Mon, 15 Nov 2021 22:44:36 +0100 Subject: [PATCH] Second floor please --- .gitignore | 2 ++ Cargo.lock | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 ++- src/main.rs | 62 +++++++++++++++++++++++++++++++++------- 4 files changed, 138 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index ea8c4bf..e6bc2a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target +savegame.json + diff --git a/Cargo.lock b/Cargo.lock index 152ebd0..4ba6892 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + [[package]] name = "lazy_static" version = "1.4.0" @@ -38,6 +44,24 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +[[package]] +name = "proc-macro2" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rand" version = "0.3.23" @@ -90,9 +114,59 @@ name = "roguelike" version = "0.1.0" dependencies = [ "rand 0.3.23", + "serde", + "serde_json", "tcod", ] +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e277c495ac6cd1a01a58d0a0c574568b4d1ddf14f59965c6a58b8d96400b54f3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "tcod" version = "0.15.0" @@ -100,6 +174,8 @@ source = "git+https://github.com/tomassedovic/tcod-rs#d4ad0749867acad6c1e510bf5e dependencies = [ "bitflags", "lazy_static", + "serde", + "serde_derive", "tcod-sys", ] @@ -112,6 +188,12 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 9d9f51e..44ce00c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,5 +6,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -tcod = { git = "https://github.com/tomassedovic/tcod-rs" } +tcod = { git = "https://github.com/tomassedovic/tcod-rs", features = ["serialization"] } rand = "0.3.9" +serde = { version = "*", features = ["derive"] } +serde_json = "*" diff --git a/src/main.rs b/src/main.rs index 094cd4f..9367ed0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,14 @@ -#![allow(unused_imports)] -#![allow(unused_variables)] -#![allow(unused_mut)] -#![allow(dead_code)] +// #![allow(unused_imports)] +// #![allow(unused_variables)] +// #![allow(unused_mut)] +// #![allow(dead_code)] use rand::Rng; +use serde::{Deserialize, Serialize}; use std::cmp; +use std::error::Error; +use std::fs::File; +use std::io::{Read, Write}; use tcod::colors::*; use tcod::console::*; use tcod::input::{self, Event, Key, Mouse}; @@ -65,7 +69,7 @@ struct Tcod { mouse: Mouse, } -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] struct Object { x: i32, y: i32, @@ -173,7 +177,7 @@ impl Object { } } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] struct Tile { blocked: bool, explored: bool, @@ -200,6 +204,7 @@ impl Tile { type Map = Vec>; +#[derive(Serialize, Deserialize)] struct Game { map: Map, messages: Messages, @@ -237,7 +242,7 @@ impl Rect { } // Combat related properties and methods (monster, player, NPC). -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] struct Fighter { max_hp: i32, hp: i32, @@ -246,6 +251,7 @@ struct Fighter { on_death: DeathCallback, } +#[derive(Serialize, Deserialize)] struct Messages { messages: Vec<(String, Color)>, } @@ -273,7 +279,7 @@ enum PlayerAction { Exit, } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] enum Ai { Basic, Confused { @@ -282,7 +288,7 @@ enum Ai { }, } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] enum DeathCallback { Player, Monster, @@ -299,7 +305,7 @@ impl DeathCallback { } } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] enum Item { Heal, Lightning, @@ -313,7 +319,6 @@ enum UseResult { } fn handle_keys(tcod: &mut Tcod, game: &mut Game, objects: &mut Vec) -> PlayerAction { - use tcod::input::Key; use tcod::input::KeyCode::*; use PlayerAction::*; @@ -1207,6 +1212,7 @@ fn initialise_fov(tcod: &mut Tcod, map: &Map) { ) } } + tcod.con.clear(); } fn new_game(tcod: &mut Tcod) -> (Game, Vec) { @@ -1267,6 +1273,7 @@ fn play_game(tcod: &mut Tcod, game: &mut Game, objects: &mut Vec) { previous_player_position = objects[PLAYER].pos(); let player_action = handle_keys(tcod, game, objects); if player_action == PlayerAction::Exit { + save_game(game, objects).unwrap(); break; } @@ -1316,6 +1323,19 @@ fn main_menu(tcod: &mut Tcod) { let (mut game, mut objects) = new_game(tcod); play_game(tcod, &mut game, &mut objects); } + Some(1) => { + // Load game + match load_game() { + Ok((mut game, mut objects)) => { + initialise_fov(tcod, &game.map); + play_game(tcod, &mut game, &mut objects); + } + Err(_e) => { + msgbox("\nNo saved game to load.\n", 24, &mut tcod.root); + continue; + } + } + } Some(2) => { // Quit break; @@ -1325,6 +1345,26 @@ fn main_menu(tcod: &mut Tcod) { } } +fn save_game(game: &Game, objects: &[Object]) -> Result<(), Box> { + let save_data = serde_json::to_string(&(game, objects))?; + let mut file = File::create("savegame.json")?; + file.write_all(save_data.as_bytes())?; + Ok(()) +} + +fn load_game() -> Result<(Game, Vec), Box> { + let mut json_save_state = String::new(); + let mut file = File::open("savegame.json")?; + file.read_to_string(&mut json_save_state)?; + let result = serde_json::from_str::<(Game, Vec)>(&json_save_state)?; + Ok(result) +} + +fn msgbox(text: &str, width: i32, root: &mut Root) { + let options: &[&str] = &[]; + menu(text, options, width, root); +} + fn main() { tcod::system::set_fps(FPS);