diff options
Diffstat (limited to 'src/net/eathena')
-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 |
4 files changed, 1056 insertions, 975 deletions
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 |