Looks like this is _possibly_ working but the last step of actually loading a save needs to be figured out.

main
Zed A. Shaw 3 weeks ago
parent 6add24fed2
commit 99d56b246c
  1. 2
      gui.cpp
  2. 5
      map.hpp
  3. 9
      save.cpp
  4. 16
      save.hpp
  5. 14
      tests/save.cpp

@ -59,7 +59,7 @@ void GUI::resize_map(int new_size) {
void GUI::save_world() { void GUI::save_world() {
$log.log("Game saved!"); $log.log("Game saved!");
save::to_file("./savefile.world", $world); save::to_file("./savefile.world", $world, $game_map);
} }
void GUI::create_renderer() { void GUI::create_renderer() {

@ -6,6 +6,7 @@
#include <algorithm> #include <algorithm>
#include <fmt/core.h> #include <fmt/core.h>
#include "point.hpp" #include "point.hpp"
#include "tser.hpp"
#define INV_WALL 0 #define INV_WALL 0
#define INV_SPACE 1 #define INV_SPACE 1
@ -19,6 +20,8 @@ struct Room {
size_t height = 0; size_t height = 0;
Point entry; Point entry;
Point exit; Point exit;
DEFINE_SERIALIZABLE(Room, x, y, width, height);
}; };
typedef std::vector<int> MatrixRow; typedef std::vector<int> 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); void add_neighbors(Matrix &closed, size_t j, size_t i);
class Map { class Map {
public:
Matrix $input_map; Matrix $input_map;
Matrix $walls; Matrix $walls;
Matrix $paths; Matrix $paths;
std::vector<Room> $rooms; std::vector<Room> $rooms;
int $limit = 0; int $limit = 0;
public:
// make explicit // make explicit
Map(Matrix input_map, Matrix walls_map, int limit) : Map(Matrix input_map, Matrix walls_map, int limit) :

@ -16,11 +16,12 @@ inline void extract(DinkyECS::World &world, std::map<DinkyECS::Entity, CompT> &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; SaveData save_data;
tser::BinaryArchive archive; tser::BinaryArchive archive;
save_data.facts.player = world.get_the<Player>(); save_data.facts.player = world.get_the<Player>();
save_data.map = MapData{map.$rooms, map.$input_map, map.$walls, map.$limit};
extract<Position>(world, save_data.position); extract<Position>(world, save_data.position);
extract<Combat>(world, save_data.combat); extract<Combat>(world, save_data.combat);
@ -41,7 +42,7 @@ inline void inject(DinkyECS::World &world, std::map<DinkyECS::Entity, CompT> &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); tser::BinaryArchive archive(0);
dbc::check(fs::exists(path), format("save file does not exist {}", path.string())); dbc::check(fs::exists(path), format("save file does not exist {}", path.string()));
auto size = fs::file_size(path); 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<SaveData>(); auto save_data = archive.load<SaveData>();
world_out.set_the<Player>(save_data.facts.player); world_out.set_the<Player>(save_data.facts.player);
inject<Position>(world_out, save_data.position); inject<Position>(world_out, save_data.position);
inject<Combat>(world_out, save_data.combat); inject<Combat>(world_out, save_data.combat);
inject<Motion>(world_out, save_data.motion); inject<Motion>(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); save::load_configs(world_out);
} }

@ -10,6 +10,15 @@
namespace save { namespace save {
namespace fs = std::filesystem; namespace fs = std::filesystem;
struct MapData {
std::vector<Room> rooms;
Matrix input_map;
Matrix walls;
int limit;
DEFINE_SERIALIZABLE(MapData, rooms, input_map, walls);
};
struct Facts { struct Facts {
components::Player player; components::Player player;
@ -18,15 +27,16 @@ namespace save {
struct SaveData { struct SaveData {
Facts facts; Facts facts;
MapData map;
std::map<DinkyECS::Entity, components::Position> position; std::map<DinkyECS::Entity, components::Position> position;
std::map<DinkyECS::Entity, components::Motion> motion; std::map<DinkyECS::Entity, components::Motion> motion;
std::map<DinkyECS::Entity, components::Combat> combat; std::map<DinkyECS::Entity, components::Combat> 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 to_file(fs::path path, DinkyECS::World &world, Map &map);
void from_file(fs::path path, DinkyECS::World &world_out); void from_file(fs::path path, DinkyECS::World &world_out, Map &map);
void load_configs(DinkyECS::World &world); void load_configs(DinkyECS::World &world);
} }

@ -6,12 +6,14 @@
#include "save.hpp" #include "save.hpp"
#include <optional> #include <optional>
#include <iostream> #include <iostream>
#include "map.hpp"
#include "tser.hpp" #include "tser.hpp"
using namespace fmt; using namespace fmt;
using std::string; using std::string;
using namespace components; using namespace components;
enum class Item : char { enum class Item : char {
RADAR = 'R', RADAR = 'R',
TRAP = 'T', TRAP = 'T',
@ -54,6 +56,8 @@ TEST_CASE("test using tser for serialization", "[config]") {
TEST_CASE("basic save a world", "[save]") { TEST_CASE("basic save a world", "[save]") {
DinkyECS::World world; DinkyECS::World world;
Map map(20, 20);
map.generate();
// configure a player as a fact of the world // configure a player as a fact of the world
Player player{world.entity()}; Player player{world.entity()};
@ -63,10 +67,11 @@ TEST_CASE("basic save a world", "[save]") {
world.set<Motion>(player.entity, {0, 0}); world.set<Motion>(player.entity, {0, 0});
world.set<Combat>(player.entity, {100, 10}); world.set<Combat>(player.entity, {100, 10});
save::to_file("./savetest.world", world); save::to_file("./savetest.world", world, map);
DinkyECS::World in_world; 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<Position>(player.entity); Position &position1 = world.get<Position>(player.entity);
Position &position2 = in_world.get<Position>(player.entity); Position &position2 = in_world.get<Position>(player.entity);
@ -81,4 +86,9 @@ TEST_CASE("basic save a world", "[save]") {
Motion &motion2 = in_world.get<Motion>(player.entity); Motion &motion2 = in_world.get<Motion>(player.entity);
REQUIRE(motion1.dx == motion2.dx); REQUIRE(motion1.dx == motion2.dx);
REQUIRE(motion1.dy == motion2.dy); 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);
} }

Loading…
Cancel
Save