diff options
author | Majin Sniper <majinsniper@gmx.de> | 2009-02-23 19:19:55 +0100 |
---|---|---|
committer | Jared Adams <jaxad0127@gmail.com> | 2009-02-23 17:19:56 -0700 |
commit | e15b8c360ac5171fe73b8b73fbe00eedba8970ff (patch) | |
tree | ec7d2129c8dc35c3cdf7669a08beb71c30a7760c /src/gui | |
parent | c54b987a4e4d28d35e8bafb03e1dba33b5fda4ab (diff) | |
download | mana-e15b8c360ac5171fe73b8b73fbe00eedba8970ff.tar.gz mana-e15b8c360ac5171fe73b8b73fbe00eedba8970ff.tar.bz2 mana-e15b8c360ac5171fe73b8b73fbe00eedba8970ff.tar.xz mana-e15b8c360ac5171fe73b8b73fbe00eedba8970ff.zip |
Allow to sell non-stackable items like stackables
Make it possible to sell non-stackable items all at once by introducing
"Duplicate Items" and a Shop that can handle them. Also fix a
trivial bug to correctly preview you money while selling.
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/sell.cpp | 35 | ||||
-rw-r--r-- | src/gui/shop.cpp | 51 | ||||
-rw-r--r-- | src/gui/shop.h | 59 |
3 files changed, 119 insertions, 26 deletions
diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index 20a2a786..14620aa6 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -50,7 +50,8 @@ SellDialog::SellDialog(Network *network): setMinHeight(230); setDefaultSize(0, 0, 260, 230); - mShopItems = new ShopItems; + // Create a ShopItems instance, that is aware of duplicate entries. + mShopItems = new ShopItems(true); mShopItemList = new ShopListBox(mShopItems, mShopItems); mScrollArea = new ScrollArea(mShopItemList); @@ -115,10 +116,11 @@ void SellDialog::reset() void SellDialog::addItem(const Item *item, int price) { if (!item) + { return; + } - mShopItems->addItem( - item->getInvIndex(), item->getId(), + mShopItems->addItem(item->getInvIndex(), item->getId(), item->getQuantity(), price); mShopItemList->adjustSize(); @@ -164,23 +166,34 @@ void SellDialog::action(const gcn::ActionEvent &event) { // Attempt sell MessageOut outMsg(mNetwork); - outMsg.writeInt16(CMSG_NPC_SELL_REQUEST); - outMsg.writeInt16(8); - outMsg.writeInt16(mShopItems->at(selectedItem)->getInvIndex()); - outMsg.writeInt16(mAmountItems); + ShopItem* item = mShopItems->at(selectedItem); + int sellCount; + mPlayerMoney += + mAmountItems * mShopItems->at(selectedItem)->getPrice(); mMaxItems -= mAmountItems; - mShopItems->getShop()->at(selectedItem)->setQuantity(mMaxItems); + while (mAmountItems > 0) { + outMsg.writeInt16(CMSG_NPC_SELL_REQUEST); + outMsg.writeInt16(8); + outMsg.writeInt16(item->getCurrentInvIndex()); + // This order is important, item->getCurrentInvIndex() would return + // the inventory index of the next Duplicate otherwise. + sellCount = item->sellCurrentDuplicate(mAmountItems); + mAmountItems -= sellCount; + outMsg.writeInt16(sellCount); + } + mPlayerMoney += mAmountItems * mShopItems->at(selectedItem)->getPrice(); mAmountItems = 1; + mSlider->setValue(0); if (!mMaxItems) { // All were sold mShopItemList->setSelected(-1); - mShopItems->getShop()->erase( - mShopItems->getShop()->begin() + selectedItem); + delete mShopItems->at(selectedItem); + mShopItems->erase(selectedItem); gcn::Rectangle scroll; scroll.y = mShopItemList->getRowHeight() * (selectedItem + 1); @@ -252,7 +265,7 @@ void SellDialog::updateButtonsAndLabels() mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); mMoneyLabel->setCaption(strprintf(_("Price: %s / Total: %s"), Units::formatCurrency(income).c_str(), - Units::formatCurrency(mPlayerMoney - income).c_str())); + Units::formatCurrency(mPlayerMoney + income).c_str())); } void SellDialog::logic() diff --git a/src/gui/shop.cpp b/src/gui/shop.cpp index a5f59bac..e13e218c 100644 --- a/src/gui/shop.cpp +++ b/src/gui/shop.cpp @@ -23,6 +23,11 @@ #include "../utils/dtor.h" +ShopItems::ShopItems(bool mergeDuplicates) : + mMergeDuplicates(mergeDuplicates) +{ +} + ShopItems::~ShopItems() { clear(); @@ -38,16 +43,29 @@ std::string ShopItems::getElementAt(int i) return mShopItems.at(i)->getDisplayName(); } -void ShopItems::addItem(int inventoryIndex, short id, int amount, int price) +void ShopItems::addItem(int inventoryIndex, int id, int quantity, + int price) { - ShopItem *item = new ShopItem(id, amount, price); - item->setInvIndex(inventoryIndex); - mShopItems.push_back(item); + ShopItem* item = 0; + if (mMergeDuplicates) + { + item = findItem(id); + } + + if (item) + { + item->addDuplicate (inventoryIndex, quantity); + } + else + { + item = new ShopItem(inventoryIndex, id, quantity, price); + mShopItems.push_back(item); + } } -void ShopItems::addItem(short id, int price) +void ShopItems::addItem(int id, int price) { - mShopItems.push_back(new ShopItem(id, 0, price)); + addItem(-1, id, 0, price); } ShopItem* ShopItems::at(int i) const @@ -55,13 +73,30 @@ ShopItem* ShopItems::at(int i) const return mShopItems.at(i); } +void ShopItems::erase(int i) +{ + mShopItems.erase(mShopItems.begin() + i); +} + void ShopItems::clear() { delete_all(mShopItems); mShopItems.clear(); } -std::vector<ShopItem*>* ShopItems::getShop() +ShopItem* ShopItems::findItem(int id) { - return &mShopItems; + ShopItem *item; + + std::vector<ShopItem*>::iterator it; + for(it = mShopItems.begin(); it != mShopItems.end(); it++) + { + item = *(it); + if (item->getId() == id) + { + return item; + } + } + + return 0; } diff --git a/src/gui/shop.h b/src/gui/shop.h index e0db4c59..faffe7e3 100644 --- a/src/gui/shop.h +++ b/src/gui/shop.h @@ -31,31 +31,62 @@ class ShopItem; +/** + * This class handles the list of items available in a shop. + * + * The addItem routine can automatically check, if an item already exists and + * only adds duplicates to the old item, if one is found. The original + * distribution of the duplicates can be retrieved from the item. + * + * This functionality can be enabled in the constructor. + */ class ShopItems : public gcn::ListModel { public: /** + * Constructor. Creates a new ShopItems instance. + * + * @param mergeDuplicates lets the Shop look for duplicate entries and + * merges them to one item. + */ + ShopItems(bool mergeDuplicates = false); + + /** * Destructor. */ ~ShopItems(); /** - * Adds an item to the list (used by sell dialog). + * Adds an item to the list (used by sell dialog). Looks for + * duplicate entries, if mergeDuplicates was turned on. + * + * @param inventoryIndex the inventory index of the item + * @param id the id of the item + * @param quantity number of available copies of the item + * @param price price of the item */ - void addItem(int inventoryIndex, short id, int amount, int price); + void addItem(int inventoryIndex, int id, int amount, int price); /** - * Adds an item to the list (used by buy dialog). + * Adds an item to the list (used by buy dialog). Looks for + * duplicate entries, if mergeDuplicates was turned on. + * + * @param id the id of the item + * @param price price of the item */ - void addItem(short id, int price); + void addItem(int id, int price); /** * Returns the number of items in the shop. + * + * @return the number of items in the shop */ int getNumberOfElements(); /** * Returns the name of item number i in the shop. + * + * @param i the index to retrieve */ std::string getElementAt(int i); @@ -65,17 +96,31 @@ class ShopItems : public gcn::ListModel ShopItem* at(int i) const; /** + * Removes an element from the shop. + * + * @param i index to remove + */ + void erase(int i); + + /** * Clear the vector. */ void clear(); + private: /** - * Direct access to the vector. + * Searches the current items in the shop for the specified + * id and returns the item if found, or 0 else. + * + * @return the item found or 0 */ - std::vector<ShopItem*>* getShop(); + ShopItem* findItem(int id); - private: + /** the shop storage */ std::vector<ShopItem*> mShopItems; + + /** Look for duplicate entries on addition */ + bool mMergeDuplicates; }; #endif |