X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fscript%2Flua_api%2Fl_inventory.cpp;h=6e7afa4a4e67bf67575341f79af1ee72b1397d6e;hb=91eef646a59575bd9ae792e257bb6ad12fafc0b1;hp=1404c3c8a026fcbf00ca6c57506f1cda50aeab8b;hpb=64627817fcca52f20948c24b60ce192b218f6ce2;p=dragonfireclient.git diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp index 1404c3c8a..6e7afa4a4 100644 --- a/src/script/lua_api/l_inventory.cpp +++ b/src/script/lua_api/l_inventory.cpp @@ -17,15 +17,13 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "cpp_api/scriptapi.h" -#include "common/c_converter.h" -#include "common/c_content.h" #include "lua_api/l_inventory.h" +#include "lua_api/l_internal.h" #include "lua_api/l_item.h" -#include "common/c_internal.h" +#include "common/c_converter.h" +#include "common/c_content.h" #include "server.h" -#include "log.h" -#include "inventorymanager.h" +#include "remoteplayer.h" /* InvRef @@ -40,7 +38,7 @@ InvRef* InvRef::checkobject(lua_State *L, int narg) Inventory* InvRef::getinv(lua_State *L, InvRef *ref) { - return STACK_TO_SERVER(L)->getInventory(ref->m_loc); + return getServer(L)->getInventory(ref->m_loc); } InventoryList* InvRef::getlist(lua_State *L, InvRef *ref, @@ -56,7 +54,7 @@ InventoryList* InvRef::getlist(lua_State *L, InvRef *ref, void InvRef::reportInventoryChange(lua_State *L, InvRef *ref) { // Inform other things that the inventory has changed - STACK_TO_SERVER(L)->setInventoryModified(ref->m_loc); + getServer(L)->setInventoryModified(ref->m_loc); } // Exported functions @@ -119,21 +117,38 @@ int InvRef::l_set_size(lua_State *L) NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); + int newsize = luaL_checknumber(L, 3); + if (newsize < 0) { + lua_pushboolean(L, false); + return 1; + } + Inventory *inv = getinv(L, ref); + if(inv == NULL){ + lua_pushboolean(L, false); + return 1; + } if(newsize == 0){ inv->deleteList(listname); reportInventoryChange(L, ref); - return 0; + lua_pushboolean(L, true); + return 1; } InventoryList *list = inv->getList(listname); if(list){ list->setSize(newsize); } else { list = inv->addList(listname, newsize); + if (!list) + { + lua_pushboolean(L, false); + return 1; + } } reportInventoryChange(L, ref); - return 0; + lua_pushboolean(L, true); + return 1; } // set_width(self, listname, size) @@ -144,6 +159,9 @@ int InvRef::l_set_width(lua_State *L) const char *listname = luaL_checkstring(L, 2); int newwidth = luaL_checknumber(L, 3); Inventory *inv = getinv(L, ref); + if(inv == NULL){ + return 0; + } InventoryList *list = inv->getList(listname); if(list){ list->setWidth(newwidth); @@ -176,7 +194,7 @@ int InvRef::l_set_stack(lua_State *L) InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); int i = luaL_checknumber(L, 3) - 1; - ItemStack newitem = read_item(L, 4,STACK_TO_SERVER(L)); + ItemStack newitem = read_item(L, 4, getServer(L)->idef()); InventoryList *list = getlist(L, ref, listname); if(list != NULL && i >= 0 && i < (int) list->getSize()){ list->changeItem(i, newitem); @@ -195,7 +213,11 @@ int InvRef::l_get_list(lua_State *L) InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); Inventory *inv = getinv(L, ref); - push_inventory_list(inv, listname, L); + if(inv){ + push_inventory_list(L, inv, listname); + } else { + lua_pushnil(L); + } return 1; } @@ -206,16 +228,66 @@ int InvRef::l_set_list(lua_State *L) InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); Inventory *inv = getinv(L, ref); + if(inv == NULL){ + return 0; + } InventoryList *list = inv->getList(listname); if(list) - read_inventory_list(inv, listname, L, 3, - STACK_TO_SERVER(L),list->getSize()); + read_inventory_list(L, 3, inv, listname, + getServer(L), list->getSize()); else - read_inventory_list(inv, listname, L, 3,STACK_TO_SERVER(L)); + read_inventory_list(L, 3, inv, listname, getServer(L)); reportInventoryChange(L, ref); return 0; } +// get_lists(self) -> list of InventoryLists +int InvRef::l_get_lists(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + Inventory *inv = getinv(L, ref); + if (!inv) { + return 0; + } + std::vector lists = inv->getLists(); + std::vector::iterator iter = lists.begin(); + lua_createtable(L, 0, lists.size()); + for (; iter != lists.end(); iter++) { + const char* name = (*iter)->getName().c_str(); + lua_pushstring(L, name); + push_inventory_list(L, inv, name); + lua_rawset(L, -3); + } + return 1; +} + +// set_lists(self, lists) +int InvRef::l_set_lists(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + InvRef *ref = checkobject(L, 1); + Inventory *inv = getinv(L, ref); + if (!inv) { + return 0; + } + + // Make a temporary inventory in case reading fails + Inventory *tempInv(inv); + tempInv->clear(); + + Server *server = getServer(L); + + lua_pushnil(L); + while (lua_next(L, 2)) { + const char *listname = lua_tostring(L, -2); + read_inventory_list(L, -1, tempInv, listname, server); + lua_pop(L, 1); + } + inv = tempInv; + return 0; +} + // add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack // Returns the leftover stack int InvRef::l_add_item(lua_State *L) @@ -223,7 +295,7 @@ int InvRef::l_add_item(lua_State *L) NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); - ItemStack item = read_item(L, 3,STACK_TO_SERVER(L)); + ItemStack item = read_item(L, 3, getServer(L)->idef()); InventoryList *list = getlist(L, ref, listname); if(list){ ItemStack leftover = list->addItem(item); @@ -243,7 +315,7 @@ int InvRef::l_room_for_item(lua_State *L) NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); - ItemStack item = read_item(L, 3,STACK_TO_SERVER(L)); + ItemStack item = read_item(L, 3, getServer(L)->idef()); InventoryList *list = getlist(L, ref, listname); if(list){ lua_pushboolean(L, list->roomForItem(item)); @@ -253,17 +325,20 @@ int InvRef::l_room_for_item(lua_State *L) return 1; } -// contains_item(self, listname, itemstack or itemstring or table or nil) -> true/false -// Returns true if the list contains the given count of the given item name +// contains_item(self, listname, itemstack or itemstring or table or nil, [match_meta]) -> true/false +// Returns true if the list contains the given count of the given item int InvRef::l_contains_item(lua_State *L) { NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); - ItemStack item = read_item(L, 3, STACK_TO_SERVER(L)); + ItemStack item = read_item(L, 3, getServer(L)->idef()); InventoryList *list = getlist(L, ref, listname); - if(list){ - lua_pushboolean(L, list->containsItem(item)); + bool match_meta = false; + if (lua_isboolean(L, 4)) + match_meta = readParam(L, 4); + if (list) { + lua_pushboolean(L, list->containsItem(item, match_meta)); } else { lua_pushboolean(L, false); } @@ -277,7 +352,7 @@ int InvRef::l_remove_item(lua_State *L) NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); - ItemStack item = read_item(L, 3,STACK_TO_SERVER(L)); + ItemStack item = read_item(L, 3, getServer(L)->idef()); InventoryList *list = getlist(L, ref, listname); if(list){ ItemStack removed = list->removeItem(item); @@ -290,7 +365,7 @@ int InvRef::l_remove_item(lua_State *L) return 1; } -// get_location() -> location (like minetest.get_inventory(location)) +// get_location() -> location (like get_inventory(location)) int InvRef::l_get_location(lua_State *L) { NO_MAP_LOCK_REQUIRED; @@ -334,10 +409,6 @@ InvRef::InvRef(const InventoryLocation &loc): { } -InvRef::~InvRef() -{ -} - // Creates an InvRef and leaves it on top of stack // Not callable from Lua; all references are created on the C side. void InvRef::create(lua_State *L, const InventoryLocation &loc) @@ -348,7 +419,7 @@ void InvRef::create(lua_State *L, const InventoryLocation &loc) luaL_getmetatable(L, className); lua_setmetatable(L, -2); } -void InvRef::createPlayer(lua_State *L, Player *player) +void InvRef::createPlayer(lua_State *L, RemotePlayer *player) { NO_MAP_LOCK_REQUIRED; InventoryLocation loc; @@ -391,7 +462,7 @@ void InvRef::Register(lua_State *L) } const char InvRef::className[] = "InvRef"; -const luaL_reg InvRef::methods[] = { +const luaL_Reg InvRef::methods[] = { luamethod(InvRef, is_empty), luamethod(InvRef, get_size), luamethod(InvRef, set_size), @@ -401,6 +472,8 @@ const luaL_reg InvRef::methods[] = { luamethod(InvRef, set_stack), luamethod(InvRef, get_list), luamethod(InvRef, set_list), + luamethod(InvRef, get_lists), + luamethod(InvRef, set_lists), luamethod(InvRef, add_item), luamethod(InvRef, room_for_item), luamethod(InvRef, contains_item), @@ -417,63 +490,64 @@ int ModApiInventory::l_get_inventory(lua_State *L) std::string type = checkstringfield(L, 1, "type"); if(type == "node"){ + MAP_LOCK_REQUIRED; lua_getfield(L, 1, "pos"); v3s16 pos = check_v3s16(L, -1); loc.setNodeMeta(pos); - if(getServer(L)->getInventory(loc) != NULL) + if (getServer(L)->getInventory(loc) != NULL) InvRef::create(L, loc); else lua_pushnil(L); return 1; - } else { - NO_MAP_LOCK_REQUIRED; - if(type == "player"){ - std::string name = checkstringfield(L, 1, "name"); - loc.setPlayer(name); - } else if(type == "detached"){ - std::string name = checkstringfield(L, 1, "name"); - loc.setDetached(name); - } + } - if(getServer(L)->getInventory(loc) != NULL) - InvRef::create(L, loc); - else - lua_pushnil(L); - return 1; - // END NO_MAP_LOCK_REQUIRED; + NO_MAP_LOCK_REQUIRED; + if (type == "player") { + std::string name = checkstringfield(L, 1, "name"); + loc.setPlayer(name); + } else if (type == "detached") { + std::string name = checkstringfield(L, 1, "name"); + loc.setDetached(name); } + + if (getServer(L)->getInventory(loc) != NULL) + InvRef::create(L, loc); + else + lua_pushnil(L); + return 1; + // END NO_MAP_LOCK_REQUIRED; + } -// create_detached_inventory_raw(name) +// create_detached_inventory_raw(name, [player_name]) int ModApiInventory::l_create_detached_inventory_raw(lua_State *L) { NO_MAP_LOCK_REQUIRED; const char *name = luaL_checkstring(L, 1); - if(getServer(L)->createDetachedInventory(name) != NULL){ + std::string player = readParam(L, 2, ""); + if (getServer(L)->createDetachedInventory(name, player) != NULL) { InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - }else{ + } else { lua_pushnil(L); } return 1; } -bool ModApiInventory::Initialize(lua_State *L, int top) { - bool retval = true; - - retval &= API_FCT(create_detached_inventory_raw); - retval &= API_FCT(get_inventory); - - InvRef::Register(L); - - return retval; +// remove_detached_inventory_raw(name) +int ModApiInventory::l_remove_detached_inventory_raw(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const std::string &name = luaL_checkstring(L, 1); + lua_pushboolean(L, getServer(L)->removeDetachedInventory(name)); + return 1; } -ModApiInventory::ModApiInventory() - : ModApiBase() { - +void ModApiInventory::Initialize(lua_State *L, int top) +{ + API_FCT(create_detached_inventory_raw); + API_FCT(remove_detached_inventory_raw); + API_FCT(get_inventory); } - -ModApiInventory modapiinventory_prototype;