diff options
author | Ira Rice <irarice@gmail.com> | 2008-11-29 19:58:41 +0000 |
---|---|---|
committer | Ira Rice <irarice@gmail.com> | 2008-11-29 19:58:41 +0000 |
commit | d628724789db142c529af8c25e115dd7ea0626a7 (patch) | |
tree | c3799c68b66c5dd29dfeb5417520c7cbd0fcffb0 /src/gui/itemcontainer.cpp | |
parent | c6adb930edd2d0a88d7c5ca4edd58d95382a5abf (diff) | |
download | mana-d628724789db142c529af8c25e115dd7ea0626a7.tar.gz mana-d628724789db142c529af8c25e115dd7ea0626a7.tar.bz2 mana-d628724789db142c529af8c25e115dd7ea0626a7.tar.xz mana-d628724789db142c529af8c25e115dd7ea0626a7.zip |
Imported patch that Fate made on TMW which which changes the item
container to guarantee that the inventory window always reports what the
player has correctly, getting rid of the stale item references that
could occur from time to time.
Diffstat (limited to 'src/gui/itemcontainer.cpp')
-rw-r--r-- | src/gui/itemcontainer.cpp | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp index 5069e102..fca0c72d 100644 --- a/src/gui/itemcontainer.cpp +++ b/src/gui/itemcontainer.cpp @@ -40,9 +40,12 @@ const int ItemContainer::gridWidth = 36; // item icon width + 4 const int ItemContainer::gridHeight = 42; // item icon height + 10 +static const int NO_ITEM = -1; + ItemContainer::ItemContainer(Inventory *inventory, int offset): mInventory(inventory), - mSelectedItem(NULL), + mSelectedItemIndex(NO_ITEM), + mLastSelectedItemId(NO_ITEM), mOffset(offset) { ResourceManager *resman = ResourceManager::getInstance(); @@ -86,13 +89,6 @@ ItemContainer::draw(gcn::Graphics *graphics) columns = 1; } - // Reset selected item when quantity not above 0 (should probably be made - // sure somewhere else) - if (mSelectedItem && mSelectedItem->getQuantity() <= 0) - { - selectNone(); - } - /* * mOffset is used to compensate for some weirdness that eAthena inherited from * Ragnarok Online. Inventory slots and cart slots are +2 from their actual index, @@ -109,7 +105,7 @@ ItemContainer::draw(gcn::Graphics *graphics) int itemY = ((i - 2) / columns) * gridHeight; // Draw selection image below selected item - if (mSelectedItem == item) + if (mSelectedItemIndex == i) { static_cast<Graphics*>(graphics)->drawImage( mSelImg, itemX, itemY); @@ -151,23 +147,67 @@ void ItemContainer::recalculateHeight() } Item* -ItemContainer::getSelectedItem() const +ItemContainer::getSelectedItem() { - return mSelectedItem; + refindSelectedItem(); // Make sure that we're still current + + if (mSelectedItemIndex == NO_ITEM) + return NULL; + + return mInventory->getItem(mSelectedItemIndex); } void ItemContainer::selectNone() { - setSelectedItem(NULL); + setSelectedItemIndex(NO_ITEM); } -void -ItemContainer::setSelectedItem(Item *item) +void ItemContainer::refindSelectedItem() +{ + if (mSelectedItemIndex != NO_ITEM) { + + if (mInventory->getItem(mSelectedItemIndex) && + mInventory->getItem(mSelectedItemIndex)->getId() == mLastSelectedItemId) + return; // we're already fine + + // Otherwise ensure the invariant: we must point to an item of the specified last ID, + // or nowhere at all. + + for (int i = 0; i <= mMaxItems + mOffset; i++) + if (mInventory->getItem(i) && + mInventory->getItem(i)->getId() == mLastSelectedItemId) { + mSelectedItemIndex = i; + return; + } + } + + mLastSelectedItemId = mSelectedItemIndex = NO_ITEM; +} + +void ItemContainer::setSelectedItemIndex(int index) { - if (mSelectedItem != item) + int newSelectedItemIndex; + + /* + * mOffset is used to compensate for some weirdness that eAthena inherited from + * Ragnarok Online. Inventory slots and cart slots are +2 from their actual index, + * while storage slots are +1. + */ + if (index < 0 || index > mMaxItems + mOffset || mInventory->getItem(index) == NULL) + newSelectedItemIndex = NO_ITEM; + else + newSelectedItemIndex = index; + + if (mSelectedItemIndex != newSelectedItemIndex) { - mSelectedItem = item; + mSelectedItemIndex = newSelectedItemIndex; + + if (mSelectedItemIndex == NO_ITEM) + mLastSelectedItemId = NO_ITEM; + else + mLastSelectedItemId = mInventory->getItem(index)->getId(); + distributeValueChangedEvent(); } } @@ -198,14 +238,10 @@ ItemContainer::mousePressed(gcn::MouseEvent &event) int index = mx / gridWidth + ((my / gridHeight) * columns) + mOffset; itemShortcut->setItemSelected(-1); - // Fix for old server, it should be: if (index >= mMaxItems) - if (index > mMaxItems + 1) - { - setSelectedItem(NULL); - return; - } + setSelectedItemIndex(index); + Item *item = mInventory->getItem(index); - setSelectedItem(item); + if (item) { itemShortcut->setItemSelected(item->getId()); |