Better player save & load

This commit is contained in:
InfiniteCoder 2024-03-03 00:25:05 +03:00
parent 0157213a56
commit 9376dc4165
6 changed files with 34 additions and 35 deletions

View File

@ -559,21 +559,6 @@ bool WorldFiles::readWorldInfo(World* world) {
return true; return true;
} }
void WorldFiles::writePlayer(std::shared_ptr<Player> player) {
files::write_json(getPlayerFile(), player->serialize().release());
}
bool WorldFiles::readPlayer(std::shared_ptr<Player> player) {
fs::path file = getPlayerFile();
if (!fs::is_regular_file(file)) {
std::cerr << "warning: player.json does not exists" << std::endl;
return false;
}
player->deserialize(files::read_json(file).get());
return true;
}
void WorldFiles::addPack(const World* world, const std::string& id) { void WorldFiles::addPack(const World* world, const std::string& id) {
fs::path file = getPacksFile(); fs::path file = getPacksFile();
if (!fs::is_regular_file(file)) { if (!fs::is_regular_file(file)) {

View File

@ -139,14 +139,9 @@ public:
chunk_inventories_map fetchInventories(int x, int z); chunk_inventories_map fetchInventories(int x, int z);
bool readWorldInfo(World* world); bool readWorldInfo(World* world);
bool readPlayer(std::shared_ptr<Player> player);
void writeRegion(int x, int y, WorldRegion* entry, fs::path file, int layer); void writeRegion(int x, int y, WorldRegion* entry, fs::path file, int layer);
/// @brief Write player data to world files
/// @param player target player
void writePlayer(std::shared_ptr<Player> player);
/// @brief Write all unsaved data to world files /// @brief Write all unsaved data to world files
/// @param world target world /// @param world target world
/// @param content world content /// @param content world content
@ -169,4 +164,4 @@ public:
static const char* WORLD_FILE; static const char* WORLD_FILE;
}; };
#endif /* FILES_WORLDFILES_H_ */ #endif /* FILES_WORLDFILES_H_ */

View File

@ -12,11 +12,6 @@
#include "../items/Inventory.h" #include "../items/Inventory.h"
#include "../items/Inventories.h" #include "../items/Inventories.h"
const float DEF_PLAYER_Y = 100.0f;
const float DEF_PLAYER_SPEED = 4.0f;
const int DEF_PLAYER_INVENTORY_SIZE = 40;
Level::Level(World* world, const Content* content, EngineSettings& settings) Level::Level(World* world, const Content* content, EngineSettings& settings)
: world(world), : world(world),
content(content), content(content),
@ -25,7 +20,7 @@ Level::Level(World* world, const Content* content, EngineSettings& settings)
events(std::make_unique<LevelEvents>()), events(std::make_unique<LevelEvents>()),
settings(settings) settings(settings)
{ {
auto inv = std::make_shared<Inventory>(0, DEF_PLAYER_INVENTORY_SIZE); auto inv = std::make_shared<Inventory>(world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE);
auto player = spawnObject<Player>(glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, inv); auto player = spawnObject<Player>(glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, inv);
uint matrixSize = (settings.chunks.loadDistance + settings.chunks.padding) * 2; uint matrixSize = (settings.chunks.loadDistance + settings.chunks.padding) * 2;

View File

@ -7,6 +7,10 @@
#include "../interfaces/Object.h" #include "../interfaces/Object.h"
#include <vector> #include <vector>
const float DEF_PLAYER_Y = 100.0f;
const float DEF_PLAYER_SPEED = 4.0f;
const int DEF_PLAYER_INVENTORY_SIZE = 40;
class Content; class Content;
class World; class World;
class Player; class Player;

View File

@ -64,11 +64,16 @@ void World::write(Level* level) {
} }
wfile->write(this, content); wfile->write(this, content);
for (auto object : level->objects) { auto playerFile = dynamic::Map();
if (std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(object)) { {
wfile->writePlayer(player); auto& players = playerFile.putList("players");
for (auto object : level->objects) {
if (std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(object)) {
players.put(player->serialize().release());
}
} }
} }
files::write_json(wfile->getPlayerFile(), &playerFile);
} }
Level* World::create(std::string name, Level* World::create(std::string name,
@ -98,10 +103,25 @@ Level* World::load(fs::path directory,
} }
auto level = new Level(world.get(), content, settings); auto level = new Level(world.get(), content, settings);
for (auto object : level->objects) { {
if (std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(object)) { fs::path file = wfile->getPlayerFile();
wfile->readPlayer(player); if (!fs::is_regular_file(file)) {
level->inventories->store(player->getInventory()); std::cerr << "warning: player.json does not exists" << std::endl;
} else {
auto playerFile = files::read_json(file);
if (playerFile->has("players")) {
level->objects.clear();
auto players = playerFile->list("players");
for (size_t i = 0; i < players->size(); i++) {
auto player = level->spawnObject<Player>(glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, level->inventories->create(DEF_PLAYER_INVENTORY_SIZE));
player->deserialize(players->map(i));
level->inventories->store(player->getInventory());
}
} else {
auto player = level->getObject<Player>(0);
player->deserialize(playerFile.get());
level->inventories->store(player->getInventory());
}
} }
} }
(void)world.release(); (void)world.release();

View File

@ -36,7 +36,7 @@ class World : Serializable {
const Content* const content; const Content* const content;
std::vector<ContentPack> packs; std::vector<ContentPack> packs;
int64_t nextInventoryId = 1; int64_t nextInventoryId = 0;
public: public:
std::unique_ptr<WorldFiles> wfile; std::unique_ptr<WorldFiles> wfile;