diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index bb816c37..4100e7b2 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -171,6 +171,9 @@ const Mesh* ChunksRenderer::retrieveChunk( if (mesh == nullptr) { return nullptr; } + if (chunk->flags.dirtyHeights) { + chunk->updateHeights(); + } if (culling) { glm::vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D); glm::vec3 max( diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index eb699bc5..52e2931c 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -101,12 +101,9 @@ static int l_set(lua::State* L) { if (static_cast(id) >= indices->blocks.count()) { return 0; } - int cx = floordiv(x); - int cz = floordiv(z); - if (!blocks_agent::get_chunk(*level->chunks, cx, cz)) { + if (!blocks_agent::set(*level->chunks, x, y, z, id, int2blockstate(state))) { return 0; } - blocks_agent::set(*level->chunks, x, y, z, id, int2blockstate(state)); auto chunksController = controller->getChunksController(); if (chunksController == nullptr) { diff --git a/src/voxels/Chunk.cpp b/src/voxels/Chunk.cpp index 2c1f4fd8..e6da850e 100644 --- a/src/voxels/Chunk.cpp +++ b/src/voxels/Chunk.cpp @@ -14,6 +14,7 @@ Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos) { } void Chunk::updateHeights() { + flags.dirtyHeights = false; for (uint i = 0; i < CHUNK_VOL; i++) { if (voxels[i].id != 0) { bottom = i / (CHUNK_D * CHUNK_W); diff --git a/src/voxels/Chunk.hpp b/src/voxels/Chunk.hpp index 3ce6e641..a15907f0 100644 --- a/src/voxels/Chunk.hpp +++ b/src/voxels/Chunk.hpp @@ -37,6 +37,7 @@ public: bool loadedLights : 1; bool entities : 1; bool blocksData : 1; + bool dirtyHeights : 1; } flags {}; /// @brief Block inventories map where key is index of block in voxels array diff --git a/src/voxels/blocks_agent.cpp b/src/voxels/blocks_agent.cpp index a23fa9ef..d56b1838 100644 --- a/src/voxels/blocks_agent.cpp +++ b/src/voxels/blocks_agent.cpp @@ -7,7 +7,7 @@ using namespace blocks_agent; template -static inline void set_block( +static inline bool set_block( Storage& chunks, int32_t x, int32_t y, @@ -16,14 +16,14 @@ static inline void set_block( blockstate state ) { if (y < 0 || y >= CHUNK_H) { - return; + return false; } const auto& indices = chunks.getContentIndices(); int cx = floordiv(x); int cz = floordiv(z); Chunk* chunk = get_chunk(chunks, cx, cz); if (chunk == nullptr) { - return; + return false; } int lx = x - cx * CHUNK_W; int lz = z - cz * CHUNK_D; @@ -60,7 +60,8 @@ static inline void set_block( else if (y + 1 > chunk->top) chunk->top = y + 1; else if (id == 0) - chunk->updateHeights(); + chunk->flags.dirtyHeights = true; + if (lx == 0 && (chunk = get_chunk(chunks, cx - 1, cz))) { chunk->flags.modified = true; @@ -74,9 +75,10 @@ static inline void set_block( if (lz == CHUNK_D - 1 && (chunk = get_chunk(chunks, cx, cz + 1))) { chunk->flags.modified = true; } + return true; } -void blocks_agent::set( +bool blocks_agent::set( Chunks& chunks, int32_t x, int32_t y, @@ -84,10 +86,10 @@ void blocks_agent::set( uint32_t id, blockstate state ) { - set_block(chunks, x, y, z, id, state); + return set_block(chunks, x, y, z, id, state); } -void blocks_agent::set( +bool blocks_agent::set( GlobalChunks& chunks, int32_t x, int32_t y, @@ -95,7 +97,7 @@ void blocks_agent::set( uint32_t id, blockstate state ) { - set_block(chunks, x, y, z, id, state); + return set_block(chunks, x, y, z, id, state); } template diff --git a/src/voxels/blocks_agent.hpp b/src/voxels/blocks_agent.hpp index 34fde035..efecf4e3 100644 --- a/src/voxels/blocks_agent.hpp +++ b/src/voxels/blocks_agent.hpp @@ -119,7 +119,7 @@ inline bool is_replaceable_at(const Storage& chunks, int32_t x, int32_t y, int32 /// @param z block position Z /// @param id new block id /// @param state new block state -void set( +bool set( Chunks& chunks, int32_t x, int32_t y, @@ -135,7 +135,7 @@ void set( /// @param z block position Z /// @param id new block id /// @param state new block state -void set( +bool set( GlobalChunks& chunks, int32_t x, int32_t y,