diff options
author | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2008-06-12 09:06:01 +0000 |
---|---|---|
committer | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2008-06-12 09:06:01 +0000 |
commit | 2f8ee95fbacb71e7cbca85fcc11e6f9f7e36c258 (patch) | |
tree | 8d256ac1a38932aaf0db7b55ed178e4212616555 /src | |
parent | eb019ab915998a3ec247b33dad4b23f763d7a29a (diff) | |
download | mana-2f8ee95fbacb71e7cbca85fcc11e6f9f7e36c258.tar.gz mana-2f8ee95fbacb71e7cbca85fcc11e6f9f7e36c258.tar.bz2 mana-2f8ee95fbacb71e7cbca85fcc11e6f9f7e36c258.tar.xz mana-2f8ee95fbacb71e7cbca85fcc11e6f9f7e36c258.zip |
Merged revisions 3738 via svnmerge from
https://themanaworld.svn.sourceforge.net/svnroot/themanaworld/tmw/trunk
........
r3738 | b_lindeijer | 2007-11-16 00:44:01 +0100 (Fri, 16 Nov 2007) | 3 lines
Moved item icon from ItemInfo class to the Item class, so that it can be loaded
on demand. Results in faster startup time and reduced memory usage.
........
Diffstat (limited to 'src')
36 files changed, 376 insertions, 286 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3d19fdc9..0c2ef4cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -326,6 +326,8 @@ SET(SRCS player.h properties.h serverinfo.h + shopitem.cpp + shopitem.h simpleanimation.cpp simpleanimation.h sound.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 98c0e53e..3156a800 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -284,6 +284,8 @@ tmw_SOURCES = gui/widgets/resizegrip.cpp \ player_relations.h \ properties.h \ serverinfo.h \ + shopitem.cpp \ + shopitem.h \ simpleanimation.cpp \ simpleanimation.h \ sound.cpp \ diff --git a/src/equipment.cpp b/src/equipment.cpp index 6cd4d967..d1f9a6cf 100644 --- a/src/equipment.cpp +++ b/src/equipment.cpp @@ -26,18 +26,19 @@ #include <algorithm> #include "item.h" +#include "item.h" Equipment::Equipment(): mArrows(0) { - std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*)0); + std::fill_n(mEquipment, EQUIPMENT_SIZE, (Item*) 0); } void Equipment::removeEquipment(Item *item) { - Item **i = std::find(mEquipment, mEquipment+EQUIPMENT_SIZE, item); - if (i != mEquipment+EQUIPMENT_SIZE) { + Item **i = std::find(mEquipment, mEquipment + EQUIPMENT_SIZE, item); + if (i != mEquipment + EQUIPMENT_SIZE) { *i = 0; } } diff --git a/src/equipment.h b/src/equipment.h index db9cf27d..80a2ae49 100644 --- a/src/equipment.h +++ b/src/equipment.h @@ -39,8 +39,8 @@ class Equipment /** * Get equipment at the given slot. */ - Item* - getEquipment(int index) { return mEquipment[index]; } + Item* getEquipment(int index) const + { return mEquipment[index]; } /** * Set equipment at the given slot. @@ -71,7 +71,7 @@ class Equipment void setArrows(Item *arrows) { mArrows = arrows; } - protected: + private: Item *mEquipment[EQUIPMENT_SIZE]; Item *mArrows; }; diff --git a/src/floor_item.cpp b/src/floor_item.cpp index 5d83e1dd..9727093f 100644 --- a/src/floor_item.cpp +++ b/src/floor_item.cpp @@ -25,23 +25,18 @@ #include "map.h" -#include "resources/itemdb.h" -#include "resources/iteminfo.h" - - FloorItem::FloorItem(unsigned int id, unsigned int itemId, unsigned short x, unsigned short y, Map *map): mId(id), - mItemId(itemId), mX(x), mY(y), mMap(map) { - // Retrieve item image from item info - mImage = ItemDB::get(itemId).getImage(); + // Create a corresponding item instance + mItem = new Item(itemId); // Add ourselves to the map mSpriteIterator = mMap->addSprite(this); @@ -51,4 +46,6 @@ FloorItem::~FloorItem() { // Remove ourselves from the map mMap->removeSprite(mSpriteIterator); + + delete mItem; } diff --git a/src/floor_item.h b/src/floor_item.h index 36f81585..a87e3f79 100644 --- a/src/floor_item.h +++ b/src/floor_item.h @@ -25,6 +25,7 @@ #define _TMW_FLOORITEM_H_ #include "graphics.h" +#include "item.h" #include "map.h" #include "sprite.h" #include "resources/image.h" @@ -59,7 +60,7 @@ class FloorItem : public Sprite * Returns the item id. */ unsigned int - getItemId() const { return mItemId; } + getItemId() const { return mItem->getId(); } /** * Returns the x coordinate. @@ -89,16 +90,15 @@ class FloorItem : public Sprite void draw(Graphics *graphics, int offsetX, int offsetY) const { - graphics->drawImage(mImage, + graphics->drawImage(mItem->getImage(), mX * 32 + offsetX, mY * 32 + offsetY); } private: unsigned int mId; - unsigned int mItemId; unsigned short mX, mY; - Image *mImage; + Item *mItem; Sprites::iterator mSpriteIterator; Map *mMap; }; diff --git a/src/gui/buy.cpp b/src/gui/buy.cpp index 17e5dba7..259fcfd9 100644 --- a/src/gui/buy.cpp +++ b/src/gui/buy.cpp @@ -33,8 +33,6 @@ #include "../npc.h" -#include "../resources/itemdb.h" - #include "../net/messageout.h" #include "../net/protocol.h" @@ -170,7 +168,7 @@ void BuyDialog::action(const gcn::ActionEvent &event) outMsg.writeInt16(CMSG_NPC_BUY_REQUEST); outMsg.writeInt16(8); outMsg.writeInt16(mAmountItems); - outMsg.writeInt16(mShopItems->at(selectedItem).id); + outMsg.writeInt16(mShopItems->at(selectedItem)->getId()); // Reset selection mAmountItems = 1; @@ -179,7 +177,8 @@ void BuyDialog::action(const gcn::ActionEvent &event) // Update money and adjust the max number of items that can be bought mMaxItems -= mAmountItems; - setMoney(mMoney - mAmountItems * mShopItems->at(selectedItem).price); + setMoney(mMoney - + mAmountItems * mShopItems->at(selectedItem)->getPrice()); } } @@ -246,20 +245,22 @@ BuyDialog::updateButtonsAndLabels() if (selectedItem > -1) { - const ItemInfo &info = ItemDB::get(mShopItems->at(selectedItem).id); + const ItemInfo &info = mShopItems->at(selectedItem)->getInfo(); mItemDescLabel->setCaption("Description: " + info.getDescription()); mItemEffectLabel->setCaption("Effect: " + info.getEffect()); + int itemPrice = mShopItems->at(selectedItem)->getPrice(); + // Calculate how many the player can afford - mMaxItems = mMoney / mShopItems->at(selectedItem).price; + mMaxItems = mMoney / itemPrice; if (mAmountItems > mMaxItems) { mAmountItems = mMaxItems; } // Calculate price of pending purchase - price = mAmountItems * mShopItems->at(selectedItem).price; + price = mAmountItems * itemPrice; } else { diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 4df18b19..93b9ea37 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -61,22 +61,20 @@ void EquipmentWindow::draw(gcn::Graphics *graphics) graphics->drawRectangle(gcn::Rectangle(10 + 36 * (i % 4), 36 * (i / 4) + 25, 32, 32)); - if (!(item = mEquipment->getEquipment(i))) { + if (!(item = mEquipment->getEquipment(i))) continue; - } - image = item->getInfo().getImage(); + image = item->getImage(); static_cast<Graphics*>(graphics)->drawImage( image, 36 * (i % 4) + 10, 36 * (i / 4) + 25); } graphics->drawRectangle(gcn::Rectangle(160, 25, 32, 32)); - if (!(item = mEquipment->getArrows())) { + if (!(item = mEquipment->getArrows())) return; - } - image = item->getInfo().getImage(); + image = item->getImage(); static_cast<Graphics*>(graphics)->drawImage(image, 160, 25); graphics->drawText(toString(item->getQuantity()), 170, 62, diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 4172a532..fcc602f9 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -57,7 +57,7 @@ InventoryWindow::InventoryWindow(): mUseButton = new Button("Use", "use", this); mDropButton = new Button("Drop", "drop", this); - mItems = new ItemContainer(player_node->mInventory); + mItems = new ItemContainer(player_node->getInventory()); mItems->addSelectionListener(this); mInvenScroll = new ScrollArea(mItems); @@ -100,11 +100,10 @@ void InventoryWindow::logic() void InventoryWindow::action(const gcn::ActionEvent &event) { - Item *item = mItems->getItem(); + Item *item = mItems->getSelectedItem(); - if (!item) { + if (!item) return; - } if (event.getId() == "use") { if (item->isEquipment()) { @@ -133,7 +132,7 @@ void InventoryWindow::action(const gcn::ActionEvent &event) void InventoryWindow::valueChanged(const gcn::SelectionEvent &event) { - Item *item = mItems->getItem(); + const Item *item = mItems->getSelectedItem(); // Update name, effect and description if (!item) @@ -161,7 +160,7 @@ void InventoryWindow::mouseClicked(gcn::MouseEvent &event) if (event.getButton() == gcn::MouseEvent::RIGHT) { - Item *item = mItems->getItem(); + Item *item = mItems->getSelectedItem(); if (!item) return; @@ -208,11 +207,11 @@ void InventoryWindow::widgetResized(const gcn::Event &event) void InventoryWindow::updateButtons() { - Item *item; + const Item *selectedItem = mItems->getSelectedItem(); - if ((item = mItems->getItem()) && item->isEquipment()) + if (selectedItem && selectedItem->isEquipment()) { - if (item->isEquipped()) { + if (selectedItem->isEquipped()) { mUseButton->setCaption("Unequip"); } else { @@ -220,14 +219,14 @@ void InventoryWindow::updateButtons() } } else { - mUseButton ->setCaption("Use"); + mUseButton->setCaption("Use"); } - mUseButton->setEnabled(!!item); - mDropButton->setEnabled(!!item); + mUseButton->setEnabled(selectedItem != 0); + mDropButton->setEnabled(selectedItem != 0); } -Item* InventoryWindow::getItem() +Item* InventoryWindow::getSelectedItem() const { - return mItems->getItem(); + return mItems->getSelectedItem(); } diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h index 3222009f..d45602d2 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -58,7 +58,10 @@ class InventoryWindow : public Window, gcn::ActionListener, */ void action(const gcn::ActionEvent &event); - Item* getItem(); + /** + * Returns the selected item. + */ + Item* getSelectedItem() const; /** * Updates labels to currently selected item. diff --git a/src/gui/itemcontainer.cpp b/src/gui/itemcontainer.cpp index eb8b91a7..cf5dcb92 100644 --- a/src/gui/itemcontainer.cpp +++ b/src/gui/itemcontainer.cpp @@ -101,9 +101,8 @@ ItemContainer::draw(gcn::Graphics *graphics) { Item *item = mInventory->getItem(i); - if (item->getQuantity() <= 0) { + if (!item || item->getQuantity() <= 0) continue; - } int itemX = ((i - 2) % columns) * gridWidth; int itemY = ((i - 2) / columns) * gridHeight; @@ -116,8 +115,8 @@ ItemContainer::draw(gcn::Graphics *graphics) } // Draw item icon - Image* image; - if ((image = item->getInfo().getImage()) != NULL) + Image* image = item->getImage(); + if (image) { static_cast<Graphics*>(graphics)->drawImage( image, itemX, itemY); @@ -151,7 +150,7 @@ void ItemContainer::recalculateHeight() } Item* -ItemContainer::getItem() +ItemContainer::getSelectedItem() const { return mSelectedItem; } @@ -206,7 +205,7 @@ ItemContainer::mousePressed(gcn::MouseEvent &event) } Item *item = mInventory->getItem(index); setSelectedItem(item); - if (!item->isEquipment()) + if (item && !item->isEquipment()) { itemShortcut->setItemSelected(item->getId()); } diff --git a/src/gui/itemcontainer.h b/src/gui/itemcontainer.h index 9320cdcf..db8c6f3d 100644 --- a/src/gui/itemcontainer.h +++ b/src/gui/itemcontainer.h @@ -80,7 +80,7 @@ class ItemContainer : public gcn::Widget, public gcn::MouseListener, /** * Returns the selected item. */ - Item* getItem(); + Item* getSelectedItem() const; /** * Sets selected item to NULL. diff --git a/src/gui/itemshortcutcontainer.cpp b/src/gui/itemshortcutcontainer.cpp index b15c8983..0ce4f6b7 100644 --- a/src/gui/itemshortcutcontainer.cpp +++ b/src/gui/itemshortcutcontainer.cpp @@ -25,6 +25,7 @@ #include "../localplayer.h" #include "../graphics.h" +#include "../inventory.h" #include "../item.h" #include "../itemshortcut.h" #include "../keyboardconfig.h" @@ -93,10 +94,11 @@ ItemShortcutContainer::draw(gcn::Graphics *graphics) if (itemShortcut->getItem(i) < 0) continue; - Item *item = player_node->searchForItem(itemShortcut->getItem(i)); + Item *item = + player_node->getInventory()->findItem(itemShortcut->getItem(i)); if (item) { // Draw item icon. - Image* image = item->getInfo().getImage(); + Image* image = item->getImage(); if (image) { g->drawImage(image, itemX, itemY); g->drawText( @@ -110,7 +112,7 @@ ItemShortcutContainer::draw(gcn::Graphics *graphics) if (mItemMoved) { // Draw the item image being dragged by the cursor. - Image* image = mItemMoved->getInfo().getImage(); + Image* image = mItemMoved->getImage(); if (image) { const int tPosX = mCursorPosX - (image->getWidth() / 2); @@ -151,9 +153,10 @@ ItemShortcutContainer::mouseDragged(gcn::MouseEvent &event) if (index == -1) { return; } - if (itemShortcut->getItem(index) < 0) + const int itemId = itemShortcut->getItem(index); + if (itemId < 0) return; - Item *item = player_node->searchForItem(itemShortcut->getItem(index)); + Item *item = player_node->getInventory()->findItem(itemId); if (item) { mItemMoved = item; diff --git a/src/gui/sell.cpp b/src/gui/sell.cpp index 0a590ec6..82d340fb 100644 --- a/src/gui/sell.cpp +++ b/src/gui/sell.cpp @@ -37,7 +37,6 @@ #include "../npc.h" #include "../resources/iteminfo.h" -#include "../resources/itemdb.h" #include "../net/messageout.h" #include "../net/protocol.h" @@ -117,22 +116,15 @@ void SellDialog::reset() updateButtonsAndLabels(); } -void SellDialog::addItem(Item *item, int price) +void SellDialog::addItem(const Item *item, int price) { if (!item) return; - ITEM_SHOP item_shop; + mShopItems->addItem( + item->getInvIndex(), item->getId(), + item->getQuantity(), price); - item_shop.name = item->getInfo().getName() - + " (" + toString(price) + " GP)"; - item_shop.price = price; - item_shop.index = item->getInvIndex(); - item_shop.id = item->getId(); - item_shop.quantity = item->getQuantity(); - item_shop.image = item->getInfo().getImage(); - - mShopItems->push_back(item_shop); mShopItemList->adjustSize(); } @@ -178,12 +170,13 @@ void SellDialog::action(const gcn::ActionEvent &event) MessageOut outMsg(mNetwork); outMsg.writeInt16(CMSG_NPC_SELL_REQUEST); outMsg.writeInt16(8); - outMsg.writeInt16(mShopItems->at(selectedItem).index); + outMsg.writeInt16(mShopItems->at(selectedItem)->getInvIndex()); outMsg.writeInt16(mAmountItems); mMaxItems -= mAmountItems; - mShopItems->getShop()->at(selectedItem).quantity = mMaxItems; - mPlayerMoney += (mAmountItems * mShopItems->at(selectedItem).price); + mShopItems->getShop()->at(selectedItem)->setQuantity(mMaxItems); + mPlayerMoney += + mAmountItems * mShopItems->at(selectedItem)->getPrice(); mAmountItems = 1; if (!mMaxItems) @@ -277,15 +270,15 @@ SellDialog::updateButtonsAndLabels() if (selectedItem > -1) { - mMaxItems = mShopItems->at(selectedItem).quantity; + mMaxItems = mShopItems->at(selectedItem)->getQuantity(); if (mAmountItems > mMaxItems) { mAmountItems = mMaxItems; } - income = mAmountItems * mShopItems->at(selectedItem).price; + income = mAmountItems * mShopItems->at(selectedItem)->getPrice(); - const ItemInfo &info = ItemDB::get(mShopItems->at(selectedItem).id); + const ItemInfo &info = mShopItems->at(selectedItem)->getInfo(); mItemDescLabel->setCaption("Description: " + info.getDescription()); mItemEffectLabel->setCaption("Effect: " + info.getEffect()); } diff --git a/src/gui/sell.h b/src/gui/sell.h index c56337ef..0c1a2007 100644 --- a/src/gui/sell.h +++ b/src/gui/sell.h @@ -64,7 +64,7 @@ class SellDialog : public Window, gcn::ActionListener, gcn::SelectionListener /** * Adds an item to the inventory. */ - void addItem(Item *item, int price); + void addItem(const Item *item, int price); /** * Called when receiving actions from the widgets. diff --git a/src/gui/shop.cpp b/src/gui/shop.cpp index 3d972bc2..ff6e3d68 100644 --- a/src/gui/shop.cpp +++ b/src/gui/shop.cpp @@ -22,8 +22,8 @@ */ #include "shop.h" -#include "../utils/tostring.h" -#include "../resources/itemdb.h" + +#include "../utils/dtor.h" ShopItems::~ShopItems() { @@ -32,43 +32,38 @@ ShopItems::~ShopItems() int ShopItems::getNumberOfElements() { - return mItemsShop.size(); + return mShopItems.size(); } std::string ShopItems::getElementAt(int i) { - return mItemsShop.at(i).name; + return mShopItems.at(i)->getDisplayName(); } -void ShopItems::addItem(short id, int price) +void ShopItems::addItem(int inventoryIndex, short id, int amount, int price) { - ITEM_SHOP item_shop; - - item_shop.name = ItemDB::get(id).getName() - + " (" + toString(price) + " GP)"; - item_shop.price = price; - item_shop.id = id; - item_shop.image = ItemDB::get(id).getImage(); - - mItemsShop.push_back(item_shop); + ShopItem *item = new ShopItem(id, amount, price); + item->setInvIndex(inventoryIndex); + mShopItems.push_back(item); } -ITEM_SHOP ShopItems::at(int i) +void ShopItems::addItem(short id, int price) { - return mItemsShop.at(i); + mShopItems.push_back(new ShopItem(id, 0, price)); } -void ShopItems::push_back(ITEM_SHOP item_shop) +ShopItem* ShopItems::at(int i) const { - mItemsShop.push_back(item_shop); + return mShopItems.at(i); } void ShopItems::clear() { - mItemsShop.clear(); + std::for_each(mShopItems.begin(), mShopItems.end(), make_dtor(mShopItems)); + mShopItems.clear(); } -std::vector<ITEM_SHOP>* ShopItems::getShop() +std::vector<ShopItem*>* ShopItems::getShop() { - return &mItemsShop; + return &mShopItems; } diff --git a/src/gui/shop.h b/src/gui/shop.h index de452b5c..22e715c9 100644 --- a/src/gui/shop.h +++ b/src/gui/shop.h @@ -28,34 +28,28 @@ #include <vector> #include <guichan/listmodel.hpp> + #include "../resources/image.h" -struct ITEM_SHOP { - short id; - std::string name; - Image *image; - int price; - int index; - int quantity; -}; +#include "../shopitem.h" class ShopItems : public gcn::ListModel { public: /** - * Destructor + * Destructor. */ ~ShopItems(); /** - * Adds an item and its associated picture + * Adds an item to the list (used by sell dialog). */ - void addItem(short id, int price); + void addItem(int inventoryIndex, short id, int amount, int price); /** - * Convenience function for adding items + * Adds an item to the list (used by buy dialog). */ - void push_back(ITEM_SHOP item_shop); + void addItem(short id, int price); /** * Returns the number of items in the shop. @@ -70,7 +64,7 @@ class ShopItems : public gcn::ListModel /** * Returns the item number i in the shop. */ - ITEM_SHOP at(int i); + ShopItem* at(int i) const; /** * Clear the vector. @@ -78,13 +72,12 @@ class ShopItems : public gcn::ListModel void clear(); /** - * Direct access to the vector + * Direct access to the vector. */ - std::vector<ITEM_SHOP>* getShop(); + std::vector<ShopItem*>* getShop(); private: - std::vector<ITEM_SHOP> mItemsShop; - + std::vector<ShopItem*> mShopItems; }; #endif diff --git a/src/gui/shoplistbox.cpp b/src/gui/shoplistbox.cpp index f3f98062..7a8b52ed 100644 --- a/src/gui/shoplistbox.cpp +++ b/src/gui/shoplistbox.cpp @@ -77,7 +77,7 @@ void ShopListBox::draw(gcn::Graphics *gcnGraphics) backgroundColor = gcn::Color(110, 160, 255); } else if (mShopItems && - mPlayerMoney < mShopItems->at(i).price && mPriceCheck) + mPlayerMoney < mShopItems->at(i)->getPrice() && mPriceCheck) { backgroundColor = gcn::Color(0x919191); } @@ -87,7 +87,7 @@ void ShopListBox::draw(gcn::Graphics *gcnGraphics) if (mShopItems) { - Image *icon = mShopItems->at(i).image; + Image *icon = mShopItems->at(i)->getImage(); if (icon) { graphics->drawImage(icon, 1, y); diff --git a/src/gui/trade.cpp b/src/gui/trade.cpp index db33fb12..54544250 100644 --- a/src/gui/trade.cpp +++ b/src/gui/trade.cpp @@ -227,17 +227,17 @@ void TradeWindow::tradeItem(Item *item, int quantity) void TradeWindow::valueChanged(const gcn::SelectionEvent &event) { - Item *item; + const Item *item; /* If an item is selected in one container, make sure no item is selected * in the other container. */ if (event.getSource() == mMyItemContainer && - (item = mMyItemContainer->getItem())) + (item = mMyItemContainer->getSelectedItem())) { mPartnerItemContainer->selectNone(); } - else if ((item = mPartnerItemContainer->getItem())) + else if ((item = mPartnerItemContainer->getSelectedItem())) { mMyItemContainer->selectNone(); } @@ -262,19 +262,15 @@ void TradeWindow::valueChanged(const gcn::SelectionEvent &event) void TradeWindow::action(const gcn::ActionEvent &event) { - Item *item = inventoryWindow->getItem(); + Item *item = inventoryWindow->getSelectedItem(); if (event.getId() == "add") { if (!item) - { return; - } if (mMyInventory->getFreeSlot() < 1) - { return; - } if (mMyInventory->contains(item)) { chatWindow->chatLog("Failed adding item. You can not " diff --git a/src/inventory.cpp b/src/inventory.cpp index be002dfe..470b6c85 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -29,84 +29,104 @@ #include "item.h" #include "log.h" -struct SlotUsed : public std::unary_function<Item, bool> +struct SlotUsed : public std::unary_function<Item*, bool> { - bool operator()(const Item &item) const { - return (item.getId() != -1 && item.getQuantity() > 0); + bool operator()(const Item *item) const { + return item && item->getId() != -1 && item->getQuantity() > 0; } }; Inventory::Inventory() { - mItems = new Item[INVENTORY_SIZE]; - for (int i = 0; i < INVENTORY_SIZE; i++) { - mItems[i].setInvIndex(i); - } + mItems = new Item*[INVENTORY_SIZE]; + std::fill_n(mItems, INVENTORY_SIZE, (Item*) 0); } Inventory::~Inventory() { + for (int i = 0; i < INVENTORY_SIZE; i++) + delete mItems[i]; + delete [] mItems; } -Item* Inventory::getItem(int index) +Item* Inventory::getItem(int index) const { if (index < 0 || index >= INVENTORY_SIZE) - { return 0; - } - return &mItems[index]; + return mItems[index]; +} + +Item* Inventory::findItem(int itemId) const +{ + for (int i = 0; i < INVENTORY_SIZE; i++) + { + if (mItems[i] && mItems[i]->getId() == itemId) + return mItems[i]; + } + return NULL; } void Inventory::addItem(int id, int quantity, bool equipment) { - addItem(getFreeSlot(), id, quantity, equipment); + setItem(getFreeSlot(), id, quantity, equipment); } -void Inventory::addItem(int index, int id, int quantity, bool equipment) +void Inventory::setItem(int index, int id, int quantity, bool equipment) { if (index < 0 || index >= INVENTORY_SIZE) { logger->log("Warning: invalid inventory index: %d", index); return; } - mItems[index].setId(id); - + /* TODO: Check where to reenable this code. // Dont stack equipment other than arrows. if (equipment && !(id == 1199 || id == 529)) mItems[index].setQuantity(quantity); else mItems[index].increaseQuantity(quantity); - - mItems[index].setEquipment(equipment); + */ + + if (!mItems[index] && id > 0) { + Item *item = new Item(id, quantity, equipment); + item->setInvIndex(index); + mItems[index] = item; + } else if (id > 0) { + mItems[index]->setId(id); + mItems[index]->setQuantity(quantity); + mItems[index]->setEquipment(equipment); + } else if (mItems[index]) { + removeItemAt(index); + } } - void Inventory::clear() { for (int i = 0; i < INVENTORY_SIZE; i++) { - mItems[i].setId(-1); - mItems[i].setQuantity(0); - mItems[i].setEquipped(false); + removeItemAt(i); } } void Inventory::removeItem(int id) { for (int i = 0; i < INVENTORY_SIZE; i++) { - if (mItems[i].getId() == id) { - mItems[i].setId(-1); - mItems[i].setQuantity(0); - mItems[i].setEquipped(false); + if (mItems[i] && mItems[i]->getId() == id) { + removeItemAt(i); } } } -bool Inventory::contains(Item *item) +void Inventory::removeItemAt(int index) +{ + delete mItems[index]; + mItems[index] = 0; +} + +bool Inventory::contains(Item *item) const { for (int i = 0; i < INVENTORY_SIZE; i++) { - if (mItems[i].getId() == item->getId()) { + if (mItems[i] && mItems[i]->getId() == item->getId()) { return true; } } @@ -116,7 +136,7 @@ bool Inventory::contains(Item *item) int Inventory::getFreeSlot() { - Item *i = std::find_if(mItems + 2, mItems + INVENTORY_SIZE, + Item **i = std::find_if(mItems + 2, mItems + INVENTORY_SIZE, std::not1(SlotUsed())); return (i == mItems + INVENTORY_SIZE) ? -1 : (i - mItems); } diff --git a/src/inventory.h b/src/inventory.h index d5c3cf35..0d2bbc5a 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -44,7 +44,15 @@ class Inventory /** * Returns the item at the specified index. */ - Item* getItem(int index); + Item* getItem(int index) const; + + /** + * Searches for the specified item by it's id. + * + * @param itemId The id of the item to be searched. + * @return Item found on success, NULL on failure. + */ + Item* findItem(int itemId) const; /** * Adds a new item in a free slot. @@ -52,9 +60,9 @@ class Inventory void addItem(int id, int quantity, bool equipment); /** - * Adds a new item at a given position. + * Sets the item at the given position. */ - void addItem(int index, int id, int quantity, bool equipment); + void setItem(int index, int id, int quantity, bool equipment); /** * Remove a item from the inventory. @@ -62,9 +70,14 @@ class Inventory void removeItem(int id); /** + * Remove the item at the specified index from the inventory. + */ + void removeItemAt(int index); + + /** * Checks if the given item is in the inventory */ - bool contains(Item *item); + bool contains(Item *item) const; /** * Returns id of next free slot or -1 if all occupied. @@ -87,7 +100,7 @@ class Inventory int getLastUsedSlot(); protected: - Item *mItems; /**< The holder of items */ + Item **mItems; /**< The holder of items */ }; #endif diff --git a/src/item.cpp b/src/item.cpp index 3cea30e5..e84a06df 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -21,3 +21,38 @@ * $Id$ */ +#include "item.h" + +#include "resources/image.h" +#include "resources/resourcemanager.h" + +Item::Item(int id, int quantity, bool equipment, bool equipped): + mImage(0), + mQuantity(quantity), + mEquipment(equipment), + mEquipped(equipped) +{ + setId(id); +} + +Item::~Item() +{ + if (mImage) + mImage->decRef(); +} + +void Item::setId(int id) +{ + mId = id; + + // Load the associated image + if (mImage) + mImage->decRef(); + + ResourceManager *resman = ResourceManager::getInstance(); + std::string imagePath = "graphics/items/" + getInfo().getImageName(); + mImage = resman->getImage(imagePath); + + if (!mImage) + mImage = resman->getImage("graphics/gui/unknown-item.png"); +} @@ -26,6 +26,8 @@ #include "resources/itemdb.h" +class Image; + /** * Represents one or more instances of a certain item type. */ @@ -36,24 +38,18 @@ class Item * Constructor. */ Item(int id = -1, int quantity = 0, - bool equipment = false, bool equipped = false): - mId(id), - mQuantity(quantity), - mEquipment(equipment), - mEquipped(equipped) - { - } + bool equipment = false, bool equipped = false); /** * Destructor. */ - ~Item() {} + ~Item(); /** * Sets the item id, identifying the item type. */ void - setId(int id) { mId = id; } + setId(int id); /** * Returns the item id. @@ -62,6 +58,11 @@ class Item getId() const { return mId; } /** + * Returns the item image. + */ + Image* getImage() { return mImage; } + + /** * Sets the number of items. */ void @@ -123,6 +124,7 @@ class Item protected: int mId; /**< Item type id. */ + Image *mImage; /**< Item image. */ int mQuantity; /**< Number of items. */ bool mEquipment; /**< Item is equipment. */ bool mEquipped; /**< Item is equipped. */ diff --git a/src/itemshortcut.cpp b/src/itemshortcut.cpp index 1201b23b..a32e50e0 100644 --- a/src/itemshortcut.cpp +++ b/src/itemshortcut.cpp @@ -23,9 +23,10 @@ #include "itemshortcut.h" +#include "configuration.h" +#include "inventory.h" #include "item.h" #include "localplayer.h" -#include "configuration.h" #include "utils/tostring.h" @@ -78,9 +79,8 @@ void ItemShortcut::useItem(int index) { if (mItems[index]) { - Item *item = player_node->searchForItem(mItems[index]); - if (item && item->getQuantity()) { + Item *item = player_node->getInventory()->findItem(mItems[index]); + if (item && item->getQuantity()) player_node->useItem(item); - } } } diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 20f6b6a7..3929da8b 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -45,12 +45,12 @@ LocalPlayer::LocalPlayer(Uint32 id, Uint16 job, Map *map): Player(id, job, map), mXpForNextLevel(0), mAttackRange(0), - mInventory(new Inventory), mXp(0), mNetwork(0), mTarget(NULL), mPickUpTarget(NULL), mTrading(false), mGoingToTarget(false), mLastAction(-1), - mWalkingDir(0), mDestX(0), mDestY(0) + mWalkingDir(0), mDestX(0), mDestY(0), + mInventory(new Inventory) { } @@ -125,37 +125,6 @@ void LocalPlayer::nextStep() Player::nextStep(); } -void LocalPlayer::clearInventory() -{ - mInventory->clear(); -} - -void LocalPlayer::addInvItem(int id, int quantity, bool equipment) -{ - mInventory->addItem(id, quantity, equipment); -} - -void LocalPlayer::addInvItem(int index, int id, int quantity, bool equipment) -{ - mInventory->addItem(index, id, quantity, equipment); -} - -Item* LocalPlayer::getInvItem(int index) -{ - return mInventory->getItem(index); -} - -Item* LocalPlayer::searchForItem(int itemId) -{ - for (int i = 0; i < INVENTORY_SIZE; i++) - { - if (itemId == mInventory->getItem(i)->getId()) { - return mInventory->getItem(i); - } - } - return NULL; -} - void LocalPlayer::equipItem(Item *item) { MessageOut outMsg(mNetwork); @@ -173,7 +142,7 @@ void LocalPlayer::unequipItem(Item *item) outMsg.writeInt16(CMSG_PLAYER_UNEQUIP); outMsg.writeInt16(item->getInvIndex()); - // Tidy equipment directly to avoid weapon still shown bug, by instance + // Tidy equipment directly to avoid weapon still shown bug, for instance mEquipment->removeEquipment(item); } diff --git a/src/localplayer.h b/src/localplayer.h index bdf43fff..5ce94081 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -70,18 +70,10 @@ class LocalPlayer : public Player virtual void drawName(Graphics *graphics, Sint32 offsetX, Sint32 offsetY) {}; - void clearInventory(); - void addInvItem(int id, int quantity, bool equipment); - void addInvItem(int index, int id, int quantity, bool equipment); - Item* getInvItem(int index); - /** - * Searches for the specified item by it's identification. - * - * @param itemId The id of the item to be searched. - * @return Item found on success, NULL on failure. + * Returns the player's inventory. */ - Item* searchForItem(int itemId); + Inventory* getInventory() const { return mInventory; } /** * Equips an item. @@ -213,8 +205,6 @@ class LocalPlayer : public Player float mLastAttackTime; /**< Used to synchronize the charge dialog */ - Inventory *mInventory; - protected: void walk(unsigned char dir); @@ -230,6 +220,8 @@ class LocalPlayer : public Player int mWalkingDir; /**< The direction the player is walking in. */ int mDestX; /**< X coordinate of destination. */ int mDestY; /**< Y coordinate of destination. */ + + Inventory *mInventory; }; extern LocalPlayer *player_node; diff --git a/src/net/buysellhandler.cpp b/src/net/buysellhandler.cpp index d7f063a7..26261664 100644 --- a/src/net/buysellhandler.cpp +++ b/src/net/buysellhandler.cpp @@ -29,6 +29,7 @@ #include "protocol.h" #include "../beingmanager.h" +#include "../inventory.h" #include "../item.h" #include "../localplayer.h" #include "../npc.h" @@ -99,7 +100,7 @@ void BuySellHandler::handleMessage(MessageIn *msg) Sint32 value = msg->readInt32(); msg->readInt32(); // OCvalue - Item *item = player_node->getInvItem(index); + Item *item = player_node->getInventory()->getItem(index); if (item && !(item->isEquipped())) { sellDialog->addItem(item, value); } diff --git a/src/net/equipmenthandler.cpp b/src/net/equipmenthandler.cpp index 69f24d80..85790b42 100644 --- a/src/net/equipmenthandler.cpp +++ b/src/net/equipmenthandler.cpp @@ -28,6 +28,7 @@ #include "../beingmanager.h" #include "../equipment.h" +#include "../inventory.h" #include "../item.h" #include "../localplayer.h" #include "../log.h" @@ -54,6 +55,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg) Sint8 type; int mask, position; Item *item; + Inventory *inventory = player_node->getInventory(); switch (msg->getId()) { @@ -73,7 +75,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg) msg->readInt8(); // refine msg->skip(8); // card - player_node->addInvItem(index, itemId, 1, true); + inventory->setItem(index, itemId, 1, true); if (equipPoint) { @@ -84,7 +86,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg) mask <<= 1; position++; } - item = player_node->getInvItem(index); + item = inventory->getItem(index); player_node->mEquipment->setEquipment(position, item); } } @@ -120,7 +122,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg) item->setEquipped(false); } - item = player_node->getInvItem(index); + item = inventory->getItem(index); player_node->mEquipment->setEquipment(position, item); break; @@ -146,8 +148,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg) position++; } - item = player_node->getInvItem(index); - + item = inventory->getItem(index); if (!item) break; @@ -181,18 +182,18 @@ void EquipmentHandler::handleMessage(MessageIn *msg) break; case SMSG_PLAYER_ARROW_EQUIP: - itemId = msg->readInt16(); + index = msg->readInt16(); - if (itemId <= 1) + if (index <= 1) break; - item = player_node->getInvItem(itemId); + item = inventory->getItem(index); if (!item) break; item->setEquipped(true); player_node->mEquipment->setArrows(item); - logger->log("Arrows equipped: %i", itemId); + logger->log("Arrows equipped: %i", index); break; } } diff --git a/src/net/inventoryhandler.cpp b/src/net/inventoryhandler.cpp index a2190c1e..48cf18ff 100644 --- a/src/net/inventoryhandler.cpp +++ b/src/net/inventoryhandler.cpp @@ -32,9 +32,13 @@ #include "../item.h" #include "../itemshortcut.h" #include "../localplayer.h" +#include "../log.h" +#include "../inventory.h" #include "../gui/chat.h" +#include "../utils/tostring.h" + InventoryHandler::InventoryHandler() { static const Uint16 _messages[] = { @@ -52,13 +56,14 @@ void InventoryHandler::handleMessage(MessageIn *msg) { Sint32 number; Sint16 index, amount, itemId, equipType; + Inventory *inventory = player_node->getInventory(); switch (msg->getId()) { case SMSG_PLAYER_INVENTORY: // Only called on map load / warp. First reset all items // to not load them twice on map change. - player_node->clearInventory(); + inventory->clear(); msg->readInt16(); // length number = (msg->getLength() - 4) / 18; @@ -72,12 +77,13 @@ void InventoryHandler::handleMessage(MessageIn *msg) msg->skip(2); // unknown msg->skip(8); // card (4 shorts) - player_node->addInvItem(index, itemId, amount, false); + inventory->setItem(index, itemId, amount, false); // Trick because arrows are not considered equipment if (itemId == 1199 || itemId == 529) { - player_node->getInvItem(index)->setEquipment(true); + if (Item *item = inventory->getItem(index)) + item->setEquipment(true); } } break; @@ -93,20 +99,32 @@ void InventoryHandler::handleMessage(MessageIn *msg) equipType = msg->readInt16(); msg->readInt8(); // type - if (msg->readInt8()> 0) { + if (msg->readInt8() > 0) { chatWindow->chatLog("Unable to pick up item", BY_SERVER); } else { const ItemInfo &itemInfo = ItemDB::get(itemId); - chatWindow->chatLog("You picked up a " + + const std::string amountStr = + (amount > 1) ? toString(amount) : "a"; + chatWindow->chatLog("You picked up " + amountStr + " " + itemInfo.getName(), BY_SERVER); - player_node->addInvItem(index, itemId, amount, equipType != 0); + + if (Item *item = inventory->getItem(index)) { + item->setId(itemId); + item->increaseQuantity(amount); + } else { + inventory->setItem(index, itemId, amount, equipType != 0); + } } break; case SMSG_PLAYER_INVENTORY_REMOVE: index = msg->readInt16(); amount = msg->readInt16(); - player_node->getInvItem(index)->increaseQuantity(-amount); + if (Item *item = inventory->getItem(index)) { + item->increaseQuantity(-amount); + if (item->getQuantity() == 0) + inventory->removeItemAt(index); + } break; case SMSG_PLAYER_INVENTORY_USE: @@ -116,7 +134,8 @@ void InventoryHandler::handleMessage(MessageIn *msg) amount = msg->readInt16(); msg->readInt8(); // type - player_node->getInvItem(index)->setQuantity(amount); + if (Item *item = inventory->getItem(index)) + item->setQuantity(amount); break; case SMSG_ITEM_USE_RESPONSE: @@ -126,7 +145,8 @@ void InventoryHandler::handleMessage(MessageIn *msg) if (msg->readInt8() == 0) { chatWindow->chatLog("Failed to use item", BY_SERVER); } else { - player_node->getInvItem(index)->setQuantity(amount); + if (Item *item = inventory->getItem(index)) + item->setQuantity(amount); } break; } diff --git a/src/net/tradehandler.cpp b/src/net/tradehandler.cpp index 9b3c590e..85ab65c1 100644 --- a/src/net/tradehandler.cpp +++ b/src/net/tradehandler.cpp @@ -26,6 +26,7 @@ #include "messagein.h" #include "protocol.h" +#include "../inventory.h" #include "../item.h" #include "../localplayer.h" #include "../player_relations.h" @@ -157,7 +158,8 @@ void TradeHandler::handleMessage(MessageIn *msg) case SMSG_TRADE_ITEM_ADD_RESPONSE: // Trade: New Item add response (was 0x00ea, now 01b1) { - Item *item = player_node->getInvItem(msg->readInt16()); + const int index = msg->readInt16(); + Item *item = player_node->getInventory()->getItem(index); Sint16 quantity = msg->readInt16(); switch (msg->readInt8()) diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index e8ad393b..71bd898a 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -55,7 +55,7 @@ void ItemDB::load() mUnknown = new ItemInfo(); mUnknown->setName("Unknown item"); - mUnknown->setImage(""); + mUnknown->setImageName(""); mUnknown->setSprite("error.xml", 0); mUnknown->setSprite("error.xml", 1); @@ -97,7 +97,7 @@ void ItemDB::load() if (id) { ItemInfo *itemInfo = new ItemInfo(); - itemInfo->setImage(image); + itemInfo->setImageName(image); itemInfo->setName((name == "") ? "Unnamed" : name); itemInfo->setDescription(description); itemInfo->setEffect(effect); diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp index 82c46e3c..f1ebd0a9 100644 --- a/src/resources/iteminfo.cpp +++ b/src/resources/iteminfo.cpp @@ -23,36 +23,8 @@ #include "iteminfo.h" -#include "resourcemanager.h" -#include "image.h" #include "itemdb.h" -ItemInfo::~ItemInfo() -{ - if (mImage) - { - mImage->decRef(); - } -} - -void -ItemInfo::setImage(const std::string &image) -{ - if (mImage) - { - mImage->decRef(); - } - - ResourceManager *resman = ResourceManager::getInstance(); - mImageName = "graphics/items/" + image; - mImage = ResourceManager::getInstance()->getImage(mImageName); - - if (!mImage) - { - mImage = resman->getImage("graphics/gui/unknown-item.png"); - } -} - const std::string& ItemInfo::getSprite(int gender) const { diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h index 2726a012..680c8d61 100644 --- a/src/resources/iteminfo.h +++ b/src/resources/iteminfo.h @@ -30,8 +30,6 @@ #include "spritedef.h" -class Image; - enum EquipmentSoundEvent { EQUIP_EVENT_STRIKE, @@ -49,7 +47,6 @@ class ItemInfo * Constructor. */ ItemInfo(): - mImage(NULL), mType(0), mWeight(0), mView(0), @@ -57,21 +54,17 @@ class ItemInfo { } - /** - * Destructor. - */ - ~ItemInfo(); - void setName(const std::string &name) { mName = name; } const std::string& getName() const { return mName; } - void setImage(const std::string &image); + void setImageName(const std::string &imageName) + { mImageName = imageName; } - Image* getImage() const - { return mImage; } + const std::string& getImageName() const + { return mImageName; } void setDescription(const std::string &description) { mDescription = description; } @@ -116,13 +109,6 @@ class ItemInfo protected: std::string mImageName; /**< The filename of the icon image. */ - - /* TODO (BL): I do not think the item info should keep a reference to - * the item icon. It would probably be better if this was kept in the - * Item class, so that the images can be lazily instantiated and also - * unloaded when no longer used. - */ - Image *mImage; /**< The loaded icon image. */ std::string mName; std::string mDescription; /**< Short description. */ std::string mEffect; /**< Description of effects. */ diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index 9c109257..ef8671a8 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -98,11 +98,15 @@ ResourceManager::~ResourceManager() void ResourceManager::cleanUp(Resource *res) { - logger->log("ResourceManager::~ResourceManager() cleaning up %d " + if (res->mRefCount > 0) + { + logger->log("ResourceManager::~ResourceManager() cleaning up %d " "reference%s to %s", res->mRefCount, (res->mRefCount == 1) ? "" : "s", res->mIdPath.c_str()); + } + delete res; } diff --git a/src/shopitem.cpp b/src/shopitem.cpp new file mode 100644 index 00000000..ed5d30a9 --- /dev/null +++ b/src/shopitem.cpp @@ -0,0 +1,33 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "shopitem.h" + +#include "utils/tostring.h" + +ShopItem::ShopItem(int id, int quantity, int price): + Item(id, quantity), + mPrice(price) +{ + mDisplayName = getInfo().getName() + " (" + toString(mPrice) + " GP)"; +} diff --git a/src/shopitem.h b/src/shopitem.h new file mode 100644 index 00000000..ffafbebe --- /dev/null +++ b/src/shopitem.h @@ -0,0 +1,58 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _SHOPITEM_H_ +#define _SHOPITEM_H_ + +#include "item.h" + +/** + * Represents an item in a shop inventory. + */ +class ShopItem : public Item +{ + public: + /** + * Constructor. + */ + ShopItem(int id, int quantity, int price); + + /** + * Gets the price of the item. + */ + int getPrice() const + { return mPrice; } + + /** + * Gets the display name for in the shop list. + */ + const std::string& getDisplayName() const + { return mDisplayName; } + + protected: + int mPrice; + int mIndex; + std::string mDisplayName; +}; + +#endif |