[WorldController] Now saving block inventory and metadata.

This commit is contained in:
Quentin Bazin 2020-06-23 17:36:06 +02:00
parent 2c18d3ba49
commit 0cdb08060a
7 changed files with 38 additions and 8 deletions

View File

@ -73,10 +73,10 @@ void Chunk::setBlock(int x, int y, int z, u16 type) {
const Block &block = Registry::getInstance().getBlock(type);
if (block.canUpdate()) {
m_tickingBlocks.emplace(x + y * width + z * (width * height), block);
addTickingBlock(x, y, z, block);
}
else {
auto it = m_tickingBlocks.find(x + y * width + z * (width * height));
auto it = m_tickingBlocks.find(gk::Vector3i{x, y, z});
if (it != m_tickingBlocks.end())
m_tickingBlocks.erase(it);
}

View File

@ -83,6 +83,8 @@ class Chunk : public gk::NonCopyable {
bool areAllNeighboursLoaded() const;
bool areAllNeighboursInitialized() const;
void addTickingBlock(int x, int y, int z, const Block &block) { m_tickingBlocks.emplace(gk::Vector3i{x, y, z}, block); }
bool hasChanged() const { return m_hasChanged; }
void setChanged(bool hasChanged) { m_hasChanged = hasChanged; }
@ -124,8 +126,7 @@ class Chunk : public gk::NonCopyable {
std::atomic_bool m_hasLightChanged{false};
std::atomic_bool m_isInitialized{false};
std::unordered_map<std::size_t, const Block&> m_tickingBlocks;
std::unordered_map<gk::Vector3i, const Block&> m_tickingBlocks;
std::unordered_map<gk::Vector3i, std::unique_ptr<BlockData>> m_blockData;
};

View File

@ -165,6 +165,8 @@ int ServerApplication::run(bool isProtected) {
m_serverCommandHandler.sendServerClosed("Server closed.");
m_server.disconnectAllClients();
m_registry.clear();
m_worldController.clearEntities();
}

View File

@ -38,6 +38,11 @@ void Server::init(u16 port) {
m_selector.add(m_tcpListener);
}
void Server::disconnectAllClients() {
for (auto &it : m_info.clients())
disconnectClient(it);
}
void Server::handleGameEvents() {
if (m_selector.wait(sf::milliseconds(10))) {
if (m_selector.isReady(m_tcpListener)) {

View File

@ -43,6 +43,8 @@ class Server {
public:
void init(u16 port = 4242);
void disconnectAllClients();
void handleGameEvents();
void sendToAllClients(Network::Packet &packet) const;

View File

@ -54,11 +54,13 @@ void ServerChunk::onBlockDestroyed(int x, int y, int z, const Block &block) {
void ServerChunk::tick(World &world, ServerCommandHandler &server) {
if (!m_tickingBlocks.empty()) {
for (auto &it : m_tickingBlocks) {
int z = it.first / (width * height);
int y = (it.first - z * (width * height)) / width;
int x = (it.first - z * (width * height)) % width;
((ServerBlock &)it.second).onTick(
glm::ivec3{x + m_x * width, y + m_y * depth, z + m_z * height}, *this, world, server);
glm::ivec3{
it.first.x + m_x * width,
it.first.y + m_y * depth,
it.first.z + m_z * height
},
*this, world, server);
}
}
}

View File

@ -82,6 +82,14 @@ void WorldController::load(const std::string &name) {
for (u8 z = 0 ; z < Chunk::height ; ++z) {
for (u8 y = 0 ; y < Chunk::depth ; ++y) {
for (u8 x = 0 ; x < Chunk::width ; ++x) {
bool hasMetadata;
save >> hasMetadata;
if (hasMetadata) {
BlockData *blockData = chunk.addBlockData(x, y, z);
save >> blockData->inventory >> blockData->meta >> blockData->useAltTiles;
}
u32 data;
u8 light;
save >> data >> light;
@ -89,6 +97,10 @@ void WorldController::load(const std::string &name) {
chunk.setBlockRaw(x, y, z, data & 0xffff);
chunk.setData(x, y, z, data >> 16);
chunk.lightmap().setLightData(x, y, z, light);
const Block &block = Registry::getInstance().getBlock(data & 0xffff);
if (block.canUpdate())
chunk.addTickingBlock(x, y, z, block);
}
}
}
@ -124,6 +136,12 @@ void WorldController::save(const std::string &name) {
for (u8 z = 0 ; z < Chunk::height ; ++z) {
for (u8 y = 0 ; y < Chunk::depth ; ++y) {
for (u8 x = 0 ; x < Chunk::width ; ++x) {
BlockData *blockData = it.second->getBlockData(x, y, z);
if (blockData)
chunks << true << blockData->inventory << blockData->meta << blockData->useAltTiles;
else
chunks << false;
chunks << u32(data[z][y][x])
<< u8(it.second->lightmap().getLightData(x, y, z));
}