diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index f7fb4209..20d3253d 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -68,18 +68,18 @@ static int l_is_segment(lua::State* L) { auto x = lua::tointeger(L, 1); auto y = lua::tointeger(L, 2); auto z = lua::tointeger(L, 3); - auto vox = level->chunks->get(x, y, z); - return lua::pushboolean(L, vox->state.segment); + const auto& vox = level->chunks->require(x, y, z); + return lua::pushboolean(L, vox.state.segment); } static int l_seek_origin(lua::State* L) { auto x = lua::tointeger(L, 1); auto y = lua::tointeger(L, 2); auto z = lua::tointeger(L, 3); - auto vox = level->chunks->get(x, y, z); - auto& def = indices->blocks.require(vox->id); + const auto& vox = level->chunks->require(x, y, z); + auto& def = indices->blocks.require(vox.id); return lua::pushivec_stack( - L, level->chunks->seekOrigin({x, y, z}, def, vox->state) + L, level->chunks->seekOrigin({x, y, z}, def, vox.state) ); } @@ -223,6 +223,9 @@ static int l_get_user_bits(lua::State* L) { if (def.rt.extended) { auto origin = level->chunks->seekOrigin({x, y, z}, def, vox->state); vox = level->chunks->get(origin.x, origin.y, origin.z); + if (vox == nullptr) { + return lua::pushinteger(L, 0); + } } uint mask = ((1 << bits) - 1) << offset; uint data = (blockstate2int(vox->state) & mask) >> offset; @@ -251,6 +254,9 @@ static int l_set_user_bits(lua::State* L) { if (def.rt.extended) { auto origin = level->chunks->seekOrigin({x, y, z}, def, vox->state); vox = level->chunks->get(origin); + if (vox == nullptr) { + return 0; + } } vox->state.userbits = (vox->state.userbits & (~mask)) | value; chunk->setModifiedAndUnsaved(); @@ -487,7 +493,6 @@ static int l_get_field(lua::State* L) { if (lua::gettop(L) >= 5) { index = lua::tointeger(L, 5); } - auto vox = level->chunks->get(x, y, z); auto cx = floordiv(x, CHUNK_W); auto cz = floordiv(z, CHUNK_D); auto chunk = level->chunks->getChunk(cx, cz); @@ -495,7 +500,8 @@ static int l_get_field(lua::State* L) { auto lz = z - cz * CHUNK_W; size_t voxelIndex = vox_index(lx, y, lz); - const auto& def = content->getIndices()->blocks.require(vox->id); + const auto& vox = level->chunks->require(x, y, z); + const auto& def = content->getIndices()->blocks.require(vox.id); if (def.dataStruct == nullptr) { return 0; } diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index 53c436f3..5937a38e 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "data/StructLayout.hpp" @@ -61,6 +62,14 @@ voxel* Chunks::get(int32_t x, int32_t y, int32_t z) const { return &chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx]; } +voxel& Chunks::require(int32_t x, int32_t y, int32_t z) const { + auto voxel = get(x, y, z); + if (voxel == nullptr) { + throw std::runtime_error("voxel does not exist"); + } + return *voxel; +} + const AABB* Chunks::isObstacleAt(float x, float y, float z) const { int ix = std::floor(x); int iy = std::floor(y); @@ -243,7 +252,10 @@ void Chunks::repairSegments( } bool Chunks::checkReplaceability( - const Block& def, blockstate state, glm::ivec3 origin, blockid_t ignore + const Block& def, + blockstate state, + const glm::ivec3& origin, + blockid_t ignore ) { const auto& rotation = def.rotations.variants[state.rotation]; const auto size = def.size; @@ -269,7 +281,7 @@ bool Chunks::checkReplaceability( } void Chunks::setRotationExtended( - const Block& def, blockstate state, glm::ivec3 origin, uint8_t index + const Block& def, blockstate state, const glm::ivec3& origin, uint8_t index ) { auto newstate = state; newstate.rotation = index; @@ -418,8 +430,8 @@ void Chunks::set( } voxel* Chunks::rayCast( - glm::vec3 start, - glm::vec3 dir, + const glm::vec3& start, + const glm::vec3& dir, float maxDist, glm::vec3& end, glm::ivec3& norm, @@ -557,7 +569,7 @@ voxel* Chunks::rayCast( } glm::vec3 Chunks::rayCastToObstacle( - glm::vec3 start, glm::vec3 dir, float maxDist + const glm::vec3& start, const glm::vec3& dir, float maxDist ) { const float px = start.x; const float py = start.y; diff --git a/src/voxels/Chunks.hpp b/src/voxels/Chunks.hpp index 67746199..fed09f1d 100644 --- a/src/voxels/Chunks.hpp +++ b/src/voxels/Chunks.hpp @@ -32,7 +32,10 @@ class Chunks { const Block& def, blockstate state, int x, int y, int z ); void setRotationExtended( - const Block& def, blockstate state, glm::ivec3 origin, uint8_t rotation + const Block& def, + blockstate state, + const glm::ivec3& origin, + uint8_t rotation ); util::AreaMap2D, int32_t> areaMap; @@ -55,12 +58,13 @@ public: Chunk* getChunk(int32_t x, int32_t z); Chunk* getChunkByVoxel(int32_t x, int32_t y, int32_t z); voxel* get(int32_t x, int32_t y, int32_t z) const; + voxel& require(int32_t x, int32_t y, int32_t z) const; - inline voxel* get(glm::ivec3 pos) { + inline voxel* get(const glm::ivec3& pos) { return get(pos.x, pos.y, pos.z); } - inline const voxel* get(glm::ivec3 pos) const { + inline const voxel* get(const glm::ivec3& pos) const { return get(pos.x, pos.y, pos.z); } @@ -85,15 +89,15 @@ public: bool checkReplaceability( const Block& def, blockstate state, - glm::ivec3 coord, + const glm::ivec3& coord, blockid_t ignore = 0 ); void setRotation(int32_t x, int32_t y, int32_t z, uint8_t rotation); voxel* rayCast( - glm::vec3 start, - glm::vec3 dir, + const glm::vec3& start, + const glm::vec3& dir, float maxLength, glm::vec3& end, glm::ivec3& norm, @@ -101,7 +105,9 @@ public: std::set filter = {} ); - glm::vec3 rayCastToObstacle(glm::vec3 start, glm::vec3 dir, float maxDist); + glm::vec3 rayCastToObstacle( + const glm::vec3& start, const glm::vec3& dir, float maxDist + ); const AABB* isObstacleAt(float x, float y, float z) const;