From 4845cb439a0850ab0af0ab81c0455c13a9d16208 Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Mon, 4 Apr 2016 22:00:17 +0400 Subject: [PATCH 01/10] Added files via upload --- src/inventorymanager.cpp | 42 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp index 3d8513492..d82dd6fc8 100644 --- a/src/inventorymanager.cpp +++ b/src/inventorymanager.cpp @@ -171,7 +171,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame { Inventory *inv_from = mgr->getInventory(from_inv); Inventory *inv_to = mgr->getInventory(to_inv); - + if (!inv_from) { infostream << "IMoveAction::apply(): FAIL: source inventory not found: " << "from_inv=\""<on_inventory_move_item(from_loc, from_list, from_i, to_loc, to_list, to_i, src_item, count, player); + mgr->setInventoryModified(from_inv, false); if(inv_from != inv_to) mgr->setInventoryModified(to_inv, false); @@ -697,6 +734,9 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame PLAYER_TO_SA(player)->nodemeta_inventory_OnTake( from_inv.p, from_list, from_i, src_item, player); } + + // Report drop to registered listeners + PLAYER_TO_SA(player)->on_inventory_drop_item(from_inv, from_list, from_i, src_item, player,player->getBasePosition() + v3f(0,1,0)); /* Record rollback information From 81beac794ba5ba46e2afdb73de5c259708c28308 Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Mon, 4 Apr 2016 22:01:10 +0400 Subject: [PATCH 02/10] Added files via upload --- src/script/cpp_api/s_player.cpp | 73 +++++++++++++++++++++++++++++++++ src/script/cpp_api/s_player.h | 20 +++++++++ 2 files changed, 93 insertions(+) diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp index 807430678..1219f38aa 100644 --- a/src/script/cpp_api/s_player.cpp +++ b/src/script/cpp_api/s_player.cpp @@ -22,6 +22,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common/c_converter.h" #include "common/c_content.h" #include "util/string.h" +#include "inventory.h" // For inventry and itemstack declarations +#include "lua_api/l_inventory.h" +#include "lua_api/l_item.h" +#include "server.h" void ScriptApiPlayer::on_newplayer(ServerActiveObject *player) { @@ -103,6 +107,75 @@ bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player) return positioning_handled_by_some; } +// This event launched when: player move itemstack from any inventory to any inventory +void ScriptApiPlayer::on_inventory_move_item( + InventoryLocation from_loc, + const std::string &from_list, int from_index, + InventoryLocation to_loc, + const std::string &to_list, int to_index, + ItemStack &stack, + int count, ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_inventory_move_item + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_inventory_move_item"); + // Call callbacks + InvRef::create(L, from_loc); // InvRef from 1 + lua_pushstring(L, from_list.c_str()); // listname 2 + lua_pushinteger(L, from_index + 1); // index 3 + InvRef::create(L, to_loc); // InvRef to 4 + lua_pushstring(L, to_list.c_str()); // listname 5 + lua_pushinteger(L, to_index + 1); // index 6 + LuaItemStack::create(L, stack); // stack 7 + lua_pushinteger(L, count); // amount 8 + objectrefGetOrCreate(L, player); // player 9 + runCallbacks(9, RUN_CALLBACKS_MODE_LAST); +} + +void ScriptApiPlayer::on_inventory_add_item( + InventoryLocation to_loc, + const std::string &to_list, + ItemStack &added_stack, + ItemStack &leftover_stack, + ServerActiveObject *player) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_inventory_add_item + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_inventory_add_item"); + // Call callbacks + InvRef::create(L, to_loc); // InvRef to 1 + lua_pushstring(L, to_list.c_str()); // listname 2 + LuaItemStack::create(L, added_stack); // added stack 3 + LuaItemStack::create(L, leftover_stack);// leftover stack 4 + objectrefGetOrCreate(L, player); // player 5 + runCallbacks(5, RUN_CALLBACKS_MODE_LAST); +} + +void ScriptApiPlayer::on_inventory_drop_item( + InventoryLocation from_loc, + const std::string &from_list, int from_index, + ItemStack &stack, + ServerActiveObject *player, v3f pos) +{ + SCRIPTAPI_PRECHECKHEADER + + // Get core.registered_on_inventory_add_item + lua_getglobal(L, "core"); + lua_getfield(L, -1, "registered_on_inventory_drop_item"); + // Call callbacks + InvRef::create(L, from_loc); // InvRef from 1 + lua_pushstring(L, from_list.c_str()); // listname 2 + lua_pushinteger(L, from_index + 1); // index 3 + LuaItemStack::create(L, stack); // dropped stack 4 + objectrefGetOrCreate(L, player); // player 5 + pushFloatPos(L, pos); // drop pos 6 + runCallbacks(6, RUN_CALLBACKS_MODE_LAST); +} + bool ScriptApiPlayer::on_prejoinplayer( const std::string &name, const std::string &ip, diff --git a/src/script/cpp_api/s_player.h b/src/script/cpp_api/s_player.h index 2e4dc2222..734f0bd24 100644 --- a/src/script/cpp_api/s_player.h +++ b/src/script/cpp_api/s_player.h @@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "cpp_api/s_base.h" #include "irr_v3d.h" #include "util/string.h" +#include "inventory.h" // For inventry and itemstack declarations +#include "inventorymanager.h" struct ToolCapabilities; @@ -35,6 +37,24 @@ public: void on_newplayer(ServerActiveObject *player); void on_dieplayer(ServerActiveObject *player); bool on_respawnplayer(ServerActiveObject *player); + void on_inventory_move_item( + InventoryLocation from_loc, + const std::string &from_list, int from_index, + InventoryLocation to_loc, + const std::string &to_list, int to_index, + ItemStack &stack, + int count, ServerActiveObject *player); + void on_inventory_add_item( + InventoryLocation to_loc, + const std::string &to_list, + ItemStack &added_stack, + ItemStack &leftover_stack, + ServerActiveObject *player); + void on_inventory_drop_item( + InventoryLocation from_loc, + const std::string &from_list, int from_index, + ItemStack &stack, + ServerActiveObject *player, v3f pos); bool on_prejoinplayer(const std::string &name, const std::string &ip, std::string *reason); void on_joinplayer(ServerActiveObject *player); From 890ea8af98cae07f60ea8bc018d7938ce71e08fd Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Mon, 4 Apr 2016 22:17:03 +0400 Subject: [PATCH 04/10] Added files via upload --- src/script/lua_api/l_object.cpp | 46 +++++++++++++++++++++++++++++++++ src/script/lua_api/l_object.h | 3 +++ 2 files changed, 49 insertions(+) diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 6d6614e7d..aec48cc18 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -315,6 +315,50 @@ int ObjectRef::l_get_inventory(lua_State *L) return 1; } +// add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack +int ObjectRef::l_add_item(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + ObjectRef *ref = checkobject(L, 1); + ServerActiveObject *co = getobject(ref); + if (co == NULL) return 0; + // Do it + InventoryLocation loc = co->getInventoryLocation(); + Inventory *inv = getServer(L)->getInventory(loc); + ItemStack item = read_item(L, 3, getServer(L)); + if (inv != NULL) + { + const char *listname = luaL_checkstring(L, 2); + InventoryList *list = inv->getList(listname); + if(list) + { + ItemStack leftover = list->addItem(item); + if(leftover.count != item.count) + { + getServer(L)->setInventoryModified(loc); + LuaItemStack::create(L, leftover); + // Report inventory change to subscribed listeners + getServer(L)->getScriptIface()->on_inventory_add_item(loc, listname, item, leftover, co); + // Get core.registered_on_inventory_update + //lua_getglobal(L, "core"); + //lua_getfield(L, -1, "registered_on_inventory_add_item"); + // Call callbacks + //InvRef::create(L, loc); // InvRef to 2 + //lua_pushstring(L, listname.c_str()); // listname 3 + //objectrefGetOrCreate(L, ref); // player 4 + //runCallbacks(9, RUN_CALLBACKS_MODE_LAST); + } + else + { + LuaItemStack::create(L, item); + } + } + } + else + LuaItemStack::create(L, item); + return 1; +} + // get_wield_list(self) int ObjectRef::l_get_wield_list(lua_State *L) { @@ -1784,5 +1828,7 @@ const luaL_reg ObjectRef::methods[] = { luamethod(ObjectRef, get_local_animation), luamethod(ObjectRef, set_eye_offset), luamethod(ObjectRef, get_eye_offset), + luamethod(ObjectRef, get_eye_offset), + luamethod(ObjectRef, add_item), {0,0} }; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index a4457cc05..1c2e241e5 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -86,6 +86,9 @@ private: // get_inventory(self) static int l_get_inventory(lua_State *L); + // add_item_inventory(self) + static int l_add_item(lua_State *L); + // get_wield_list(self) static int l_get_wield_list(lua_State *L); From 601ce775917fb694fd1a816c07f9466ad32da894 Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Mon, 4 Apr 2016 22:18:00 +0400 Subject: [PATCH 05/10] Added files via upload --- builtin/game/item.lua | 4 ++-- builtin/game/item_entity.lua | 2 +- builtin/game/register.lua | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/builtin/game/item.lua b/builtin/game/item.lua index 36c2c1a68..cedd3b712 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -389,7 +389,7 @@ function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed else local inv = user:get_inventory() if inv:room_for_item("main", {name=replace_with_item}) then - inv:add_item("main", replace_with_item) + user:add_item("main", replace_with_item) else local pos = user:getpos() pos.y = math.floor(pos.y + 0.5) @@ -423,7 +423,7 @@ function core.handle_node_drops(pos, drops, digger) if digger:get_inventory() then local _, dropped_item for _, dropped_item in ipairs(drops) do - local left = digger:get_inventory():add_item("main", dropped_item) + local left = digger:add_item("main", dropped_item) if not left:is_empty() then local p = { x = pos.x + math.random()/2-0.25, diff --git a/builtin/game/item_entity.lua b/builtin/game/item_entity.lua index a66bf33d0..939055cc4 100644 --- a/builtin/game/item_entity.lua +++ b/builtin/game/item_entity.lua @@ -208,7 +208,7 @@ core.register_entity(":__builtin:item", { on_punch = function(self, hitter) local inv = hitter:get_inventory() if inv and self.itemstring ~= '' then - local left = inv:add_item("main", self.itemstring) + local left = hitter:add_item("main", self.itemstring) if left and not left:is_empty() then self.itemstring = left:to_string() return diff --git a/builtin/game/register.lua b/builtin/game/register.lua index f330491a2..c6c20c8a6 100644 --- a/builtin/game/register.lua +++ b/builtin/game/register.lua @@ -507,6 +507,9 @@ core.registered_on_player_receive_fields, core.register_on_player_receive_fields core.registered_on_cheats, core.register_on_cheat = make_registration() core.registered_on_crafts, core.register_on_craft = make_registration() core.registered_craft_predicts, core.register_craft_predict = make_registration() +core.registered_on_inventory_move_item, core.register_on_inventory_move_item = make_registration() +core.registered_on_inventory_add_item, core.register_on_inventory_add_item = make_registration() +core.registered_on_inventory_drop_item, core.register_on_inventory_drop_item = make_registration() core.registered_on_protection_violation, core.register_on_protection_violation = make_registration() core.registered_on_item_eats, core.register_on_item_eat = make_registration() core.registered_on_punchplayers, core.register_on_punchplayer = make_registration() From aa61c4b5a3d0ab05b52e76fc71daee672ed6b58d Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Mon, 4 Apr 2016 22:22:04 +0400 Subject: [PATCH 06/10] Update l_object.cpp --- src/script/lua_api/l_object.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index aec48cc18..0672b5a4f 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1828,7 +1828,6 @@ const luaL_reg ObjectRef::methods[] = { luamethod(ObjectRef, get_local_animation), luamethod(ObjectRef, set_eye_offset), luamethod(ObjectRef, get_eye_offset), - luamethod(ObjectRef, get_eye_offset), luamethod(ObjectRef, add_item), {0,0} }; From e416ab07933d26cbd1dcb9e74a5d962b34218ece Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Tue, 5 Apr 2016 15:19:19 +0400 Subject: [PATCH 07/10] Update inventorymanager.cpp --- src/inventorymanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp index d82dd6fc8..c55a0f9c8 100644 --- a/src/inventorymanager.cpp +++ b/src/inventorymanager.cpp @@ -171,7 +171,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame { Inventory *inv_from = mgr->getInventory(from_inv); Inventory *inv_to = mgr->getInventory(to_inv); - + if (!inv_from) { infostream << "IMoveAction::apply(): FAIL: source inventory not found: " << "from_inv=\""< Date: Tue, 5 Apr 2016 15:20:22 +0400 Subject: [PATCH 08/10] Update inventorymanager.cpp --- src/inventorymanager.cpp | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp index c55a0f9c8..0bf35d325 100644 --- a/src/inventorymanager.cpp +++ b/src/inventorymanager.cpp @@ -524,38 +524,30 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame } InventoryLocation from_loc; - if(from_inv.type == InventoryLocation::NODEMETA) - { + if(from_inv.type == InventoryLocation::NODEMETA){ from_loc.setNodeMeta(from_inv.p); } - else if(from_inv.type == InventoryLocation::DETACHED) - { + else if(from_inv.type == InventoryLocation::DETACHED){ from_loc.setDetached(from_inv.name); } - else if(from_inv.type == InventoryLocation::PLAYER) - { + else if(from_inv.type == InventoryLocation::PLAYER){ from_loc.setPlayer(from_inv.name); } - else if(from_inv.type == InventoryLocation::UNDEFINED) - { + else if(from_inv.type == InventoryLocation::UNDEFINED){ from_loc.setUndefined(); } InventoryLocation to_loc; - if(to_inv.type == InventoryLocation::NODEMETA) - { + if(to_inv.type == InventoryLocation::NODEMETA){ to_loc.setNodeMeta(to_inv.p); } - else if(to_inv.type == InventoryLocation::DETACHED) - { + else if(to_inv.type == InventoryLocation::DETACHED){ to_loc.setDetached(to_inv.name); } - else if(to_inv.type == InventoryLocation::PLAYER) - { + else if(to_inv.type == InventoryLocation::PLAYER){ to_loc.setPlayer(to_inv.name); } - else if(to_inv.type == InventoryLocation::UNDEFINED) - { + else if(to_inv.type == InventoryLocation::UNDEFINED){ to_loc.setUndefined(); } PLAYER_TO_SA(player)->on_inventory_move_item(from_loc, from_list, from_i, to_loc, to_list, to_i, src_item, count, player); From ca6324a479a34c47f9b03db7c0fc338eeaa90ee4 Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Tue, 5 Apr 2016 15:22:17 +0400 Subject: [PATCH 09/10] Update l_object.cpp --- src/script/lua_api/l_object.cpp | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 0672b5a4f..375ca4122 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -326,30 +326,18 @@ int ObjectRef::l_add_item(lua_State *L) InventoryLocation loc = co->getInventoryLocation(); Inventory *inv = getServer(L)->getInventory(loc); ItemStack item = read_item(L, 3, getServer(L)); - if (inv != NULL) - { + if (inv != NULL){ const char *listname = luaL_checkstring(L, 2); InventoryList *list = inv->getList(listname); - if(list) - { + if(list){ ItemStack leftover = list->addItem(item); - if(leftover.count != item.count) - { + if(leftover.count != item.count){ getServer(L)->setInventoryModified(loc); LuaItemStack::create(L, leftover); // Report inventory change to subscribed listeners getServer(L)->getScriptIface()->on_inventory_add_item(loc, listname, item, leftover, co); - // Get core.registered_on_inventory_update - //lua_getglobal(L, "core"); - //lua_getfield(L, -1, "registered_on_inventory_add_item"); - // Call callbacks - //InvRef::create(L, loc); // InvRef to 2 - //lua_pushstring(L, listname.c_str()); // listname 3 - //objectrefGetOrCreate(L, ref); // player 4 - //runCallbacks(9, RUN_CALLBACKS_MODE_LAST); } - else - { + else{ LuaItemStack::create(L, item); } } From bca616493783b18b2f280d4773cb4be41d01c434 Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Mon, 11 Apr 2016 19:37:31 +0400 Subject: [PATCH 10/10] Adding missing description of new API functions Added description for: * minetest.register_on_inventory_move_item * minetest.register_on_inventory_add_item * minetest.register_on_inventory_drop_item * ObjRev:add_item --- doc/lua_api.txt | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index a03a95d9e..274704bef 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1881,6 +1881,33 @@ Call these functions only at load time! * Called when a player joins the game * `minetest.register_on_leaveplayer(func(ObjectRef))` * Called when a player leaves the game +* `minetest.register_on_inventory_move_item(func(inv_from,list_from,slot_from,inv_to,list_to,slot_to,stack,amount,player)` + * Called when a player move items between inventories using GUI (including crafting grid). + * `inv_from`: InvRef of inventory from which item was extracted. + * `list_from`: name of a list, where from stack extracted. + * `slot_from`: integer, speak by itself + * `inv_to`: InvRef of inventory to which item was dropped. + * `list_to`: name of a list, where to stack dropped. + * `slot_to`: integer, speak by itself + * `stack`: ItemStack of a stack moved + * `amount`: integer, amount of items, which was sucessfully transported + * `player`: ObjectRef of the player +* `minetest.register_on_inventory_add_item(func(inv_to,list_to,stack,stack_left,player)` + * Called when a player recive item via digging or from item entity or when `player:add_item(list, item)` called. + * `inv_to`: InvRef of inventory to which item was added. + * `list_to`: name of a list, where stack was added. + * `slot_to`: integer, speak by itself + * `stack`: ItemStack of a stack added + * `stack_left`: ItemStack of a stack which was left on ground + * `player`: ObjectRef of the player +* `minetest.register_on_inventory_drop_item(func(inv_from,list_from,slot_from,stack,player, dropped_pos)` + * Called when a player drop item on ground + * `inv_from`: InvRef of inventory from which item was dropped. + * `list_from`: name of a list, where from stack dropped. Usually 'main'. + * `slot_from`: integer, speak by itself + * `stack`: ItemStack of a stack dropped + * `player`: ObjectRef of the player + * `dropped_pos`: a table `{x=x_pos, y=y_pos, z=z_pos}`, where values contain absolute position of new item object. * `minetest.register_on_cheat(func(ObjectRef, cheat))` * Called when a player cheats * `cheat`: `{type=}`, where `` is one of: @@ -2572,6 +2599,7 @@ This is basically a reference to a C++ `ServerActiveObject` * `get_hp()`: returns number of hitpoints (2 * number of hearts) * `set_hp(hp)`: set number of hitpoints (2 * number of hearts) * `get_inventory()`: returns an `InvRef` +* `add_item(listname, stack)`: add item somewhere in list, returns leftover `ItemStack`. If object has no inventory, return `ItemStack`. Same as for `InvRef`, `player:add_item(listname, stack)` can be used instead of `player:get_inventory():add_item(listname, stack)`, but will launch callbacks registered by `minetest.register_on_inventory_add_item`. * `get_wield_list()`: returns the name of the inventory list the wielded item is in * `get_wield_index()`: returns the index of the wielded item * `get_wielded_item()`: returns an `ItemStack`