diff options
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/ea/inventoryhandler.cpp | 232 | ||||
-rw-r--r-- | src/net/ea/inventoryhandler.h | 28 | ||||
-rw-r--r-- | src/net/ea/inventoryrecv.cpp | 257 | ||||
-rw-r--r-- | src/net/ea/inventoryrecv.h | 69 | ||||
-rw-r--r-- | src/net/eathena/inventoryhandler.cpp | 950 | ||||
-rw-r--r-- | src/net/eathena/inventoryhandler.h | 69 | ||||
-rw-r--r-- | src/net/eathena/inventoryrecv.cpp | 940 | ||||
-rw-r--r-- | src/net/eathena/inventoryrecv.h | 72 | ||||
-rw-r--r-- | src/net/tmwa/inventoryhandler.cpp | 439 | ||||
-rw-r--r-- | src/net/tmwa/inventoryhandler.h | 19 | ||||
-rw-r--r-- | src/net/tmwa/inventoryrecv.cpp | 464 | ||||
-rw-r--r-- | src/net/tmwa/inventoryrecv.h | 46 |
12 files changed, 1932 insertions, 1653 deletions
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 |