fix blocks variants

This commit is contained in:
clasher113 2026-02-28 15:59:04 +02:00
parent a32845d083
commit 0cc8c70a17
6 changed files with 38 additions and 8 deletions

View file

@ -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

View file

@ -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]

View file

@ -120,8 +120,8 @@ template<> void ContentUnitLoader<Block>::loadUnit(
}
def.variants = std::make_unique<Variants>();
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;

View file

@ -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;

View file

@ -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(

View file

@ -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<CHUNK_W>(origin.x);
int ocz = floordiv<CHUNK_D>(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<CHUNK_W>(origin.x);
int ocz = floordiv<CHUNK_D>(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();