From 90c398a3926f097e51955817e2829d831ae2bd2b Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 19 May 2013 18:22:37 +0000 Subject: Inventory code cleanup, players can now see each other's armor git-svn-id: http://mc-server.googlecode.com/svn/trunk@1493 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Inventory.cpp | 209 +++++++++++++++++++++++++++++---------------------- 1 file changed, 118 insertions(+), 91 deletions(-) (limited to 'source/Inventory.cpp') diff --git a/source/Inventory.cpp b/source/Inventory.cpp index b6de2d821..7cfe69be8 100644 --- a/source/Inventory.cpp +++ b/source/Inventory.cpp @@ -7,6 +7,7 @@ #include "UI/Window.h" #include "Item.h" #include "Root.h" +#include "World.h" #include @@ -16,6 +17,21 @@ +cInventory::cInventory(cPlayer & a_Owner) : + 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; + + SetEquippedSlotNum(0); +} + + + + + cInventory::~cInventory() { /* @@ -33,26 +49,6 @@ cInventory::~cInventory() -cInventory::cInventory(cPlayer & a_Owner) : - m_Owner(a_Owner) -{ - for (unsigned int i = 0; i < c_NumSlots; i++) - { - m_Slots[i].Empty(); - } - - m_CraftSlots = m_Slots + c_CraftOffset; - m_ArmorSlots = m_Slots + c_ArmorOffset; - m_MainSlots = m_Slots + c_MainOffset; - m_HotSlots = m_Slots + c_HotOffset; - - SetEquippedSlot(0); -} - - - - - bool cInventory::AddItem( cItem & a_Item ) { cItem BackupSlots[c_NumSlots]; @@ -120,25 +116,25 @@ 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 ) +bool cInventory::RemoveItem(cItem & a_Item) { // First check equipped slot - if ((m_EquippedSlot >= 0) && (m_EquippedSlot < 9)) + if ((m_EquippedSlotNum >= 0) && (m_EquippedSlotNum < 9)) { - if (m_HotSlots[m_EquippedSlot].m_ItemType == a_Item.m_ItemType) + if (m_HotSlots[m_EquippedSlotNum].m_ItemType == a_Item.m_ItemType) { - cItem & Item = m_HotSlots[m_EquippedSlot]; - if(Item.m_ItemCount > a_Item.m_ItemCount) + cItem & Item = m_HotSlots[m_EquippedSlotNum]; + if (Item.m_ItemCount > a_Item.m_ItemCount) { Item.m_ItemCount -= a_Item.m_ItemCount; - SendSlot( m_EquippedSlot + c_HotOffset ); + SendSlot(m_EquippedSlotNum + c_HotOffset); return true; } - else if(Item.m_ItemCount > 0 ) + else if (Item.m_ItemCount > 0) { a_Item.m_ItemCount -= Item.m_ItemCount; Item.Empty(); - SendSlot( m_EquippedSlot + c_HotOffset ); + SendSlot(m_EquippedSlotNum + c_HotOffset); } } } @@ -146,22 +142,22 @@ bool cInventory::RemoveItem( cItem & a_Item ) // Then check other slotz if (a_Item.m_ItemCount > 0) { - for(int i = 0; i < 36; i++) + for (int i = 0; i < c_MainSlots; i++) { cItem & Item = m_MainSlots[i]; - if( Item.m_ItemType == a_Item.m_ItemType ) + if (Item.m_ItemType == a_Item.m_ItemType) { - if(Item.m_ItemCount > a_Item.m_ItemCount) + if (Item.m_ItemCount > a_Item.m_ItemCount) { Item.m_ItemCount -= a_Item.m_ItemCount; - SendSlot( i + c_MainOffset ); + SendSlot(i + c_MainOffset); return true; } - else if(Item.m_ItemCount > 0 ) + else if (Item.m_ItemCount > 0) { a_Item.m_ItemCount -= Item.m_ItemCount; Item.Empty(); - SendSlot( i + c_MainOffset ); + SendSlot(i + c_MainOffset); } } } @@ -176,113 +172,129 @@ bool cInventory::RemoveItem( cItem & a_Item ) void cInventory::Clear() { - for(unsigned int i = 0; i < c_NumSlots; i++) + for (unsigned int i = 0; i < ARRAYCOUNT(m_Slots); i++) + { m_Slots[i].Empty(); + } + // TODO: Broadcast / send the changes to wherever needed } -cItem * cInventory::GetSlotsForType( int a_Type ) +void cInventory::SetSlot(int a_SlotNum, const cItem & a_Item) { - switch( a_Type ) + if ((a_SlotNum < 0) || (a_SlotNum >= ARRAYCOUNT(m_Slots))) { - case -1: - return m_MainSlots; - case -2: - return m_CraftSlots; - case -3: - return m_ArmorSlots; + LOGWARNING("%s requesting an invalid slot index: %d out of %d. Ignoring.", __FUNCTION__, a_SlotNum, ARRAYCOUNT(m_Slots)); + 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)) + { + m_Owner.GetWorld()->BroadcastEntityEquipment(m_Owner, SlotNumToEntityEquipmentID(a_SlotNum), a_Item, m_Owner.GetClientHandle()); } - return 0; } -/* -int cInventory::GetSlotCountForType( int a_Type ) +void cInventory::SetHotBarSlot(int a_HotBarSlotNum, const cItem & a_Item) { - switch (a_Type) - { - case -1: - return 36; - case -2: - case -3: - return 4; - } - return 0; + SetSlot(a_HotBarSlotNum + c_HotSlots, a_Item); } -*/ -cItem* cInventory::GetSlot( int a_SlotNum ) +const cItem & cInventory::GetSlot(int a_SlotNum) const { - if( a_SlotNum < 0 || a_SlotNum >= (short)c_NumSlots ) return 0; - return &m_Slots[a_SlotNum]; + if ((a_SlotNum < 0) || (a_SlotNum >= ARRAYCOUNT(m_Slots))) + { + 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]; + } + + return m_Slots[a_SlotNum]; } -cItem* cInventory::GetFromHotBar( int a_SlotNum ) +const cItem & cInventory::GetHotBarSlot(int a_SlotNum) const { if ((a_SlotNum < 0) || (a_SlotNum >= 9)) { - return NULL; + LOGWARNING("%s requesting an invalid slot index: %d out of 9. Returning the first one instead", __FUNCTION__, a_SlotNum); + return m_HotSlots[0]; } - return &m_HotSlots[a_SlotNum]; + return m_HotSlots[a_SlotNum]; +} + + + + + +const cItem & cInventory::GetEquippedItem(void) const +{ + return GetHotBarSlot(m_EquippedSlotNum); } -void cInventory::SetEquippedSlot(int a_SlotNum) +void cInventory::SetEquippedSlotNum(int a_SlotNum) { if ((a_SlotNum < 0) || (a_SlotNum >= 9)) { - m_EquippedSlot = 0; + LOGWARNING("%s requesting invalid slot index: %d out of 9. Setting 0 instead.", __FUNCTION__, a_SlotNum); + m_EquippedSlotNum = 0; } else { - m_EquippedSlot = (short)a_SlotNum; + m_EquippedSlotNum = (short)a_SlotNum; } - m_EquippedItem = GetFromHotBar(m_EquippedSlot); } -cItem & cInventory::GetEquippedItem(void) +bool cInventory::DamageEquippedItem(short a_Amount) { - cItem* Item = GetFromHotBar( m_EquippedSlot ); - if( Item ) - { - *m_EquippedItem = *Item; - return *Item; - } - else - { - m_EquippedItem->Empty(); - } - return *m_EquippedItem; + return DamageItem(c_HotOffset + m_EquippedSlotNum, a_Amount); } -const cItem & cInventory::GetEquippedItem(void) const +bool cInventory::DamageItem(int a_SlotNum, short a_Amount) { - return *m_EquippedItem; + if ((a_SlotNum < 0) || (a_SlotNum >= ARRAYCOUNT(m_Slots))) + { + LOGWARNING("%s requesting an invalid slot index: %d out of %d", __FUNCTION__, a_SlotNum, ARRAYCOUNT(m_Slots)); + return false; + } + + if (!m_Slots[a_SlotNum].DamageItem(a_Amount)) + { + 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 + return true; } @@ -300,16 +312,13 @@ void cInventory::SendWholeInventory(cClientHandle & a_Client) void cInventory::SendSlot(int a_SlotNum) { - cItem * Item = GetSlot(a_SlotNum); - if (Item != NULL) + cItem Item(GetSlot(a_SlotNum)); + if (Item.IsEmpty()) { - if (Item->IsEmpty()) - { - // Sanitize items that are not completely empty (ie. count == 0, but type != empty) - Item->Empty(); - } - m_Owner.GetClientHandle()->SendInventorySlot(0, a_SlotNum, *Item); + // Sanitize items that are not completely empty (ie. count == 0, but type != empty) + Item.Empty(); } + m_Owner.GetClientHandle()->SendInventorySlot(0, a_SlotNum, Item); } @@ -372,6 +381,23 @@ int cInventory::MoveItem(short a_ItemType, short a_ItemDamage, int a_Count, int +int cInventory::SlotNumToEntityEquipmentID(short a_SlotNum) +{ + switch (a_SlotNum) + { + case 5: return 4; // Helmet + case 6: return 3; // Chestplate + case 7: return 2; // Leggings + case 8: return 1; // Boots + } + LOGWARN("%s: invalid slot number: %d", __FUNCTION__, a_SlotNum); + return 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 @@ -442,13 +468,14 @@ bool cInventory::LoadFromJson(Json::Value & a_Value) { int SlotIdx = 0; - // TODO: Limit the number of slots written to the actual number of slots, - // otherwise an invalid json will crash the server! - for( Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr ) { m_Slots[SlotIdx].FromJson( *itr ); SlotIdx++; + if (SlotIdx >= ARRAYCOUNT(m_Slots)) + { + break; + } } return true; } -- cgit v1.2.3