refactor players
This commit is contained in:
+16
-5
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user