summaryrefslogtreecommitdiff
path: root/src/gui/itemcontainer.cpp
diff options
context:
space:
mode:
authorIra Rice <irarice@gmail.com>2008-11-29 19:58:41 +0000
committerIra Rice <irarice@gmail.com>2008-11-29 19:58:41 +0000
commitd628724789db142c529af8c25e115dd7ea0626a7 (patch)
treec3799c68b66c5dd29dfeb5417520c7cbd0fcffb0 /src/gui/itemcontainer.cpp
parentc6adb930edd2d0a88d7c5ca4edd58d95382a5abf (diff)
downloadmana-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.cpp82
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());