From 1145267308594c1a51e20c5298b82b1b6574c255 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 14 Feb 2024 01:37:10 +0300 Subject: [PATCH] lua api refactor --- src/logic/scripting/LuaState.cpp | 2 + src/logic/scripting/api/api_lua.cpp | 493 ++++++++++++++++++++++++++ src/logic/scripting/api/api_lua.h | 518 +++------------------------- 3 files changed, 539 insertions(+), 474 deletions(-) create mode 100644 src/logic/scripting/api/api_lua.cpp diff --git a/src/logic/scripting/LuaState.cpp b/src/logic/scripting/LuaState.cpp index 8a42e42a..7a81e237 100644 --- a/src/logic/scripting/LuaState.cpp +++ b/src/logic/scripting/LuaState.cpp @@ -1,5 +1,7 @@ #include "LuaState.h" +#include +#include "lua_util.h" #include "api/api_lua.h" #include "api/libgui.h" #include "../../util/stringutil.h" diff --git a/src/logic/scripting/api/api_lua.cpp b/src/logic/scripting/api/api_lua.cpp new file mode 100644 index 00000000..27878066 --- /dev/null +++ b/src/logic/scripting/api/api_lua.cpp @@ -0,0 +1,493 @@ +#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 "../../../items/ItemDef.h" +#include "../../../items/ItemStack.h" +#include "../../../items/Inventory.h" +#include "../../../items/Inventories.h" +#include "../../../lighting/Lighting.h" +#include "../../../logic/BlocksController.h" +#include "../../../window/Window.h" +#include "../../../engine.h" + +/* == file library == */ +int l_file_resolve(lua_State* L) { + std::string path = lua_tostring(L, 1); + fs::path resolved = scripting::engine->getPaths()->resolve(path); + lua_pushstring(L, resolved.u8string().c_str()); + return 1; +} + +int l_file_read(lua_State* L) { + auto paths = scripting::engine->getPaths(); + fs::path path = paths->resolve(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) { + auto paths = scripting::engine->getPaths(); + fs::path path = paths->resolve(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) { + auto paths = scripting::engine->getPaths(); + fs::path path = paths->resolve(lua_tostring(L, 1)); + lua_pushboolean(L, fs::exists(path)); + return 1; +} + +int l_file_isfile(lua_State* L) { + auto paths = scripting::engine->getPaths(); + fs::path path = paths->resolve(lua_tostring(L, 1)); + lua_pushboolean(L, fs::is_regular_file(path)); + return 1; +} + +int l_file_isdir(lua_State* L) { + auto paths = scripting::engine->getPaths(); + fs::path path = paths->resolve(lua_tostring(L, 1)); + lua_pushboolean(L, fs::is_directory(path)); + return 1; +} + +int l_file_length(lua_State* L) { + auto paths = scripting::engine->getPaths(); + fs::path path = paths->resolve(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) { + auto paths = scripting::engine->getPaths(); + fs::path path = paths->resolve(lua_tostring(L, 1)); + lua_pushboolean(L, fs::create_directory(path)); + 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; +} + +/* == player library ==*/ +int l_player_get_pos(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + glm::vec3 pos = scripting::level->player->hitbox->position; + lua_pushnumber(L, pos.x); + lua_pushnumber(L, pos.y); + lua_pushnumber(L, pos.z); + return 3; +} + +int l_player_get_rot(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + glm::vec2 rot = scripting::level->player->cam; + lua_pushnumber(L, rot.x); + lua_pushnumber(L, rot.y); + return 2; +} + +int l_player_set_rot(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + lua::luanumber x = lua_tonumber(L, 2); + lua::luanumber y = lua_tonumber(L, 3); + glm::vec2& cam = scripting::level->player->cam; + cam.x = x; + cam.y = y; + return 0; +} + +int l_player_set_pos(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + lua::luanumber x = lua_tonumber(L, 2); + lua::luanumber y = lua_tonumber(L, 3); + lua::luanumber z = lua_tonumber(L, 4); + scripting::level->player->hitbox->position = glm::vec3(x, y, z); + return 0; +} + +int l_player_get_inv(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + Player* player = scripting::level->player; + lua_pushinteger(L, player->getInventory()->getId()); + lua_pushinteger(L, player->getChosenSlot()); + return 2; +} + +static void validate_itemid(lua_State* L, itemid_t id) { + if (id >= scripting::indices->countItemDefs()) { + luaL_error(L, "invalid item id"); + } +} + +/* == inventory library == */ +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); + if (inv == nullptr) { + luaL_error(L, "inventory does not exists in runtime: %d", invid); + } + if (slotid < 0 || uint64_t(slotid) >= inv->size()) { + luaL_error(L, "slot index is out of range [0, inventory.size(invid)]"); + } + ItemStack& item = inv->getSlot(slotid); + lua_pushinteger(L, item.getItemId()); + lua_pushinteger(L, item.getCount()); + return 2; +} + +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); + lua::luaint count = lua_tointeger(L, 4); + validate_itemid(L, itemid); + + auto inv = scripting::level->inventories->get(invid); + if (inv == nullptr) { + luaL_error(L, "inventory does not exists in runtime: %d", invid); + } + if (slotid < 0 || uint64_t(slotid) >= inv->size()) { + luaL_error(L, "slot index is out of range [0, inventory.size(invid)]"); + } + ItemStack& item = inv->getSlot(slotid); + item.set(ItemStack(itemid, count)); + return 0; +} + +int l_inventory_size(lua_State* L) { + lua::luaint invid = lua_tointeger(L, 1); + auto inv = scripting::level->inventories->get(invid); + if (inv == nullptr) { + luaL_error(L, "inventory does not exists in runtime: %d", invid); + } + lua_pushinteger(L, inv->size()); + return 1; +} + +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); + validate_itemid(L, itemid); + + auto inv = scripting::level->inventories->get(invid); + if (inv == nullptr) { + luaL_error(L, "inventory does not exists in runtime: %d", invid); + } + ItemStack item(itemid, count); + inv->move(item, scripting::indices); + lua_pushinteger(L, item.getCount()); + return 1; +} + +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); + int64_t id = scripting::blocks->createBlockInventory(x, y, z); + lua_pushinteger(L, id); + 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_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_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/api/api_lua.h b/src/logic/scripting/api/api_lua.h index 43b639cd..d6a59bfb 100644 --- a/src/logic/scripting/api/api_lua.h +++ b/src/logic/scripting/api/api_lua.h @@ -1,94 +1,17 @@ #ifndef LOGIC_SCRIPTING_API_LUA_H_ #define LOGIC_SCRIPTING_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 "../../../items/ItemDef.h" -#include "../../../items/ItemStack.h" -#include "../../../items/Inventory.h" -#include "../../../items/Inventories.h" -#include "../../../lighting/Lighting.h" -#include "../../../logic/BlocksController.h" -#include "../../../window/Window.h" -#include "../../../engine.h" +#include /* == file library == */ -static int l_file_resolve(lua_State* L) { - std::string path = lua_tostring(L, 1); - fs::path resolved = scripting::engine->getPaths()->resolve(path); - lua_pushstring(L, resolved.u8string().c_str()); - return 1; -} - -static int l_file_read(lua_State* L) { - auto paths = scripting::engine->getPaths(); - fs::path path = paths->resolve(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) { - auto paths = scripting::engine->getPaths(); - fs::path path = paths->resolve(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) { - auto paths = scripting::engine->getPaths(); - fs::path path = paths->resolve(lua_tostring(L, 1)); - lua_pushboolean(L, fs::exists(path)); - return 1; -} - -static int l_file_isfile(lua_State* L) { - auto paths = scripting::engine->getPaths(); - fs::path path = paths->resolve(lua_tostring(L, 1)); - lua_pushboolean(L, fs::is_regular_file(path)); - return 1; -} - -static int l_file_isdir(lua_State* L) { - auto paths = scripting::engine->getPaths(); - fs::path path = paths->resolve(lua_tostring(L, 1)); - lua_pushboolean(L, fs::is_directory(path)); - return 1; -} - -static int l_file_length(lua_State* L) { - auto paths = scripting::engine->getPaths(); - fs::path path = paths->resolve(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) { - auto paths = scripting::engine->getPaths(); - fs::path path = paths->resolve(lua_tostring(L, 1)); - lua_pushboolean(L, fs::create_directory(path)); - return 1; -} +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); static const luaL_Reg filelib [] = { {"resolve", l_file_resolve}, @@ -103,15 +26,8 @@ static const luaL_Reg filelib [] = { }; /* == time library == */ -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; -} +extern int l_time_uptime(lua_State* L); +extern int l_time_delta(lua_State* L); static const luaL_Reg timelib [] = { {"uptime", l_time_uptime}, @@ -120,23 +36,7 @@ static const luaL_Reg timelib [] = { }; /* == pack library == */ -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; -} +extern int l_pack_get_folder(lua_State* L); static const luaL_Reg packlib [] = { {"get_folder", l_pack_get_folder}, @@ -144,26 +44,10 @@ static const luaL_Reg packlib [] = { }; /* == world library == */ -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; -} +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", l_world_get_total_time}, @@ -174,59 +58,11 @@ static const luaL_Reg worldlib [] = { }; /* == player library ==*/ -static int l_player_get_pos(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - glm::vec3 pos = scripting::level->player->hitbox->position; - lua_pushnumber(L, pos.x); - lua_pushnumber(L, pos.y); - lua_pushnumber(L, pos.z); - return 3; -} - -static int l_player_get_rot(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - glm::vec2 rot = scripting::level->player->cam; - lua_pushnumber(L, rot.x); - lua_pushnumber(L, rot.y); - return 2; -} - -static int l_player_set_rot(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - glm::vec2& cam = scripting::level->player->cam; - cam.x = x; - cam.y = y; - return 0; -} - -static int l_player_set_pos(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - lua::luanumber z = lua_tonumber(L, 4); - scripting::level->player->hitbox->position = glm::vec3(x, y, z); - return 0; -} - -static int l_player_get_inv(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - Player* player = scripting::level->player; - lua_pushinteger(L, player->getInventory()->getId()); - lua_pushinteger(L, player->getChosenSlot()); - return 2; -} +extern int l_player_get_pos(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_set_pos(lua_State* L); +extern int l_player_get_inv(lua_State* L); static const luaL_Reg playerlib [] = { {"get_pos", l_player_get_pos}, @@ -237,82 +73,12 @@ static const luaL_Reg playerlib [] = { {NULL, NULL} }; -static void validate_itemid(lua_State* L, itemid_t id) { - if (id >= scripting::indices->countItemDefs()) { - luaL_error(L, "invalid item id"); - } -} - /* == inventory library == */ -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); - if (inv == nullptr) { - luaL_error(L, "inventory does not exists in runtime: %d", invid); - } - if (slotid < 0 || uint64_t(slotid) >= inv->size()) { - luaL_error(L, "slot index is out of range [0, inventory.size(invid)]"); - } - ItemStack& item = inv->getSlot(slotid); - lua_pushinteger(L, item.getItemId()); - lua_pushinteger(L, item.getCount()); - return 2; -} - -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); - lua::luaint count = lua_tointeger(L, 4); - validate_itemid(L, itemid); - - auto inv = scripting::level->inventories->get(invid); - if (inv == nullptr) { - luaL_error(L, "inventory does not exists in runtime: %d", invid); - } - if (slotid < 0 || uint64_t(slotid) >= inv->size()) { - luaL_error(L, "slot index is out of range [0, inventory.size(invid)]"); - } - ItemStack& item = inv->getSlot(slotid); - item.set(ItemStack(itemid, count)); - return 0; -} - -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) { - luaL_error(L, "inventory does not exists in runtime: %d", invid); - } - lua_pushinteger(L, inv->size()); - return 1; -} - -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); - validate_itemid(L, itemid); - - auto inv = scripting::level->inventories->get(invid); - if (inv == nullptr) { - luaL_error(L, "inventory does not exists in runtime: %d", invid); - } - ItemStack item(itemid, count); - inv->move(item, scripting::indices); - lua_pushinteger(L, item.getCount()); - return 1; -} - -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); - int64_t id = scripting::blocks->createBlockInventory(x, y, z); - lua_pushinteger(L, id); - return 1; -} +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); static const luaL_Reg inventorylib [] = { {"get", l_inventory_get}, @@ -324,38 +90,10 @@ static const luaL_Reg inventorylib [] = { }; /* == item library == */ -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; -} +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", l_item_index}, @@ -366,189 +104,21 @@ static const luaL_Reg itemlib [] = { }; /* == blocks-related functions == */ -static 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; -} - -static 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; -} - -static int l_blocks_count(lua_State* L) { - lua_pushinteger(L, scripting::indices->countBlockDefs()); - return 1; -} - -static int l_block_index(lua_State* L) { - auto name = lua_tostring(L, 1); - lua_pushinteger(L, scripting::content->requireBlock(name).rt.id); - return 1; -} - -static 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; -} - -static 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; -} - -static 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); - } -} - -static 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); - } -} - -static 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); - } -} - -static 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; -} - -static 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; -} - -static 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; -} - -static 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; -} +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_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 -static 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; -} +extern int l_print(lua_State* L); #endif // LOGIC_SCRIPTING_API_LUA_H_