From cf87169737fdeeee7d4b160688bbed7194e46147 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Fri, 24 May 2013 07:30:39 +0000 Subject: Refactored cInventory to use cItemGrid for the actual Storage This makes the API more orthogonal and is easier to use in the plugins. Also changes in the inventory are now propagated to the needed places (armor updates to BroadcastEntityEquipment etc.) even when the inventory is changed by a plugin. git-svn-id: http://mc-server.googlecode.com/svn/trunk@1503 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- MCServer/Plugins/Core/item.lua | 43 +- MCServer/Plugins/Debuggers/Debuggers.lua | 8 +- source/Bindings.cpp | 1054 +++++++++++++++++++++++------- source/Bindings.h | 2 +- source/Blocks/BlockCauldron.h | 8 +- source/Blocks/BlockFlowerPot.h | 5 +- source/ClientHandle.cpp | 7 +- source/Inventory.cpp | 528 ++++++++++----- source/Inventory.h | 159 +++-- source/Item.cpp | 2 +- source/Item.h | 2 +- source/ItemGrid.cpp | 203 +++++- source/ItemGrid.h | 66 +- source/Items/ItemBucket.h | 12 +- source/Items/ItemDye.h | 6 +- source/Items/ItemSlab.h | 3 +- source/Items/ItemSpawnEgg.h | 3 +- source/JukeboxEntity.cpp | 3 +- source/Pickup.cpp | 14 +- source/Player.cpp | 18 +- source/Player.h | 6 +- source/Protocol/Protocol125.cpp | 3 +- source/Protocol/Protocol132.cpp | 20 +- source/UI/SlotArea.cpp | 2 +- source/UI/SlotArea.h | 8 +- 25 files changed, 1616 insertions(+), 569 deletions(-) diff --git a/MCServer/Plugins/Core/item.lua b/MCServer/Plugins/Core/item.lua index 00a6aa790..30e8820a9 100644 --- a/MCServer/Plugins/Core/item.lua +++ b/MCServer/Plugins/Core/item.lua @@ -1,36 +1,39 @@ -function HandleItemCommand( Split, Player ) - if( #Split ~= 2 and #Split ~=3 ) then - Player:SendMessage( cChatColor.Green .. "Usage: /item [ItemType/Name:Dmg] " ) - return true +function HandleItemCommand(Split, Player) + if ((#Split ~= 2) and (#Split ~=3)) then + Player:SendMessage(cChatColor.Green .. "Usage: /item [ItemType/Name:Dmg] "); + return true; end - local Item = cItem(E_ITEM_EMPTY, 1) - local FoundItem = StringToItem( Split[2], Item ) + local Item = cItem(E_ITEM_EMPTY, 1); + local FoundItem = StringToItem(Split[2], Item); - if( IsValidItem( Item.m_ItemType ) == false ) then -- StringToItem does not check if item is valid + if not(IsValidItem(Item.m_ItemType)) then -- StringToItem does not check if item is valid FoundItem = false end - if( FoundItem == false ) then + if not(FoundItem) then Player:SendMessage( cChatColor.Green .. "Invalid Item type / name !" ) return true end - if( #Split == 3 ) then - ItemAmount = tonumber( Split[3] ) - if( ItemAmount == nil or ItemAmount < 1 or ItemAmount > 512 ) then - Player:SendMessage( cChatColor.Green .. "Invalid Amount !" ) - return true - else - Item.m_ItemCount = ItemAmount + local ItemAmount = 1; + if (#Split == 3) then + ItemAmount = tonumber(Split[3]); + if ((ItemAmount == nil) or (ItemAmount < 1) or (ItemAmount > 512)) then + Player:SendMessage(cChatColor.Green .. "Invalid Amount!"); + return true; end end - if( Player:GetInventory():AddItem( Item ) == true ) then - Player:SendMessage( cChatColor.Green .. "There you go !" ) - LOG("Gave " .. Player:GetName() .. " " .. Item.m_ItemCount .. " times " .. Item.m_ItemType .. ":" .. Item.m_ItemDamage) + Item.m_ItemCount = ItemAmount; + + local ItemsGiven = Player:GetInventory():AddItem(Item); + if (ItemsGiven == ItemAmount) then + Player:SendMessage( cChatColor.Green .. "There you go !"); + LOG("Gave " .. Player:GetName() .. " " .. Item.m_ItemCount .. " times " .. Item.m_ItemType .. ":" .. Item.m_ItemDamage); else - Player:SendMessage( cChatColor.Green .. "Not enough space in inventory !" ) + Player:SendMessage(cChatColor.Green .. "Not enough space in inventory, only gave " .. ItemsGiven); + LOG("Player " .. Player:GetName() .. " asked for " .. Item.m_ItemCount .. " times " .. Item.m_ItemType .. ":" .. Item.m_ItemDamage ..", but only could fit " .. ItemsGiven); end - return true + return true; end \ No newline at end of file diff --git a/MCServer/Plugins/Debuggers/Debuggers.lua b/MCServer/Plugins/Debuggers/Debuggers.lua index 21cc4bb86..3f6dcfb7e 100644 --- a/MCServer/Plugins/Debuggers/Debuggers.lua +++ b/MCServer/Plugins/Debuggers/Debuggers.lua @@ -456,10 +456,10 @@ end function HandleWoolCmd(Split, Player) local Wool = cItem(E_BLOCK_WOOL, 1, E_META_WOOL_BLUE); - Player:GetInventory():SetSlot(5, Wool); - Player:GetInventory():SetSlot(6, Wool); - Player:GetInventory():SetSlot(7, Wool); - Player:GetInventory():SetSlot(8, Wool); + Player:GetInventory():SetArmorSlot(0, Wool); + Player:GetInventory():SetArmorSlot(1, Wool); + Player:GetInventory():SetArmorSlot(2, Wool); + Player:GetInventory():SetArmorSlot(3, Wool); Player:SendMessage("You have been bluewooled :)"); return true; end \ No newline at end of file diff --git a/source/Bindings.cpp b/source/Bindings.cpp index e01e982a8..5207c512e 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 05/21/13 14:54:10. +** Generated automatically by tolua++-1.0.92 on 05/24/13 09:11:00. */ #ifndef __cplusplus @@ -154,38 +154,41 @@ static void tolua_reg_types (lua_State* tolua_S) tolua_usertype(tolua_S,"cBlockArea"); tolua_usertype(tolua_S,"cInventory"); tolua_usertype(tolua_S,"cRoot"); + tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cTracer"); tolua_usertype(tolua_S,"cPickup"); tolua_usertype(tolua_S,"cItems"); + tolua_usertype(tolua_S,"cGroup"); tolua_usertype(tolua_S,"cClientHandle"); tolua_usertype(tolua_S,"cChunkDesc"); tolua_usertype(tolua_S,"cFurnaceRecipe"); - tolua_usertype(tolua_S,"cCraftingGrid"); + tolua_usertype(tolua_S,"cCuboid"); tolua_usertype(tolua_S,"cChatColor"); - tolua_usertype(tolua_S,"cGroup"); - tolua_usertype(tolua_S,"cTracer"); + tolua_usertype(tolua_S,"Vector3i"); + tolua_usertype(tolua_S,"cStairs"); tolua_usertype(tolua_S,"Lua__cWebPlugin"); tolua_usertype(tolua_S,"Lua__cPawn"); - tolua_usertype(tolua_S,"cCuboid"); + tolua_usertype(tolua_S,"cWebPlugin"); tolua_usertype(tolua_S,"cItem"); tolua_usertype(tolua_S,"Vector3f"); - tolua_usertype(tolua_S,"Vector3i"); + tolua_usertype(tolua_S,"cGroupManager"); tolua_usertype(tolua_S,"cCraftingRecipes"); tolua_usertype(tolua_S,"Lua__cPlayer"); - tolua_usertype(tolua_S,"cStairs"); + tolua_usertype(tolua_S,"Lua__cPickup"); tolua_usertype(tolua_S,"cChestEntity"); tolua_usertype(tolua_S,"cWebAdmin"); - tolua_usertype(tolua_S,"cGroupManager"); - tolua_usertype(tolua_S,"cBlockEntity"); - tolua_usertype(tolua_S,"Lua__cPickup"); - tolua_usertype(tolua_S,"cWebPlugin"); - tolua_usertype(tolua_S,"cPluginManager"); tolua_usertype(tolua_S,"HTTPRequest"); + tolua_usertype(tolua_S,"cBlockEntity"); + tolua_usertype(tolua_S,"cItemGrid::cListener"); tolua_usertype(tolua_S,"HTTPFormData"); - tolua_usertype(tolua_S,"cLadder"); tolua_usertype(tolua_S,"cWorld"); + tolua_usertype(tolua_S,"cPluginManager"); + tolua_usertype(tolua_S,"cPlugin"); + tolua_usertype(tolua_S,"cLadder"); tolua_usertype(tolua_S,"cEntity"); + tolua_usertype(tolua_S,"cCriticalSection"); tolua_usertype(tolua_S,"cIniFile"); - tolua_usertype(tolua_S,"cPlugin"); + tolua_usertype(tolua_S,"cListeners"); tolua_usertype(tolua_S,"AStringVector"); tolua_usertype(tolua_S,"cVine"); tolua_usertype(tolua_S,"cPlayer"); @@ -3281,6 +3284,35 @@ static int tolua_AllToLua_ItemCategory_IsBoots00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* function: ItemCategory::IsArmor */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_ItemCategory_IsArmor00 +static int tolua_AllToLua_ItemCategory_IsArmor00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isnumber(tolua_S,1,0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + short a_ItemType = ((short) tolua_tonumber(tolua_S,1,0)); + { + bool tolua_ret = (bool) ItemCategory::IsArmor(a_ItemType); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'IsArmor'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* function: GetTime */ #ifndef TOLUA_DISABLE_tolua_AllToLua_GetTime00 static int tolua_AllToLua_GetTime00(lua_State* tolua_S) @@ -4295,38 +4327,6 @@ static int tolua_AllToLua_cEntity_GetHeadYaw00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: GetHeight of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetHeight00 -static int tolua_AllToLua_cEntity_GetHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHeight'", NULL); -#endif - { - double tolua_ret = (double) self->GetHeight(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - /* method: GetMass of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetMass00 static int tolua_AllToLua_cEntity_GetMass00(lua_State* tolua_S) @@ -4785,38 +4785,6 @@ static int tolua_AllToLua_cEntity_GetSpeedZ00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: GetWidth of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetWidth00 -static int tolua_AllToLua_cEntity_GetWidth00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"const cEntity",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - const cEntity* self = (const cEntity*) tolua_tousertype(tolua_S,1,0); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetWidth'", NULL); -#endif - { - double tolua_ret = (double) self->GetWidth(); - tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); - } - } - return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetWidth'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - /* method: GetChunkX of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_GetChunkX00 static int tolua_AllToLua_cEntity_GetChunkX00(lua_State* tolua_S) @@ -4914,39 +4882,6 @@ static int tolua_AllToLua_cEntity_SetHeadYaw00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: SetHeight of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetHeight00 -static int tolua_AllToLua_cEntity_SetHeight00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - double a_Height = ((double) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetHeight'", NULL); -#endif - { - self->SetHeight(a_Height); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetHeight'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - /* method: SetMass of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetMass00 static int tolua_AllToLua_cEntity_SetMass00(lua_State* tolua_S) @@ -5440,39 +5375,6 @@ static int tolua_AllToLua_cEntity_SetSpeedZ00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: SetWidth of class cEntity */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_SetWidth00 -static int tolua_AllToLua_cEntity_SetWidth00(lua_State* tolua_S) -{ -#ifndef TOLUA_RELEASE - tolua_Error tolua_err; - if ( - !tolua_isusertype(tolua_S,1,"cEntity",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) - ) - goto tolua_lerror; - else -#endif - { - cEntity* self = (cEntity*) tolua_tousertype(tolua_S,1,0); - double a_Width = ((double) tolua_tonumber(tolua_S,2,0)); -#ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetWidth'", NULL); -#endif - { - self->SetWidth(a_Width); - } - } - return 0; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetWidth'.",&tolua_err); - return 0; -#endif -} -#endif //#ifndef TOLUA_DISABLE - /* method: AddPosX of class cEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cEntity_AddPosX00 static int tolua_AllToLua_cEntity_AddPosX00(lua_State* tolua_S) @@ -12685,217 +12587,587 @@ static int tolua_AllToLua_cInventory_Clear00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: AddItem of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_AddItem00 -static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S) +/* method: HowManyCanFit of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_HowManyCanFit00 +static int tolua_AllToLua_cInventory_HowManyCanFit00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isboolean(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) ) goto tolua_lerror; else #endif { cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); + const cItem* a_ItemStack = ((const cItem*) tolua_tousertype(tolua_S,2,0)); + bool a_ConsiderEmptySlots = ((bool) tolua_toboolean(tolua_S,3,0)); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HowManyCanFit'", NULL); #endif { - bool tolua_ret = (bool) self->AddItem(*a_Item); - tolua_pushboolean(tolua_S,(bool)tolua_ret); + int tolua_ret = (int) self->HowManyCanFit(*a_ItemStack,a_ConsiderEmptySlots); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } return 1; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddItem'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'HowManyCanFit'.",&tolua_err); return 0; #endif } #endif //#ifndef TOLUA_DISABLE -/* method: AddItemAnyAmount of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_AddItemAnyAmount00 -static int tolua_AllToLua_cInventory_AddItemAnyAmount00(lua_State* tolua_S) +/* method: HowManyCanFit of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_HowManyCanFit01 +static int tolua_AllToLua_cInventory_HowManyCanFit01(lua_State* tolua_S) { -#ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isboolean(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) ) goto tolua_lerror; else -#endif { cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); + const cItem* a_ItemStack = ((const cItem*) tolua_tousertype(tolua_S,2,0)); + int a_BeginSlotNum = ((int) tolua_tonumber(tolua_S,3,0)); + int a_EndSlotNum = ((int) tolua_tonumber(tolua_S,4,0)); + bool a_ConsiderEmptySlots = ((bool) tolua_toboolean(tolua_S,5,0)); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItemAnyAmount'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HowManyCanFit'", NULL); #endif { - bool tolua_ret = (bool) self->AddItemAnyAmount(*a_Item); - tolua_pushboolean(tolua_S,(bool)tolua_ret); + int tolua_ret = (int) self->HowManyCanFit(*a_ItemStack,a_BeginSlotNum,a_EndSlotNum,a_ConsiderEmptySlots); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } return 1; -#ifndef TOLUA_RELEASE - tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddItemAnyAmount'.",&tolua_err); - return 0; -#endif +tolua_lerror: + return tolua_AllToLua_cInventory_HowManyCanFit00(tolua_S); } #endif //#ifndef TOLUA_DISABLE -/* method: RemoveItem of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_RemoveItem00 -static int tolua_AllToLua_cInventory_RemoveItem00(lua_State* tolua_S) +/* method: AddItem of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_AddItem00 +static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isboolean(tolua_S,3,1,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) ) goto tolua_lerror; else #endif { cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,0)); + const cItem* a_ItemStack = ((const cItem*) tolua_tousertype(tolua_S,2,0)); + bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,true)); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveItem'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL); #endif { - bool tolua_ret = (bool) self->RemoveItem(*a_Item); - tolua_pushboolean(tolua_S,(bool)tolua_ret); + int tolua_ret = (int) self->AddItem(*a_ItemStack,a_AllowNewStacks); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } return 1; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'RemoveItem'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'AddItem'.",&tolua_err); return 0; #endif } #endif //#ifndef TOLUA_DISABLE -/* method: GetSlot of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetSlot00 -static int tolua_AllToLua_cInventory_GetSlot00(lua_State* tolua_S) +/* method: AddItems of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_AddItems00 +static int tolua_AllToLua_cInventory_AddItems00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype(tolua_S,1,"const cInventory",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItems",0,&tolua_err)) || + !tolua_isboolean(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) ) goto tolua_lerror; else #endif { - const cInventory* self = (const cInventory*) tolua_tousertype(tolua_S,1,0); - int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + cItems* a_ItemStackList = ((cItems*) tolua_tousertype(tolua_S,2,0)); + bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,0)); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSlot'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItems'", NULL); #endif { - const cItem& tolua_ret = (const cItem&) self->GetSlot(a_SlotNum); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + int tolua_ret = (int) self->AddItems(*a_ItemStackList,a_AllowNewStacks); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } return 1; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetSlot'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'AddItems'.",&tolua_err); return 0; #endif } #endif //#ifndef TOLUA_DISABLE -/* method: GetHotBarSlot of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetHotBarSlot00 -static int tolua_AllToLua_cInventory_GetHotBarSlot00(lua_State* tolua_S) +/* method: RemoveOneEquippedItem of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_RemoveOneEquippedItem00 +static int tolua_AllToLua_cInventory_RemoveOneEquippedItem00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype(tolua_S,1,"const cInventory",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || - !tolua_isnoobj(tolua_S,3,&tolua_err) + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) ) goto tolua_lerror; else #endif { - const cInventory* self = (const cInventory*) tolua_tousertype(tolua_S,1,0); - int a_HotBarSlotNum = ((int) tolua_tonumber(tolua_S,2,0)); + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHotBarSlot'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'RemoveOneEquippedItem'", NULL); #endif { - const cItem& tolua_ret = (const cItem&) self->GetHotBarSlot(a_HotBarSlotNum); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + bool tolua_ret = (bool) self->RemoveOneEquippedItem(); + tolua_pushboolean(tolua_S,(bool)tolua_ret); } } return 1; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetHotBarSlot'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'RemoveOneEquippedItem'.",&tolua_err); return 0; #endif } #endif //#ifndef TOLUA_DISABLE -/* method: GetEquippedItem of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedItem00 -static int tolua_AllToLua_cInventory_GetEquippedItem00(lua_State* tolua_S) +/* method: HowManyItems of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_HowManyItems00 +static int tolua_AllToLua_cInventory_HowManyItems00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype(tolua_S,1,"const cInventory",0,&tolua_err) || - !tolua_isnoobj(tolua_S,2,&tolua_err) + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) ) goto tolua_lerror; else #endif { - const cInventory* self = (const cInventory*) tolua_tousertype(tolua_S,1,0); + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0)); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedItem'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HowManyItems'", NULL); #endif { - const cItem& tolua_ret = (const cItem&) self->GetEquippedItem(); - tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + int tolua_ret = (int) self->HowManyItems(*a_Item); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } return 1; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'GetEquippedItem'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'HowManyItems'.",&tolua_err); return 0; #endif } #endif //#ifndef TOLUA_DISABLE -/* method: SetSlot of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetSlot00 -static int tolua_AllToLua_cInventory_SetSlot00(lua_State* tolua_S) +/* method: HasItems of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_HasItems00 +static int tolua_AllToLua_cInventory_HasItems00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || - !tolua_isnumber(tolua_S,2,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + const cItem* a_ItemStack = ((const cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasItems'", NULL); +#endif + { + bool tolua_ret = (bool) self->HasItems(*a_ItemStack); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HasItems'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetArmorGrid of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetArmorGrid00 +static int tolua_AllToLua_cInventory_GetArmorGrid00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetArmorGrid'", NULL); +#endif + { + cItemGrid& tolua_ret = (cItemGrid&) self->GetArmorGrid(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItemGrid"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetArmorGrid'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetInventoryGrid of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetInventoryGrid00 +static int tolua_AllToLua_cInventory_GetInventoryGrid00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetInventoryGrid'", NULL); +#endif + { + cItemGrid& tolua_ret = (cItemGrid&) self->GetInventoryGrid(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItemGrid"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetInventoryGrid'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHotbarGrid of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetHotbarGrid00 +static int tolua_AllToLua_cInventory_GetHotbarGrid00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHotbarGrid'", NULL); +#endif + { + cItemGrid& tolua_ret = (cItemGrid&) self->GetHotbarGrid(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cItemGrid"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHotbarGrid'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetOwner of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetOwner00 +static int tolua_AllToLua_cInventory_GetOwner00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetOwner'", NULL); +#endif + { + cPlayer& tolua_ret = (cPlayer&) self->GetOwner(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"cPlayer"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetOwner'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: CopyToItems of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_CopyToItems00 +static int tolua_AllToLua_cInventory_CopyToItems00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItems",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + cItems* a_Items = ((cItems*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'CopyToItems'", NULL); +#endif + { + self->CopyToItems(*a_Items); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'CopyToItems'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetSlot00 +static int tolua_AllToLua_cInventory_GetSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cInventory* self = (const cInventory*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetSlot'", NULL); +#endif + { + const cItem& tolua_ret = (const cItem&) self->GetSlot(a_SlotNum); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetArmorSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetArmorSlot00 +static int tolua_AllToLua_cInventory_GetArmorSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cInventory* self = (const cInventory*) tolua_tousertype(tolua_S,1,0); + int a_ArmorSlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetArmorSlot'", NULL); +#endif + { + const cItem& tolua_ret = (const cItem&) self->GetArmorSlot(a_ArmorSlotNum); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetArmorSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetInventorySlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetInventorySlot00 +static int tolua_AllToLua_cInventory_GetInventorySlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cInventory* self = (const cInventory*) tolua_tousertype(tolua_S,1,0); + int a_InventorySlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetInventorySlot'", NULL); +#endif + { + const cItem& tolua_ret = (const cItem&) self->GetInventorySlot(a_InventorySlotNum); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetInventorySlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetHotbarSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetHotbarSlot00 +static int tolua_AllToLua_cInventory_GetHotbarSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cInventory* self = (const cInventory*) tolua_tousertype(tolua_S,1,0); + int a_HotBarSlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHotbarSlot'", NULL); +#endif + { + const cItem& tolua_ret = (const cItem&) self->GetHotbarSlot(a_HotBarSlotNum); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetHotbarSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: GetEquippedItem of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_GetEquippedItem00 +static int tolua_AllToLua_cInventory_GetEquippedItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"const cInventory",0,&tolua_err) || + !tolua_isnoobj(tolua_S,2,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + const cInventory* self = (const cInventory*) tolua_tousertype(tolua_S,1,0); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetEquippedItem'", NULL); +#endif + { + const cItem& tolua_ret = (const cItem&) self->GetEquippedItem(); + tolua_pushusertype(tolua_S,(void*)&tolua_ret,"const cItem"); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'GetEquippedItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetSlot00 +static int tolua_AllToLua_cInventory_SetSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const cItem",0,&tolua_err)) || !tolua_isnoobj(tolua_S,4,&tolua_err) ) @@ -12922,9 +13194,79 @@ static int tolua_AllToLua_cInventory_SetSlot00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE -/* method: SetHotBarSlot of class cInventory */ -#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetHotBarSlot00 -static int tolua_AllToLua_cInventory_SetHotBarSlot00(lua_State* tolua_S) +/* method: SetArmorSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetArmorSlot00 +static int tolua_AllToLua_cInventory_SetArmorSlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_ArmorSlotNum = ((int) tolua_tonumber(tolua_S,2,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetArmorSlot'", NULL); +#endif + { + self->SetArmorSlot(a_ArmorSlotNum,*a_Item); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetArmorSlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetInventorySlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetInventorySlot00 +static int tolua_AllToLua_cInventory_SetInventorySlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cInventory",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + (tolua_isvaluenil(tolua_S,3,&tolua_err) || !tolua_isusertype(tolua_S,3,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); + int a_InventorySlotNum = ((int) tolua_tonumber(tolua_S,2,0)); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetInventorySlot'", NULL); +#endif + { + self->SetInventorySlot(a_InventorySlotNum,*a_Item); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SetInventorySlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: SetHotbarSlot of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_SetHotbarSlot00 +static int tolua_AllToLua_cInventory_SetHotbarSlot00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; @@ -12942,16 +13284,16 @@ static int tolua_AllToLua_cInventory_SetHotBarSlot00(lua_State* tolua_S) int a_HotBarSlotNum = ((int) tolua_tonumber(tolua_S,2,0)); const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,3,0)); #ifndef TOLUA_RELEASE - if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetHotBarSlot'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SetHotbarSlot'", NULL); #endif { - self->SetHotBarSlot(a_HotBarSlotNum,*a_Item); + self->SetHotbarSlot(a_HotBarSlotNum,*a_Item); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'SetHotBarSlot'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'SetHotbarSlot'.",&tolua_err); return 0; #endif } @@ -13631,7 +13973,7 @@ static int tolua_AllToLua_cItem_IsStackableWith00(lua_State* tolua_S) #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype(tolua_S,1,"cItem",0,&tolua_err) || + !tolua_isusertype(tolua_S,1,"const cItem",0,&tolua_err) || (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || !tolua_isnoobj(tolua_S,3,&tolua_err) ) @@ -13639,7 +13981,7 @@ static int tolua_AllToLua_cItem_IsStackableWith00(lua_State* tolua_S) else #endif { - cItem* self = (cItem*) tolua_tousertype(tolua_S,1,0); + const cItem* self = (const cItem*) tolua_tousertype(tolua_S,1,0); const cItem* a_OtherStack = ((const cItem*) tolua_tousertype(tolua_S,2,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'IsStackableWith'", NULL); @@ -14493,6 +14835,69 @@ tolua_lerror: } #endif //#ifndef TOLUA_DISABLE +/* method: EmptySlot of class cItemGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItemGrid_EmptySlot00 +static int tolua_AllToLua_cItemGrid_EmptySlot00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); + int a_X = ((int) tolua_tonumber(tolua_S,2,0)); + int a_Y = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'EmptySlot'", NULL); +#endif + { + self->EmptySlot(a_X,a_Y); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'EmptySlot'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: EmptySlot of class cItemGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItemGrid_EmptySlot01 +static int tolua_AllToLua_cItemGrid_EmptySlot01(lua_State* tolua_S) +{ + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else + { + cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'EmptySlot'", NULL); +#endif + { + self->EmptySlot(a_SlotNum); + } + } + return 0; +tolua_lerror: + return tolua_AllToLua_cItemGrid_EmptySlot00(tolua_S); +} +#endif //#ifndef TOLUA_DISABLE + /* method: Clear of class cItemGrid */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cItemGrid_Clear00 static int tolua_AllToLua_cItemGrid_Clear00(lua_State* tolua_S) @@ -14567,7 +14972,8 @@ static int tolua_AllToLua_cItemGrid_AddItem00(lua_State* tolua_S) if ( !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) + !tolua_isboolean(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) ) goto tolua_lerror; else @@ -14575,12 +14981,13 @@ static int tolua_AllToLua_cItemGrid_AddItem00(lua_State* tolua_S) { cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); cItem* a_ItemStack = ((cItem*) tolua_tousertype(tolua_S,2,0)); + bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItem'", NULL); #endif { - bool tolua_ret = (bool) self->AddItem(*a_ItemStack); - tolua_pushboolean(tolua_S,(bool)tolua_ret); + int tolua_ret = (int) self->AddItem(*a_ItemStack,a_AllowNewStacks); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } return 1; @@ -14601,7 +15008,8 @@ static int tolua_AllToLua_cItemGrid_AddItems00(lua_State* tolua_S) if ( !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItems",0,&tolua_err)) || - !tolua_isnoobj(tolua_S,3,&tolua_err) + !tolua_isboolean(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) ) goto tolua_lerror; else @@ -14609,12 +15017,13 @@ static int tolua_AllToLua_cItemGrid_AddItems00(lua_State* tolua_S) { cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); cItems* a_ItemStackList = ((cItems*) tolua_tousertype(tolua_S,2,0)); + bool a_AllowNewStacks = ((bool) tolua_toboolean(tolua_S,3,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItems'", NULL); #endif { - bool tolua_ret = (bool) self->AddItems(*a_ItemStackList); - tolua_pushboolean(tolua_S,(bool)tolua_ret); + int tolua_ret = (int) self->AddItems(*a_ItemStackList,a_AllowNewStacks); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } return 1; @@ -14626,6 +15035,110 @@ static int tolua_AllToLua_cItemGrid_AddItems00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: ChangeSlotCount of class cItemGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItemGrid_ChangeSlotCount00 +static int tolua_AllToLua_cItemGrid_ChangeSlotCount00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); + int a_AddToCount = ((int) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'ChangeSlotCount'", NULL); +#endif + { + int tolua_ret = (int) self->ChangeSlotCount(a_SlotNum,a_AddToCount); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'ChangeSlotCount'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HowManyItems of class cItemGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItemGrid_HowManyItems00 +static int tolua_AllToLua_cItemGrid_HowManyItems00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); + const cItem* a_Item = ((const cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HowManyItems'", NULL); +#endif + { + int tolua_ret = (int) self->HowManyItems(*a_Item); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HowManyItems'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HasItems of class cItemGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItemGrid_HasItems00 +static int tolua_AllToLua_cItemGrid_HasItems00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || + (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"const cItem",0,&tolua_err)) || + !tolua_isnoobj(tolua_S,3,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); + const cItem* a_ItemStack = ((const cItem*) tolua_tousertype(tolua_S,2,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HasItems'", NULL); +#endif + { + bool tolua_ret = (bool) self->HasItems(*a_ItemStack); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'HasItems'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: GetFirstEmptySlot of class cItemGrid */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cItemGrid_GetFirstEmptySlot00 static int tolua_AllToLua_cItemGrid_GetFirstEmptySlot00(lua_State* tolua_S) @@ -14757,6 +15270,42 @@ static int tolua_AllToLua_cItemGrid_CopyToItems00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* method: DamageItem of class cItemGrid */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cItemGrid_DamageItem00 +static int tolua_AllToLua_cItemGrid_DamageItem00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cItemGrid",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnoobj(tolua_S,4,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cItemGrid* self = (cItemGrid*) tolua_tousertype(tolua_S,1,0); + int a_SlotNum = ((int) tolua_tonumber(tolua_S,2,0)); + short a_Amount = ((short) tolua_tonumber(tolua_S,3,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'DamageItem'", NULL); +#endif + { + bool tolua_ret = (bool) self->DamageItem(a_SlotNum,a_Amount); + tolua_pushboolean(tolua_S,(bool)tolua_ret); + } + } + return 1; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'DamageItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: new of class cChestEntity */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cChestEntity_new00 static int tolua_AllToLua_cChestEntity_new00(lua_State* tolua_S) @@ -24893,6 +25442,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsChestPlate",tolua_AllToLua_ItemCategory_IsChestPlate00); tolua_function(tolua_S,"IsLeggings",tolua_AllToLua_ItemCategory_IsLeggings00); tolua_function(tolua_S,"IsBoots",tolua_AllToLua_ItemCategory_IsBoots00); + tolua_function(tolua_S,"IsArmor",tolua_AllToLua_ItemCategory_IsArmor00); tolua_endmodule(tolua_S); tolua_function(tolua_S,"GetTime",tolua_AllToLua_GetTime00); tolua_function(tolua_S,"GetChar",tolua_AllToLua_GetChar00); @@ -24973,7 +25523,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetParentClass",tolua_AllToLua_cEntity_GetParentClass00); tolua_function(tolua_S,"GetWorld",tolua_AllToLua_cEntity_GetWorld00); tolua_function(tolua_S,"GetHeadYaw",tolua_AllToLua_cEntity_GetHeadYaw00); - tolua_function(tolua_S,"GetHeight",tolua_AllToLua_cEntity_GetHeight00); tolua_function(tolua_S,"GetMass",tolua_AllToLua_cEntity_GetMass00); tolua_function(tolua_S,"GetPosition",tolua_AllToLua_cEntity_GetPosition00); tolua_function(tolua_S,"GetPosX",tolua_AllToLua_cEntity_GetPosX00); @@ -24988,11 +25537,9 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"GetSpeedX",tolua_AllToLua_cEntity_GetSpeedX00); tolua_function(tolua_S,"GetSpeedY",tolua_AllToLua_cEntity_GetSpeedY00); tolua_function(tolua_S,"GetSpeedZ",tolua_AllToLua_cEntity_GetSpeedZ00); - tolua_function(tolua_S,"GetWidth",tolua_AllToLua_cEntity_GetWidth00); tolua_function(tolua_S,"GetChunkX",tolua_AllToLua_cEntity_GetChunkX00); tolua_function(tolua_S,"GetChunkZ",tolua_AllToLua_cEntity_GetChunkZ00); tolua_function(tolua_S,"SetHeadYaw",tolua_AllToLua_cEntity_SetHeadYaw00); - tolua_function(tolua_S,"SetHeight",tolua_AllToLua_cEntity_SetHeight00); tolua_function(tolua_S,"SetMass",tolua_AllToLua_cEntity_SetMass00); tolua_function(tolua_S,"SetPosX",tolua_AllToLua_cEntity_SetPosX00); tolua_function(tolua_S,"SetPosY",tolua_AllToLua_cEntity_SetPosY00); @@ -25008,7 +25555,6 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"SetSpeedX",tolua_AllToLua_cEntity_SetSpeedX00); tolua_function(tolua_S,"SetSpeedY",tolua_AllToLua_cEntity_SetSpeedY00); tolua_function(tolua_S,"SetSpeedZ",tolua_AllToLua_cEntity_SetSpeedZ00); - tolua_function(tolua_S,"SetWidth",tolua_AllToLua_cEntity_SetWidth00); tolua_function(tolua_S,"AddPosX",tolua_AllToLua_cEntity_AddPosX00); tolua_function(tolua_S,"AddPosY",tolua_AllToLua_cEntity_AddPosY00); tolua_function(tolua_S,"AddPosZ",tolua_AllToLua_cEntity_AddPosZ00); @@ -25306,17 +25852,37 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"IsBlockDirectlyWatered",tolua_AllToLua_cWorld_IsBlockDirectlyWatered00); tolua_function(tolua_S,"SpawnMob",tolua_AllToLua_cWorld_SpawnMob00); tolua_endmodule(tolua_S); - tolua_cclass(tolua_S,"cInventory","cInventory","",NULL); + tolua_cclass(tolua_S,"cInventory","cInventory","cItemGrid::cListener",NULL); tolua_beginmodule(tolua_S,"cInventory"); + tolua_constant(tolua_S,"invArmorCount",cInventory::invArmorCount); + tolua_constant(tolua_S,"invInventoryCount",cInventory::invInventoryCount); + tolua_constant(tolua_S,"invHotbarCount",cInventory::invHotbarCount); + tolua_constant(tolua_S,"invArmorOffset",cInventory::invArmorOffset); + tolua_constant(tolua_S,"invInventoryOffset",cInventory::invInventoryOffset); + tolua_constant(tolua_S,"invHotbarOffset",cInventory::invHotbarOffset); + tolua_constant(tolua_S,"invNumSlots",cInventory::invNumSlots); tolua_function(tolua_S,"Clear",tolua_AllToLua_cInventory_Clear00); + tolua_function(tolua_S,"HowManyCanFit",tolua_AllToLua_cInventory_HowManyCanFit00); + tolua_function(tolua_S,"HowManyCanFit",tolua_AllToLua_cInventory_HowManyCanFit01); tolua_function(tolua_S,"AddItem",tolua_AllToLua_cInventory_AddItem00); - tolua_function(tolua_S,"AddItemAnyAmount",tolua_AllToLua_cInventory_AddItemAnyAmount00); - tolua_function(tolua_S,"RemoveItem",tolua_AllToLua_cInventory_RemoveItem00); + tolua_function(tolua_S,"AddItems",tolua_AllToLua_cInventory_AddItems00); + tolua_function(tolua_S,"RemoveOneEquippedItem",tolua_AllToLua_cInventory_RemoveOneEquippedItem00); + tolua_function(tolua_S,"HowManyItems",tolua_AllToLua_cInventory_HowManyItems00); + tolua_function(tolua_S,"HasItems",tolua_AllToLua_cInventory_HasItems00); + tolua_function(tolua_S,"GetArmorGrid",tolua_AllToLua_cInventory_GetArmorGrid00); + tolua_function(tolua_S,"GetInventoryGrid",tolua_AllToLua_cInventory_GetInventoryGrid00); + tolua_function(tolua_S,"GetHotbarGrid",tolua_AllToLua_cInventory_GetHotbarGrid00); + tolua_function(tolua_S,"GetOwner",tolua_AllToLua_cInventory_GetOwner00); + tolua_function(tolua_S,"CopyToItems",tolua_AllToLua_cInventory_CopyToItems00); tolua_function(tolua_S,"GetSlot",tolua_AllToLua_cInventory_GetSlot00); - tolua_function(tolua_S,"GetHotBarSlot",tolua_AllToLua_cInventory_GetHotBarSlot00); + tolua_function(tolua_S,"GetArmorSlot",tolua_AllToLua_cInventory_GetArmorSlot00); + tolua_function(tolua_S,"GetInventorySlot",tolua_AllToLua_cInventory_GetInventorySlot00); + tolua_function(tolua_S,"GetHotbarSlot",tolua_AllToLua_cInventory_GetHotbarSlot00); tolua_function(tolua_S,"GetEquippedItem",tolua_AllToLua_cInventory_GetEquippedItem00); tolua_function(tolua_S,"SetSlot",tolua_AllToLua_cInventory_SetSlot00); - tolua_function(tolua_S,"SetHotBarSlot",tolua_AllToLua_cInventory_SetHotBarSlot00); + tolua_function(tolua_S,"SetArmorSlot",tolua_AllToLua_cInventory_SetArmorSlot00); + tolua_function(tolua_S,"SetInventorySlot",tolua_AllToLua_cInventory_SetInventorySlot00); + tolua_function(tolua_S,"SetHotbarSlot",tolua_AllToLua_cInventory_SetHotbarSlot00); tolua_function(tolua_S,"SetEquippedSlotNum",tolua_AllToLua_cInventory_SetEquippedSlotNum00); tolua_function(tolua_S,"GetEquippedSlotNum",tolua_AllToLua_cInventory_GetEquippedSlotNum00); tolua_function(tolua_S,"DamageItem",tolua_AllToLua_cInventory_DamageItem00); @@ -25383,14 +25949,20 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"SetSlot",tolua_AllToLua_cItemGrid_SetSlot01); tolua_function(tolua_S,"SetSlot",tolua_AllToLua_cItemGrid_SetSlot02); tolua_function(tolua_S,"SetSlot",tolua_AllToLua_cItemGrid_SetSlot03); + tolua_function(tolua_S,"EmptySlot",tolua_AllToLua_cItemGrid_EmptySlot00); + tolua_function(tolua_S,"EmptySlot",tolua_AllToLua_cItemGrid_EmptySlot01); tolua_function(tolua_S,"Clear",tolua_AllToLua_cItemGrid_Clear00); tolua_function(tolua_S,"HowManyCanFit",tolua_AllToLua_cItemGrid_HowManyCanFit00); tolua_function(tolua_S,"AddItem",tolua_AllToLua_cItemGrid_AddItem00); tolua_function(tolua_S,"AddItems",tolua_AllToLua_cItemGrid_AddItems00); + tolua_function(tolua_S,"ChangeSlotCount",tolua_AllToLua_cItemGrid_ChangeSlotCount00); + tolua_function(tolua_S,"HowManyItems",tolua_AllToLua_cItemGrid_HowManyItems00); + tolua_function(tolua_S,"HasItems",tolua_AllToLua_cItemGrid_HasItems00); tolua_function(tolua_S,"GetFirstEmptySlot",tolua_AllToLua_cItemGrid_GetFirstEmptySlot00); tolua_function(tolua_S,"GetLastEmptySlot",tolua_AllToLua_cItemGrid_GetLastEmptySlot00); tolua_function(tolua_S,"GetNextEmptySlot",tolua_AllToLua_cItemGrid_GetNextEmptySlot00); tolua_function(tolua_S,"CopyToItems",tolua_AllToLua_cItemGrid_CopyToItems00); + tolua_function(tolua_S,"DamageItem",tolua_AllToLua_cItemGrid_DamageItem00); tolua_endmodule(tolua_S); #ifdef __cplusplus tolua_cclass(tolua_S,"cChestEntity","cChestEntity","cBlockEntity",tolua_collect_cChestEntity); diff --git a/source/Bindings.h b/source/Bindings.h index 92199ac97..f4b0a8d0c 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 05/21/13 14:54:11. +** Generated automatically by tolua++-1.0.92 on 05/24/13 09:11:00. */ /* Exported function */ diff --git a/source/Blocks/BlockCauldron.h b/source/Blocks/BlockCauldron.h index 360604f85..571235441 100644 --- a/source/Blocks/BlockCauldron.h +++ b/source/Blocks/BlockCauldron.h @@ -29,8 +29,7 @@ public: case E_ITEM_WATER_BUCKET: { a_World->SetBlockMeta( a_BlockX, a_BlockY, a_BlockZ, 3 ); - cItem Item(a_Player->GetEquippedItem().m_ItemType, 1); - a_Player->GetInventory().RemoveItem(Item); + a_Player->GetInventory().RemoveOneEquippedItem(); cItem NewItem(E_ITEM_BUCKET, 1); a_Player->GetInventory().AddItem(NewItem); break; @@ -39,9 +38,8 @@ public: { if( Meta > 0 ) { - a_World->SetBlockMeta( a_BlockX, a_BlockY, a_BlockZ, --Meta ); - cItem Item(a_Player->GetEquippedItem().m_ItemType, 1); - a_Player->GetInventory().RemoveItem(Item); + a_World->SetBlockMeta( a_BlockX, a_BlockY, a_BlockZ, --Meta); + a_Player->GetInventory().RemoveOneEquippedItem(); cItem NewItem(E_ITEM_POTIONS, 1, 0); a_Player->GetInventory().AddItem(NewItem); } diff --git a/source/Blocks/BlockFlowerPot.h b/source/Blocks/BlockFlowerPot.h index 1c02126df..12cd594de 100644 --- a/source/Blocks/BlockFlowerPot.h +++ b/source/Blocks/BlockFlowerPot.h @@ -86,10 +86,9 @@ public: } } - if (a_Player->GetGameMode() != eGameMode_Creative) + if (a_Player->GetGameMode() != gmCreative) { - cItem Item(a_Player->GetEquippedItem().m_ItemType, 1); - a_Player->GetInventory().RemoveItem(Item); + a_Player->GetInventory().RemoveOneEquippedItem(); } a_World->SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); } diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 1ea94c8c2..6fe874bc4 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -791,7 +791,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, c if (ItemHandler->EatItem(m_Player, &Item)) { ItemHandler->OnFoodEaten(World, m_Player, &Item); - m_Player->GetInventory().RemoveItem(Item); + m_Player->GetInventory().RemoveOneEquippedItem(); return; } } @@ -877,10 +877,9 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c // The actual block placement: World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); - if (m_Player->GetGameMode() == eGameMode_Survival) + if (m_Player->GetGameMode() != gmCreative) { - cItem Item(m_Player->GetEquippedItem().m_ItemType, 1); - m_Player->GetInventory().RemoveItem(Item); + m_Player->GetInventory().RemoveOneEquippedItem(); } NewBlock->OnPlacedByPlayer(World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta); diff --git a/source/Inventory.cpp b/source/Inventory.cpp index 8591b7dc2..fc52d4621 100644 --- a/source/Inventory.cpp +++ b/source/Inventory.cpp @@ -18,13 +18,16 @@ cInventory::cInventory(cPlayer & a_Owner) : + m_ArmorSlots (1, 4), // 1 x 4 slots + m_InventorySlots(9, 3), // 9 x 3 slots + m_HotbarSlots (9, 1), // 9 x 1 slots m_Owner(a_Owner) { - m_CraftSlots = m_Slots + c_CraftOffset; - m_ArmorSlots = m_Slots + c_ArmorOffset; - m_MainSlots = m_Slots + c_MainOffset; - m_HotSlots = m_Slots + c_HotOffset; - + // Ask each ItemGrid to report changes to us: + m_ArmorSlots.AddListener(*this); + m_InventorySlots.AddListener(*this); + m_HotbarSlots.AddListener(*this); + SetEquippedSlotNum(0); } @@ -32,151 +35,153 @@ cInventory::cInventory(cPlayer & a_Owner) : -cInventory::~cInventory() +void cInventory::Clear(void) { - /* - // TODO - cWindow wnd = GetWindow(); - if (wnd != NULL) - { - wnd->Close(*m_Owner); - } - CloseWindow(); - */ + m_ArmorSlots.Clear(); + m_InventorySlots.Clear(); + m_HotbarSlots.Clear(); } -bool cInventory::AddItem( cItem & a_Item ) +int cInventory::HowManyCanFit(const cItem & a_ItemStack, bool a_ConsiderEmptySlots) { - cItem BackupSlots[c_NumSlots]; - memcpy( BackupSlots, m_Slots, c_NumSlots * sizeof( cItem ) ); + return HowManyCanFit(a_ItemStack, 0, invNumSlots - 1, a_ConsiderEmptySlots); +} + + - bool ChangedSlots[c_NumSlots]; - memset( ChangedSlots, false, c_NumSlots * sizeof( bool ) ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 0 ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 0 ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 2 ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 2 ); - if( a_Item.m_ItemCount > 0 ) // Could not add all items +int cInventory::HowManyCanFit(const cItem & a_ItemStack, int a_BeginSlotNum, int a_EndSlotNum, bool a_ConsiderEmptySlots) +{ + if ((a_BeginSlotNum < 0) || (a_BeginSlotNum >= invNumSlots)) { - // retore backup - memcpy( m_Slots, BackupSlots, c_NumSlots * sizeof( cItem ) ); - return false; + LOGWARNING("%s: Bad BeginSlotNum, got %d, there are %d slots; correcting to 0.", __FUNCTION__, a_BeginSlotNum, invNumSlots - 1); + a_BeginSlotNum = 0; + } + if ((a_EndSlotNum < 0) || (a_EndSlotNum >= invNumSlots)) + { + LOGWARNING("%s: Bad EndSlotNum, got %d, there are %d slots; correcting to %d.", __FUNCTION__, a_BeginSlotNum, invNumSlots, invNumSlots - 1); + a_EndSlotNum = invNumSlots - 1; + } + if (a_BeginSlotNum > a_EndSlotNum) + { + std::swap(a_BeginSlotNum, a_EndSlotNum); } - for (unsigned int i = 0; i < c_NumSlots; i++) + char NumLeft = a_ItemStack.m_ItemCount; + int MaxStack = ItemHandler(a_ItemStack.m_ItemType)->GetMaxStackSize(); + for (int i = a_BeginSlotNum; i <= a_EndSlotNum; i++) { - if (ChangedSlots[i]) + const cItem & Slot = GetSlot(i); + if (Slot.IsEmpty()) { - LOGD("cInventory::AddItem(): Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemType, m_Slots[i].m_ItemCount); - SendSlot(i); + NumLeft -= MaxStack; } - } - - return (a_Item.m_ItemCount == 0); + else if (Slot.IsStackableWith(a_ItemStack)) + { + NumLeft -= MaxStack - Slot.m_ItemCount; + } + if (NumLeft <= 0) + { + // All items fit + return a_ItemStack.m_ItemCount; + } + } // for i - m_Slots[] + return a_ItemStack.m_ItemCount - NumLeft; } -bool cInventory::AddItemAnyAmount( cItem & a_Item ) +int cInventory::AddItem(const cItem & a_Item, bool a_AllowNewStacks) { - bool ChangedSlots[c_NumSlots]; - memset( ChangedSlots, false, c_NumSlots * sizeof( bool ) ); - - char StartCount = a_Item.m_ItemCount; - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 0 ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 0 ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_HotOffset, c_HotSlots, ChangedSlots, 2 ); - if( a_Item.m_ItemCount > 0 ) AddToBar( a_Item, c_MainOffset, c_MainSlots, ChangedSlots, 2 ); - - if (a_Item.m_ItemCount == StartCount) - return false; - - for (unsigned int i = 0; i < c_NumSlots; i++) + cItem ToAdd(a_Item); + int res = 0; + if (ItemCategory::IsArmor(a_Item.m_ItemType)) { - if (ChangedSlots[i]) + res = m_ArmorSlots.AddItem(ToAdd, a_AllowNewStacks); + ToAdd.m_ItemCount -= res; + if (ToAdd.m_ItemCount == 0) { - LOGD("cInventory::AddItemAnyAmount(): Item was added to %i ID:%i Count:%i", i, m_Slots[i].m_ItemType, m_Slots[i].m_ItemCount); - SendSlot(i); + return res; } } - return true; + res += m_HotbarSlots.AddItem(ToAdd, a_AllowNewStacks); + ToAdd.m_ItemCount = a_Item.m_ItemCount - res; + if (ToAdd.m_ItemCount == 0) + { + return res; + } + + res += m_InventorySlots.AddItem(ToAdd, a_AllowNewStacks); + return res; } -// TODO: Right now if you dont have enough items, the items you did have are removed, and the function returns false anyway -bool cInventory::RemoveItem(cItem & a_Item) +int cInventory::AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks) { - // First check equipped slot - if ((m_EquippedSlotNum >= 0) && (m_EquippedSlotNum < 9)) + int TotalAdded = 0; + for (cItems::iterator itr = a_ItemStackList.begin(); itr != a_ItemStackList.end();) { - if (m_HotSlots[m_EquippedSlotNum].m_ItemType == a_Item.m_ItemType) + int NumAdded = AddItem(*itr, a_AllowNewStacks); + if (itr->m_ItemCount == NumAdded) { - cItem & Item = m_HotSlots[m_EquippedSlotNum]; - if (Item.m_ItemCount > a_Item.m_ItemCount) - { - Item.m_ItemCount -= a_Item.m_ItemCount; - SendSlot(m_EquippedSlotNum + c_HotOffset); - return true; - } - else if (Item.m_ItemCount > 0) - { - a_Item.m_ItemCount -= Item.m_ItemCount; - Item.Empty(); - SendSlot(m_EquippedSlotNum + c_HotOffset); - } + itr = a_ItemStackList.erase(itr); } - } - - // Then check other slotz - if (a_Item.m_ItemCount > 0) - { - for (int i = 0; i < c_MainSlots; i++) + else { - cItem & Item = m_MainSlots[i]; - if (Item.m_ItemType == a_Item.m_ItemType) - { - if (Item.m_ItemCount > a_Item.m_ItemCount) - { - Item.m_ItemCount -= a_Item.m_ItemCount; - SendSlot(i + c_MainOffset); - return true; - } - else if (Item.m_ItemCount > 0) - { - a_Item.m_ItemCount -= Item.m_ItemCount; - Item.Empty(); - SendSlot(i + c_MainOffset); - } - } + itr->m_ItemCount -= NumAdded; + ++itr; } + TotalAdded += NumAdded; } - - return (a_Item.m_ItemCount == 0); + return TotalAdded; } -void cInventory::Clear() +bool cInventory::RemoveOneEquippedItem(void) { - for (unsigned int i = 0; i < ARRAYCOUNT(m_Slots); i++) + if (m_HotbarSlots.GetSlot(m_EquippedSlotNum).IsEmpty()) { - m_Slots[i].Empty(); + return false; } - // TODO: Broadcast / send the changes to wherever needed + + m_HotbarSlots.ChangeSlotCount(m_EquippedSlotNum, -1); + return true; +} + + + + + +int cInventory::HowManyItems(const cItem & a_Item) +{ + return + m_ArmorSlots.HowManyItems(a_Item) + + m_InventorySlots.HowManyItems(a_Item) + + m_HotbarSlots.HowManyItems(a_Item); +} + + + + + +bool cInventory::HasItems(const cItem & a_ItemStack) +{ + int CurrentlyHave = HowManyItems(a_ItemStack); + return (CurrentlyHave >= a_ItemStack.m_ItemCount); } @@ -185,29 +190,47 @@ void cInventory::Clear() void cInventory::SetSlot(int a_SlotNum, const cItem & a_Item) { - if ((a_SlotNum < 0) || (a_SlotNum >= ARRAYCOUNT(m_Slots))) + if ((a_SlotNum < 0) || (a_SlotNum >= invNumSlots)) { - LOGWARNING("%s requesting an invalid slot index: %d out of %d. Ignoring.", __FUNCTION__, a_SlotNum, ARRAYCOUNT(m_Slots)); + LOGWARNING("%s: requesting an invalid slot index: %d out of %d. Ignoring.", __FUNCTION__, a_SlotNum, invNumSlots - 1); return; } - m_Slots[a_SlotNum] = a_Item; - - // If an armor slot was touched, broadcast an EntityEquipment packet - if ((a_SlotNum >= c_ArmorOffset) && (a_SlotNum < c_MainOffset)) + + int GridSlotNum = 0; + cItemGrid * Grid = GetGridForSlotNum(a_SlotNum, GridSlotNum); + if (Grid == NULL) { - m_Owner.GetWorld()->BroadcastEntityEquipment(m_Owner, SlotNumToEntityEquipmentID(a_SlotNum), a_Item, m_Owner.GetClientHandle()); + LOGWARNING("%s(%d): requesting an invalid itemgrid. Ignoring.", __FUNCTION__, a_SlotNum); + return; } - - SendSlot(a_SlotNum); + Grid->SetSlot(GridSlotNum, a_Item); +} + + + + + +void cInventory::SetArmorSlot(int a_ArmorSlotNum, const cItem & a_Item) +{ + m_ArmorSlots.SetSlot(a_ArmorSlotNum, a_Item); } -void cInventory::SetHotBarSlot(int a_HotBarSlotNum, const cItem & a_Item) +void cInventory::SetInventorySlot(int a_InventorySlotNum, const cItem & a_Item) { - SetSlot(a_HotBarSlotNum + c_HotSlots, a_Item); + m_InventorySlots.SetSlot(a_InventorySlotNum, a_Item); +} + + + + + +void cInventory::SetHotbarSlot(int a_HotBarSlotNum, const cItem & a_Item) +{ + m_HotbarSlots.SetSlot(a_HotBarSlotNum, a_Item); } @@ -216,27 +239,62 @@ void cInventory::SetHotBarSlot(int a_HotBarSlotNum, const cItem & a_Item) const cItem & cInventory::GetSlot(int a_SlotNum) const { - if ((a_SlotNum < 0) || (a_SlotNum >= ARRAYCOUNT(m_Slots))) + if ((a_SlotNum < 0) || (a_SlotNum >= invNumSlots)) { - LOGWARNING("%s requesting an invalid slot index: %d out of %d. Returning the first one instead.", __FUNCTION__, a_SlotNum, ARRAYCOUNT(m_Slots)); - return m_Slots[0]; + LOGWARNING("%s: requesting an invalid slot index: %d out of %d. Returning the first inventory slot instead.", __FUNCTION__, a_SlotNum, invNumSlots - 1); + return m_InventorySlots.GetSlot(0); } - - return m_Slots[a_SlotNum]; + int GridSlotNum = 0; + const cItemGrid * Grid = GetGridForSlotNum(a_SlotNum, GridSlotNum); + if (Grid == NULL) + { + // Something went wrong, but we don't know what. We must return a value, so return the first inventory slot + LOGWARNING("%s(%d): requesting an invalid ItemGrid, returning the first inventory slot instead.", __FUNCTION__, a_SlotNum); + return m_InventorySlots.GetSlot(0); + } + return Grid->GetSlot(GridSlotNum); +} + + + + + +const cItem & cInventory::GetArmorSlot(int a_ArmorSlotNum) const +{ + if ((a_ArmorSlotNum < 0) || (a_ArmorSlotNum >= invArmorCount)) + { + LOGWARNING("%s: requesting an invalid slot index: %d out of %d. Returning the first one instead", __FUNCTION__, a_ArmorSlotNum, invArmorCount - 1); + return m_ArmorSlots.GetSlot(0); + } + return m_ArmorSlots.GetSlot(a_ArmorSlotNum); } -const cItem & cInventory::GetHotBarSlot(int a_SlotNum) const +const cItem & cInventory::GetInventorySlot(int a_InventorySlotNum) const { - if ((a_SlotNum < 0) || (a_SlotNum >= 9)) + if ((a_InventorySlotNum < 0) || (a_InventorySlotNum >= invInventoryCount)) { - LOGWARNING("%s requesting an invalid slot index: %d out of 9. Returning the first one instead", __FUNCTION__, a_SlotNum); - return m_HotSlots[0]; + LOGWARNING("%s: requesting an invalid slot index: %d out of %d. Returning the first one instead", __FUNCTION__, a_InventorySlotNum, invInventoryCount - 1); + return m_InventorySlots.GetSlot(0); } - return m_HotSlots[a_SlotNum]; + return m_InventorySlots.GetSlot(a_InventorySlotNum); +} + + + + + +const cItem & cInventory::GetHotbarSlot(int a_SlotNum) const +{ + if ((a_SlotNum < 0) || (a_SlotNum >= invHotbarCount)) + { + LOGWARNING("%s: requesting an invalid slot index: %d out of %d. Returning the first one instead", __FUNCTION__, a_SlotNum, invHotbarCount - 1); + return m_HotbarSlots.GetSlot(0); + } + return m_HotbarSlots.GetSlot(a_SlotNum); } @@ -245,7 +303,7 @@ const cItem & cInventory::GetHotBarSlot(int a_SlotNum) const const cItem & cInventory::GetEquippedItem(void) const { - return GetHotBarSlot(m_EquippedSlotNum); + return GetHotbarSlot(m_EquippedSlotNum); } @@ -254,14 +312,14 @@ const cItem & cInventory::GetEquippedItem(void) const void cInventory::SetEquippedSlotNum(int a_SlotNum) { - if ((a_SlotNum < 0) || (a_SlotNum >= 9)) + if ((a_SlotNum < 0) || (a_SlotNum >= invHotbarCount)) { - LOGWARNING("%s requesting invalid slot index: %d out of 9. Setting 0 instead.", __FUNCTION__, a_SlotNum); + LOGWARNING("%s: requesting invalid slot index: %d out of %d. Setting 0 instead.", __FUNCTION__, a_SlotNum, invHotbarCount - 1); m_EquippedSlotNum = 0; } else { - m_EquippedSlotNum = (short)a_SlotNum; + m_EquippedSlotNum = a_SlotNum; } } @@ -271,7 +329,7 @@ void cInventory::SetEquippedSlotNum(int a_SlotNum) bool cInventory::DamageEquippedItem(short a_Amount) { - return DamageItem(c_HotOffset + m_EquippedSlotNum, a_Amount); + return DamageItem(invHotbarOffset + m_EquippedSlotNum, a_Amount); } @@ -280,22 +338,27 @@ bool cInventory::DamageEquippedItem(short a_Amount) bool cInventory::DamageItem(int a_SlotNum, short a_Amount) { - if ((a_SlotNum < 0) || (a_SlotNum >= ARRAYCOUNT(m_Slots))) + if ((a_SlotNum < 0) || (a_SlotNum >= invNumSlots)) { - LOGWARNING("%s requesting an invalid slot index: %d out of %d", __FUNCTION__, a_SlotNum, ARRAYCOUNT(m_Slots)); + LOGWARNING("%s: requesting an invalid slot index: %d out of %d", __FUNCTION__, a_SlotNum, invNumSlots - 1); return false; } - if (!m_Slots[a_SlotNum].DamageItem(a_Amount)) + int GridSlotNum = 0; + cItemGrid * Grid = GetGridForSlotNum(a_SlotNum, GridSlotNum); + if (Grid == NULL) { + LOGWARNING("%s(%d, %d): requesting an invalid grid, ignoring.", __FUNCTION__, a_SlotNum, a_Amount); + return false; + } + if (!Grid->DamageItem(GridSlotNum, a_Amount)) + { + // The item has been damaged, but did not break yet return false; } // The item has broken, remove it: - m_Slots[a_SlotNum].Empty(); - SendSlot(a_SlotNum); - - // TODO: If it was a special slot (armor / equipped), broadcast the change + Grid->EmptySlot(a_SlotNum); return true; } @@ -303,6 +366,17 @@ bool cInventory::DamageItem(int a_SlotNum, short a_Amount) +void cInventory::CopyToItems(cItems & a_Items) +{ + m_ArmorSlots.CopyToItems(a_Items); + m_InventorySlots.CopyToItems(a_Items); + m_HotbarSlots.CopyToItems(a_Items); +} + + + + + void cInventory::SendWholeInventory(cClientHandle & a_Client) { a_Client.SendWholeInventory(*this); @@ -320,35 +394,14 @@ void cInventory::SendSlot(int a_SlotNum) // Sanitize items that are not completely empty (ie. count == 0, but type != empty) Item.Empty(); } - m_Owner.GetClientHandle()->SendInventorySlot(0, a_SlotNum, Item); -} - - - - - -int cInventory::HowManyCanFit(short a_ItemType, short a_ItemDamage, int a_BeginSlot, int a_EndSlot) -{ - int res = 0; - for (int i = a_BeginSlot; i <= a_EndSlot; i++) - { - if ( - m_Slots[i].IsEmpty() || - ((m_Slots[i].m_ItemType == a_ItemType) && (m_Slots[i].m_ItemDamage == a_ItemDamage)) - ) - { - int MaxCount = ItemHandler(a_ItemType)->GetMaxStackSize(); - ASSERT(m_Slots[i].m_ItemCount <= MaxCount); - res += MaxCount - m_Slots[i].m_ItemCount; - } - } // for i - m_Slots[] - return res; + m_Owner.GetClientHandle()->SendInventorySlot(0, a_SlotNum + 5, Item); // Slots in the client are numbered "+ 5" because of crafting grid and result } +/* int cInventory::MoveItem(short a_ItemType, short a_ItemDamage, int a_Count, int a_BeginSlot, int a_EndSlot) { int res = 0; @@ -378,21 +431,22 @@ int cInventory::MoveItem(short a_ItemType, short a_ItemDamage, int a_Count, int // No more space to distribute to return res; } +*/ -int cInventory::SlotNumToEntityEquipmentID(short a_SlotNum) +int cInventory::ArmorSlotNumToEntityEquipmentID(short a_ArmorSlotNum) { - switch (a_SlotNum) + switch (a_ArmorSlotNum) { - case 5: return 4; // Helmet - case 6: return 3; // Chestplate - case 7: return 2; // Leggings - case 8: return 1; // Boots + case 0: return 4; // Helmet + case 1: return 3; // Chestplate + case 2: return 2; // Leggings + case 3: return 1; // Boots } - LOGWARN("%s: invalid slot number: %d", __FUNCTION__, a_SlotNum); + LOGWARN("%s: invalid armor slot number: %d", __FUNCTION__, a_ArmorSlotNum); return 0; } @@ -400,6 +454,7 @@ int cInventory::SlotNumToEntityEquipmentID(short a_SlotNum) +#if 0 bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode /* = 0 */ ) { // Fill already present stacks @@ -447,6 +502,7 @@ bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, return true; } +#endif @@ -454,11 +510,37 @@ bool cInventory::AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, void cInventory::SaveToJson(Json::Value & a_Value) { - for(unsigned int i = 0; i < c_NumSlots; i++) + // The JSON originally included the 4 crafting slots and the result, so we have to put empty items there, too: + cItem EmptyItem; + Json::Value EmptyItemJson; + EmptyItem.GetJson(EmptyItemJson); + for (int i = 0; i < 5; i++) + { + a_Value.append(EmptyItemJson); + } + + // The 4 armor slots follow: + for (int i = 0; i < invArmorCount; i++) { Json::Value JSON_Item; - m_Slots[i].GetJson( JSON_Item ); - a_Value.append( JSON_Item ); + m_ArmorSlots.GetSlot(i).GetJson(JSON_Item); + a_Value.append(JSON_Item); + } + + // Next comes the main inventory: + for (int i = 0; i < invInventoryCount; i++) + { + Json::Value JSON_Item; + m_InventorySlots.GetSlot(i).GetJson(JSON_Item); + a_Value.append(JSON_Item); + } + + // The hotbar is the last: + for (int i = 0; i < invHotbarCount; i++) + { + Json::Value JSON_Item; + m_HotbarSlots.GetSlot(i).GetJson(JSON_Item); + a_Value.append(JSON_Item); } } @@ -470,18 +552,124 @@ bool cInventory::LoadFromJson(Json::Value & a_Value) { int SlotIdx = 0; - for( Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr ) + for (Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr, SlotIdx++) { - m_Slots[SlotIdx].FromJson( *itr ); - SlotIdx++; - if (SlotIdx >= ARRAYCOUNT(m_Slots)) + cItem Item; + Item.FromJson(*itr); + + // The JSON originally included the 4 crafting slots and the result slot, so we need to skip the first 5 items: + if (SlotIdx < 5) + { + continue; + } + + // If we loaded all the slots, stop now, even if the JSON has more: + if (SlotIdx - 5 >= invNumSlots) { break; } - } + + int GridSlotNum = 0; + cItemGrid * Grid = GetGridForSlotNum(SlotIdx - 5, GridSlotNum); + ASSERT(Grid != NULL); + Grid->SetSlot(GridSlotNum, Item); + } // for itr - a_Value[] return true; } + +const cItemGrid * cInventory::GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) const +{ + ASSERT(a_SlotNum >= 0); + + if (a_SlotNum < invArmorCount) + { + a_GridSlotNum = a_SlotNum; + return &m_ArmorSlots; + } + a_SlotNum -= invArmorCount; + if (a_SlotNum < invInventoryCount) + { + a_GridSlotNum = a_SlotNum; + return &m_InventorySlots; + } + a_GridSlotNum = a_SlotNum - invInventoryCount; + return &m_HotbarSlots; +} + + + + + +cItemGrid * cInventory::GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) +{ + ASSERT(a_SlotNum >= 0); + + if (a_SlotNum < invArmorCount) + { + a_GridSlotNum = a_SlotNum; + return &m_ArmorSlots; + } + a_SlotNum -= invArmorCount; + if (a_SlotNum < invInventoryCount) + { + a_GridSlotNum = a_SlotNum; + return &m_InventorySlots; + } + a_GridSlotNum = a_SlotNum - invInventoryCount; + return &m_HotbarSlots; +} + + + + + +void cInventory::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) +{ + // Send the neccessary updates to whoever needs them + + if (m_Owner.IsDestroyed()) + { + // Owner is not (yet) valid, skip for now + return; + } + + // Armor update needs broadcast to other players: + cWorld * World = m_Owner.GetWorld(); + if ((a_ItemGrid == &m_ArmorSlots) && (World != NULL)) + { + World->BroadcastEntityEquipment( + m_Owner, ArmorSlotNumToEntityEquipmentID(a_SlotNum), + m_ArmorSlots.GetSlot(a_SlotNum), m_Owner.GetClientHandle() + ); + } + + // Convert the grid-local a_SlotNum to our global SlotNum: + int Base = 0; + if (a_ItemGrid == &m_ArmorSlots) + { + Base = invArmorOffset; + } + else if (a_ItemGrid == &m_InventorySlots) + { + Base = invInventoryOffset; + } + else if (a_ItemGrid == &m_HotbarSlots) + { + Base = invHotbarOffset; + } + else + { + ASSERT(!"Unknown ItemGrid calling OnSlotChanged()"); + return; + } + + SendSlot(Base + a_SlotNum); +} + + + + diff --git a/source/Inventory.h b/source/Inventory.h index 351d900dc..572a566e1 100644 --- a/source/Inventory.h +++ b/source/Inventory.h @@ -1,7 +1,7 @@ #pragma once -#include "Item.h" +#include "ItemGrid.h" @@ -18,36 +18,108 @@ class cPlayer; +// tolua_begin -class cInventory // tolua_export -{ // tolua_export +/** This class represents the player's inventory +The slots are divided into three areas: +- armor slots (1 x 4) +- inventory slots (9 x 3) +- hotbar slots (9 x 1) +The generic GetSlot(), SetSlot() and HowManyCanFit() functions take the index of the slots, +as if armor slots, inventory slots and then hotbar slots were put one after another. +You can use the invArmorOffset, invInventoryOffset and invHotbarOffset constants. +*/ + +class cInventory : + public cItemGrid::cListener +{ public: - cInventory(cPlayer & a_Owner); - ~cInventory(); + + // Counts and offsets to individual parts of the inventory, as used by GetSlot() / SetSlot() / HowManyCanFit(): + enum + { + invArmorCount = 4, + invInventoryCount = 9 * 3, + invHotbarCount = 9, + + invArmorOffset = 0, + invInventoryOffset = invArmorOffset + invArmorCount, + invHotbarOffset = invInventoryOffset + invInventoryCount, + invNumSlots = invHotbarOffset + invHotbarCount + } ; - void Clear(); // tolua_export + // tolua_end + + cInventory(cPlayer & a_Owner); + + // tolua_begin - // cItem * GetSlotsForType( int a_Type ); - // int GetSlotCountForType( int a_Type ); + /// Removes all items from the entire inventory + void Clear(void); - bool AddItem( cItem & a_Item ); // tolua_export - bool AddItemAnyAmount( cItem & a_Item ); // tolua_export - bool RemoveItem( cItem & a_Item ); // tolua_export + /// Returns number of items out of a_ItemStack that can fit in the storage + int HowManyCanFit(const cItem & a_ItemStack, bool a_ConsiderEmptySlots); - void SaveToJson(Json::Value & a_Value); - bool LoadFromJson(Json::Value & a_Value); + /// Returns how many items of the specified type would fit into the slot range specified + int HowManyCanFit(const cItem & a_ItemStack, int a_BeginSlotNum, int a_EndSlotNum, bool a_ConsiderEmptySlots); + + /** Adds as many items out of a_ItemStack as can fit. + If a_AllowNewStacks is set to false, only existing stacks can be topped up; + if a_AllowNewStacks is set to true, empty slots can be used for the rest. + Returns the number of items that fit. + */ + int AddItem(const cItem & a_ItemStack, bool a_AllowNewStacks = true); + + /** Same as AddItem, but works on an entire list of item stacks. + The a_ItemStackList is modified to reflect the leftover items. + If a_AllowNewStacks is set to false, only existing stacks can be topped up; + if a_AllowNewStacks is set to true, empty slots can be used for the rest + Returns the total number of items that fit. + */ + int AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks); + + /// Removes one item out of the currently equipped item stack, returns true if successful, false if empty-handed + bool RemoveOneEquippedItem(void); + + /// Returns the number of items of type a_Item that are stored + int HowManyItems(const cItem & a_Item); + + /// Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack + bool HasItems(const cItem & a_ItemStack); + + /// Returns the cItemGrid object representing the armor slots + cItemGrid & GetArmorGrid(void) { return m_ArmorSlots; } + + /// Returns the cItemGrid object representing the main inventory slots + cItemGrid & GetInventoryGrid(void) { return m_InventorySlots; } + + /// Returns the cItemGrid object representing the hotbar slots + cItemGrid & GetHotbarGrid(void) { return m_HotbarSlots; } + + /// Returns the player associated with this inventory + cPlayer & GetOwner(void) { return m_Owner; } + + /// Copies the non-empty slots into a_ItemStacks; preserves the original a_Items contents + void CopyToItems(cItems & a_Items); + + // tolua_end void SendWholeInventory(cClientHandle & a_Client); - const cItem * GetSlots(void) const { return m_Slots; } - + /// Returns the player associated with this inventory (const version) + const cPlayer & GetOwner(void) const { return m_Owner; } + // tolua_begin const cItem & GetSlot(int a_SlotNum) const; - const cItem & GetHotBarSlot(int a_HotBarSlotNum) const; + const cItem & GetArmorSlot(int a_ArmorSlotNum) const; + const cItem & GetInventorySlot(int a_InventorySlotNum) const; + const cItem & GetHotbarSlot(int a_HotBarSlotNum) const; const cItem & GetEquippedItem(void) const; void SetSlot(int a_SlotNum, const cItem & a_Item); - void SetHotBarSlot(int a_HotBarSlotNum, const cItem & a_Item); + void SetArmorSlot(int a_ArmorSlotNum, const cItem & a_Item); + void SetInventorySlot(int a_InventorySlotNum, const cItem & a_Item); + void SetHotbarSlot(int a_HotBarSlotNum, const cItem & a_Item); void SetEquippedSlotNum(int a_SlotNum); int GetEquippedSlotNum(void) { return m_EquippedSlotNum; } @@ -58,48 +130,41 @@ public: /// Adds the specified damage to the currently held item; deletes the item and returns true if the item broke. bool DamageEquippedItem(short a_Amount = 1); - const cItem & GetEquippedHelmet (void) const { return m_Slots[c_ArmorOffset]; } - const cItem & GetEquippedChestplate(void) const { return m_Slots[c_ArmorOffset + 1]; } - const cItem & GetEquippedLeggings (void) const { return m_Slots[c_ArmorOffset + 2]; } - const cItem & GetEquippedBoots (void) const { return m_Slots[c_ArmorOffset + 3]; } + const cItem & GetEquippedHelmet (void) const { return m_ArmorSlots.GetSlot(0); } + const cItem & GetEquippedChestplate(void) const { return m_ArmorSlots.GetSlot(1); } + const cItem & GetEquippedLeggings (void) const { return m_ArmorSlots.GetSlot(2); } + const cItem & GetEquippedBoots (void) const { return m_ArmorSlots.GetSlot(3); } - // tolua_end + /// Sends the slot contents to the owner + void SendSlot(int a_SlotNum); - void SendSlot( int a_SlotNum ); // tolua_export - - /// Returns how many items of the specified type would fit into the slot range specified - int HowManyCanFit(short a_ItemType, short a_ItemDamage, int a_BeginSlot, int a_EndSlot); + // tolua_end - /// Moves items, fitting them into the slot range specified, up to a_Count items. Returns the number of items moved - int MoveItem(short a_ItemType, short a_ItemDamage, int a_Count, int a_BeginSlot, int a_EndSlot); - - static const unsigned int c_NumSlots = 45; - static const unsigned int c_MainSlots = 27; - static const unsigned int c_HotSlots = 9; - static const unsigned int c_CraftSlots = 4; - static const unsigned int c_ArmorSlots = 4; + /// Converts an armor slot number into the ID for the EntityEquipment packet + static int ArmorSlotNumToEntityEquipmentID(short a_ArmorSlotNum); - static const unsigned int c_CraftOffset = 0; - static const unsigned int c_ArmorOffset = 5; - static const unsigned int c_MainOffset = 9; - static const unsigned int c_HotOffset = 36; - - /// Converts a slot number into the ID for the EntityEquipment packet - static int SlotNumToEntityEquipmentID(short a_SlotNum); + void SaveToJson(Json::Value & a_Value); + bool LoadFromJson(Json::Value & a_Value); protected: bool AddToBar( cItem & a_Item, const int a_Offset, const int a_Size, bool* a_bChangedSlots, int a_Mode = 0 ); - - cItem m_Slots[c_NumSlots]; - cItem * m_MainSlots; - cItem * m_CraftSlots; - cItem * m_ArmorSlots; - cItem * m_HotSlots; + cItemGrid m_ArmorSlots; + cItemGrid m_InventorySlots; + cItemGrid m_HotbarSlots; int m_EquippedSlotNum; cPlayer & m_Owner; + + /// Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum + const cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) const; + + /// Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum + cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum); + + // cItemGrid::cListener override: + virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override; }; // tolua_export diff --git a/source/Item.cpp b/source/Item.cpp index a2e4a9f24..e2cacdac1 100644 --- a/source/Item.cpp +++ b/source/Item.cpp @@ -75,7 +75,7 @@ bool cItem::DamageItem(short a_Amount) -bool cItem::IsStackableWith(const cItem & a_OtherStack) +bool cItem::IsStackableWith(const cItem & a_OtherStack) const { if (a_OtherStack.m_ItemType != m_ItemType) { diff --git a/source/Item.h b/source/Item.h index 15109ab15..9e37ce3bc 100644 --- a/source/Item.h +++ b/source/Item.h @@ -74,7 +74,7 @@ public: inline bool IsDamageable(void) const { return (GetMaxDamage() > 0); } /// Returns true if this itemstack can stack with the specified stack (types match, enchantments etc.) ItemCounts are ignored! - bool IsStackableWith(const cItem & a_OtherStack); + bool IsStackableWith(const cItem & a_OtherStack) const; // tolua_end void GetJson( Json::Value & a_OutValue ) const; diff --git a/source/ItemGrid.cpp b/source/ItemGrid.cpp index e9521d832..aa8ed92c8 100644 --- a/source/ItemGrid.cpp +++ b/source/ItemGrid.cpp @@ -16,7 +16,8 @@ cItemGrid::cItemGrid(int a_Width, int a_Height) : m_Width(a_Width), m_Height(a_Height), m_NumSlots(a_Width * a_Height), - m_Slots(new cItem[a_Width * a_Height]) + m_Slots(new cItem[a_Width * a_Height]), + m_IsInTriggerListeners(false) { } @@ -149,6 +150,7 @@ void cItemGrid::SetSlot(int a_SlotNum, const cItem & a_Item) return; } m_Slots[a_SlotNum] = a_Item; + TriggerListeners(a_SlotNum); } @@ -164,11 +166,46 @@ void cItemGrid::SetSlot(int a_SlotNum, short a_ItemType, char a_ItemCount, short +void cItemGrid::EmptySlot(int a_X, int a_Y) +{ + EmptySlot(GetSlotNum(a_X, a_Y)); +} + + + + + +void cItemGrid::EmptySlot(int a_SlotNum) +{ + if ((a_SlotNum < 0) || (a_SlotNum >= m_NumSlots)) + { + LOGWARNING("%s: Invalid slot number %d out of %d slots", + __FUNCTION__, a_SlotNum, m_NumSlots + ); + return; + } + + // Check if already empty: + if (m_Slots[a_SlotNum].IsEmpty()) + { + return; + } + + // Empty and notify + m_Slots[a_SlotNum].Empty(); + TriggerListeners(a_SlotNum); +} + + + + + void cItemGrid::Clear(void) { for (int i = 0; i < m_NumSlots; i++) { m_Slots[i].Empty(); + TriggerListeners(i); } } @@ -203,10 +240,33 @@ int cItemGrid::HowManyCanFit(const cItem & a_ItemStack) -bool cItemGrid::AddItem(cItem & a_ItemStack) +int cItemGrid::AddItem(cItem & a_ItemStack, bool a_AllowNewStacks) { int NumLeft = a_ItemStack.m_ItemCount; int MaxStack = ItemHandler(a_ItemStack.m_ItemType)->GetMaxStackSize(); + + // Scan existing stacks: + for (int i = m_NumSlots - 1; i >= 0; i--) + { + if (m_Slots[i].IsStackableWith(a_ItemStack)) + { + int PrevCount = m_Slots[i].m_ItemCount; + m_Slots[i].m_ItemCount = std::min(MaxStack, PrevCount + NumLeft); + NumLeft -= m_Slots[i].m_ItemCount - PrevCount; + TriggerListeners(i); + } + if (NumLeft <= 0) + { + // All items fit + return a_ItemStack.m_ItemCount; + } + } // for i - m_Slots[] + + if (!a_AllowNewStacks) + { + return (a_ItemStack.m_ItemCount - NumLeft); + } + for (int i = m_NumSlots - 1; i >= 0; i--) { if (m_Slots[i].IsEmpty()) @@ -214,40 +274,87 @@ bool cItemGrid::AddItem(cItem & a_ItemStack) m_Slots[i] = a_ItemStack; m_Slots[i].m_ItemCount = std::min(MaxStack, NumLeft); NumLeft -= m_Slots[i].m_ItemCount; - } - else if (m_Slots[i].IsStackableWith(a_ItemStack)) - { - int PrevCount = m_Slots[i].m_ItemCount; - m_Slots[i].m_ItemCount = std::min(MaxStack, PrevCount + NumLeft); - NumLeft -= m_Slots[i].m_ItemCount - PrevCount; + TriggerListeners(i); } if (NumLeft <= 0) { // All items fit - return true; + return a_ItemStack.m_ItemCount; } } // for i - m_Slots[] - return (a_ItemStack.m_ItemCount > NumLeft); + return (a_ItemStack.m_ItemCount - NumLeft); } -bool cItemGrid::AddItems(cItems & a_ItemStackList) +int cItemGrid::AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks) { - bool res; + int TotalAdded = 0; for (cItems::iterator itr = a_ItemStackList.begin(); itr != a_ItemStackList.end();) { - res = AddItem(*itr) | res; - if (itr->IsEmpty()) + int NumAdded = AddItem(*itr, a_AllowNewStacks); + if (itr->m_ItemCount == NumAdded) { itr = a_ItemStackList.erase(itr); } else { + itr->m_ItemCount -= NumAdded; ++itr; } + TotalAdded += NumAdded; + } + return TotalAdded; +} + + + + + +int cItemGrid::ChangeSlotCount(int a_SlotNum, int a_AddToCount) +{ + if ((a_SlotNum < 0) || (a_SlotNum >= m_NumSlots)) + { + LOGWARNING("%s: Invalid slot number %d out of %d slots, ignoring the call, returning empty item", + __FUNCTION__, a_SlotNum, m_NumSlots + ); + return 0; + } + + if (m_Slots[a_SlotNum].IsEmpty()) + { + // The item is empty, it's not gonna change + return 0; + } + + if (m_Slots[a_SlotNum].m_ItemCount < -a_AddToCount) + { + // Trying to remove more items than there already are, make the item empty + m_Slots[a_SlotNum].Empty(); + TriggerListeners(a_SlotNum); + return 0; + } + + m_Slots[a_SlotNum].m_ItemCount += a_AddToCount; + TriggerListeners(a_SlotNum); + return m_Slots[a_SlotNum].m_ItemCount; +} + + + + + +int cItemGrid::HowManyItems(const cItem & a_Item) +{ + int res = 0; + for (int i = 0; i < m_NumSlots; i++) + { + if (m_Slots[i].IsStackableWith(a_Item)) + { + res += m_Slots[i].m_ItemCount; + } } return res; } @@ -256,6 +363,16 @@ bool cItemGrid::AddItems(cItems & a_ItemStackList) +bool cItemGrid::HasItems(const cItem & a_ItemStack) +{ + int CurrentlyHave = HowManyItems(a_ItemStack); + return (CurrentlyHave >= a_ItemStack.m_ItemCount); +} + + + + + int cItemGrid::GetFirstEmptySlot(void) const { return GetNextEmptySlot(-1); @@ -312,6 +429,20 @@ void cItemGrid::CopyToItems(cItems & a_Items) const +bool cItemGrid::DamageItem(int a_SlotNum, short a_Amount) +{ + if ((a_SlotNum < 0) || (a_SlotNum >= m_NumSlots)) + { + LOGWARNING("%s: invalid slot number %d out of %d slots, ignoring.", __FUNCTION__, a_SlotNum, m_NumSlots); + return false; + } + return m_Slots[a_SlotNum].DamageItem(a_Amount); +} + + + + + void cItemGrid::GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, int a_CountLootProbabs, int a_NumSlots, int a_Seed) { // Calculate the total weight: @@ -347,3 +478,47 @@ void cItemGrid::GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, i + +void cItemGrid::AddListener(cListener & a_Listener) +{ + cCSLock Lock(m_CSListeners); + ASSERT(!m_IsInTriggerListeners); // Must not call this while in TriggerListeners() + m_Listeners.push_back(&a_Listener); +} + + + + + +void cItemGrid::RemoveListener(cListener & a_Listener) +{ + cCSLock Lock(m_CSListeners); + ASSERT(!m_IsInTriggerListeners); // Must not call this while in TriggerListeners() + for (cListeners::iterator itr = m_Listeners.begin(), end = m_Listeners.end(); itr != end; ++itr) + { + if (*itr == &a_Listener) + { + m_Listeners.erase(itr); + return; + } + } // for itr - m_Listeners[] +} + + + + + +void cItemGrid::TriggerListeners(int a_SlotNum) +{ + cCSLock Lock(m_CSListeners); + m_IsInTriggerListeners = true; + for (cListeners::iterator itr = m_Listeners.begin(), end = m_Listeners.end(); itr != end; ++itr) + { + (*itr)->OnSlotChanged(this, a_SlotNum); + } // for itr - m_Listeners[] + m_IsInTriggerListeners = false; +} + + + + diff --git a/source/ItemGrid.h b/source/ItemGrid.h index ed4d5e58d..7a2a828b1 100644 --- a/source/ItemGrid.h +++ b/source/ItemGrid.h @@ -19,6 +19,16 @@ class cItemGrid { public: // tolua_end + + /// This class is used as a callback for when a slot changes + class cListener + { + public: + /// Called whenever a slot changes + virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) = 0; + } ; + typedef std::vector cListeners; + cItemGrid(int a_Width, int a_Height); ~cItemGrid(); @@ -48,17 +58,42 @@ public: void SetSlot(int a_SlotNum, const cItem & a_Item); void SetSlot(int a_SlotNum, short a_ItemType, char a_ItemCount, short a_ItemDamage); + // Empty the specified slot; Logs warning and doesn't set on invalid coords / slotnum + void EmptySlot(int a_X, int a_Y); + void EmptySlot(int a_SlotNum); + /// Sets all items as empty void Clear(void); /// Returns number of items out of a_ItemStack that can fit in the storage int HowManyCanFit(const cItem & a_ItemStack); - /// Adds as many items out of a_ItemStack as can fit; the rest is left in a_ItemStack; returns true if any items fit. - bool AddItem(cItem & a_ItemStack); + /** Adds as many items out of a_ItemStack as can fit. + If a_AllowNewStacks is set to false, only existing stacks can be topped up; + if a_AllowNewStacks is set to true, empty slots can be used for the rest + Returns the number of items that fit. + */ + int AddItem(cItem & a_ItemStack, bool a_AllowNewStacks); + + /** Same as AddItem, but works on an entire list of item stacks. + The a_ItemStackList is modified to reflect the leftover items. + If a_AllowNewStacks is set to false, only existing stacks can be topped up; + if a_AllowNewStacks is set to true, empty slots can be used for the rest + Returns the total number of items that fit. + */ + int AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks); + + /** Adds (or subtracts, if a_AddToCount is negative) to the count of items in the specified slot. + If the slot is empty, ignores the call. + Returns the new count. + */ + int ChangeSlotCount(int a_SlotNum, int a_AddToCount); - /// Same as AddItem, but works on an entire list of item stacks - bool AddItems(cItems & a_ItemStackList); + /// Returns the number of items of type a_Item that are stored + int HowManyItems(const cItem & a_Item); + + /// Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack + bool HasItems(const cItem & a_ItemStack); /// Returns the index of the first empty slot; -1 if all full int GetFirstEmptySlot(void) const; @@ -69,16 +104,26 @@ public: /// Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked) int GetNextEmptySlot(int a_StartFrom) const; - /// Copies the contents into a cItems object + /// Copies the contents into a cItems object; preserves the original a_Items contents void CopyToItems(cItems & a_Items) const; + /// Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) + bool DamageItem(int a_SlotNum, short a_Amount); + // tolua_end + /** Generates random loot from the specified loot probability table, with a chance of enchanted books added. A total of a_NumSlots are taken by the loot. - Cannot export to Lua due to raw array a_LootProbabs. + Cannot export to Lua due to raw array a_LootProbabs. TODO: Make this exportable / export through ManualBindings.cpp with a Lua table as LootProbabs */ void GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, int a_CountLootProbabs, int a_NumSlots, int a_Seed); + + /// Adds a callback that gets called whenever a slot changes. Must not be called from within the listener callback! + void AddListener(cListener & a_Listener); + + /// Removes a slot-change-callback. Must not be called from within the listener callback! + void RemoveListener(cListener & a_Listener); // tolua_begin @@ -86,7 +131,14 @@ protected: int m_Width; int m_Height; int m_NumSlots; // m_Width * m_Height, for easier validity checking in the access functions - cItem * m_Slots; // x + m_Width * y + cItem * m_Slots; // x + m_Width * y + + cListeners m_Listeners; ///< Listeners which should be notified on slot changes; the pointers are not owned by this object + cCriticalSection m_CSListeners; ///< CS that guards the m_Listeners against multi-thread access + bool m_IsInTriggerListeners; ///< Set to true while TriggerListeners is running, to detect attempts to manipulate listener list while triggerring + + /// Calls all m_Listeners for the specified slot number + void TriggerListeners(int a_SlotNum); } ; // tolua_end diff --git a/source/Items/ItemBucket.h b/source/Items/ItemBucket.h index 098742724..4792fa62d 100644 --- a/source/Items/ItemBucket.h +++ b/source/Items/ItemBucket.h @@ -81,8 +81,7 @@ public: } // Remove the bucket from the inventory - cItem Item(a_Item.m_ItemType, 1); - if (!a_Player->GetInventory().RemoveItem(Item)) + if (!a_Player->GetInventory().RemoveOneEquippedItem()) { LOG("Clicked with an empty bucket, but cannot remove one from the inventory? WTF?"); ASSERT(!"Inventory bucket mismatch"); @@ -90,8 +89,7 @@ public: } // Give new bucket, filled with fluid: - Item.m_ItemType = NewItem; - Item.m_ItemCount = 1; + cItem Item(NewItem, 1); a_Player->GetInventory().AddItem(Item); // Remove water / lava block @@ -131,15 +129,13 @@ public: if (a_Player->GetGameMode() != gmCreative) { // Remove fluid bucket, add empty bucket: - cItem Item(a_Item.m_ItemType, 1); - if (!a_Player->GetInventory().RemoveItem(Item)) + if (!a_Player->GetInventory().RemoveOneEquippedItem()) { LOG("Clicked with a full bucket, but cannot remove one from the inventory? WTF?"); ASSERT(!"Inventory bucket mismatch"); return false; } - Item.m_ItemType = E_ITEM_BUCKET; - Item.m_ItemCount = 1; + cItem Item(E_ITEM_BUCKET, 1); if (!a_Player->GetInventory().AddItem(Item)) { return false; diff --git a/source/Items/ItemDye.h b/source/Items/ItemDye.h index ab9ff3f60..e4c31fa4b 100644 --- a/source/Items/ItemDye.h +++ b/source/Items/ItemDye.h @@ -22,15 +22,15 @@ public: virtual bool OnItemUse(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) override { // TODO: Handle coloring the sheep, too (OnItemUseOnEntity maybe) + // Handle growing the plants: if (a_Item.m_ItemDamage == E_META_DYE_WHITE) { if (a_World->GrowRipePlant(a_BlockX, a_BlockY, a_BlockZ, true)) { - if (a_Player->GetGameMode() != eGameMode_Creative) + if (a_Player->GetGameMode() != gmCreative) { - cItem Item(a_Item.m_ItemType, 1, a_Item.m_ItemDamage); - a_Player->GetInventory().RemoveItem(Item); + a_Player->GetInventory().RemoveOneEquippedItem(); return true; } } diff --git a/source/Items/ItemSlab.h b/source/Items/ItemSlab.h index 9f4760053..9b3aaed03 100644 --- a/source/Items/ItemSlab.h +++ b/source/Items/ItemSlab.h @@ -36,8 +36,7 @@ public: } else { - cItem Item(a_Item.m_ItemType, 1); - if (a_Player->GetInventory().RemoveItem(Item)) + if (a_Player->GetInventory().RemoveOneEquippedItem()) { a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, Block - 1, Meta); // Block - 1 simple hack to save one if statement return true; diff --git a/source/Items/ItemSpawnEgg.h b/source/Items/ItemSpawnEgg.h index c6fa363bb..7f5b253ef 100644 --- a/source/Items/ItemSpawnEgg.h +++ b/source/Items/ItemSpawnEgg.h @@ -38,8 +38,7 @@ public: if (a_Player->GetGameMode() != 1) { // The mob was spawned, "use" the item: - cItem Equipped(a_Player->GetEquippedItem()); - a_Player->GetInventory().RemoveItem(Equipped); + a_Player->GetInventory().RemoveOneEquippedItem(); } return true; } diff --git a/source/JukeboxEntity.cpp b/source/JukeboxEntity.cpp index 00f4bd533..249e86df2 100644 --- a/source/JukeboxEntity.cpp +++ b/source/JukeboxEntity.cpp @@ -40,8 +40,7 @@ void cJukeboxEntity::UsedBy(cPlayer * a_Player) if (HeldItem.m_ItemType >= 2256 && HeldItem.m_ItemType <= 2267) { m_Record = HeldItem.m_ItemType; - cItem Equipped(a_Player->GetInventory().GetEquippedItem()); - a_Player->GetInventory().RemoveItem(Equipped); + a_Player->GetInventory().RemoveOneEquippedItem(); PlayRecord(); } } diff --git a/source/Pickup.cpp b/source/Pickup.cpp index bf48daf82..19959efa3 100644 --- a/source/Pickup.cpp +++ b/source/Pickup.cpp @@ -149,17 +149,17 @@ bool cPickup::CollectedBy(cPlayer * a_Dest) return false; } - if (a_Dest->GetInventory().AddItemAnyAmount(m_Item)) + int NumAdded = a_Dest->GetInventory().AddItem(m_Item); + if (NumAdded > 0) { + m_Item.m_ItemCount -= NumAdded; m_World->BroadcastCollectPickup(*this, *a_Dest); - m_bCollected = true; - m_Timer = 0; - if (m_Item.m_ItemCount != 0) + if (m_Item.m_ItemCount == 0) { - cItems Pickup; - Pickup.push_back(cItem(m_Item)); - m_World->SpawnItemPickups(Pickup, GetPosX(), GetPosY(), GetPosZ()); + // All of the pickup has been collected, schedule the pickup for destroying + m_bCollected = true; } + m_Timer = 0; return true; } diff --git a/source/Player.cpp b/source/Player.cpp index 0076b2cff..031b7a6c9 100644 --- a/source/Player.cpp +++ b/source/Player.cpp @@ -360,25 +360,18 @@ void cPlayer::KilledBy(cPawn * a_Killer) m_bVisible = false; // So new clients don't see the player // Puke out all the items - const cItem * Items = m_Inventory.GetSlots(); cItems Pickups; - for (unsigned int i = 1; i < m_Inventory.c_NumSlots; ++i) - { - if (!Items[i].IsEmpty()) - { - Pickups.push_back(Items[i]); - } - } + m_Inventory.CopyToItems(Pickups); m_Inventory.Clear(); m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10); - SaveToDisk(); // Save it, yeah the world is a tough place ! + SaveToDisk(); // Save it, yeah the world is a tough place ! } -void cPlayer::Respawn() +void cPlayer::Respawn(void) { m_Health = GetMaxHealth(); @@ -768,7 +761,7 @@ void cPlayer::TossItem( ) { cItems Drops; - if (a_CreateType) + if (a_CreateType != 0) { // Just create item without touching the inventory (used in creative mode) Drops.push_back(cItem(a_CreateType, a_Amount, a_CreateHealth)); @@ -800,8 +793,7 @@ void cPlayer::TossItem( cItem DroppedItem(GetInventory().GetEquippedItem()); if (!DroppedItem.IsEmpty()) { - DroppedItem.m_ItemCount = 1; - if (GetInventory().RemoveItem(DroppedItem)) + if (GetInventory().RemoveOneEquippedItem()) { DroppedItem.m_ItemCount = 1; // RemoveItem decreases the count, so set it to 1 again Drops.push_back(DroppedItem); diff --git a/source/Player.h b/source/Player.h index c8425a128..378c5d782 100644 --- a/source/Player.h +++ b/source/Player.h @@ -81,10 +81,12 @@ public: void LoginSetGameMode( eGameMode a_GameMode ); void SetIP(const AString & a_IP); - // Tries to move to a new position, with collision checks and stuff + /// Tries to move to a new position, with collision checks and stuff virtual void MoveTo( const Vector3d & a_NewPos ); // tolua_export - cWindow* GetWindow() { return m_CurrentWindow; } + cWindow * GetWindow(void) { return m_CurrentWindow; } + const cWindow * GetWindow(void) const { return m_CurrentWindow; } + void OpenWindow( cWindow* a_Window ); void CloseWindow(char a_WindowType); diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp index 17def7c8a..a4b5feb82 100644 --- a/source/Protocol/Protocol125.cpp +++ b/source/Protocol/Protocol125.cpp @@ -874,8 +874,7 @@ void cProtocol125::SendWeather(eWeather a_Weather) void cProtocol125::SendWholeInventory(const cInventory & a_Inventory) { - cCSLock Lock(m_CSPacket); - SendWindowSlots(0, a_Inventory.c_NumSlots, a_Inventory.GetSlots()); + SendWholeInventory(*(a_Inventory.GetOwner().GetWindow())); } diff --git a/source/Protocol/Protocol132.cpp b/source/Protocol/Protocol132.cpp index c10338f54..50c335180 100644 --- a/source/Protocol/Protocol132.cpp +++ b/source/Protocol/Protocol132.cpp @@ -438,14 +438,24 @@ void cProtocol132::SendWholeInventory(const cWindow & a_Window) { // 1.3.2 requires player inventory slots to be sent as SetSlot packets, // otherwise it sometimes fails to update the window + + // Send the entire window: super::SendWholeInventory(a_Window); - const cItem * Slots = m_Client->GetPlayer()->GetInventory().GetSlots(); - int BaseOffset = a_Window.GetNumSlots() - cInventory::c_NumSlots + cInventory::c_MainOffset; // the number of non-inventory slots the window has; inventory follows + + // Send the player inventory and hotbar: + const cInventory & Inventory = m_Client->GetPlayer()->GetInventory(); + int BaseOffset = a_Window.GetNumSlots() - (cInventory::invNumSlots - cInventory::invInventoryOffset); // Number of non-inventory slots char WindowID = a_Window.GetWindowID(); - for (int i = 0; i < cInventory::c_NumSlots - cInventory::c_MainOffset; i++) + for (int i = 0; i < cInventory::invInventoryCount; i++) { - SendInventorySlot(WindowID, BaseOffset + i, Slots[i + cInventory::c_MainOffset]); - } // for i - Slots[] + SendInventorySlot(WindowID, BaseOffset + i, Inventory.GetInventorySlot(i)); + } // for i - Inventory[] + BaseOffset += cInventory::invInventoryCount; + for (int i = 0; i < cInventory::invHotbarCount; i++) + { + SendInventorySlot(WindowID, BaseOffset + i, Inventory.GetHotbarSlot(i)); + } // for i - Hotbar[] + // Send even the item being dragged: SendInventorySlot(-1, -1, m_Client->GetPlayer()->GetDraggingItem()); } diff --git a/source/UI/SlotArea.cpp b/source/UI/SlotArea.cpp index 7c7b8cd4a..07b191292 100644 --- a/source/UI/SlotArea.cpp +++ b/source/UI/SlotArea.cpp @@ -613,7 +613,7 @@ void cSlotAreaInventoryBase::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAc const cItem * cSlotAreaInventoryBase::GetSlot(int a_SlotNum, cPlayer & a_Player) { - // a_SlotNum ranges from 0 to 35, map that to the player's inventory slots 9 to 44 + // a_SlotNum ranges from 0 to 35, map that to the player's inventory slots according to the internal offset return &a_Player.GetInventory().GetSlot(a_SlotNum + m_SlotOffset); } diff --git a/source/UI/SlotArea.h b/source/UI/SlotArea.h index 2738e08e9..2b56f3228 100644 --- a/source/UI/SlotArea.h +++ b/source/UI/SlotArea.h @@ -8,7 +8,7 @@ #pragma once -#include "../Item.h" +#include "../Inventory.h" @@ -97,7 +97,7 @@ class cSlotAreaInventory : public: cSlotAreaInventory(cWindow & a_ParentWindow) : - cSlotAreaInventoryBase(27, 9, a_ParentWindow) // 27 slots, starting at inventory index 9 + cSlotAreaInventoryBase(cInventory::invInventoryCount, cInventory::invInventoryOffset, a_ParentWindow) { } } ; @@ -114,7 +114,7 @@ class cSlotAreaHotBar : public: cSlotAreaHotBar(cWindow & a_ParentWindow) : - cSlotAreaInventoryBase(9, 36, a_ParentWindow) + cSlotAreaInventoryBase(cInventory::invHotbarCount, cInventory::invHotbarOffset, a_ParentWindow) { } } ; @@ -129,7 +129,7 @@ class cSlotAreaArmor : { public: cSlotAreaArmor(cWindow & a_ParentWindow) : - cSlotAreaInventoryBase(4, 5, a_ParentWindow) + cSlotAreaInventoryBase(cInventory::invArmorCount, cInventory::invArmorOffset, a_ParentWindow) { } -- cgit v1.2.3