From 2288a403ad4377fbb552243e805aaf0b5a4f5a0d Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 3 Nov 2015 21:54:44 +0300 Subject: Allow buy from npc shop or from market more than one of item at one transaction. --- src/gui/windows/buydialog.cpp | 67 ++++++++++++++++++++++++++++++++----- src/gui/windows/buydialog.h | 4 ++- src/net/cashshophandler.h | 5 +++ src/net/eathena/cashshophandler.cpp | 5 +++ src/net/eathena/cashshophandler.h | 2 ++ src/net/eathena/markethandler.cpp | 52 ++++++++++++++++++++++++++++ src/net/eathena/markethandler.h | 2 ++ src/net/eathena/npchandler.cpp | 51 ++++++++++++++++++++++++++++ src/net/eathena/npchandler.h | 2 ++ src/net/eathena/serverfeatures.cpp | 5 +++ src/net/eathena/serverfeatures.h | 2 ++ src/net/markethandler.h | 5 +++ src/net/npchandler.h | 6 ++++ src/net/serverfeatures.h | 2 ++ src/net/tmwa/cashshophandler.cpp | 4 +++ src/net/tmwa/cashshophandler.h | 2 ++ src/net/tmwa/markethandler.cpp | 4 +++ src/net/tmwa/markethandler.h | 2 ++ src/net/tmwa/npchandler.cpp | 4 +++ src/net/tmwa/npchandler.h | 2 ++ src/net/tmwa/serverfeatures.cpp | 5 +++ src/net/tmwa/serverfeatures.h | 2 ++ src/shopitem.cpp | 28 ++++++++++++++-- src/shopitem.h | 6 ++++ 24 files changed, 257 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/gui/windows/buydialog.cpp b/src/gui/windows/buydialog.cpp index 667867ff4..a7769482a 100644 --- a/src/gui/windows/buydialog.cpp +++ b/src/gui/windows/buydialog.cpp @@ -180,11 +180,12 @@ BuyDialog::BuyDialog() : mSortDropDown(nullptr), mFilterTextField(new TextField(this, "", true, this, "namefilter", true)), mFilterLabel(nullptr), + mNick(), mNpcId(fromInt(Items, BeingId)), mMoney(0), mAmountItems(0), mMaxItems(0), - mNick() + mAdvanced(false) { init(); } @@ -198,11 +199,12 @@ BuyDialog::BuyDialog(const BeingId npcId) : mSortDropDown(nullptr), mFilterTextField(new TextField(this, "", true, this, "namefilter", true)), mFilterLabel(nullptr), + mNick(), mNpcId(npcId), mMoney(0), mAmountItems(0), mMaxItems(0), - mNick() + mAdvanced(serverFeatures ? serverFeatures->haveAdvancedBuySell() : false) { init(); } @@ -217,11 +219,12 @@ BuyDialog::BuyDialog(std::string nick) : Modal_false, this, "sort")), mFilterTextField(new TextField(this, "", true, this, "namefilter", true)), mFilterLabel(nullptr), + mNick(nick), mNpcId(fromInt(Nick, BeingId)), mMoney(0), mAmountItems(0), mMaxItems(0), - mNick(nick) + mAdvanced(false) { init(); } @@ -236,6 +239,13 @@ void BuyDialog::init() setMinHeight(220); setDefaultSize(260, 230, ImageRect::CENTER); + // reset advance flag for personal shops and cash shop + if (mAdvanced && + (mNpcId == fromInt(Nick, BeingId) || mNpcId == fromInt(Cash, BeingId))) + { + mAdvanced = false; + } + if (setupWindow) setupWindow->registerWindowForReset(this); @@ -270,9 +280,19 @@ void BuyDialog::init() // TRANSLATORS: This is a narrow symbol used to denote 'decreasing'. // You may change this symbol if your language uses another. mDecreaseButton = new Button(this, _("-"), "dec", this); - // TRANSLATORS: buy dialog button mBuyButton = new Button(this, mNpcId == fromInt(Items, BeingId) - ? _("Create") :_("Buy"), "buy", this); + // TRANSLATORS: buy dialog button + ? _("Create") : (mAdvanced ? _("Add") : _("Buy")), "buy", this); + if (mAdvanced) + { + // TRANSLATORS: buy dialog button + mConfirmButton = new Button(this, _("Buy"), "confirm", this); + mConfirmButton->setEnabled(false); + } + else + { + mConfirmButton = nullptr; + } // TRANSLATORS: buy dialog button mQuitButton = new Button(this, _("Quit"), "quit", this); // TRANSLATORS: buy dialog button @@ -318,7 +338,15 @@ void BuyDialog::init() placer(0, 8, mFilterLabel, 2); } placer(2, 8, mFilterTextField, 2); - placer(7, 8, mBuyButton); + if (mAdvanced) + { + placer(6, 8, mBuyButton); + placer(7, 8, mConfirmButton); + } + else + { + placer(7, 8, mBuyButton); + } placer(8, 8, mQuitButton); Layout &layout = getLayout(); @@ -498,8 +526,15 @@ void BuyDialog::action(const ActionEvent &event) } else if (mNpcId != fromInt(Nick, BeingId)) { + if (mAdvanced) + { + item->increaseUsedQuantity(mAmountItems); + item->update(); + if (mConfirmButton) + mConfirmButton->setEnabled(true); + } #ifdef EATHENA_SUPPORT - if (mNpcId == fromInt(Market, BeingId)) + else if (mNpcId == fromInt(Market, BeingId)) { marketHandler->buyItem(item->getId(), item->getType(), @@ -515,8 +550,8 @@ void BuyDialog::action(const ActionEvent &event) item->getColor(), mAmountItems); } - else #endif + else { npcHandler->buyItem(mNpcId, item->getId(), @@ -554,6 +589,22 @@ void BuyDialog::action(const ActionEvent &event) } } } + else if (eventId == "confirm") + { + std::vector &items = mShopItems->allItems(); + +#ifdef EATHENA_SUPPORT + if (mNpcId == fromInt(Market, BeingId)) + { + marketHandler->buyItems(items); + } +#endif + else + { + npcHandler->buyItems(items); + } + close(); + } } void BuyDialog::updateSlider(const int selectedItem) diff --git a/src/gui/windows/buydialog.h b/src/gui/windows/buydialog.h index dbb84b0ef..b74680509 100644 --- a/src/gui/windows/buydialog.h +++ b/src/gui/windows/buydialog.h @@ -159,6 +159,7 @@ class BuyDialog final : public Window, static DialogList instances; Button *mBuyButton A_NONNULLPOINTER; + Button *mConfirmButton A_NONNULLPOINTER; Button *mQuitButton A_NONNULLPOINTER; Button *mAddMaxButton A_NONNULLPOINTER; Button *mIncreaseButton A_NONNULLPOINTER; @@ -176,11 +177,12 @@ class BuyDialog final : public Window, TextField *mFilterTextField A_NONNULLPOINTER; Label *mFilterLabel; + std::string mNick; BeingId mNpcId; int mMoney; int mAmountItems; int mMaxItems; - std::string mNick; + bool mAdvanced; }; #endif // GUI_WINDOWS_BUYDIALOG_H diff --git a/src/net/cashshophandler.h b/src/net/cashshophandler.h index 1577aa543..9ff528404 100644 --- a/src/net/cashshophandler.h +++ b/src/net/cashshophandler.h @@ -26,9 +26,12 @@ #include "enums/simpletypes/itemcolor.h" #include +#include #include "localconsts.h" +class ShopItem; + namespace Net { @@ -43,6 +46,8 @@ class CashShopHandler notfinal const ItemColor color, const int amount) const = 0; + virtual void buyItems(std::vector &items) const = 0; + virtual void close() const = 0; virtual void requestPoints() const = 0; diff --git a/src/net/eathena/cashshophandler.cpp b/src/net/eathena/cashshophandler.cpp index 5bb54b119..9dcbe208a 100644 --- a/src/net/eathena/cashshophandler.cpp +++ b/src/net/eathena/cashshophandler.cpp @@ -50,6 +50,11 @@ void CashShopHandler::buyItem(const int points, outMsg.writeInt16(static_cast(itemId), "item id"); } +void CashShopHandler::buyItems(std::vector &items A_UNUSED) const +{ + // +++ probably need impliment buy many items at same time +} + void CashShopHandler::close() const { createOutPacket(CMSG_NPC_CASH_SHOP_CLOSE); diff --git a/src/net/eathena/cashshophandler.h b/src/net/eathena/cashshophandler.h index 099aa3e92..132d019b8 100644 --- a/src/net/eathena/cashshophandler.h +++ b/src/net/eathena/cashshophandler.h @@ -39,6 +39,8 @@ class CashShopHandler final : public Net::CashShopHandler const ItemColor color, const int amount) const override final; + void buyItems(std::vector &items) const override final; + void close() const override final; void requestPoints() const override final; diff --git a/src/net/eathena/markethandler.cpp b/src/net/eathena/markethandler.cpp index b96e5b588..47aa05418 100644 --- a/src/net/eathena/markethandler.cpp +++ b/src/net/eathena/markethandler.cpp @@ -18,6 +18,8 @@ * along with this program. If not, see . */ +#include "shopitem.h" + #include "net/eathena/markethandler.h" #include "net/eathena/marketrecv.h" @@ -62,4 +64,54 @@ void MarketHandler::buyItem(const int itemId, } } +void MarketHandler::buyItems(std::vector &items) const +{ + int cnt = 0; + const int pairSize = 6; + + FOR_EACH (std::vector::iterator, it, items) + { + ShopItem *const item = *it; + const int usedQuantity = item->getUsedQuantity(); + const int type = item->getType(); + if (!usedQuantity) + continue; + if (type == 4 || type == 5 || type == 7 || type == 8) + cnt += item->getUsedQuantity(); + else + cnt ++; + } + + if (cnt > 100) + return; + + createOutPacket(CMSG_NPC_MARKET_BUY); + outMsg.writeInt16(static_cast(4 + pairSize * cnt), "len"); + FOR_EACH (std::vector::iterator, it, items) + { + ShopItem *const item = *it; + const int usedQuantity = item->getUsedQuantity(); + if (!usedQuantity) + continue; + item->increaseQuantity(usedQuantity); + item->increaseUsedQuantity(-usedQuantity); + item->update(); + const int type = item->getType(); + if (type == 4 || type == 5 || type == 7 || type == 8) + { + for (int f = 0; f < usedQuantity; f ++) + { + outMsg.writeInt16(static_cast(item->getId()), + "item id"); + outMsg.writeInt32(static_cast(1), "amount"); + } + } + else + { + outMsg.writeInt16(static_cast(item->getId()), "item id"); + outMsg.writeInt32(static_cast(usedQuantity), "amount"); + } + } +} + } // namespace EAthena diff --git a/src/net/eathena/markethandler.h b/src/net/eathena/markethandler.h index 30d1eb2b1..bcc59e351 100644 --- a/src/net/eathena/markethandler.h +++ b/src/net/eathena/markethandler.h @@ -39,6 +39,8 @@ class MarketHandler final : public Net::MarketHandler const int type, const ItemColor color, const int amount) const override final; + + void buyItems(std::vector &items) const override final; }; } // namespace EAthena diff --git a/src/net/eathena/npchandler.cpp b/src/net/eathena/npchandler.cpp index c84c0cab6..dc01d512c 100644 --- a/src/net/eathena/npchandler.cpp +++ b/src/net/eathena/npchandler.cpp @@ -22,6 +22,8 @@ #include "net/eathena/npchandler.h" +#include "shopitem.h" + #include "being/localplayer.h" #include "gui/windows/npcdialog.h" @@ -130,6 +132,55 @@ void NpcHandler::buyItem(const BeingId beingId A_UNUSED, outMsg.writeInt16(static_cast(itemId), "item id"); } +void NpcHandler::buyItems(std::vector &items) const +{ + int cnt = 0; + const int pairSize = 4; + + FOR_EACH (std::vector::iterator, it, items) + { + ShopItem *const item = *it; + const int usedQuantity = item->getUsedQuantity(); + const int type = item->getType(); + if (!usedQuantity) + continue; + if (type == 4 || type == 5 || type == 7 || type == 8) + cnt += item->getUsedQuantity(); + else + cnt ++; + } + + if (cnt > 100) + return; + + createOutPacket(CMSG_NPC_BUY_REQUEST); + outMsg.writeInt16(static_cast(4 + pairSize * cnt), "len"); + FOR_EACH (std::vector::iterator, it, items) + { + ShopItem *const item = *it; + const int usedQuantity = item->getUsedQuantity(); + if (!usedQuantity) + continue; + item->increaseUsedQuantity(-usedQuantity); + item->update(); + const int type = item->getType(); + if (type == 4 || type == 5 || type == 7 || type == 8) + { + for (int f = 0; f < usedQuantity; f ++) + { + outMsg.writeInt16(static_cast(1), "amount"); + outMsg.writeInt16(static_cast(item->getId()), + "item id"); + } + } + else + { + outMsg.writeInt16(static_cast(usedQuantity), "amount"); + outMsg.writeInt16(static_cast(item->getId()), "item id"); + } + } +} + void NpcHandler::sellItem(const BeingId beingId A_UNUSED, const int itemId, const int amount) const { diff --git a/src/net/eathena/npchandler.h b/src/net/eathena/npchandler.h index b1ef9128d..608c7d775 100644 --- a/src/net/eathena/npchandler.h +++ b/src/net/eathena/npchandler.h @@ -59,6 +59,8 @@ class NpcHandler final : public Ea::NpcHandler const ItemColor color, const int amount) const override final; + void buyItems(std::vector &items) const override final; + void sellItem(const BeingId beingId, const int itemId, const int amount) const override final; diff --git a/src/net/eathena/serverfeatures.cpp b/src/net/eathena/serverfeatures.cpp index b3f4b7814..fbc97b97e 100644 --- a/src/net/eathena/serverfeatures.cpp +++ b/src/net/eathena/serverfeatures.cpp @@ -245,4 +245,9 @@ bool ServerFeatures::haveExtendedRiding() const return serverVersion >= 9; } +bool ServerFeatures::haveAdvancedBuySell() const +{ + return true; +} + } // namespace EAthena diff --git a/src/net/eathena/serverfeatures.h b/src/net/eathena/serverfeatures.h index b1fc7c74e..6bb2176ae 100644 --- a/src/net/eathena/serverfeatures.h +++ b/src/net/eathena/serverfeatures.h @@ -117,6 +117,8 @@ class ServerFeatures final : public Net::ServerFeatures bool haveAdvancedSprites() const override final; bool haveExtendedRiding() const override final; + + bool haveAdvancedBuySell() const override final; }; } // namespace EAthena diff --git a/src/net/markethandler.h b/src/net/markethandler.h index 13027024e..2037d95cf 100644 --- a/src/net/markethandler.h +++ b/src/net/markethandler.h @@ -26,9 +26,12 @@ #include "enums/simpletypes/itemcolor.h" #include +#include #include "localconsts.h" +class ShopItem; + namespace Net { @@ -44,6 +47,8 @@ class MarketHandler notfinal const int type, const ItemColor color, const int amount) const = 0; + + virtual void buyItems(std::vector &items) const = 0; }; } // namespace Net diff --git a/src/net/npchandler.h b/src/net/npchandler.h index e3ef4ab23..cb7a088f1 100644 --- a/src/net/npchandler.h +++ b/src/net/npchandler.h @@ -32,8 +32,12 @@ #include "enums/simpletypes/beingid.h" #include "enums/simpletypes/itemcolor.h" +#include + #include "localconsts.h" +class ShopItem; + namespace Net { @@ -72,6 +76,8 @@ class NpcHandler notfinal const ItemColor color, const int amount) const = 0; + virtual void buyItems(std::vector &items) const = 0; + virtual void sellItem(const BeingId beingId, const int itemId, const int amount) const = 0; diff --git a/src/net/serverfeatures.h b/src/net/serverfeatures.h index c03d409af..5926d9d3a 100644 --- a/src/net/serverfeatures.h +++ b/src/net/serverfeatures.h @@ -114,6 +114,8 @@ class ServerFeatures notfinal virtual bool haveAdvancedSprites() const = 0; virtual bool haveExtendedRiding() const = 0; + + virtual bool haveAdvancedBuySell() const = 0; }; } // namespace Net diff --git a/src/net/tmwa/cashshophandler.cpp b/src/net/tmwa/cashshophandler.cpp index a0b6d64cd..e940d2a54 100644 --- a/src/net/tmwa/cashshophandler.cpp +++ b/src/net/tmwa/cashshophandler.cpp @@ -39,6 +39,10 @@ void CashShopHandler::buyItem(const int points A_UNUSED, { } +void CashShopHandler::buyItems(std::vector &items A_UNUSED) const +{ +} + void CashShopHandler::close() const { } diff --git a/src/net/tmwa/cashshophandler.h b/src/net/tmwa/cashshophandler.h index 7d90067c8..c81ed394e 100644 --- a/src/net/tmwa/cashshophandler.h +++ b/src/net/tmwa/cashshophandler.h @@ -40,6 +40,8 @@ class CashShopHandler final : public Net::CashShopHandler const ItemColor color, const int amount) const override final; + void buyItems(std::vector &items) const override final; + void close() const override final; void requestPoints() const override final; diff --git a/src/net/tmwa/markethandler.cpp b/src/net/tmwa/markethandler.cpp index b9dbfa4bb..4eb36c841 100644 --- a/src/net/tmwa/markethandler.cpp +++ b/src/net/tmwa/markethandler.cpp @@ -43,4 +43,8 @@ void MarketHandler::buyItem(const int itemId A_UNUSED, { } +void MarketHandler::buyItems(std::vector &items A_UNUSED) const +{ +} + } // namespace TmwAthena diff --git a/src/net/tmwa/markethandler.h b/src/net/tmwa/markethandler.h index 7bbf04aea..9cd4b0b8b 100644 --- a/src/net/tmwa/markethandler.h +++ b/src/net/tmwa/markethandler.h @@ -40,6 +40,8 @@ class MarketHandler final : public Net::MarketHandler const int type, const ItemColor color, const int amount) const override final; + + void buyItems(std::vector &items) const override final; }; } // namespace TmwAthena diff --git a/src/net/tmwa/npchandler.cpp b/src/net/tmwa/npchandler.cpp index 4b24bce1f..57ad5850f 100644 --- a/src/net/tmwa/npchandler.cpp +++ b/src/net/tmwa/npchandler.cpp @@ -130,6 +130,10 @@ void NpcHandler::buyItem(const BeingId beingId A_UNUSED, outMsg.writeInt16(static_cast(itemId), "item id"); } +void NpcHandler::buyItems(std::vector &items A_UNUSED) const +{ +} + void NpcHandler::sellItem(const BeingId beingId A_UNUSED, const int itemId, const int amount) const diff --git a/src/net/tmwa/npchandler.h b/src/net/tmwa/npchandler.h index 3a3cb1969..6eed8e81f 100644 --- a/src/net/tmwa/npchandler.h +++ b/src/net/tmwa/npchandler.h @@ -59,6 +59,8 @@ class NpcHandler final : public Ea::NpcHandler const ItemColor color, const int amount) const override final; + void buyItems(std::vector &items) const override final; + void sellItem(const BeingId beingId, const int itemId, const int amount) const override final; diff --git a/src/net/tmwa/serverfeatures.cpp b/src/net/tmwa/serverfeatures.cpp index 566bcc983..a2d60675a 100644 --- a/src/net/tmwa/serverfeatures.cpp +++ b/src/net/tmwa/serverfeatures.cpp @@ -244,4 +244,9 @@ bool ServerFeatures::haveExtendedRiding() const return false; } +bool ServerFeatures::haveAdvancedBuySell() const +{ + return false; +} + } // namespace TmwAthena diff --git a/src/net/tmwa/serverfeatures.h b/src/net/tmwa/serverfeatures.h index 33eb1457d..7a0008583 100644 --- a/src/net/tmwa/serverfeatures.h +++ b/src/net/tmwa/serverfeatures.h @@ -117,6 +117,8 @@ class ServerFeatures final : public Net::ServerFeatures bool haveAdvancedSprites() const override final; bool haveExtendedRiding() const override final; + + bool haveAdvancedBuySell() const override final; }; } // namespace TmwAthena diff --git a/src/shopitem.cpp b/src/shopitem.cpp index faf635fbd..0430e4d0f 100644 --- a/src/shopitem.cpp +++ b/src/shopitem.cpp @@ -22,6 +22,7 @@ #include "shopitem.h" +#include "logger.h" #include "units.h" #include "resources/iteminfo.h" @@ -47,6 +48,7 @@ ShopItem::ShopItem(const int inventoryIndex, mDisplayName(), mDuplicates(), mPrice(price), + mUsedQuantity(0), mShowQuantity(true), mVisible(true) { @@ -68,6 +70,7 @@ ShopItem::ShopItem(const int id, mDisplayName(), mDuplicates(), mPrice(price), + mUsedQuantity(0), mShowQuantity(false), mVisible(true) { @@ -97,14 +100,15 @@ void ShopItem::updateDisplayName(const int quantity) mDisplayName.append(" (").append( Units::formatCurrency(mPrice)).append(") "); } - if (quantity > 1) + if (mShowQuantity && quantity > 1) mDisplayName.append("[").append(toString(quantity)).append("]"); + if (mUsedQuantity > 0) + mDisplayName.append(" +").append(toString(mUsedQuantity)); } void ShopItem::update() { - if (mShowQuantity) - updateDisplayName(mQuantity); + updateDisplayName(mQuantity); } void ShopItem::addDuplicate(const int inventoryIndex, const int quantity) @@ -141,3 +145,21 @@ int ShopItem::sellCurrentDuplicate(const int quantity) } return sellCount; } + +void ShopItem::increaseUsedQuantity(const int amount) +{ + if (mShowQuantity && mQuantity) + { + if (mQuantity < mUsedQuantity + amount || + mUsedQuantity + amount < 0) + { + return; + } + } + else if (mUsedQuantity + amount < 0) + { + return; + } + + mUsedQuantity += amount; +} diff --git a/src/shopitem.h b/src/shopitem.h index a1c3d5649..bfe7fe39a 100644 --- a/src/shopitem.h +++ b/src/shopitem.h @@ -143,6 +143,11 @@ class ShopItem final : public Item bool isVisible() const { return mVisible; } + void increaseUsedQuantity(const int amount); + + int getUsedQuantity() const A_WARN_UNUSED + { return mUsedQuantity; } + protected: void updateDisplayName(const int quantity); @@ -158,6 +163,7 @@ class ShopItem final : public Item } DuplicateItem; std::stack mDuplicates; /** <-- Stores duplicates */ int mPrice; + int mUsedQuantity; bool mShowQuantity; bool mVisible; }; -- cgit v1.2.3-70-g09d2