diff options
author | Weblate <42@minetest.ru> | 2013-06-01 13:18:52 +0200 |
---|---|---|
committer | Weblate <42@minetest.ru> | 2013-06-01 13:18:52 +0200 |
commit | 1dfc2e02b3c358af4bb20bb3cb60ac7bd3ed1124 (patch) | |
tree | 54660f353f3342f89b6259ea6a5dfedfa20dc16f /src/script/lua_api/l_inventory.cpp | |
parent | ec039a3d123120f9918812b13f5971e94546b9af (diff) | |
parent | 64627817fcca52f20948c24b60ce192b218f6ce2 (diff) | |
download | hax-minetest-server-1dfc2e02b3c358af4bb20bb3cb60ac7bd3ed1124.tar.gz hax-minetest-server-1dfc2e02b3c358af4bb20bb3cb60ac7bd3ed1124.zip |
Merge remote-tracking branch 'origin/master'
Diffstat (limited to '')
-rw-r--r-- | src/script/lua_api/l_inventory.cpp (renamed from src/scriptapi_inventory.cpp) | 411 |
1 files changed, 82 insertions, 329 deletions
diff --git a/src/scriptapi_inventory.cpp b/src/script/lua_api/l_inventory.cpp index bb40748db..1404c3c8a 100644 --- a/src/scriptapi_inventory.cpp +++ b/src/script/lua_api/l_inventory.cpp @@ -17,17 +17,15 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "scriptapi.h" -#include "scriptapi_inventory.h" +#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_item.h" +#include "common/c_internal.h" #include "server.h" -#include "script.h" #include "log.h" -#include "scriptapi_types.h" -#include "scriptapi_common.h" -#include "scriptapi_inventory.h" -#include "scriptapi_item.h" -#include "scriptapi_object.h" - +#include "inventorymanager.h" /* InvRef @@ -42,12 +40,13 @@ InvRef* InvRef::checkobject(lua_State *L, int narg) Inventory* InvRef::getinv(lua_State *L, InvRef *ref) { - return get_server(L)->getInventory(ref->m_loc); + return STACK_TO_SERVER(L)->getInventory(ref->m_loc); } InventoryList* InvRef::getlist(lua_State *L, InvRef *ref, const char *listname) { + NO_MAP_LOCK_REQUIRED; Inventory *inv = getinv(L, ref); if(!inv) return NULL; @@ -57,7 +56,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 - get_server(L)->setInventoryModified(ref->m_loc); + STACK_TO_SERVER(L)->setInventoryModified(ref->m_loc); } // Exported functions @@ -72,6 +71,7 @@ int InvRef::gc_object(lua_State *L) { // is_empty(self, listname) -> true/false int InvRef::l_is_empty(lua_State *L) { + NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); InventoryList *list = getlist(L, ref, listname); @@ -86,6 +86,7 @@ int InvRef::l_is_empty(lua_State *L) // get_size(self, listname) int InvRef::l_get_size(lua_State *L) { + NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); InventoryList *list = getlist(L, ref, listname); @@ -100,6 +101,7 @@ int InvRef::l_get_size(lua_State *L) // get_width(self, listname) int InvRef::l_get_width(lua_State *L) { + NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); InventoryList *list = getlist(L, ref, listname); @@ -114,6 +116,7 @@ int InvRef::l_get_width(lua_State *L) // set_size(self, listname, size) 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); @@ -136,6 +139,7 @@ int InvRef::l_set_size(lua_State *L) // set_width(self, listname, size) int InvRef::l_set_width(lua_State *L) { + NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); int newwidth = luaL_checknumber(L, 3); @@ -153,6 +157,7 @@ int InvRef::l_set_width(lua_State *L) // get_stack(self, listname, i) -> itemstack int InvRef::l_get_stack(lua_State *L) { + NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); int i = luaL_checknumber(L, 3) - 1; @@ -167,10 +172,11 @@ int InvRef::l_get_stack(lua_State *L) // set_stack(self, listname, i, stack) -> true/false int InvRef::l_set_stack(lua_State *L) { + NO_MAP_LOCK_REQUIRED; 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); + ItemStack newitem = read_item(L, 4,STACK_TO_SERVER(L)); InventoryList *list = getlist(L, ref, listname); if(list != NULL && i >= 0 && i < (int) list->getSize()){ list->changeItem(i, newitem); @@ -185,25 +191,27 @@ int InvRef::l_set_stack(lua_State *L) // get_list(self, listname) -> list or nil int InvRef::l_get_list(lua_State *L) { + NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); Inventory *inv = getinv(L, ref); - inventory_get_list_to_lua(inv, listname, L); + push_inventory_list(inv, listname, L); return 1; } // set_list(self, listname, list) int InvRef::l_set_list(lua_State *L) { + NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const char *listname = luaL_checkstring(L, 2); Inventory *inv = getinv(L, ref); InventoryList *list = inv->getList(listname); if(list) - inventory_set_list_from_lua(inv, listname, L, 3, - list->getSize()); + read_inventory_list(inv, listname, L, 3, + STACK_TO_SERVER(L),list->getSize()); else - inventory_set_list_from_lua(inv, listname, L, 3); + read_inventory_list(inv, listname, L, 3,STACK_TO_SERVER(L)); reportInventoryChange(L, ref); return 0; } @@ -212,9 +220,10 @@ int InvRef::l_set_list(lua_State *L) // Returns the leftover stack 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); + ItemStack item = read_item(L, 3,STACK_TO_SERVER(L)); InventoryList *list = getlist(L, ref, listname); if(list){ ItemStack leftover = list->addItem(item); @@ -231,9 +240,10 @@ int InvRef::l_add_item(lua_State *L) // Returns true if the item completely fits into the list 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); + ItemStack item = read_item(L, 3,STACK_TO_SERVER(L)); InventoryList *list = getlist(L, ref, listname); if(list){ lua_pushboolean(L, list->roomForItem(item)); @@ -247,9 +257,10 @@ int InvRef::l_room_for_item(lua_State *L) // Returns true if the list contains the given count of the given item name 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); + ItemStack item = read_item(L, 3, STACK_TO_SERVER(L)); InventoryList *list = getlist(L, ref, listname); if(list){ lua_pushboolean(L, list->containsItem(item)); @@ -263,9 +274,10 @@ int InvRef::l_contains_item(lua_State *L) // Returns the items that were actually removed 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); + ItemStack item = read_item(L, 3,STACK_TO_SERVER(L)); InventoryList *list = getlist(L, ref, listname); if(list){ ItemStack removed = list->removeItem(item); @@ -281,6 +293,7 @@ int InvRef::l_remove_item(lua_State *L) // get_location() -> location (like minetest.get_inventory(location)) int InvRef::l_get_location(lua_State *L) { + NO_MAP_LOCK_REQUIRED; InvRef *ref = checkobject(L, 1); const InventoryLocation &loc = ref->m_loc; switch(loc.type){ @@ -293,10 +306,10 @@ int InvRef::l_get_location(lua_State *L) return 1; case InventoryLocation::NODEMETA: lua_newtable(L); - lua_pushstring(L, "nodemeta"); + lua_pushstring(L, "node"); lua_setfield(L, -2, "type"); push_v3s16(L, loc.p); - lua_setfield(L, -2, "name"); + lua_setfield(L, -2, "pos"); return 1; case InventoryLocation::DETACHED: lua_newtable(L); @@ -329,6 +342,7 @@ InvRef::~InvRef() // Not callable from Lua; all references are created on the C side. void InvRef::create(lua_State *L, const InventoryLocation &loc) { + NO_MAP_LOCK_REQUIRED; InvRef *o = new InvRef(loc); *(void **)(lua_newuserdata(L, sizeof(void *))) = o; luaL_getmetatable(L, className); @@ -336,6 +350,7 @@ void InvRef::create(lua_State *L, const InventoryLocation &loc) } void InvRef::createPlayer(lua_State *L, Player *player) { + NO_MAP_LOCK_REQUIRED; InventoryLocation loc; loc.setPlayer(player->getName()); create(L, loc); @@ -394,328 +409,48 @@ const luaL_reg InvRef::methods[] = { {0,0} }; -void inventory_get_list_to_lua(Inventory *inv, const char *name, - lua_State *L) -{ - InventoryList *invlist = inv->getList(name); - if(invlist == NULL){ - lua_pushnil(L); - return; - } - std::vector<ItemStack> items; - for(u32 i=0; i<invlist->getSize(); i++) - items.push_back(invlist->getItem(i)); - push_items(L, items); -} - -void inventory_set_list_from_lua(Inventory *inv, const char *name, - lua_State *L, int tableindex, int forcesize) -{ - if(tableindex < 0) - tableindex = lua_gettop(L) + 1 + tableindex; - // If nil, delete list - if(lua_isnil(L, tableindex)){ - inv->deleteList(name); - return; - } - // Otherwise set list - std::vector<ItemStack> items = read_items(L, tableindex); - int listsize = (forcesize != -1) ? forcesize : items.size(); - InventoryList *invlist = inv->addList(name, listsize); - int index = 0; - for(std::vector<ItemStack>::const_iterator - i = items.begin(); i != items.end(); i++){ - if(forcesize != -1 && index == forcesize) - break; - invlist->changeItem(index, *i); - index++; - } - while(forcesize != -1 && index < forcesize){ - invlist->deleteItem(index); - index++; - } -} - // get_inventory(location) -int l_get_inventory(lua_State *L) +int ModApiInventory::l_get_inventory(lua_State *L) { InventoryLocation loc; std::string type = checkstringfield(L, 1, "type"); - if(type == "player"){ - std::string name = checkstringfield(L, 1, "name"); - loc.setPlayer(name); - } else if(type == "node"){ + + if(type == "node"){ lua_getfield(L, 1, "pos"); v3s16 pos = check_v3s16(L, -1); loc.setNodeMeta(pos); - } else if(type == "detached"){ - std::string name = checkstringfield(L, 1, "name"); - loc.setDetached(name); - } - if(get_server(L)->getInventory(loc) != NULL) - InvRef::create(L, loc); - else - lua_pushnil(L); - return 1; -} - -/* - Detached inventory callbacks -*/ - -// Retrieves minetest.detached_inventories[name][callbackname] -// If that is nil or on error, return false and stack is unchanged -// If that is a function, returns true and pushes the -// function onto the stack -static bool get_detached_inventory_callback(lua_State *L, - const std::string &name, const char *callbackname) -{ - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "detached_inventories"); - lua_remove(L, -2); - luaL_checktype(L, -1, LUA_TTABLE); - lua_getfield(L, -1, name.c_str()); - lua_remove(L, -2); - // Should be a table - if(lua_type(L, -1) != LUA_TTABLE) - { - errorstream<<"Item \""<<name<<"\" not defined"<<std::endl; - lua_pop(L, 1); - return false; - } - lua_getfield(L, -1, callbackname); - lua_remove(L, -2); - // Should be a function or nil - if(lua_type(L, -1) == LUA_TFUNCTION) - { - return true; - } - else if(lua_isnil(L, -1)) - { - lua_pop(L, 1); - return false; - } - else - { - errorstream<<"Detached inventory \""<<name<<"\" callback \"" - <<callbackname<<"\" is not a function"<<std::endl; - lua_pop(L, 1); - return false; + 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; } } -// Return number of accepted items to be moved -int scriptapi_detached_inventory_allow_move(lua_State *L, - const std::string &name, - const std::string &from_list, int from_index, - const std::string &to_list, int to_index, - int count, ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "allow_move")) - return count; - - // function(inv, from_list, from_index, to_list, to_index, count, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 7, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_move should return a number"); - return luaL_checkinteger(L, -1); -} - -// Return number of accepted items to be put -int scriptapi_detached_inventory_allow_put(lua_State *L, - const std::string &name, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "allow_put")) - return stack.count; // All will be accepted - - // Call function(inv, listname, index, stack, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_put should return a number"); - return luaL_checkinteger(L, -1); -} - -// Return number of accepted items to be taken -int scriptapi_detached_inventory_allow_take(lua_State *L, - const std::string &name, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "allow_take")) - return stack.count; // All will be accepted - - // Call function(inv, listname, index, stack, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 1, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); - if(!lua_isnumber(L, -1)) - throw LuaError(L, "allow_take should return a number"); - return luaL_checkinteger(L, -1); -} - -// Report moved items -void scriptapi_detached_inventory_on_move(lua_State *L, - const std::string &name, - const std::string &from_list, int from_index, - const std::string &to_list, int to_index, - int count, ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "on_move")) - return; - - // function(inv, from_list, from_index, to_list, to_index, count, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // from_list - lua_pushstring(L, from_list.c_str()); - // from_index - lua_pushinteger(L, from_index + 1); - // to_list - lua_pushstring(L, to_list.c_str()); - // to_index - lua_pushinteger(L, to_index + 1); - // count - lua_pushinteger(L, count); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 7, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); -} - -// Report put items -void scriptapi_detached_inventory_on_put(lua_State *L, - const std::string &name, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "on_put")) - return; - - // Call function(inv, listname, index, stack, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); -} - -// Report taken items -void scriptapi_detached_inventory_on_take(lua_State *L, - const std::string &name, - const std::string &listname, int index, ItemStack &stack, - ServerActiveObject *player) -{ - realitycheck(L); - assert(lua_checkstack(L, 20)); - StackUnroller stack_unroller(L); - - // Push callback function on stack - if(!get_detached_inventory_callback(L, name, "on_take")) - return; - - // Call function(inv, listname, index, stack, player) - // inv - InventoryLocation loc; - loc.setDetached(name); - InvRef::create(L, loc); - // listname - lua_pushstring(L, listname.c_str()); - // index - lua_pushinteger(L, index + 1); - // stack - LuaItemStack::create(L, stack); - // player - objectref_get_or_create(L, player); - if(lua_pcall(L, 5, 0, 0)) - script_error(L, "error: %s", lua_tostring(L, -1)); -} - // create_detached_inventory_raw(name) -int l_create_detached_inventory_raw(lua_State *L) +int ModApiInventory::l_create_detached_inventory_raw(lua_State *L) { + NO_MAP_LOCK_REQUIRED; const char *name = luaL_checkstring(L, 1); - if(get_server(L)->createDetachedInventory(name) != NULL){ + if(getServer(L)->createDetachedInventory(name) != NULL){ InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); @@ -724,3 +459,21 @@ int l_create_detached_inventory_raw(lua_State *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; +} + +ModApiInventory::ModApiInventory() + : ModApiBase() { + +} + +ModApiInventory modapiinventory_prototype; |