summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/being/being.cpp6
-rw-r--r--src/being/being.h2
-rw-r--r--src/being/playerinfo.cpp11
-rw-r--r--src/being/playerinfo.h4
-rw-r--r--src/enums/inventorytype.h1
-rw-r--r--src/gui/models/shopitems.cpp45
-rw-r--r--src/gui/models/shopitems.h34
-rw-r--r--src/gui/windows/buydialog.cpp41
-rw-r--r--src/gui/windows/buydialog.h11
-rw-r--r--src/gui/windows/shopwindow.cpp91
-rw-r--r--src/gui/windows/shopwindow.h5
-rw-r--r--src/listeners/vendingmodelistener.cpp36
-rw-r--r--src/listeners/vendingmodelistener.h38
-rw-r--r--src/net/eathena/vendinghandler.cpp13
16 files changed, 252 insertions, 90 deletions
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<int> 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<ShopItem*> &oldItems = mSellShopItems->items();
- std::vector<ShopItem*> items;
- Inventory *const inv = PlayerInfo::getCartInventory();
- if (!inv)
- return;
- FOR_EACH (std::vector<ShopItem*>::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<signed int>(items.size()) >= mSellShopSize)
- break;
+ vendingHandler->close();
+ VendingModeListener::distributeEvent(false);
}
- if (!items.empty())
+ else
{
- vendingHandler->createShop("test shop", true, items);
- mSellShopSize = 0;
+ std::vector<ShopItem*> &oldItems = mSellShopItems->items();
+ std::vector<ShopItem*> items;
+ Inventory *const inv = PlayerInfo::getCartInventory();
+ if (!inv)
+ return;
+ FOR_EACH (std::vector<ShopItem*>::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<signed int>(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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "listeners/vendingmodelistener.h"
+
+#include "debug.h"
+
+defineListener(VendingModeListener)
+
+void VendingModeListener::distributeEvent(const bool b)
+{
+ FOR_EACH (std::vector<VendingModeListener*>::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 <http://www.gnu.org/licenses/>.
+ */
+
+#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)