summaryrefslogtreecommitdiff
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
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.
-rw-r--r--src/equipment.h2
-rw-r--r--src/gui/inventorywindow.cpp4
-rw-r--r--src/gui/itemcontainer.cpp82
-rw-r--r--src/gui/itemcontainer.h19
-rw-r--r--src/localplayer.cpp1
-rw-r--r--src/localplayer.h2
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;