From 6bf6e8e0116883df4c7e74eeb6b9715e565bb620 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 5 Mar 2024 13:58:08 +0300 Subject: [PATCH] lua api refactor --- res/scripts/stdlib.lua | 18 + src/logic/scripting/lua/LuaState.cpp | 21 +- src/logic/scripting/lua/api_lua.cpp | 474 --------------------- src/logic/scripting/lua/api_lua.h | 103 +---- src/logic/scripting/lua/libblock.cpp | 234 ++++++++++ src/logic/scripting/lua/libfile.cpp | 163 +++++++ src/logic/scripting/lua/libgui.cpp | 19 +- src/logic/scripting/lua/libgui.h | 19 - src/logic/scripting/lua/libhud.cpp | 24 +- src/logic/scripting/lua/libhud.h | 21 - src/logic/scripting/lua/libinventory.cpp | 33 +- src/logic/scripting/lua/libinventory.h | 27 -- src/logic/scripting/lua/libitem.cpp | 46 ++ src/logic/scripting/lua/libpack.cpp | 31 ++ src/logic/scripting/lua/libplayer.cpp | 29 +- src/logic/scripting/lua/libplayer.h | 26 -- src/logic/scripting/lua/libtime.cpp | 21 + src/logic/scripting/lua/libworld.cpp | 36 ++ src/logic/scripting/lua/lua_overrides.cpp | 26 ++ src/logic/scripting/scripting_frontend.cpp | 2 +- 20 files changed, 663 insertions(+), 710 deletions(-) delete mode 100644 src/logic/scripting/lua/api_lua.cpp create mode 100644 src/logic/scripting/lua/libblock.cpp create mode 100644 src/logic/scripting/lua/libfile.cpp delete mode 100644 src/logic/scripting/lua/libgui.h delete mode 100644 src/logic/scripting/lua/libhud.h delete mode 100644 src/logic/scripting/lua/libinventory.h create mode 100644 src/logic/scripting/lua/libitem.cpp create mode 100644 src/logic/scripting/lua/libpack.cpp delete mode 100644 src/logic/scripting/lua/libplayer.h create mode 100644 src/logic/scripting/lua/libtime.cpp create mode 100644 src/logic/scripting/lua/libworld.cpp create mode 100644 src/logic/scripting/lua/lua_overrides.cpp diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index b6d7523d..4968b675 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -142,3 +142,21 @@ function Document.new(docname) end }) end + +-- Deprecated functions +block_index = block.index +block_name = block.name +blocks_count = block.defs_count +is_solid_at = block.is_solid_at +is_replaceable_at = block.is_replaceable_at +set_block = block.set +get_block = block.get +get_block_X = block.get_X +get_block_Y = block.get_Y +get_block_Z = block.get_Z +get_block_states = block.get_states +set_block_states = block.set_states +get_block_rotation = block.get_rotation +set_block_rotation = block.set_rotation +get_block_user_bits = block.get_user_bits +set_block_user_bits = block.set_user_bits diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index 0b870f92..0a49fa89 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -3,9 +3,6 @@ #include #include "lua_util.h" #include "api_lua.h" -#include "libgui.h" -#include "libplayer.h" -#include "libinventory.h" #include "../../../util/stringutil.h" lua::luaerror::luaerror(const std::string& message) : std::runtime_error(message) { @@ -120,29 +117,13 @@ void lua::LuaState::createLibs() { openlib("world", worldlib, 0); openlib("player", playerlib, 0); openlib("inventory", inventorylib, 0); + openlib("block", blocklib, 0); openlib("item", itemlib, 0); openlib("time", timelib, 0); openlib("file", filelib, 0); openlib("gui", guilib, 0); addfunc("print", lua_wrap_errors); - - addfunc("block_index", lua_wrap_errors); - addfunc("block_name", lua_wrap_errors); - addfunc("blocks_count", lua_wrap_errors); - addfunc("is_solid_at", lua_wrap_errors); - addfunc("is_replaceable_at", lua_wrap_errors); - addfunc("set_block", lua_wrap_errors); - addfunc("get_block", lua_wrap_errors); - addfunc("get_block_X", lua_wrap_errors); - addfunc("get_block_Y", lua_wrap_errors); - addfunc("get_block_Z", lua_wrap_errors); - addfunc("get_block_states", lua_wrap_errors); - addfunc("set_block_states", lua_wrap_errors); - addfunc("get_block_rotation", lua_wrap_errors); - addfunc("set_block_rotation", lua_wrap_errors); - addfunc("get_block_user_bits", lua_wrap_errors); - addfunc("set_block_user_bits", lua_wrap_errors); } void lua::LuaState::loadbuffer(int env, const std::string& src, const std::string& file) { diff --git a/src/logic/scripting/lua/api_lua.cpp b/src/logic/scripting/lua/api_lua.cpp deleted file mode 100644 index 258e9612..00000000 --- a/src/logic/scripting/lua/api_lua.cpp +++ /dev/null @@ -1,474 +0,0 @@ -#include "api_lua.h" - -#include "../scripting.h" -#include "lua_util.h" - -#include -#include - -#include "../../../files/files.h" -#include "../../../physics/Hitbox.h" -#include "../../../objects/Player.h" -#include "../../../world/Level.h" -#include "../../../world/World.h" -#include "../../../content/Content.h" -#include "../../../voxels/Block.h" -#include "../../../voxels/Chunks.h" -#include "../../../voxels/voxel.h" -#include "../../../voxels/Chunk.h" -#include "../../../items/ItemDef.h" -#include "../../../items/Inventory.h" -#include "../../../items/Inventories.h" -#include "../../../lighting/Lighting.h" -#include "../../../logic/BlocksController.h" -#include "../../../window/Window.h" -#include "../../../engine.h" - -fs::path resolve_path(lua_State* L, const std::string& path) { - try { - return scripting::engine->getPaths()->resolve(path); - } catch (const files_access_error& err) { - luaL_error(L, err.what()); - abort(); // unreachable - } -} - -/* == file library == */ -int l_file_resolve(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - lua_pushstring(L, path.u8string().c_str()); - return 1; -} - -int l_file_read(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - if (fs::is_regular_file(path)) { - lua_pushstring(L, files::read_string(path).c_str()); - return 1; - } - return luaL_error(L, "file does not exists '%s'", path.u8string().c_str()); -} - -int l_file_write(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - const char* text = lua_tostring(L, 2); - files::write_string(path, text); - return 1; -} - -int l_file_exists(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - lua_pushboolean(L, fs::exists(path)); - return 1; -} - -int l_file_isfile(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - lua_pushboolean(L, fs::is_regular_file(path)); - return 1; -} - -int l_file_isdir(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - lua_pushboolean(L, fs::is_directory(path)); - return 1; -} - -int l_file_length(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - if (fs::exists(path)){ - lua_pushinteger(L, fs::file_size(path)); - } else { - lua_pushinteger(L, -1); - } - return 1; -} - -int l_file_mkdir(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - lua_pushboolean(L, fs::create_directory(path)); - return 1; -} - -int l_file_mkdirs(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - lua_pushboolean(L, fs::create_directories(path)); - return 1; -} - -int l_file_read_bytes(lua_State* L) { - fs::path path = resolve_path(L, lua_tostring(L, 1)); - if (fs::is_regular_file(path)) { - size_t length = (size_t) fs::file_size(path); - - ubyte* bytes = files::read_bytes(path, length); - - lua_createtable(L, length, 0); - int newTable = lua_gettop(L); - - for(size_t i = 0; i < length; i++) { - lua_pushnumber(L, bytes[i]); - lua_rawseti(L, newTable, i+1); - } - return 1; - } - return luaL_error(L, "file does not exists '%s'", path.u8string().c_str()); -} - -int l_file_write_bytes(lua_State* L) { - int pathIndex = 1; - - if(!lua_isstring(L, pathIndex)) { - return luaL_error(L, "string expected"); - } - - fs::path path = resolve_path(L, lua_tostring(L, pathIndex)); - - std::vector bytes; - - size_t len = lua_objlen(L, 2); - - int bytesIndex = -1; - - if(!lua_istable(L, bytesIndex)) { - return luaL_error(L, "table expected"); - } else { - lua_pushnil(L); - - bytesIndex--; - - size_t i = 1; - - while(lua_next(L, bytesIndex) != 0) { - if(i >= len) { - break; - } - - const int byte = lua_tointeger(L, -1); - - if(byte < 0 || byte > 255) { - return luaL_error(L, "byte '%i' at index '%i' is less than 0 or greater than 255", byte, i); - } - - bytes.push_back(byte); - - lua_pop(L, 1); - - i++; - } - - lua_pushboolean(L, files::write_bytes(path, &bytes[0], len)); - return 1; - } -} - -/* == time library == */ -int l_time_uptime(lua_State* L) { - lua_pushnumber(L, Window::time()); - return 1; -} - -int l_time_delta(lua_State* L) { - lua_pushnumber(L, scripting::engine->getDelta()); - return 1; -} - -/* == pack library == */ -int l_pack_get_folder(lua_State* L) { - std::string packName = lua_tostring(L, 1); - if (packName == "core") { - auto folder = scripting::engine->getPaths() - ->getResources().u8string()+"/"; - lua_pushstring(L, folder.c_str()); - return 1; - } - for (auto& pack : scripting::engine->getContentPacks()) { - if (pack.id == packName) { - lua_pushstring(L, (pack.folder.u8string()+"/").c_str()); - return 1; - } - } - lua_pushstring(L, ""); - return 1; -} - -/* == world library == */ -int l_world_get_total_time(lua_State* L) { - lua_pushnumber(L, scripting::level->world->totalTime); - return 1; -} - -int l_world_get_day_time(lua_State* L) { - lua_pushnumber(L, scripting::level->world->daytime); - return 1; -} - -int l_world_set_day_time(lua_State* L) { - double value = lua_tonumber(L, 1); - scripting::level->world->daytime = fmod(value, 1.0); - return 0; -} - -int l_world_get_seed(lua_State* L) { - lua_pushinteger(L, scripting::level->world->getSeed()); - return 1; -} - -/* == item library == */ -int l_item_name(lua_State* L) { - auto indices = scripting::content->getIndices(); - lua::luaint id = lua_tointeger(L, 1); - if (id < 0 || size_t(id) >= indices->countItemDefs()) { - return 0; - } - auto def = indices->getItemDef(id); - lua_pushstring(L, def->name.c_str()); - return 1; -} - -int l_item_index(lua_State* L) { - auto name = lua_tostring(L, 1); - lua_pushinteger(L, scripting::content->requireItem(name).rt.id); - return 1; -} - -int l_item_stack_size(lua_State* L) { - auto indices = scripting::content->getIndices(); - lua::luaint id = lua_tointeger(L, 1); - if (id < 0 || size_t(id) >= indices->countItemDefs()) { - return 0; - } - auto def = indices->getItemDef(id); - lua_pushinteger(L, def->stackSize); - return 1; -} - -int l_item_defs_count(lua_State* L) { - lua_pushinteger(L, scripting::indices->countItemDefs()); - return 1; -} - -/* == blocks-related functions == */ -int l_block_name(lua_State* L) { - auto indices = scripting::content->getIndices(); - lua::luaint 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_is_solid_at(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint 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) { - auto name = lua_tostring(L, 1); - lua_pushinteger(L, scripting::content->requireBlock(name).rt.id); - return 1; -} - -int l_set_block(lua_State* L) { - lua::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint id = lua_tointeger(L, 4); - lua::luaint states = lua_tointeger(L, 5); - bool noupdate = lua_toboolean(L, 6); - if (id < 0 || size_t(id) >= scripting::indices->countBlockDefs()) { - 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; - lua::luaint 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::luaint x = lua_tointeger(L, 1); - lua::luaint y = lua_tointeger(L, 2); - lua::luaint z = lua_tointeger(L, 3); - lua::luaint offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; - lua::luaint bits = lua_tointeger(L, 5); - - uint mask = ((1 << bits) - 1) << offset; - lua::luaint 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) { - int x = lua_tointeger(L, 1); - int y = lua_tointeger(L, 2); - int z = lua_tointeger(L, 3); - - lua_pushboolean(L, scripting::level->chunks->isReplaceableBlock(x, y, z)); - return 1; -} - -int l_print(lua_State* L) { - int n = lua_gettop(L); /* number of arguments */ - lua_getglobal(L, "tostring"); - for (int i=1; i<=n; i++) { - lua_pushvalue(L, -1); /* function to be called */ - lua_pushvalue(L, i); /* value to print */ - lua_call(L, 1, 1); - const char* s = lua_tostring(L, -1); /* get result */ - if (s == NULL) - return luaL_error(L, LUA_QL("tostring") " must return a string to " - LUA_QL("print")); - if (i > 1) - std::cout << "\t"; - std::cout << s; - lua_pop(L, 1); /* pop result */ - } - std::cout << std::endl; - return 0; -} diff --git a/src/logic/scripting/lua/api_lua.h b/src/logic/scripting/lua/api_lua.h index aecadf06..5cc5a6a7 100644 --- a/src/logic/scripting/lua/api_lua.h +++ b/src/logic/scripting/lua/api_lua.h @@ -3,100 +3,21 @@ #include #include "lua_commons.h" - -/* == file library == */ -extern int l_file_resolve(lua_State* L); -extern int l_file_read(lua_State* L); -extern int l_file_write(lua_State* L); -extern int l_file_exists(lua_State* L); -extern int l_file_isfile(lua_State* L); -extern int l_file_isdir(lua_State* L); -extern int l_file_length(lua_State* L); -extern int l_file_mkdir(lua_State* L); -extern int l_file_mkdirs(lua_State* L); -extern int l_file_read_bytes(lua_State* L); -extern int l_file_write_bytes(lua_State* L); - -static const luaL_Reg filelib [] = { - {"resolve", lua_wrap_errors}, - {"read", lua_wrap_errors}, - {"write", lua_wrap_errors}, - {"exists", lua_wrap_errors}, - {"isfile", lua_wrap_errors}, - {"isdir", lua_wrap_errors}, - {"length", lua_wrap_errors}, - {"mkdir", lua_wrap_errors}, - {"mkdirs", lua_wrap_errors}, - {"read_bytes", lua_wrap_errors}, - {"write_bytes", lua_wrap_errors}, - {NULL, NULL} -}; - -/* == time library == */ -extern int l_time_uptime(lua_State* L); -extern int l_time_delta(lua_State* L); - -static const luaL_Reg timelib [] = { - {"uptime", lua_wrap_errors}, - {"delta", lua_wrap_errors}, - {NULL, NULL} -}; -/* == pack library == */ -extern int l_pack_get_folder(lua_State* L); +// Libraries +extern const luaL_Reg packlib []; +extern const luaL_Reg timelib []; +extern const luaL_Reg filelib []; +extern const luaL_Reg worldlib []; +extern const luaL_Reg blocklib []; +extern const luaL_Reg itemlib []; +extern const luaL_Reg playerlib []; +extern const luaL_Reg inventorylib []; +extern const luaL_Reg guilib []; +extern const luaL_Reg hudlib []; -static const luaL_Reg packlib [] = { - {"get_folder", lua_wrap_errors}, - {NULL, NULL} -}; -/* == world library == */ -extern int l_world_get_total_time(lua_State* L); -extern int l_world_get_day_time(lua_State* L); -extern int l_world_set_day_time(lua_State* L); -extern int l_world_get_seed(lua_State* L); - -static const luaL_Reg worldlib [] = { - {"get_total_time", lua_wrap_errors}, - {"get_day_time", lua_wrap_errors}, - {"set_day_time", lua_wrap_errors}, - {"get_seed", lua_wrap_errors}, - {NULL, NULL} -}; - -/* == item library == */ -extern int l_item_name(lua_State* L); -extern int l_item_index(lua_State* L); -extern int l_item_stack_size(lua_State* L); -extern int l_item_defs_count(lua_State* L); - -static const luaL_Reg itemlib [] = { - {"index", lua_wrap_errors}, - {"name", lua_wrap_errors}, - {"stack_size", lua_wrap_errors}, - {"defs_count", lua_wrap_errors}, - {NULL, NULL} -}; - -/* == blocks-related functions == */ -extern int l_block_name(lua_State* L); -extern int l_is_solid_at(lua_State* L); -extern int l_blocks_count(lua_State* L); -extern int l_block_index(lua_State* L); -extern int l_set_block(lua_State* L); -extern int l_get_block(lua_State* L); -extern int l_get_block_x(lua_State* L); -extern int l_get_block_y(lua_State* L); -extern int l_get_block_z(lua_State* L); -extern int l_get_block_states(lua_State* L); -extern int l_set_block_states(lua_State* L); -extern int l_get_block_rotation(lua_State* L); -extern int l_set_block_rotation(lua_State* L); -extern int l_get_block_user_bits(lua_State* L); -extern int l_set_block_user_bits(lua_State* L); -extern int l_is_replaceable_at(lua_State* L); - -// Modified version of luaB_print from lbaselib.c +// Lua Overrides extern int l_print(lua_State* L); #endif // LOGIC_SCRIPTING_API_LUA_H_ diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp new file mode 100644 index 00000000..56b3d963 --- /dev/null +++ b/src/logic/scripting/lua/libblock.cpp @@ -0,0 +1,234 @@ +#include "lua_commons.h" +#include "api_lua.h" +#include "lua_util.h" +#include "../scripting.h" +#include "../../../world/Level.h" +#include "../../../voxels/Chunks.h" +#include "../../../voxels/Chunk.h" +#include "../../../voxels/Block.h" +#include "../../../voxels/voxel.h" +#include "../../../lighting/Lighting.h" +#include "../../../content/Content.h" +#include "../../../logic/BlocksController.h" + +int l_block_name(lua_State* L) { + auto indices = scripting::content->getIndices(); + lua::luaint 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_is_solid_at(lua_State* L) { + lua::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint 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) { + auto name = lua_tostring(L, 1); + lua_pushinteger(L, scripting::content->requireBlock(name).rt.id); + return 1; +} + +int l_set_block(lua_State* L) { + lua::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint z = lua_tointeger(L, 3); + lua::luaint id = lua_tointeger(L, 4); + lua::luaint states = lua_tointeger(L, 5); + bool noupdate = lua_toboolean(L, 6); + if (id < 0 || size_t(id) >= scripting::indices->countBlockDefs()) { + 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint z = lua_tointeger(L, 3); + lua::luaint 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint z = lua_tointeger(L, 3); + lua::luaint 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint z = lua_tointeger(L, 3); + lua::luaint offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; + lua::luaint 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::luaint x = lua_tointeger(L, 1); + lua::luaint y = lua_tointeger(L, 2); + lua::luaint z = lua_tointeger(L, 3); + lua::luaint offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET; + lua::luaint bits = lua_tointeger(L, 5); + + uint mask = ((1 << bits) - 1) << offset; + lua::luaint 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) { + int x = lua_tointeger(L, 1); + int y = lua_tointeger(L, 2); + int 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}, + {"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_user_bits", lua_wrap_errors}, + {"set_user_bits", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp new file mode 100644 index 00000000..73d69de3 --- /dev/null +++ b/src/logic/scripting/lua/libfile.cpp @@ -0,0 +1,163 @@ +#include "lua_commons.h" +#include "api_lua.h" +#include "../scripting.h" +#include "../../../engine.h" +#include "../../../files/files.h" +#include "../../../files/engine_paths.h" + +#include +#include + +namespace fs = std::filesystem; + +static fs::path resolve_path(lua_State* L, const std::string& path) { + try { + return scripting::engine->getPaths()->resolve(path); + } catch (const files_access_error& err) { + luaL_error(L, err.what()); + abort(); // unreachable + } +} + +static int l_file_resolve(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + lua_pushstring(L, path.u8string().c_str()); + return 1; +} + +static int l_file_read(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + if (fs::is_regular_file(path)) { + lua_pushstring(L, files::read_string(path).c_str()); + return 1; + } + return luaL_error(L, "file does not exists '%s'", path.u8string().c_str()); +} + +static int l_file_write(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + const char* text = lua_tostring(L, 2); + files::write_string(path, text); + return 1; +} + +static int l_file_exists(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + lua_pushboolean(L, fs::exists(path)); + return 1; +} + +static int l_file_isfile(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + lua_pushboolean(L, fs::is_regular_file(path)); + return 1; +} + +static int l_file_isdir(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + lua_pushboolean(L, fs::is_directory(path)); + return 1; +} + +static int l_file_length(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + if (fs::exists(path)){ + lua_pushinteger(L, fs::file_size(path)); + } else { + lua_pushinteger(L, -1); + } + return 1; +} + +static int l_file_mkdir(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + lua_pushboolean(L, fs::create_directory(path)); + return 1; +} + +static int l_file_mkdirs(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + lua_pushboolean(L, fs::create_directories(path)); + return 1; +} + +static int l_file_read_bytes(lua_State* L) { + fs::path path = resolve_path(L, lua_tostring(L, 1)); + if (fs::is_regular_file(path)) { + size_t length = (size_t) fs::file_size(path); + + ubyte* bytes = files::read_bytes(path, length); + + lua_createtable(L, length, 0); + int newTable = lua_gettop(L); + + for(size_t i = 0; i < length; i++) { + lua_pushnumber(L, bytes[i]); + lua_rawseti(L, newTable, i+1); + } + return 1; + } + return luaL_error(L, "file does not exists '%s'", path.u8string().c_str()); +} + +static int l_file_write_bytes(lua_State* L) { + int pathIndex = 1; + + if(!lua_isstring(L, pathIndex)) { + return luaL_error(L, "string expected"); + } + + fs::path path = resolve_path(L, lua_tostring(L, pathIndex)); + + std::vector bytes; + + size_t len = lua_objlen(L, 2); + + int bytesIndex = -1; + + if(!lua_istable(L, bytesIndex)) { + return luaL_error(L, "table expected"); + } else { + lua_pushnil(L); + + bytesIndex--; + + size_t i = 1; + + while(lua_next(L, bytesIndex) != 0) { + if(i >= len) { + break; + } + + const int byte = lua_tointeger(L, -1); + + if(byte < 0 || byte > 255) { + return luaL_error(L, "byte '%i' at index '%i' is less than 0 or greater than 255", byte, i); + } + + bytes.push_back(byte); + + lua_pop(L, 1); + + i++; + } + + lua_pushboolean(L, files::write_bytes(path, &bytes[0], len)); + return 1; + } +} + +const luaL_Reg filelib [] = { + {"resolve", lua_wrap_errors}, + {"read", lua_wrap_errors}, + {"write", lua_wrap_errors}, + {"exists", lua_wrap_errors}, + {"isfile", lua_wrap_errors}, + {"isdir", lua_wrap_errors}, + {"length", lua_wrap_errors}, + {"mkdir", lua_wrap_errors}, + {"mkdirs", lua_wrap_errors}, + {"read_bytes", lua_wrap_errors}, + {"write_bytes", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index d83c57f9..11d563af 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -1,4 +1,5 @@ -#include "libgui.h" +#include "lua_commons.h" +#include "api_lua.h" #include #include "../scripting.h" @@ -161,7 +162,7 @@ static bool setattr(lua_State* L, gui::Label* label, const std::string& attr) { return false; } -int l_gui_getattr(lua_State* L) { +static int l_gui_getattr(lua_State* L) { auto docname = lua_tostring(L, 1); auto element = lua_tostring(L, 2); const std::string attr = lua_tostring(L, 3); @@ -197,12 +198,12 @@ int l_gui_getattr(lua_State* L) { return 0; } -int l_gui_getviewport(lua_State* L) { +static int l_gui_getviewport(lua_State* L) { lua::pushvec2_arr(L, scripting::engine->getGUI()->getContainer()->getSize()); return 1; } -int l_gui_setattr(lua_State* L) { +static int l_gui_setattr(lua_State* L) { auto docname = lua_tostring(L, 1); auto element = lua_tostring(L, 2); const std::string attr = lua_tostring(L, 3); @@ -235,7 +236,7 @@ int l_gui_setattr(lua_State* L) { return 0; } -int l_gui_get_env(lua_State* L) { +static int l_gui_get_env(lua_State* L) { auto name = lua_tostring(L, 1); auto doc = scripting::engine->getAssets()->getLayout(name); if (doc == nullptr) { @@ -244,3 +245,11 @@ int l_gui_get_env(lua_State* L) { lua_getglobal(L, lua::LuaState::envName(doc->getEnvironment()).c_str()); return 1; } + +const luaL_Reg guilib [] = { + {"get_viewport", lua_wrap_errors}, + {"getattr", lua_wrap_errors}, + {"setattr", lua_wrap_errors}, + {"get_env", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/libgui.h b/src/logic/scripting/lua/libgui.h deleted file mode 100644 index bbc225b8..00000000 --- a/src/logic/scripting/lua/libgui.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LOGIC_SCRIPTING_API_LIBGUI_H_ -#define LOGIC_SCRIPTING_API_LIBGUI_H_ - -#include "lua_commons.h" - -extern int l_gui_getviewport(lua_State* L); -extern int l_gui_getattr(lua_State* L); -extern int l_gui_setattr(lua_State* L); -extern int l_gui_get_env(lua_State* L); - -static const luaL_Reg guilib [] = { - {"get_viewport", lua_wrap_errors}, - {"getattr", lua_wrap_errors}, - {"setattr", lua_wrap_errors}, - {"get_env", lua_wrap_errors}, - {NULL, NULL} -}; - -#endif // LOGIC_SCRIPTING_API_LIBGUI_H_ diff --git a/src/logic/scripting/lua/libhud.cpp b/src/logic/scripting/lua/libhud.cpp index a3289968..85567d75 100644 --- a/src/logic/scripting/lua/libhud.cpp +++ b/src/logic/scripting/lua/libhud.cpp @@ -1,4 +1,5 @@ -#include "libhud.h" +#include "lua_commons.h" +#include "api_lua.h" #include "LuaState.h" #include @@ -22,21 +23,21 @@ namespace scripting { extern Hud* hud; } -int l_hud_open_inventory(lua_State* L) { +static int l_hud_open_inventory(lua_State* L) { if (!scripting::hud->isInventoryOpen()) { scripting::hud->openInventory(); } return 0; } -int l_hud_close_inventory(lua_State* L) { +static int l_hud_close_inventory(lua_State* L) { if (scripting::hud->isInventoryOpen()) { scripting::hud->closeInventory(); } return 0; } -int l_hud_open_block(lua_State* L) { +static int l_hud_open_block(lua_State* L) { lua::luaint x = lua_tointeger(L, 1); lua::luaint y = lua_tointeger(L, 2); lua::luaint z = lua_tointeger(L, 3); @@ -64,7 +65,7 @@ int l_hud_open_block(lua_State* L) { return 2; } -UiDocument* require_layout(lua_State* L, const char* name) { +static UiDocument* require_layout(lua_State* L, const char* name) { auto assets = scripting::engine->getAssets(); auto layout = assets->getLayout(name); if (layout == nullptr) { @@ -73,14 +74,23 @@ UiDocument* require_layout(lua_State* L, const char* name) { return layout; } -int l_hud_open_permanent(lua_State* L) { +static int l_hud_open_permanent(lua_State* L) { auto layout = require_layout(L, lua_tostring(L, 1)); scripting::hud->openPermanent(layout); return 0; } -int l_hud_close(lua_State* L) { +static int l_hud_close(lua_State* L) { auto layout = require_layout(L, lua_tostring(L, 1)); scripting::hud->remove(layout->getRoot()); return 0; } + +const luaL_Reg hudlib [] = { + {"open_inventory", lua_wrap_errors}, + {"close_inventory", lua_wrap_errors}, + {"open_block", lua_wrap_errors}, + {"open_permanent", lua_wrap_errors}, + {"close", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/libhud.h b/src/logic/scripting/lua/libhud.h deleted file mode 100644 index 88800dfe..00000000 --- a/src/logic/scripting/lua/libhud.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef LOGIC_SCRIPTING_API_LIBHUD_H_ -#define LOGIC_SCRIPTING_API_LIBHUD_H_ - -#include "lua_commons.h" - -extern int l_hud_open_inventory(lua_State* L); -extern int l_hud_close_inventory(lua_State* L); -extern int l_hud_open_block(lua_State* L); -extern int l_hud_open_permanent(lua_State* L); -extern int l_hud_close(lua_State* L); - -static const luaL_Reg hudlib [] = { - {"open_inventory", lua_wrap_errors}, - {"close_inventory", lua_wrap_errors}, - {"open_block", lua_wrap_errors}, - {"open_permanent", lua_wrap_errors}, - {"close", lua_wrap_errors}, - {NULL, NULL} -}; - -#endif // LOGIC_SCRIPTING_API_LIBHUD_H_ diff --git a/src/logic/scripting/lua/libinventory.cpp b/src/logic/scripting/lua/libinventory.cpp index 8e657d6a..c2221d7c 100644 --- a/src/logic/scripting/lua/libinventory.cpp +++ b/src/logic/scripting/lua/libinventory.cpp @@ -1,4 +1,5 @@ -#include "libinventory.h" +#include "lua_commons.h" +#include "api_lua.h" #include "lua_util.h" #include "../scripting.h" @@ -14,8 +15,7 @@ static void validate_itemid(lua_State* L, itemid_t id) { } } -/* == inventory library == */ -int l_inventory_get(lua_State* L) { +static int l_inventory_get(lua_State* L) { lua::luaint invid = lua_tointeger(L, 1); lua::luaint slotid = lua_tointeger(L, 2); auto inv = scripting::level->inventories->get(invid); @@ -31,7 +31,7 @@ int l_inventory_get(lua_State* L) { return 2; } -int l_inventory_set(lua_State* L) { +static int l_inventory_set(lua_State* L) { lua::luaint invid = lua_tointeger(L, 1); lua::luaint slotid = lua_tointeger(L, 2); lua::luaint itemid = lua_tointeger(L, 3); @@ -50,7 +50,7 @@ int l_inventory_set(lua_State* L) { return 0; } -int l_inventory_size(lua_State* L) { +static int l_inventory_size(lua_State* L) { lua::luaint invid = lua_tointeger(L, 1); auto inv = scripting::level->inventories->get(invid); if (inv == nullptr) { @@ -60,7 +60,7 @@ int l_inventory_size(lua_State* L) { return 1; } -int l_inventory_add(lua_State* L) { +static int l_inventory_add(lua_State* L) { lua::luaint invid = lua_tointeger(L, 1); lua::luaint itemid = lua_tointeger(L, 2); lua::luaint count = lua_tointeger(L, 3); @@ -76,7 +76,7 @@ int l_inventory_add(lua_State* L) { return 1; } -int l_inventory_get_block(lua_State* L) { +static int l_inventory_get_block(lua_State* L) { lua::luaint x = lua_tointeger(L, 1); lua::luaint y = lua_tointeger(L, 2); lua::luaint z = lua_tointeger(L, 3); @@ -85,7 +85,7 @@ int l_inventory_get_block(lua_State* L) { return 1; } -int l_inventory_bind_block(lua_State* L) { +static int l_inventory_bind_block(lua_State* L) { lua::luaint id = lua_tointeger(L, 1); lua::luaint x = lua_tointeger(L, 2); lua::luaint y = lua_tointeger(L, 3); @@ -94,7 +94,7 @@ int l_inventory_bind_block(lua_State* L) { return 0; } -int l_inventory_unbind_block(lua_State* L) { +static int l_inventory_unbind_block(lua_State* L) { lua::luaint x = lua_tointeger(L, 1); lua::luaint y = lua_tointeger(L, 2); lua::luaint z = lua_tointeger(L, 3); @@ -102,7 +102,7 @@ int l_inventory_unbind_block(lua_State* L) { return 0; } -int l_inventory_clone(lua_State* L) { +static int l_inventory_clone(lua_State* L) { lua::luaint id = lua_tointeger(L, 1); auto clone = scripting::level->inventories->clone(id); if (clone == nullptr) { @@ -112,3 +112,16 @@ int l_inventory_clone(lua_State* L) { lua_pushinteger(L, clone->getId()); return 1; } + +const luaL_Reg inventorylib [] = { + {"get", lua_wrap_errors}, + {"set", lua_wrap_errors}, + {"size", lua_wrap_errors}, + {"add", lua_wrap_errors}, + {"get_block", lua_wrap_errors}, + {"bind_block", lua_wrap_errors}, + {"unbind_block", lua_wrap_errors}, + {"clone", lua_wrap_errors}, + {NULL, NULL} +}; + diff --git a/src/logic/scripting/lua/libinventory.h b/src/logic/scripting/lua/libinventory.h deleted file mode 100644 index feca2942..00000000 --- a/src/logic/scripting/lua/libinventory.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef LOGIC_SCRIPTING_API_LIBINVENTORY_H_ -#define LOGIC_SCRIPTING_API_LIBINVENTORY_H_ - -#include "lua_commons.h" - -extern int l_inventory_get(lua_State* L); -extern int l_inventory_set(lua_State* L); -extern int l_inventory_size(lua_State* L); -extern int l_inventory_add(lua_State* L); -extern int l_inventory_get_block(lua_State* L); -extern int l_inventory_bind_block(lua_State* L); -extern int l_inventory_unbind_block(lua_State* L); -extern int l_inventory_clone(lua_State* L); - -static const luaL_Reg inventorylib [] = { - {"get", lua_wrap_errors}, - {"set", lua_wrap_errors}, - {"size", lua_wrap_errors}, - {"add", lua_wrap_errors}, - {"get_block", lua_wrap_errors}, - {"bind_block", lua_wrap_errors}, - {"unbind_block", lua_wrap_errors}, - {"clone", lua_wrap_errors}, - {NULL, NULL} -}; - -#endif // LOGIC_SCRIPTING_API_LIBINVENTORY_H_ diff --git a/src/logic/scripting/lua/libitem.cpp b/src/logic/scripting/lua/libitem.cpp new file mode 100644 index 00000000..2d1451f2 --- /dev/null +++ b/src/logic/scripting/lua/libitem.cpp @@ -0,0 +1,46 @@ +#include "lua_commons.h" +#include "api_lua.h" +#include "../scripting.h" +#include "../../../content/Content.h" +#include "../../../items/ItemDef.h" + +static int l_item_name(lua_State* L) { + auto indices = scripting::content->getIndices(); + lua::luaint id = lua_tointeger(L, 1); + if (id < 0 || size_t(id) >= indices->countItemDefs()) { + return 0; + } + auto def = indices->getItemDef(id); + lua_pushstring(L, def->name.c_str()); + return 1; +} + +static int l_item_index(lua_State* L) { + auto name = lua_tostring(L, 1); + lua_pushinteger(L, scripting::content->requireItem(name).rt.id); + return 1; +} + +static int l_item_stack_size(lua_State* L) { + auto indices = scripting::content->getIndices(); + lua::luaint id = lua_tointeger(L, 1); + if (id < 0 || size_t(id) >= indices->countItemDefs()) { + return 0; + } + auto def = indices->getItemDef(id); + lua_pushinteger(L, def->stackSize); + return 1; +} + +static int l_item_defs_count(lua_State* L) { + lua_pushinteger(L, scripting::indices->countItemDefs()); + return 1; +} + +const luaL_Reg itemlib [] = { + {"index", lua_wrap_errors}, + {"name", lua_wrap_errors}, + {"stack_size", lua_wrap_errors}, + {"defs_count", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/libpack.cpp b/src/logic/scripting/lua/libpack.cpp new file mode 100644 index 00000000..ff0b8186 --- /dev/null +++ b/src/logic/scripting/lua/libpack.cpp @@ -0,0 +1,31 @@ +#include "api_lua.h" +#include "lua_commons.h" +#include "../scripting.h" +#include "../../../engine.h" +#include "../../../files/engine_paths.h" + +#include +#include + +static int l_pack_get_folder(lua_State* L) { + std::string packName = lua_tostring(L, 1); + if (packName == "core") { + auto folder = scripting::engine->getPaths() + ->getResources().u8string()+"/"; + lua_pushstring(L, folder.c_str()); + return 1; + } + for (auto& pack : scripting::engine->getContentPacks()) { + if (pack.id == packName) { + lua_pushstring(L, (pack.folder.u8string()+"/").c_str()); + return 1; + } + } + lua_pushstring(L, ""); + return 1; +} + +const luaL_Reg packlib [] = { + {"get_folder", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/libplayer.cpp b/src/logic/scripting/lua/libplayer.cpp index 05e70635..7806b535 100644 --- a/src/logic/scripting/lua/libplayer.cpp +++ b/src/logic/scripting/lua/libplayer.cpp @@ -1,4 +1,5 @@ -#include "libplayer.h" +#include "lua_commons.h" +#include "api_lua.h" #include "../scripting.h" #include "../../../world/Level.h" #include "../../../objects/Player.h" @@ -8,8 +9,7 @@ #include -/* == player library ==*/ -int l_player_get_pos(lua_State* L) { +static int l_player_get_pos(lua_State* L) { int playerid = lua_tointeger(L, 1); auto player = scripting::level->getObject(playerid); if (!player) return 0; @@ -20,7 +20,7 @@ int l_player_get_pos(lua_State* L) { return 3; } -int l_player_set_pos(lua_State* L) { +static int l_player_set_pos(lua_State* L) { int playerid = lua_tointeger(L, 1); lua::luanumber x = lua_tonumber(L, 2); lua::luanumber y = lua_tonumber(L, 3); @@ -30,7 +30,7 @@ int l_player_set_pos(lua_State* L) { return 0; } -int l_player_get_vel(lua_State* L) { +static int l_player_get_vel(lua_State* L) { int playerid = lua_tointeger(L, 1); auto player = scripting::level->getObject(playerid); if (!player) return 0; @@ -41,7 +41,7 @@ int l_player_get_vel(lua_State* L) { return 3; } -int l_player_set_vel(lua_State* L) { +static int l_player_set_vel(lua_State* L) { int playerid = lua_tointeger(L, 1); lua::luanumber x = lua_tonumber(L, 2); lua::luanumber y = lua_tonumber(L, 3); @@ -51,7 +51,7 @@ int l_player_set_vel(lua_State* L) { return 0; } -int l_player_get_rot(lua_State* L) { +static int l_player_get_rot(lua_State* L) { int playerid = lua_tointeger(L, 1); auto player = scripting::level->getObject(playerid); if (!player) return 0; @@ -61,7 +61,7 @@ int l_player_get_rot(lua_State* L) { return 2; } -int l_player_set_rot(lua_State* L) { +static int l_player_set_rot(lua_State* L) { int playerid = lua_tointeger(L, 1); auto player = scripting::level->getObject(playerid); if (!player) return 0; @@ -73,7 +73,7 @@ int l_player_set_rot(lua_State* L) { return 0; } -int l_player_get_inv(lua_State* L) { +static int l_player_get_inv(lua_State* L) { int playerid = lua_tointeger(L, 1); auto player = scripting::level->getObject(playerid); if (!player) return 0; @@ -81,3 +81,14 @@ int l_player_get_inv(lua_State* L) { lua_pushinteger(L, player->getChosenSlot()); return 2; } + +const luaL_Reg playerlib [] = { + {"get_pos", lua_wrap_errors}, + {"set_pos", lua_wrap_errors}, + {"get_vel", lua_wrap_errors}, + {"set_vel", lua_wrap_errors}, + {"get_rot", lua_wrap_errors}, + {"set_rot", lua_wrap_errors}, + {"get_inventory", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/libplayer.h b/src/logic/scripting/lua/libplayer.h deleted file mode 100644 index eb49f775..00000000 --- a/src/logic/scripting/lua/libplayer.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef LOGIC_SCRIPTING_LUA_LIBPLAYER_H_ -#define LOGIC_SCRIPTING_LUA_LIBPLAYER_H_ - -#include "lua_commons.h" - -/* == player library ==*/ -extern int l_player_get_pos(lua_State* L); -extern int l_player_set_pos(lua_State* L); -extern int l_player_get_vel(lua_State* L); -extern int l_player_set_vel(lua_State* L); -extern int l_player_get_rot(lua_State* L); -extern int l_player_set_rot(lua_State* L); -extern int l_player_get_inv(lua_State* L); - -static const luaL_Reg playerlib [] = { - {"get_pos", lua_wrap_errors}, - {"set_pos", lua_wrap_errors}, - {"get_vel", lua_wrap_errors}, - {"set_vel", lua_wrap_errors}, - {"get_rot", lua_wrap_errors}, - {"set_rot", lua_wrap_errors}, - {"get_inventory", lua_wrap_errors}, - {NULL, NULL} -}; - -#endif // LOGIC_SCRIPTING_LUA_LIBPLAYER_H_ diff --git a/src/logic/scripting/lua/libtime.cpp b/src/logic/scripting/lua/libtime.cpp new file mode 100644 index 00000000..9347e23b --- /dev/null +++ b/src/logic/scripting/lua/libtime.cpp @@ -0,0 +1,21 @@ +#include "api_lua.h" +#include "lua_commons.h" +#include "../scripting.h" +#include "../../../engine.h" +#include "../../../window/Window.h" + +static int l_time_uptime(lua_State* L) { + lua_pushnumber(L, Window::time()); + return 1; +} + +static int l_time_delta(lua_State* L) { + lua_pushnumber(L, scripting::engine->getDelta()); + return 1; +} + +const luaL_Reg timelib [] = { + {"uptime", lua_wrap_errors}, + {"delta", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/libworld.cpp b/src/logic/scripting/lua/libworld.cpp new file mode 100644 index 00000000..aea29404 --- /dev/null +++ b/src/logic/scripting/lua/libworld.cpp @@ -0,0 +1,36 @@ +#include "lua_commons.h" +#include "api_lua.h" +#include "../scripting.h" +#include "../../../world/Level.h" +#include "../../../world/World.h" + +#include + +static int l_world_get_total_time(lua_State* L) { + lua_pushnumber(L, scripting::level->world->totalTime); + return 1; +} + +static int l_world_get_day_time(lua_State* L) { + lua_pushnumber(L, scripting::level->world->daytime); + return 1; +} + +static int l_world_set_day_time(lua_State* L) { + double value = lua_tonumber(L, 1); + scripting::level->world->daytime = fmod(value, 1.0); + return 0; +} + +static int l_world_get_seed(lua_State* L) { + lua_pushinteger(L, scripting::level->world->getSeed()); + return 1; +} + +const luaL_Reg worldlib [] = { + {"get_total_time", lua_wrap_errors}, + {"get_day_time", lua_wrap_errors}, + {"set_day_time", lua_wrap_errors}, + {"get_seed", lua_wrap_errors}, + {NULL, NULL} +}; diff --git a/src/logic/scripting/lua/lua_overrides.cpp b/src/logic/scripting/lua/lua_overrides.cpp new file mode 100644 index 00000000..20ef61a5 --- /dev/null +++ b/src/logic/scripting/lua/lua_overrides.cpp @@ -0,0 +1,26 @@ +#include "api_lua.h" +#include "lua_commons.h" + +#include + +/// @brief Modified version of luaB_print from lbaselib.c +int l_print(lua_State* L) { + int n = lua_gettop(L); /* number of arguments */ + lua_getglobal(L, "tostring"); + for (int i=1; i<=n; i++) { + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + const char* s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + return luaL_error(L, LUA_QL("tostring") " must return a string to " + LUA_QL("print")); + if (i > 1) + std::cout << "\t"; + std::cout << s; + lua_pop(L, 1); /* pop result */ + } + std::cout << std::endl; + return 0; +} + diff --git a/src/logic/scripting/scripting_frontend.cpp b/src/logic/scripting/scripting_frontend.cpp index 00923457..25828b70 100644 --- a/src/logic/scripting/scripting_frontend.cpp +++ b/src/logic/scripting/scripting_frontend.cpp @@ -1,7 +1,7 @@ #include "scripting_frontend.h" #include "scripting.h" -#include "lua/libhud.h" +#include "lua/api_lua.h" #include "lua/LuaState.h" #include "../../frontend/hud.h"