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