From 6dc1f5e0b68cf390f7938329b50a9b28bd187862 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 1 Feb 2015 23:48:15 +0300 Subject: Set correct vending status to local player. Allow buy from vending shop. --- src/CMakeLists.txt | 2 + src/Makefile.am | 2 + src/being/being.cpp | 6 +++ src/being/being.h | 2 + src/being/playerinfo.cpp | 11 +++++ src/being/playerinfo.h | 4 ++ src/enums/inventorytype.h | 1 + src/gui/models/shopitems.cpp | 45 +++++++++-------- src/gui/models/shopitems.h | 34 ++++++------- src/gui/windows/buydialog.cpp | 41 +++++++++++----- src/gui/windows/buydialog.h | 11 +++-- src/gui/windows/shopwindow.cpp | 91 +++++++++++++++++++++-------------- src/gui/windows/shopwindow.h | 5 ++ src/listeners/vendingmodelistener.cpp | 36 ++++++++++++++ src/listeners/vendingmodelistener.h | 38 +++++++++++++++ src/net/eathena/vendinghandler.cpp | 13 ++++- 16 files changed, 252 insertions(+), 90 deletions(-) create mode 100644 src/listeners/vendingmodelistener.cpp create mode 100644 src/listeners/vendingmodelistener.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f39580294..ff6986678 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1145,6 +1145,8 @@ SET(SRCS listeners/updatestatuslistener.h listeners/uploadlistener.cpp listeners/uploadlistener.h + listeners/vendingmodelistener.cpp + listeners/vendingmodelistener.h listeners/vendingslotslistener.cpp listeners/vendingslotslistener.h utils/sdlpixel.h diff --git a/src/Makefile.am b/src/Makefile.am index 11dc8364a..a788d3f80 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -223,6 +223,8 @@ manaplus_SOURCES += events/actionevent.h \ listeners/updatestatuslistener.h \ listeners/uploadlistener.cpp \ listeners/uploadlistener.h \ + listeners/vendingmodelistener.cpp \ + listeners/vendingmodelistener.h \ listeners/vendingslotslistener.cpp \ listeners/vendingslotslistener.h \ utils/sdlpixel.h \ diff --git a/src/being/being.cpp b/src/being/being.cpp index 170ad3f15..004e728c6 100644 --- a/src/being/being.cpp +++ b/src/being/being.cpp @@ -3537,3 +3537,9 @@ void Being::setBoard(const std::string &text) mBoard = text; updateName(); } + +void Being::enableShop(const bool b) +{ + mShop = b; + updateName(); +} diff --git a/src/being/being.h b/src/being/being.h index 6453e272d..043124c58 100644 --- a/src/being/being.h +++ b/src/being/being.h @@ -764,6 +764,8 @@ class Being notfinal : public ActorSprite, bool isShopEnabled() const A_WARN_UNUSED { return mShop; } + void enableShop(const bool b); + /** * Sets the attack range. */ diff --git a/src/being/playerinfo.cpp b/src/being/playerinfo.cpp index eb26ab892..91d0119b9 100644 --- a/src/being/playerinfo.cpp +++ b/src/being/playerinfo.cpp @@ -67,6 +67,7 @@ PetInfo *mPet = nullptr; GuildPositionFlags::Type mGuildPositionFlags = GuildPositionFlags::None; bool mTrading = false; +bool mVending = false; int mLevelProgress = 0; std::set mProtectedItems; @@ -572,4 +573,14 @@ GuildPositionFlags::Type getGuildPositionFlags() return mGuildPositionFlags; } +void enableVending(const bool b) +{ + mVending = b; +} + +bool isVending() +{ + return mVending; +} + } // namespace PlayerInfo diff --git a/src/being/playerinfo.h b/src/being/playerinfo.h index 807d9d03d..1f91f6e3d 100644 --- a/src/being/playerinfo.h +++ b/src/being/playerinfo.h @@ -268,6 +268,10 @@ namespace PlayerInfo void setGuildPositionFlags(const GuildPositionFlags::Type pos); GuildPositionFlags::Type getGuildPositionFlags(); + + void enableVending(const bool b); + + bool isVending() A_WARN_UNUSED; } // namespace PlayerInfo #endif // BEING_PLAYERINFO_H diff --git a/src/enums/inventorytype.h b/src/enums/inventorytype.h index 6ba30b2a4..136a80734 100644 --- a/src/enums/inventorytype.h +++ b/src/enums/inventorytype.h @@ -32,6 +32,7 @@ namespace InventoryType CART, TRADE, NPC, + VENDING, TYPE_END }; } // namespace InventoryType diff --git a/src/gui/models/shopitems.cpp b/src/gui/models/shopitems.cpp index e154c0b2e..52a0d60b2 100644 --- a/src/gui/models/shopitems.cpp +++ b/src/gui/models/shopitems.cpp @@ -50,32 +50,38 @@ std::string ShopItems::getElementAt(int i) return mShopItems.at(i)->getDisplayName(); } -void ShopItems::addItem(const int id, - const int type, - const unsigned char color, - const int amount, - const int price) +ShopItem *ShopItems::addItem(const int id, + const int type, + const unsigned char color, + const int amount, + const int price) { - mShopItems.push_back(new ShopItem(-1, id, type, color, amount, price)); + ShopItem *const item = new ShopItem(-1, id, type, color, amount, price); + mShopItems.push_back(item); + return item; } -void ShopItems::addItemNoDup(const int id, - const int type, - const unsigned char color, - const int amount, - const int price) +ShopItem *ShopItems::addItemNoDup(const int id, + const int type, + const unsigned char color, + const int amount, + const int price) { - const ShopItem *const item = findItem(id, color); + ShopItem *item = findItem(id, color); if (!item) - mShopItems.push_back(new ShopItem(-1, id, type, color, amount, price)); + { + item = new ShopItem(-1, id, type, color, amount, price); + mShopItems.push_back(item); + } + return item; } -void ShopItems::addItem2(const int inventoryIndex, - const int id, - const int type, - const unsigned char color, - const int quantity, - const int price) +ShopItem *ShopItems::addItem2(const int inventoryIndex, + const int id, + const int type, + const unsigned char color, + const int quantity, + const int price) { ShopItem *item = nullptr; if (mMergeDuplicates) @@ -90,6 +96,7 @@ void ShopItems::addItem2(const int inventoryIndex, item = new ShopItem(inventoryIndex, id, type, color, quantity, price); mShopItems.push_back(item); } + return item; } ShopItem *ShopItems::at(unsigned int i) const diff --git a/src/gui/models/shopitems.h b/src/gui/models/shopitems.h index f0db94e3a..d3d4a44fc 100644 --- a/src/gui/models/shopitems.h +++ b/src/gui/models/shopitems.h @@ -59,11 +59,11 @@ class ShopItems final : public ListModel /** * Adds an item to the list. */ - void addItem(const int id, - const int type, - const unsigned char color, - const int amount, - const int price); + ShopItem *addItem(const int id, + const int type, + const unsigned char color, + const int amount, + const int price); /** * Adds an item to the list (used by sell dialog). Looks for @@ -74,18 +74,18 @@ class ShopItems final : public ListModel * @param quantity number of available copies of the item * @param price price of the item */ - void addItem2(const int inventoryIndex, - const int id, - const int type, - const unsigned char color, - const int amount, - const int price); - - void addItemNoDup(const int id, - const int type, - const unsigned char color, - const int amount, - const int price); + ShopItem *addItem2(const int inventoryIndex, + const int id, + const int type, + const unsigned char color, + const int amount, + const int price); + + ShopItem *addItemNoDup(const int id, + const int type, + const unsigned char color, + const int amount, + const int price); /** * Returns the number of items in the shop. diff --git a/src/gui/windows/buydialog.cpp b/src/gui/windows/buydialog.cpp index b0564eb52..068440c65 100644 --- a/src/gui/windows/buydialog.cpp +++ b/src/gui/windows/buydialog.cpp @@ -22,6 +22,7 @@ #include "gui/windows/buydialog.h" +#include "actormanager.h" #include "configuration.h" #include "shopitem.h" #include "units.h" @@ -48,6 +49,8 @@ #include "net/cashshophandler.h" #include "net/markethandler.h" #include "net/npchandler.h" +#include "net/serverfeatures.h" +#include "net/vendinghandler.h" #include "resources/iteminfo.h" @@ -336,14 +339,15 @@ void BuyDialog::reset() setMoney(0); } -void BuyDialog::addItem(const int id, - const int type, - const unsigned char color, - const int amount, - const int price) +ShopItem *BuyDialog::addItem(const int id, + const int type, + const unsigned char color, + const int amount, + const int price) { - mShopItems->addItem(id, type, color, amount, price); + ShopItem *const item = mShopItems->addItem(id, type, color, amount, price); mShopItemList->adjustSize(); + return item; } void BuyDialog::sort() @@ -478,14 +482,27 @@ void BuyDialog::action(const ActionEvent &event) mSlider->setScale(1, mMaxItems); mSlider->setValue(1); } - else if (tradeWindow) + else if (mNpcId == Nick) { - if (item) + if (serverFeatures->haveVending()) { - buySellHandler->sendBuyRequest(mNick, - item, mAmountItems); - tradeWindow->addAutoMoney(mNick, - item->getPrice() * mAmountItems); + Being *const being = actorManager->findBeingByName(mNick); + if (being) + { + vendingHandler->buy(being, + item->getInvIndex(), + mAmountItems); + } + } + else if (tradeWindow) + { + if (item) + { + buySellHandler->sendBuyRequest(mNick, + item, mAmountItems); + tradeWindow->addAutoMoney(mNick, + item->getPrice() * mAmountItems); + } } } } diff --git a/src/gui/windows/buydialog.h b/src/gui/windows/buydialog.h index 06e169c92..d697eff5d 100644 --- a/src/gui/windows/buydialog.h +++ b/src/gui/windows/buydialog.h @@ -30,6 +30,7 @@ class Button; class DropDown; +class ShopItem; class ShopItems; class ShopListBox; class SortListModelBuy; @@ -99,11 +100,11 @@ class BuyDialog final : public Window, /** * Adds an item to the shop inventory. */ - void addItem(const int id, - const int type, - const unsigned char color, - const int amount, - const int price); + ShopItem *addItem(const int id, + const int type, + const unsigned char color, + const int amount, + const int price); /** * Called when receiving actions from the widgets. diff --git a/src/gui/windows/shopwindow.cpp b/src/gui/windows/shopwindow.cpp index 5d013430a..2541ae247 100644 --- a/src/gui/windows/shopwindow.cpp +++ b/src/gui/windows/shopwindow.cpp @@ -82,6 +82,7 @@ ShopWindow::ShopWindow() : Window(_("Personal Shop"), false, nullptr, "shop.xml"), ActionListener(), SelectionListener(), + VendingModeListener(), VendingSlotsListener(), // TRANSLATORS: shop window button mCloseButton(new Button(this, _("Close"), "close", this)), @@ -111,7 +112,8 @@ ShopWindow::ShopWindow() : mTradeMoney(0), mSellShopSize(0), isBuySelected(true), - mHaveVending(serverFeatures->haveVending()) + mHaveVending(serverFeatures->haveVending()), + mEnableVending(false) { mBuyShopItemList->postInit(); mSellShopItemList->postInit(); @@ -270,32 +272,37 @@ void ShopWindow::action(const ActionEvent &event) } else if (eventId == "publish") { - std::vector &oldItems = mSellShopItems->items(); - std::vector items; - Inventory *const inv = PlayerInfo::getCartInventory(); - if (!inv) - return; - FOR_EACH (std::vector::iterator, it, oldItems) + if (mEnableVending) { - ShopItem *const item = *it; - // +++ need add colors - Item *const cartItem = inv->findItem(item->getId(), 1); - if (!cartItem) - continue; - item->setInvIndex(cartItem->getInvIndex()); - const int amount = cartItem->getQuantity(); - if (!amount) - continue; - if (item->getQuantity() < amount) - item->setQuantity(amount); - items.push_back(item); - if (static_cast(items.size()) >= mSellShopSize) - break; + vendingHandler->close(); + VendingModeListener::distributeEvent(false); } - if (!items.empty()) + else { - vendingHandler->createShop("test shop", true, items); - mSellShopSize = 0; + std::vector &oldItems = mSellShopItems->items(); + std::vector items; + Inventory *const inv = PlayerInfo::getCartInventory(); + if (!inv) + return; + FOR_EACH (std::vector::iterator, it, oldItems) + { + ShopItem *const item = *it; + // +++ need add colors + Item *const cartItem = inv->findItem(item->getId(), 1); + if (!cartItem) + continue; + item->setInvIndex(cartItem->getInvIndex()); + const int amount = cartItem->getQuantity(); + if (!amount) + continue; + if (item->getQuantity() < amount) + item->setQuantity(amount); + items.push_back(item); + if (static_cast(items.size()) >= mSellShopSize) + break; + } + if (!items.empty()) + vendingHandler->createShop("test shop", true, items); } } @@ -369,18 +376,25 @@ void ShopWindow::updateButtonsAndLabels() allowDel = mSellShopItemList->getSelected() != -1 && sellNotEmpty; } mDeleteButton->setEnabled(allowDel); - if (mPublishButton - && !isBuySelected - && sellNotEmpty - && mSellShopSize > 0 - && localPlayer - && localPlayer->getHaveCart()) + if (mPublishButton) { - mPublishButton->setEnabled(true); - } - else - { - mPublishButton->setEnabled(false); + if (mEnableVending) + mPublishButton->setCaption(_("Close shop")); + else + mPublishButton->setCaption(_("Publish")); + mPublishButton->adjustSize(); + if (!isBuySelected + && sellNotEmpty + && mSellShopSize > 0 + && localPlayer + && localPlayer->getHaveCart()) + { + mPublishButton->setEnabled(true); + } + else + { + mPublishButton->setEnabled(false); + } } } @@ -958,3 +972,10 @@ void ShopWindow::vendingSlotsChanged(const int slots) { mSellShopSize = slots; } + +void ShopWindow::vendingEnabled(const bool b) +{ + mEnableVending = b; + updateButtonsAndLabels(); + localPlayer->enableShop(b); +} diff --git a/src/gui/windows/shopwindow.h b/src/gui/windows/shopwindow.h index 06f0a997d..c746bff17 100644 --- a/src/gui/windows/shopwindow.h +++ b/src/gui/windows/shopwindow.h @@ -27,6 +27,7 @@ #include "listeners/actionlistener.h" #include "listeners/selectionlistener.h" +#include "listeners/vendingmodelistener.h" #include "listeners/vendingslotslistener.h" class Button; @@ -46,6 +47,7 @@ class TabStrip; class ShopWindow final : public Window, public ActionListener, public SelectionListener, + public VendingModeListener, public VendingSlotsListener { public: @@ -141,6 +143,8 @@ class ShopWindow final : public Window, void vendingSlotsChanged(const int slots) override final; + void vendingEnabled(const bool b) override final; + private: void startTrade(); @@ -176,6 +180,7 @@ class ShopWindow final : public Window, int mSellShopSize; bool isBuySelected; bool mHaveVending; + bool mEnableVending; }; extern ShopWindow *shopWindow; diff --git a/src/listeners/vendingmodelistener.cpp b/src/listeners/vendingmodelistener.cpp new file mode 100644 index 000000000..7dd34f7ba --- /dev/null +++ b/src/listeners/vendingmodelistener.cpp @@ -0,0 +1,36 @@ +/* + * The ManaPlus Client + * Copyright (C) 2014-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 . + */ + +#include "listeners/vendingmodelistener.h" + +#include "debug.h" + +defineListener(VendingModeListener) + +void VendingModeListener::distributeEvent(const bool b) +{ + FOR_EACH (std::vector::iterator, + it, mListeners) + { + VendingModeListener *const listener = *it; + if (listener) + listener->vendingEnabled(b); + } +} diff --git a/src/listeners/vendingmodelistener.h b/src/listeners/vendingmodelistener.h new file mode 100644 index 000000000..2330c3d8d --- /dev/null +++ b/src/listeners/vendingmodelistener.h @@ -0,0 +1,38 @@ +/* + * The ManaPlus Client + * Copyright (C) 2014-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 . + */ + +#ifndef LISTENERS_VENDINGMODELISTENER_H +#define LISTENERS_VENDINGMODELISTENER_H + +#include "listeners/baselistener.hpp" + +#include "localconsts.h" + +class VendingModeListener notfinal +{ + public: + virtual void vendingEnabled(const bool b) = 0; + + static void distributeEvent(const bool b); + + defineListenerHeader(VendingModeListener) +}; + +#endif // LISTENERS_VENDINGMODELISTENER_H diff --git a/src/net/eathena/vendinghandler.cpp b/src/net/eathena/vendinghandler.cpp index 25bec7c68..823709b6f 100644 --- a/src/net/eathena/vendinghandler.cpp +++ b/src/net/eathena/vendinghandler.cpp @@ -26,10 +26,12 @@ #include "enums/being/attributes.h" #include "being/being.h" +#include "being/localplayer.h" #include "being/playerinfo.h" #include "gui/windows/buydialog.h" +#include "listeners/vendingmodelistener.h" #include "listeners/vendingslotslistener.h" #include "net/ea/eaprotocol.h" @@ -121,6 +123,8 @@ void VendingHandler::processHideBoard(Net::MessageIn &msg) Being *const dstBeing = actorManager->findBeing(id); if (dstBeing) dstBeing->setBoard(std::string()); + if (dstBeing == localPlayer) + VendingModeListener::distributeEvent(false); } void VendingHandler::processItemsList(Net::MessageIn &msg) @@ -138,7 +142,7 @@ void VendingHandler::processItemsList(Net::MessageIn &msg) { const int value = msg.readInt32("price"); const int amount = msg.readInt16("amount"); - msg.readInt16("inv index"); + const int index = msg.readInt16("inv index"); const int type = msg.readUInt8("item type"); const int itemId = msg.readInt16("item id"); msg.readUInt8("identify"); @@ -148,7 +152,10 @@ void VendingHandler::processItemsList(Net::MessageIn &msg) msg.readInt16("card"); const unsigned char color = 1; - mBuyDialog->addItem(itemId, type, color, amount, value); + ShopItem *const item = mBuyDialog->addItem(itemId, type, + color, amount, value); + if (item) + item->setInvIndex(index); } mBuyDialog->sort(); } @@ -177,6 +184,8 @@ void VendingHandler::processOpen(Net::MessageIn &msg) for (int d = 0; d < 4; d ++) msg.readInt16("card"); } + PlayerInfo::enableVending(true); + VendingModeListener::distributeEvent(true); } void VendingHandler::processReport(Net::MessageIn &msg) -- cgit v1.2.3-60-g2f50