GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/gui/windows/outfitwindow.cpp Lines: 105 364 28.8 %
Date: 2018-05-23 22:10:27 Branches: 125 438 28.5 %

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-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/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", BUTTON_SKIN, this)),
65
    // TRANSLATORS: outfits window button
66

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

4
    mEquipBottom(new Button(this, _("Equip"), "equip", BUTTON_SKIN, 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

8
        serverConfig.getValueBool("OutfitUnequip0", true),
74

4
        nullptr, std::string())),
75
    // TRANSLATORS: outfits window checkbox
76
2
    mAwayOutfitCheck(new CheckBox(this, _("Away outfit"),
77

8
        serverConfig.getValue("OutfitAwayIndex", OUTFITS_COUNT - 1) != 0u,
78

4
        nullptr, std::string())),
79
    // TRANSLATORS: outfits window label
80
4
    mKeyLabel(new Label(this, strprintf(_("Key: %s"),
81

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








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


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

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


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

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

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

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

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

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

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

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

6
}