Skip to content

Commit

Permalink
add a reset --hard option (#46)
Browse files Browse the repository at this point in the history
* add a reset --hard option

* move game file handling to a separate module

* handle both cases in the same function

* improve naming

* update changelog
  • Loading branch information
facundoolano authored Jun 7, 2021
1 parent 8da6036 commit 7415eb8
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog

## Unreleased
### Added
* a `rpg reset --hard` flag to remove data files and forget information from previous plays #46

## [0.4.0](https://github.com/facundoolano/rpg-cli/releases/tag/0.4.0) - 2021-06-05
### Added
* This Changelog
Expand Down
28 changes: 28 additions & 0 deletions src/game/datafile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use std::{fs, io, path};

pub fn read() -> io::Result<Vec<u8>> {
fs::read(file())
}

pub fn write(data: Vec<u8>) -> Result<(), io::Error> {
let rpg_dir = rpg_dir();
if !rpg_dir.exists() {
fs::create_dir(&rpg_dir).unwrap();
}
fs::write(file(), &data)
}

pub fn remove() {
let rpg_dir = rpg_dir();
if !rpg_dir.exists() {
fs::remove_dir_all(&rpg_dir).unwrap();
}
}

fn rpg_dir() -> path::PathBuf {
dirs::home_dir().unwrap().join(".rpg")
}

fn file() -> path::PathBuf {
rpg_dir().join("data")
}
31 changes: 12 additions & 19 deletions src/game/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ use crate::randomizer::random;
use crate::randomizer::Randomizer;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::{fs, io, path};
use std::io;
use tombstone::Tombstone;

pub mod battle;
mod datafile;
pub mod tombstone;

#[derive(Debug)]
Expand Down Expand Up @@ -42,27 +43,27 @@ impl Game {
}

pub fn load() -> Result<Self, Error> {
let data = fs::read(data_file()).or(Err(Error::NoDataFile))?;
let data: Vec<u8> = datafile::read().or(Err(Error::NoDataFile))?;
let game: Game = bincode::deserialize(&data).unwrap();
Ok(game)
}

pub fn save(&self) -> Result<(), io::Error> {
let rpg_dir = rpg_dir();
if !rpg_dir.exists() {
fs::create_dir(&rpg_dir).unwrap();
}

let data = bincode::serialize(&self).unwrap();
fs::write(data_file(), &data)
datafile::write(data)
}

/// Remove the game data and reset this reference.
/// Tombstones are preserved across games.
pub fn reset(&mut self) {
// move the tombstones to the new game
pub fn reset(&mut self, hard: bool) {
let mut new_game = Self::new();
new_game.tombstones = self.tombstones.drain().collect();

if hard {
datafile::remove();
} else {
// preserve tombstones across hero's lifes
new_game.tombstones = self.tombstones.drain().collect();
}

// replace the current, finished game with the new one
*self = new_game;
Expand Down Expand Up @@ -219,14 +220,6 @@ impl Default for Game {
}
}

fn rpg_dir() -> path::PathBuf {
dirs::home_dir().unwrap().join(".rpg")
}

fn data_file() -> path::PathBuf {
rpg_dir().join("data")
}

fn enemy_level(player_level: i32, distance_from_home: i32) -> i32 {
std::cmp::max(player_level / 2 + distance_from_home - 1, 1)
}
Expand Down
12 changes: 8 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ enum Command {
},

/// Resets the current game.
Reset,
Reset {
/// Reset data files, losing cross-hero progress.
#[clap(long)]
hard: bool,
},

/// Buys an item from the shop.
/// If name is omitted lists the items available for sale.
Expand Down Expand Up @@ -103,7 +107,7 @@ fn main() {
exit_code = battle(&mut game, run, bribe);
}
Command::PrintWorkDir => println!("{}", game.location.path_string()),
Command::Reset => game.reset(),
Command::Reset { hard } => game.reset(hard),
Command::Buy { item } => shop(&mut game, &item),
Command::Use { item } => use_item(&mut game, &item),
}
Expand All @@ -119,7 +123,7 @@ fn change_dir(game: &mut Game, dest: &str, run: bool, bribe: bool, force: bool)
if force {
game.visit(dest);
} else if let Err(game::Error::GameOver) = game.go_to(&dest, run, bribe) {
game.reset();
game.reset(false);
return 1;
}
} else {
Expand All @@ -135,7 +139,7 @@ fn battle(game: &mut Game, run: bool, bribe: bool) -> i32 {
let mut exit_code = 0;
if let Some(mut enemy) = game.maybe_spawn_enemy() {
if let Err(game::Error::GameOver) = game.maybe_battle(&mut enemy, run, bribe) {
game.reset();
game.reset(false);
exit_code = 1;
}
}
Expand Down

0 comments on commit 7415eb8

Please # to comment.