#include "lua_commons.hpp" #include "api_lua.hpp" #include "lua_util.hpp" #include "../scripting.hpp" #include "../../../world/Level.hpp" #include "../../../voxels/Chunks.hpp" #include "../../../voxels/Chunk.hpp" #include "../../../voxels/Block.hpp" #include "../../../voxels/voxel.hpp" #include "../../../lighting/Lighting.hpp" #include "../../../content/Content.hpp" #include "../../../logic/BlocksController.hpp" int l_block_name(lua_State* L) { auto indices = scripting::content->getIndices(); lua_Integer id = lua_tointeger(L, 1); if (id < 0 || size_t(id) >= indices->countBlockDefs()) { return 0; } auto def = indices->getBlockDef(id); lua_pushstring(L, def->name.c_str()); return 1; } int l_block_material(lua_State* L) { auto indices = scripting::content->getIndices(); lua_Integer id = lua_tointeger(L, 1); if (id < 0 || size_t(id) >= indices->countBlockDefs()) { return 0; } auto def = indices->getBlockDef(id); lua_pushstring(L, def->material.c_str()); return 1; } int l_is_solid_at(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); lua_pushboolean(L, scripting::level->chunks->isSolidBlock(x, y, z)); return 1; } int l_blocks_count(lua_State* L) { lua_pushinteger(L, scripting::indices->countBlockDefs()); return 1; } int l_block_index(lua_State* L) { std::string name = lua_tostring(L, 1); lua_pushinteger(L, scripting::content->requireBlock(name).rt.id); return 1; } int l_set_block(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); lua_Integer id = lua_tointeger(L, 4); lua_Integer states = lua_tointeger(L, 5); bool noupdate = lua_toboolean(L, 6); if (id < 0 || size_t(id) >= scripting::indices->countBlockDefs()) { return 0; } if (!scripting::level->chunks->get(x, y, z)) { return 0; } scripting::level->chunks->set(x, y, z, id, states); scripting::level->lighting->onBlockSet(x,y,z, id); if (!noupdate) scripting::blocks->updateSides(x, y, z); return 0; } int l_get_block(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); int id = vox == nullptr ? -1 : vox->id; lua_pushinteger(L, id); return 1; } int l_get_block_x(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return lua::pushivec3(L, 1, 0, 0); } auto def = scripting::level->content->getIndices()->getBlockDef(vox->id); if (!def->rotatable) { return lua::pushivec3(L, 1, 0, 0); } else { const CoordSystem& rot = def->rotations.variants[vox->rotation()]; return lua::pushivec3(L, rot.axisX.x, rot.axisX.y, rot.axisX.z); } } int l_get_block_y(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return lua::pushivec3(L, 0, 1, 0); } auto def = scripting::level->content->getIndices()->getBlockDef(vox->id); if (!def->rotatable) { return lua::pushivec3(L, 0, 1, 0); } else { const CoordSystem& rot = def->rotations.variants[vox->rotation()]; return lua::pushivec3(L, rot.axisY.x, rot.axisY.y, rot.axisY.z); } } int l_get_block_z(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return lua::pushivec3(L, 0, 0, 1); } auto def = scripting::level->content->getIndices()->getBlockDef(vox->id); if (!def->rotatable) { return lua::pushivec3(L, 0, 0, 1); } else { const CoordSystem& rot = def->rotations.variants[vox->rotation()]; return lua::pushivec3(L, rot.axisZ.x, rot.axisZ.y, rot.axisZ.z); } } int l_get_block_rotation(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); int rotation = vox == nullptr ? 0 : vox->rotation(); lua_pushinteger(L, rotation); return 1; } int l_set_block_rotation(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); lua_Integer value = lua_tointeger(L, 4); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return 0; } vox->setRotation(value); scripting::level->chunks->getChunkByVoxel(x, y, z)->setModified(true); return 0; } int l_get_block_states(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); voxel* vox = scripting::level->chunks->get(x, y, z); int states = vox == nullptr ? 0 : vox->states; lua_pushinteger(L, states); return 1; } int l_set_block_states(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); lua_Integer states = lua_tointeger(L, 4); Chunk* chunk = scripting::level->chunks->getChunkByVoxel(x, y, z); if (chunk == nullptr) { return 0; } voxel* vox = scripting::level->chunks->get(x, y, z); vox->states = states; chunk->setModified(true); return 0; } int l_get_block_user_bits(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); lua_Integer offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; lua_Integer bits = lua_tointeger(L, 5); voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { lua_pushinteger(L, 0); return 1; } uint mask = ((1 << bits) - 1) << offset; uint data = (vox->states & mask) >> offset; lua_pushinteger(L, data); return 1; } int l_set_block_user_bits(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); lua_Integer offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; lua_Integer bits = lua_tointeger(L, 5); size_t mask = ((1 << bits) - 1) << offset; lua_Integer value = (lua_tointeger(L, 6) << offset) & mask; voxel* vox = scripting::level->chunks->get(x, y, z); if (vox == nullptr) { return 0; } vox->states = (vox->states & (~mask)) | value; return 0; } int l_is_replaceable_at(lua_State* L) { lua_Integer x = lua_tointeger(L, 1); lua_Integer y = lua_tointeger(L, 2); lua_Integer z = lua_tointeger(L, 3); lua_pushboolean(L, scripting::level->chunks->isReplaceableBlock(x, y, z)); return 1; } const luaL_Reg blocklib [] = { {"index", lua_wrap_errors}, {"name", lua_wrap_errors}, {"material", lua_wrap_errors}, {"defs_count", lua_wrap_errors}, {"is_solid_at", lua_wrap_errors}, {"is_replaceable_at", lua_wrap_errors}, {"set", lua_wrap_errors}, {"get", lua_wrap_errors}, {"get_X", lua_wrap_errors}, {"get_Y", lua_wrap_errors}, {"get_Z", lua_wrap_errors}, {"get_states", lua_wrap_errors}, {"set_states", lua_wrap_errors}, {"get_rotation", lua_wrap_errors}, {"set_rotation", lua_wrap_errors}, {"get_user_bits", lua_wrap_errors}, {"set_user_bits", lua_wrap_errors}, {NULL, NULL} };