From 1ad3e55c431b61e6fe6638ee0afc5e8f4c14496c Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 25 Aug 2016 02:55:51 +0300 Subject: Allow buy more than one item at vending shop at once. --- src/gui/windows/buydialog.cpp | 77 ++++++++++++++++++++++++++------------ src/gui/windows/buydialog.h | 17 +++++++-- src/net/eathena/vendinghandler.cpp | 35 +++++++++++++++++ src/net/eathena/vendinghandler.h | 4 ++ src/net/eathena/vendingrecv.cpp | 2 +- src/net/tmwa/vendinghandler.cpp | 6 +++ src/net/tmwa/vendinghandler.h | 4 ++ src/net/vendinghandler.h | 3 ++ 8 files changed, 119 insertions(+), 29 deletions(-) diff --git a/src/gui/windows/buydialog.cpp b/src/gui/windows/buydialog.cpp index eb01e0562..9dc2b8111 100644 --- a/src/gui/windows/buydialog.cpp +++ b/src/gui/windows/buydialog.cpp @@ -26,6 +26,8 @@ #include "configuration.h" #include "units.h" +#include "being/being.h" + #include "gui/windows/setupwindow.h" #include "gui/windows/tradewindow.h" @@ -226,6 +228,26 @@ BuyDialog::BuyDialog(std::string nick) : init(); } +BuyDialog::BuyDialog(const Being *const being) : + // TRANSLATORS: buy dialog name + Window(_("Buy"), Modal_false, nullptr, "buy.xml"), + ActionListener(), + SelectionListener(), + mSortModel(new SortListModelBuy), + mSortDropDown(new DropDown(this, mSortModel, false, + Modal_false, this, "sort")), + mFilterTextField(new TextField(this, "", true, this, "namefilter", true)), + mFilterLabel(nullptr), + mNick(being ? being->getName() : std::string()), + mNpcId(fromInt(Vending, BeingId)), + mMoney(0), + mAmountItems(0), + mMaxItems(0), + mAdvanced(true) +{ + init(); +} + void BuyDialog::init() { setWindowName("Buy"); @@ -446,6 +468,9 @@ void BuyDialog::close() case Cash: cashShopHandler->close(); break; + case Vending: + vendingHandler->close(); + break; default: buySellHandler->close(); break; @@ -523,6 +548,23 @@ void BuyDialog::action(const ActionEvent &event) item->getColor(), mAmountItems); } + else if (mNpcId == fromInt(Nick, BeingId)) + { + if (tradeWindow) + { + buySellHandler->sendBuyRequest(mNick, + item, mAmountItems); + tradeWindow->addAutoMoney(mNick, + item->getPrice() * mAmountItems); + } + } + else if (mNpcId == fromInt(Vending, BeingId)) + { + item->increaseUsedQuantity(mAmountItems); + item->update(); + if (mConfirmButton) + mConfirmButton->setEnabled(true); + } else if (mNpcId != fromInt(Nick, BeingId)) { if (mAdvanced) @@ -558,30 +600,6 @@ void BuyDialog::action(const ActionEvent &event) updateSlider(selectedItem); } - else if (mNpcId == fromInt(Nick, BeingId)) - { - if (serverFeatures->haveVending()) - { - const Being *const being = actorManager->findBeingByName( - mNick); - if (being) - { - vendingHandler->buy(being, - item->getInvIndex(), - mAmountItems); - item->increaseQuantity(-mAmountItems); - item->update(); - updateSlider(selectedItem); - } - } - else if (tradeWindow) - { - buySellHandler->sendBuyRequest(mNick, - item, mAmountItems); - tradeWindow->addAutoMoney(mNick, - item->getPrice() * mAmountItems); - } - } } else if (eventId == "confirm") { @@ -591,6 +609,17 @@ void BuyDialog::action(const ActionEvent &event) { marketHandler->buyItems(items); } + else if (mNpcId == fromInt(Vending, BeingId)) + { + const Being *const being = actorManager->findBeingByName( + mNick, + ActorType::Player); + if (being) + { + vendingHandler->buyItems(being, + items); + } + } else { npcHandler->buyItems(items); diff --git a/src/gui/windows/buydialog.h b/src/gui/windows/buydialog.h index 24e616152..fd346f53a 100644 --- a/src/gui/windows/buydialog.h +++ b/src/gui/windows/buydialog.h @@ -33,6 +33,7 @@ #include "listeners/actionlistener.h" #include "listeners/selectionlistener.h" +class Being; class Button; class DropDown; class ShopItem; @@ -76,6 +77,13 @@ class BuyDialog final : public Window, */ explicit BuyDialog(std::string nick); + /** + * Constructor. + * + * @see Window::Window + */ + explicit BuyDialog(const Being *const being); + A_DELETE_COPY(BuyDialog) /** @@ -85,10 +93,11 @@ class BuyDialog final : public Window, enum { - Nick = -1, - Items = -2, - Market = -3, - Cash = -4 + Nick = -1, + Items = -2, + Market = -3, + Cash = -4, + Vending = -5 }; void init(); diff --git a/src/net/eathena/vendinghandler.cpp b/src/net/eathena/vendinghandler.cpp index 739f39acd..35e77f954 100644 --- a/src/net/eathena/vendinghandler.cpp +++ b/src/net/eathena/vendinghandler.cpp @@ -73,6 +73,41 @@ void VendingHandler::buy(const Being *const being, outMsg.writeInt16(CAST_S16(index), "index"); } +void VendingHandler::buyItems(const Being *const being, + const std::vector &items) const +{ + int cnt = 0; + const int pairSize = 4; + + FOR_EACH (std::vector::const_iterator, it, items) + { + ShopItem *const item = *it; + const int usedQuantity = item->getUsedQuantity(); + if (!usedQuantity) + continue; + cnt ++; + } + + if (cnt > 100) + return; + + createOutPacket(CMSG_VENDING_BUY); + outMsg.writeInt16(CAST_S16(4 + 4 + pairSize * cnt), "len"); + outMsg.writeBeingId(being->getId(), "account id"); + 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(); + outMsg.writeInt16(CAST_S16(usedQuantity), "amount"); + outMsg.writeInt16(CAST_S16(item->getInvIndex()), "index"); + } +} + void VendingHandler::buy2(const Being *const being, const int vendId, const int index, diff --git a/src/net/eathena/vendinghandler.h b/src/net/eathena/vendinghandler.h index b824a8d8e..307c93ad9 100644 --- a/src/net/eathena/vendinghandler.h +++ b/src/net/eathena/vendinghandler.h @@ -45,6 +45,10 @@ class VendingHandler final : public Net::VendingHandler const int index, const int amount) const override final; + void buyItems(const Being *const being, + const std::vector &items) const + override final; + void createShop(const std::string &name, const bool flag, const std::vector &items) const diff --git a/src/net/eathena/vendingrecv.cpp b/src/net/eathena/vendingrecv.cpp index 468143dfd..d3b625159 100644 --- a/src/net/eathena/vendingrecv.cpp +++ b/src/net/eathena/vendingrecv.cpp @@ -98,7 +98,7 @@ void VendingRecv::processItemsList(Net::MessageIn &msg) if (!being) return; int cards[maxCards]; - CREATEWIDGETV(mBuyDialog, BuyDialog, being->getName()); + CREATEWIDGETV(mBuyDialog, BuyDialog, being); mBuyDialog->setMoney(PlayerInfo::getAttribute(Attributes::MONEY)); if (msg.getVersion() >= 20100105) msg.readInt32("vender id"); diff --git a/src/net/tmwa/vendinghandler.cpp b/src/net/tmwa/vendinghandler.cpp index b2da37855..6bddd659f 100644 --- a/src/net/tmwa/vendinghandler.cpp +++ b/src/net/tmwa/vendinghandler.cpp @@ -46,6 +46,12 @@ void VendingHandler::buy(const Being *const being A_UNUSED, { } +void VendingHandler::buyItems(const Being *const being A_UNUSED, + const std::vector &items A_UNUSED) + const +{ +} + void VendingHandler::buy2(const Being *const being A_UNUSED, const int vendId A_UNUSED, const int index A_UNUSED, diff --git a/src/net/tmwa/vendinghandler.h b/src/net/tmwa/vendinghandler.h index 47a99c7b4..d8023fb1c 100644 --- a/src/net/tmwa/vendinghandler.h +++ b/src/net/tmwa/vendinghandler.h @@ -41,6 +41,10 @@ class VendingHandler final : public Net::VendingHandler const int index, const int amount) const override final A_CONST; + void buyItems(const Being *const being, + const std::vector &items) const + override final A_CONST; + void buy2(const Being *const being, const int vendId, const int index, diff --git a/src/net/vendinghandler.h b/src/net/vendinghandler.h index dbabbef7a..2e5d2dffe 100644 --- a/src/net/vendinghandler.h +++ b/src/net/vendinghandler.h @@ -46,6 +46,9 @@ class VendingHandler notfinal const int index, const int amount) const = 0; + virtual void buyItems(const Being *const being, + const std::vector &items) const = 0; + virtual void buy2(const Being *const being, const int vendId, const int index, -- cgit v1.2.3-70-g09d2