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", BUTTON_SKIN, this)),
90  mOkButton(new Button(this, "", "",
91  BUTTON_SKIN, this)), // Will be filled in later
92  // TRANSLATORS: trade window money change button
93  mMoneyChangeButton(new Button(this, _("Change"), "money",
94  BUTTON_SKIN, this)),
95  mMoneyField(new TextField(this, std::string(),
96  LoseFocusOnTab_true, nullptr, std::string(), false)),
97  mAutoAddItem(nullptr),
98  mAutoAddToNick(""),
99  mGotMoney(0),
100  mGotMaxMoney(0),
101  mAutoMoney(0),
102  mAutoAddAmount(0),
103  mStatus(PROPOSING),
104  mOkOther(false),
105  mOkMe(false)
106 {
107  setWindowName("Trade");
108  setResizable(true);
109  setCloseButton(true);
110  setStickyButtonLock(true);
111  setDefaultSize(386, 180, ImagePosition::CENTER, 0, 0);
112  setMinWidth(310);
113  setMinHeight(180);
114 
115  if (setupWindow != nullptr)
117 
118  const Font *const fnt = mOkButton->getFont();
119  int width = std::max(fnt->getWidth(CAPTION_PROPOSE),
121  width = std::max(width, fnt->getWidth(CAPTION_ACCEPT));
122  width = std::max(width, fnt->getWidth(CAPTION_ACCEPTED));
123 
124  mOkButton->setWidth(8 + width);
125 
127 
128  ScrollArea *const myScroll = new ScrollArea(this, mMyItemContainer,
129  Opaque_true, "trade_background.xml");
131 
133 
134  ScrollArea *const partnerScroll = new ScrollArea(this,
136  Opaque_true, "trade_background.xml");
138 
139  // TRANSLATORS: trade window money label
140  Label *const moneyLabel2 = new Label(this, _("You give:"));
141 
142  mMoneyField->setWidth(40);
143 
144  place(1, 0, mMoneyLabel, 1, 1);
145  place(0, 1, myScroll, 1, 1).setPadding(3);
146  place(1, 1, partnerScroll, 1, 1).setPadding(3);
147  ContainerPlacer placer = getPlacer(0, 0);
148  placer(0, 0, moneyLabel2, 1, 1);
149  placer(1, 0, mMoneyField, 2, 1);
150  placer(3, 0, mMoneyChangeButton, 1, 1).setHAlign(LayoutCell::LEFT);
151  placer = getPlacer(0, 2);
152  placer(0, 0, mAddButton, 1, 1);
153  placer(1, 0, mOkButton, 1, 1);
154  Layout &layout = getLayout();
155  layout.extend(0, 2, 2, 1);
156  layout.setRowHeight(1, LayoutType::SET);
157  layout.setRowHeight(2, 0);
158  layout.setColWidth(0, LayoutType::SET);
159  layout.setColWidth(1, LayoutType::SET);
160 
161  loadWindowState();
162  enableVisibleSound(true);
163 
164  reset();
165 }
166 
168 {
171 }
172 
173 void TradeWindow::setMoney(const int amount)
174 {
175  if (amount < 0 || amount < mGotMaxMoney)
176  {
177  if (config.getBoolValue("securetrades"))
178  {
179  close();
180  return;
181  }
185  }
186  else
187  {
191  mGotMaxMoney = amount;
192  }
193 
194  mGotMoney = amount;
195  // TRANSLATORS: trade window money label
196  mMoneyLabel->setCaption(strprintf(_("You get %s"),
197  UnitsDb::formatCurrency(amount).c_str()));
199 }
200 
201 void TradeWindow::addItem(const int id,
202  const ItemTypeT type,
203  const bool own,
204  const int quantity,
205  const uint8_t refine,
206  const ItemColor color,
207  const Identified identified,
208  const Damaged damaged,
209  const Favorite favorite) const
210 {
211  Inventory *const inv = own ? mMyInventory : mPartnerInventory;
212  inv->addItem(id,
213  type,
214  quantity,
215  refine,
216  color,
217  identified,
218  damaged,
219  favorite,
220  Equipm_false,
222 }
223 
224 void TradeWindow::addItem2(const int id,
225  const ItemTypeT type,
226  const int *const cards,
227  const ItemOptionsList *const options,
228  const int sz,
229  const bool own,
230  const int quantity,
231  const uint8_t refine,
232  const ItemColor color,
233  const Identified identified,
234  const Damaged damaged,
235  const Favorite favorite,
236  const Equipm equipment) const
237 {
238  Inventory *const inv = own ? mMyInventory : mPartnerInventory;
239  const int slot = inv->addItem(id,
240  type,
241  quantity,
242  refine,
243  color,
244  identified,
245  damaged,
246  favorite,
247  equipment,
249  if (slot >= 0)
250  {
251  inv->setCards(slot, cards, sz);
252  inv->setOptions(slot, options);
253  }
254 }
255 
256 void TradeWindow::changeQuantity(const int index, const bool own,
257  const int quantity) const
258 {
259  Item *item;
260  if (own)
261  item = mMyInventory->getItem(index);
262  else
263  item = mPartnerInventory->getItem(index);
264  if (item != nullptr)
265  item->setQuantity(quantity);
266 }
267 
268 void TradeWindow::increaseQuantity(const int index, const bool own,
269  const int quantity) const
270 {
271  Item *item;
272  if (own)
273  item = mMyInventory->getItem(index);
274  else
275  item = mPartnerInventory->getItem(index);
276  if (item != nullptr)
277  item->increaseQuantity(quantity);
278 }
279 
281 {
282  mMyInventory->clear();
284  mOkOther = false;
285  mOkMe = false;
286  setMoney(0);
287  mMoneyField->setEnabled(true);
288  mMoneyField->setText("");
292  mAddButton->setEnabled(true);
294  mGotMoney = 0;
295  mGotMaxMoney = 0;
297 }
298 
299 void TradeWindow::receivedOk(const bool own)
300 {
301  if (own)
302  mOkMe = true;
303  else
304  mOkOther = true;
305 
306  if (mOkMe && mOkOther)
308 }
309 
311 {
312  if (config.getBoolValue("tradescreenshot"))
313  Game::createScreenshot(std::string());
315  reset();
316 }
317 
318 void TradeWindow::tradeItem(const Item *const item, const int quantity,
319  const bool check) const
320 {
321  if (check && !checkItem(item))
322  return;
323 
324  tradeHandler->addItem(item, quantity);
325 }
326 
328 {
329  if ((mMyItemContainer == nullptr) || (mPartnerItemContainer == nullptr))
330  return;
331 
332  /* If an item is selected in one container, make sure no item is selected
333  * in the other container.
334  */
335  if (event.getSource() == mMyItemContainer &&
336  (mMyItemContainer->getSelectedItem() != nullptr))
337  {
339  }
340  else if (mPartnerItemContainer->getSelectedItem() != nullptr)
341  {
343  }
344 }
345 
347 {
348  if (s == mStatus)
349  return;
350  mStatus = s;
351 
352  switch (s)
353  {
354  case PREPARING:
357  break;
358  case PROPOSING:
361  break;
362  case ACCEPTING:
364  mOkButton->setActionEventId("trade");
365  break;
366  case ACCEPTED:
369  break;
370  default:
371  break;
372  }
373 
374  mOkButton->setEnabled((s != PROPOSING && s != ACCEPTED));
375 }
376 
378 {
379  if (inventoryWindow == nullptr)
380  return;
381 
383  const std::string &eventId = event.getId();
384 
385  if (eventId == "add")
386  {
387  if (mStatus != PREPARING)
388  return;
389 
391  {
393  return;
394  }
395 
396  if (item == nullptr)
397  return;
398 
399  if (mMyInventory->getFreeSlot() == -1)
400  return;
401 
402  if (!checkItem(item))
403  return;
404 
405  // Choose amount of items to trade
407  this,
408  item,
409  0,
410  0);
411 
413  }
414  else if (eventId == "cancel")
415  {
417  reset();
419  tradeHandler->cancel();
420  }
421  else if (eventId == "ok")
422  {
423  mMoneyField->setEnabled(false);
424  mAddButton->setEnabled(false);
426  receivedOk(true);
429  }
430  else if (eventId == "trade")
431  {
432  receivedOk(true);
434  tradeHandler->finish();
435  }
436  else if (eventId == "money")
437  {
438  if (mStatus != PREPARING)
439  return;
440 
441  int v = atoi(mMoneyField->getText().c_str());
442  const int curMoney = PlayerInfo::getAttribute(Attributes::MONEY);
443  if (v > curMoney)
444  {
445  if (localChatTab != nullptr)
446  {
447  // TRANSLATORS: trade error
448  localChatTab->chatLog(_("You don't have enough money."),
452  }
453  v = curMoney;
454  }
456  mMoneyField->setText(strprintf("%d", v));
457  }
458 }
459 
461 {
462  tradeHandler->cancel();
463  clear();
464 }
465 
467 {
468  mAutoAddItem = nullptr;
469  mAutoAddToNick.clear();
470  mAutoMoney = 0;
471  mAutoAddAmount = 0;
472  mGotMoney = 0;
473  mGotMaxMoney = 0;
477 }
478 
479 void TradeWindow::addAutoItem(const std::string &nick, Item* const item,
480  const int amount)
481 {
482  mAutoAddToNick = nick;
483  mAutoAddItem = item;
484  mAutoAddAmount = amount;
485 }
486 
487 void TradeWindow::addAutoMoney(const std::string &nick, const int money)
488 {
489  mAutoAddToNick = nick;
490  mAutoMoney = money;
491 }
492 
493 void TradeWindow::initTrade(const std::string &nick)
494 {
495  if (localPlayer == nullptr)
496  return;
497 
498  if (!mAutoAddToNick.empty() && mAutoAddToNick == nick)
499  {
500  if ((mAutoAddItem != nullptr) && (mAutoAddItem->getQuantity() != 0))
501  {
502  const Inventory *const inv = PlayerInfo::getInventory();
503  if (inv != nullptr)
504  {
505  const Item *const item = inv->findItem(mAutoAddItem->getId(),
507  if (item != nullptr)
508  tradeItem(item, mAutoAddAmount, false);
509  }
510  }
511  if (mAutoMoney != 0)
512  {
515  }
516  }
517  clear();
518  if (!playerRelations.isGoodName(nick))
520 }
521 
522 bool TradeWindow::checkItem(const Item *const item) const
523 {
524  if (item == nullptr)
525  return false;
526 
527  const int itemId = item->getId();
528  if (PlayerInfo::isItemProtected(itemId))
529  return false;
530  const Item *const tItem = mMyInventory->findItem(
531  itemId, item->getColor());
532 
533  if ((tItem != nullptr) && (tItem->getQuantity() > 1
534  || item->getQuantity() > 1))
535  {
536  if (localChatTab != nullptr)
537  {
538  // TRANSLATORS: trade error
539  localChatTab->chatLog(_("Failed adding item. You can not "
540  "overlap one kind of item on the window."),
544  }
545  return false;
546  }
548  item->isEquipped() == Equipped_true)
549  {
550  if (localChatTab != nullptr)
551  {
553  // TRANSLATORS: trade error
554  _("Failed adding item. You can not trade equipped items."),
558  }
559  return false;
560  }
561  return true;
562 }
563 
565 {
566  return mMoneyField != nullptr && mMoneyField->isFocused();
567 }
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:534
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:96
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:213
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
const std::string BUTTON_SKIN
Definition: button.h:88
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:182
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:94
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