roguelike-game/src/saveload_system.rs

80 lines
2.0 KiB
Rust
Raw Normal View History

2021-11-08 13:58:40 -05:00
use crate::components::*;
use specs::error::NoError;
use specs::prelude::*;
use specs::saveload::{
DeserializeComponents, MarkedBuilder, SerializeComponents, SimpleMarker, SimpleMarkerAllocator,
};
use std::fs;
use std::fs::File;
use std::path::Path;
macro_rules! serialize_individually {
($ecs:expr, $ser:expr, $data:expr, $( $type:ty),*) => {
$(
SerializeComponents::<NoError, SimpleMarker<SerializeMe>>::serialize(
&( $ecs.read_storage::<$type>(), ),
&$data.0,
&$data.1,
&mut $ser,
)
.unwrap();
)*
};
}
pub fn save_game(ecs: &mut World) {
// Create helper
let mapcopy = ecs.get_mut::<crate::map::Map>().unwrap().clone();
let savehelper = ecs
.create_entity()
.with(SerializationHelper { map: mapcopy })
.marked::<SimpleMarker<SerializeMe>>()
.build();
// Actually serialize
{
let data = (
ecs.entities(),
ecs.read_storage::<SimpleMarker<SerializeMe>>(),
);
let writer = File::create("./savegame.json").unwrap();
let mut serializer = serde_json::Serializer::new(writer);
serialize_individually!(
ecs,
serializer,
data,
Position,
Renderable,
Player,
Viewshed,
Monster,
Name,
BlocksTile,
CombatStats,
SufferDamage,
WantsToMelee,
Item,
Consumable,
Ranged,
InflictsDamage,
AreaOfEffect,
Confusion,
ProvidesHealing,
InBackpack,
WantsToPickupItem,
WantsToUseItem,
WantsToDropItem,
SerializationHelper
);
}
// Clean up
ecs.delete_entity(savehelper)
.expect("Failed to clean up savehelper component");
}
pub fn does_save_exist() -> bool {
Path::new("./savegame.json").exists()
}