[ServerWorld] New function added to send spawn data to connecting clients.
This commit is contained in:
parent
12dcb38ebd
commit
1dc66fd9e2
@ -30,22 +30,14 @@ class ClientWorld : public World, public gk::Drawable {
|
|||||||
|
|
||||||
void receiveChunkData(sf::Packet &packet);
|
void receiveChunkData(sf::Packet &packet);
|
||||||
|
|
||||||
// FIXME: Duplicated with ServerWorld
|
Chunk *getChunk(int cx, int cy, int cz) const override;
|
||||||
ClientChunk *getChunk(int cx, int cy, int cz) const;
|
|
||||||
BlockData *getBlockData(int x, int y, int z) const override;
|
|
||||||
|
|
||||||
// FIXME: Duplicated with ServerWorld
|
|
||||||
u16 getBlock(int x, int y, int z) const override;
|
|
||||||
void setBlock(int x, int y, int z, u16 id) const override;
|
|
||||||
u16 getData(int x, int y, int z) const override;
|
|
||||||
void setData(int x, int y, int z, u16 id) const override;
|
|
||||||
|
|
||||||
void setClient(ClientCommandHandler &client) { m_client = &client; }
|
void setClient(ClientCommandHandler &client) { m_client = &client; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
|
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
|
||||||
|
|
||||||
mutable std::unordered_map<gk::Vector3i, std::unique_ptr<ClientChunk>> m_chunks;
|
std::unordered_map<gk::Vector3i, std::unique_ptr<ClientChunk>> m_chunks;
|
||||||
|
|
||||||
gk::Texture &m_texture;
|
gk::Texture &m_texture;
|
||||||
|
|
||||||
|
@ -55,8 +55,11 @@ void ClientApplication::init() {
|
|||||||
Registry::setInstance(m_registry);
|
Registry::setInstance(m_registry);
|
||||||
|
|
||||||
// m_stateStack.push<TitleScreenState>();
|
// m_stateStack.push<TitleScreenState>();
|
||||||
auto &game = m_stateStack.push<GameState>(m_host, m_port);
|
|
||||||
m_stateStack.push<ServerLoadingState>(game);
|
m_stateStack.push<GameState>(m_host, m_port);
|
||||||
|
|
||||||
|
// auto &game = m_stateStack.push<GameState>(m_host, m_port);
|
||||||
|
// m_stateStack.push<ServerLoadingState>(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientApplication::initOpenGL() {
|
void ClientApplication::initOpenGL() {
|
||||||
|
@ -38,37 +38,40 @@ void ClientWorld::receiveChunkData(sf::Packet &packet) {
|
|||||||
s32 cx, cy, cz;
|
s32 cx, cy, cz;
|
||||||
packet >> cx >> cy >> cz;
|
packet >> cx >> cy >> cz;
|
||||||
|
|
||||||
ClientChunk *chunk = getChunk(cx, cy, cz);
|
Chunk *chunk = getChunk(cx, cy, cz);
|
||||||
if (chunk) {
|
if (!chunk) {
|
||||||
for (u16 z = 0 ; z < CHUNK_DEPTH ; ++z) {
|
auto it = m_chunks.emplace(gk::Vector3i{cx, cy, cz}, new ClientChunk(cx, cy, cz, m_texture));
|
||||||
for (u16 y = 0 ; y < CHUNK_HEIGHT ; ++y) {
|
chunk = it.first->second.get();
|
||||||
for (u16 x = 0 ; x < CHUNK_WIDTH ; ++x) {
|
}
|
||||||
u16 block;
|
|
||||||
u8 light;
|
|
||||||
|
|
||||||
packet >> block >> light;
|
for (u16 z = 0 ; z < CHUNK_DEPTH ; ++z) {
|
||||||
|
for (u16 y = 0 ; y < CHUNK_HEIGHT ; ++y) {
|
||||||
|
for (u16 x = 0 ; x < CHUNK_WIDTH ; ++x) {
|
||||||
|
u16 block;
|
||||||
|
u8 light;
|
||||||
|
|
||||||
chunk->setBlockRaw(x, y, z, block & 0xffff);
|
packet >> block >> light;
|
||||||
// chunk->setData(x, y, z, block >> 16);
|
|
||||||
chunk->lightmap().setLightData(x, y, z, light);
|
chunk->setBlockRaw(x, y, z, block & 0xffff);
|
||||||
}
|
// chunk->setData(x, y, z, block >> 16);
|
||||||
|
chunk->lightmap().setLightData(x, y, z, light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chunk->setInitialized(true);
|
|
||||||
|
|
||||||
// if(chunk->getSurroundingChunk(Chunk::Left)) chunk->getSurroundingChunk(Chunk::Left)->setChanged(true);
|
|
||||||
// if(chunk->getSurroundingChunk(Chunk::Right)) chunk->getSurroundingChunk(Chunk::Right)->setChanged(true);
|
|
||||||
// if(chunk->getSurroundingChunk(Chunk::Bottom)) chunk->getSurroundingChunk(Chunk::Bottom)->setChanged(true);
|
|
||||||
// if(chunk->getSurroundingChunk(Chunk::Top)) chunk->getSurroundingChunk(Chunk::Top)->setChanged(true);
|
|
||||||
// if(chunk->getSurroundingChunk(Chunk::Front)) chunk->getSurroundingChunk(Chunk::Front)->setChanged(true);
|
|
||||||
// if(chunk->getSurroundingChunk(Chunk::Back)) chunk->getSurroundingChunk(Chunk::Back)->setChanged(true);
|
|
||||||
|
|
||||||
// std::cout << "Chunk at (" << cx << ", " << cy << ", " << cz << ") received" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chunk->setInitialized(true);
|
||||||
|
|
||||||
|
// if(chunk->getSurroundingChunk(Chunk::Left)) chunk->getSurroundingChunk(Chunk::Left)->setChanged(true);
|
||||||
|
// if(chunk->getSurroundingChunk(Chunk::Right)) chunk->getSurroundingChunk(Chunk::Right)->setChanged(true);
|
||||||
|
// if(chunk->getSurroundingChunk(Chunk::Bottom)) chunk->getSurroundingChunk(Chunk::Bottom)->setChanged(true);
|
||||||
|
// if(chunk->getSurroundingChunk(Chunk::Top)) chunk->getSurroundingChunk(Chunk::Top)->setChanged(true);
|
||||||
|
// if(chunk->getSurroundingChunk(Chunk::Front)) chunk->getSurroundingChunk(Chunk::Front)->setChanged(true);
|
||||||
|
// if(chunk->getSurroundingChunk(Chunk::Back)) chunk->getSurroundingChunk(Chunk::Back)->setChanged(true);
|
||||||
|
|
||||||
|
// std::cout << "Chunk at (" << cx << ", " << cy << ", " << cz << ") received" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientChunk *ClientWorld::getChunk(int cx, int cy, int cz) const {
|
Chunk *ClientWorld::getChunk(int cx, int cy, int cz) const {
|
||||||
auto it = m_chunks.find({cx, cy, cz});
|
auto it = m_chunks.find({cx, cy, cz});
|
||||||
if (it == m_chunks.end())
|
if (it == m_chunks.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -76,42 +79,6 @@ ClientChunk *ClientWorld::getChunk(int cx, int cy, int cz) const {
|
|||||||
return it->second.get();
|
return it->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockData *ClientWorld::getBlockData(int x, int y, int z) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
return chunk->getBlockData(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1));
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 ClientWorld::getBlock(int x, int y, int z) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
return chunk->getBlock(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientWorld::setBlock(int x, int y, int z, u16 id) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
chunk->setBlock(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1), id);
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 ClientWorld::getData(int x, int y, int z) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
return chunk->getData(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientWorld::setData(int x, int y, int z, u16 id) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
chunk->setBlock(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1), id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const {
|
void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const {
|
||||||
if (!target.getView()) {
|
if (!target.getView()) {
|
||||||
DEBUG("ERROR: Trying to draw world without a camera");
|
DEBUG("ERROR: Trying to draw world without a camera");
|
||||||
@ -122,11 +89,6 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
|||||||
states.shader->setUniform("u_renderDistance", Config::renderDistance * CHUNK_WIDTH);
|
states.shader->setUniform("u_renderDistance", Config::renderDistance * CHUNK_WIDTH);
|
||||||
gk::Shader::bind(nullptr);
|
gk::Shader::bind(nullptr);
|
||||||
|
|
||||||
float ud = 1000.0;
|
|
||||||
s32 ux = 0;
|
|
||||||
s32 uy = 0;
|
|
||||||
s32 uz = 0;
|
|
||||||
|
|
||||||
std::vector<std::pair<ClientChunk*, gk::Transform>> chunks;
|
std::vector<std::pair<ClientChunk*, gk::Transform>> chunks;
|
||||||
for(auto &it : m_chunks) {
|
for(auto &it : m_chunks) {
|
||||||
states.transform = glm::translate(glm::mat4(1.0f),
|
states.transform = glm::translate(glm::mat4(1.0f),
|
||||||
@ -139,6 +101,7 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
|||||||
* states.transform.getMatrix()
|
* states.transform.getMatrix()
|
||||||
* glm::vec4(CHUNK_WIDTH / 2, CHUNK_HEIGHT / 2, CHUNK_DEPTH / 2, 1);
|
* glm::vec4(CHUNK_WIDTH / 2, CHUNK_HEIGHT / 2, CHUNK_DEPTH / 2, 1);
|
||||||
|
|
||||||
|
// Nope, too far, don't render it
|
||||||
if(glm::length(center) > (Config::renderDistance + 1) * CHUNK_WIDTH) {
|
if(glm::length(center) > (Config::renderDistance + 1) * CHUNK_WIDTH) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -146,7 +109,7 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
|||||||
// Is this chunk on the screen?
|
// Is this chunk on the screen?
|
||||||
center = target.getView()->getTransform().getMatrix() * center;
|
center = target.getView()->getTransform().getMatrix() * center;
|
||||||
|
|
||||||
float d = glm::length(center);
|
// float d = glm::length(center);
|
||||||
center.x /= center.w;
|
center.x /= center.w;
|
||||||
center.y /= center.w;
|
center.y /= center.w;
|
||||||
|
|
||||||
@ -163,30 +126,12 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
|||||||
|
|
||||||
// If this chunk is not initialized, skip it
|
// If this chunk is not initialized, skip it
|
||||||
if(!it.second->isInitialized()) {
|
if(!it.second->isInitialized()) {
|
||||||
// But if it is the closest to the camera, mark it for initialization
|
|
||||||
if(d < ud) {
|
|
||||||
ud = d;
|
|
||||||
ux = it.second->x();
|
|
||||||
uy = it.second->y();
|
|
||||||
uz = it.second->z();
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
chunks.emplace_back(it.second.get(), states.transform);
|
chunks.emplace_back(it.second.get(), states.transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientChunk *chunk = getChunk(ux, uy, uz);
|
|
||||||
if(ud <= 1000 && (!chunk || !chunk->hasBeenRequested())) {
|
|
||||||
auto it = m_chunks.emplace(gk::Vector3i(ux, uy, uz), new ClientChunk(ux, uy, uz, m_texture));
|
|
||||||
it.first->second->setHasBeenRequested(true);
|
|
||||||
|
|
||||||
m_client->sendChunkRequest(ux, uy, uz);
|
|
||||||
|
|
||||||
DEBUG("Chunk requested at", ux, uy, uz);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u8 i = 0 ; i < ChunkBuilder::layers ; ++i) {
|
for (u8 i = 0 ; i < ChunkBuilder::layers ; ++i) {
|
||||||
for (auto &it : chunks) {
|
for (auto &it : chunks) {
|
||||||
states.transform = it.second;
|
states.transform = it.second;
|
||||||
|
@ -22,12 +22,13 @@ class World {
|
|||||||
public:
|
public:
|
||||||
virtual ~World() = default;
|
virtual ~World() = default;
|
||||||
|
|
||||||
virtual BlockData *getBlockData(int x, int y, int z) const = 0;
|
virtual Chunk *getChunk(int cx, int cy, int cz) const = 0;
|
||||||
|
BlockData *getBlockData(int x, int y, int z) const;
|
||||||
|
|
||||||
virtual u16 getBlock(int x, int y, int z) const = 0;
|
u16 getBlock(int x, int y, int z) const;
|
||||||
virtual void setBlock(int x, int y, int z, u16 id) const = 0;
|
void setBlock(int x, int y, int z, u16 id) const;
|
||||||
virtual u16 getData(int x, int y, int z) const = 0;
|
u16 getData(int x, int y, int z) const;
|
||||||
virtual void setData(int x, int y, int z, u16 id) const = 0;
|
void setData(int x, int y, int z, u16 id) const;
|
||||||
|
|
||||||
static bool isReloadRequested;
|
static bool isReloadRequested;
|
||||||
};
|
};
|
||||||
|
@ -20,3 +20,38 @@
|
|||||||
|
|
||||||
bool World::isReloadRequested = false;
|
bool World::isReloadRequested = false;
|
||||||
|
|
||||||
|
BlockData *World::getBlockData(int x, int y, int z) const {
|
||||||
|
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
||||||
|
if (chunk)
|
||||||
|
return chunk->getBlockData(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1));
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 World::getBlock(int x, int y, int z) const {
|
||||||
|
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
||||||
|
if (chunk)
|
||||||
|
return chunk->getBlock(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::setBlock(int x, int y, int z, u16 id) const {
|
||||||
|
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
||||||
|
if (chunk)
|
||||||
|
chunk->setBlock(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1), id);
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 World::getData(int x, int y, int z) const {
|
||||||
|
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
||||||
|
if (chunk)
|
||||||
|
return chunk->getData(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void World::setData(int x, int y, int z, u16 id) const {
|
||||||
|
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
||||||
|
if (chunk)
|
||||||
|
chunk->setBlock(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1), id);
|
||||||
|
}
|
||||||
|
@ -29,18 +29,11 @@ class ServerWorld : public World {
|
|||||||
|
|
||||||
void update(Server &server, std::unordered_map<u16, ServerPlayer> &players);
|
void update(Server &server, std::unordered_map<u16, ServerPlayer> &players);
|
||||||
|
|
||||||
|
void sendSpawnData(Client &client, ServerPlayer &player);
|
||||||
void sendChunkData(Client &client, ServerChunk *chunk);
|
void sendChunkData(Client &client, ServerChunk *chunk);
|
||||||
void sendRequestedData(Client &client, int cx, int cy, int cz);
|
void sendRequestedData(Client &client, int cx, int cy, int cz);
|
||||||
|
|
||||||
// FIXME: Duplicated with ClientWorld
|
Chunk *getChunk(int cx, int cy, int cz) const override;
|
||||||
ServerChunk *getChunk(int cx, int cy, int cz) const;
|
|
||||||
BlockData *getBlockData(int x, int y, int z) const override;
|
|
||||||
|
|
||||||
// FIXME: Duplicated with ClientWorld
|
|
||||||
u16 getBlock(int x, int y, int z) const override;
|
|
||||||
void setBlock(int x, int y, int z, u16 id) const override;
|
|
||||||
u16 getData(int x, int y, int z) const override;
|
|
||||||
void setData(int x, int y, int z, u16 id) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<gk::Vector3i, std::unique_ptr<ServerChunk>> m_chunks;
|
std::unordered_map<gk::Vector3i, std::unique_ptr<ServerChunk>> m_chunks;
|
||||||
|
@ -53,11 +53,12 @@ void ServerCommandHandler::setupCallbacks() {
|
|||||||
spawnPacket << m_spawnPosition.x << m_spawnPosition.y << m_spawnPosition.z;
|
spawnPacket << m_spawnPosition.x << m_spawnPosition.y << m_spawnPosition.z;
|
||||||
m_server.sendToAllClients(spawnPacket);
|
m_server.sendToAllClients(spawnPacket);
|
||||||
|
|
||||||
// m_world.sendWorldData(client); // FIXME
|
// FIXME: Temporarily useless
|
||||||
|
// sf::Packet worldSentPacket;
|
||||||
|
// worldSentPacket << Network::Command::WorldSent;
|
||||||
|
// client.tcpSocket->send(worldSentPacket);
|
||||||
|
|
||||||
sf::Packet worldSentPacket;
|
m_world.sendSpawnData(client, player);
|
||||||
worldSentPacket << Network::Command::WorldSent;
|
|
||||||
client.tcpSocket->send(worldSentPacket);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
m_server.setCommandCallback(Network::Command::ChunkRequest, [this](Client &client, sf::Packet &packet) {
|
m_server.setCommandCallback(Network::Command::ChunkRequest, [this](Client &client, sf::Packet &packet) {
|
||||||
|
@ -41,6 +41,68 @@ void ServerWorld::update(Server &server, std::unordered_map<u16, ServerPlayer> &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerWorld::sendSpawnData(Client &client, ServerPlayer &player) {
|
||||||
|
// Player chunk pos
|
||||||
|
int pcx = std::floor(player.x() / CHUNK_WIDTH);
|
||||||
|
int pcy = std::floor(player.y() / CHUNK_HEIGHT);
|
||||||
|
int pcz = std::floor(player.z() / CHUNK_DEPTH);
|
||||||
|
|
||||||
|
// Create a chunk at the current player position
|
||||||
|
auto it = m_chunks.emplace(gk::Vector3i{pcx, pcy, pcz}, new ServerChunk(pcx, pcy, pcz));
|
||||||
|
ServerChunk *chunk = it.first->second.get();
|
||||||
|
|
||||||
|
// Send the chunk to the client
|
||||||
|
sendChunkData(client, chunk);
|
||||||
|
|
||||||
|
// Load surrounding chunks, starting from the one we generated above
|
||||||
|
std::queue<ServerChunk *> chunks;
|
||||||
|
chunks.emplace(chunk);
|
||||||
|
while (!chunks.empty()) {
|
||||||
|
ServerChunk *chunk = chunks.front();
|
||||||
|
chunks.pop();
|
||||||
|
|
||||||
|
gk::Vector3i surroundingChunks[6] = {
|
||||||
|
{chunk->x() - 1, chunk->y(), chunk->z()},
|
||||||
|
{chunk->x() + 1, chunk->y(), chunk->z()},
|
||||||
|
{chunk->x(), chunk->y(), chunk->z() - 1},
|
||||||
|
{chunk->x(), chunk->y(), chunk->z() + 1},
|
||||||
|
{chunk->x(), chunk->y() - 1, chunk->z()},
|
||||||
|
{chunk->x(), chunk->y() + 1, chunk->z()},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (u8 i = 0 ; i < 6 ; ++i) {
|
||||||
|
// Create our neighbour
|
||||||
|
auto it = m_chunks.emplace(
|
||||||
|
gk::Vector3i{
|
||||||
|
surroundingChunks[i].x,
|
||||||
|
surroundingChunks[i].y,
|
||||||
|
surroundingChunks[i].z
|
||||||
|
},
|
||||||
|
new ServerChunk{
|
||||||
|
surroundingChunks[i].x,
|
||||||
|
surroundingChunks[i].y,
|
||||||
|
surroundingChunks[i].z
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assign surrounding chunk pointers
|
||||||
|
ServerChunk *neighbour = it.first->second.get();
|
||||||
|
chunk->setSurroundingChunk(i, neighbour);
|
||||||
|
neighbour->setSurroundingChunk((i % 2 == 0) ? i + 1 : i - 1, chunk);
|
||||||
|
|
||||||
|
// Compute distance to player chunk
|
||||||
|
int dx = std::abs(surroundingChunks[i].x - pcx);
|
||||||
|
int dy = std::abs(surroundingChunks[i].y - pcy);
|
||||||
|
int dz = std::abs(surroundingChunks[i].z - pcz);
|
||||||
|
int distance = std::max(dx, std::max(dy, dz));
|
||||||
|
|
||||||
|
// If the chunk is close enough, add it to the queue
|
||||||
|
if (distance < Config::renderDistance)
|
||||||
|
chunks.emplace(neighbour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ServerWorld::sendChunkData(Client &client, ServerChunk *chunk) {
|
void ServerWorld::sendChunkData(Client &client, ServerChunk *chunk) {
|
||||||
if (!chunk) return;
|
if (!chunk) return;
|
||||||
|
|
||||||
@ -69,16 +131,16 @@ void ServerWorld::sendChunkData(Client &client, ServerChunk *chunk) {
|
|||||||
void ServerWorld::sendRequestedData(Client &client, int cx, int cy, int cz) {
|
void ServerWorld::sendRequestedData(Client &client, int cx, int cy, int cz) {
|
||||||
std::cout << "Chunk at (" << cx << ", " << cy << ", " << cz << ") requested" << std::endl;
|
std::cout << "Chunk at (" << cx << ", " << cy << ", " << cz << ") requested" << std::endl;
|
||||||
|
|
||||||
ServerChunk *chunk = getChunk(cx, cy, cz);
|
Chunk *chunk = getChunk(cx, cy, cz);
|
||||||
if (!chunk) {
|
if (!chunk) {
|
||||||
auto it = m_chunks.emplace(gk::Vector3i(cx, cy, cz), new ServerChunk(cx, cy, cz));
|
auto it = m_chunks.emplace(gk::Vector3i(cx, cy, cz), new ServerChunk(cx, cy, cz));
|
||||||
chunk = it.first->second.get();
|
chunk = it.first->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
sendChunkData(client, chunk);
|
sendChunkData(client, (ServerChunk *)chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerChunk *ServerWorld::getChunk(int cx, int cy, int cz) const {
|
Chunk *ServerWorld::getChunk(int cx, int cy, int cz) const {
|
||||||
auto it = m_chunks.find({cx, cy, cz});
|
auto it = m_chunks.find({cx, cy, cz});
|
||||||
if (it == m_chunks.end())
|
if (it == m_chunks.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -86,39 +148,3 @@ ServerChunk *ServerWorld::getChunk(int cx, int cy, int cz) const {
|
|||||||
return it->second.get();
|
return it->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockData *ServerWorld::getBlockData(int x, int y, int z) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
return chunk->getBlockData(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1));
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 ServerWorld::getBlock(int x, int y, int z) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
return chunk->getBlock(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerWorld::setBlock(int x, int y, int z, u16 id) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
chunk->setBlock(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1), id);
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 ServerWorld::getData(int x, int y, int z) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
return chunk->getData(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerWorld::setData(int x, int y, int z, u16 id) const {
|
|
||||||
Chunk *chunk = getChunk(x / CHUNK_WIDTH, y / CHUNK_HEIGHT, z / CHUNK_DEPTH);
|
|
||||||
if (chunk)
|
|
||||||
chunk->setBlock(x & (CHUNK_WIDTH - 1), y & (CHUNK_HEIGHT - 1), z & (CHUNK_DEPTH - 1), id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user