From 7027bd6f2828ae92b0e2232d2a9d97afacbf59e3 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 23 Nov 2024 05:14:12 +0300 Subject: [PATCH] add Players --- src/logic/PlayerController.cpp | 3 +- src/logic/scripting/lua/libs/libblock.cpp | 5 +- src/logic/scripting/lua/libs/libplayer.cpp | 3 +- src/objects/Players.cpp | 71 ++++++++++++++++++++++ src/objects/Players.hpp | 31 ++++++++++ src/world/Level.cpp | 26 +------- src/world/Level.hpp | 13 +--- src/world/World.cpp | 41 +++---------- 8 files changed, 125 insertions(+), 68 deletions(-) create mode 100644 src/objects/Players.cpp create mode 100644 src/objects/Players.hpp diff --git a/src/logic/PlayerController.cpp b/src/logic/PlayerController.cpp index 5d14852b..69cc8422 100644 --- a/src/logic/PlayerController.cpp +++ b/src/logic/PlayerController.cpp @@ -13,6 +13,7 @@ #include "lighting/Lighting.hpp" #include "objects/Entities.hpp" #include "objects/Player.hpp" +#include "objects/Players.hpp" #include "physics/Hitbox.hpp" #include "physics/PhysicsSolver.hpp" #include "settings.hpp" @@ -193,7 +194,7 @@ PlayerController::PlayerController( BlocksController* blocksController ) : settings(settings), level(level), - player(level->getPlayer(0)), + player(level->players->getPlayer(0)), camControl(player, settings.camera), blocksController(blocksController), playerTickClock(20, 3) { diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index 31d7238c..d2451940 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -2,6 +2,7 @@ #include "lighting/Lighting.hpp" #include "logic/BlocksController.hpp" #include "logic/LevelController.hpp" +#include "objects/Players.hpp" #include "voxels/Block.hpp" #include "voxels/Chunk.hpp" #include "voxels/Chunks.hpp" @@ -350,7 +351,7 @@ static int l_place(lua::State* L) { "there is no block with index " + std::to_string(id) ); } - auto player = level->getPlayer(playerid); + auto player = level->players->getPlayer(playerid); controller->getBlocksController()->placeBlock( player, *def, int2blockstate(state), x, y, z ); @@ -367,7 +368,7 @@ static int l_destruct(lua::State* L) { return 0; } auto& def = level->content->getIndices()->blocks.require(voxel->id); - auto player = level->getPlayer(playerid); + auto player = level->players->getPlayer(playerid); controller->getBlocksController()->breakBlock(player, def, x, y, z); return 0; } diff --git a/src/logic/scripting/lua/libs/libplayer.cpp b/src/logic/scripting/lua/libs/libplayer.cpp index 3fcc457e..0411fef9 100644 --- a/src/logic/scripting/lua/libs/libplayer.cpp +++ b/src/logic/scripting/lua/libs/libplayer.cpp @@ -4,6 +4,7 @@ #include "items/Inventory.hpp" #include "objects/Entities.hpp" #include "objects/Player.hpp" +#include "objects/Players.hpp" #include "physics/Hitbox.hpp" #include "window/Camera.hpp" #include "world/Level.hpp" @@ -12,7 +13,7 @@ using namespace scripting; inline Player* get_player(lua::State* L, int idx) { - return level->getPlayer(lua::tointeger(L, idx)); + return level->players->getPlayer(lua::tointeger(L, idx)); } static int l_get_pos(lua::State* L) { diff --git a/src/objects/Players.cpp b/src/objects/Players.cpp new file mode 100644 index 00000000..309a0bfd --- /dev/null +++ b/src/objects/Players.cpp @@ -0,0 +1,71 @@ +#include "Players.hpp" + +#include "Player.hpp" +#include "items/Inventories.hpp" +#include "world/Level.hpp" +#include "world/World.hpp" + +Players::Players(Level* level) : level(level) {} + +void Players::addPlayer(std::unique_ptr player) { + players[player->getId()] = std::move(player); +} + +Player* Players::getPlayer(int64_t id) const { + const auto& found = players.find(id); + if (found == players.end()) { + return nullptr; + } + return found->second.get(); +} + +Player* Players::create() { + auto playerPtr = std::make_unique( + level, + level->getWorld()->getInfo().nextPlayerId++, + glm::vec3(0, DEF_PLAYER_Y, 0), + DEF_PLAYER_SPEED, + level->inventories->create(DEF_PLAYER_INVENTORY_SIZE), + 0 + ); + auto player = playerPtr.get(); + addPlayer(std::move(playerPtr)); + + level->inventories->store(player->getInventory()); + return player; +} + +dv::value Players::serialize() const { + auto root = dv::object(); + auto& list = root.list("players"); + + for (const auto& [id, player] : players) { + list.add(player->serialize()); + } + return list; +} + +void Players::deserialize(const dv::value& src) { + players.clear(); + + const auto& players = src["players"]; + for (auto& playerMap : players) { + auto playerPtr = std::make_unique( + level, + 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); + 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()); + } +} diff --git a/src/objects/Players.hpp b/src/objects/Players.hpp new file mode 100644 index 00000000..e32f4755 --- /dev/null +++ b/src/objects/Players.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#include "typedefs.hpp" +#include "interfaces/Serializable.hpp" + +inline constexpr float DEF_PLAYER_Y = 100.0f; +inline constexpr float DEF_PLAYER_SPEED = 4.0f; +inline constexpr int DEF_PLAYER_INVENTORY_SIZE = 40; + +class Level; +class Player; + +class Players : public Serializable { + Level* level; + std::unordered_map> players; + + void addPlayer(std::unique_ptr player); +public: + Players(Level* level); + + Player* getPlayer(int64_t id) const; + + Player* create(); + + dv::value serialize() const override; + + void deserialize(const dv::value& src) override; +}; diff --git a/src/world/Level.cpp b/src/world/Level.cpp index ced03728..ed370d08 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -7,6 +7,7 @@ #include "lighting/Lighting.hpp" #include "objects/Entities.hpp" #include "objects/Player.hpp" +#include "objects/Players.hpp" #include "physics/Hitbox.hpp" #include "physics/PhysicsSolver.hpp" #include "settings.hpp" @@ -28,6 +29,7 @@ Level::Level( physics(std::make_unique(glm::vec3(0, -22.6f, 0))), events(std::make_unique()), entities(std::make_unique(this)), + players(std::make_unique(this)), settings(settings) { const auto& worldInfo = world->getInfo(); auto& cameraIndices = content->getIndices(ResourceType::CAMERA); @@ -51,14 +53,6 @@ Level::Level( if (worldInfo.nextEntityId) { entities->setNextID(worldInfo.nextEntityId); } - auto inv = std::make_shared( - world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE - ); - auto playerPtr = std::make_unique( - 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()) * @@ -73,23 +67,9 @@ Level::Level( }); inventories = std::make_unique(*this); - inventories->store(player->getInventory()); } -Level::~Level() { -} - -void Level::addPlayer(std::unique_ptr 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(); -} +Level::~Level() = default; void Level::loadMatrix(int32_t x, int32_t z, uint32_t radius) { chunks->setCenter(x, z); diff --git a/src/world/Level.hpp b/src/world/Level.hpp index 74485e7c..1f3ef183 100644 --- a/src/world/Level.hpp +++ b/src/world/Level.hpp @@ -7,10 +7,6 @@ #include "typedefs.hpp" -inline constexpr float DEF_PLAYER_Y = 100.0f; -inline constexpr float DEF_PLAYER_SPEED = 4.0f; -inline constexpr int DEF_PLAYER_INVENTORY_SIZE = 40; - class Content; class World; class Chunks; @@ -21,7 +17,7 @@ class Lighting; class PhysicsSolver; class ChunksStorage; class Camera; -class Player; +class Players; struct EngineSettings; /// @brief A level, contains chunks and objects @@ -29,7 +25,7 @@ class Level { std::unique_ptr world; public: const Content* const content; - std::unordered_map> players; + std::unique_ptr chunks; std::unique_ptr chunksStorage; std::unique_ptr inventories; @@ -38,6 +34,7 @@ public: std::unique_ptr lighting; std::unique_ptr events; std::unique_ptr entities; + std::unique_ptr players; std::vector> cameras; // move somewhere? const EngineSettings& settings; @@ -55,10 +52,6 @@ public: const World* getWorld() const; - void addPlayer(std::unique_ptr player); - - Player* getPlayer(int64_t id) const; - void onSave(); std::shared_ptr getCamera(const std::string& name); diff --git a/src/world/World.cpp b/src/world/World.cpp index 1b732c69..4eb2631a 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -11,6 +11,7 @@ #include "items/Inventories.hpp" #include "objects/Entities.hpp" #include "objects/Player.hpp" +#include "objects/Players.hpp" #include "settings.hpp" #include "voxels/Chunk.hpp" #include "voxels/Chunks.hpp" @@ -69,11 +70,7 @@ void World::write(Level* level) { info.nextEntityId = level->entities->peekNextID(); wfile->write(this, content); - auto playerFile = dv::object(); - auto& players = playerFile.list("players"); - for (const auto& [id, player] : level->players) { - players.add(player->serialize()); - } + auto playerFile = level->players->serialize(); files::write_json(wfile->getPlayerFile(), playerFile); writeResources(content); @@ -92,14 +89,15 @@ std::unique_ptr World::create( info.name = name; info.generator = generator; info.seed = seed; - info.nextPlayerId = 1; auto world = std::make_unique( info, std::make_unique(directory, settings.debug), content, packs ); - return std::make_unique(std::move(world), content, settings); + auto level = std::make_unique(std::move(world), content, settings); + level->players->create(); + return level; } std::unique_ptr World::load( @@ -130,32 +128,13 @@ std::unique_ptr World::load( fs::path file = wfile->getPlayerFile(); if (!fs::is_regular_file(file)) { logger.warning() << "player.json does not exists"; + level->players->create(); } 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( - 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()); + level->players->deserialize(playerRoot); + + if (!playerRoot["players"][0].has("id")) { + level->getWorld()->getInfo().nextPlayerId++; } } return level;