diff --git a/doc/en/scripting/builtins/libblock.md b/doc/en/scripting/builtins/libblock.md index b2528c364..db407e92a 100644 --- a/doc/en/scripting/builtins/libblock.md +++ b/doc/en/scripting/builtins/libblock.md @@ -67,7 +67,7 @@ block.get_picking_item(id: int) -> int block.get_variant(x: int, y: int, z: int) -> int -- Sets the block variant by index -block.set_variant(x: int, y: int, z: int, index: int) -> int +block.set_variant(x: int, y: int, z: int, index: int) -- Checks if an block has specified tag block.has_tag(id: int, tag: str) -> bool diff --git a/doc/ru/scripting/builtins/libblock.md b/doc/ru/scripting/builtins/libblock.md index a82d2ff66..b7af3e462 100644 --- a/doc/ru/scripting/builtins/libblock.md +++ b/doc/ru/scripting/builtins/libblock.md @@ -46,7 +46,7 @@ block.destruct(x: int, y: int, z: int, playerid: int) block.get_variant(x: int, y: int, z: int) -> int -- Устанавливает вариант блока по индексу -block.set_variant(x: int, y: int, z: int, index: int) -> int +block.set_variant(x: int, y: int, z: int, index: int) ``` > [!WARNING] diff --git a/src/content/loading/BlockLoader.cpp b/src/content/loading/BlockLoader.cpp index 87c10fa67..c4df790c6 100644 --- a/src/content/loading/BlockLoader.cpp +++ b/src/content/loading/BlockLoader.cpp @@ -120,8 +120,8 @@ template<> void ContentUnitLoader::loadUnit( } def.variants = std::make_unique(); - def.variants->offset = 0; - def.variants->mask = 0xF; + def.variants->offset = offset; + def.variants->mask = (1ULL << bitsCount) - 1; def.variants->variants.push_back(def.defaults); for (int i = 0; i < variants.size(); i++) { Variant variant = def.defaults; diff --git a/src/frontend/ContentGfxCache.cpp b/src/frontend/ContentGfxCache.cpp index 20b7cdaa7..b8ce69a5f 100644 --- a/src/frontend/ContentGfxCache.cpp +++ b/src/frontend/ContentGfxCache.cpp @@ -70,7 +70,7 @@ void ContentGfxCache::refresh(const Block& def, const Atlas& atlas) { refreshVariant(def, def.defaults, 0, atlas); if (def.variants) { const auto& variants = def.variants->variants; - for (int i = 1; i < variants.size() - 1; i++) { + for (int i = 1; i < variants.size(); i++) { refreshVariant(def, variants[i], i, atlas); } def.variants->variants.at(0) = def.defaults; diff --git a/src/graphics/render/ModelsGenerator.cpp b/src/graphics/render/ModelsGenerator.cpp index b4f423480..da82680bb 100644 --- a/src/graphics/render/ModelsGenerator.cpp +++ b/src/graphics/render/ModelsGenerator.cpp @@ -92,6 +92,12 @@ void ModelsGenerator::prepareModel( void ModelsGenerator::prepare(Content& content, Assets& assets) { for (auto& [name, def] : content.blocks.getDefs()) { prepareModel(assets, *def, def->defaults, 0); + if (def->variants) { + auto& variants = def->variants->variants; + for (int i = 1; i < variants.size(); i++) { + prepareModel(assets, *def, variants[i], i); + } + } } for (auto& [name, def] : content.items.getDefs()) { assets.store( diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index 6a84b4113..2fa2b1281 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -246,11 +246,12 @@ static int l_get_user_bits(lua::State* L) { } static int l_get_variant(lua::State* L) { + auto& chunks = *level->chunks; auto x = lua::tointeger(L, 1); auto y = lua::tointeger(L, 2); auto z = lua::tointeger(L, 3); - auto vox = blocks_agent::get(*level->chunks, x, y, z); + auto vox = blocks_agent::get(chunks, x, y, z); if (vox == nullptr) { return lua::pushinteger(L, 0); } @@ -258,6 +259,13 @@ static int l_get_variant(lua::State* L) { if (def.variants == nullptr) { return lua::pushinteger(L, 0); } + if (def.rt.extended) { + auto origin = blocks_agent::seek_origin(chunks, {x, y, z}, def, vox->state); + vox = blocks_agent::get(chunks, origin.x, origin.y, origin.z); + if (vox == nullptr) { + return lua::pushinteger(L, 0); + } + } return lua::pushinteger( L, (vox->state.userbits >> def.variants->offset) & def.variants->mask ); @@ -290,6 +298,14 @@ static int l_set_user_bits(lua::State* L) { if (vox == nullptr) { return 0; } + int ocx = floordiv(origin.x); + int ocz = floordiv(origin.z); + if (cx != ocx || cz != ocz) { + chunk = blocks_agent::get_chunk(chunks, ocx, ocz); + if (chunk == nullptr) { + return 0; + } + } } vox->state.userbits = (vox->state.userbits & (~mask)) | value; chunk->setModifiedAndUnsaved(); @@ -318,8 +334,8 @@ static int l_set_variant(lua::State* L) { } auto offset = def.variants->offset; - auto mask = def.variants->mask; - auto value = (lua::tointeger(L, 4) << offset) & mask; + auto mask = def.variants->mask << offset; + auto value = (lua::tointeger(L, 4) << offset); if (def.rt.extended) { auto origin = blocks_agent::seek_origin(chunks, {x, y, z}, def, vox->state); @@ -327,6 +343,14 @@ static int l_set_variant(lua::State* L) { if (vox == nullptr) { return 0; } + int ocx = floordiv(origin.x); + int ocz = floordiv(origin.z); + if (cx != ocx || cz != ocz) { + chunk = blocks_agent::get_chunk(chunks, ocx, ocz); + if (chunk == nullptr) { + return 0; + } + } } vox->state.userbits = (vox->state.userbits & (~mask)) | value; chunk->setModifiedAndUnsaved();