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,"cEntity"); - tolua_usertype(tolua_S,"cIniFile"); + 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,"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,6 +12587,77 @@ static int tolua_AllToLua_cInventory_Clear00(lua_State* tolua_S) } #endif //#ifndef TOLUA_DISABLE +/* 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,"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); + 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 'HowManyCanFit'", NULL); +#endif + { + 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 'HowManyCanFit'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* method: HowManyCanFit of class cInventory */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cInventory_HowManyCanFit01 +static int tolua_AllToLua_cInventory_HowManyCanFit01(lua_State* tolua_S) +{ + 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,"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 + { + cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,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 'HowManyCanFit'", NULL); +#endif + { + int tolua_ret = (int) self->HowManyCanFit(*a_ItemStack,a_BeginSlotNum,a_EndSlotNum,a_ConsiderEmptySlots); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); + } + } + return 1; +tolua_lerror: + return tolua_AllToLua_cInventory_HowManyCanFit00(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) @@ -12693,21 +12666,23 @@ static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S) 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 'AddItem'", NULL); #endif { - bool tolua_ret = (bool) self->AddItem(*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; @@ -12719,49 +12694,83 @@ static int tolua_AllToLua_cInventory_AddItem00(lua_State* tolua_S) } #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: 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,"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,"cItems",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)); + 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 'AddItemAnyAmount'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'AddItems'", NULL); #endif { - bool tolua_ret = (bool) self->AddItemAnyAmount(*a_Item); - 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; #ifndef TOLUA_RELEASE tolua_lerror: - tolua_error(tolua_S,"#ferror in function 'AddItemAnyAmount'.",&tolua_err); + tolua_error(tolua_S,"#ferror in function 'AddItems'.",&tolua_err); return 0; #endif } #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: 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,"cInventory",0,&tolua_err) || - (tolua_isvaluenil(tolua_S,2,&tolua_err) || !tolua_isusertype(tolua_S,2,"cItem",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 'RemoveOneEquippedItem'", NULL); +#endif + { + 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 'RemoveOneEquippedItem'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + +/* 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,"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; @@ -12769,19 +12778,214 @@ static int tolua_AllToLua_cInventory_RemoveItem00(lua_State* tolua_S) #endif { cInventory* self = (cInventory*) tolua_tousertype(tolua_S,1,0); - cItem* a_Item = ((cItem*) tolua_tousertype(tolua_S,2,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 'RemoveItem'", NULL); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'HowManyItems'", NULL); #endif { - bool tolua_ret = (bool) self->RemoveItem(*a_Item); + 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 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_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 'RemoveItem'.",&tolua_err); + 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 } @@ -12821,9 +13025,77 @@ static int tolua_AllToLua_cInventory_GetSlot00(lua_State* tolua_S) } #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: 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; @@ -12839,17 +13111,17 @@ static int tolua_AllToLua_cInventory_GetHotBarSlot00(lua_State* tolua_S) 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); + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetHotbarSlot'", NULL); #endif { - const cItem& tolua_ret = (const cItem&) self->GetHotBarSlot(a_HotBarSlotNum); + 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); + tolua_error(tolua_S,"#ferror in function 'GetHotbarSlot'.",&tolua_err); return 0; #endif } @@ -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,82 +35,130 @@ 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; + } + 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; +} + + + + + +int cInventory::AddItem(const cItem & a_Item, bool a_AllowNewStacks) +{ + cItem ToAdd(a_Item); + int res = 0; + if (ItemCategory::IsArmor(a_Item.m_ItemType)) + { + res = m_ArmorSlots.AddItem(ToAdd, a_AllowNewStacks); + ToAdd.m_ItemCount -= res; + if (ToAdd.m_ItemCount == 0) + { + return res; } } - return (a_Item.m_ItemCount == 0); -} - - - - - -bool cInventory::AddItemAnyAmount( cItem & a_Item ) -{ - 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 ); + res += m_HotbarSlots.AddItem(ToAdd, a_AllowNewStacks); + ToAdd.m_ItemCount = a_Item.m_ItemCount - res; + if (ToAdd.m_ItemCount == 0) + { + return res; + } - if (a_Item.m_ItemCount == StartCount) - return false; + res += m_InventorySlots.AddItem(ToAdd, a_AllowNewStacks); + return res; +} - for (unsigned int i = 0; i < c_NumSlots; i++) + + + + +int cInventory::AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks) +{ + int TotalAdded = 0; + for (cItems::iterator itr = a_ItemStackList.begin(); itr != a_ItemStackList.end();) { - if (ChangedSlots[i]) + int NumAdded = AddItem(*itr, a_AllowNewStacks); + if (itr->m_ItemCount == NumAdded) { - 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); + itr = a_ItemStackList.erase(itr); } + else + { + itr->m_ItemCount -= NumAdded; + ++itr; + } + TotalAdded += NumAdded; } + return TotalAdded; +} + + + + +bool cInventory::RemoveOneEquippedItem(void) +{ + if (m_HotbarSlots.GetSlot(m_EquippedSlotNum).IsEmpty()) + { + return false; + } + + m_HotbarSlots.ChangeSlotCount(m_EquippedSlotNum, -1); return true; } @@ -115,68 +166,22 @@ bool cInventory::AddItemAnyAmount( cItem & a_Item ) -// 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::HowManyItems(const cItem & a_Item) { - // First check equipped slot - if ((m_EquippedSlotNum >= 0) && (m_EquippedSlotNum < 9)) - { - if (m_HotSlots[m_EquippedSlotNum].m_ItemType == a_Item.m_ItemType) - { - 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); - } - } - } - - // Then check other slotz - if (a_Item.m_ItemCount > 0) - { - for (int i = 0; i < c_MainSlots; i++) - { - 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); - } - } - } - } - - return (a_Item.m_ItemCount == 0); + return + m_ArmorSlots.HowManyItems(a_Item) + + m_InventorySlots.HowManyItems(a_Item) + + m_HotbarSlots.HowManyItems(a_Item); } -void cInventory::Clear() +bool cInventory::HasItems(const cItem & a_ItemStack) { - for (unsigned int i = 0; i < ARRAYCOUNT(m_Slots); i++) - { - m_Slots[i].Empty(); - } - // TODO: Broadcast / send the changes to wherever needed + 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::SetHotBarSlot(int a_HotBarSlotNum, const cItem & a_Item) +void cInventory::SetArmorSlot(int a_ArmorSlotNum, const cItem & a_Item) { - SetSlot(a_HotBarSlotNum + c_HotSlots, a_Item); + m_ArmorSlots.SetSlot(a_ArmorSlotNum, a_Item); +} + + + + + +void cInventory::SetInventorySlot(int a_InventorySlotNum, const cItem & 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::GetHotBarSlot(int a_SlotNum) const +const cItem & cInventory::GetArmorSlot(int a_ArmorSlotNum) const { - if ((a_SlotNum < 0) || (a_SlotNum >= 9)) + if ((a_ArmorSlotNum < 0) || (a_ArmorSlotNum >= invArmorCount)) { - 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_ArmorSlotNum, invArmorCount - 1); + return m_ArmorSlots.GetSlot(0); } - return m_HotSlots[a_SlotNum]; + return m_ArmorSlots.GetSlot(a_ArmorSlotNum); +} + + + + + +const cItem & cInventory::GetInventorySlot(int a_InventorySlotNum) const +{ + if ((a_InventorySlotNum < 0) || (a_InventorySlotNum >= invInventoryCount)) + { + 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_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: + + // 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 + } ; + + // tolua_end + cInventory(cPlayer & a_Owner); - ~cInventory(); + + // tolua_begin - void Clear(); // tolua_export + /// Removes all items from the entire inventory + void Clear(void); - // cItem * GetSlotsForType( int a_Type ); - // int GetSlotCountForType( int a_Type ); + /// Returns number of items out of a_ItemStack that can fit in the storage + int HowManyCanFit(const cItem & a_ItemStack, bool a_ConsiderEmptySlots); - bool AddItem( cItem & a_Item ); // tolua_export - bool AddItemAnyAmount( cItem & a_Item ); // tolua_export - bool RemoveItem( cItem & a_Item ); // tolua_export + /// 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); - void SaveToJson(Json::Value & a_Value); - bool LoadFromJson(Json::Value & a_Value); + /** 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); } + + /// Sends the slot contents to the owner + void SendSlot(int a_SlotNum); // tolua_end - - 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); - - /// 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); + /// Converts an armor slot number into the ID for the EntityEquipment packet + static int ArmorSlotNumToEntityEquipmentID(short a_ArmorSlotNum); - 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; - - 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 - bool AddItems(cItems & a_ItemStackList); + /** 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); + + /// 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) { }