Add special return value -1 to inventry callbacks
authorPerttu Ahola <celeron55@gmail.com>
Wed, 25 Jul 2012 13:52:00 +0000 (16:52 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Wed, 25 Jul 2012 13:52:00 +0000 (16:52 +0300)
doc/lua_api.txt
src/inventorymanager.cpp

index 4dcb0af877f26f8acb218d4855a2b59561ecfe8b..35b89021d3e7686e494b372c536e75e26aef904b 100644 (file)
@@ -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),
index 02b887ac2e857805efb62d5a690716ad841d6e5b..06978fbb9e39216de4aa2a56f71d4f772dd59611 100644 (file)
@@ -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 "