ManaPlus
shopwindow.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 
23 #include "gui/windows/shopwindow.h"
24 
26 
27 #ifdef TMWA_SUPPORT
28 #include "gui/windows/buydialog.h"
29 #include "gui/windows/chatwindow.h"
33 
34 #include "const/sound.h"
35 
36 #include "const/gui/chat.h"
37 #endif // TMWA_SUPPORT
38 
39 #include "enums/gui/layouttype.h"
40 
41 #include "gui/windows/editdialog.h"
42 
45 
46 #include "gui/models/shopitems.h"
47 
48 #include "gui/widgets/button.h"
49 #include "gui/widgets/checkbox.h"
52 #include "gui/widgets/layout.h"
53 #include "gui/widgets/scrollarea.h"
55 #include "gui/widgets/tabstrip.h"
56 
58 
59 #ifdef TMWA_SUPPORT
60 #include "actormanager.h"
61 #include "soundmanager.h"
62 #endif // TMWA_SUPPORT
63 #include "configuration.h"
64 #include "settings.h"
65 
66 #include "being/localplayer.h"
67 #include "being/playerinfo.h"
68 
69 #ifdef TMWA_SUPPORT
70 #include "being/playerrelations.h"
71 #include "net/chathandler.h"
72 #endif // TMWA_SUPPORT
73 #include "net/buyingstorehandler.h"
74 #include "net/vendinghandler.h"
75 #include "net/net.h"
76 #ifdef TMWA_SUPPORT
77 #include "net/tradehandler.h"
78 #endif // TMWA_SUPPORT
79 
80 #include "utils/checkutils.h"
81 #include "utils/delete2.h"
82 #include "utils/foreach.h"
83 #include "utils/gettext.h"
84 
85 #ifdef TMWA_SUPPORT
86 #include "resources/iteminfo.h"
87 #endif // TMWA_SUPPORT
88 
90 
92 
93 #include <sys/stat.h>
94 
95 #include <fstream>
96 #include <sstream>
97 
98 #include "debug.h"
99 
101 extern std::string tradePartnerName;
103 
105  // TRANSLATORS: shop window name
106  Window(_("Personal Shop"), Modal_false, nullptr, "shop.xml"),
111  ActionListener(),
113  // TRANSLATORS: shop window button
114  mCloseButton(new Button(this, _("Close"), "close", BUTTON_SKIN, this)),
115  mBuyShopItems(new ShopItems(false, DEFAULT_CURRENCY)),
116  mSellShopItems(new ShopItems(false, DEFAULT_CURRENCY)),
117  mTradeItem(nullptr),
118  mBuyShopItemList(CREATEWIDGETR(ShopListBox,
119  this, mBuyShopItems, mBuyShopItems, ShopListBoxType::BuyShop)),
120  mSellShopItemList(CREATEWIDGETR(ShopListBox,
121  this, mSellShopItems, mSellShopItems, ShopListBoxType::SellShop)),
122  mCurrentShopItemList(nullptr),
123  mScrollArea(new ScrollArea(this, mBuyShopItemList,
124  fromBool(getOptionBool("showbuybackground", false), Opaque),
125  "shop_buy_background.xml")),
126  // TRANSLATORS: shop window label
127  mAddButton(new Button(this, _("Add"), "add", BUTTON_SKIN, this)),
128  // TRANSLATORS: shop window label
129  mDeleteButton(new Button(this, _("Delete"), "delete", BUTTON_SKIN, this)),
130  mAnnounceButton(nullptr),
131  mPublishButton(nullptr),
132  mRenameButton(nullptr),
133  mAnnounceLinks(nullptr),
134  mTabs(nullptr),
135  mAcceptPlayer(),
136  mTradeNick(),
137  mSellShopName(serverConfig.getStringValue("sellShopName")),
138  mSelectedItem(-1),
139  mAnnonceTime(0),
140  mLastRequestTimeList(0),
141  mLastRequestTimeItem(0),
142  mRandCounter(0),
143  mTradeMoney(0),
144  mSellShopSize(0),
145  mBuyShopSize(0),
146  isBuySelected(true),
147  mHaveVending(Net::getNetworkType() != ServerType::TMWATHENA),
148  mEnableBuyingStore(false),
149  mEnableVending(false)
150 {
151  setWindowName("Personal Shop");
152  setResizable(true);
153  setCloseButton(true);
154  setStickyButtonLock(true);
155  setMinWidth(300);
156  setMinHeight(220);
157  if (mainGraphics->mWidth > 600)
158  setDefaultSize(500, 300, ImagePosition::CENTER, 0, 0);
159  else
160  setDefaultSize(380, 300, ImagePosition::CENTER, 0, 0);
161 
162  if (setupWindow != nullptr)
164 
165  const int size = config.getIntValue("fontSize")
166  + getOption("tabHeightAdjust", 16);
167  mTabs = new TabStrip(this, "shop", size, 0);
168  mTabs->addActionListener(this);
169  mTabs->setActionEventId("tab_");
170  // TRANSLATORS: shop window tab name
171  mTabs->addButton(_("Buy"), "buy", true);
172  // TRANSLATORS: shop window tab name
173  mTabs->addButton(_("Sell"), "sell", false);
174  mTabs->setSelectable(false);
175  mScrollArea->setSelectable(false);
176 
177  loadList();
178 
181 
183 
186 
187  ContainerPlacer placer(nullptr, nullptr);
188  placer = getPlacer(0, 0);
189 
190  placer(0, 0, mTabs, 8, 1).setPadding(3);
191 
192  if (mHaveVending)
193  {
194  mPublishButton = new Button(this,
195  // TRANSLATORS: shop window button
196  _("Publish"),
197  "publish",
198  BUTTON_SKIN,
199  this);
200  mRenameButton = new Button(this,
201  // TRANSLATORS: shop window button
202  _("Rename"),
203  "rename",
204  BUTTON_SKIN,
205  this);
206  placer(2, 6, mPublishButton, 1, 1);
207  placer(3, 6, mRenameButton, 1, 1);
208  }
209  else
210  {
211  mAnnounceButton = new Button(this,
212  // TRANSLATORS: shop window button
213  _("Announce"),
214  "announce",
215  BUTTON_SKIN,
216  this);
217  // TRANSLATORS: shop window checkbox
218  mAnnounceLinks = new CheckBox(this, _("Show links in announce"), false,
219  this, "link announce");
220 
221  placer(2, 6, mAnnounceButton, 1, 1);
222  placer(0, 7, mAnnounceLinks, 7, 1);
223  }
224 
225  placer(0, 1, mScrollArea, 8, 5).setPadding(3);
226  placer(0, 6, mAddButton, 1, 1);
227  placer(1, 6, mDeleteButton, 1, 1);
228  placer(7, 6, mCloseButton, 1, 1);
229 
230  Layout &layout = getLayout();
231  layout.setRowHeight(0, LayoutType::SET);
232 
233  center();
234  loadWindowState();
235  updateShopName();
236  instances.push_back(this);
237 }
238 
240 {
243  enableVisibleSound(true);
244  updateSelection();
245 }
246 
248 {
249  saveList();
250 
256 
257  instances.remove(this);
258 }
259 
260 void ShopWindow::action(const ActionEvent &event)
261 {
262  const std::string &eventId = event.getId();
263  if (eventId == "close")
264  {
265  close();
266  return;
267  }
268 #ifdef TMWA_SUPPORT
269  else if (eventId == "yes")
270  {
271  startTrade();
272  }
273  else if (eventId == "no")
274  {
275  mTradeNick.clear();
276  }
277  else if (eventId == "ignore")
278  {
280  mTradeNick.clear();
281  }
282  else if (eventId == "announce")
283  {
284  if (isBuySelected)
285  {
288  }
289  else if (mSellShopItems->getNumberOfElements() > 0)
290  {
292  }
293  }
294 #endif // TMWA_SUPPORT
295  else if (eventId == "delete")
296  {
297  if (isBuySelected)
298  {
299  if (mBuyShopItemList != nullptr &&
301  {
303  if (isShopEmpty() && (localPlayer != nullptr))
305  }
306  }
307  else if ((mSellShopItemList != nullptr)
308  && mSellShopItemList->getSelected() >= 0)
309  {
311  if (isShopEmpty() && (localPlayer != nullptr))
313  }
314  }
315  else if (eventId == "tab_buy")
316  {
317  isBuySelected = true;
318  updateSelection();
319  }
320  else if (eventId == "tab_sell")
321  {
322  isBuySelected = false;
323  updateSelection();
324  }
325  else if (eventId == "publish")
326  {
327  if (isBuySelected)
328  {
329  if (mEnableBuyingStore)
330  {
333  }
334  else
335  {
336  STD_VECTOR<ShopItem*> &items = mBuyShopItems->items();
337  if (!items.empty())
338  {
341  true,
342  items);
343  }
344  }
345  }
346  else
347  {
348  if (mEnableVending)
349  {
352  }
353  else
354  {
355  STD_VECTOR<ShopItem*> &oldItems = mSellShopItems->items();
356  STD_VECTOR<ShopItem*> items;
357  const Inventory *const inv = PlayerInfo::getCartInventory();
358  if (inv == nullptr)
359  return;
360  FOR_EACH (STD_VECTOR<ShopItem*>::iterator, it, oldItems)
361  {
362  ShopItem *const item = *it;
363  if (item == nullptr)
364  continue;
365  const Item *const cartItem = inv->findItem(item->getId(),
366  item->getColor());
367  if (cartItem == nullptr)
368  continue;
369  item->setInvIndex(cartItem->getInvIndex());
370  const int amount = cartItem->getQuantity();
371  if (amount == 0)
372  continue;
373  if (item->getQuantity() > amount)
374  item->setQuantity(amount);
375  items.push_back(item);
376  if (static_cast<signed int>(items.size()) >= mSellShopSize)
377  break;
378  }
379  if (!items.empty())
380  vendingHandler->createShop(mSellShopName, true, items);
381  }
382  }
383  }
384  else if (eventId == "rename")
385  {
386  EditDialog *const dialog = CREATEWIDGETR(EditDialog,
387  // TRANSLATORS: shop rename dialog title
388  _("Please enter new shop name"),
390  "OK",
391  300,
392  nullptr,
393  Modal_true);
396  }
397 
398  if (mSelectedItem < 1)
399  return;
400 
401  const Inventory *const inv = mHaveVending && !isBuySelected
403  if (inv == nullptr)
404  return;
405 
406  // +++ need support for colors
408  if (item != nullptr)
409  {
410  if (eventId == "add")
411  {
412  if (isBuySelected)
413  {
415  this,
416  item,
417  sumAmount(item),
418  0);
419  }
420  else
421  {
424  this,
425  item,
426  sumAmount(item),
427  0);
428  }
429  }
430  }
431 }
432 
434 {
436 }
437 
439 {
440  bool allowDel(false);
441  bool allowAdd(false);
442  const bool sellNotEmpty = mSellShopItems->getNumberOfElements() > 0;
443  if (isBuySelected)
444  {
445  allowAdd = !mEnableBuyingStore;
446  allowDel = !mEnableBuyingStore
447  && mBuyShopItemList->getSelected() != -1
449  if (mPublishButton != nullptr)
450  {
451  if (mEnableBuyingStore)
452  {
453  // TRANSLATORS: unpublish shop button
454  mPublishButton->setCaption(_("Unpublish"));
455  }
456  else
457  {
458  // TRANSLATORS: publish shop button
459  mPublishButton->setCaption(_("Publish"));
460  }
462  if (mBuyShopSize > 0)
463  mPublishButton->setEnabled(true);
464  else
465  mPublishButton->setEnabled(false);
466  }
467  }
468  else
469  {
470  allowAdd = !mEnableVending && mSelectedItem != -1;
471  allowDel = !mEnableVending
472  && mSellShopItemList->getSelected() != -1
473  && sellNotEmpty;
474  if (mPublishButton != nullptr)
475  {
476  if (mEnableVending)
477  {
478  // TRANSLATORS: unpublish shop button
479  mPublishButton->setCaption(_("Unpublish"));
480  }
481  else
482  {
483  // TRANSLATORS: publish shop button
484  mPublishButton->setCaption(_("Publish"));
485  }
487  if (sellNotEmpty
488  && mSellShopSize > 0
489  && (localPlayer != nullptr)
490  && localPlayer->getHaveCart())
491  {
492  mPublishButton->setEnabled(true);
493  }
494  else
495  {
496  mPublishButton->setEnabled(false);
497  }
498  }
499  }
500  mAddButton->setEnabled(allowAdd);
501  mDeleteButton->setEnabled(allowDel);
502  if (mRenameButton != nullptr)
504 }
505 
507 {
508  Window::setVisible(visible);
509 }
510 
511 void ShopWindow::addBuyItem(const Item *const item, const int amount,
512  const int price)
513 {
514  if (item == nullptr)
515  return;
516  const bool emp = isShopEmpty();
518  item->getType(),
519  item->getColor(),
520  amount,
521  price);
522  if (emp && (localPlayer != nullptr))
524 
526 }
527 
528 void ShopWindow::addSellItem(const Item *const item, const int amount,
529  const int price)
530 {
531  if (item == nullptr)
532  return;
533  const bool emp = isShopEmpty();
535  item->getType(),
536  item->getColor(),
537  amount,
538  price);
539  if (emp && (localPlayer != nullptr))
541 
543 }
544 
546 {
547  std::ifstream shopFile;
548  struct stat statbuf;
549 
550  mBuyShopItems->clear();
552 
553  const std::string shopListName = settings.serverConfigDir
554  + "/shoplist.txt";
555 
556  if (stat(shopListName.c_str(), &statbuf) == 0 &&
557  S_ISREG(statbuf.st_mode))
558  {
559  shopFile.open(shopListName.c_str(), std::ios::in);
560  if (!shopFile.is_open())
561  {
562  reportAlways("Error opening file for reading: %s",
563  shopListName.c_str())
564  shopFile.close();
565  return;
566  }
567  char line[101];
568  while (shopFile.getline(line, 100))
569  {
570  std::string buf;
571  const std::string str = line;
572  if (!str.empty())
573  {
574  STD_VECTOR<int> tokens;
575  std::stringstream ss(str);
576 
577  while (ss >> buf)
578  tokens.push_back(atoi(buf.c_str()));
579 
580  if (tokens.size() == 5 && (tokens[0] != 0))
581  {
582  // +++ need impliment colors?
583  if ((tokens[1] != 0) && (tokens[2] != 0))
584  {
586  tokens[0],
589  tokens[1],
590  tokens[2]);
591  }
592  if ((tokens[3] != 0) && (tokens[4] != 0))
593  {
595  tokens[0],
598  tokens[3],
599  tokens[4]);
600  }
601  }
602  }
603  }
604  shopFile.close();
605  }
606 }
607 
609 {
610  std::ofstream shopFile;
611  const std::string shopListName = settings.serverConfigDir
612  + "/shoplist.txt";
613  std::map<int, ShopItem*> mapItems;
614 
615  shopFile.open(shopListName.c_str(), std::ios::binary);
616  if (!shopFile.is_open())
617  {
618  reportAlways("Error opening file writing: %s",
619  shopListName.c_str())
620  return;
621  }
622 
623  STD_VECTOR<ShopItem*> items = mBuyShopItems->items();
624  FOR_EACH (STD_VECTOR<ShopItem*>::const_iterator, it, items)
625  {
626  ShopItem *const item = *(it);
627  if (item != nullptr)
628  mapItems[item->getId()] = item;
629  }
630 
631  items = mSellShopItems->items();
632  FOR_EACH (STD_VECTOR<ShopItem*>::const_iterator, it, items)
633  {
634  if ((*it) == nullptr)
635  continue;
636  const ShopItem *const sellItem = *(it);
637  const ShopItem *const buyItem = mapItems[sellItem->getId()];
638 
639  shopFile << sellItem->getId();
640  if (buyItem != nullptr)
641  {
642  shopFile << strprintf(" %d %d ", buyItem->getQuantity(),
643  buyItem->getPrice());
644  mapItems.erase(sellItem->getId());
645  }
646  else
647  {
648  shopFile << " 0 0 ";
649  }
650 
651  shopFile << strprintf("%d %d", sellItem->getQuantity(),
652  sellItem->getPrice()) << std::endl;
653  }
654 
655  for (std::map<int, ShopItem*>::const_iterator mapIt = mapItems.begin(),
656  mapIt_fend = mapItems.end();
657  mapIt != mapIt_fend;
658  ++mapIt)
659  {
660  const ShopItem *const buyItem = (*mapIt).second;
661  if (buyItem != nullptr)
662  {
663  shopFile << buyItem->getId();
664  shopFile << strprintf(" %d %d ", buyItem->getQuantity(),
665  buyItem->getPrice());
666  shopFile << "0 0" << std::endl;
667  }
668  }
669 
670  shopFile.close();
671 }
672 
673 #ifdef TMWA_SUPPORT
674 void ShopWindow::announce(ShopItems *const list, const int mode)
675 {
676  if (list == nullptr)
677  return;
678 
679  std::string data;
680  if (mode == BUY)
681  data.append("Buy ");
682  else
683  data.append("Sell ");
684 
685  if (mAnnonceTime != 0 &&
686  (mAnnonceTime + (2 * 60) > cur_time || mAnnonceTime > cur_time))
687  {
688  return;
689  }
690 
692  if (mAnnounceButton != nullptr)
693  mAnnounceButton->setEnabled(false);
694 
695  STD_VECTOR<ShopItem*> items = list->items();
696 
697  FOR_EACH (STD_VECTOR<ShopItem*>::const_iterator, it, items)
698  {
699  const ShopItem *const item = *(it);
700  if (item->getQuantity() > 1)
701  {
702  if (mAnnounceLinks->isSelected())
703  {
704  data.append(strprintf("[@@%d|%[email protected]@] (%dGP) %d, ", item->getId(),
705  item->getInfo().getName().c_str(),
706  item->getPrice(), item->getQuantity()));
707  }
708  else
709  {
710  data.append(strprintf("%s (%dGP) %d, ",
711  item->getInfo().getName().c_str(),
712  item->getPrice(), item->getQuantity()));
713  }
714  }
715  else
716  {
717  if (mAnnounceLinks->isSelected())
718  {
719  data.append(strprintf("[@@%d|%[email protected]@] (%dGP), ", item->getId(),
720  item->getInfo().getName().c_str(), item->getPrice()));
721  }
722  else
723  {
724  data.append(strprintf("%s (%dGP), ",
725  item->getInfo().getName().c_str(), item->getPrice()));
726  }
727  }
728  }
729 
731 }
732 
734 {
735  if (actorManager == nullptr ||
736  tradeWindow == nullptr)
737  {
738  return;
739  }
740 
741  const Being *const being = actorManager->findBeingByName(
743  tradeWindow->clear();
744  if (mTradeMoney != 0)
745  {
747  }
748  else
749  {
752  }
753  tradeHandler->request(being);
755  mTradeNick.clear();
756 }
757 
758 void ShopWindow::giveList(const std::string &nick, const int mode)
759 {
761  return;
762 
763  std::string data("\302\202");
764 
765  ShopItems *list;
766  if (mode == BUY)
767  {
768  list = mBuyShopItems;
769  data.append("S1");
770  }
771  else
772  {
773  list = mSellShopItems;
774  data.append("B1");
775  }
776  if (list == nullptr)
777  return;
778 
779  const Inventory *const inv = PlayerInfo::getInventory();
780  if (inv == nullptr)
781  return;
782 
783  STD_VECTOR<ShopItem*> items = list->items();
784 
785  FOR_EACH (STD_VECTOR<ShopItem*>::const_iterator, it, items)
786  {
787  const ShopItem *const item = *(it);
788  if (item == nullptr)
789  continue;
790 
791  if (mode == SELL)
792  {
793  const Item *const item2 = inv->findItem(item->getId(),
795  if (item2 != nullptr)
796  {
797  int amount = item->getQuantity();
798  if (item2->getQuantity() < amount)
799  amount = item2->getQuantity();
800 
801  if (amount != 0)
802  {
803  data.append(strprintf("%s%s%s",
804  encodeStr(item->getId(), 2).c_str(),
805  encodeStr(item->getPrice(), 4).c_str(),
806  encodeStr(amount, 3).c_str()));
807  }
808  }
809  }
810  else
811  {
812  int amount = item->getQuantity();
813  if (item->getPrice() * amount > PlayerInfo::getAttribute(
815  {
817  / item->getPrice();
818  }
819 
820  if (amount > 0)
821  {
822  data.append(strprintf("%s%s%s",
823  encodeStr(item->getId(), 2).c_str(),
824  encodeStr(item->getPrice(), 4).c_str(),
825  encodeStr(amount, 3).c_str()));
826  }
827  }
828  }
829  sendMessage(nick, data, true);
830 }
831 
832 void ShopWindow::sendMessage(const std::string &nick,
833  std::string data,
834  const bool random)
835 {
836  if (chatWindow == nullptr)
837  return;
838 
839  if (random)
840  {
841  mRandCounter ++;
842  if (mRandCounter > 200)
843  mRandCounter = 0;
844  data.append(encodeStr(mRandCounter, 2));
845  }
846 
847  if (config.getBoolValue("hideShopMessages"))
848  chatHandler->privateMessage(nick, data);
849  else
851 }
852 
853 void ShopWindow::showList(const std::string &nick, std::string data)
854 {
855  const Inventory *const inv = PlayerInfo::getInventory();
856  if (inv == nullptr)
857  return;
858 
859  BuyDialog *buyDialog = nullptr;
860  SellDialog *sellDialog = nullptr;
861  if (data.find("B1") == 0)
862  {
863  data = data.substr(2);
864  CREATEWIDGETV(buyDialog, BuyDialog, nick, DEFAULT_CURRENCY);
865  }
866  else if (data.find("S1") == 0)
867  {
868  data = data.substr(2);
869  CREATEWIDGETV(sellDialog, ShopSellDialog, nick);
870  }
871  else
872  {
873  return;
874  }
875 
876  if (buyDialog != nullptr)
878  if (sellDialog != nullptr)
880 
881  for (unsigned f = 0; f < data.length(); f += 9)
882  {
883  if (f + 9 > data.length())
884  break;
885 
886  const int id = decodeStr(data.substr(f, 2));
887  const int price = decodeStr(data.substr(f + 2, 4));
888  int amount = decodeStr(data.substr(f + 6, 3));
889  if (buyDialog != nullptr && amount > 0)
890  {
891  buyDialog->addItem(id,
894  amount,
895  price);
896  }
897  if (sellDialog != nullptr)
898  {
899  const Item *const item = inv->findItem(id, ItemColor_zero);
900  if (item != nullptr)
901  {
902  if (item->getQuantity() < amount)
903  amount = item->getQuantity();
904  }
905  else
906  {
907  amount = 0;
908  }
909  ShopItem *const shopItem = sellDialog->addItem(id,
912  amount,
913  price);
914 
915  if (shopItem != nullptr && amount <= 0)
916  shopItem->setDisabled(true);
917  }
918  }
919  if (buyDialog != nullptr)
920  buyDialog->sort();
921 }
922 
923 void ShopWindow::processRequest(const std::string &nick,
924  std::string data,
925  const int mode)
926 {
927  if (localPlayer == nullptr ||
928  !mTradeNick.empty() ||
930  actorManager == nullptr ||
932  {
933  return;
934  }
935 
936  const Inventory *const inv = PlayerInfo::getInventory();
937  if (inv == nullptr)
938  return;
939 
940  const size_t idx = data.find(' ');
941  if (idx == std::string::npos)
942  return;
943 
945  return;
946 
947  if (!mTradeNick.empty())
948  {
949  sendMessage(nick,
950  // TRANSLATORS: error buy/sell shop request
951  _("error: player busy") + std::string(" "),
952  true);
953  return;
954  }
955 
956  data = data.substr(idx + 1);
957 
958  std::string part1;
959  std::string part2;
960  std::string part3;
961  std::stringstream ss(data);
962  int id;
963  int price;
964  int amount;
965 
966  if (!(ss >> part1))
967  return;
968 
969  if (!(ss >> part2))
970  return;
971 
972  if (!(ss >> part3))
973  return;
974 
975  id = atoi(part1.c_str());
976  price = atoi(part2.c_str());
977  amount = atoi(part3.c_str());
978 
979  delete mTradeItem;
980  // +++ need impliment colors?
981  mTradeItem = new ShopItem(-1,
982  id,
985  amount,
986  price,
988 
989  if (mode == BUY)
990  {
991  // +++ need support for colors
992  const Item *const item2 = inv->findItem(mTradeItem->getId(),
994  if (item2 == nullptr ||
995  item2->getQuantity() < amount ||
996  !findShopItem(mTradeItem, SELL))
997  {
998  sendMessage(nick,
999  // TRANSLATORS: error buy/sell shop request
1000  _("error: Can't sell this item") + std::string(" "),
1001  true);
1002  return;
1003  }
1004  mTradeMoney = 0;
1005  }
1006  else
1007  {
1008  if (!findShopItem(mTradeItem, BUY))
1009  {
1010  sendMessage(nick,
1011  // TRANSLATORS: error buy/sell shop request
1012  _("error: Can't buy this item") + std::string(" "),
1013  true);
1014  return;
1015  }
1016  mTradeMoney = mTradeItem->getPrice() * mTradeItem->getQuantity();
1017  }
1018 
1019  mTradeNick = nick;
1020 
1021  if (config.getBoolValue("autoShop"))
1022  {
1024  startTrade();
1025  }
1026  else
1027  {
1028  std::string msg;
1029  if (mode == BUY)
1030  {
1031  // TRANSLATORS: buy shop request (nick, item)
1032  msg = strprintf(_("%s wants to buy %s do you accept?"),
1033  nick.c_str(),
1034  mTradeItem->getInfo().getName().c_str());
1035  }
1036  else
1037  {
1038  // TRANSLATORS: sell shop request (nick, item)
1039  msg = strprintf(_("%s wants to sell %s do you accept?"),
1040  nick.c_str(),
1041  mTradeItem->getInfo().getName().c_str());
1042  }
1043 
1045  // TRANSLATORS: shop window dialog
1046  _("Request for Trade"),
1047  msg,
1048  SOUND_REQUEST,
1049  true,
1050  Modal_false,
1051  nullptr);
1052  confirmDlg->addActionListener(this);
1053  }
1054 }
1055 
1057 {
1058  BLOCK_START("ShopWindow::updateTimes")
1059  if (mAnnounceButton == nullptr)
1060  {
1061  BLOCK_END("ShopWindow::updateTimes")
1062  return;
1063  }
1064  if (mAnnonceTime + (2 * 60) < cur_time ||
1066  {
1067  mAnnounceButton->setEnabled(true);
1068  }
1069  BLOCK_END("ShopWindow::updateTimes")
1070 }
1071 
1072 bool ShopWindow::checkFloodCounter(time_t &counterTime)
1073 {
1074  if (counterTime == 0 || counterTime > cur_time)
1075  counterTime = cur_time;
1076  else if (counterTime + 10 > cur_time)
1077  return false;
1078  else
1079  counterTime = cur_time;
1080  return true;
1081 }
1082 
1083 bool ShopWindow::findShopItem(const ShopItem *const shopItem,
1084  const int mode) const
1085 {
1086  if (shopItem == nullptr)
1087  return false;
1088 
1089  STD_VECTOR<ShopItem*> items;
1090  if (mode == SELL)
1091  items = mSellShopItems->items();
1092  else
1093  items = mBuyShopItems->items();
1094 
1095  FOR_EACH (STD_VECTOR<ShopItem*>::const_iterator, it, items)
1096  {
1097  const ShopItem *const item = *(it);
1098  if (item == nullptr)
1099  continue;
1100 
1101  if (item->getId() == shopItem->getId()
1102  && item->getPrice() == shopItem->getPrice()
1103  && item->getQuantity() >= shopItem->getQuantity())
1104  {
1105  return true;
1106  }
1107  }
1108  return false;
1109 }
1110 #endif // TMWA_SUPPORT
1111 
1112 int ShopWindow::sumAmount(const Item *const shopItem)
1113 {
1114  if ((localPlayer == nullptr) || (shopItem == nullptr))
1115  return 0;
1116 
1117  const Inventory *const inv = PlayerInfo::getInventory();
1118  if (inv == nullptr)
1119  return 0;
1120  int sum = 0;
1121 
1122  for (unsigned f = 0; f < inv->getSize(); f ++)
1123  {
1124  const Item *const item = inv->getItem(f);
1125  if ((item != nullptr) && item->getId() == shopItem->getId())
1126  sum += item->getQuantity();
1127  }
1128  return sum;
1129 }
1130 
1132 {
1133  if (mBuyShopItems->empty() && mSellShopItems->empty())
1134  return true;
1135  return false;
1136 }
1137 
1139 {
1140  if (isBuySelected)
1142  else
1146 }
1147 
1149 {
1150  if (mSellShopName.empty())
1151  {
1152  // TRANSLATORS: shop window name
1153  setCaption(_("Personal Shop"));
1154  }
1155  else
1156  {
1157  // TRANSLATORS: shop window name
1158  setCaption(strprintf(_("Personal Shop - %s"), mSellShopName.c_str()));
1159  }
1160 }
1161 
1162 void ShopWindow::setShopName(const std::string &name)
1163 {
1164  mSellShopName = name;
1165  serverConfig.setValue("sellShopName", mSellShopName);
1166  updateShopName();
1167 }
1168 
1169 void ShopWindow::vendingSlotsChanged(const int slots)
1170 {
1171  mSellShopSize = slots;
1173 }
1174 
1175 void ShopWindow::vendingEnabled(const bool b)
1176 {
1177  mEnableVending = b;
1178  localPlayer->enableShop(b);
1179  if (!b)
1180  mSellShopSize = 0;
1182 }
1183 
1185 {
1186  mBuyShopSize = slots;
1188 }
1189 
1191 {
1192  mEnableBuyingStore = b;
1193  localPlayer->enableShop(b);
1194  if (!b)
1195  mBuyShopSize = 0;
1197 }
Button * mDeleteButton
Definition: shopwindow.h:183
int getInvIndex() const
Definition: item.h:164
ShopListBox * mSellShopItemList
Definition: shopwindow.h:179
ChatWindow * chatWindow
Definition: chatwindow.cpp:89
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
void setDefaultSize()
Definition: window.cpp:1197
int mBuyShopSize
Definition: shopwindow.h:199
bool mHaveVending
Definition: shopwindow.h:201
Button * mRenameButton
Definition: shopwindow.h:186
#define _(s)
Definition: gettext.h:34
bool isBuySelected
Definition: shopwindow.h:200
void loadList()
Definition: shopwindow.cpp:545
void addAutoMoney(const std::string &nick, const int money)
Button * mPublishButton
Definition: shopwindow.h:185
void action(const ActionEvent &event)
Definition: shopwindow.cpp:260
std::string mSellShopName
Definition: shopwindow.h:191
bool mEnableVending
Definition: shopwindow.h:203
Button * mAddButton
Definition: shopwindow.h:182
ShopItem * addItem(const int id, const ItemTypeT type, const ItemColor color, const int amount, const int price)
Definition: shopitems.cpp:58
TradeWindow * tradeWindow
Definition: tradewindow.cpp:64
ShopItems * mBuyShopItems
Definition: shopwindow.h:174
void buyingStoreSlotsChanged(const int slots)
ShopItem * mTradeItem
Definition: shopwindow.h:176
void loadWindowState()
Definition: window.cpp:1086
void setPriceCheck(const bool check)
virtual void addButton(const std::string &text, const std::string &tag, const bool pressed)
Definition: widgetgroup.cpp:41
const std::string encodeStr(unsigned int value, const unsigned int size)
virtual void create(const std::string &name, const int maxMoney, const bool flag, const std::vector< ShopItem *> &items) const =0
void ignoreTrade(const std::string &name) const
Item * findItem(const int itemId, const ItemColor color) const
Definition: inventory.cpp:93
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:251
void vendingEnabled(const bool b)
virtual void close() const =0
bool empty() const
Definition: shopitems.h:101
void updateStatus() const
Inventory * getInventory()
Definition: playerinfo.cpp:193
void addSelectionListener(SelectionListener *const selectionListener)
Definition: listbox.cpp:434
void setMinWidth(const int width)
Definition: window.cpp:590
Definition: window.h:98
int mWidth
Definition: graphics.h:483
#define BLOCK_START(name)
Definition: perfomance.h:78
Definition: button.h:96
SoundManager soundManager
Configuration config
static void showWindow(const ItemAmountWindowUsageT usage, Window *const parent, Item *const item, int maxRange, const int tag)
int getOption(const std::string &name, const int def) const
Definition: window.cpp:1453
static const std::string SOUND_REQUEST
Definition: sound.h:28
void saveList() const
Definition: shopwindow.cpp:608
virtual void createShop(const std::string &name, const bool flag, const std::vector< ShopItem *> &items) const =0
#define BLOCK_END(name)
Definition: perfomance.h:79
bool msg(InputEvent &event)
Definition: chat.cpp:38
const ItemColor ItemColor_zero
Definition: itemcolor.h:29
int getIntValue(const std::string &key) const
int mTradeMoney
Definition: shopwindow.h:197
const ItemColor ItemColor_one
Definition: itemcolor.h:29
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:595
#define CREATEWIDGETV(var, type,...)
Definition: createwidget.h:24
const std::string & getName() const
Definition: iteminfo.h:73
#define delete2(var)
Definition: delete2.h:24
ShopListBox * mCurrentShopItemList
Definition: shopwindow.h:180
Configuration serverConfig
ShopListBox * mBuyShopItemList
Definition: shopwindow.h:178
void vendingSlotsChanged(const int slots)
std::string tradePartnerName
Definition: popupmenu.cpp:100
void processRequest(const std::string &nick, std::string data, const int mode)
Definition: shopwindow.cpp:923
void registerWindowForReset(Window *const window)
void adjustSize()
Definition: button.cpp:798
ShopItem * addItem(const int id, const ItemTypeT type, const ItemColor color, const int amount, const int price)
Definition: buydialog.cpp:456
void clear()
Definition: shopitems.cpp:173
static int sumAmount(const Item *const shopItem)
static void distributeEvent(const bool b)
void startTrade()
Definition: shopwindow.cpp:733
void setSelectable(const bool selectable)
Definition: widget.h:947
virtual void close()
Definition: window.cpp:901
#define new
Definition: debug_new.h:147
Settings settings
Definition: settings.cpp:31
bool mEnableBuyingStore
Definition: shopwindow.h:202
void setShopName(const std::string &name)
bool getBoolValue(const std::string &key) const
void setCaption(const std::string &caption)
Definition: button.h:213
void buyingStoreEnabled(const bool b)
std::vector< ShopItem * > & items()
Definition: shopitems.h:135
Inventory * getCartInventory()
Definition: playerinfo.cpp:205
virtual void privateMessage(const std::string &recipient, const std::string &text) const =0
void giveList(const std::string &nick, const int mode)
Definition: shopwindow.cpp:758
const std::string DEFAULT_CURRENCY
Definition: currency.h:26
const std::string BUTTON_SKIN
Definition: button.h:88
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
time_t mLastRequestTimeItem
Definition: shopwindow.h:195
void sort()
Definition: buydialog.cpp:471
int mSellShopSize
Definition: shopwindow.h:198
int getPrice() const
Definition: shopitem.h:131
const bool Visible_false
Definition: visible.h:29
void announce(ShopItems *const list, const int mode)
Definition: shopwindow.cpp:674
int getQuantity() const
Definition: item.h:104
#define fromBool(val, name)
Definition: booldefines.h:48
std::string serverConfigDir
Definition: settings.h:115
void addBuyItem(const Item *const item, const int amount, const int price)
Definition: shopwindow.cpp:511
uint32_t data
time_t mAnnonceTime
Definition: shopwindow.h:193
void updateTimes()
void setMoney(const int amount)
Definition: selldialog.cpp:339
LocalPlayer * localPlayer
ItemColor getColor() const
Definition: item.h:180
std::string mTradeNick
Definition: shopwindow.h:190
static void showList(const std::string &nick, std::string data)
Definition: shopwindow.cpp:853
int getSelected() const
Definition: listbox.h:167
Definition: item.h:48
static void distributeEvent(const bool b)
void setInvIndex(const int index)
Definition: item.h:158
#define nullptr
Definition: localconsts.h:44
Graphics * mainGraphics
Definition: graphics.cpp:108
int mSelectedItem
Definition: shopwindow.h:192
void updateButtonsAndLabels()
Definition: shopwindow.cpp:438
void setCloseButton(const bool flag)
Definition: window.cpp:748
void sendMessage(const std::string &nick, std::string data, const bool random)
Definition: shopwindow.cpp:832
const ItemInfo & getInfo() const
Definition: item.h:170
volatile time_t cur_time
Definition: timer.cpp:57
void addItem(const Item *const item, const int price)
Definition: selldialog.cpp:237
ShopRenameListener shopRenameListener
void setContent(Widget *widget)
void enableVisibleSound(bool b)
Definition: window.h:480
void valueChanged(const SelectionEvent &event)
Definition: shopwindow.cpp:433
void setMinHeight(const int height)
Definition: window.cpp:603
ContainerPlacer getPlacer(const int x, const int y)
Definition: window.cpp:1390
void setEnabled(const bool enabled)
Definition: widget.h:351
void enableShop(const bool b)
Definition: being.cpp:5344
Layout & getLayout()
Definition: window.cpp:1364
Button * mAnnounceButton
Definition: shopwindow.h:184
Net::BuyingStoreHandler * buyingStoreHandler
Definition: net.cpp:104
ShopWindow * shopWindow
Definition: shopwindow.cpp:100
ServerTypeT getNetworkType()
Definition: net.cpp:184
unsigned int decodeStr(const std::string &str)
TabStrip * mTabs
Definition: shopwindow.h:188
void updateShopName()
int getId() const
Definition: item.h:80
#define A_UNUSED
Definition: localconsts.h:159
virtual void setVisible(Visible visible)
Definition: window.cpp:777
void center()
Definition: window.cpp:1416
void addAutoItem(const std::string &nick, Item *const item, const int amount)
ConfirmDialog * confirmDlg
Definition: traderecv.cpp:48
Net::ChatHandler * chatHandler
Definition: net.cpp:83
ShopItem * addItemNoDup(const int id, const ItemTypeT type, const ItemColor color, const int amount, const int price)
Definition: shopitems.cpp:76
std::list< ShopWindow * > DialogList
Definition: shopwindow.h:169
Net::TradeHandler * tradeHandler
Definition: net.cpp:95
void setDisabled(const bool b)
Definition: shopitem.h:153
void updateSelection()
bool isShopEmpty() const
ScrollArea * mScrollArea
Definition: shopwindow.h:181
time_t mLastRequestTimeList
Definition: shopwindow.h:194
void setMoney(const int amount)
Definition: buydialog.cpp:436
ItemTypeT getType() const
Definition: item.h:224
Button * mCloseButton
Definition: shopwindow.h:172
static DialogList instances
Definition: shopwindow.h:170
void setQuantity(const int quantity)
Definition: item.h:92
static const std::string SOUND_TRADE
Definition: sound.h:29
Being * findBeingByName(const std::string &name, const ActorTypeT type) const
void setResizable(const bool resize)
Definition: window.cpp:626
void del(const unsigned int i)
Definition: shopitems.cpp:160
Net::VendingHandler * vendingHandler
Definition: net.cpp:117
void setStickyButtonLock(const bool sticky)
Definition: window.cpp:771
SetupWindow * setupWindow
Definition: setupwindow.cpp:63
virtual void channelMessage(const std::string &channel, const std::string &text) const =0
virtual void request(const Being *const being) const
Definition: tradehandler.h:45
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:35
const std::string TRADE_CHANNEL
Definition: chat.h:30
bool findShopItem(const ShopItem *const shopItem, const int mode) const
const bool Trading_true
Definition: trading.h:29
Item * getItem(const int index) const
Definition: inventory.cpp:82
Definition: layout.h:43
static bool checkFloodCounter(time_t &counterTime)
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:100
CheckBox * mAnnounceLinks
Definition: shopwindow.h:187
void setCaption(const std::string &caption)
Definition: window.h:530
Definition: being.h:93
bool isSelected() const
Definition: checkbox.h:146
PlayerRelationsManager playerRelations
void setRowHeight(const int n, const int h)
Definition: layoutcell.cpp:127
void setDialog(EditDialog *const dialog)
#define reportAlways(...)
Definition: checkutils.h:252
void addSellItem(const Item *const item, const int amount, const int price)
Definition: shopwindow.cpp:528
virtual void close() const =0
bool getHaveCart() const
Definition: actorsprite.h:174
void setValue(const std::string &key, const std::string &value)
void postInit()
Definition: shopwindow.cpp:239
void addWhisper(const std::string &nick, const std::string &mes, const ChatMsgTypeT own)
void postInit()
Definition: window.cpp:248
ActorManager * actorManager
ShopItems * mSellShopItems
Definition: shopwindow.h:175
void playGuiSound(const std::string &name)
void setWindowName(const std::string &name)
Definition: window.h:354
int getNumberOfElements()
Definition: shopitems.h:98
unsigned getSize() const
Definition: inventory.h:75
int mRandCounter
Definition: shopwindow.h:196
Trading isTrading()
Definition: playerinfo.cpp:389
void setHorizontalScrollPolicy(const ScrollPolicy hPolicy)
void setVisible(Visible visible)
Definition: shopwindow.cpp:506