refactor players

This commit is contained in:
MihailRis
2024-11-22 16:17:13 +03:00
parent 7f41f95013
commit bd2acd5766
13 changed files with 101 additions and 151 deletions
+16 -5
View File
@@ -29,7 +29,7 @@ Level::Level(
events(std::make_unique<LevelEvents>()),
entities(std::make_unique<Entities>(this)),
settings(settings) {
auto& worldInfo = world->getInfo();
const auto& worldInfo = world->getInfo();
auto& cameraIndices = content->getIndices(ResourceType::CAMERA);
for (size_t i = 0; i < cameraIndices.size(); i++) {
auto camera = std::make_shared<Camera>();
@@ -54,9 +54,11 @@ Level::Level(
auto inv = std::make_shared<Inventory>(
world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE
);
auto player = spawnObject<Player>(
this, glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, inv, 0
auto playerPtr = std::make_unique<Player>(
this, 0, glm::vec3(0, DEF_PLAYER_Y, 0), DEF_PLAYER_SPEED, inv, 0
);
auto player = playerPtr.get();
addPlayer(std::move(playerPtr));
uint matrixSize =
(settings.chunks.loadDistance.get() + settings.chunks.padding.get()) *
@@ -75,9 +77,18 @@ Level::Level(
}
Level::~Level() {
for (auto obj : objects) {
obj.reset();
}
void Level::addPlayer(std::unique_ptr<Player> player) {
players[player->getId()] = std::move(player);
}
Player* Level::getPlayer(int64_t id) const {
const auto& found = players.find(id);
if (found == players.end()) {
return nullptr;
}
return found->second.get();
}
void Level::loadMatrix(int32_t x, int32_t z, uint32_t radius) {
+6 -30
View File
@@ -2,8 +2,9 @@
#include <memory>
#include <vector>
#include <unordered_map>
#include "interfaces/Object.hpp"
#include "typedefs.hpp"
inline constexpr float DEF_PLAYER_Y = 100.0f;
inline constexpr float DEF_PLAYER_SPEED = 4.0f;
@@ -19,6 +20,7 @@ class Lighting;
class PhysicsSolver;
class ChunksStorage;
class Camera;
class Player;
struct EngineSettings;
/// @brief A level, contains chunks and objects
@@ -26,7 +28,7 @@ class Level {
std::unique_ptr<World> world;
public:
const Content* const content;
std::vector<std::shared_ptr<Object>> objects;
std::unordered_map<int64_t, std::unique_ptr<Player>> players;
std::unique_ptr<Chunks> chunks;
std::unique_ptr<ChunksStorage> chunksStorage;
std::unique_ptr<Inventories> inventories;
@@ -52,35 +54,9 @@ public:
const World* getWorld() const;
/// Spawns object of class T and returns pointer to it.
/// @param T class that derives the Object class
/// @param args pass arguments needed for T class constructor
template <class T, typename... Args>
std::shared_ptr<T> spawnObject(Args&&... args) {
static_assert(
std::is_base_of<Object, T>::value,
"T must be a derived of Object class"
);
std::shared_ptr<T> tObj = std::make_shared<T>(args...);
void addPlayer(std::unique_ptr<Player> player);
std::shared_ptr<Object> obj =
std::dynamic_pointer_cast<Object, T>(tObj);
obj->objectUID = objects.size();
objects.push_back(obj);
obj->spawned();
return tObj;
}
template <class T>
std::shared_ptr<T> getObject(uint64_t id) const {
static_assert(
std::is_base_of<Object, T>::value,
"T must be a derived of Object class"
);
if (id >= objects.size()) return nullptr;
std::shared_ptr<T> object = std::dynamic_pointer_cast<T>(objects[id]);
return object;
}
Player* getPlayer(int64_t id) const;
void onSave();
+35 -37
View File
@@ -71,10 +71,8 @@ void World::write(Level* level) {
auto playerFile = dv::object();
auto& players = playerFile.list("players");
for (const auto& object : level->objects) {
if (auto player = std::dynamic_pointer_cast<Player>(object)) {
players.add(player->serialize());
}
for (const auto& [id, player] : level->players) {
players.add(player->serialize());
}
files::write_json(wfile->getPlayerFile(), playerFile);
@@ -94,6 +92,7 @@ std::unique_ptr<Level> World::create(
info.name = name;
info.generator = generator;
info.seed = seed;
info.nextPlayerId = 1;
auto world = std::make_unique<World>(
info,
std::make_unique<WorldFiles>(directory, settings.debug),
@@ -121,45 +120,42 @@ std::unique_ptr<Level> World::load(
<< " generator: " << info->generator;
auto world = std::make_unique<World>(
info.value(),
std::move(worldFilesPtr),
content,
packs
info.value(), std::move(worldFilesPtr), content, packs
);
auto& wfile = world->wfile;
wfile->readResourcesData(content);
auto level = std::make_unique<Level>(std::move(world), content, settings);
{
fs::path file = wfile->getPlayerFile();
if (!fs::is_regular_file(file)) {
logger.warning() << "player.json does not exists";
} else {
auto playerRoot = files::read_json(file);
if (playerRoot.has("players")) {
level->objects.clear();
const auto& players = playerRoot["players"];
for (auto& playerMap : players) {
auto player = level->spawnObject<Player>(
level.get(),
glm::vec3(0, DEF_PLAYER_Y, 0),
DEF_PLAYER_SPEED,
level->inventories->create(DEF_PLAYER_INVENTORY_SIZE),
0
);
player->deserialize(playerMap);
auto& inventory = player->getInventory();
// invalid inventory id pre 0.25
if (inventory->getId() == 0) {
inventory->setId(level->getWorld()->getNextInventoryId());
}
level->inventories->store(player->getInventory());
}
} else {
auto player = level->getObject<Player>(0);
player->deserialize(playerRoot);
level->inventories->store(player->getInventory());
fs::path file = wfile->getPlayerFile();
if (!fs::is_regular_file(file)) {
logger.warning() << "player.json does not exists";
} else {
level->players.clear();
auto playerRoot = files::read_json(file);
const auto& players = playerRoot["players"];
if (!players[0].has("id")) {
world->getInfo().nextPlayerId++;
}
for (auto& playerMap : players) {
auto playerPtr = std::make_unique<Player>(
level.get(),
0,
glm::vec3(0, DEF_PLAYER_Y, 0),
DEF_PLAYER_SPEED,
level->inventories->create(DEF_PLAYER_INVENTORY_SIZE),
0
);
auto player = playerPtr.get();
player->deserialize(playerMap);
level->addPlayer(std::move(playerPtr));
auto& inventory = player->getInventory();
// invalid inventory id pre 0.25
if (inventory->getId() == 0) {
inventory->setId(level->getWorld()->getNextInventoryId());
}
level->inventories->store(player->getInventory());
}
}
return level;
@@ -231,6 +227,7 @@ void WorldInfo::deserialize(const dv::value& root) {
}
nextInventoryId = root["next-inventory-id"].asInteger(2);
nextEntityId = root["next-entity-id"].asInteger(1);
root.at("next-player-id").get(nextPlayerId);
}
dv::value WorldInfo::serialize() const {
@@ -254,5 +251,6 @@ dv::value WorldInfo::serialize() const {
root["next-inventory-id"] = nextInventoryId;
root["next-entity-id"] = nextEntityId;
root["next-player-id"] = nextPlayerId;
return root;
}
+1
View File
@@ -28,6 +28,7 @@ struct WorldInfo : public Serializable {
std::string generator;
uint64_t seed;
int64_t nextInventoryId = 1;
int64_t nextPlayerId = 0;
/// @brief Day/night loop timer in range 0..1 where
/// 0.0 - is midnight and