From 13f27a605fc55bee0b321335013ff6e2541d35ba Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Wed, 15 May 2024 20:51:34 +0200 Subject: [PATCH] Update neighbor block state on the server. fixes #354 --- src/network.zig | 6 +----- src/server/world.zig | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/network.zig b/src/network.zig index a171c87a..6106d21f 100644 --- a/src/network.zig +++ b/src/network.zig @@ -818,11 +818,7 @@ pub const Protocols = struct { const z = std.mem.readInt(i32, data[8..12], .big); const newBlock = Block.fromInt(std.mem.readInt(u32, data[12..16], .big)); if(conn.user != null) { // TODO: Send update event to other players. - const mask = ~@as(i32, chunk.chunkMask); - const ch = main.server.world.?.getOrGenerateChunk(.{.wx = x & mask, .wy = y & mask, .wz = z & mask, .voxelSize = 1}); - ch.mutex.lock(); - defer ch.mutex.unlock(); - ch.updateBlockAndSetChanged(x & chunk.chunkMask, y & chunk.chunkMask, z & chunk.chunkMask, newBlock); + main.server.world.?.updateBlock(x, y, z, newBlock); } else { renderer.mesh_storage.updateBlock(x, y, z, newBlock); } diff --git a/src/server/world.zig b/src/server/world.zig index 72cc6a26..6548117d 100644 --- a/src/server/world.zig +++ b/src/server/world.zig @@ -542,6 +542,42 @@ pub const ServerWorld = struct { return Block {.typ = 0, .data = 0}; } + pub fn updateBlock(_: *ServerWorld, wx: i32, wy: i32, wz: i32, _newBlock: Block) void { + const baseChunk = ChunkManager.getOrGenerateChunk(.{.wx = wx & ~@as(i32, chunk.chunkMask), .wy = wy & ~@as(i32, chunk.chunkMask), .wz = wz & ~@as(i32, chunk.chunkMask), .voxelSize = 1}); + const x: u5 = @intCast(wx & chunk.chunkMask); + const y: u5 = @intCast(wy & chunk.chunkMask); + const z: u5 = @intCast(wz & chunk.chunkMask); + var newBlock = _newBlock; + for(chunk.Neighbors.iterable) |neighbor| { + const nx = x + chunk.Neighbors.relX[neighbor]; + const ny = y + chunk.Neighbors.relY[neighbor]; + const nz = z + chunk.Neighbors.relZ[neighbor]; + var ch = baseChunk; + if(nx & chunk.chunkMask != nx or ny & chunk.chunkMask != ny or nz & chunk.chunkMask != nz) { + ch = ChunkManager.getOrGenerateChunk(.{ + .wx = baseChunk.pos.wx + nx, + .wy = baseChunk.pos.wy + ny, + .wz = baseChunk.pos.wz + nz, + .voxelSize = 1, + }); + } + ch.mutex.lock(); + defer ch.mutex.unlock(); + var neighborBlock = ch.getBlock(nx & chunk.chunkMask, ny & chunk.chunkMask, nz & chunk.chunkMask); + if(neighborBlock.mode().dependsOnNeighbors) { + if(neighborBlock.mode().updateData(&neighborBlock, neighbor ^ 1, newBlock)) { + ch.updateBlockAndSetChanged(nx & chunk.chunkMask, ny & chunk.chunkMask, nz & chunk.chunkMask, neighborBlock); + } + } + if(newBlock.mode().dependsOnNeighbors) { + _ = newBlock.mode().updateData(&newBlock, neighbor, neighborBlock); + } + } + baseChunk.mutex.lock(); + defer baseChunk.mutex.unlock(); + baseChunk.updateBlock(x, y, z, newBlock); + } + pub fn queueChunkUpdate(self: *ServerWorld, ch: *Chunk) void { self.mutex.lock(); self.chunkUpdateQueue.enqueue(.{.ch = ch, .milliTimeStamp = std.time.milliTimestamp()});