diff options
author | Andrei Karas <akaras@inbox.ru> | 2015-11-02 18:10:42 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2015-11-02 18:10:42 +0300 |
commit | 2127361148d4ea5531a115cc92131a3f956ca528 (patch) | |
tree | 668182e046ff19bbacdc8cfc326bc2fab224b62b | |
parent | f89de74b1ac1cd9a02a70dab9221d601296da8cd (diff) | |
download | mv-2127361148d4ea5531a115cc92131a3f956ca528.tar.gz mv-2127361148d4ea5531a115cc92131a3f956ca528.tar.bz2 mv-2127361148d4ea5531a115cc92131a3f956ca528.tar.xz mv-2127361148d4ea5531a115cc92131a3f956ca528.zip |
Allow add items to npc inventory from same slot multiple times.
Added items automatically removed from inventory item amounts.
-rw-r--r-- | src/gui/widgets/itemcontainer.cpp | 10 | ||||
-rw-r--r-- | src/gui/windows/npcdialog.cpp | 18 | ||||
-rw-r--r-- | src/gui/windows/npcdialog.h | 2 | ||||
-rw-r--r-- | src/inventory.cpp | 51 | ||||
-rw-r--r-- | src/inventory.h | 9 |
5 files changed, 78 insertions, 12 deletions
diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp index 650911f9d..975b865d9 100644 --- a/src/gui/widgets/itemcontainer.cpp +++ b/src/gui/widgets/itemcontainer.cpp @@ -789,9 +789,13 @@ void ItemContainer::mouseReleased(MouseEvent &event) inventory = PlayerInfo::getInventory(); if (inventory) { - mInventory->addVirtualItem( - inventory->getItem(dragDrop.getTag()), - getSlotByXY(event.getX(), event.getY())); + Item *const item = inventory->getItem(dragDrop.getTag()); + if (mInventory->addVirtualItem( + item, + getSlotByXY(event.getX(), event.getY()))) + { + inventory->virtualRemove(item, 1); + } } return; } diff --git a/src/gui/windows/npcdialog.cpp b/src/gui/windows/npcdialog.cpp index 406e90c1a..539662f51 100644 --- a/src/gui/windows/npcdialog.cpp +++ b/src/gui/windows/npcdialog.cpp @@ -30,6 +30,7 @@ #include "soundmanager.h" #include "being/being.h" +#include "being/playerinfo.h" #include "gui/gui.h" #include "gui/viewport.h" @@ -367,6 +368,7 @@ void NpcDialog::action(const ActionEvent &event) } case NPC_INPUT_ITEM: { + restoreVirtuals(); if (!PacketLimiter::limitPackets( PacketType::PACKET_NPC_INPUT)) { @@ -414,6 +416,7 @@ void NpcDialog::action(const ActionEvent &event) } case NPC_INPUT_ITEM_INDEX: { + restoreVirtuals(); if (!PacketLimiter::limitPackets( PacketType::PACKET_NPC_INPUT)) { @@ -517,6 +520,7 @@ void NpcDialog::action(const ActionEvent &event) } else if (eventId == "close") { + restoreVirtuals(); if (mActionState == NPC_ACTION_INPUT) { switch (mInputState) @@ -541,7 +545,12 @@ void NpcDialog::action(const ActionEvent &event) else if (eventId == "add") { if (inventoryWindow) - mInventory->addVirtualItem(inventoryWindow->getSelectedItem(), 0); + { + Item *const item = inventoryWindow->getSelectedItem(); + Inventory *const inventory = PlayerInfo::getInventory(); + if (mInventory->addVirtualItem(item, 0) && inventory) + inventory->virtualRemove(item, 1); + } } else if (eventId.find("skin_") == 0) { @@ -1244,3 +1253,10 @@ void NpcDialog::createSkinControls() button->adjustSize(); } } + +void NpcDialog::restoreVirtuals() +{ + Inventory *const inventory = PlayerInfo::getInventory(); + if (inventory) + inventory->restoreVirtuals(); +} diff --git a/src/gui/windows/npcdialog.h b/src/gui/windows/npcdialog.h index ffe021bc6..584cbb6fe 100644 --- a/src/gui/windows/npcdialog.h +++ b/src/gui/windows/npcdialog.h @@ -248,6 +248,8 @@ class NpcDialog final : public Window, void deleteSkinControls(); + void restoreVirtuals(); + BeingId mNpcId; int mDefaultInt; diff --git a/src/inventory.cpp b/src/inventory.cpp index 61434754f..29df424e1 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -55,6 +55,7 @@ namespace Inventory::Inventory(const InventoryType::Type type, const int size1) : mInventoryListeners(), + mVirtualRemove(), mType(type), mSize(size1 == -1 ? static_cast<unsigned>( inventoryHandler->getSize(type)) @@ -364,18 +365,15 @@ int Inventory::findIndexByTag(const int tag) const return -1; } -void Inventory::addVirtualItem(const Item *const item, +bool Inventory::addVirtualItem(const Item *const item, int index) { if (item && !PlayerInfo::isItemProtected(item->getId())) { - if (findIndexByTag(item->getInvIndex()) != -1) - return; - - if (index >= 0 && - index < static_cast<int>(mSize) && - mItems[index] == nullptr) + if (index >= 0 && index < static_cast<int>(mSize)) { + if (mItems[index] != nullptr) + return false; setItem(index, item->getId(), item->getType(), @@ -401,8 +399,47 @@ void Inventory::addVirtualItem(const Item *const item, Equipm_false, Equipped_false); } + if (index == -1) + return false; + Item *const item2 = getItem(index); if (item2) item2->setTag(item->getInvIndex()); + return true; + } + return false; +} + +void Inventory::virtualRemove(Item *const item, + const int amount) +{ + if (!item || item->mQuantity < amount) + return; + + const int index = item->getInvIndex(); + const IntMapCIter it = mVirtualRemove.find(index); + if (it == mVirtualRemove.end()) + mVirtualRemove[index] = amount; + else + mVirtualRemove[index] += amount; + item->mQuantity -= amount; +} + +void Inventory::restoreVirtuals() +{ + const int sz = static_cast<int>(mSize); + + logger->log("Inventory::restoreVirtuals 1"); + FOR_EACH (IntMapCIter, it, mVirtualRemove) + { + logger->log("Inventory::restoreVirtuals 2"); + const int index = (*it).first; + if (index < 0 || index >= sz) + continue; + Item *const item = mItems[index]; + if (!item) + continue; + item->mQuantity += (*it).second; } + mVirtualRemove.clear(); } diff --git a/src/inventory.h b/src/inventory.h index 1d1f49ebe..995a8ef52 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -35,6 +35,8 @@ #include "enums/being/gender.h" +#include "utils/intmap.h" + #include <list> #include <string> @@ -174,15 +176,20 @@ class Inventory final int findIndexByTag(const int tag) const; - void addVirtualItem(const Item *const item, + bool addVirtualItem(const Item *const item, int index); + void virtualRemove(Item *const item, + const int amount); + + void restoreVirtuals(); protected: typedef std::list<InventoryListener*> InventoryListenerList; InventoryListenerList mInventoryListeners; void distributeSlotsChangedEvent(); + IntMap mVirtualRemove; InventoryType::Type mType; unsigned mSize; /**< The max number of inventory items */ Item **mItems; /**< The holder of items */ |