summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-11-02 18:10:42 +0300
committerAndrei Karas <akaras@inbox.ru>2015-11-02 18:10:42 +0300
commit2127361148d4ea5531a115cc92131a3f956ca528 (patch)
tree668182e046ff19bbacdc8cfc326bc2fab224b62b /src
parentf89de74b1ac1cd9a02a70dab9221d601296da8cd (diff)
downloadplus-2127361148d4ea5531a115cc92131a3f956ca528.tar.gz
plus-2127361148d4ea5531a115cc92131a3f956ca528.tar.bz2
plus-2127361148d4ea5531a115cc92131a3f956ca528.tar.xz
plus-2127361148d4ea5531a115cc92131a3f956ca528.zip
Allow add items to npc inventory from same slot multiple times.
Added items automatically removed from inventory item amounts.
Diffstat (limited to 'src')
-rw-r--r--src/gui/widgets/itemcontainer.cpp10
-rw-r--r--src/gui/windows/npcdialog.cpp18
-rw-r--r--src/gui/windows/npcdialog.h2
-rw-r--r--src/inventory.cpp51
-rw-r--r--src/inventory.h9
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 */