From 99d56b246ce3d30daac3fba929382060b2fa6c51 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Wed, 6 Nov 2024 07:18:59 -0500 Subject: [PATCH] Looks like this is _possibly_ working but the last step of actually loading a save needs to be figured out. --- gui.cpp | 2 +- map.hpp | 5 ++++- save.cpp | 9 +++++++-- save.hpp | 16 +++++++++++++--- tests/save.cpp | 14 ++++++++++++-- 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/gui.cpp b/gui.cpp index d977969..057a4a6 100644 --- a/gui.cpp +++ b/gui.cpp @@ -59,7 +59,7 @@ void GUI::resize_map(int new_size) { void GUI::save_world() { $log.log("Game saved!"); - save::to_file("./savefile.world", $world); + save::to_file("./savefile.world", $world, $game_map); } void GUI::create_renderer() { diff --git a/map.hpp b/map.hpp index d368952..6c127f6 100644 --- a/map.hpp +++ b/map.hpp @@ -6,6 +6,7 @@ #include #include #include "point.hpp" +#include "tser.hpp" #define INV_WALL 0 #define INV_SPACE 1 @@ -19,6 +20,8 @@ struct Room { size_t height = 0; Point entry; Point exit; + + DEFINE_SERIALIZABLE(Room, x, y, width, height); }; typedef std::vector MatrixRow; @@ -28,12 +31,12 @@ void dump_map(const std::string &msg, Matrix &map); void add_neighbors(Matrix &closed, size_t j, size_t i); class Map { +public: Matrix $input_map; Matrix $walls; Matrix $paths; std::vector $rooms; int $limit = 0; -public: // make explicit Map(Matrix input_map, Matrix walls_map, int limit) : diff --git a/save.cpp b/save.cpp index 27f4919..831db50 100644 --- a/save.cpp +++ b/save.cpp @@ -16,11 +16,12 @@ inline void extract(DinkyECS::World &world, std::map &i } } -void save::to_file(fs::path path, DinkyECS::World &world) { +void save::to_file(fs::path path, DinkyECS::World &world, Map &map) { SaveData save_data; tser::BinaryArchive archive; save_data.facts.player = world.get_the(); + save_data.map = MapData{map.$rooms, map.$input_map, map.$walls, map.$limit}; extract(world, save_data.position); extract(world, save_data.combat); @@ -41,7 +42,7 @@ inline void inject(DinkyECS::World &world, std::map &ou } } -void save::from_file(fs::path path, DinkyECS::World &world_out) { +void save::from_file(fs::path path, DinkyECS::World &world_out, Map &map_out) { tser::BinaryArchive archive(0); dbc::check(fs::exists(path), format("save file does not exist {}", path.string())); auto size = fs::file_size(path); @@ -60,11 +61,15 @@ void save::from_file(fs::path path, DinkyECS::World &world_out) { } auto save_data = archive.load(); + world_out.set_the(save_data.facts.player); inject(world_out, save_data.position); inject(world_out, save_data.combat); inject(world_out, save_data.motion); + map_out = Map(save_data.map.input_map, + save_data.map.walls, save_data.map.limit); + save::load_configs(world_out); } diff --git a/save.hpp b/save.hpp index 389616b..cdaac04 100644 --- a/save.hpp +++ b/save.hpp @@ -10,6 +10,15 @@ namespace save { namespace fs = std::filesystem; + struct MapData { + std::vector rooms; + Matrix input_map; + Matrix walls; + int limit; + + DEFINE_SERIALIZABLE(MapData, rooms, input_map, walls); + }; + struct Facts { components::Player player; @@ -18,15 +27,16 @@ namespace save { struct SaveData { Facts facts; + MapData map; std::map position; std::map motion; std::map combat; - DEFINE_SERIALIZABLE(SaveData, facts, position, motion, combat); + DEFINE_SERIALIZABLE(SaveData, facts, map, position, motion, combat); }; - void to_file(fs::path path, DinkyECS::World &world); - void from_file(fs::path path, DinkyECS::World &world_out); + void to_file(fs::path path, DinkyECS::World &world, Map &map); + void from_file(fs::path path, DinkyECS::World &world_out, Map &map); void load_configs(DinkyECS::World &world); } diff --git a/tests/save.cpp b/tests/save.cpp index ade0541..09726af 100644 --- a/tests/save.cpp +++ b/tests/save.cpp @@ -6,12 +6,14 @@ #include "save.hpp" #include #include +#include "map.hpp" #include "tser.hpp" using namespace fmt; using std::string; using namespace components; + enum class Item : char { RADAR = 'R', TRAP = 'T', @@ -54,6 +56,8 @@ TEST_CASE("test using tser for serialization", "[config]") { TEST_CASE("basic save a world", "[save]") { DinkyECS::World world; + Map map(20, 20); + map.generate(); // configure a player as a fact of the world Player player{world.entity()}; @@ -63,10 +67,11 @@ TEST_CASE("basic save a world", "[save]") { world.set(player.entity, {0, 0}); world.set(player.entity, {100, 10}); - save::to_file("./savetest.world", world); + save::to_file("./savetest.world", world, map); DinkyECS::World in_world; - save::from_file("./savetest.world", in_world); + Map in_map(0, 0); // this will be changed on load + save::from_file("./savetest.world", in_world, in_map); Position &position1 = world.get(player.entity); Position &position2 = in_world.get(player.entity); @@ -81,4 +86,9 @@ TEST_CASE("basic save a world", "[save]") { Motion &motion2 = in_world.get(player.entity); REQUIRE(motion1.dx == motion2.dx); REQUIRE(motion1.dy == motion2.dy); + + REQUIRE(map.width() == in_map.width()); + REQUIRE(map.height() == in_map.height()); + REQUIRE(map.$walls == in_map.$walls); + REQUIRE(map.$input_map == in_map.$input_map); }