X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Finventorymanager.cpp;h=1c511e9cbe69f7659e70e8a7a1d5e172285af73b;hb=58e6d25e033c76dc91aaac18fdeda92ac23fe0e1;hp=5412a5dca5e1d916858540c3ff68710085cdeff6;hpb=9eaf93d41d6745b877f8f52cf54b21050abefda1;p=oweals%2Fminetest.git diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp index 5412a5dca..1c511e9cb 100644 --- a/src/inventorymanager.cpp +++ b/src/inventorymanager.cpp @@ -1,6 +1,6 @@ /* -Minetest-c55 -Copyright (C) 2010-2011 celeron55, Perttu Ahola +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -20,14 +20,17 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "inventorymanager.h" #include "log.h" #include "environment.h" -#include "scriptapi.h" +#include "scripting_game.h" #include "serverobject.h" #include "main.h" // for g_settings #include "settings.h" #include "craftdef.h" +#include "rollback_interface.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" +#define PLAYER_TO_SA(p) p->getEnv()->getScriptIface() + /* InventoryLocation */ @@ -199,6 +202,14 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame return; } + /* + Do not handle rollback if both inventories are that of the same player + */ + bool ignore_rollback = ( + from_inv.type == InventoryLocation::PLAYER && + to_inv.type == InventoryLocation::PLAYER && + from_inv.name == to_inv.name); + /* Collect information of endpoints */ @@ -217,9 +228,8 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame to_inv.type == InventoryLocation::DETACHED && from_inv.name == to_inv.name) { - lua_State *L = player->getEnv()->getLua(); - src_can_take_count = scriptapi_detached_inventory_allow_move( - L, from_inv.name, from_list, from_i, + src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowMove( + from_inv.name, from_list, from_i, to_list, to_i, try_take_count, player); dst_can_put_count = src_can_take_count; } @@ -228,18 +238,18 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame // Destination is detached if(to_inv.type == InventoryLocation::DETACHED) { - lua_State *L = player->getEnv()->getLua(); ItemStack src_item = list_from->getItem(from_i); src_item.count = try_take_count; - dst_can_put_count = scriptapi_detached_inventory_allow_put( - L, to_inv.name, to_list, to_i, src_item, player); + dst_can_put_count = PLAYER_TO_SA(player)->detached_inventory_AllowPut( + to_inv.name, to_list, to_i, src_item, player); } // Source is detached if(from_inv.type == InventoryLocation::DETACHED) { - lua_State *L = player->getEnv()->getLua(); - src_can_take_count = scriptapi_detached_inventory_allow_take( - L, from_inv.name, from_list, from_i, try_take_count, player); + ItemStack src_item = list_from->getItem(from_i); + src_item.count = try_take_count; + src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowTake( + from_inv.name, from_list, from_i, src_item, player); } } @@ -251,9 +261,8 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame to_inv.type == InventoryLocation::NODEMETA && from_inv.p == to_inv.p) { - lua_State *L = player->getEnv()->getLua(); - src_can_take_count = scriptapi_nodemeta_inventory_allow_move( - L, from_inv.p, from_list, from_i, + src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowMove( + from_inv.p, from_list, from_i, to_list, to_i, try_take_count, player); dst_can_put_count = src_can_take_count; } @@ -262,33 +271,38 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame // Destination is nodemeta if(to_inv.type == InventoryLocation::NODEMETA) { - lua_State *L = player->getEnv()->getLua(); ItemStack src_item = list_from->getItem(from_i); src_item.count = try_take_count; - dst_can_put_count = scriptapi_nodemeta_inventory_allow_put( - L, to_inv.p, to_list, to_i, src_item, player); + dst_can_put_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowPut( + to_inv.p, to_list, to_i, src_item, player); } // Source is nodemeta if(from_inv.type == InventoryLocation::NODEMETA) { - lua_State *L = player->getEnv()->getLua(); - src_can_take_count = scriptapi_nodemeta_inventory_allow_take( - L, from_inv.p, from_list, from_i, try_take_count, player); + ItemStack src_item = list_from->getItem(from_i); + src_item.count = try_take_count; + src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowTake( + 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="<getSize(); i++){ + if(list_to->getItem(i).empty()){ + list_to->changeItem(i, to_stack_was); + break; + } + } + } + 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->deleteItem(from_i); + list_from->addItem(from_i, from_stack_was); + list_from->takeItem(from_i, count); + } + + infostream<<"IMoveAction::apply(): moved" <<" count="<getBool("creative_mode") == true - && from_inv.type == InventoryLocation::PLAYER){ - } - else{ + + // 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); if(item2.count != actually_dropped_count) errorstream<<"Could not take dropped count of items"<setInventoryModified(from_inv); } } @@ -534,6 +605,8 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame <<" list=\""<getList("craft"); - if(!clist || clist->getSize() != 9) + if(!clist) return false; // Mangle crafting grid to an another format CraftInput ci; ci.method = CRAFT_METHOD_NORMAL; - ci.width = 3; - for(u16 i=0; i<9; i++) + ci.width = clist->getWidth() ? clist->getWidth() : 3; + for(u16 i=0; igetSize(); i++) ci.items.push_back(clist->getItem(i)); // Find out what is crafted and add it to result item slot @@ -700,7 +799,7 @@ bool getCraftingResult(Inventory *inv, ItemStack& result, if(found && decrementInput) { // CraftInput has been changed, apply changes in clist - for(u16 i=0; i<9; i++) + for(u16 i=0; igetSize(); i++) { clist->changeItem(i, ci.items[i]); }