diff --git a/src/logic/BlocksController.cpp b/src/logic/BlocksController.cpp index 03e4e9c1..b3d9bfd1 100644 --- a/src/logic/BlocksController.cpp +++ b/src/logic/BlocksController.cpp @@ -169,3 +169,26 @@ int64_t BlocksController::createBlockInventory(int x, int y, int z) { } return inv->getId(); } + +void BlocksController::bindInventory(int64_t invid, int x, int y, int z) { + auto chunk = chunks->getChunkByVoxel(x, y, z); + if (chunk == nullptr) { + throw std::runtime_error("block does not exists"); + } + if (invid <= 0) { + throw std::runtime_error("unable to bind virtual inventory"); + } + int lx = x - chunk->x * CHUNK_W; + int lz = z - chunk->z * CHUNK_D; + chunk->addBlockInventory(level->inventories->get(invid), lx, y, lz); +} + +void BlocksController::unbindInventory(int x, int y, int z) { + auto chunk = chunks->getChunkByVoxel(x, y, z); + if (chunk == nullptr) { + throw std::runtime_error("block does not exists"); + } + int lx = x - chunk->x * CHUNK_W; + int lz = z - chunk->z * CHUNK_D; + chunk->removeBlockInventory(lx, y, lz); +} diff --git a/src/logic/BlocksController.h b/src/logic/BlocksController.h index c4171f80..bb837938 100644 --- a/src/logic/BlocksController.h +++ b/src/logic/BlocksController.h @@ -48,6 +48,8 @@ public: void randomTick(int tickid, int parts); void onBlocksTick(int tickid, int parts); int64_t createBlockInventory(int x, int y, int z); + void bindInventory(int64_t invid, int x, int y, int z); + void unbindInventory(int x, int y, int z); }; #endif // LOGIC_BLOCKS_CONTROLLER_H_ diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index fd240c5d..381d4edc 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -4,6 +4,7 @@ #include "lua_util.h" #include "api_lua.h" #include "libgui.h" +#include "libinventory.h" #include "../../../util/stringutil.h" lua::luaerror::luaerror(const std::string& message) : std::runtime_error(message) { diff --git a/src/logic/scripting/lua/LuaState.h b/src/logic/scripting/lua/LuaState.h index 860a4cbd..8c76f233 100644 --- a/src/logic/scripting/lua/LuaState.h +++ b/src/logic/scripting/lua/LuaState.h @@ -1,7 +1,7 @@ #ifndef LOGIC_SCRIPTING_LUA_STATE_H_ #define LOGIC_SCRIPTING_LUA_STATE_H_ -#include +#include "lua_commons.h" #include #include @@ -10,9 +10,6 @@ #endif namespace lua { - using luaint = lua_Integer; - using luanumber = lua_Number; - class luaerror : public std::runtime_error { public: luaerror(const std::string& message); diff --git a/src/logic/scripting/lua/api_lua.cpp b/src/logic/scripting/lua/api_lua.cpp index 1049e633..88835056 100644 --- a/src/logic/scripting/lua/api_lua.cpp +++ b/src/logic/scripting/lua/api_lua.cpp @@ -17,7 +17,6 @@ #include "../../../voxels/voxel.h" #include "../../../voxels/Chunk.h" #include "../../../items/ItemDef.h" -#include "../../../items/ItemStack.h" #include "../../../items/Inventory.h" #include "../../../items/Inventories.h" #include "../../../lighting/Lighting.h" @@ -198,83 +197,6 @@ int l_player_get_inv(lua_State* L) { 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(); diff --git a/src/logic/scripting/lua/api_lua.h b/src/logic/scripting/lua/api_lua.h index 62e21923..ea809ceb 100644 --- a/src/logic/scripting/lua/api_lua.h +++ b/src/logic/scripting/lua/api_lua.h @@ -2,24 +2,7 @@ #define LOGIC_SCRIPTING_API_LUA_H_ #include -#include - -template int lua_wrap_errors(lua_State *L) { - int result = 0; - try { - result = func(L); - } - // transform exception with description into lua_error - catch (std::exception &e) { - luaL_error(L, e.what()); - } - // Rethrow any other exception (lua error for example) - catch (...) { - throw; - } - - return result; -} +#include "lua_commons.h" /* == file library == */ extern int l_file_resolve(lua_State* L); @@ -91,22 +74,6 @@ static const luaL_Reg playerlib [] = { {NULL, NULL} }; -/* == inventory library == */ -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", lua_wrap_errors}, - {"set", lua_wrap_errors}, - {"size", lua_wrap_errors}, - {"add", lua_wrap_errors}, - {"get_block", lua_wrap_errors}, - {NULL, NULL} -}; - /* == item library == */ extern int l_item_name(lua_State* L); extern int l_item_index(lua_State* L); diff --git a/src/logic/scripting/lua/libhud.h b/src/logic/scripting/lua/libhud.h index 167b5f03..88800dfe 100644 --- a/src/logic/scripting/lua/libhud.h +++ b/src/logic/scripting/lua/libhud.h @@ -1,7 +1,7 @@ #ifndef LOGIC_SCRIPTING_API_LIBHUD_H_ #define LOGIC_SCRIPTING_API_LIBHUD_H_ -#include +#include "lua_commons.h" extern int l_hud_open_inventory(lua_State* L); extern int l_hud_close_inventory(lua_State* L); @@ -10,11 +10,11 @@ extern int l_hud_open_permanent(lua_State* L); extern int l_hud_close(lua_State* L); static const luaL_Reg hudlib [] = { - {"open_inventory", l_hud_open_inventory}, - {"close_inventory", l_hud_close_inventory}, - {"open_block", l_hud_open_block}, - {"open_permanent", l_hud_open_permanent}, - {"close", l_hud_close}, + {"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/libinventory.cpp b/src/logic/scripting/lua/libinventory.cpp new file mode 100644 index 00000000..69d2e4c8 --- /dev/null +++ b/src/logic/scripting/lua/libinventory.cpp @@ -0,0 +1,103 @@ +#include "libinventory.h" + +#include "lua_util.h" +#include "../scripting.h" +#include "../../../content/Content.h" +#include "../../../world/Level.h" +#include "../../../items/ItemStack.h" +#include "../../../items/Inventories.h" +#include "../../../logic/BlocksController.h" + +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; +} + +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); + lua::luaint z = lua_tointeger(L, 4); + scripting::blocks->bindInventory(id, x, y, z); + return 0; +} + +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); + scripting::blocks->unbindInventory(x, y, z); + return 0; +} diff --git a/src/logic/scripting/lua/libinventory.h b/src/logic/scripting/lua/libinventory.h new file mode 100644 index 00000000..b6510e6f --- /dev/null +++ b/src/logic/scripting/lua/libinventory.h @@ -0,0 +1,25 @@ +#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); + +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}, + {NULL, NULL} +}; + +#endif // LOGIC_SCRIPTING_API_LIBINVENTORY_H_ diff --git a/src/logic/scripting/lua/lua_commons.h b/src/logic/scripting/lua/lua_commons.h new file mode 100644 index 00000000..c139be40 --- /dev/null +++ b/src/logic/scripting/lua/lua_commons.h @@ -0,0 +1,28 @@ +#ifndef LOGIC_SCRIPTING_LUA_H_ +#define LOGIC_SCRIPTING_LUA_H_ + +#include +#include + +namespace lua { + using luaint = lua_Integer; + using luanumber = lua_Number; +} + +template int lua_wrap_errors(lua_State *L) { + int result = 0; + try { + result = func(L); + } + // transform exception with description into lua_error + catch (std::exception &e) { + luaL_error(L, e.what()); + } + // Rethrow any other exception (lua error for example) + catch (...) { + throw; + } + return result; +} + +#endif // LOGIC_SCRIPTING_LUA_H_ \ No newline at end of file