From cdd2dd27b61e36a376dc32947fd9e29f0a492d9b Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 31 Jan 2017 18:14:44 +0300 Subject: Allow buy multiply items at once from cash shops. --- src/enums/resources/notifytypes.h | 3 ++ src/gui/windows/buydialog.cpp | 10 ++++-- src/net/cashshophandler.h | 3 +- src/net/eathena/cashshophandler.cpp | 68 +++++++++++++++++++++++++++++++++++-- src/net/eathena/cashshophandler.h | 3 +- src/net/eathena/cashshoprecv.cpp | 34 +++++++++++++++++-- src/net/tmwa/cashshophandler.cpp | 3 +- src/net/tmwa/cashshophandler.h | 3 +- src/resources/notifications.h | 12 +++++++ 9 files changed, 127 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/enums/resources/notifytypes.h b/src/enums/resources/notifytypes.h index e7d6a7bce..a4f9a5761 100644 --- a/src/enums/resources/notifytypes.h +++ b/src/enums/resources/notifytypes.h @@ -230,6 +230,9 @@ namespace NotifyTypes SKILL_MEMO_ERROR_SKILL, BUY_TRADE_FAILED, VENDING_SOLD_ITEM, + BUY_FAILED_NPC_NOT_FOUND, + BUY_FAILED_SYSTEM_ERROR, + BUY_FAILED_WRONG_ITEM, TYPE_END }; diff --git a/src/gui/windows/buydialog.cpp b/src/gui/windows/buydialog.cpp index df478891c..d2c4e3a6a 100644 --- a/src/gui/windows/buydialog.cpp +++ b/src/gui/windows/buydialog.cpp @@ -277,11 +277,11 @@ void BuyDialog::init() setDefaultSize(260, 230, ImagePosition::CENTER); // reset advance flag for personal shops and cash shop - if (mAdvanced && ( + if (mAdvanced && #ifdef TMWA_SUPPORT - mNpcId == fromInt(Nick, BeingId) || + mNpcId == fromInt(Nick, BeingId) #endif // TMWA_SUPPORT - mNpcId == fromInt(Cash, BeingId))) + ) { mAdvanced = false; } @@ -653,6 +653,10 @@ void BuyDialog::action(const ActionEvent &event) items); } } + else if (mNpcId == fromInt(Cash, BeingId)) + { + cashShopHandler->buyItems(0, items); + } else { npcHandler->buyItems(items); diff --git a/src/net/cashshophandler.h b/src/net/cashshophandler.h index 18fbb207c..2d07be871 100644 --- a/src/net/cashshophandler.h +++ b/src/net/cashshophandler.h @@ -48,7 +48,8 @@ class CashShopHandler notfinal const ItemColor color, const int amount) const = 0; - virtual void buyItems(const std::vector &items) const = 0; + virtual void buyItems(const int points, + const std::vector &items) const = 0; virtual void close() const = 0; diff --git a/src/net/eathena/cashshophandler.cpp b/src/net/eathena/cashshophandler.cpp index 1179f0823..e5d40dca7 100644 --- a/src/net/eathena/cashshophandler.cpp +++ b/src/net/eathena/cashshophandler.cpp @@ -24,6 +24,8 @@ #include "net/eathena/messageout.h" #include "net/eathena/protocolout.h" +#include "resources/item/shopitem.h" + #include "debug.h" extern Net::CashShopHandler *cashShopHandler; @@ -54,10 +56,70 @@ void CashShopHandler::buyItem(const int points, outMsg.writeInt16(CAST_S16(itemId), "item id"); } -void CashShopHandler::buyItems(const std::vector &items A_UNUSED) - const +void CashShopHandler::buyItems(const int points, + const std::vector &items) const { - // +++ probably need impliment buy many items at same time + if (packetVersion < 20101124) + return; + + int cnt = 0; + const int pairSize = 4; + + FOR_EACH (std::vector::const_iterator, it, items) + { + const ShopItem *const item = *it; + const int usedQuantity = item->getUsedQuantity(); + const ItemTypeT type = item->getType(); + if (!usedQuantity) + continue; + if (type == ItemType::Weapon || + type == ItemType::Armor || + type == ItemType::PetEgg || + type == ItemType::PetArmor) + { + cnt += item->getUsedQuantity(); + } + else + { + cnt ++; + } + } + + if (cnt > 100) + return; + + createOutPacket(CMSG_NPC_CASH_SHOP_BUY); + outMsg.writeInt16(CAST_S16(10 + pairSize * cnt), "len"); + outMsg.writeInt32(points, "points"); + outMsg.writeInt16(cnt, "count"); + FOR_EACH (std::vector::const_iterator, it, items) + { + ShopItem *const item = *it; + const int usedQuantity = item->getUsedQuantity(); + if (!usedQuantity) + continue; + item->increaseQuantity(usedQuantity); + item->increaseUsedQuantity(-usedQuantity); + item->update(); + const ItemTypeT type = item->getType(); + if (type == ItemType::Weapon || + type == ItemType::Armor || + type == ItemType::PetEgg || + type == ItemType::PetArmor) + { + for (int f = 0; f < usedQuantity; f ++) + { + outMsg.writeInt16(CAST_S16(1), "amount"); + outMsg.writeInt16(CAST_S16(item->getId()), + "item id"); + } + } + else + { + outMsg.writeInt16(CAST_S16(usedQuantity), "amount"); + outMsg.writeInt16(CAST_S16(item->getId()), "item id"); + } + } } void CashShopHandler::close() const diff --git a/src/net/eathena/cashshophandler.h b/src/net/eathena/cashshophandler.h index c8b36f657..5fe2a6517 100644 --- a/src/net/eathena/cashshophandler.h +++ b/src/net/eathena/cashshophandler.h @@ -37,7 +37,8 @@ class CashShopHandler final : public Net::CashShopHandler const ItemColor color, const int amount) const override final; - void buyItems(const std::vector &items) const override final + void buyItems(const int points, + const std::vector &items) const override final A_CONST; void close() const override final; diff --git a/src/net/eathena/cashshoprecv.cpp b/src/net/eathena/cashshoprecv.cpp index 6c75a1052..d9912342f 100644 --- a/src/net/eathena/cashshoprecv.cpp +++ b/src/net/eathena/cashshoprecv.cpp @@ -20,8 +20,12 @@ #include "net/eathena/cashshoprecv.h" +#include "notifymanager.h" + #include "being/playerinfo.h" +#include "enums/resources/notifytypes.h" + #include "gui/windows/buydialog.h" #include "gui/widgets/createwidget.h" @@ -69,11 +73,37 @@ void CashShopRecv::processCashShopOpen(Net::MessageIn &msg) void CashShopRecv::processCashShopBuyAck(Net::MessageIn &msg) { - UNIMPLEMENTEDPACKET; msg.readInt32("cash points"); if (packetVersion >= 20070711) msg.readInt32("kafra points"); - msg.readInt16("error"); + const uint16_t res = msg.readInt16("error"); + switch (res) + { + case 0: + NotifyManager::notify(NotifyTypes::BUY_DONE); + break; + case 1: + NotifyManager::notify(NotifyTypes::BUY_FAILED_NPC_NOT_FOUND); + break; + case 2: + NotifyManager::notify(NotifyTypes::BUY_FAILED_SYSTEM_ERROR); + break; + case 3: + NotifyManager::notify(NotifyTypes::BUY_FAILED_OVERWEIGHT); + break; + case 4: + NotifyManager::notify(NotifyTypes::BUY_TRADE_FAILED); + break; + case 5: + NotifyManager::notify(NotifyTypes::BUY_FAILED_WRONG_ITEM); + break; + case 6: + NotifyManager::notify(NotifyTypes::BUY_FAILED_NO_MONEY); + break; + default: + UNIMPLEMENTEDPACKETFIELD(res); + break; + } } void CashShopRecv::processCashShopPoints(Net::MessageIn &msg) diff --git a/src/net/tmwa/cashshophandler.cpp b/src/net/tmwa/cashshophandler.cpp index d8263033e..8379de3ab 100644 --- a/src/net/tmwa/cashshophandler.cpp +++ b/src/net/tmwa/cashshophandler.cpp @@ -40,7 +40,8 @@ void CashShopHandler::buyItem(const int points A_UNUSED, { } -void CashShopHandler::buyItems(const std::vector &items A_UNUSED) +void CashShopHandler::buyItems(const int points A_UNUSED, + const std::vector &items A_UNUSED) const { } diff --git a/src/net/tmwa/cashshophandler.h b/src/net/tmwa/cashshophandler.h index 8100d6e50..6b43cdce6 100644 --- a/src/net/tmwa/cashshophandler.h +++ b/src/net/tmwa/cashshophandler.h @@ -38,7 +38,8 @@ class CashShopHandler final : public Net::CashShopHandler const ItemColor color, const int amount) const override final A_CONST; - void buyItems(const std::vector &items) const override final + void buyItems(const int points, + const std::vector &items) const override final A_CONST; void close() const override final A_CONST; diff --git a/src/resources/notifications.h b/src/resources/notifications.h index fab76d35e..8fabc0217 100644 --- a/src/resources/notifications.h +++ b/src/resources/notifications.h @@ -837,6 +837,18 @@ namespace NotifyManager {"vending sold item", ("%s"), NotifyFlags::STRING}, + {"buy fail npc not found", + // TRANSLATORS: notification message + N_("Unable to buy. Npc not found."), + NotifyFlags::EMPTY}, + {"buy fail system error", + // TRANSLATORS: notification message + N_("Unable to buy. Shop system error."), + NotifyFlags::EMPTY}, + {"buy fail wrong item", + // TRANSLATORS: notification message + N_("Unable to buy. Wrong items selected."), + NotifyFlags::EMPTY}, }; } // namespace NotifyManager #endif // RESOURCES_NOTIFICATIONS_H -- cgit v1.2.3-70-g09d2