add block.get_field(...), block.set_field(...)
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
#include "util/stringutil.hpp"
|
#include "util/stringutil.hpp"
|
||||||
#include "voxels/Block.hpp"
|
#include "voxels/Block.hpp"
|
||||||
#include "data/dv_util.hpp"
|
#include "data/dv_util.hpp"
|
||||||
|
#include "data/StructLayout.hpp"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
@@ -250,6 +251,12 @@ void ContentLoader::loadBlock(
|
|||||||
root.at("ui-layout").get(def.uiLayout);
|
root.at("ui-layout").get(def.uiLayout);
|
||||||
root.at("inventory-size").get(def.inventorySize);
|
root.at("inventory-size").get(def.inventorySize);
|
||||||
root.at("tick-interval").get(def.tickInterval);
|
root.at("tick-interval").get(def.tickInterval);
|
||||||
|
|
||||||
|
if (root.has("fields")) {
|
||||||
|
def.dataStruct = std::make_unique<data::StructLayout>();
|
||||||
|
def.dataStruct->deserialize(root["fields"]);
|
||||||
|
}
|
||||||
|
|
||||||
if (def.tickInterval == 0) {
|
if (def.tickInterval == 0) {
|
||||||
def.tickInterval = 1;
|
def.tickInterval = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-16
@@ -183,7 +183,7 @@ std::vector<FieldIncapatibility> StructLayout::checkCompatibility(
|
|||||||
return report;
|
return report;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Field& StructLayout::requreField(const std::string& name) const {
|
const Field& StructLayout::requireField(const std::string& name) const {
|
||||||
auto found = indices.find(name);
|
auto found = indices.find(name);
|
||||||
if (found == indices.end()) {
|
if (found == indices.end()) {
|
||||||
throw std::runtime_error("field '"+name+"' does not exist");
|
throw std::runtime_error("field '"+name+"' does not exist");
|
||||||
@@ -200,9 +200,8 @@ static void set_int(ubyte* dst, integer_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StructLayout::setInteger(
|
void StructLayout::setInteger(
|
||||||
ubyte* dst, integer_t value, const std::string& name, int index
|
ubyte* dst, integer_t value, const Field& field, int index
|
||||||
) const {
|
) const {
|
||||||
const auto& field = requreField(name);
|
|
||||||
if (index < 0 || index >= field.elements) {
|
if (index < 0 || index >= field.elements) {
|
||||||
throw std::out_of_range(
|
throw std::out_of_range(
|
||||||
"index out of bounds [0, "+std::to_string(field.elements)+"]");
|
"index out of bounds [0, "+std::to_string(field.elements)+"]");
|
||||||
@@ -216,7 +215,7 @@ void StructLayout::setInteger(
|
|||||||
case FieldType::CHAR: set_int<int8_t>(ptr, value); break;
|
case FieldType::CHAR: set_int<int8_t>(ptr, value); break;
|
||||||
case FieldType::F32:
|
case FieldType::F32:
|
||||||
case FieldType::F64:
|
case FieldType::F64:
|
||||||
setNumber(dst, static_cast<number_t>(value), name, index);
|
setNumber(dst, static_cast<number_t>(value), field, index);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("type error");
|
throw std::runtime_error("type error");
|
||||||
@@ -224,9 +223,8 @@ void StructLayout::setInteger(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StructLayout::setNumber(
|
void StructLayout::setNumber(
|
||||||
ubyte* dst, number_t value, const std::string& name, int index
|
ubyte* dst, number_t value, const Field& field, int index
|
||||||
) const {
|
) const {
|
||||||
const auto& field = requreField(name);
|
|
||||||
if (index < 0 || index >= field.elements) {
|
if (index < 0 || index >= field.elements) {
|
||||||
throw std::out_of_range(
|
throw std::out_of_range(
|
||||||
"index out of bounds [0, "+std::to_string(field.elements)+"]");
|
"index out of bounds [0, "+std::to_string(field.elements)+"]");
|
||||||
@@ -255,7 +253,7 @@ void StructLayout::setNumber(
|
|||||||
size_t StructLayout::setAscii(
|
size_t StructLayout::setAscii(
|
||||||
ubyte* dst, std::string_view value, const std::string& name
|
ubyte* dst, std::string_view value, const std::string& name
|
||||||
) const {
|
) const {
|
||||||
const auto& field = requreField(name);
|
const auto& field = requireField(name);
|
||||||
if (field.type != FieldType::CHAR) {
|
if (field.type != FieldType::CHAR) {
|
||||||
throw std::runtime_error("'char' field type required");
|
throw std::runtime_error("'char' field type required");
|
||||||
}
|
}
|
||||||
@@ -266,9 +264,8 @@ size_t StructLayout::setAscii(
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t StructLayout::setUnicode(
|
size_t StructLayout::setUnicode(
|
||||||
ubyte* dst, std::string_view value, const std::string& name
|
ubyte* dst, std::string_view value, const Field& field
|
||||||
) const {
|
) const {
|
||||||
const auto& field = requreField(name);
|
|
||||||
if (field.type != FieldType::CHAR) {
|
if (field.type != FieldType::CHAR) {
|
||||||
throw std::runtime_error("'char' field type required");
|
throw std::runtime_error("'char' field type required");
|
||||||
}
|
}
|
||||||
@@ -285,9 +282,8 @@ static T get_int(const ubyte* src) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
integer_t StructLayout::getInteger(
|
integer_t StructLayout::getInteger(
|
||||||
const ubyte* src, const std::string& name, int index
|
const ubyte* src, const Field& field, int index
|
||||||
) const {
|
) const {
|
||||||
const auto& field = requreField(name);
|
|
||||||
if (index < 0 || index >= field.elements) {
|
if (index < 0 || index >= field.elements) {
|
||||||
throw std::out_of_range(
|
throw std::out_of_range(
|
||||||
"index out of bounds [0, "+std::to_string(field.elements)+"]");
|
"index out of bounds [0, "+std::to_string(field.elements)+"]");
|
||||||
@@ -305,9 +301,8 @@ integer_t StructLayout::getInteger(
|
|||||||
}
|
}
|
||||||
|
|
||||||
number_t StructLayout::getNumber(
|
number_t StructLayout::getNumber(
|
||||||
const ubyte* src, const std::string& name, int index
|
const ubyte* src, const Field& field, int index
|
||||||
) const {
|
) const {
|
||||||
const auto& field = requreField(name);
|
|
||||||
if (index < 0 || index >= field.elements) {
|
if (index < 0 || index >= field.elements) {
|
||||||
throw std::out_of_range(
|
throw std::out_of_range(
|
||||||
"index out of bounds [0, "+std::to_string(field.elements)+"]");
|
"index out of bounds [0, "+std::to_string(field.elements)+"]");
|
||||||
@@ -331,16 +326,15 @@ number_t StructLayout::getNumber(
|
|||||||
case FieldType::I32:
|
case FieldType::I32:
|
||||||
case FieldType::I64:
|
case FieldType::I64:
|
||||||
case FieldType::CHAR:
|
case FieldType::CHAR:
|
||||||
return getInteger(src, name, index);
|
return getInteger(src, field, index);
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("type error");
|
throw std::runtime_error("type error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view StructLayout::getChars(
|
std::string_view StructLayout::getChars(
|
||||||
const ubyte* src, const std::string& name
|
const ubyte* src, const Field& field
|
||||||
) const {
|
) const {
|
||||||
const auto& field = requreField(name);
|
|
||||||
if (field.type != FieldType::CHAR) {
|
if (field.type != FieldType::CHAR) {
|
||||||
throw std::runtime_error("'char' field type required");
|
throw std::runtime_error("'char' field type required");
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-12
@@ -129,35 +129,54 @@ namespace data {
|
|||||||
/// @throws std::runtime_exception - field not found
|
/// @throws std::runtime_exception - field not found
|
||||||
/// @param name field name
|
/// @param name field name
|
||||||
/// @return read-only field reference
|
/// @return read-only field reference
|
||||||
const Field& requreField(const std::string& name) const;
|
const Field& requireField(const std::string& name) const;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
integer_t getInteger(const ubyte* src, const std::string& name, int index=0) const {
|
||||||
|
return getInteger(src, requireField(name), index);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Get integer from specified field.
|
/// @brief Get integer from specified field.
|
||||||
/// Types: (i8, i16, i32, i64, char)
|
/// Types: (i8, i16, i32, i64, char)
|
||||||
/// @throws std::runtime_exception - field not found
|
/// @throws std::runtime_exception - field not found
|
||||||
/// @throws std::out_of_range - index is out of range [0, elements-1]
|
/// @throws std::out_of_range - index is out of range [0, elements-1]
|
||||||
/// @param src source buffer
|
/// @param src source buffer
|
||||||
/// @param name field name
|
/// @param field target field
|
||||||
/// @param index array index
|
/// @param index array index
|
||||||
/// @return field value
|
/// @return field value
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
integer_t getInteger(const ubyte* src, const std::string& name, int index=0) const;
|
integer_t getInteger(const ubyte* src, const Field& field, int index=0) const;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
number_t getNumber(const ubyte* src, const std::string& name, int index=0) const {
|
||||||
|
return getNumber(src, requireField(name), index);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Get floating-point number from specified field.
|
/// @brief Get floating-point number from specified field.
|
||||||
/// Types: (f32, f64, i8, i16, i32, i64, char)
|
/// Types: (f32, f64, i8, i16, i32, i64, char)
|
||||||
/// @throws std::runtime_exception - field not found
|
/// @throws std::runtime_exception - field not found
|
||||||
/// @throws std::out_of_range - index is out of range [0, elements-1]
|
/// @throws std::out_of_range - index is out of range [0, elements-1]
|
||||||
/// @param src source buffer
|
/// @param src source buffer
|
||||||
/// @param name field name
|
/// @param field target field
|
||||||
/// @param index array index
|
/// @param index array index
|
||||||
/// @return field value
|
/// @return field value
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
number_t getNumber(const ubyte* src, const std::string& name, int index=0) const;
|
number_t getNumber(const ubyte* src, const Field& field, int index=0) const;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
std::string_view getChars(const ubyte* src, const std::string& name) const {
|
||||||
|
return getChars(src, requireField(name));
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Get read-only chars array as string_view.
|
/// @brief Get read-only chars array as string_view.
|
||||||
/// @param src source buffer
|
/// @param src source buffer
|
||||||
/// @param name field name
|
/// @param field target field
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
std::string_view getChars(const ubyte* src, const std::string& name) const;
|
std::string_view getChars(const ubyte* src, const Field& field) const;
|
||||||
|
|
||||||
|
void setInteger(ubyte* dst, integer_t value, const std::string& name, int index=0) const {
|
||||||
|
setInteger(dst, value, requireField(name), index);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Set field integer value.
|
/// @brief Set field integer value.
|
||||||
/// Types: (i8, i16, i32, i64, f32, f64, char)
|
/// Types: (i8, i16, i32, i64, f32, f64, char)
|
||||||
@@ -165,9 +184,13 @@ namespace data {
|
|||||||
/// @throws std::out_of_range - index is out of range [0, elements-1]
|
/// @throws std::out_of_range - index is out of range [0, elements-1]
|
||||||
/// @param dst destination buffer
|
/// @param dst destination buffer
|
||||||
/// @param value value
|
/// @param value value
|
||||||
/// @param name field name
|
/// @param field target field
|
||||||
/// @param index array index
|
/// @param index array index
|
||||||
void setInteger(ubyte* dst, integer_t value, const std::string& name, int index=0) const;
|
void setInteger(ubyte* dst, integer_t value, const Field& field, int index=0) const;
|
||||||
|
|
||||||
|
void setNumber(ubyte* dst, number_t value, const std::string& name, int index=0) const {
|
||||||
|
setNumber(dst, value, requireField(name), index);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Set field numeric value.
|
/// @brief Set field numeric value.
|
||||||
/// Types: (f32, f64)
|
/// Types: (f32, f64)
|
||||||
@@ -175,9 +198,9 @@ namespace data {
|
|||||||
/// @throws std::out_of_range - index is out of range [0, elements-1]
|
/// @throws std::out_of_range - index is out of range [0, elements-1]
|
||||||
/// @param dst destination buffer
|
/// @param dst destination buffer
|
||||||
/// @param value value
|
/// @param value value
|
||||||
/// @param name field name
|
/// @param field target field
|
||||||
/// @param index array index
|
/// @param index array index
|
||||||
void setNumber(ubyte* dst, number_t value, const std::string& name, int index=0) const;
|
void setNumber(ubyte* dst, number_t value, const Field& field, int index=0) const;
|
||||||
|
|
||||||
/// @brief Replace chars array to given ASCII string
|
/// @brief Replace chars array to given ASCII string
|
||||||
/// @throws std::runtime_exception - field not found
|
/// @throws std::runtime_exception - field not found
|
||||||
@@ -188,13 +211,17 @@ namespace data {
|
|||||||
/// @return number of written string chars
|
/// @return number of written string chars
|
||||||
size_t setAscii(ubyte* dst, std::string_view value, const std::string& name) const;
|
size_t setAscii(ubyte* dst, std::string_view value, const std::string& name) const;
|
||||||
|
|
||||||
|
size_t setUnicode(ubyte* dst, std::string_view value, const std::string& name) const {
|
||||||
|
return setUnicode(dst, value, requireField(name));
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Unicode-safe version of setAscii
|
/// @brief Unicode-safe version of setAscii
|
||||||
/// @throws std::runtime_exception - field not found
|
/// @throws std::runtime_exception - field not found
|
||||||
/// @param dst destination buffer
|
/// @param dst destination buffer
|
||||||
/// @param value utf-8 string
|
/// @param value utf-8 string
|
||||||
/// @param name field name
|
/// @param name field name
|
||||||
/// @return number of written string chars
|
/// @return number of written string chars
|
||||||
size_t setUnicode(ubyte* dst, std::string_view value, const std::string& name) const;
|
size_t setUnicode(ubyte* dst, std::string_view value, const Field& field) const;
|
||||||
|
|
||||||
/// @return total structure size (bytes)
|
/// @return total structure size (bytes)
|
||||||
[[nodiscard]] size_t size() const {
|
[[nodiscard]] size_t size() const {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include "voxels/Chunks.hpp"
|
#include "voxels/Chunks.hpp"
|
||||||
#include "voxels/voxel.hpp"
|
#include "voxels/voxel.hpp"
|
||||||
#include "world/Level.hpp"
|
#include "world/Level.hpp"
|
||||||
|
#include "maths/voxmaths.hpp"
|
||||||
|
#include "data/StructLayout.hpp"
|
||||||
#include "api_lua.hpp"
|
#include "api_lua.hpp"
|
||||||
|
|
||||||
using namespace scripting;
|
using namespace scripting;
|
||||||
@@ -436,6 +438,107 @@ static int l_decompose_state(lua::State* L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_get_field(lua::State* L) {
|
||||||
|
auto x = lua::tointeger(L, 1);
|
||||||
|
auto y = lua::tointeger(L, 2);
|
||||||
|
auto z = lua::tointeger(L, 3);
|
||||||
|
auto name = lua::require_string(L, 4);
|
||||||
|
size_t index = 0;
|
||||||
|
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);
|
||||||
|
auto lx = x - cx * CHUNK_W;
|
||||||
|
auto lz = z - cz * CHUNK_W;
|
||||||
|
size_t voxelIndex = vox_index(lx, y, lz);
|
||||||
|
|
||||||
|
const auto& def = content->getIndices()->blocks.require(vox->id);
|
||||||
|
if (def.dataStruct == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const auto& dataStruct = *def.dataStruct;
|
||||||
|
const auto field = dataStruct.getField(name);
|
||||||
|
if (field == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const ubyte* src = chunk->blocksMetadata.find(voxelIndex);
|
||||||
|
if (src == nullptr) {
|
||||||
|
throw std::runtime_error("block data is not allocated");
|
||||||
|
}
|
||||||
|
switch (field->type) {
|
||||||
|
case data::FieldType::I8:
|
||||||
|
case data::FieldType::I16:
|
||||||
|
case data::FieldType::I32:
|
||||||
|
case data::FieldType::I64:
|
||||||
|
return lua::pushinteger(L, dataStruct.getInteger(src, *field, index));
|
||||||
|
case data::FieldType::F32:
|
||||||
|
case data::FieldType::F64:
|
||||||
|
return lua::pushnumber(L, dataStruct.getNumber(src, *field, index));
|
||||||
|
case data::FieldType::CHAR:
|
||||||
|
return lua::pushstring(L,
|
||||||
|
std::string(dataStruct.getChars(src, *field)).c_str());
|
||||||
|
case data::FieldType::COUNT:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_set_field(lua::State* L) {
|
||||||
|
auto x = lua::tointeger(L, 1);
|
||||||
|
auto y = lua::tointeger(L, 2);
|
||||||
|
auto z = lua::tointeger(L, 3);
|
||||||
|
auto name = lua::require_string(L, 4);
|
||||||
|
auto value = lua::tovalue(L, 5);
|
||||||
|
size_t index = 0;
|
||||||
|
if (lua::gettop(L) >= 6) {
|
||||||
|
index = lua::tointeger(L, 6);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
auto lx = x - cx * CHUNK_W;
|
||||||
|
auto lz = z - cz * CHUNK_W;
|
||||||
|
size_t voxelIndex = vox_index(lx, y, lz);
|
||||||
|
|
||||||
|
const auto& def = content->getIndices()->blocks.require(vox->id);
|
||||||
|
if (def.dataStruct == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const auto& dataStruct = *def.dataStruct;
|
||||||
|
const auto field = dataStruct.getField(name);
|
||||||
|
if (field == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ubyte* dst = chunk->blocksMetadata.find(voxelIndex);
|
||||||
|
if (dst == nullptr) {
|
||||||
|
throw std::runtime_error("block data is not allocated");
|
||||||
|
}
|
||||||
|
switch (field->type) {
|
||||||
|
case data::FieldType::CHAR:
|
||||||
|
if (value.isString()) {
|
||||||
|
return lua::pushinteger(L,
|
||||||
|
dataStruct.setUnicode(dst, value.asString(), *field));
|
||||||
|
}
|
||||||
|
case data::FieldType::I8:
|
||||||
|
case data::FieldType::I16:
|
||||||
|
case data::FieldType::I32:
|
||||||
|
case data::FieldType::I64:
|
||||||
|
dataStruct.setInteger(dst, value.asInteger(), *field, index);
|
||||||
|
break;
|
||||||
|
case data::FieldType::F32:
|
||||||
|
case data::FieldType::F64:
|
||||||
|
dataStruct.setNumber(dst, value.asNumber(), *field, index);
|
||||||
|
break;
|
||||||
|
case data::FieldType::COUNT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg blocklib[] = {
|
const luaL_Reg blocklib[] = {
|
||||||
{"index", lua::wrap<l_index>},
|
{"index", lua::wrap<l_index>},
|
||||||
{"name", lua::wrap<l_get_def>},
|
{"name", lua::wrap<l_get_def>},
|
||||||
@@ -469,5 +572,7 @@ const luaL_Reg blocklib[] = {
|
|||||||
{"raycast", lua::wrap<l_raycast>},
|
{"raycast", lua::wrap<l_raycast>},
|
||||||
{"compose_state", lua::wrap<l_compose_state>},
|
{"compose_state", lua::wrap<l_compose_state>},
|
||||||
{"decompose_state", lua::wrap<l_decompose_state>},
|
{"decompose_state", lua::wrap<l_decompose_state>},
|
||||||
|
{"get_field", lua::wrap<l_get_field>},
|
||||||
|
{"set_field", lua::wrap<l_set_field>},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "data/StructLayout.hpp"
|
||||||
#include "coders/byte_utils.hpp"
|
#include "coders/byte_utils.hpp"
|
||||||
#include "coders/json.hpp"
|
#include "coders/json.hpp"
|
||||||
#include "content/Content.hpp"
|
#include "content/Content.hpp"
|
||||||
@@ -370,6 +371,7 @@ void Chunks::set(
|
|||||||
}
|
}
|
||||||
int lx = x - cx * CHUNK_W;
|
int lx = x - cx * CHUNK_W;
|
||||||
int lz = z - cz * CHUNK_D;
|
int lz = z - cz * CHUNK_D;
|
||||||
|
size_t index = vox_index(lx, y, lz);
|
||||||
|
|
||||||
// block finalization
|
// block finalization
|
||||||
voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx];
|
voxel& vox = chunk->voxels[(y * CHUNK_D + lz) * CHUNK_W + lx];
|
||||||
@@ -380,6 +382,9 @@ void Chunks::set(
|
|||||||
if (prevdef.rt.extended && !vox.state.segment) {
|
if (prevdef.rt.extended && !vox.state.segment) {
|
||||||
eraseSegments(prevdef, vox.state, gx, y, gz);
|
eraseSegments(prevdef, vox.state, gx, y, gz);
|
||||||
}
|
}
|
||||||
|
if (prevdef.dataStruct) {
|
||||||
|
chunk->blocksMetadata.free(chunk->blocksMetadata.find(index));
|
||||||
|
}
|
||||||
|
|
||||||
// block initialization
|
// block initialization
|
||||||
const auto& newdef = indices->blocks.require(id);
|
const auto& newdef = indices->blocks.require(id);
|
||||||
@@ -389,6 +394,9 @@ void Chunks::set(
|
|||||||
if (!state.segment && newdef.rt.extended) {
|
if (!state.segment && newdef.rt.extended) {
|
||||||
repairSegments(newdef, state, gx, y, gz);
|
repairSegments(newdef, state, gx, y, gz);
|
||||||
}
|
}
|
||||||
|
if (newdef.dataStruct) {
|
||||||
|
chunk->blocksMetadata.allocate(index, newdef.dataStruct->size());
|
||||||
|
}
|
||||||
|
|
||||||
if (y < chunk->bottom)
|
if (y < chunk->bottom)
|
||||||
chunk->bottom = y;
|
chunk->bottom = y;
|
||||||
|
|||||||
Reference in New Issue
Block a user