diff options
-rw-r--r-- | doc/lua_api.txt | 4 | ||||
-rw-r--r-- | src/inventorymanager.cpp | 56 |
2 files changed, 42 insertions, 18 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 4dcb0af87..35b89021d 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1370,10 +1370,12 @@ Node definition (register_node) allow_metadata_inventory_put = func(pos, listname, index, stack, player), ^ Called when a player wants to put something into the inventory ^ Return value: number of items allowed to put + ^ Return value: -1: Allow and don't modify item count in inventory allow_metadata_inventory_take = func(pos, listname, index, stack, player), ^ Called when a player wants to take something out of the inventory ^ Return value: number of items allowed to take + ^ Return value: -1: Allow and don't modify item count in inventory on_metadata_inventory_move = func(pos, from_list, from_index, to_list, to_index, count, player), @@ -1446,10 +1448,12 @@ Detached inventory callbacks allow_put = func(inv, listname, index, stack, player), ^ Called when a player wants to put something into the inventory ^ Return value: number of items allowed to put + ^ Return value: -1: Allow and don't modify item count in inventory allow_take = func(inv, listname, index, stack, player), ^ Called when a player wants to take something out of the inventory ^ Return value: number of items allowed to take + ^ Return value: -1: Allow and don't modify item count in inventory on_move = func(inv, from_list, from_index, to_list, to_index, count, player), on_put = func(inv, listname, index, stack, player), diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp index 02b887ac2..06978fbb9 100644 --- a/src/inventorymanager.cpp +++ b/src/inventorymanager.cpp @@ -280,19 +280,24 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame L, from_inv.p, from_list, from_i, src_item, player); } } + + int old_count = count; /* Modify count according to collected data */ - int new_count = try_take_count; - if(new_count > src_can_take_count) - new_count = src_can_take_count; - if(new_count > dst_can_put_count) - new_count = dst_can_put_count; + count = try_take_count; + if(src_can_take_count != -1 && count > src_can_take_count) + count = src_can_take_count; + if(dst_can_put_count != -1 && count > dst_can_put_count) + count = dst_can_put_count; + /* Limit according to source item count */ + if(count > list_from->getItem(from_i).count) + count = list_from->getItem(from_i).count; /* If no items will be moved, don't go further */ - if(new_count == 0) + if(count == 0) { - infostream<<"IMoveAction::apply(): move was completely disallowed: " - <<" count="<<count + infostream<<"IMoveAction::apply(): move was completely disallowed:" + <<" count="<<old_count <<" from inv=\""<<from_inv.dump()<<"\"" <<" list=\""<<from_list<<"\"" <<" i="<<from_i @@ -303,10 +308,10 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame return; } - count = new_count; - ItemStack src_item = list_from->getItem(from_i); src_item.count = count; + ItemStack from_stack_was = list_from->getItem(from_i); + ItemStack to_stack_was = list_to->getItem(to_i); /* Perform actual move @@ -316,7 +321,19 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame */ list_from->moveItem(from_i, list_to, to_i, count); - infostream<<"IMoveAction::apply(): moved " + // If source is infinite, reset it's stack + if(src_can_take_count == -1){ + list_from->deleteItem(from_i); + list_from->addItem(from_i, from_stack_was); + } + // If destination is infinite, reset it's stack and take count from source + if(dst_can_put_count == -1){ + list_to->deleteItem(to_i); + list_to->addItem(to_i, to_stack_was); + list_from->takeItem(from_i, count); + } + + infostream<<"IMoveAction::apply(): moved" <<" count="<<count <<" from inv=\""<<from_inv.dump()<<"\"" <<" list=\""<<from_list<<"\"" @@ -500,7 +517,7 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame L, from_inv.p, from_list, from_i, src_item, player); } - if(src_can_take_count < take_count) + if(src_can_take_count != -1 && src_can_take_count < take_count) take_count = src_can_take_count; int actually_dropped_count = 0; @@ -518,14 +535,17 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame infostream<<"Actually dropped no items"<<std::endl; return; } + + // If source isn't infinite + if(src_can_take_count != -1){ + // Take item from source list + ItemStack item2 = list_from->takeItem(from_i, actually_dropped_count); - // Take item from source list - ItemStack item2 = list_from->takeItem(from_i, actually_dropped_count); + if(item2.count != actually_dropped_count) + errorstream<<"Could not take dropped count of items"<<std::endl; - if(item2.count != actually_dropped_count) - errorstream<<"Could not take dropped count of items"<<std::endl; - - mgr->setInventoryModified(from_inv); + mgr->setInventoryModified(from_inv); + } } infostream<<"IDropAction::apply(): dropped " |