summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2015-08-27 16:07:33 +0300
committerAndrei Karas <akaras@inbox.ru>2015-08-27 16:07:33 +0300
commitf964252564162f70df2cda6b06b45245d0a383ad (patch)
tree7a7514d600d4a6f453477237deea3f6a52602cf2 /src
parentd1ed605d722ea17a9d5576bdb306b9f4680d646f (diff)
downloadmanaplus-f964252564162f70df2cda6b06b45245d0a383ad.tar.gz
manaplus-f964252564162f70df2cda6b06b45245d0a383ad.tar.bz2
manaplus-f964252564162f70df2cda6b06b45245d0a383ad.tar.xz
manaplus-f964252564162f70df2cda6b06b45245d0a383ad.zip
Move receive code from inventoryhandler into separate file.
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/Makefile.am6
-rw-r--r--src/net/ea/inventoryhandler.cpp232
-rw-r--r--src/net/ea/inventoryhandler.h28
-rw-r--r--src/net/ea/inventoryrecv.cpp257
-rw-r--r--src/net/ea/inventoryrecv.h69
-rw-r--r--src/net/eathena/inventoryhandler.cpp950
-rw-r--r--src/net/eathena/inventoryhandler.h69
-rw-r--r--src/net/eathena/inventoryrecv.cpp940
-rw-r--r--src/net/eathena/inventoryrecv.h72
-rw-r--r--src/net/tmwa/inventoryhandler.cpp439
-rw-r--r--src/net/tmwa/inventoryhandler.h19
-rw-r--r--src/net/tmwa/inventoryrecv.cpp464
-rw-r--r--src/net/tmwa/inventoryrecv.h46
14 files changed, 1944 insertions, 1653 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 471ff7c3f..7bb471242 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1371,6 +1371,8 @@ SET(SRCS_EVOL
net/ea/guildrecv.h
net/ea/inventoryhandler.cpp
net/ea/inventoryhandler.h
+ net/ea/inventoryrecv.cpp
+ net/ea/inventoryrecv.h
net/ea/itemhandler.cpp
net/ea/itemhandler.h
net/ea/loginhandler.cpp
@@ -1429,6 +1431,8 @@ SET(SRCS_TMWA
net/tmwa/guildrecv.h
net/tmwa/inventoryhandler.cpp
net/tmwa/inventoryhandler.h
+ net/tmwa/inventoryrecv.cpp
+ net/tmwa/inventoryrecv.h
net/tmwa/itemhandler.cpp
net/tmwa/itemhandler.h
net/tmwa/loginhandler.cpp
@@ -1611,6 +1615,8 @@ SET(SRCS_EATHENA
net/eathena/homunculusrecv.h
net/eathena/inventoryhandler.cpp
net/eathena/inventoryhandler.h
+ net/eathena/inventoryrecv.cpp
+ net/eathena/inventoryrecv.h
net/eathena/itemflags.h
net/eathena/itemhandler.cpp
net/eathena/itemhandler.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 9a5839036..493c521fd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1213,6 +1213,8 @@ manaplus_SOURCES += main.cpp \
net/ea/guildrecv.h \
net/ea/inventoryhandler.cpp \
net/ea/inventoryhandler.h \
+ net/ea/inventoryrecv.cpp \
+ net/ea/inventoryrecv.h \
net/ea/itemhandler.cpp \
net/ea/itemhandler.h \
net/ea/loginhandler.cpp \
@@ -1272,6 +1274,8 @@ manaplus_SOURCES += \
net/tmwa/guildrecv.h \
net/tmwa/inventoryhandler.cpp \
net/tmwa/inventoryhandler.h \
+ net/tmwa/inventoryrecv.cpp \
+ net/tmwa/inventoryrecv.h \
net/tmwa/itemhandler.cpp \
net/tmwa/itemhandler.h \
net/tmwa/loginhandler.cpp \
@@ -1457,6 +1461,8 @@ manaplus_SOURCES += gui/windows/bankwindow.cpp \
net/eathena/homunculusrecv.h \
net/eathena/inventoryhandler.cpp \
net/eathena/inventoryhandler.h \
+ net/eathena/inventoryrecv.cpp \
+ net/eathena/inventoryrecv.h \
net/eathena/itemflags.h \
net/eathena/itemhandler.cpp \
net/eathena/itemhandler.h \
diff --git a/src/net/ea/inventoryhandler.cpp b/src/net/ea/inventoryhandler.cpp
index b3821822e..e4409278c 100644
--- a/src/net/ea/inventoryhandler.cpp
+++ b/src/net/ea/inventoryhandler.cpp
@@ -36,6 +36,7 @@
#include "net/ea/eaprotocol.h"
#include "net/ea/equipbackend.h"
+#include "net/ea/inventoryrecv.h"
#include "utils/delete2.h"
@@ -43,50 +44,18 @@
#include "debug.h"
-const EquipSlot::Type EQUIP_POINTS[EquipSlot::VECTOREND] =
-{
- EquipSlot::LEGS_SLOT, // Lower Headgear
- EquipSlot::FIGHT1_SLOT, // Weapon
- EquipSlot::GLOVES_SLOT, // Garment
- EquipSlot::RING2_SLOT, // Accessory 1
- EquipSlot::RING1_SLOT, // Armor
- EquipSlot::FIGHT2_SLOT, // Shield
- EquipSlot::FEET_SLOT, // Footgear
- EquipSlot::NECK_SLOT, // Accessory 2
- EquipSlot::HEAD_SLOT, // Upper Headgear
- EquipSlot::TORSO_SLOT, // Middle Headgear
- EquipSlot::EVOL_RING1_SLOT, // Costume Top Headgear
- EquipSlot::EVOL_RING2_SLOT, // Costume Mid Headgear
- EquipSlot::PROJECTILE_SLOT, // Costume Low Headgear
- EquipSlot::COSTUME_ROBE_SLOT, // Costume Garment/Robe
- EquipSlot::MISSING1_SLOT, // Missing slot 1
- EquipSlot::MISSING2_SLOT, // Missing slot 2
- EquipSlot::SHADOW_ARMOR_SLOT, // Shadow Armor
- EquipSlot::SHADOW_WEAPON_SLOT, // Shadow Weapon
- EquipSlot::SHADOW_SHIELD_SLOT, // Shadow Shield
- EquipSlot::SHADOW_SHOES_SLOT, // Shadow Shoes
- EquipSlot::SHADOW_ACCESSORY2_SLOT, // Shadow Accessory 2
- EquipSlot::SHADOW_ACCESSORY1_SLOT, // Shadow Accessory 1
-};
-
namespace Ea
{
-EquipBackend InventoryHandler::mEquips;
-InventoryItems InventoryHandler::mInventoryItems;
-Inventory *InventoryHandler::mStorage = nullptr;
-PickupQueue InventoryHandler::mSentPickups;
-bool InventoryHandler::mDebugInventory = true;
-
InventoryHandler::InventoryHandler()
{
- mEquips.clear();
- mInventoryItems.clear();
- mStorage = nullptr;
+ InventoryRecv::mEquips.clear();
+ InventoryRecv::mInventoryItems.clear();
+ InventoryRecv::mStorage = nullptr;
storageWindow = nullptr;
- while (!mSentPickups.empty())
- mSentPickups.pop();
- mDebugInventory = true;
+ while (!InventoryRecv::mSentPickups.empty())
+ InventoryRecv::mSentPickups.pop();
+ InventoryRecv::mDebugInventory = true;
}
InventoryHandler::~InventoryHandler()
@@ -97,12 +66,12 @@ InventoryHandler::~InventoryHandler()
storageWindow = nullptr;
}
- delete2(mStorage);
+ delete2(InventoryRecv::mStorage);
}
void InventoryHandler::clear()
{
- delete2(mStorage);
+ delete2(InventoryRecv::mStorage);
}
bool InventoryHandler::canSplit(const Item *const item A_UNUSED) const
@@ -144,179 +113,6 @@ size_t InventoryHandler::getSize(const int type) const
return 0;
}
}
-int InventoryHandler::getSlot(const int eAthenaSlot)
-{
- if (eAthenaSlot == 0)
- return EquipSlot::VECTOREND;
-
- if (eAthenaSlot & 0x8000)
- return inventoryHandler->getProjectileSlot();
-
- unsigned int mask = 1;
- int position = 0;
- while (!(eAthenaSlot & mask))
- {
- mask <<= 1;
- position++;
- }
- return static_cast<int>(EQUIP_POINTS[position]);
-}
-
-void InventoryHandler::processPlayerInventoryRemove(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerInventoryRemove")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int amount = msg.readInt16("amount");
- if (inventory)
- {
- if (Item *const item = inventory->getItem(index))
- {
- item->increaseQuantity(-amount);
- if (item->getQuantity() == 0)
- inventory->removeItemAt(index);
- ArrowsListener::distributeEvent();
- }
- }
- BLOCK_END("InventoryHandler::processPlayerInventoryRemove")
-}
-
-void InventoryHandler::processPlayerInventoryUse(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerInventoryUse")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- msg.readInt16("item id");
- msg.readInt32("id?");
- const int amount = msg.readInt16("amount");
- msg.readUInt8("type");
-
- if (inventory)
- {
- if (Item *const item = inventory->getItem(index))
- {
- if (amount)
- item->setQuantity(amount);
- else
- inventory->removeItemAt(index);
- }
- }
- BLOCK_END("InventoryHandler::processPlayerInventoryUse")
-}
-
-void InventoryHandler::processItemUseResponse(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processItemUseResponse")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int amount = msg.readInt16("amount");
-
- if (msg.readUInt8("result") == 0)
- {
- NotifyManager::notify(NotifyTypes::USE_FAILED);
- }
- else
- {
- if (inventory)
- {
- if (Item *const item = inventory->getItem(index))
- {
- if (amount)
- item->setQuantity(amount);
- else
- inventory->removeItemAt(index);
- }
- }
- }
- BLOCK_END("InventoryHandler::processItemUseResponse")
-}
-
-void InventoryHandler::processPlayerStorageStatus(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerStorageStatus")
- /*
- * This is the closest we get to an "Open Storage" packet from the
- * server. It always comes after the two SMSG_PLAYER_STORAGE_...
- * packets that update storage contents.
- */
- msg.readInt16("used count");
- const int size = msg.readInt16("max size");
-
- if (!mStorage)
- mStorage = new Inventory(InventoryType::STORAGE, size);
-
- FOR_EACH (Ea::InventoryItems::const_iterator, it, mInventoryItems)
- {
- mStorage->setItem((*it).slot,
- (*it).id,
- (*it).type,
- (*it).quantity,
- (*it).refine,
- (*it).color,
- (*it).identified,
- (*it).damaged,
- (*it).favorite,
- (*it).equip,
- Equipped_false);
- }
- mInventoryItems.clear();
-
- if (!storageWindow)
- {
- CREATEWIDGETV(storageWindow, InventoryWindow, mStorage);
- }
- BLOCK_END("InventoryHandler::processPlayerStorageStatus")
-}
-
-void InventoryHandler::processPlayerStorageClose(Net::MessageIn &msg A_UNUSED)
-{
- BLOCK_START("InventoryHandler::processPlayerStorageClose")
- // Storage access has been closed
- // Storage window deletes itself
- if (storageWindow)
- {
- storageWindow->unsetInventory();
- storageWindow->close();
- }
- storageWindow = nullptr;
-
- if (mStorage)
- mStorage->clear();
-
- delete2(mStorage);
- BLOCK_END("InventoryHandler::processPlayerStorageClose")
-}
-
-void InventoryHandler::processPlayerAttackRange(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerAttackRange")
- const int range = msg.readInt16("range");
- if (localPlayer)
- localPlayer->setAttackRange(range);
- PlayerInfo::setStatBase(Attributes::ATTACK_RANGE, range);
- PlayerInfo::setStatMod(Attributes::ATTACK_RANGE, 0);
- BLOCK_END("InventoryHandler::processPlayerAttackRange")
-}
-
-void InventoryHandler::processPlayerArrowEquip(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerArrowEquip")
- int index = msg.readInt16("index");
- if (index <= 1)
- return;
-
- index -= INVENTORY_OFFSET;
- mEquips.setEquipment(inventoryHandler->getProjectileSlot(), index);
- ArrowsListener::distributeEvent();
- BLOCK_END("InventoryHandler::processPlayerArrowEquip")
-}
-
void InventoryHandler::destroyStorage()
{
BLOCK_START("InventoryHandler::closeStorage")
@@ -334,4 +130,14 @@ void InventoryHandler::forgotStorage()
storageWindow = nullptr;
}
+void InventoryHandler::pushPickup(const BeingId floorId)
+{
+ InventoryRecv::mSentPickups.push(floorId);
+}
+
+Inventory *InventoryHandler::getStorage() const
+{
+ return InventoryRecv::mStorage;
+}
+
} // namespace Ea
diff --git a/src/net/ea/inventoryhandler.h b/src/net/ea/inventoryhandler.h
index 29d24a1ac..3883ab0d4 100644
--- a/src/net/ea/inventoryhandler.h
+++ b/src/net/ea/inventoryhandler.h
@@ -68,40 +68,16 @@ class InventoryHandler notfinal : public Net::InventoryHandler
size_t getSize(const int type) const override final A_WARN_UNUSED;
- void pushPickup(const BeingId floorId)
- { mSentPickups.push(floorId); }
-
- static int getSlot(const int eAthenaSlot) A_WARN_UNUSED;
+ void pushPickup(const BeingId floorId);
void destroyStorage() override final;
void forgotStorage() override final;
- Inventory *getStorage() const override final
- { return mStorage; }
+ Inventory *getStorage() const override final;
protected:
InventoryHandler();
-
- static void processPlayerInventoryRemove(Net::MessageIn &msg);
-
- static void processPlayerInventoryUse(Net::MessageIn &msg);
-
- static void processItemUseResponse(Net::MessageIn &msg);
-
- static void processPlayerStorageStatus(Net::MessageIn &msg);
-
- static void processPlayerStorageClose(Net::MessageIn &msg);
-
- static void processPlayerAttackRange(Net::MessageIn &msg);
-
- static void processPlayerArrowEquip(Net::MessageIn &msg);
-
- static EquipBackend mEquips;
- static InventoryItems mInventoryItems;
- static Inventory *mStorage;
- static PickupQueue mSentPickups;
- static bool mDebugInventory;
};
} // namespace Ea
diff --git a/src/net/ea/inventoryrecv.cpp b/src/net/ea/inventoryrecv.cpp
new file mode 100644
index 000000000..810743d26
--- /dev/null
+++ b/src/net/ea/inventoryrecv.cpp
@@ -0,0 +1,257 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2015 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "net/ea/inventoryrecv.h"
+
+#include "notifymanager.h"
+
+#include "being/localplayer.h"
+
+#include "enums/equipslot.h"
+
+#include "enums/resources/notifytypes.h"
+
+#include "gui/widgets/createwidget.h"
+
+#include "net/messagein.h"
+
+#include "net/ea/eaprotocol.h"
+#include "net/ea/equipbackend.h"
+
+#include "utils/delete2.h"
+
+#include "listeners/arrowslistener.h"
+
+#include "debug.h"
+
+namespace Ea
+{
+
+namespace InventoryRecv
+{
+ const EquipSlot::Type EQUIP_POINTS[EquipSlot::VECTOREND] =
+ {
+ EquipSlot::LEGS_SLOT, // Lower Headgear
+ EquipSlot::FIGHT1_SLOT, // Weapon
+ EquipSlot::GLOVES_SLOT, // Garment
+ EquipSlot::RING2_SLOT, // Accessory 1
+ EquipSlot::RING1_SLOT, // Armor
+ EquipSlot::FIGHT2_SLOT, // Shield
+ EquipSlot::FEET_SLOT, // Footgear
+ EquipSlot::NECK_SLOT, // Accessory 2
+ EquipSlot::HEAD_SLOT, // Upper Headgear
+ EquipSlot::TORSO_SLOT, // Middle Headgear
+ EquipSlot::EVOL_RING1_SLOT, // Costume Top Headgear
+ EquipSlot::EVOL_RING2_SLOT, // Costume Mid Headgear
+ EquipSlot::PROJECTILE_SLOT, // Costume Low Headgear
+ EquipSlot::COSTUME_ROBE_SLOT, // Costume Garment/Robe
+ EquipSlot::MISSING1_SLOT, // Missing slot 1
+ EquipSlot::MISSING2_SLOT, // Missing slot 2
+ EquipSlot::SHADOW_ARMOR_SLOT, // Shadow Armor
+ EquipSlot::SHADOW_WEAPON_SLOT, // Shadow Weapon
+ EquipSlot::SHADOW_SHIELD_SLOT, // Shadow Shield
+ EquipSlot::SHADOW_SHOES_SLOT, // Shadow Shoes
+ EquipSlot::SHADOW_ACCESSORY2_SLOT, // Shadow Accessory 2
+ EquipSlot::SHADOW_ACCESSORY1_SLOT, // Shadow Accessory 1
+ };
+
+ EquipBackend mEquips;
+ InventoryItems mInventoryItems;
+ Inventory *mStorage = nullptr;
+ PickupQueue mSentPickups;
+ bool mDebugInventory = true;
+}
+
+void InventoryRecv::processPlayerInventoryRemove(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerInventoryRemove")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int amount = msg.readInt16("amount");
+ if (inventory)
+ {
+ if (Item *const item = inventory->getItem(index))
+ {
+ item->increaseQuantity(-amount);
+ if (item->getQuantity() == 0)
+ inventory->removeItemAt(index);
+ ArrowsListener::distributeEvent();
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerInventoryRemove")
+}
+
+void InventoryRecv::processPlayerInventoryUse(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerInventoryUse")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ msg.readInt16("item id");
+ msg.readInt32("id?");
+ const int amount = msg.readInt16("amount");
+ msg.readUInt8("type");
+
+ if (inventory)
+ {
+ if (Item *const item = inventory->getItem(index))
+ {
+ if (amount)
+ item->setQuantity(amount);
+ else
+ inventory->removeItemAt(index);
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerInventoryUse")
+}
+
+void InventoryRecv::processItemUseResponse(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processItemUseResponse")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int amount = msg.readInt16("amount");
+
+ if (msg.readUInt8("result") == 0)
+ {
+ NotifyManager::notify(NotifyTypes::USE_FAILED);
+ }
+ else
+ {
+ if (inventory)
+ {
+ if (Item *const item = inventory->getItem(index))
+ {
+ if (amount)
+ item->setQuantity(amount);
+ else
+ inventory->removeItemAt(index);
+ }
+ }
+ }
+ BLOCK_END("InventoryRecv::processItemUseResponse")
+}
+
+void InventoryRecv::processPlayerStorageStatus(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerStorageStatus")
+ /*
+ * This is the closest we get to an "Open Storage" packet from the
+ * server. It always comes after the two SMSG_PLAYER_STORAGE_...
+ * packets that update storage contents.
+ */
+ msg.readInt16("used count");
+ const int size = msg.readInt16("max size");
+
+ if (!mStorage)
+ mStorage = new Inventory(InventoryType::STORAGE, size);
+
+ FOR_EACH (Ea::InventoryItems::const_iterator, it, mInventoryItems)
+ {
+ mStorage->setItem((*it).slot,
+ (*it).id,
+ (*it).type,
+ (*it).quantity,
+ (*it).refine,
+ (*it).color,
+ (*it).identified,
+ (*it).damaged,
+ (*it).favorite,
+ (*it).equip,
+ Equipped_false);
+ }
+ mInventoryItems.clear();
+
+ if (!storageWindow)
+ {
+ CREATEWIDGETV(storageWindow, InventoryWindow, mStorage);
+ }
+ BLOCK_END("InventoryRecv::processPlayerStorageStatus")
+}
+
+void InventoryRecv::processPlayerStorageClose(Net::MessageIn &msg A_UNUSED)
+{
+ BLOCK_START("InventoryRecv::processPlayerStorageClose")
+ // Storage access has been closed
+ // Storage window deletes itself
+ if (storageWindow)
+ {
+ storageWindow->unsetInventory();
+ storageWindow->close();
+ }
+ storageWindow = nullptr;
+
+ if (mStorage)
+ mStorage->clear();
+
+ delete2(mStorage);
+ BLOCK_END("InventoryRecv::processPlayerStorageClose")
+}
+
+void InventoryRecv::processPlayerAttackRange(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerAttackRange")
+ const int range = msg.readInt16("range");
+ if (localPlayer)
+ localPlayer->setAttackRange(range);
+ PlayerInfo::setStatBase(Attributes::ATTACK_RANGE, range);
+ PlayerInfo::setStatMod(Attributes::ATTACK_RANGE, 0);
+ BLOCK_END("InventoryRecv::processPlayerAttackRange")
+}
+
+void InventoryRecv::processPlayerArrowEquip(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerArrowEquip")
+ int index = msg.readInt16("index");
+ if (index <= 1)
+ return;
+
+ index -= INVENTORY_OFFSET;
+ mEquips.setEquipment(inventoryHandler->getProjectileSlot(), index);
+ ArrowsListener::distributeEvent();
+ BLOCK_END("InventoryRecv::processPlayerArrowEquip")
+}
+
+int InventoryRecv::getSlot(const int eAthenaSlot)
+{
+ if (eAthenaSlot == 0)
+ return EquipSlot::VECTOREND;
+
+ if (eAthenaSlot & 0x8000)
+ return inventoryHandler->getProjectileSlot();
+
+ unsigned int mask = 1;
+ int position = 0;
+ while (!(eAthenaSlot & mask))
+ {
+ mask <<= 1;
+ position++;
+ }
+ return static_cast<int>(EQUIP_POINTS[position]);
+}
+
+} // namespace Ea
diff --git a/src/net/ea/inventoryrecv.h b/src/net/ea/inventoryrecv.h
new file mode 100644
index 000000000..b5ba2a4df
--- /dev/null
+++ b/src/net/ea/inventoryrecv.h
@@ -0,0 +1,69 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2015 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NET_EA_INVENTORYRECV_H
+#define NET_EA_INVENTORYRECV_H
+
+#include "localconsts.h"
+
+#include "enums/simpletypes/beingid.h"
+
+#include "net/inventoryhandler.h"
+
+#include "net/ea/inventoryitem.h"
+
+#include <queue>
+
+namespace Net
+{
+ class MessageIn;
+}
+
+namespace Ea
+{
+
+ class EquipBackend;
+
+ typedef std::vector<InventoryItem> InventoryItems;
+ typedef std::queue<BeingId> PickupQueue;
+
+ namespace InventoryRecv
+ {
+ extern EquipBackend mEquips;
+ extern InventoryItems mInventoryItems;
+ extern Inventory *mStorage;
+ extern PickupQueue mSentPickups;
+ extern bool mDebugInventory;
+
+ void processPlayerInventoryRemove(Net::MessageIn &msg);
+ void processPlayerInventoryUse(Net::MessageIn &msg);
+ void processItemUseResponse(Net::MessageIn &msg);
+ void processPlayerStorageStatus(Net::MessageIn &msg);
+ void processPlayerStorageClose(Net::MessageIn &msg);
+ void processPlayerAttackRange(Net::MessageIn &msg);
+ void processPlayerArrowEquip(Net::MessageIn &msg);
+
+ int getSlot(const int eAthenaSlot) A_WARN_UNUSED;
+ } // namespace InventoryRecv
+} // namespace Ea
+
+#endif // NET_EA_INVENTORYRECV_H
diff --git a/src/net/eathena/inventoryhandler.cpp b/src/net/eathena/inventoryhandler.cpp
index fd74ac11a..a6b16c466 100644
--- a/src/net/eathena/inventoryhandler.cpp
+++ b/src/net/eathena/inventoryhandler.cpp
@@ -39,6 +39,9 @@
#include "listeners/arrowslistener.h"
+#include "net/ea/inventoryrecv.h"
+
+#include "net/eathena/inventoryrecv.h"
#include "net/eathena/itemflags.h"
#include "net/eathena/menu.h"
#include "net/eathena/messageout.h"
@@ -80,8 +83,6 @@ const EquipSlot::Type EQUIP_CONVERT[] =
namespace EAthena
{
-Ea::InventoryItems InventoryHandler::mCartItems;
-
InventoryHandler::InventoryHandler() :
MessageHandler(),
Ea::InventoryHandler(),
@@ -134,7 +135,7 @@ InventoryHandler::InventoryHandler() :
handledMessages = _messages;
inventoryHandler = this;
- mCartItems.clear();
+ InventoryRecv::mCartItems.clear();
}
InventoryHandler::~InventoryHandler()
@@ -146,163 +147,163 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
switch (msg.getId())
{
case SMSG_PLAYER_INVENTORY:
- processPlayerInventory(msg);
+ InventoryRecv::processPlayerInventory(msg);
break;
case SMSG_PLAYER_STORAGE_ITEMS:
- processPlayerStorage(msg);
+ InventoryRecv::processPlayerStorage(msg);
break;
case SMSG_PLAYER_STORAGE_EQUIP:
- processPlayerStorageEquip(msg);
+ InventoryRecv::processPlayerStorageEquip(msg);
break;
case SMSG_PLAYER_INVENTORY_ADD:
- processPlayerInventoryAdd(msg);
+ InventoryRecv::processPlayerInventoryAdd(msg);
break;
case SMSG_PLAYER_INVENTORY_REMOVE:
- processPlayerInventoryRemove(msg);
+ Ea::InventoryRecv::processPlayerInventoryRemove(msg);
break;
case SMSG_PLAYER_INVENTORY_REMOVE2:
- processPlayerInventoryRemove2(msg);
+ InventoryRecv::processPlayerInventoryRemove2(msg);
break;
case SMSG_PLAYER_INVENTORY_USE:
- processPlayerInventoryUse(msg);
+ Ea::InventoryRecv::processPlayerInventoryUse(msg);
break;
case SMSG_ITEM_USE_RESPONSE:
- processItemUseResponse(msg);
+ Ea::InventoryRecv::processItemUseResponse(msg);
break;
case SMSG_PLAYER_STORAGE_STATUS:
- processPlayerStorageStatus(msg);
+ Ea::InventoryRecv::processPlayerStorageStatus(msg);
break;
case SMSG_PLAYER_STORAGE_ADD:
- processPlayerStorageAdd(msg);
+ InventoryRecv::processPlayerStorageAdd(msg);
break;
case SMSG_PLAYER_STORAGE_REMOVE:
- processPlayerStorageRemove(msg);
+ InventoryRecv::processPlayerStorageRemove(msg);
break;
case SMSG_PLAYER_STORAGE_CLOSE:
- processPlayerStorageClose(msg);
+ Ea::InventoryRecv::processPlayerStorageClose(msg);
break;
case SMSG_PLAYER_EQUIPMENT:
- processPlayerEquipment(msg);
+ InventoryRecv::processPlayerEquipment(msg);
break;
case SMSG_PLAYER_EQUIP:
- processPlayerEquip(msg);
+ InventoryRecv::processPlayerEquip(msg);
break;
case SMSG_PLAYER_UNEQUIP:
- processPlayerUnEquip(msg);
+ InventoryRecv::processPlayerUnEquip(msg);
break;
case SMSG_PLAYER_ATTACK_RANGE:
- processPlayerAttackRange(msg);
+ Ea::InventoryRecv::processPlayerAttackRange(msg);
break;
case SMSG_PLAYER_ARROW_EQUIP:
- processPlayerArrowEquip(msg);
+ Ea::InventoryRecv::processPlayerArrowEquip(msg);
break;
case SMSG_PLAYER_USE_CARD:
- processPlayerUseCard(msg);
+ InventoryRecv::processPlayerUseCard(msg);
break;
case SMSG_PLAYER_INSERT_CARD:
- processPlayerInsertCard(msg);
+ InventoryRecv::processPlayerInsertCard(msg);
break;
case SMSG_PLAYER_ITEM_RENTAL_TIME:
- processPlayerItemRentalTime(msg);
+ InventoryRecv::processPlayerItemRentalTime(msg);
break;
case SMSG_PLAYER_ITEM_RENTAL_EXPIRED:
- processPlayerItemRentalExpired(msg);
+ InventoryRecv::processPlayerItemRentalExpired(msg);
break;
case SMSG_CART_INFO:
- processCartInfo(msg);
+ InventoryRecv::processCartInfo(msg);
break;
case SMSG_CART_REMOVE:
- processCartRemove(msg);
+ InventoryRecv::processCartRemove(msg);
break;
case SMSG_PLAYER_CART_ADD:
- processPlayerCartAdd(msg);
+ InventoryRecv::processPlayerCartAdd(msg);
break;
case SMSG_PLAYER_CART_EQUIP:
- processPlayerCartEquip(msg);
+ InventoryRecv::processPlayerCartEquip(msg);
break;
case SMSG_PLAYER_CART_ITEMS:
- processPlayerCartItems(msg);
+ InventoryRecv::processPlayerCartItems(msg);
break;
case SMSG_PLAYER_CART_REMOVE:
- processPlayerCartRemove(msg);
+ InventoryRecv::processPlayerCartRemove(msg);
break;
case SMSG_PLAYER_IDENTIFY_LIST:
- processPlayerIdentifyList(msg);
+ InventoryRecv::processPlayerIdentifyList(msg);
break;
case SMSG_PLAYER_IDENTIFIED:
- processPlayerIdentified(msg);
+ InventoryRecv::processPlayerIdentified(msg);
break;
case SMSG_PLAYER_REFINE:
- processPlayerRefine(msg);
+ InventoryRecv::processPlayerRefine(msg);
break;
case SMSG_PLAYER_REPAIR_LIST:
- processPlayerRepairList(msg);
+ InventoryRecv::processPlayerRepairList(msg);
break;
case SMSG_PLAYER_REPAIR_EFFECT:
- processPlayerRepairEffect(msg);
+ InventoryRecv::processPlayerRepairEffect(msg);
break;
case SMSG_PLAYER_REFINE_LIST:
- processPlayerRefineList(msg);
+ InventoryRecv::processPlayerRefineList(msg);
break;
case SMSG_PLAYER_STORAGE_PASSWORD:
- processPlayerStoragePassword(msg);
+ InventoryRecv::processPlayerStoragePassword(msg);
break;
case SMSG_PLAYER_STORAGE_PASSWORD_RESULT:
- processPlayerStoragePasswordResult(msg);
+ InventoryRecv::processPlayerStoragePasswordResult(msg);
break;
case SMSG_PLAYER_COOKING_LIST:
- processPlayerCookingList(msg);
+ InventoryRecv::processPlayerCookingList(msg);
break;
case SMSG_ITEM_DAMAGED:
- processItemDamaged(msg);
+ InventoryRecv::processItemDamaged(msg);
break;
case SMSG_PLAYER_FAVORITE_ITEM:
- processFavoriteItem(msg);
+ InventoryRecv::processFavoriteItem(msg);
break;
case SMSG_PLAYER_CART_ADD_ERROR:
- processCartAddError(msg);
+ InventoryRecv::processCartAddError(msg);
break;
case SMSG_BIND_ITEM:
- processBindItem(msg);
+ InventoryRecv::processBindItem(msg);
break;
default:
@@ -431,467 +432,6 @@ void InventoryHandler::favoriteItem(const Item *const item,
outMsg.writeInt8(favorite, "favorite flag");
}
-void InventoryHandler::processPlayerEquipment(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerEquipment")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- msg.readInt16("len");
- Equipment *const equipment = PlayerInfo::getEquipment();
- if (equipment && !equipment->getBackend())
- { // look like SMSG_PLAYER_INVENTORY was not received
- mEquips.clear();
- equipment->setBackend(&mEquips);
- }
- const int number = (msg.getLength() - 4) / 31;
-
- for (int loop = 0; loop < number; loop++)
- {
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int itemId = msg.readInt16("item id");
- const int itemType = msg.readUInt8("item type");
- msg.readInt32("location");
- const int equipType = msg.readInt32("wear state");
- const uint8_t refine = static_cast<uint8_t>(msg.readInt8("refine"));
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
- msg.readInt32("hire expire date (?)");
- msg.readInt16("equip type");
- msg.readInt16("item sprite number");
- ItemFlags flags;
- flags.byte = msg.readUInt8("flags");
- if (inventory)
- {
- inventory->setItem(index,
- itemId,
- itemType,
- 1,
- refine,
- ItemColorManager::getColorFromCards(&cards[0]),
- fromBool(flags.bits.isIdentified, Identified),
- fromBool(flags.bits.isDamaged, Damaged),
- fromBool(flags.bits.isFavorite, Favorite),
- Equipm_true,
- Equipped_false);
- inventory->setCards(index, cards, 4);
- }
-
- if (equipType)
- mEquips.setEquipment(getSlot(equipType), index);
- }
- BLOCK_END("InventoryHandler::processPlayerEquipment")
-}
-
-void InventoryHandler::processPlayerInventoryAdd(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerInventoryAdd")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- if (PlayerInfo::getEquipment()
- && !PlayerInfo::getEquipment()->getBackend())
- { // look like SMSG_PLAYER_INVENTORY was not received
- mEquips.clear();
- PlayerInfo::getEquipment()->setBackend(&mEquips);
- }
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- int amount = msg.readInt16("count");
- const int itemId = msg.readInt16("item id");
- uint8_t identified = msg.readUInt8("identified");
- const uint8_t damaged = msg.readUInt8("is damaged");
- const uint8_t refine = msg.readUInt8("refine");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
- const int equipType = msg.readInt32("location");
- const int itemType = msg.readUInt8("item type");
- const unsigned char err = msg.readUInt8("result");
- msg.readInt32("hire expire date");
- msg.readInt16("bind on equip");
-
- const ItemColor color = ItemColorManager::getColorFromCards(&cards[0]);
- const ItemInfo &itemInfo = ItemDB::get(itemId);
- BeingId floorId;
- if (mSentPickups.empty())
- {
- floorId = BeingId_zero;
- }
- else
- {
- floorId = mSentPickups.front();
- mSentPickups.pop();
- }
-
- if (err)
- {
- PickupT pickup;
- switch (err)
- {
- case 1:
- pickup = Pickup::BAD_ITEM;
- break;
- case 2:
- pickup = Pickup::TOO_HEAVY;
- break;
- case 4:
- pickup = Pickup::INV_FULL;
- break;
- case 5:
- pickup = Pickup::MAX_AMOUNT;
- break;
- case 6:
- pickup = Pickup::TOO_FAR;
- break;
- case 7:
- pickup = Pickup::STACK_AMOUNT;
- break;
- default:
- pickup = Pickup::UNKNOWN;
- UNIMPLIMENTEDPACKET;
- break;
- }
- if (localPlayer)
- {
- localPlayer->pickedUp(itemInfo,
- 0,
- color,
- floorId,
- pickup);
- }
- }
- else
- {
- if (localPlayer)
- {
- localPlayer->pickedUp(itemInfo,
- amount,
- color,
- floorId,
- Pickup::OKAY);
- }
-
- if (inventory)
- {
- const Item *const item = inventory->getItem(index);
-
- if (item && item->getId() == itemId)
- amount += item->getQuantity();
-
- inventory->setItem(index,
- itemId,
- itemType,
- amount,
- refine,
- color,
- fromBool(identified, Identified),
- fromBool(damaged, Damaged),
- Favorite_false,
- fromBool(equipType, Equipm),
- Equipped_false);
- inventory->setCards(index, cards, 4);
- }
- ArrowsListener::distributeEvent();
- }
- BLOCK_END("InventoryHandler::processPlayerInventoryAdd")
-}
-
-void InventoryHandler::processPlayerInventory(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerInventory")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
- if (PlayerInfo::getEquipment())
- {
- // Clear inventory - this will be a complete refresh
- mEquips.clear();
- PlayerInfo::getEquipment()->setBackend(&mEquips);
- }
-
- if (inventory)
- inventory->clear();
-
- msg.readInt16("len");
-
- const int number = (msg.getLength() - 4) / 24;
-
- for (int loop = 0; loop < number; loop++)
- {
- const int index = msg.readInt16("item index") - INVENTORY_OFFSET;
- const int itemId = msg.readInt16("item id");
- const int itemType = msg.readUInt8("item type");
- const int amount = msg.readInt16("count");
- msg.readInt32("wear state / equip");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
- msg.readInt32("hire expire date (?)");
- ItemFlags flags;
- flags.byte = msg.readUInt8("flags");
-
- if (inventory)
- {
- inventory->setItem(index,
- itemId,
- itemType,
- amount,
- 0,
- ItemColorManager::getColorFromCards(&cards[0]),
- fromBool(flags.bits.isIdentified, Identified),
- fromBool(flags.bits.isDamaged, Damaged),
- fromBool(flags.bits.isFavorite, Favorite),
- Equipm_false,
- Equipped_false);
- inventory->setCards(index, cards, 4);
- }
- }
- BLOCK_END("InventoryHandler::processPlayerInventory")
-}
-
-void InventoryHandler::processPlayerStorage(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerInventory")
- mInventoryItems.clear();
-
- msg.readInt16("len");
- msg.readString(24, "storage name");
-
- const int number = (msg.getLength() - 4 - 24) / 24;
-
- for (int loop = 0; loop < number; loop++)
- {
- const int index = msg.readInt16("item index") - STORAGE_OFFSET;
- const int itemId = msg.readInt16("item id");
- const int itemType = msg.readUInt8("item type");
- const int amount = msg.readInt16("count");
- msg.readInt32("wear state / equip");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
- msg.readInt32("hire expire date (?)");
- ItemFlags flags;
- flags.byte = msg.readUInt8("flags");
-
- mInventoryItems.push_back(Ea::InventoryItem(index,
- itemId,
- itemType,
- cards,
- amount,
- 0,
- ItemColorManager::getColorFromCards(&cards[0]),
- fromBool(flags.bits.isIdentified, Identified),
- fromBool(flags.bits.isDamaged, Damaged),
- fromBool(flags.bits.isFavorite, Favorite),
- Equipm_false));
- }
- BLOCK_END("InventoryHandler::processPlayerInventory")
-}
-
-void InventoryHandler::processPlayerEquip(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerEquip")
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int equipType = msg.readInt32("wear location");
- msg.readInt16("sprite");
- const uint8_t flag = msg.readUInt8("result");
-
- switch (flag)
- {
- case 0:
- mEquips.setEquipment(getSlot(equipType), index);
- break;
- case 1:
- NotifyManager::notify(NotifyTypes::EQUIP_FAILED_LEVEL);
- break;
-
- case 2:
- default:
- NotifyManager::notify(NotifyTypes::EQUIP_FAILED);
- break;
- }
- BLOCK_END("InventoryHandler::processPlayerEquip")
-}
-
-void InventoryHandler::processPlayerUnEquip(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerUnEquip")
- msg.readInt16("index");
- const int equipType = msg.readInt32("wear location");
- const uint8_t flag = msg.readUInt8("result");
-
- // +++ need use UNEQUIP_FAILED event
- if (flag)
- NotifyManager::notify(NotifyTypes::EQUIP_FAILED);
- else
- mEquips.setEquipment(getSlot(equipType), -1);
- if (equipType & 0x8000)
- ArrowsListener::distributeEvent();
- BLOCK_END("InventoryHandler::processPlayerUnEquip")
-}
-
-void InventoryHandler::processPlayerInventoryRemove2(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerInventoryRemove2")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- // +++ here possible use particle or text/sound effects
- // for different reasons
- msg.readInt16("reason");
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int amount = msg.readInt16("amount");
- if (inventory)
- {
- if (Item *const item = inventory->getItem(index))
- {
- item->increaseQuantity(-amount);
- if (item->getQuantity() == 0)
- inventory->removeItemAt(index);
- ArrowsListener::distributeEvent();
- }
- }
- BLOCK_END("InventoryHandler::processPlayerInventoryRemove2")
-}
-
-void InventoryHandler::processPlayerStorageEquip(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerStorageEquip")
- msg.readInt16("len");
- const int number = (msg.getLength() - 4 - 24) / 31;
-
- msg.readString(24, "storage name");
- for (int loop = 0; loop < number; loop++)
- {
- const int index = msg.readInt16("index") - STORAGE_OFFSET;
- const int itemId = msg.readInt16("item id");
- const int itemType = msg.readUInt8("item type");
- const int amount = 1;
- msg.readInt32("location");
- msg.readInt32("wear state");
- const uint8_t refine = msg.readUInt8("refine level");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
- msg.readInt32("hire expire date");
- msg.readInt16("bind on equip");
- msg.readInt16("sprite");
- ItemFlags flags;
- flags.byte = msg.readUInt8("flags");
-
- mInventoryItems.push_back(Ea::InventoryItem(index,
- itemId,
- itemType,
- cards,
- amount,
- refine,
- ItemColorManager::getColorFromCards(&cards[0]),
- fromBool(flags.bits.isIdentified, Identified),
- fromBool(flags.bits.isDamaged, Damaged),
- fromBool(flags.bits.isFavorite, Favorite),
- Equipm_false));
- }
- BLOCK_END("InventoryHandler::processPlayerStorageEquip")
-}
-
-void InventoryHandler::processPlayerStorageAdd(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerStorageAdd")
- // Move an item into storage
- const int index = msg.readInt16("index") - STORAGE_OFFSET;
- const int amount = msg.readInt32("amount");
- const int itemId = msg.readInt16("item id");
- const int itemType = msg.readUInt8("type");
- const unsigned char identified = msg.readUInt8("identify");
- const Damaged damaged = fromBool(msg.readUInt8("attribute"), Damaged);
- const uint8_t refine = msg.readUInt8("refine");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
-
- const ItemColor color = ItemColorManager::getColorFromCards(&cards[0]);
- if (Item *const item = mStorage->getItem(index))
- {
- item->setId(itemId, color);
- item->increaseQuantity(amount);
- }
- else
- {
- if (mStorage)
- {
- mStorage->setItem(index,
- itemId,
- itemType,
- amount,
- refine,
- color,
- fromBool(identified, Identified),
- damaged,
- Favorite_false,
- Equipm_false,
- Equipped_false);
- mStorage->setCards(index, cards, 4);
- }
- }
- BLOCK_END("InventoryHandler::processPlayerStorageAdd")
-}
-
-void InventoryHandler::processPlayerUseCard(Net::MessageIn &msg)
-{
- const Inventory *const inv = PlayerInfo::getInventory();
- const int index = inventoryHandler->getItemIndex();
- const Item *item1 = nullptr;
- if (inv)
- item1 = inv->getItem(index);
- SellDialog *const dialog = CREATEWIDGETR(InsertCardDialog,
- index, item1);
-
- const int count = (msg.readInt16("len") - 4) / 2;
- for (int f = 0; f < count; f ++)
- {
- const int itemIndex = msg.readInt16("item index") - INVENTORY_OFFSET;
- if (!inv)
- continue;
- const Item *const item = inv->getItem(itemIndex);
- if (!item)
- continue;
- dialog->addItem(item, 0);
- }
-}
-
-void InventoryHandler::processPlayerInsertCard(Net::MessageIn &msg)
-{
- const int itemIndex = msg.readInt16("item index") - INVENTORY_OFFSET;
- const int cardIndex = msg.readInt16("card index") - INVENTORY_OFFSET;
- if (msg.readUInt8("flag"))
- {
- NotifyManager::notify(NotifyTypes::CARD_INSERT_FAILED);
- }
- else
- {
- NotifyManager::notify(NotifyTypes::CARD_INSERT_SUCCESS);
- Inventory *const inv = PlayerInfo::getInventory();
- if (!inv)
- return;
- Item *const card = inv->getItem(cardIndex);
- int cardId = 0;
- if (card)
- {
- cardId = card->getId();
- card->increaseQuantity(-1);
- if (card->getQuantity() == 0)
- inv->removeItemAt(cardIndex);
- }
- Item *const item = inv->getItem(itemIndex);
- if (item)
- {
- item->addCard(cardId);
- item->updateColor();
- itemPopup->resetPopup();
- }
- }
-}
-
void InventoryHandler::selectEgg(const Item *const item) const
{
if (!item)
@@ -902,40 +442,6 @@ void InventoryHandler::selectEgg(const Item *const item) const
menu = MenuType::Unknown;
}
-void InventoryHandler::processPlayerItemRentalTime(Net::MessageIn &msg)
-{
- const int id = msg.readInt16("item id");
- const int seconds = msg.readInt32("seconds");
- const ItemInfo &info = ItemDB::get(id);
- const std::string timeStr = timeDiffToString(seconds);
- NotifyManager::notify(NotifyTypes::RENTAL_TIME_LEFT,
- // TRANSLATORS: notification message
- strprintf(_("Left %s rental time for item %s."),
- timeStr.c_str(), info.getName().c_str()));
-}
-
-void InventoryHandler::processPlayerItemRentalExpired(Net::MessageIn &msg)
-{
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int id = msg.readInt16("item id");
- const ItemInfo &info = ItemDB::get(id);
-
- NotifyManager::notify(NotifyTypes::RENTAL_TIME_EXPIRED,
- info.getName());
- if (inventory)
- {
- if (Item *const item = inventory->getItem(index))
- {
- item->increaseQuantity(-item->getQuantity());
- inventory->removeItemAt(index);
- ArrowsListener::distributeEvent();
- }
- }
-}
-
int InventoryHandler::convertFromServerSlot(const int serverSlot) const
{
if (serverSlot < 0 || serverSlot > 15)
@@ -944,372 +450,4 @@ int InventoryHandler::convertFromServerSlot(const int serverSlot) const
return static_cast<int>(EQUIP_CONVERT[serverSlot]);
}
-void InventoryHandler::processPlayerStorageRemove(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerStorageRemove")
- // Move an item out of storage
- const int index = msg.readInt16("index") - STORAGE_OFFSET;
- const int amount = msg.readInt32("amount");
- if (mStorage)
- {
- if (Item *const item = mStorage->getItem(index))
- {
- item->increaseQuantity(-amount);
- if (item->getQuantity() == 0)
- mStorage->removeItemAt(index);
- }
- }
- BLOCK_END("InventoryHandler::processPlayerStorageRemove")
-}
-
-void InventoryHandler::processCartInfo(Net::MessageIn &msg)
-{
- msg.readInt16("cart items used");
- const int size = msg.readInt16("max cart items");
- PlayerInfo::setAttribute(Attributes::CART_TOTAL_WEIGHT,
- msg.readInt32("cart weight"));
- PlayerInfo::setAttribute(Attributes::CART_MAX_WEIGHT,
- msg.readInt32("max cart weight"));
- if (mCartItems.empty())
- return;
-
- Inventory *const inv = PlayerInfo::getCartInventory();
- if (!inv)
- return;
-
- inv->resize(size);
-
- FOR_EACH (Ea::InventoryItems::const_iterator, it, mCartItems)
- {
- inv->setItem((*it).slot,
- (*it).id,
- (*it).type,
- (*it).quantity,
- (*it).refine,
- (*it).color,
- (*it).identified,
- (*it).damaged,
- (*it).favorite,
- (*it).equip,
- Equipped_false);
- }
- mCartItems.clear();
-}
-
-void InventoryHandler::processCartRemove(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
- // +++ need close or clear cart?
-}
-
-void InventoryHandler::processPlayerCartAdd(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerCartAdd")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getCartInventory() : nullptr;
-
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- int amount = msg.readInt32("count");
- const int itemId = msg.readInt16("item id");
- const int itemType = msg.readUInt8("item type");
- uint8_t identified = msg.readUInt8("identified");
- const Damaged damaged = fromBool(msg.readUInt8("attribute"), Damaged);
- const uint8_t refine = msg.readUInt8("refine");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
-
- if (inventory)
- {
- const Item *const item = inventory->getItem(index);
-
- if (item && item->getId() == itemId)
- amount += item->getQuantity();
-
- inventory->setItem(index,
- itemId,
- itemType,
- amount,
- refine,
- ItemColorManager::getColorFromCards(&cards[0]),
- fromBool(identified, Identified),
- damaged,
- Favorite_false,
- Equipm_false,
- Equipped_false);
- inventory->setCards(index, cards, 4);
- }
- BLOCK_END("InventoryHandler::processPlayerCartAdd")
-}
-
-void InventoryHandler::processPlayerCartEquip(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerCartEquip")
- msg.readInt16("len");
- const int number = (msg.getLength() - 4) / 31;
- for (int loop = 0; loop < number; loop++)
- {
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int itemId = msg.readInt16("item id");
- const int itemType = msg.readUInt8("item type");
- const int amount = 1;
- msg.readInt32("location");
- msg.readInt32("wear state");
- const uint8_t refine = msg.readUInt8("refine level");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
- msg.readInt32("hire expire date");
- msg.readInt16("bind on equip");
- msg.readInt16("sprite");
- ItemFlags flags;
- flags.byte = msg.readUInt8("flags");
-
- mCartItems.push_back(Ea::InventoryItem(index,
- itemId,
- itemType,
- cards,
- amount,
- refine,
- ItemColorManager::getColorFromCards(&cards[0]),
- fromBool(flags.bits.isIdentified, Identified),
- fromBool(flags.bits.isDamaged, Damaged),
- fromBool(flags.bits.isFavorite, Favorite),
- Equipm_false));
- }
- BLOCK_END("InventoryHandler::processPlayerCartEquip")
-}
-
-void InventoryHandler::processPlayerCartItems(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerCartItems")
- mInventoryItems.clear();
-
- msg.readInt16("len");
- const int number = (msg.getLength() - 4) / 23;
-
- for (int loop = 0; loop < number; loop++)
- {
- const int index = msg.readInt16("item index") - INVENTORY_OFFSET;
- const int itemId = msg.readInt16("item id");
- const int itemType = msg.readUInt8("item type");
- const int amount = msg.readInt16("count");
- msg.readInt32("wear state / equip");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
- msg.readInt32("hire expire date (?)");
- ItemFlags flags;
- flags.byte = msg.readUInt8("flags");
-
- mCartItems.push_back(Ea::InventoryItem(index,
- itemId,
- itemType,
- cards,
- amount,
- 0,
- ItemColorManager::getColorFromCards(&cards[0]),
- fromBool(flags.bits.isIdentified, Identified),
- fromBool(flags.bits.isDamaged, Damaged),
- fromBool(flags.bits.isFavorite, Favorite),
- Equipm_false));
- }
- BLOCK_END("InventoryHandler::processPlayerCartItems")
-}
-
-void InventoryHandler::processPlayerCartRemove(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerCartRemove")
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int amount = msg.readInt32("amount");
-
- Inventory *const inv = PlayerInfo::getCartInventory();
- if (!inv)
- return;
-
- if (Item *const item = inv->getItem(index))
- {
- item->increaseQuantity(-amount);
- if (item->getQuantity() == 0)
- inv->removeItemAt(index);
- }
- BLOCK_END("InventoryHandler::processPlayerCartRemove")
-}
-
-void InventoryHandler::processPlayerIdentifyList(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- menu = MenuType::Identify;
- const int count = msg.readInt16("len") - 4;
- for (int f = 0; f < count; f ++)
- msg.readInt16("inv index");
-}
-
-void InventoryHandler::processPlayerIdentified(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- msg.readInt16("inv index");
- msg.readUInt8("flag");
-}
-
-void InventoryHandler::processPlayerRefine(Net::MessageIn &msg)
-{
- const int flag = msg.readInt16("flag");
- const int index = msg.readInt16("inv index") - INVENTORY_OFFSET;
- msg.readInt16("refine");
- const Inventory *const inv = PlayerInfo::getInventory();
- const Item *item = nullptr;
- int notifyType;
- std::string message;
- std::string itemName;
- if (inv)
- item = inv->getItem(index);
- if (item)
- {
- itemName = item->getName();
- }
- else
- {
- // TRANSLATORS: unknown item
- itemName = _("Unknown item");
- }
- switch (flag)
- {
- case 0:
- notifyType = NotifyTypes::REFINE_SUCCESS;
- break;
- case 1:
- notifyType = NotifyTypes::REFINE_FAILURE;
- break;
- case 2:
- notifyType = NotifyTypes::REFINE_DOWNGRADE;
- break;
- default:
- UNIMPLIMENTEDPACKET;
- notifyType = NotifyTypes::REFINE_UNKNOWN;
- break;
- }
- NotifyManager::notify(notifyType, itemName);
-}
-
-void InventoryHandler::processPlayerRepairList(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- const int count = (msg.readInt16("len") - 4) / 13;
- for (int f = 0; f < count; f ++)
- {
- msg.readInt16("index");
- msg.readInt16("item id");
- msg.readUInt8("refine");
- for (int d = 0; d < 4; d ++)
- msg.readInt16("card");
- }
- menu = MenuType::RepairWespon;
-}
-
-void InventoryHandler::processPlayerRepairEffect(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- msg.readInt16("item index");
- msg.readUInt8("flag");
-}
-
-void InventoryHandler::processPlayerRefineList(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- const int count = (msg.readInt16("len") - 4) / 13;
-
- for (int f = 0; f < count; f ++)
- {
- msg.readInt16("item index");
- msg.readInt16("item id");
- msg.readUInt8("refine");
- for (int d = 0; d < 4; d ++)
- msg.readInt16("card");
- }
- menu = MenuType::WeaponeRefine;
-}
-
-void InventoryHandler::processPlayerStoragePassword(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- msg.readInt16("info");
-}
-
-void InventoryHandler::processPlayerStoragePasswordResult(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- msg.readInt16("result");
- msg.readInt16("error count");
-}
-
-void InventoryHandler::processPlayerCookingList(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- const int count = (msg.readInt16("len") - 6) / 2;
- msg.readInt16("list type");
- for (int f = 0; f < count; f ++)
- msg.readInt16("item id");
-}
-
-void InventoryHandler::processItemDamaged(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- msg.readInt16("position");
- msg.readBeingId("account id");
-}
-
-void InventoryHandler::processFavoriteItem(Net::MessageIn &msg)
-{
- UNIMPLIMENTEDPACKET;
-
- msg.readInt16("item index");
- msg.readUInt8("favorite (0 - favorite)");
-}
-
-void InventoryHandler::processCartAddError(Net::MessageIn &msg)
-{
- switch(msg.readUInt8("flag"))
- {
- case 0:
- NotifyManager::notify(NotifyTypes::CART_ADD_WEIGHT_ERROR);
- break;
- case 1:
- NotifyManager::notify(NotifyTypes::CART_ADD_COUNT_ERROR);
- break;
- default:
- break;
- }
-}
-
-void InventoryHandler::processBindItem(Net::MessageIn &msg)
-{
- const int index = msg.readInt16("item index") - INVENTORY_OFFSET;
- const Inventory *const inv = PlayerInfo::getInventory();
- if (inv)
- {
- std::string itemName;
- const Item *item = inv->getItem(index);
- if (item)
- {
- itemName = item->getName();
- }
- else
- {
- // TRANSLATORS: unknown item message
- itemName = _("Unknown item");
- }
- NotifyManager::notify(NotifyTypes::BOUND_ITEM, itemName);
- }
-}
-
} // namespace EAthena
diff --git a/src/net/eathena/inventoryhandler.h b/src/net/eathena/inventoryhandler.h
index c593a2c67..b234aada7 100644
--- a/src/net/eathena/inventoryhandler.h
+++ b/src/net/eathena/inventoryhandler.h
@@ -77,75 +77,6 @@ class InventoryHandler final : public MessageHandler,
int getItemIndex() const override final A_WARN_UNUSED
{ return mItemIndex; }
- protected:
- static void processPlayerEquipment(Net::MessageIn &msg);
-
- static void processPlayerInventoryAdd(Net::MessageIn &msg);
-
- static void processPlayerInventory(Net::MessageIn &msg);
-
- static void processPlayerStorage(Net::MessageIn &msg);
-
- static void processPlayerEquip(Net::MessageIn &msg);
-
- static void processPlayerUnEquip(Net::MessageIn &msg);
-
- static void processPlayerInventoryRemove2(Net::MessageIn &msg);
-
- static void processPlayerStorageEquip(Net::MessageIn &msg);
-
- static void processPlayerStorageAdd(Net::MessageIn &msg);
-
- static void processPlayerUseCard(Net::MessageIn &msg);
-
- static void processPlayerInsertCard(Net::MessageIn &msg);
-
- static void processPlayerItemRentalTime(Net::MessageIn &msg);
-
- static void processPlayerItemRentalExpired(Net::MessageIn &msg);
-
- static void processPlayerStorageRemove(Net::MessageIn &msg);
-
- static void processCartInfo(Net::MessageIn &msg);
-
- static void processCartRemove(Net::MessageIn &msg);
-
- static void processPlayerCartAdd(Net::MessageIn &msg);
-
- static void processPlayerCartEquip(Net::MessageIn &msg);
-
- static void processPlayerCartItems(Net::MessageIn &msg);
-
- static void processPlayerCartRemove(Net::MessageIn &msg);
-
- static void processPlayerIdentifyList(Net::MessageIn &msg);
-
- static void processPlayerIdentified(Net::MessageIn &msg);
-
- static void processPlayerRefine(Net::MessageIn &msg);
-
- static void processPlayerRepairList(Net::MessageIn &msg);
-
- static void processPlayerRepairEffect(Net::MessageIn &msg);
-
- static void processPlayerRefineList(Net::MessageIn &msg);
-
- static void processPlayerStoragePassword(Net::MessageIn &msg);
-
- static void processPlayerStoragePasswordResult(Net::MessageIn &msg);
-
- static void processPlayerCookingList(Net::MessageIn &msg);
-
- static void processItemDamaged(Net::MessageIn &msg);
-
- static void processFavoriteItem(Net::MessageIn &msg);
-
- static void processCartAddError(Net::MessageIn &msg);
-
- static void processBindItem(Net::MessageIn &msg);
-
- static Ea::InventoryItems mCartItems;
-
private:
int mItemIndex;
};
diff --git a/src/net/eathena/inventoryrecv.cpp b/src/net/eathena/inventoryrecv.cpp
new file mode 100644
index 000000000..186e34cbd
--- /dev/null
+++ b/src/net/eathena/inventoryrecv.cpp
@@ -0,0 +1,940 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2015 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "net/eathena/inventoryrecv.h"
+
+#include "notifymanager.h"
+#include "itemcolormanager.h"
+
+#include "being/localplayer.h"
+
+#include "enums/equipslot.h"
+
+#include "enums/resources/notifytypes.h"
+
+#include "gui/popups/itempopup.h"
+
+#include "gui/widgets/createwidget.h"
+
+#include "gui/windows/insertcarddialog.h"
+
+#include "listeners/arrowslistener.h"
+
+#include "net/eathena/itemflags.h"
+#include "net/eathena/menu.h"
+#include "net/eathena/messageout.h"
+#include "net/eathena/protocol.h"
+
+#include "net/ea/eaprotocol.h"
+#include "net/ea/equipbackend.h"
+#include "net/ea/inventoryrecv.h"
+
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include "debug.h"
+
+namespace EAthena
+{
+
+namespace InventoryRecv
+{
+ Ea::InventoryItems mCartItems;
+}
+
+void InventoryRecv::processPlayerEquipment(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerEquipment")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ msg.readInt16("len");
+ Equipment *const equipment = PlayerInfo::getEquipment();
+ if (equipment && !equipment->getBackend())
+ { // look like SMSG_PLAYER_INVENTORY was not received
+ Ea::InventoryRecv::mEquips.clear();
+ equipment->setBackend(&Ea::InventoryRecv::mEquips);
+ }
+ const int number = (msg.getLength() - 4) / 31;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const int itemType = msg.readUInt8("item type");
+ msg.readInt32("location");
+ const int equipType = msg.readInt32("wear state");
+ const uint8_t refine = static_cast<uint8_t>(msg.readInt8("refine"));
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+ msg.readInt32("hire expire date (?)");
+ msg.readInt16("equip type");
+ msg.readInt16("item sprite number");
+ ItemFlags flags;
+ flags.byte = msg.readUInt8("flags");
+ if (inventory)
+ {
+ inventory->setItem(index,
+ itemId,
+ itemType,
+ 1,
+ refine,
+ ItemColorManager::getColorFromCards(&cards[0]),
+ fromBool(flags.bits.isIdentified, Identified),
+ fromBool(flags.bits.isDamaged, Damaged),
+ fromBool(flags.bits.isFavorite, Favorite),
+ Equipm_true,
+ Equipped_false);
+ inventory->setCards(index, cards, 4);
+ }
+
+ if (equipType)
+ {
+ Ea::InventoryRecv::mEquips.setEquipment(
+ Ea::InventoryRecv::getSlot(equipType), index);
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerEquipment")
+}
+
+void InventoryRecv::processPlayerInventoryAdd(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerInventoryAdd")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ if (PlayerInfo::getEquipment()
+ && !PlayerInfo::getEquipment()->getBackend())
+ { // look like SMSG_PLAYER_INVENTORY was not received
+ Ea::InventoryRecv::mEquips.clear();
+ PlayerInfo::getEquipment()->setBackend(&Ea::InventoryRecv::mEquips);
+ }
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ int amount = msg.readInt16("count");
+ const int itemId = msg.readInt16("item id");
+ uint8_t identified = msg.readUInt8("identified");
+ const uint8_t damaged = msg.readUInt8("is damaged");
+ const uint8_t refine = msg.readUInt8("refine");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+ const int equipType = msg.readInt32("location");
+ const int itemType = msg.readUInt8("item type");
+ const unsigned char err = msg.readUInt8("result");
+ msg.readInt32("hire expire date");
+ msg.readInt16("bind on equip");
+
+ const ItemColor color = ItemColorManager::getColorFromCards(&cards[0]);
+ const ItemInfo &itemInfo = ItemDB::get(itemId);
+ BeingId floorId;
+ if (Ea::InventoryRecv::mSentPickups.empty())
+ {
+ floorId = BeingId_zero;
+ }
+ else
+ {
+ floorId = Ea::InventoryRecv::mSentPickups.front();
+ Ea::InventoryRecv::mSentPickups.pop();
+ }
+
+ if (err)
+ {
+ PickupT pickup;
+ switch (err)
+ {
+ case 1:
+ pickup = Pickup::BAD_ITEM;
+ break;
+ case 2:
+ pickup = Pickup::TOO_HEAVY;
+ break;
+ case 4:
+ pickup = Pickup::INV_FULL;
+ break;
+ case 5:
+ pickup = Pickup::MAX_AMOUNT;
+ break;
+ case 6:
+ pickup = Pickup::TOO_FAR;
+ break;
+ case 7:
+ pickup = Pickup::STACK_AMOUNT;
+ break;
+ default:
+ pickup = Pickup::UNKNOWN;
+ UNIMPLIMENTEDPACKET;
+ break;
+ }
+ if (localPlayer)
+ {
+ localPlayer->pickedUp(itemInfo,
+ 0,
+ color,
+ floorId,
+ pickup);
+ }
+ }
+ else
+ {
+ if (localPlayer)
+ {
+ localPlayer->pickedUp(itemInfo,
+ amount,
+ color,
+ floorId,
+ Pickup::OKAY);
+ }
+
+ if (inventory)
+ {
+ const Item *const item = inventory->getItem(index);
+
+ if (item && item->getId() == itemId)
+ amount += item->getQuantity();
+
+ inventory->setItem(index,
+ itemId,
+ itemType,
+ amount,
+ refine,
+ color,
+ fromBool(identified, Identified),
+ fromBool(damaged, Damaged),
+ Favorite_false,
+ fromBool(equipType, Equipm),
+ Equipped_false);
+ inventory->setCards(index, cards, 4);
+ }
+ ArrowsListener::distributeEvent();
+ }
+ BLOCK_END("InventoryRecv::processPlayerInventoryAdd")
+}
+
+void InventoryRecv::processPlayerInventory(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerInventory")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+ if (PlayerInfo::getEquipment())
+ {
+ // Clear inventory - this will be a complete refresh
+ Ea::InventoryRecv::mEquips.clear();
+ PlayerInfo::getEquipment()->setBackend(&Ea::InventoryRecv::mEquips);
+ }
+
+ if (inventory)
+ inventory->clear();
+
+ msg.readInt16("len");
+
+ const int number = (msg.getLength() - 4) / 24;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ const int index = msg.readInt16("item index") - INVENTORY_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const int itemType = msg.readUInt8("item type");
+ const int amount = msg.readInt16("count");
+ msg.readInt32("wear state / equip");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+ msg.readInt32("hire expire date (?)");
+ ItemFlags flags;
+ flags.byte = msg.readUInt8("flags");
+
+ if (inventory)
+ {
+ inventory->setItem(index,
+ itemId,
+ itemType,
+ amount,
+ 0,
+ ItemColorManager::getColorFromCards(&cards[0]),
+ fromBool(flags.bits.isIdentified, Identified),
+ fromBool(flags.bits.isDamaged, Damaged),
+ fromBool(flags.bits.isFavorite, Favorite),
+ Equipm_false,
+ Equipped_false);
+ inventory->setCards(index, cards, 4);
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerInventory")
+}
+
+void InventoryRecv::processPlayerStorage(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerInventory")
+ Ea::InventoryRecv::mInventoryItems.clear();
+
+ msg.readInt16("len");
+ msg.readString(24, "storage name");
+
+ const int number = (msg.getLength() - 4 - 24) / 24;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ const int index = msg.readInt16("item index") - STORAGE_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const int itemType = msg.readUInt8("item type");
+ const int amount = msg.readInt16("count");
+ msg.readInt32("wear state / equip");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+ msg.readInt32("hire expire date (?)");
+ ItemFlags flags;
+ flags.byte = msg.readUInt8("flags");
+
+ Ea::InventoryRecv::mInventoryItems.push_back(Ea::InventoryItem(
+ index,
+ itemId,
+ itemType,
+ cards,
+ amount,
+ 0,
+ ItemColorManager::getColorFromCards(&cards[0]),
+ fromBool(flags.bits.isIdentified, Identified),
+ fromBool(flags.bits.isDamaged, Damaged),
+ fromBool(flags.bits.isFavorite, Favorite),
+ Equipm_false));
+ }
+ BLOCK_END("InventoryRecv::processPlayerInventory")
+}
+
+void InventoryRecv::processPlayerEquip(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerEquip")
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int equipType = msg.readInt32("wear location");
+ msg.readInt16("sprite");
+ const uint8_t flag = msg.readUInt8("result");
+
+ switch (flag)
+ {
+ case 0:
+ Ea::InventoryRecv::mEquips.setEquipment(
+ Ea::InventoryRecv::getSlot(equipType), index);
+ break;
+ case 1:
+ NotifyManager::notify(NotifyTypes::EQUIP_FAILED_LEVEL);
+ break;
+
+ case 2:
+ default:
+ NotifyManager::notify(NotifyTypes::EQUIP_FAILED);
+ break;
+ }
+ BLOCK_END("InventoryRecv::processPlayerEquip")
+}
+
+void InventoryRecv::processPlayerUnEquip(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerUnEquip")
+ msg.readInt16("index");
+ const int equipType = msg.readInt32("wear location");
+ const uint8_t flag = msg.readUInt8("result");
+
+ // +++ need use UNEQUIP_FAILED event
+ if (flag)
+ {
+ NotifyManager::notify(NotifyTypes::EQUIP_FAILED);
+ }
+ else
+ {
+ Ea::InventoryRecv::mEquips.setEquipment(
+ Ea::InventoryRecv::getSlot(equipType), -1);
+ }
+ if (equipType & 0x8000)
+ ArrowsListener::distributeEvent();
+ BLOCK_END("InventoryRecv::processPlayerUnEquip")
+}
+
+void InventoryRecv::processPlayerInventoryRemove2(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerInventoryRemove2")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ // +++ here possible use particle or text/sound effects
+ // for different reasons
+ msg.readInt16("reason");
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int amount = msg.readInt16("amount");
+ if (inventory)
+ {
+ if (Item *const item = inventory->getItem(index))
+ {
+ item->increaseQuantity(-amount);
+ if (item->getQuantity() == 0)
+ inventory->removeItemAt(index);
+ ArrowsListener::distributeEvent();
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerInventoryRemove2")
+}
+
+void InventoryRecv::processPlayerStorageEquip(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerStorageEquip")
+ msg.readInt16("len");
+ const int number = (msg.getLength() - 4 - 24) / 31;
+
+ msg.readString(24, "storage name");
+ for (int loop = 0; loop < number; loop++)
+ {
+ const int index = msg.readInt16("index") - STORAGE_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const int itemType = msg.readUInt8("item type");
+ const int amount = 1;
+ msg.readInt32("location");
+ msg.readInt32("wear state");
+ const uint8_t refine = msg.readUInt8("refine level");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+ msg.readInt32("hire expire date");
+ msg.readInt16("bind on equip");
+ msg.readInt16("sprite");
+ ItemFlags flags;
+ flags.byte = msg.readUInt8("flags");
+
+ Ea::InventoryRecv::mInventoryItems.push_back(Ea::InventoryItem(
+ index,
+ itemId,
+ itemType,
+ cards,
+ amount,
+ refine,
+ ItemColorManager::getColorFromCards(&cards[0]),
+ fromBool(flags.bits.isIdentified, Identified),
+ fromBool(flags.bits.isDamaged, Damaged),
+ fromBool(flags.bits.isFavorite, Favorite),
+ Equipm_false));
+ }
+ BLOCK_END("InventoryRecv::processPlayerStorageEquip")
+}
+
+void InventoryRecv::processPlayerStorageAdd(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerStorageAdd")
+ // Move an item into storage
+ const int index = msg.readInt16("index") - STORAGE_OFFSET;
+ const int amount = msg.readInt32("amount");
+ const int itemId = msg.readInt16("item id");
+ const int itemType = msg.readUInt8("type");
+ const unsigned char identified = msg.readUInt8("identify");
+ const Damaged damaged = fromBool(msg.readUInt8("attribute"), Damaged);
+ const uint8_t refine = msg.readUInt8("refine");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+
+ const ItemColor color = ItemColorManager::getColorFromCards(&cards[0]);
+ if (Item *const item = Ea::InventoryRecv::mStorage->getItem(index))
+ {
+ item->setId(itemId, color);
+ item->increaseQuantity(amount);
+ }
+ else
+ {
+ if (Ea::InventoryRecv::mStorage)
+ {
+ Ea::InventoryRecv::mStorage->setItem(index,
+ itemId,
+ itemType,
+ amount,
+ refine,
+ color,
+ fromBool(identified, Identified),
+ damaged,
+ Favorite_false,
+ Equipm_false,
+ Equipped_false);
+ Ea::InventoryRecv::mStorage->setCards(index, cards, 4);
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerStorageAdd")
+}
+
+void InventoryRecv::processPlayerUseCard(Net::MessageIn &msg)
+{
+ const Inventory *const inv = PlayerInfo::getInventory();
+ const int index = inventoryHandler->getItemIndex();
+ const Item *item1 = nullptr;
+ if (inv)
+ item1 = inv->getItem(index);
+ SellDialog *const dialog = CREATEWIDGETR(InsertCardDialog,
+ index, item1);
+
+ const int count = (msg.readInt16("len") - 4) / 2;
+ for (int f = 0; f < count; f ++)
+ {
+ const int itemIndex = msg.readInt16("item index") - INVENTORY_OFFSET;
+ if (!inv)
+ continue;
+ const Item *const item = inv->getItem(itemIndex);
+ if (!item)
+ continue;
+ dialog->addItem(item, 0);
+ }
+}
+
+void InventoryRecv::processPlayerInsertCard(Net::MessageIn &msg)
+{
+ const int itemIndex = msg.readInt16("item index") - INVENTORY_OFFSET;
+ const int cardIndex = msg.readInt16("card index") - INVENTORY_OFFSET;
+ if (msg.readUInt8("flag"))
+ {
+ NotifyManager::notify(NotifyTypes::CARD_INSERT_FAILED);
+ }
+ else
+ {
+ NotifyManager::notify(NotifyTypes::CARD_INSERT_SUCCESS);
+ Inventory *const inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+ Item *const card = inv->getItem(cardIndex);
+ int cardId = 0;
+ if (card)
+ {
+ cardId = card->getId();
+ card->increaseQuantity(-1);
+ if (card->getQuantity() == 0)
+ inv->removeItemAt(cardIndex);
+ }
+ Item *const item = inv->getItem(itemIndex);
+ if (item)
+ {
+ item->addCard(cardId);
+ item->updateColor();
+ itemPopup->resetPopup();
+ }
+ }
+}
+
+void InventoryRecv::processPlayerItemRentalTime(Net::MessageIn &msg)
+{
+ const int id = msg.readInt16("item id");
+ const int seconds = msg.readInt32("seconds");
+ const ItemInfo &info = ItemDB::get(id);
+ const std::string timeStr = timeDiffToString(seconds);
+ NotifyManager::notify(NotifyTypes::RENTAL_TIME_LEFT,
+ // TRANSLATORS: notification message
+ strprintf(_("Left %s rental time for item %s."),
+ timeStr.c_str(), info.getName().c_str()));
+}
+
+void InventoryRecv::processPlayerItemRentalExpired(Net::MessageIn &msg)
+{
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int id = msg.readInt16("item id");
+ const ItemInfo &info = ItemDB::get(id);
+
+ NotifyManager::notify(NotifyTypes::RENTAL_TIME_EXPIRED,
+ info.getName());
+ if (inventory)
+ {
+ if (Item *const item = inventory->getItem(index))
+ {
+ item->increaseQuantity(-item->getQuantity());
+ inventory->removeItemAt(index);
+ ArrowsListener::distributeEvent();
+ }
+ }
+}
+
+void InventoryRecv::processPlayerStorageRemove(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerStorageRemove")
+ // Move an item out of storage
+ const int index = msg.readInt16("index") - STORAGE_OFFSET;
+ const int amount = msg.readInt32("amount");
+ if (Ea::InventoryRecv::mStorage)
+ {
+ if (Item *const item = Ea::InventoryRecv::mStorage->getItem(index))
+ {
+ item->increaseQuantity(-amount);
+ if (item->getQuantity() == 0)
+ Ea::InventoryRecv::mStorage->removeItemAt(index);
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerStorageRemove")
+}
+
+void InventoryRecv::processCartInfo(Net::MessageIn &msg)
+{
+ msg.readInt16("cart items used");
+ const int size = msg.readInt16("max cart items");
+ PlayerInfo::setAttribute(Attributes::CART_TOTAL_WEIGHT,
+ msg.readInt32("cart weight"));
+ PlayerInfo::setAttribute(Attributes::CART_MAX_WEIGHT,
+ msg.readInt32("max cart weight"));
+ if (mCartItems.empty())
+ return;
+
+ Inventory *const inv = PlayerInfo::getCartInventory();
+ if (!inv)
+ return;
+
+ inv->resize(size);
+
+ FOR_EACH (Ea::InventoryItems::const_iterator, it, mCartItems)
+ {
+ inv->setItem((*it).slot,
+ (*it).id,
+ (*it).type,
+ (*it).quantity,
+ (*it).refine,
+ (*it).color,
+ (*it).identified,
+ (*it).damaged,
+ (*it).favorite,
+ (*it).equip,
+ Equipped_false);
+ }
+ mCartItems.clear();
+}
+
+void InventoryRecv::processCartRemove(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+ // +++ need close or clear cart?
+}
+
+void InventoryRecv::processPlayerCartAdd(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerCartAdd")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getCartInventory() : nullptr;
+
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ int amount = msg.readInt32("count");
+ const int itemId = msg.readInt16("item id");
+ const int itemType = msg.readUInt8("item type");
+ uint8_t identified = msg.readUInt8("identified");
+ const Damaged damaged = fromBool(msg.readUInt8("attribute"), Damaged);
+ const uint8_t refine = msg.readUInt8("refine");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+
+ if (inventory)
+ {
+ const Item *const item = inventory->getItem(index);
+
+ if (item && item->getId() == itemId)
+ amount += item->getQuantity();
+
+ inventory->setItem(index,
+ itemId,
+ itemType,
+ amount,
+ refine,
+ ItemColorManager::getColorFromCards(&cards[0]),
+ fromBool(identified, Identified),
+ damaged,
+ Favorite_false,
+ Equipm_false,
+ Equipped_false);
+ inventory->setCards(index, cards, 4);
+ }
+ BLOCK_END("InventoryRecv::processPlayerCartAdd")
+}
+
+void InventoryRecv::processPlayerCartEquip(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerCartEquip")
+ msg.readInt16("len");
+ const int number = (msg.getLength() - 4) / 31;
+ for (int loop = 0; loop < number; loop++)
+ {
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const int itemType = msg.readUInt8("item type");
+ const int amount = 1;
+ msg.readInt32("location");
+ msg.readInt32("wear state");
+ const uint8_t refine = msg.readUInt8("refine level");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+ msg.readInt32("hire expire date");
+ msg.readInt16("bind on equip");
+ msg.readInt16("sprite");
+ ItemFlags flags;
+ flags.byte = msg.readUInt8("flags");
+
+ mCartItems.push_back(Ea::InventoryItem(index,
+ itemId,
+ itemType,
+ cards,
+ amount,
+ refine,
+ ItemColorManager::getColorFromCards(&cards[0]),
+ fromBool(flags.bits.isIdentified, Identified),
+ fromBool(flags.bits.isDamaged, Damaged),
+ fromBool(flags.bits.isFavorite, Favorite),
+ Equipm_false));
+ }
+ BLOCK_END("InventoryRecv::processPlayerCartEquip")
+}
+
+void InventoryRecv::processPlayerCartItems(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerCartItems")
+ Ea::InventoryRecv::mInventoryItems.clear();
+
+ msg.readInt16("len");
+ const int number = (msg.getLength() - 4) / 23;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ const int index = msg.readInt16("item index") - INVENTORY_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const int itemType = msg.readUInt8("item type");
+ const int amount = msg.readInt16("count");
+ msg.readInt32("wear state / equip");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+ msg.readInt32("hire expire date (?)");
+ ItemFlags flags;
+ flags.byte = msg.readUInt8("flags");
+
+ mCartItems.push_back(Ea::InventoryItem(index,
+ itemId,
+ itemType,
+ cards,
+ amount,
+ 0,
+ ItemColorManager::getColorFromCards(&cards[0]),
+ fromBool(flags.bits.isIdentified, Identified),
+ fromBool(flags.bits.isDamaged, Damaged),
+ fromBool(flags.bits.isFavorite, Favorite),
+ Equipm_false));
+ }
+ BLOCK_END("InventoryRecv::processPlayerCartItems")
+}
+
+void InventoryRecv::processPlayerCartRemove(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerCartRemove")
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int amount = msg.readInt32("amount");
+
+ Inventory *const inv = PlayerInfo::getCartInventory();
+ if (!inv)
+ return;
+
+ if (Item *const item = inv->getItem(index))
+ {
+ item->increaseQuantity(-amount);
+ if (item->getQuantity() == 0)
+ inv->removeItemAt(index);
+ }
+ BLOCK_END("InventoryRecv::processPlayerCartRemove")
+}
+
+void InventoryRecv::processPlayerIdentifyList(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ menu = MenuType::Identify;
+ const int count = msg.readInt16("len") - 4;
+ for (int f = 0; f < count; f ++)
+ msg.readInt16("inv index");
+}
+
+void InventoryRecv::processPlayerIdentified(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ msg.readInt16("inv index");
+ msg.readUInt8("flag");
+}
+
+void InventoryRecv::processPlayerRefine(Net::MessageIn &msg)
+{
+ const int flag = msg.readInt16("flag");
+ const int index = msg.readInt16("inv index") - INVENTORY_OFFSET;
+ msg.readInt16("refine");
+ const Inventory *const inv = PlayerInfo::getInventory();
+ const Item *item = nullptr;
+ int notifyType;
+ std::string message;
+ std::string itemName;
+ if (inv)
+ item = inv->getItem(index);
+ if (item)
+ {
+ itemName = item->getName();
+ }
+ else
+ {
+ // TRANSLATORS: unknown item
+ itemName = _("Unknown item");
+ }
+ switch (flag)
+ {
+ case 0:
+ notifyType = NotifyTypes::REFINE_SUCCESS;
+ break;
+ case 1:
+ notifyType = NotifyTypes::REFINE_FAILURE;
+ break;
+ case 2:
+ notifyType = NotifyTypes::REFINE_DOWNGRADE;
+ break;
+ default:
+ UNIMPLIMENTEDPACKET;
+ notifyType = NotifyTypes::REFINE_UNKNOWN;
+ break;
+ }
+ NotifyManager::notify(notifyType, itemName);
+}
+
+void InventoryRecv::processPlayerRepairList(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ const int count = (msg.readInt16("len") - 4) / 13;
+ for (int f = 0; f < count; f ++)
+ {
+ msg.readInt16("index");
+ msg.readInt16("item id");
+ msg.readUInt8("refine");
+ for (int d = 0; d < 4; d ++)
+ msg.readInt16("card");
+ }
+ menu = MenuType::RepairWespon;
+}
+
+void InventoryRecv::processPlayerRepairEffect(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ msg.readInt16("item index");
+ msg.readUInt8("flag");
+}
+
+void InventoryRecv::processPlayerRefineList(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ const int count = (msg.readInt16("len") - 4) / 13;
+
+ for (int f = 0; f < count; f ++)
+ {
+ msg.readInt16("item index");
+ msg.readInt16("item id");
+ msg.readUInt8("refine");
+ for (int d = 0; d < 4; d ++)
+ msg.readInt16("card");
+ }
+ menu = MenuType::WeaponeRefine;
+}
+
+void InventoryRecv::processPlayerStoragePassword(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ msg.readInt16("info");
+}
+
+void InventoryRecv::processPlayerStoragePasswordResult(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ msg.readInt16("result");
+ msg.readInt16("error count");
+}
+
+void InventoryRecv::processPlayerCookingList(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ const int count = (msg.readInt16("len") - 6) / 2;
+ msg.readInt16("list type");
+ for (int f = 0; f < count; f ++)
+ msg.readInt16("item id");
+}
+
+void InventoryRecv::processItemDamaged(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ msg.readInt16("position");
+ msg.readBeingId("account id");
+}
+
+void InventoryRecv::processFavoriteItem(Net::MessageIn &msg)
+{
+ UNIMPLIMENTEDPACKET;
+
+ msg.readInt16("item index");
+ msg.readUInt8("favorite (0 - favorite)");
+}
+
+void InventoryRecv::processCartAddError(Net::MessageIn &msg)
+{
+ switch(msg.readUInt8("flag"))
+ {
+ case 0:
+ NotifyManager::notify(NotifyTypes::CART_ADD_WEIGHT_ERROR);
+ break;
+ case 1:
+ NotifyManager::notify(NotifyTypes::CART_ADD_COUNT_ERROR);
+ break;
+ default:
+ break;
+ }
+}
+
+void InventoryRecv::processBindItem(Net::MessageIn &msg)
+{
+ const int index = msg.readInt16("item index") - INVENTORY_OFFSET;
+ const Inventory *const inv = PlayerInfo::getInventory();
+ if (inv)
+ {
+ std::string itemName;
+ const Item *item = inv->getItem(index);
+ if (item)
+ {
+ itemName = item->getName();
+ }
+ else
+ {
+ // TRANSLATORS: unknown item message
+ itemName = _("Unknown item");
+ }
+ NotifyManager::notify(NotifyTypes::BOUND_ITEM, itemName);
+ }
+}
+
+} // namespace EAthena
diff --git a/src/net/eathena/inventoryrecv.h b/src/net/eathena/inventoryrecv.h
new file mode 100644
index 000000000..ea0bd71fd
--- /dev/null
+++ b/src/net/eathena/inventoryrecv.h
@@ -0,0 +1,72 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2015 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NET_EATHENA_INVENTORYRECV_H
+#define NET_EATHENA_INVENTORYRECV_H
+
+#include "net/ea/inventoryhandler.h"
+
+#include "net/eathena/messagehandler.h"
+
+namespace EAthena
+{
+ namespace InventoryRecv
+ {
+ extern Ea::InventoryItems mCartItems;
+
+ void processPlayerEquipment(Net::MessageIn &msg);
+ void processPlayerInventoryAdd(Net::MessageIn &msg);
+ void processPlayerInventory(Net::MessageIn &msg);
+ void processPlayerStorage(Net::MessageIn &msg);
+ void processPlayerEquip(Net::MessageIn &msg);
+ void processPlayerUnEquip(Net::MessageIn &msg);
+ void processPlayerInventoryRemove2(Net::MessageIn &msg);
+ void processPlayerStorageEquip(Net::MessageIn &msg);
+ void processPlayerStorageAdd(Net::MessageIn &msg);
+ void processPlayerUseCard(Net::MessageIn &msg);
+ void processPlayerInsertCard(Net::MessageIn &msg);
+ void processPlayerItemRentalTime(Net::MessageIn &msg);
+ void processPlayerItemRentalExpired(Net::MessageIn &msg);
+ void processPlayerStorageRemove(Net::MessageIn &msg);
+ void processCartInfo(Net::MessageIn &msg);
+ void processCartRemove(Net::MessageIn &msg);
+ void processPlayerCartAdd(Net::MessageIn &msg);
+ void processPlayerCartEquip(Net::MessageIn &msg);
+ void processPlayerCartItems(Net::MessageIn &msg);
+ void processPlayerCartRemove(Net::MessageIn &msg);
+ void processPlayerIdentifyList(Net::MessageIn &msg);
+ void processPlayerIdentified(Net::MessageIn &msg);
+ void processPlayerRefine(Net::MessageIn &msg);
+ void processPlayerRepairList(Net::MessageIn &msg);
+ void processPlayerRepairEffect(Net::MessageIn &msg);
+ void processPlayerRefineList(Net::MessageIn &msg);
+ void processPlayerStoragePassword(Net::MessageIn &msg);
+ void processPlayerStoragePasswordResult(Net::MessageIn &msg);
+ void processPlayerCookingList(Net::MessageIn &msg);
+ void processItemDamaged(Net::MessageIn &msg);
+ void processFavoriteItem(Net::MessageIn &msg);
+ void processCartAddError(Net::MessageIn &msg);
+ void processBindItem(Net::MessageIn &msg);
+ } // namespace InventoryRecv
+} // namespace EAthena
+
+#endif // NET_EATHENA_INVENTORYRECV_H
diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp
index 98c0a46b6..99fda9a23 100644
--- a/src/net/tmwa/inventoryhandler.cpp
+++ b/src/net/tmwa/inventoryhandler.cpp
@@ -32,6 +32,9 @@
#include "listeners/arrowslistener.h"
+#include "net/ea/inventoryrecv.h"
+
+#include "net/tmwa/inventoryrecv.h"
#include "net/tmwa/messageout.h"
#include "net/tmwa/protocol.h"
@@ -102,67 +105,67 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg)
switch (msg.getId())
{
case SMSG_PLAYER_INVENTORY:
- processPlayerInventory(msg);
+ InventoryRecv::processPlayerInventory(msg);
break;
case SMSG_PLAYER_STORAGE_ITEMS:
- processPlayerStorage(msg);
+ InventoryRecv::processPlayerStorage(msg);
break;
case SMSG_PLAYER_STORAGE_EQUIP:
- processPlayerStorageEquip(msg);
+ InventoryRecv::processPlayerStorageEquip(msg);
break;
case SMSG_PLAYER_INVENTORY_ADD:
- processPlayerInventoryAdd(msg);
+ InventoryRecv::processPlayerInventoryAdd(msg);
break;
case SMSG_PLAYER_INVENTORY_REMOVE:
- processPlayerInventoryRemove(msg);
+ Ea::InventoryRecv::processPlayerInventoryRemove(msg);
break;
case SMSG_PLAYER_INVENTORY_USE:
- processPlayerInventoryUse(msg);
+ Ea::InventoryRecv::processPlayerInventoryUse(msg);
break;
case SMSG_ITEM_USE_RESPONSE:
- processItemUseResponse(msg);
+ Ea::InventoryRecv::processItemUseResponse(msg);
break;
case SMSG_PLAYER_STORAGE_STATUS:
- processPlayerStorageStatus(msg);
+ Ea::InventoryRecv::processPlayerStorageStatus(msg);
break;
case SMSG_PLAYER_STORAGE_ADD:
- processPlayerStorageAdd(msg);
+ InventoryRecv::processPlayerStorageAdd(msg);
break;
case SMSG_PLAYER_STORAGE_REMOVE:
- processPlayerStorageRemove(msg);
+ InventoryRecv::processPlayerStorageRemove(msg);
break;
case SMSG_PLAYER_STORAGE_CLOSE:
- processPlayerStorageClose(msg);
+ Ea::InventoryRecv::processPlayerStorageClose(msg);
break;
case SMSG_PLAYER_EQUIPMENT:
- processPlayerEquipment(msg);
+ InventoryRecv::processPlayerEquipment(msg);
break;
case SMSG_PLAYER_EQUIP:
- processPlayerEquip(msg);
+ InventoryRecv::processPlayerEquip(msg);
break;
case SMSG_PLAYER_UNEQUIP:
- processPlayerUnEquip(msg);
+ InventoryRecv::processPlayerUnEquip(msg);
break;
case SMSG_PLAYER_ATTACK_RANGE:
- processPlayerAttackRange(msg);
+ Ea::InventoryRecv::processPlayerAttackRange(msg);
break;
case SMSG_PLAYER_ARROW_EQUIP:
- processPlayerArrowEquip(msg);
+ Ea::InventoryRecv::processPlayerArrowEquip(msg);
break;
default:
@@ -254,392 +257,6 @@ void InventoryHandler::favoriteItem(const Item *const item A_UNUSED,
{
}
-void InventoryHandler::processPlayerEquipment(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerEquipment")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- msg.readInt16("len");
- Equipment *const equipment = PlayerInfo::getEquipment();
- if (equipment && !equipment->getBackend())
- { // look like SMSG_PLAYER_INVENTORY was not received
- mEquips.clear();
- equipment->setBackend(&mEquips);
- }
- const int number = (msg.getLength() - 4) / 20;
-
- for (int loop = 0; loop < number; loop++)
- {
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int itemId = msg.readInt16("item id");
- const uint8_t itemType = msg.readUInt8("item type");
- const uint8_t identified = msg.readUInt8("identify");
-
- msg.readInt16("equip type?");
- const int equipType = msg.readInt16("equip type");
- msg.readUInt8("attribute");
- const uint8_t refine = msg.readUInt8("refine");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
-
- if (mDebugInventory)
- {
- logger->log("Index: %d, ID: %d, Type: %d, Identified: %d",
- index, itemId, itemType, identified);
- }
-
- if (inventory)
- {
- inventory->setItem(index,
- itemId,
- itemType,
- 1,
- refine,
- ItemColor_one,
- fromBool(identified, Identified),
- Damaged_false,
- Favorite_false,
- Equipm_true,
- Equipped_false);
- inventory->setCards(index, cards, 4);
- }
-
- if (equipType)
- mEquips.setEquipment(getSlot(equipType), index);
- }
- BLOCK_END("InventoryHandler::processPlayerEquipment")
-}
-
-void InventoryHandler::processPlayerInventoryAdd(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerInventoryAdd")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- if (PlayerInfo::getEquipment()
- && !PlayerInfo::getEquipment()->getBackend())
- { // look like SMSG_PLAYER_INVENTORY was not received
- mEquips.clear();
- PlayerInfo::getEquipment()->setBackend(&mEquips);
- }
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- int amount = msg.readInt16("amount");
- const int itemId = msg.readInt16("item id");
- const uint8_t identified = msg.readUInt8("identified");
- msg.readUInt8("attribute");
- const uint8_t refine = msg.readUInt8("refine");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
- const int equipType = msg.readInt16("equip type");
- const int type = msg.readUInt8("item type");
-
- const ItemInfo &itemInfo = ItemDB::get(itemId);
- const unsigned char err = msg.readUInt8("status");
- BeingId floorId;
- if (mSentPickups.empty())
- {
- floorId = BeingId_zero;
- }
- else
- {
- floorId = mSentPickups.front();
- mSentPickups.pop();
- }
-
- if (err)
- {
- PickupT pickup;
- switch (err)
- {
- case 1:
- pickup = Pickup::BAD_ITEM;
- break;
- case 2:
- pickup = Pickup::TOO_HEAVY;
- break;
- case 3:
- pickup = Pickup::TOO_FAR;
- break;
- case 4:
- pickup = Pickup::INV_FULL;
- break;
- case 5:
- pickup = Pickup::STACK_FULL;
- break;
- case 6:
- pickup = Pickup::DROP_STEAL;
- break;
- default:
- pickup = Pickup::UNKNOWN;
- UNIMPLIMENTEDPACKET;
- break;
- }
- if (localPlayer)
- {
- localPlayer->pickedUp(itemInfo,
- 0,
- ItemColor_one,
- floorId,
- pickup);
- }
- }
- else
- {
- if (localPlayer)
- {
- localPlayer->pickedUp(itemInfo,
- amount,
- ItemColor_one,
- floorId,
- Pickup::OKAY);
- }
-
- if (inventory)
- {
- const Item *const item = inventory->getItem(index);
-
- if (item && item->getId() == itemId)
- amount += item->getQuantity();
-
- inventory->setItem(index,
- itemId,
- type,
- amount,
- refine,
- ItemColor_one,
- fromBool(identified, Identified),
- Damaged_false,
- Favorite_false,
- fromBool(equipType, Equipm),
- Equipped_false);
- inventory->setCards(index, cards, 4);
- }
- ArrowsListener::distributeEvent();
- }
- BLOCK_END("InventoryHandler::processPlayerInventoryAdd")
-}
-
-void InventoryHandler::processPlayerInventory(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerInventory")
- Inventory *const inventory = localPlayer
- ? PlayerInfo::getInventory() : nullptr;
-
- if (PlayerInfo::getEquipment())
- {
- // Clear inventory - this will be a complete refresh
- mEquips.clear();
- PlayerInfo::getEquipment()->setBackend(&mEquips);
- }
-
- if (inventory)
- inventory->clear();
-
- msg.readInt16("len");
- const int number = (msg.getLength() - 4) / 18;
-
- for (int loop = 0; loop < number; loop++)
- {
- int cards[4];
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int itemId = msg.readInt16("item id");
- const uint8_t itemType = msg.readUInt8("item type");
- const uint8_t identified = msg.readUInt8("identified");
- const int amount = msg.readInt16("amount");
- const int arrow = msg.readInt16("arrow");
- for (int i = 0; i < 4; i++)
- cards[i] = msg.readInt16("card");
-
- if (mDebugInventory)
- {
- logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
- "Qty: %d, Cards: %d, %d, %d, %d",
- index, itemId, itemType, identified, amount,
- cards[0], cards[1], cards[2], cards[3]);
- }
-
- // Trick because arrows are not considered equipment
- const bool isEquipment = arrow & 0x8000;
-
- if (inventory)
- {
- inventory->setItem(index,
- itemId,
- itemType,
- amount,
- 0,
- ItemColor_one,
- fromBool(identified, Identified),
- Damaged_false,
- Favorite_false,
- fromBool(isEquipment, Equipm),
- Equipped_false);
- inventory->setCards(index, cards, 4);
- }
- }
- BLOCK_END("InventoryHandler::processPlayerInventory")
-}
-
-void InventoryHandler::processPlayerStorage(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerInventory")
- mInventoryItems.clear();
-
- msg.readInt16("len");
- const int number = (msg.getLength() - 4) / 18;
-
- for (int loop = 0; loop < number; loop++)
- {
- int cards[4];
- const int index = msg.readInt16("index") - STORAGE_OFFSET;
- const int itemId = msg.readInt16("item id");
- const uint8_t itemType = msg.readUInt8("item type");
- const uint8_t identified = msg.readUInt8("identified");
- const int amount = msg.readInt16("amount");
- msg.readInt16("arrow");
- for (int i = 0; i < 4; i++)
- cards[i] = msg.readInt16("card");
-
- if (mDebugInventory)
- {
- logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
- "Qty: %d, Cards: %d, %d, %d, %d",
- index, itemId, itemType, identified, amount,
- cards[0], cards[1], cards[2], cards[3]);
- }
-
- mInventoryItems.push_back(Ea::InventoryItem(index,
- itemId,
- itemType,
- cards,
- amount,
- 0,
- ItemColor_one,
- fromBool(identified, Identified),
- Damaged_false,
- Favorite_false,
- Equipm_false));
- }
- BLOCK_END("InventoryHandler::processPlayerInventory")
-}
-
-void InventoryHandler::processPlayerEquip(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerEquip")
- const int index = msg.readInt16("index") - INVENTORY_OFFSET;
- const int equipType = msg.readInt16("equip type");
- const uint8_t flag = msg.readUInt8("flag");
-
- if (!flag)
- NotifyManager::notify(NotifyTypes::EQUIP_FAILED);
- else
- mEquips.setEquipment(getSlot(equipType), index);
- BLOCK_END("InventoryHandler::processPlayerEquip")
-}
-
-void InventoryHandler::processPlayerUnEquip(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerUnEquip")
- msg.readInt16("index");
- const int equipType = msg.readInt16("equip type");
- const uint8_t flag = msg.readUInt8("flag");
-
- if (flag)
- mEquips.setEquipment(getSlot(equipType), -1);
- if (equipType & 0x8000)
- ArrowsListener::distributeEvent();
- BLOCK_END("InventoryHandler::processPlayerUnEquip")
-}
-
-void InventoryHandler::processPlayerStorageEquip(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerStorageEquip")
- msg.readInt16("len");
- const int number = (msg.getLength() - 4) / 20;
-
- for (int loop = 0; loop < number; loop++)
- {
- int cards[4];
- const int index = msg.readInt16("index") - STORAGE_OFFSET;
- const int itemId = msg.readInt16("item id");
- const uint8_t itemType = msg.readUInt8("item type");
- const uint8_t identified = msg.readUInt8("identified");
- const int amount = 1;
- msg.readInt16("equip point?");
- msg.readInt16("another equip point?");
- msg.readUInt8("attribute (broken)");
- const uint8_t refine = msg.readUInt8("refine");
- for (int i = 0; i < 4; i++)
- cards[i] = msg.readInt16("card");
-
- if (mDebugInventory)
- {
- logger->log("Index: %d, ID: %d, Type: %d, Identified: %u, "
- "Qty: %d, Cards: %d, %d, %d, %d, Refine: %u",
- index, itemId, itemType,
- static_cast<unsigned int>(identified), amount,
- cards[0], cards[1], cards[2], cards[3],
- static_cast<unsigned int>(refine));
- }
-
- mInventoryItems.push_back(Ea::InventoryItem(index,
- itemId,
- itemType,
- cards,
- amount,
- refine,
- ItemColor_one,
- fromBool(identified, Identified),
- Damaged_false,
- Favorite_false,
- Equipm_false));
- }
- BLOCK_END("InventoryHandler::processPlayerStorageEquip")
-}
-
-void InventoryHandler::processPlayerStorageAdd(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerStorageAdd")
- // Move an item into storage
- const int index = msg.readInt16("index") - STORAGE_OFFSET;
- const int amount = msg.readInt32("amount");
- const int itemId = msg.readInt16("item id");
- const unsigned char identified = msg.readUInt8("identified");
- msg.readUInt8("attribute");
- const uint8_t refine = msg.readUInt8("refine");
- int cards[4];
- for (int f = 0; f < 4; f++)
- cards[f] = msg.readInt16("card");
-
- if (Item *const item = mStorage->getItem(index))
- {
- item->setId(itemId, ItemColor_one);
- item->increaseQuantity(amount);
- }
- else
- {
- if (mStorage)
- {
- mStorage->setItem(index,
- itemId,
- 0,
- amount,
- refine,
- ItemColor_one,
- fromBool(identified, Identified),
- Damaged_false,
- Favorite_false,
- Equipm_false,
- Equipped_false);
- mStorage->setCards(index, cards, 4);
- }
- }
- BLOCK_END("InventoryHandler::processPlayerStorageAdd")
-}
-
void InventoryHandler::selectEgg(const Item *const item A_UNUSED) const
{
}
@@ -652,22 +269,4 @@ int InventoryHandler::convertFromServerSlot(const int serverSlot) const
return static_cast<int>(EQUIP_CONVERT[serverSlot]);
}
-void InventoryHandler::processPlayerStorageRemove(Net::MessageIn &msg)
-{
- BLOCK_START("InventoryHandler::processPlayerStorageRemove")
- // Move an item out of storage
- const int index = msg.readInt16("index") - STORAGE_OFFSET;
- const int amount = msg.readInt16("amount");
- if (mStorage)
- {
- if (Item *const item = mStorage->getItem(index))
- {
- item->increaseQuantity(-amount);
- if (item->getQuantity() == 0)
- mStorage->removeItemAt(index);
- }
- }
- BLOCK_END("InventoryHandler::processPlayerStorageRemove")
-}
-
} // namespace TmwAthena
diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h
index bf6badc48..8bbd17a56 100644
--- a/src/net/tmwa/inventoryhandler.h
+++ b/src/net/tmwa/inventoryhandler.h
@@ -76,25 +76,6 @@ class InventoryHandler final : public MessageHandler,
int getItemIndex() const override final A_WARN_UNUSED
{ return 0; }
-
- protected:
- static void processPlayerEquipment(Net::MessageIn &msg);
-
- static void processPlayerInventoryAdd(Net::MessageIn &msg);
-
- static void processPlayerInventory(Net::MessageIn &msg);
-
- static void processPlayerStorage(Net::MessageIn &msg);
-
- static void processPlayerEquip(Net::MessageIn &msg);
-
- static void processPlayerUnEquip(Net::MessageIn &msg);
-
- static void processPlayerStorageEquip(Net::MessageIn &msg);
-
- static void processPlayerStorageAdd(Net::MessageIn &msg);
-
- static void processPlayerStorageRemove(Net::MessageIn &msg);
};
} // namespace TmwAthena
diff --git a/src/net/tmwa/inventoryrecv.cpp b/src/net/tmwa/inventoryrecv.cpp
new file mode 100644
index 000000000..da3eb3f91
--- /dev/null
+++ b/src/net/tmwa/inventoryrecv.cpp
@@ -0,0 +1,464 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2015 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "net/tmwa/inventoryrecv.h"
+
+#include "notifymanager.h"
+
+#include "enums/equipslot.h"
+
+#include "being/localplayer.h"
+
+#include "enums/resources/notifytypes.h"
+
+#include "listeners/arrowslistener.h"
+
+#include "net/tmwa/messageout.h"
+#include "net/tmwa/protocol.h"
+
+#include "net/ea/eaprotocol.h"
+#include "net/ea/equipbackend.h"
+#include "net/ea/inventoryrecv.h"
+
+#include "debug.h"
+
+namespace TmwAthena
+{
+
+void InventoryRecv::processPlayerEquipment(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerEquipment")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ msg.readInt16("len");
+ Equipment *const equipment = PlayerInfo::getEquipment();
+ if (equipment && !equipment->getBackend())
+ { // look like SMSG_PLAYER_INVENTORY was not received
+ Ea::InventoryRecv::mEquips.clear();
+ equipment->setBackend(&Ea::InventoryRecv::mEquips);
+ }
+ const int number = (msg.getLength() - 4) / 20;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const uint8_t itemType = msg.readUInt8("item type");
+ const uint8_t identified = msg.readUInt8("identify");
+
+ msg.readInt16("equip type?");
+ const int equipType = msg.readInt16("equip type");
+ msg.readUInt8("attribute");
+ const uint8_t refine = msg.readUInt8("refine");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+
+ if (Ea::InventoryRecv::mDebugInventory)
+ {
+ logger->log("Index: %d, ID: %d, Type: %d, Identified: %d",
+ index, itemId, itemType, identified);
+ }
+
+ if (inventory)
+ {
+ inventory->setItem(index,
+ itemId,
+ itemType,
+ 1,
+ refine,
+ ItemColor_one,
+ fromBool(identified, Identified),
+ Damaged_false,
+ Favorite_false,
+ Equipm_true,
+ Equipped_false);
+ inventory->setCards(index, cards, 4);
+ }
+
+ if (equipType)
+ {
+ Ea::InventoryRecv::mEquips.setEquipment(
+ Ea::InventoryRecv::getSlot(equipType), index);
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerEquipment")
+}
+
+void InventoryRecv::processPlayerInventoryAdd(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerInventoryAdd")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ if (PlayerInfo::getEquipment()
+ && !PlayerInfo::getEquipment()->getBackend())
+ { // look like SMSG_PLAYER_INVENTORY was not received
+ Ea::InventoryRecv::mEquips.clear();
+ PlayerInfo::getEquipment()->setBackend(&Ea::InventoryRecv::mEquips);
+ }
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ int amount = msg.readInt16("amount");
+ const int itemId = msg.readInt16("item id");
+ const uint8_t identified = msg.readUInt8("identified");
+ msg.readUInt8("attribute");
+ const uint8_t refine = msg.readUInt8("refine");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+ const int equipType = msg.readInt16("equip type");
+ const int type = msg.readUInt8("item type");
+
+ const ItemInfo &itemInfo = ItemDB::get(itemId);
+ const unsigned char err = msg.readUInt8("status");
+ BeingId floorId;
+ if (Ea::InventoryRecv::mSentPickups.empty())
+ {
+ floorId = BeingId_zero;
+ }
+ else
+ {
+ floorId = Ea::InventoryRecv::mSentPickups.front();
+ Ea::InventoryRecv::mSentPickups.pop();
+ }
+
+ if (err)
+ {
+ PickupT pickup;
+ switch (err)
+ {
+ case 1:
+ pickup = Pickup::BAD_ITEM;
+ break;
+ case 2:
+ pickup = Pickup::TOO_HEAVY;
+ break;
+ case 3:
+ pickup = Pickup::TOO_FAR;
+ break;
+ case 4:
+ pickup = Pickup::INV_FULL;
+ break;
+ case 5:
+ pickup = Pickup::STACK_FULL;
+ break;
+ case 6:
+ pickup = Pickup::DROP_STEAL;
+ break;
+ default:
+ pickup = Pickup::UNKNOWN;
+ UNIMPLIMENTEDPACKET;
+ break;
+ }
+ if (localPlayer)
+ {
+ localPlayer->pickedUp(itemInfo,
+ 0,
+ ItemColor_one,
+ floorId,
+ pickup);
+ }
+ }
+ else
+ {
+ if (localPlayer)
+ {
+ localPlayer->pickedUp(itemInfo,
+ amount,
+ ItemColor_one,
+ floorId,
+ Pickup::OKAY);
+ }
+
+ if (inventory)
+ {
+ const Item *const item = inventory->getItem(index);
+
+ if (item && item->getId() == itemId)
+ amount += item->getQuantity();
+
+ inventory->setItem(index,
+ itemId,
+ type,
+ amount,
+ refine,
+ ItemColor_one,
+ fromBool(identified, Identified),
+ Damaged_false,
+ Favorite_false,
+ fromBool(equipType, Equipm),
+ Equipped_false);
+ inventory->setCards(index, cards, 4);
+ }
+ ArrowsListener::distributeEvent();
+ }
+ BLOCK_END("InventoryRecv::processPlayerInventoryAdd")
+}
+
+void InventoryRecv::processPlayerInventory(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerInventory")
+ Inventory *const inventory = localPlayer
+ ? PlayerInfo::getInventory() : nullptr;
+
+ if (PlayerInfo::getEquipment())
+ {
+ // Clear inventory - this will be a complete refresh
+ Ea::InventoryRecv::mEquips.clear();
+ PlayerInfo::getEquipment()->setBackend(&Ea::InventoryRecv::mEquips);
+ }
+
+ if (inventory)
+ inventory->clear();
+
+ msg.readInt16("len");
+ const int number = (msg.getLength() - 4) / 18;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ int cards[4];
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const uint8_t itemType = msg.readUInt8("item type");
+ const uint8_t identified = msg.readUInt8("identified");
+ const int amount = msg.readInt16("amount");
+ const int arrow = msg.readInt16("arrow");
+ for (int i = 0; i < 4; i++)
+ cards[i] = msg.readInt16("card");
+
+ if (Ea::InventoryRecv::mDebugInventory)
+ {
+ logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
+ "Qty: %d, Cards: %d, %d, %d, %d",
+ index, itemId, itemType, identified, amount,
+ cards[0], cards[1], cards[2], cards[3]);
+ }
+
+ // Trick because arrows are not considered equipment
+ const bool isEquipment = arrow & 0x8000;
+
+ if (inventory)
+ {
+ inventory->setItem(index,
+ itemId,
+ itemType,
+ amount,
+ 0,
+ ItemColor_one,
+ fromBool(identified, Identified),
+ Damaged_false,
+ Favorite_false,
+ fromBool(isEquipment, Equipm),
+ Equipped_false);
+ inventory->setCards(index, cards, 4);
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerInventory")
+}
+
+void InventoryRecv::processPlayerStorage(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerInventory")
+ Ea::InventoryRecv::mInventoryItems.clear();
+
+ msg.readInt16("len");
+ const int number = (msg.getLength() - 4) / 18;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ int cards[4];
+ const int index = msg.readInt16("index") - STORAGE_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const uint8_t itemType = msg.readUInt8("item type");
+ const uint8_t identified = msg.readUInt8("identified");
+ const int amount = msg.readInt16("amount");
+ msg.readInt16("arrow");
+ for (int i = 0; i < 4; i++)
+ cards[i] = msg.readInt16("card");
+
+ if (Ea::InventoryRecv::mDebugInventory)
+ {
+ logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
+ "Qty: %d, Cards: %d, %d, %d, %d",
+ index, itemId, itemType, identified, amount,
+ cards[0], cards[1], cards[2], cards[3]);
+ }
+
+ Ea::InventoryRecv::mInventoryItems.push_back(Ea::InventoryItem(
+ index,
+ itemId,
+ itemType,
+ cards,
+ amount,
+ 0,
+ ItemColor_one,
+ fromBool(identified, Identified),
+ Damaged_false,
+ Favorite_false,
+ Equipm_false));
+ }
+ BLOCK_END("InventoryRecv::processPlayerInventory")
+}
+
+void InventoryRecv::processPlayerEquip(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerEquip")
+ const int index = msg.readInt16("index") - INVENTORY_OFFSET;
+ const int equipType = msg.readInt16("equip type");
+ const uint8_t flag = msg.readUInt8("flag");
+
+ if (!flag)
+ {
+ NotifyManager::notify(NotifyTypes::EQUIP_FAILED);
+ }
+ else
+ {
+ Ea::InventoryRecv::mEquips.setEquipment(
+ Ea::InventoryRecv::getSlot(equipType), index);
+ }
+ BLOCK_END("InventoryRecv::processPlayerEquip")
+}
+
+void InventoryRecv::processPlayerUnEquip(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerUnEquip")
+ msg.readInt16("index");
+ const int equipType = msg.readInt16("equip type");
+ const uint8_t flag = msg.readUInt8("flag");
+
+ if (flag)
+ {
+ Ea::InventoryRecv::mEquips.setEquipment(
+ Ea::InventoryRecv::getSlot(equipType), -1);
+ }
+ if (equipType & 0x8000)
+ ArrowsListener::distributeEvent();
+ BLOCK_END("InventoryRecv::processPlayerUnEquip")
+}
+
+void InventoryRecv::processPlayerStorageEquip(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerStorageEquip")
+ msg.readInt16("len");
+ const int number = (msg.getLength() - 4) / 20;
+
+ for (int loop = 0; loop < number; loop++)
+ {
+ int cards[4];
+ const int index = msg.readInt16("index") - STORAGE_OFFSET;
+ const int itemId = msg.readInt16("item id");
+ const uint8_t itemType = msg.readUInt8("item type");
+ const uint8_t identified = msg.readUInt8("identified");
+ const int amount = 1;
+ msg.readInt16("equip point?");
+ msg.readInt16("another equip point?");
+ msg.readUInt8("attribute (broken)");
+ const uint8_t refine = msg.readUInt8("refine");
+ for (int i = 0; i < 4; i++)
+ cards[i] = msg.readInt16("card");
+
+ if (Ea::InventoryRecv::mDebugInventory)
+ {
+ logger->log("Index: %d, ID: %d, Type: %d, Identified: %u, "
+ "Qty: %d, Cards: %d, %d, %d, %d, Refine: %u",
+ index, itemId, itemType,
+ static_cast<unsigned int>(identified), amount,
+ cards[0], cards[1], cards[2], cards[3],
+ static_cast<unsigned int>(refine));
+ }
+
+ Ea::InventoryRecv::mInventoryItems.push_back(Ea::InventoryItem(
+ index,
+ itemId,
+ itemType,
+ cards,
+ amount,
+ refine,
+ ItemColor_one,
+ fromBool(identified, Identified),
+ Damaged_false,
+ Favorite_false,
+ Equipm_false));
+ }
+ BLOCK_END("InventoryRecv::processPlayerStorageEquip")
+}
+
+void InventoryRecv::processPlayerStorageAdd(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerStorageAdd")
+ // Move an item into storage
+ const int index = msg.readInt16("index") - STORAGE_OFFSET;
+ const int amount = msg.readInt32("amount");
+ const int itemId = msg.readInt16("item id");
+ const unsigned char identified = msg.readUInt8("identified");
+ msg.readUInt8("attribute");
+ const uint8_t refine = msg.readUInt8("refine");
+ int cards[4];
+ for (int f = 0; f < 4; f++)
+ cards[f] = msg.readInt16("card");
+
+ if (Item *const item = Ea::InventoryRecv::mStorage->getItem(index))
+ {
+ item->setId(itemId, ItemColor_one);
+ item->increaseQuantity(amount);
+ }
+ else
+ {
+ if (Ea::InventoryRecv::mStorage)
+ {
+ Ea::InventoryRecv::mStorage->setItem(index,
+ itemId,
+ 0,
+ amount,
+ refine,
+ ItemColor_one,
+ fromBool(identified, Identified),
+ Damaged_false,
+ Favorite_false,
+ Equipm_false,
+ Equipped_false);
+ Ea::InventoryRecv::mStorage->setCards(index, cards, 4);
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerStorageAdd")
+}
+
+void InventoryRecv::processPlayerStorageRemove(Net::MessageIn &msg)
+{
+ BLOCK_START("InventoryRecv::processPlayerStorageRemove")
+ // Move an item out of storage
+ const int index = msg.readInt16("index") - STORAGE_OFFSET;
+ const int amount = msg.readInt16("amount");
+ if (Ea::InventoryRecv::mStorage)
+ {
+ if (Item *const item = Ea::InventoryRecv::mStorage->getItem(index))
+ {
+ item->increaseQuantity(-amount);
+ if (item->getQuantity() == 0)
+ Ea::InventoryRecv::mStorage->removeItemAt(index);
+ }
+ }
+ BLOCK_END("InventoryRecv::processPlayerStorageRemove")
+}
+
+} // namespace TmwAthena
diff --git a/src/net/tmwa/inventoryrecv.h b/src/net/tmwa/inventoryrecv.h
new file mode 100644
index 000000000..3fe506d3a
--- /dev/null
+++ b/src/net/tmwa/inventoryrecv.h
@@ -0,0 +1,46 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2015 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NET_TMWA_INVENTORYRECV_H
+#define NET_TMWA_INVENTORYRECV_H
+
+#include "net/ea/inventoryhandler.h"
+
+#include "net/tmwa/messagehandler.h"
+
+namespace TmwAthena
+{
+ namespace InventoryRecv
+ {
+ void processPlayerEquipment(Net::MessageIn &msg);
+ void processPlayerInventoryAdd(Net::MessageIn &msg);
+ void processPlayerInventory(Net::MessageIn &msg);
+ void processPlayerStorage(Net::MessageIn &msg);
+ void processPlayerEquip(Net::MessageIn &msg);
+ void processPlayerUnEquip(Net::MessageIn &msg);
+ void processPlayerStorageEquip(Net::MessageIn &msg);
+ void processPlayerStorageAdd(Net::MessageIn &msg);
+ void processPlayerStorageRemove(Net::MessageIn &msg);
+ } // namespace InventoryRecv
+} // namespace TmwAthena
+
+#endif // NET_TMWA_INVENTORYRECV_H