ManaPlus
tradewindow.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
24 
25 #include "configuration.h"
26 #include "game.h"
27 
28 #include "being/localplayer.h"
29 #include "being/playerinfo.h"
30 #include "being/playerrelations.h"
31 
32 #include "enums/gui/layouttype.h"
33 
34 #include "gui/gui.h"
35 
36 #include "gui/fonts/font.h"
37 
41 
42 #include "gui/widgets/button.h"
45 #include "gui/widgets/label.h"
46 #include "gui/widgets/layout.h"
47 #include "gui/widgets/scrollarea.h"
48 #include "gui/widgets/textfield.h"
49 
51 
52 #include "resources/db/unitsdb.h"
53 
54 #include "resources/item/item.h"
55 
56 #include "net/net.h"
57 #include "net/tradehandler.h"
58 
59 #include "utils/delete2.h"
60 #include "utils/gettext.h"
61 
62 #include "debug.h"
63 
65 
66 // TRANSLATORS: trade window button
67 #define CAPTION_PROPOSE _("Propose trade")
68 // TRANSLATORS: trade window button
69 #define CAPTION_CONFIRMED _("Confirmed. Waiting...")
70 // TRANSLATORS: trade window button
71 #define CAPTION_ACCEPT _("Agree trade")
72 // TRANSLATORS: trade window button
73 #define CAPTION_ACCEPTED _("Agreed. Waiting...")
74 
76  // TRANSLATORS: trade window caption
77  Window(_("Trade: You"), Modal_false, nullptr, "trade.xml"),
80  mMyInventory(new Inventory(InventoryType::Trade, -1)),
81  mPartnerInventory(new Inventory(InventoryType::Trade, -1)),
82  mMyItemContainer(new ItemContainer(this, mMyInventory, 100000,
84  mPartnerItemContainer(new ItemContainer(this, mPartnerInventory, 100000,
86  // TRANSLATORS: trade window money label
87  mMoneyLabel(new Label(this, strprintf(_("You get %s"), ""))),
88  // TRANSLATORS: trade window button
89  mAddButton(new Button(this, _("Add"), "add", this)),
90  mOkButton(new Button(this, "", "", this)), // Will be filled in later
91  // TRANSLATORS: trade window money change button
92  mMoneyChangeButton(new Button(this, _("Change"), "money", this)),
93  mMoneyField(new TextField(this, std::string(),
94  LoseFocusOnTab_true, nullptr, std::string(), false)),
95  mAutoAddItem(nullptr),
96  mAutoAddToNick(""),
97  mGotMoney(0),
98  mGotMaxMoney(0),
99  mAutoMoney(0),
100  mAutoAddAmount(0),
101  mStatus(PROPOSING),
102  mOkOther(false),
103  mOkMe(false)
104 {
105  setWindowName("Trade");
106  setResizable(true);
107  setCloseButton(true);
108  setStickyButtonLock(true);
109  setDefaultSize(386, 180, ImagePosition::CENTER, 0, 0);
110  setMinWidth(310);
111  setMinHeight(180);
112 
113  if (setupWindow != nullptr)
115 
116  const Font *const fnt = mOkButton->getFont();
117  int width = std::max(fnt->getWidth(CAPTION_PROPOSE),
119  width = std::max(width, fnt->getWidth(CAPTION_ACCEPT));
120  width = std::max(width, fnt->getWidth(CAPTION_ACCEPTED));
121 
122  mOkButton->setWidth(8 + width);
123 
125 
126  ScrollArea *const myScroll = new ScrollArea(this, mMyItemContainer,
127  Opaque_true, "trade_background.xml");
129 
131 
132  ScrollArea *const partnerScroll = new ScrollArea(this,
134  Opaque_true, "trade_background.xml");
136 
137  // TRANSLATORS: trade window money label
138  Label *const moneyLabel2 = new Label(this, _("You give:"));
139 
140  mMoneyField->setWidth(40);
141 
142  place(1, 0, mMoneyLabel, 1, 1);
143  place(0, 1, myScroll, 1, 1).setPadding(3);
144  place(1, 1, partnerScroll, 1, 1).setPadding(3);
145  ContainerPlacer placer = getPlacer(0, 0);
146  placer(0, 0, moneyLabel2, 1, 1);
147  placer(1, 0, mMoneyField, 2, 1);
148  placer(3, 0, mMoneyChangeButton, 1, 1).setHAlign(LayoutCell::LEFT);
149  placer = getPlacer(0, 2);
150  placer(0, 0, mAddButton, 1, 1);
151  placer(1, 0, mOkButton, 1, 1);
152  Layout &layout = getLayout();
153  layout.extend(0, 2, 2, 1);
154  layout.setRowHeight(1, LayoutType::SET);
155  layout.setRowHeight(2, 0);
156  layout.setColWidth(0, LayoutType::SET);
157  layout.setColWidth(1, LayoutType::SET);
158 
159  loadWindowState();
160  enableVisibleSound(true);
161 
162  reset();
163 }
164 
166 {
169 }
170 
171 void TradeWindow::setMoney(const int amount)
172 {
173  if (amount < 0 || amount < mGotMaxMoney)
174  {
175  if (config.getBoolValue("securetrades"))
176  {
177  close();
178  return;
179  }
183  }
184  else
185  {
189  mGotMaxMoney = amount;
190  }
191 
192  mGotMoney = amount;
193  // TRANSLATORS: trade window money label
194  mMoneyLabel->setCaption(strprintf(_("You get %s"),
195  UnitsDb::formatCurrency(amount).c_str()));
197 }
198 
199 void TradeWindow::addItem(const int id,
200  const ItemTypeT type,
201  const bool own,
202  const int quantity,
203  const uint8_t refine,
204  const ItemColor color,
205  const Identified identified,
206  const Damaged damaged,
207  const Favorite favorite) const
208 {
209  Inventory *const inv = own ? mMyInventory : mPartnerInventory;
210  inv->addItem(id,
211  type,
212  quantity,
213  refine,
214  color,
215  identified,
216  damaged,
217  favorite,
218  Equipm_false,
220 }
221 
222 void TradeWindow::addItem2(const int id,
223  const ItemTypeT type,
224  const int *const cards,
225  const ItemOptionsList *const options,
226  const int sz,
227  const bool own,
228  const int quantity,
229  const uint8_t refine,
230  const ItemColor color,
231  const Identified identified,
232  const Damaged damaged,
233  const Favorite favorite,
234  const Equipm equipment) const
235 {
236  Inventory *const inv = own ? mMyInventory : mPartnerInventory;
237  const int slot = inv->addItem(id,
238  type,
239  quantity,
240  refine,
241  color,
242  identified,
243  damaged,
244  favorite,
245  equipment,
247  if (slot >= 0)
248  {
249  inv->setCards(slot, cards, sz);
250  inv->setOptions(slot, options);
251  }
252 }
253 
254 void TradeWindow::changeQuantity(const int index, const bool own,
255  const int quantity) const
256 {
257  Item *item;
258  if (own)
259  item = mMyInventory->getItem(index);
260  else
261  item = mPartnerInventory->getItem(index);
262  if (item != nullptr)
263  item->setQuantity(quantity);
264 }
265 
266 void TradeWindow::increaseQuantity(const int index, const bool own,
267  const int quantity) const
268 {
269  Item *item;
270  if (own)
271  item = mMyInventory->getItem(index);
272  else
273  item = mPartnerInventory->getItem(index);
274  if (item != nullptr)
275  item->increaseQuantity(quantity);
276 }
277 
279 {
280  mMyInventory->clear();
282  mOkOther = false;
283  mOkMe = false;
284  setMoney(0);
285  mMoneyField->setEnabled(true);
286  mMoneyField->setText("");
290  mAddButton->setEnabled(true);
292  mGotMoney = 0;
293  mGotMaxMoney = 0;
295 }
296 
297 void TradeWindow::receivedOk(const bool own)
298 {
299  if (own)
300  mOkMe = true;
301  else
302  mOkOther = true;
303 
304  if (mOkMe && mOkOther)
306 }
307 
309 {
310  if (config.getBoolValue("tradescreenshot"))
311  Game::createScreenshot(std::string());
313  reset();
314 }
315 
316 void TradeWindow::tradeItem(const Item *const item, const int quantity,
317  const bool check) const
318 {
319  if (check && !checkItem(item))
320  return;
321 
322  tradeHandler->addItem(item, quantity);
323 }
324 
326 {
327  if ((mMyItemContainer == nullptr) || (mPartnerItemContainer == nullptr))
328  return;
329 
330  /* If an item is selected in one container, make sure no item is selected
331  * in the other container.
332  */
333  if (event.getSource() == mMyItemContainer &&
334  (mMyItemContainer->getSelectedItem() != nullptr))
335  {
337  }
338  else if (mPartnerItemContainer->getSelectedItem() != nullptr)
339  {
341  }
342 }
343 
345 {
346  if (s == mStatus)
347  return;
348  mStatus = s;
349 
350  switch (s)
351  {
352  case PREPARING:
355  break;
356  case PROPOSING:
359  break;
360  case ACCEPTING:
362  mOkButton->setActionEventId("trade");
363  break;
364  case ACCEPTED:
367  break;
368  default:
369  break;
370  }
371 
372  mOkButton->setEnabled((s != PROPOSING && s != ACCEPTED));
373 }
374 
376 {
377  if (inventoryWindow == nullptr)
378  return;
379 
381  const std::string &eventId = event.getId();
382 
383  if (eventId == "add")
384  {
385  if (mStatus != PREPARING)
386  return;
387 
389  {
391  return;
392  }
393 
394  if (item == nullptr)
395  return;
396 
397  if (mMyInventory->getFreeSlot() == -1)
398  return;
399 
400  if (!checkItem(item))
401  return;
402 
403  // Choose amount of items to trade
405  this,
406  item,
407  0,
408  0);
409 
411  }
412  else if (eventId == "cancel")
413  {
415  reset();
417  tradeHandler->cancel();
418  }
419  else if (eventId == "ok")
420  {
421  mMoneyField->setEnabled(false);
422  mAddButton->setEnabled(false);
424  receivedOk(true);
427  }
428  else if (eventId == "trade")
429  {
430  receivedOk(true);
432  tradeHandler->finish();
433  }
434  else if (eventId == "money")
435  {
436  if (mStatus != PREPARING)
437  return;
438 
439  int v = atoi(mMoneyField->getText().c_str());
440  const int curMoney = PlayerInfo::getAttribute(Attributes::MONEY);
441  if (v > curMoney)
442  {
443  if (localChatTab != nullptr)
444  {
445  // TRANSLATORS: trade error
446  localChatTab->chatLog(_("You don't have enough money."),
450  }
451  v = curMoney;
452  }
454  mMoneyField->setText(strprintf("%d", v));
455  }
456 }
457 
459 {
460  tradeHandler->cancel();
461  clear();
462 }
463 
465 {
466  mAutoAddItem = nullptr;
467  mAutoAddToNick.clear();
468  mAutoMoney = 0;
469  mAutoAddAmount = 0;
470  mGotMoney = 0;
471  mGotMaxMoney = 0;
475 }
476 
477 void TradeWindow::addAutoItem(const std::string &nick, Item* const item,
478  const int amount)
479 {
480  mAutoAddToNick = nick;
481  mAutoAddItem = item;
482  mAutoAddAmount = amount;
483 }
484 
485 void TradeWindow::addAutoMoney(const std::string &nick, const int money)
486 {
487  mAutoAddToNick = nick;
488  mAutoMoney = money;
489 }
490 
491 void TradeWindow::initTrade(const std::string &nick)
492 {
493  if (localPlayer == nullptr)
494  return;
495 
496  if (!mAutoAddToNick.empty() && mAutoAddToNick == nick)
497  {
498  if ((mAutoAddItem != nullptr) && (mAutoAddItem->getQuantity() != 0))
499  {
500  const Inventory *const inv = PlayerInfo::getInventory();
501  if (inv != nullptr)
502  {
503  const Item *const item = inv->findItem(mAutoAddItem->getId(),
505  if (item != nullptr)
506  tradeItem(item, mAutoAddAmount, false);
507  }
508  }
509  if (mAutoMoney != 0)
510  {
513  }
514  }
515  clear();
516  if (!playerRelations.isGoodName(nick))
518 }
519 
520 bool TradeWindow::checkItem(const Item *const item) const
521 {
522  if (item == nullptr)
523  return false;
524 
525  const int itemId = item->getId();
526  if (PlayerInfo::isItemProtected(itemId))
527  return false;
528  const Item *const tItem = mMyInventory->findItem(
529  itemId, item->getColor());
530 
531  if ((tItem != nullptr) && (tItem->getQuantity() > 1
532  || item->getQuantity() > 1))
533  {
534  if (localChatTab != nullptr)
535  {
536  // TRANSLATORS: trade error
537  localChatTab->chatLog(_("Failed adding item. You can not "
538  "overlap one kind of item on the window."),
542  }
543  return false;
544  }
546  item->isEquipped() == Equipped_true)
547  {
548  if (localChatTab != nullptr)
549  {
551  // TRANSLATORS: trade error
552  _("Failed adding item. You can not trade equipped items."),
556  }
557  return false;
558  }
559  return true;
560 }
561 
563 {
564  return mMoneyField != nullptr && mMoneyField->isFocused();
565 }
Font * getFont() const
Definition: widget.cpp:330
#define CAPTION_ACCEPT
Definition: tradewindow.cpp:71
void setDefaultSize()
Definition: window.cpp:1193
LayoutCell & place(const int x, const int y, Widget *const wg, const int w, const int h)
Definition: window.cpp:1379
#define _(s)
Definition: gettext.h:34
int addItem(const int id, const ItemTypeT type, const int quantity, const uint8_t refine, const ItemColor color, const Identified identified, const Damaged damaged, const Favorite favorite, const Equipm equipment, const Equipped equipped)
Definition: inventory.cpp:114
ItemContainer * mPartnerItemContainer
Definition: tradewindow.h:193
void addAutoMoney(const std::string &nick, const int money)
static bool createScreenshot(const std::string &prefix)
Definition: game.cpp:528
virtual void finish() const
Definition: tradehandler.h:65
const bool LoseFocusOnTab_true
void setWidth(const int width)
Definition: widget.cpp:132
TradeWindow * tradeWindow
Definition: tradewindow.cpp:64
ChatTab * localChatTab
Definition: chattab.cpp:61
Gui * gui
Definition: gui.cpp:110
Definition: font.h:88
const bool Visible_true
Definition: visible.h:29
const bool Trading_false
Definition: trading.h:29
Item * getSelectedItem() const
void addItem2(const int id, const ItemTypeT type, const int *const cards, const ItemOptionsList *const options, const int sz, const bool own, const int quantity, const uint8_t refine, const ItemColor color, const Identified identified, const Damaged damaged, const Favorite favorite, const Equipm equipment) const
void loadWindowState()
Definition: window.cpp:1082
const bool ShowEmptyRows_false
Definition: showemptyrows.h:29
virtual void setMoney(const int amount) const
Definition: tradehandler.h:59
Inventory * mMyInventory
Definition: tradewindow.h:189
Item * findItem(const int itemId, const ItemColor color) const
Definition: inventory.cpp:93
Equipped isEquipped() const
Definition: item.h:128
void extend(const int x, const int y, const int w, const int h)
Definition: layoutcell.cpp:132
void action(const ActionEvent &event)
Inventory * getInventory()
Definition: playerinfo.cpp:192
void setMinWidth(const int width)
Definition: window.cpp:586
Definition: window.h:98
Definition: button.h:94
Configuration config
static void showWindow(const ItemAmountWindowUsageT usage, Window *const parent, Item *const item, int maxRange, const int tag)
void setColWidth(const int n, const int w)
Definition: layoutcell.cpp:122
Button * mAddButton
Definition: tradewindow.h:196
std::string formatCurrency(const int value)
Definition: unitsdb.cpp:323
const bool TryRemoveColors_true
void chatLog(std::string line, ChatMsgTypeT own, const IgnoreRecord ignoreRecord, const TryRemoveColors tryRemoveColors)
Definition: chattab.cpp:110
uint16_t ItemColor
Definition: itemcolor.h:29
void setStatus(const Status s)
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:595
#define delete2(var)
Definition: delete2.h:24
const bool Equipped_true
Definition: equipped.h:29
void setVisible(Visible visible)
virtual void addItem(const Item *const item, const int amount) const
Definition: tradehandler.h:51
InventoryWindow * inventoryWindow
bool isInpupFocused() const
void setMoney(const int quantity)
const bool Equipped_false
Definition: equipped.h:29
virtual bool isFocused() const
Definition: widget.cpp:183
void setText(const std::string &text)
Definition: textfield.cpp:802
void clear()
Definition: inventory.cpp:237
void registerWindowForReset(Window *const window)
bool isGoodName(Being *const being) const
void completeTrade()
#define new
Definition: debug_new.h:147
bool getBoolValue(const std::string &key) const
#define CAPTION_CONFIRMED
Definition: tradewindow.cpp:69
#define CAPTION_ACCEPTED
Definition: tradewindow.cpp:73
void setCaption(const std::string &caption)
Definition: button.h:214
ItemContainer * mMyItemContainer
Definition: tradewindow.h:192
void addItem(const int id, const ItemTypeT type, const bool own, const int quantity, const uint8_t refine, const ItemColor color, const Identified identified, const Damaged damaged, const Favorite favorite) const
virtual void cancel() const
Definition: tradehandler.h:68
int getFreeSlot() const
Definition: inventory.cpp:281
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
void setCaptionFont(Font *font)
Definition: window.h:477
void setCaption(const std::string &caption)
Definition: label.cpp:261
const bool Visible_false
Definition: visible.h:29
Definition: label.h:87
int getQuantity() const
Definition: item.h:104
Label * mMoneyLabel
Definition: tradewindow.h:195
Widget * getSource() const
Definition: event.h:103
#define CAPTION_PROPOSE
Definition: tradewindow.cpp:67
void changeQuantity(const int index, const bool own, const int quantity) const
LocalPlayer * localPlayer
bool checkItem(const Item *const item) const
const bool IgnoreRecord_false
Definition: ignorerecord.h:29
ItemColor getColor() const
Definition: item.h:180
int mAutoAddAmount
Definition: tradewindow.h:206
Definition: item.h:48
Item * mAutoAddItem
Definition: tradewindow.h:201
#define nullptr
Definition: localconsts.h:44
bool isWindowVisible() const
Definition: window.h:483
Button * mMoneyChangeButton
Definition: tradewindow.h:198
void valueChanged(const SelectionEvent &event)
Status mStatus
Definition: tradewindow.h:207
virtual void confirm() const
Definition: tradehandler.h:62
void setCloseButton(const bool flag)
Definition: window.cpp:744
void receivedOk(const bool own)
int mGotMaxMoney
Definition: tradewindow.h:204
void enableVisibleSound(bool b)
Definition: window.h:480
void setMinHeight(const int height)
Definition: window.cpp:599
ContainerPlacer getPlacer(const int x, const int y)
Definition: window.cpp:1386
void setEnabled(const bool enabled)
Definition: widget.h:351
LayoutCell & setPadding(int p)
Definition: layoutcell.h:59
void initTrade(const std::string &nick)
Layout & getLayout()
Definition: window.cpp:1360
void tradeItem(const Item *const item, const int quantity, const bool check) const
ItemType ::T ItemTypeT
Definition: itemtype.h:42
ServerTypeT getNetworkType()
Definition: net.cpp:178
void addSelectionListener(SelectionListener *listener)
bool isItemProtected(const int id)
Definition: playerinfo.cpp:511
int getId() const
Definition: item.h:80
virtual void setVisible(Visible visible)
Definition: window.cpp:773
void setCards(const int index, const int *const cards, const int size) const
Definition: inventory.cpp:193
void addAutoItem(const std::string &nick, Item *const item, const int amount)
Font * getSecureFont() const
Definition: gui.h:171
Item * getSelectedItem() const
Net::TradeHandler * tradeHandler
Definition: net.cpp:91
const bool Opaque_true
Definition: opaque.h:29
int getWidth(const std::string &text) const
Definition: font.cpp:333
const bool ForceQuantity_false
Definition: forcequantity.h:29
Button * mOkButton
Definition: tradewindow.h:197
void increaseQuantity(const int index, const bool own, const int quantity) const
void setQuantity(const int quantity)
Definition: item.h:92
void setResizable(const bool resize)
Definition: window.cpp:622
void setStickyButtonLock(const bool sticky)
Definition: window.cpp:767
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:44
TextField * mMoneyField
Definition: tradewindow.h:199
SetupWindow * setupWindow
Definition: setupwindow.cpp:63
void setForegroundColorAll(const Color &color1, const Color &color2)
Definition: label.cpp:214
void setOptions(const int index, const ItemOptionsList *const options)
Definition: inventory.cpp:209
Item * getItem(const int index) const
Definition: inventory.cpp:82
Definition: layout.h:43
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:100
PlayerRelationsManager playerRelations
void setRowHeight(const int n, const int h)
Definition: layoutcell.cpp:127
Inventory * mPartnerInventory
Definition: tradewindow.h:190
void adjustSize()
Definition: label.cpp:197
const std::string & getText() const
Definition: textfield.h:223
const bool Equipm_false
Definition: equipm.h:29
void setWindowName(const std::string &name)
Definition: window.h:354
std::string mAutoAddToNick
Definition: tradewindow.h:202
void setHorizontalScrollPolicy(const ScrollPolicy hPolicy)
void increaseQuantity(const int amount)
Definition: item.h:98
void setTrading(const Trading trading)
Definition: playerinfo.cpp:393