add Players

This commit is contained in:
MihailRis 2024-11-23 05:14:12 +03:00
parent 5f496eecb2
commit 7027bd6f28
8 changed files with 125 additions and 68 deletions

View File

@ -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) {

View File

@ -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;
}

View File

@ -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) {

71
src/objects/Players.cpp Normal file
View File

@ -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> 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<Player>(
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<Player>(
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());
}
}

31
src/objects/Players.hpp Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <memory>
#include <unordered_map>
#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<int64_t, std::unique_ptr<Player>> players;
void addPlayer(std::unique_ptr<Player> 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;
};

View File

@ -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<PhysicsSolver>(glm::vec3(0, -22.6f, 0))),
events(std::make_unique<LevelEvents>()),
entities(std::make_unique<Entities>(this)),
players(std::make_unique<Players>(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<Inventory>(
world->getNextInventoryId(), DEF_PLAYER_INVENTORY_SIZE
);
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()) *
@ -73,23 +67,9 @@ Level::Level(
});
inventories = std::make_unique<Inventories>(*this);
inventories->store(player->getInventory());
}
Level::~Level() {
}
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();
}
Level::~Level() = default;
void Level::loadMatrix(int32_t x, int32_t z, uint32_t radius) {
chunks->setCenter(x, z);

View File

@ -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> world;
public:
const Content* const content;
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;
@ -38,6 +34,7 @@ public:
std::unique_ptr<Lighting> lighting;
std::unique_ptr<LevelEvents> events;
std::unique_ptr<Entities> entities;
std::unique_ptr<Players> players;
std::vector<std::shared_ptr<Camera>> cameras; // move somewhere?
const EngineSettings& settings;
@ -55,10 +52,6 @@ public:
const World* getWorld() const;
void addPlayer(std::unique_ptr<Player> player);
Player* getPlayer(int64_t id) const;
void onSave();
std::shared_ptr<Camera> getCamera(const std::string& name);

View File

@ -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<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),
content,
packs
);
return std::make_unique<Level>(std::move(world), content, settings);
auto level = std::make_unique<Level>(std::move(world), content, settings);
level->players->create();
return level;
}
std::unique_ptr<Level> World::load(
@ -130,32 +128,13 @@ std::unique_ptr<Level> 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<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());
level->players->deserialize(playerRoot);
if (!playerRoot["players"][0].has("id")) {
level->getWorld()->getInfo().nextPlayerId++;
}
}
return level;