GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/windows/outfitwindow.cpp Lines: 103 362 28.5 %
Date: 2017-11-29 Branches: 127 442 28.7 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2007-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2017  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/outfitwindow.h"
24
25
#include "configuration.h"
26
#include "dragdrop.h"
27
#include "game.h"
28
29
#include "being/playerinfo.h"
30
31
#include "const/emoteshortcut.h"
32
33
#include "enums/gui/layouttype.h"
34
35
#include "input/inputactionoperators.h"
36
#include "input/inputmanager.h"
37
38
#include "gui/viewport.h"
39
40
#include "gui/popups/popupmenu.h"
41
42
#include "gui/windows/setupwindow.h"
43
44
#include "gui/widgets/button.h"
45
#include "gui/widgets/checkbox.h"
46
#include "gui/widgets/label.h"
47
#include "gui/widgets/layout.h"
48
49
#include "utils/gettext.h"
50
51
#include "resources/inventory/inventory.h"
52
53
#include <sstream>
54
55
#include "debug.h"
56
57
OutfitWindow *outfitWindow = nullptr;
58
59
2
OutfitWindow::OutfitWindow() :
60
    // TRANSLATORS: outfits window name
61
2
    Window(_("Outfits"), Modal_false, nullptr, "outfits.xml"),
62
    ActionListener(),
63
    // TRANSLATORS: outfits window button
64

4
    mPreviousButton(new Button(this, _("<"), "previous", this)),
65
    // TRANSLATORS: outfits window button
66

4
    mNextButton(new Button(this, _(">"), "next", this)),
67
    // TRANSLATORS: outfits window button
68

4
    mEquipBottom(new Button(this, _("Equip"), "equip", this)),
69
    // TRANSLATORS: outfits window label
70

4
    mCurrentLabel(new Label(this, strprintf(_("Outfit: %d"), 1))),
71
    // TRANSLATORS: outfits window checkbox
72
2
    mUnequipCheck(new CheckBox(this, _("Unequip first"),
73


10
        serverConfig.getValueBool("OutfitUnequip0", true))),
74
    // TRANSLATORS: outfits window checkbox
75
2
    mAwayOutfitCheck(new CheckBox(this, _("Away outfit"),
76


10
        serverConfig.getValue("OutfitAwayIndex", OUTFITS_COUNT - 1) != 0u)),
77
    // TRANSLATORS: outfits window label
78
4
    mKeyLabel(new Label(this, strprintf(_("Key: %s"),
79

6
        keyName(0).c_str()))),
80
4
    mBorderColor(getThemeColor(ThemeColorId::BORDER, 64)),
81
    mCurrentOutfit(0),
82
    mBoxWidth(33),
83
    mBoxHeight(33),
84
    mGridWidth(4),
85
    mGridHeight(4),
86
    mItems(),
87
    mAwayOutfit(0),
88
    mItemColors(),
89
    mItemClicked(false),
90









98
    mItemsUnequip()
91
{
92
10
    setWindowName("Outfits");
93
2
    setResizable(true);
94
2
    setCloseButton(true);
95
2
    setStickyButtonLock(true);
96
97
4
    mBackgroundColor = getThemeColor(ThemeColorId::BACKGROUND, 32);
98
99
2
    setDefaultSize(250, 400, 150, 290);
100
2
    setMinWidth(145);
101
2
    setMinHeight(220);
102
103
2
    if (setupWindow != nullptr)
104
        setupWindow->registerWindowForReset(this);
105
106
4
    mCurrentLabel->setAlignment(Graphics::CENTER);
107
4
    mKeyLabel->setAlignment(Graphics::CENTER);
108
109
10
    mUnequipCheck->setActionEventId("unequip");
110
2
    mUnequipCheck->addActionListener(this);
111
112
10
    mAwayOutfitCheck->setActionEventId("away");
113
2
    mAwayOutfitCheck->addActionListener(this);
114
115
2
    place(1, 3, mEquipBottom, 2);
116
2
    place(0, 4, mKeyLabel, 4);
117
2
    place(0, 5, mPreviousButton, 1);
118
2
    place(1, 5, mCurrentLabel, 2);
119
2
    place(3, 5, mNextButton, 1);
120
2
    place(0, 6, mUnequipCheck, 4);
121
2
    place(0, 7, mAwayOutfitCheck, 4);
122
123
2
    Layout &layout = getLayout();
124
2
    layout.setRowHeight(0, LayoutType::SET);
125
2
    layout.setColWidth(4, Layout::CENTER);
126
127
2
    loadWindowState();
128
129
4
    enableVisibleSound(true);
130
2
    load();
131
2
}
132
133
8
OutfitWindow::~OutfitWindow()
134
{
135
2
    save();
136
4
}
137
138
2
void OutfitWindow::load()
139
{
140
2
    const Configuration *cfg = &serverConfig;
141
142
4
    memset(mItems, -1, sizeof(mItems));
143
4
    memset(mItemColors, 1, sizeof(mItemColors));
144
145
202
    for (unsigned o = 0; o < OUTFITS_COUNT; o++)
146
    {
147


1400
        std::string outfit = cfg->getValue("Outfit" + toString(o), "-1");
148
400
        std::string buf;
149
400
        std::stringstream ss(outfit);
150
151
200
        STD_VECTOR<int> tokens;
152
153

1000
        while (ss >> buf)
154
600
            tokens.push_back(atoi(buf.c_str()));
155
156
600
        for (size_t i = 0, sz = tokens.size();
157
400
             i < sz && i < OUTFIT_ITEM_COUNT; i++)
158
        {
159
400
            mItems[o][i] = tokens[i];
160
        }
161
162


1400
        outfit = cfg->getValue("OutfitColor" + toString(o), "1");
163
400
        std::stringstream ss2(outfit);
164
165
200
        tokens.clear();
166
167
200
        STD_VECTOR<unsigned char> tokens2;
168

1000
        while (ss2 >> buf)
169
600
            tokens2.push_back(CAST_U8(atoi(buf.c_str())));
170
171
600
        for (size_t i = 0, sz = tokens2.size();
172
400
             i < sz && i < OUTFIT_ITEM_COUNT; i++)
173
        {
174
400
            mItemColors[o][i] = fromInt(tokens2[i], ItemColor);
175
        }
176
177

600
        mItemsUnequip[o] = cfg->getValueBool("OutfitUnequip" + toString(o),
178
                                             true);
179
    }
180

8
    mAwayOutfit = cfg->getValue("OutfitAwayIndex", OUTFITS_COUNT - 1);
181
2
    if (mAwayOutfit >= CAST_S32(OUTFITS_COUNT))
182
        mAwayOutfit = CAST_S32(OUTFITS_COUNT) - 1;
183
184
2
    if (mAwayOutfitCheck != nullptr)
185
2
        mAwayOutfitCheck->setSelected(mAwayOutfit == mCurrentOutfit);
186
2
}
187
188
2
void OutfitWindow::save() const
189
{
190
4
    std::string outfitStr;
191
4
    std::string outfitColorsStr;
192
202
    for (unsigned o = 0; o < OUTFITS_COUNT; o++)
193
    {
194
        bool good = false;
195
6600
        for (unsigned i = 0; i < OUTFIT_ITEM_COUNT; i++)
196
        {
197
3200
            const int val = mItems[o][i];
198
3200
            const int res = val != 0 ? val : -1;
199
3200
            if (res != -1)
200
                good = true;
201
9600
            outfitStr.append(toString(res));
202
3200
            if (i < OUTFIT_ITEM_COUNT - 1)
203
3000
                outfitStr.append(" ");
204
9600
            outfitColorsStr.append(toString(CAST_S32(
205
3200
                toInt(mItemColors[o][i], int))));
206
3200
            if (i < OUTFIT_ITEM_COUNT - 1)
207
3000
                outfitColorsStr.append(" ");
208
        }
209
200
        if (good)
210
        {
211
            serverConfig.setValue("Outfit" + toString(o), outfitStr);
212
            serverConfig.setValue("OutfitColor" + toString(o),
213
                outfitColorsStr);
214
        }
215
        else
216
        {
217

600
            serverConfig.deleteKey("Outfit" + toString(o));
218

600
            serverConfig.deleteKey("OutfitColor" + toString(o));
219
        }
220
221
200
        if (mItemsUnequip[o])
222
        {
223

600
            serverConfig.deleteKey("OutfitUnequip" + toString(o));
224
        }
225
        else
226
        {
227
            serverConfig.setValue("OutfitUnequip" + toString(o),
228
                mItemsUnequip[o]);
229
        }
230
200
        outfitStr.clear();
231
200
        outfitColorsStr.clear();
232
    }
233

8
    serverConfig.setValue("OutfitAwayIndex", mAwayOutfit);
234
2
}
235
236
void OutfitWindow::action(const ActionEvent &event)
237
{
238
    const std::string &eventId = event.getId();
239
    if (eventId == "next")
240
    {
241
        next();
242
    }
243
    else if (eventId == "previous")
244
    {
245
        previous();
246
    }
247
    else if (eventId == "unequip")
248
    {
249
        if (mCurrentOutfit >= 0 && mCurrentOutfit < CAST_S32(
250
            OUTFITS_COUNT))
251
        {
252
            mItemsUnequip[mCurrentOutfit] = mUnequipCheck->isSelected();
253
        }
254
    }
255
    else if (eventId == "equip")
256
    {
257
        wearOutfit(mCurrentOutfit);
258
        if (Game::instance() != nullptr)
259
            Game::instance()->setValidSpeed();
260
    }
261
    else if (eventId == "away")
262
    {
263
        mAwayOutfit = mCurrentOutfit;
264
        if (!mAwayOutfitCheck->isSelected())
265
            mAwayOutfitCheck->setSelected(true);
266
    }
267
}
268
269
void OutfitWindow::wearOutfit(const int outfit, const bool unwearEmpty,
270
                              const bool select)
271
{
272
    bool isEmpty = true;
273
274
    if (outfit < 0 || outfit > CAST_S32(OUTFITS_COUNT))
275
        return;
276
277
    for (unsigned i = 0; i < OUTFIT_ITEM_COUNT; i++)
278
    {
279
        const Item *const item = PlayerInfo::getInventory()->findItem(
280
            mItems[outfit][i],
281
            mItemColors[outfit][i]);
282
        if ((item != nullptr)
283
            && item->isEquipped() == Equipped_false
284
            && (item->getQuantity() != 0))
285
        {
286
            if (item->isEquipment() == Equipm_true)
287
            {
288
                PlayerInfo::equipItem(item, Sfx_false);
289
                isEmpty = false;
290
            }
291
        }
292
    }
293
294
    if ((!isEmpty || unwearEmpty) && outfit < CAST_S32(OUTFITS_COUNT)
295
        && mItemsUnequip[outfit])
296
    {
297
        unequipNotInOutfit(outfit);
298
    }
299
    if (select)
300
    {
301
        mCurrentOutfit = outfit;
302
        showCurrentOutfit();
303
    }
304
}
305
306
void OutfitWindow::copyOutfit(const int outfit)
307
{
308
    copyOutfit(outfit, mCurrentOutfit);
309
}
310
311
void OutfitWindow::copyOutfit(const int src, const int dst)
312
{
313
    if (src < 0 || src > CAST_S32(OUTFITS_COUNT)
314
        || dst < 0 || dst > CAST_S32(OUTFITS_COUNT))
315
    {
316
        return;
317
    }
318
319
    for (unsigned int i = 0; i < OUTFIT_ITEM_COUNT; i++)
320
        mItems[dst][i] = mItems[src][i];
321
    save();
322
}
323
324
void OutfitWindow::draw(Graphics *const graphics)
325
{
326
    BLOCK_START("OutfitWindow::draw")
327
    Window::draw(graphics);
328
329
    if (mCurrentOutfit < 0 || mCurrentOutfit
330
        >= static_cast<signed int>(OUTFITS_COUNT))
331
    {
332
        return;
333
    }
334
335
    for (unsigned int i = 0; i < OUTFIT_ITEM_COUNT; i++)
336
    {
337
        const int itemX = mPadding + ((i % mGridWidth) * mBoxWidth);
338
        const int itemY = mPadding + mTitleBarHeight
339
            + ((i / CAST_U32(mGridWidth)) * mBoxHeight);
340
341
        graphics->setColor(mBorderColor);
342
        graphics->drawRectangle(Rect(itemX, itemY, 32, 32));
343
        graphics->setColor(mBackgroundColor);
344
        graphics->fillRectangle(Rect(itemX, itemY, 32, 32));
345
346
        if (mItems[mCurrentOutfit][i] < 0)
347
            continue;
348
349
        bool foundItem = false;
350
        const Inventory *const inv = PlayerInfo::getInventory();
351
        if (inv != nullptr)
352
        {
353
            const Item *const item = inv->findItem(mItems[mCurrentOutfit][i],
354
                mItemColors[mCurrentOutfit][i]);
355
            if (item != nullptr)
356
            {
357
                // Draw item icon.
358
                const Image *const image = item->getImage();
359
                if (image != nullptr)
360
                {
361
                    graphics->drawImage(image, itemX, itemY);
362
                    foundItem = true;
363
                }
364
            }
365
        }
366
        if (!foundItem)
367
        {
368
            Image *const image = Item::getImage(mItems[mCurrentOutfit][i],
369
                mItemColors[mCurrentOutfit][i]);
370
            if (image != nullptr)
371
            {
372
                graphics->drawImage(image, itemX, itemY);
373
                image->decRef();
374
            }
375
        }
376
    }
377
    BLOCK_END("OutfitWindow::draw")
378
}
379
380
void OutfitWindow::safeDraw(Graphics *const graphics)
381
{
382
    BLOCK_START("OutfitWindow::draw")
383
    Window::safeDraw(graphics);
384
385
    if (mCurrentOutfit < 0 || mCurrentOutfit
386
        >= static_cast<signed int>(OUTFITS_COUNT))
387
    {
388
        return;
389
    }
390
391
    for (unsigned int i = 0; i < OUTFIT_ITEM_COUNT; i++)
392
    {
393
        const int itemX = mPadding + ((i % mGridWidth) * mBoxWidth);
394
        const int itemY = mPadding + mTitleBarHeight
395
            + ((i / CAST_U32(mGridWidth)) * mBoxHeight);
396
397
        graphics->setColor(mBorderColor);
398
        graphics->drawRectangle(Rect(itemX, itemY, 32, 32));
399
        graphics->setColor(mBackgroundColor);
400
        graphics->fillRectangle(Rect(itemX, itemY, 32, 32));
401
402
        if (mItems[mCurrentOutfit][i] < 0)
403
            continue;
404
405
        bool foundItem = false;
406
        const Inventory *const inv = PlayerInfo::getInventory();
407
        if (inv != nullptr)
408
        {
409
            const Item *const item = inv->findItem(mItems[mCurrentOutfit][i],
410
                mItemColors[mCurrentOutfit][i]);
411
            if (item != nullptr)
412
            {
413
                // Draw item icon.
414
                const Image *const image = item->getImage();
415
                if (image != nullptr)
416
                {
417
                    graphics->drawImage(image, itemX, itemY);
418
                    foundItem = true;
419
                }
420
            }
421
        }
422
        if (!foundItem)
423
        {
424
            Image *const image = Item::getImage(mItems[mCurrentOutfit][i],
425
                mItemColors[mCurrentOutfit][i]);
426
            if (image != nullptr)
427
            {
428
                graphics->drawImage(image, itemX, itemY);
429
                image->decRef();
430
            }
431
        }
432
    }
433
    BLOCK_END("OutfitWindow::draw")
434
}
435
436
void OutfitWindow::mouseDragged(MouseEvent &event)
437
{
438
    if (event.getButton() == MouseButton::LEFT)
439
    {
440
        if (dragDrop.isEmpty() && mItemClicked)
441
        {
442
            if (mCurrentOutfit < 0 || mCurrentOutfit
443
                >= static_cast<signed int>(OUTFITS_COUNT))
444
            {
445
                Window::mouseDragged(event);
446
                return;
447
            }
448
449
            const int index = getIndexFromGrid(event.getX(), event.getY());
450
            if (index == -1)
451
            {
452
                Window::mouseDragged(event);
453
                return;
454
            }
455
            const int itemId = mItems[mCurrentOutfit][index];
456
            const ItemColor itemColor = mItemColors[mCurrentOutfit][index];
457
            if (itemId < 0)
458
            {
459
                Window::mouseDragged(event);
460
                return;
461
            }
462
            mMoved = false;
463
            event.consume();
464
            const Inventory *const inv = PlayerInfo::getInventory();
465
            if (inv != nullptr)
466
            {
467
                Item *const item = inv->findItem(itemId, itemColor);
468
                if (item != nullptr)
469
                    dragDrop.dragItem(item, DragDropSource::Outfit);
470
                else
471
                    dragDrop.clear();
472
                mItems[mCurrentOutfit][index] = -1;
473
            }
474
        }
475
    }
476
    Window::mouseDragged(event);
477
}
478
479
void OutfitWindow::mousePressed(MouseEvent &event)
480
{
481
    const int index = getIndexFromGrid(event.getX(), event.getY());
482
    if (event.getButton() == MouseButton::RIGHT && (popupMenu != nullptr))
483
    {
484
        popupMenu->showOutfitsWindowPopup(viewport->mMouseX,
485
            viewport->mMouseY);
486
        event.consume();
487
        return;
488
    }
489
    else if (index == -1)
490
    {
491
        Window::mousePressed(event);
492
        return;
493
    }
494
    mMoved = false;
495
    event.consume();
496
497
    if (mItems[mCurrentOutfit][index] > 0)
498
    {
499
        mItemClicked = true;
500
    }
501
    else
502
    {
503
        if (dragDrop.isSelected())
504
        {
505
            mItems[mCurrentOutfit][index] = dragDrop.getSelected();
506
            mItemColors[mCurrentOutfit][index] = dragDrop.getSelectedColor();
507
            dragDrop.deselect();
508
            save();
509
        }
510
    }
511
512
    Window::mousePressed(event);
513
}
514
515
void OutfitWindow::mouseReleased(MouseEvent &event)
516
{
517
    if (event.getButton() == MouseButton::LEFT)
518
    {
519
        if (mCurrentOutfit < 0 || mCurrentOutfit
520
            >= static_cast<signed int>(OUTFITS_COUNT))
521
        {
522
            return;
523
        }
524
        const int index = getIndexFromGrid(event.getX(), event.getY());
525
        if (index == -1)
526
        {
527
            dragDrop.clear();
528
            Window::mouseReleased(event);
529
            return;
530
        }
531
        mMoved = false;
532
        event.consume();
533
        if (!dragDrop.isEmpty())
534
        {
535
            if (dragDrop.isSourceItemContainer())
536
            {
537
                mItems[mCurrentOutfit][index] = dragDrop.getItem();
538
                mItemColors[mCurrentOutfit][index] = dragDrop.getItemColor();
539
                dragDrop.clear();
540
                dragDrop.deselect();
541
                save();
542
            }
543
        }
544
        if (mItemClicked)
545
            mItemClicked = false;
546
    }
547
    Window::mouseReleased(event);
548
}
549
550
int OutfitWindow::getIndexFromGrid(const int pointX, const int pointY) const
551
{
552
    const Rect tRect = Rect(mPadding, mTitleBarHeight,
553
        mGridWidth * mBoxWidth, mGridHeight * mBoxHeight);
554
    if (!tRect.isPointInRect(pointX, pointY))
555
        return -1;
556
    const int index = (((pointY - mTitleBarHeight) / mBoxHeight) * mGridWidth)
557
        + (pointX - mPadding) / mBoxWidth;
558
    if (index >= CAST_S32(OUTFIT_ITEM_COUNT) || index < 0)
559
        return -1;
560
    return index;
561
}
562
563
void OutfitWindow::unequipNotInOutfit(const int outfit) const
564
{
565
    // here we think that outfit is correct index
566
567
    const Inventory *const inventory = PlayerInfo::getInventory();
568
    if (inventory == nullptr)
569
        return;
570
571
    const unsigned int invSize = inventory->getSize();
572
    for (unsigned i = 0; i < invSize; i++)
573
    {
574
        const Item *const item = inventory->getItem(i);
575
        if ((item != nullptr) && item->isEquipped() == Equipped_true)
576
        {
577
            bool found = false;
578
            for (unsigned f = 0; f < OUTFIT_ITEM_COUNT; f++)
579
            {
580
                if (item->getId() == mItems[outfit][f])
581
                {
582
                    found = true;
583
                    break;
584
                }
585
            }
586
            if (!found)
587
                PlayerInfo::unequipItem(item, Sfx_false);
588
        }
589
    }
590
}
591
592
2
std::string OutfitWindow::keyName(const int number)
593
{
594
2
    if (number < 0 || number >= SHORTCUT_EMOTES)
595
        return "";
596
2
    return inputManager.getKeyStringLong(InputAction::OUTFIT_1 + number);
597
}
598
599
void OutfitWindow::next()
600
{
601
    if (mCurrentOutfit < (CAST_S32(OUTFITS_COUNT) - 1))
602
        mCurrentOutfit++;
603
    else
604
        mCurrentOutfit = 0;
605
    showCurrentOutfit();
606
}
607
608
void OutfitWindow::previous()
609
{
610
    if (mCurrentOutfit > 0)
611
        mCurrentOutfit--;
612
    else
613
        mCurrentOutfit = OUTFITS_COUNT - 1;
614
    showCurrentOutfit();
615
}
616
617
void OutfitWindow::showCurrentOutfit()
618
{
619
    // TRANSLATORS: outfits window label
620
    mCurrentLabel->setCaption(strprintf(_("Outfit: %d"), mCurrentOutfit + 1));
621
    if (mCurrentOutfit < CAST_S32(OUTFITS_COUNT))
622
        mUnequipCheck->setSelected(mItemsUnequip[mCurrentOutfit]);
623
    else
624
        mUnequipCheck->setSelected(false);
625
    // TRANSLATORS: outfits window label
626
    mKeyLabel->setCaption(strprintf(_("Key: %s"),
627
        keyName(mCurrentOutfit).c_str()));
628
    mAwayOutfitCheck->setSelected(mAwayOutfit == mCurrentOutfit);
629
}
630
631
void OutfitWindow::wearNextOutfit(const bool all)
632
{
633
    next();
634
    if (!all && mCurrentOutfit >= 0 && mCurrentOutfit
635
        < CAST_S32(OUTFITS_COUNT))
636
    {
637
        bool fromStart = false;
638
        while (!mItemsUnequip[mCurrentOutfit])
639
        {
640
            next();
641
            if (mCurrentOutfit == 0)
642
            {
643
                if (!fromStart)
644
                    fromStart = true;
645
                else
646
                    return;
647
            }
648
        }
649
    }
650
    wearOutfit(mCurrentOutfit);
651
}
652
653
void OutfitWindow::wearPreviousOutfit(const bool all)
654
{
655
    previous();
656
    if (!all && mCurrentOutfit >= 0 && mCurrentOutfit
657
        < CAST_S32(OUTFITS_COUNT))
658
    {
659
        bool fromStart = false;
660
        while (!mItemsUnequip[mCurrentOutfit])
661
        {
662
            previous();
663
            if (mCurrentOutfit == 0)
664
            {
665
                if (!fromStart)
666
                    fromStart = true;
667
                else
668
                    return;
669
            }
670
        }
671
    }
672
    wearOutfit(mCurrentOutfit);
673
}
674
675
void OutfitWindow::copyFromEquiped()
676
{
677
    copyFromEquiped(mCurrentOutfit);
678
}
679
680
void OutfitWindow::copyFromEquiped(const int dst)
681
{
682
    const Inventory *const inventory = PlayerInfo::getInventory();
683
    if (inventory == nullptr)
684
        return;
685
686
    int outfitCell = 0;
687
    for (unsigned i = 0, sz = inventory->getSize(); i < sz; i++)
688
    {
689
        const Item *const item = inventory->getItem(i);
690
        if ((item != nullptr) && item->isEquipped() == Equipped_true)
691
        {
692
            mItems[dst][outfitCell] = item->getId();
693
            mItemColors[dst][outfitCell++] = item->getColor();
694
            if (outfitCell >= CAST_S32(OUTFIT_ITEM_COUNT))
695
                break;
696
        }
697
    }
698
    save();
699
}
700
701
void OutfitWindow::wearAwayOutfit()
702
{
703
    copyFromEquiped(OUTFITS_COUNT);
704
    wearOutfit(mAwayOutfit, false);
705
}
706
707
void OutfitWindow::unwearAwayOutfit()
708
{
709
    wearOutfit(OUTFITS_COUNT);
710
}
711
712
void OutfitWindow::clearCurrentOutfit()
713
{
714
    if (mCurrentOutfit < 0 || mCurrentOutfit
715
        >= static_cast<signed int>(OUTFITS_COUNT))
716
    {
717
        return;
718
    }
719
    for (unsigned f = 0; f < OUTFIT_ITEM_COUNT; f++)
720
    {
721
        mItems[mCurrentOutfit][f] = -1;
722
        mItemColors[mCurrentOutfit][f] = ItemColor_one;
723
    }
724
    save();
725
}
726
727
std::string OutfitWindow::getOutfitString() const
728
{
729
    std::string str;
730
    for (unsigned int i = 0; i < OUTFIT_ITEM_COUNT; i++)
731
    {
732
        const int id = mItems[mCurrentOutfit][i];
733
        if (id < 0)
734
            continue;
735
736
        const ItemColor color = mItemColors[mCurrentOutfit][i];
737
        STD_VECTOR<int> ids;
738
        ids.push_back(id);
739
        ids.push_back(CAST_S32(color));
740
741
        const std::string name = ItemDB::getNamesStr(ids);
742
        if (name.empty())
743
            continue;
744
        str.append("[");
745
        str.append(name);
746
        str.append("] ");
747
    }
748
    return str;
749

6
}