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 | |
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.
-rw-r--r-- | src/equipment.h | 2 | ||||
-rw-r--r-- | src/gui/inventorywindow.cpp | 4 | ||||
-rw-r--r-- | src/gui/itemcontainer.cpp | 82 | ||||
-rw-r--r-- | src/gui/itemcontainer.h | 19 | ||||
-rw-r--r-- | src/localplayer.cpp | 1 | ||||
-rw-r--r-- | src/localplayer.h | 2 |
6 files changed, 77 insertions, 33 deletions
diff --git a/src/equipment.h b/src/equipment.h index 8b2ce127..2427539c 100644 --- a/src/equipment.h +++ b/src/equipment.h @@ -52,7 +52,7 @@ class Equipment * Remove equipment from the given slot. */ void - removeEquipment(int index) { mEquipment[index] = 0; } + removeEquipment(int index) { if (index >= 0 && index < EQUIPMENT_SIZE) mEquipment[index] = 0; } /** * Get the item used in the arrow slot. diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index cbce0ee3..a8b20d40 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -73,7 +73,7 @@ InventoryWindow::InventoryWindow(): mWeightLabel->setPosition(8, 8); mSlots = "Slots: " + toString(player_node->getInventory()->getNumberOfSlotsUsed()) + - "/" + toString(player_node->getInventory()->getSize()); + "/" + toString(player_node->getInventory()->getSize() - 2); mSlotsLabel = new TextBox(); mItemEffectLabel = new TextBox(); @@ -113,7 +113,7 @@ void InventoryWindow::logic() mSlots = "Slots: " + toString(player_node->getInventory()->getNumberOfSlotsUsed()) + - "/" + toString(player_node->getInventory()->getSize()); + "/" + toString(player_node->getInventory()->getSize() - 2); draw(); } 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()); diff --git a/src/gui/itemcontainer.h b/src/gui/itemcontainer.h index 54e0c1ca..5d22b658 100644 --- a/src/gui/itemcontainer.h +++ b/src/gui/itemcontainer.h @@ -43,8 +43,9 @@ namespace gcn { * * \ingroup GUI */ -class ItemContainer : public gcn::Widget, public gcn::MouseListener, - public gcn::WidgetListener +class ItemContainer : public gcn::Widget, + public gcn::MouseListener, + public gcn::WidgetListener { public: /** @@ -80,7 +81,7 @@ class ItemContainer : public gcn::Widget, public gcn::MouseListener, /** * Returns the selected item. */ - Item* getSelectedItem() const; + Item* getSelectedItem(); /** * Sets selected item to NULL. @@ -107,9 +108,14 @@ class ItemContainer : public gcn::Widget, public gcn::MouseListener, private: /** - * Sets the currently selected item. + * Find the current item index by the most recently used item ID */ - void setSelectedItem(Item *item); + void refindSelectedItem(void); + + /** + * Sets the currently selected item. Invalid (e.g., negative) indices set `no item'. + */ + void setSelectedItemIndex(int index); /** * Determine and set the height of the container. @@ -123,7 +129,8 @@ class ItemContainer : public gcn::Widget, public gcn::MouseListener, Inventory *mInventory; Image *mSelImg; - Item *mSelectedItem; + int mSelectedItemIndex; + int mLastSelectedItemId; // last selected item ID. If we lose the item, find again by ID. int mMaxItems; int mOffset; diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 68999787..7fdbc09b 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -47,6 +47,7 @@ LocalPlayer::LocalPlayer(Uint32 id, Uint16 job, Map *map): Player(id, job, map), mXpForNextLevel(0), mAttackRange(0), + mSkillPoint(0), mXp(0), mNetwork(0), mTarget(NULL), mPickUpTarget(NULL), mTrading(false), mGoingToTarget(false), diff --git a/src/localplayer.h b/src/localplayer.h index bb37274d..ad59d138 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -28,7 +28,7 @@ // TODO move into some sane place... #define MAX_SLOT 2 -#define INVENTORY_SIZE 100 +#define INVENTORY_SIZE 102 #define STORAGE_SIZE 301 class FloorItem; |