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 "resources/item/item.h"
25 
26 #include "configuration.h"
27 #include "dragdrop.h"
28 #include "itemcolormanager.h"
29 
30 #include "gui/theme.h"
31 
32 #include "resources/iteminfo.h"
33 
34 #include "resources/item/itemoptionslist.h"
35 
36 #include "resources/loaders/imageloader.h"
37 
38 #include "net/net.h"
39 
40 #include "utils/delete2.h"
41 
42 #include "debug.h"
43 
44 DragDrop dragDrop(nullptr, DragDropSource::Empty);
45 
Item(const int id,const ItemTypeT type,const int quantity,const uint8_t refine,const ItemColor color,const Identified identified,const Damaged damaged,const Favorite favorite,const Equipm equipment,const Equipped equipped)46 Item::Item(const int id,
47            const ItemTypeT type,
48            const int quantity,
49            const uint8_t refine,
50            const ItemColor color,
51            const Identified identified,
52            const Damaged damaged,
53            const Favorite favorite,
54            const Equipm equipment,
55            const Equipped equipped) :
56     mId(0),
57     mColor(ItemColor_zero),
58     mQuantity(quantity),
59     mTag(0),
60     mImage(nullptr),
61     mDescription(),
62     mTags(),
63     mCards(),
64     mOptions(nullptr),
65     mRefine(refine),
66     mInvIndex(0),
67     mType(type),
68     mEquipment(equipment),
69     mEquipped(equipped),
70     mInEquipment(false),
71     mIdentified(identified),
72     mDamaged(damaged),
73     mFavorite(favorite)
74 {
75     setId(id, color);
76     for (int f = 0; f < maxCards; f ++)
77         mCards[f] = 0;
78 }
79 
~Item()80 Item::~Item()
81 {
82     if (mImage != nullptr)
83     {
84         mImage->decRef();
85         mImage = nullptr;
86     }
87     delete2(mOptions)
88     dragDrop.clearItem(this);
89 }
90 
setId(const int id,const ItemColor color)91 void Item::setId(const int id,
92                  const ItemColor color)
93 {
94     mId = id;
95     mColor = color;
96 
97     // Types 0 and 1 are not equippable items.
98     mEquipment = fromBool(id && CAST_S32(getInfo().getType())
99         >= 2, Equipm);
100 
101     if (mImage != nullptr)
102         mImage->decRef();
103 
104     const ItemInfo &info = getInfo();
105     mTags = info.getTags();
106 
107     const std::string dye = combineDye2(pathJoin(
108         paths.getStringValue("itemIcons"), info.getDisplay().image),
109         info.getDyeIconColorsString(color));
110     mImage = Loader::getImage(dye);
111 
112     if (mImage == nullptr)
113     {
114         mImage = Theme::getImageFromTheme(paths.getValue("unknownItemFile",
115             "unknown-item.png"));
116     }
117 }
118 
isHaveTag(const int tagId) const119 bool Item::isHaveTag(const int tagId) const
120 {
121     const std::map <int, int>::const_iterator it = mTags.find(tagId);
122     if (it == mTags.end())
123         return false;
124     return (*it).second > 0;
125 }
126 
getImage(const int id,const ItemColor color)127 Image *Item::getImage(const int id,
128                       const ItemColor color)
129 {
130     const ItemInfo &info = ItemDB::get(id);
131     Image *image = Loader::getImage(combineDye2(pathJoin(paths.getStringValue(
132         "itemIcons"), info.getDisplay().image),
133         info.getDyeIconColorsString(color)));
134 
135     if (image == nullptr)
136         image = Theme::getImageFromTheme("unknown-item.png");
137     return image;
138 }
139 
getName() const140 std::string Item::getName() const
141 {
142     const ItemInfo &info = ItemDB::get(mId);
143 #ifdef TMWA_SUPPORT
144     if (Net::getNetworkType() == ServerType::TMWATHENA)
145     {
146         return info.getName();
147     }
148 #endif  // TWMA_SUPPORT
149     return info.getName(mColor);
150 }
151 
setCard(const int index,const int id)152 void Item::setCard(const int index, const int id)
153 {
154     if (index < 0 || index >= maxCards)
155         return;
156     mCards[index] = id;
157 }
158 
getCard(const int index) const159 int Item::getCard(const int index) const
160 {
161     if (index < 0 || index >= maxCards)
162         return 0;
163     return mCards[index];
164 }
165 
setCards(const int * const cards,const int size)166 void Item::setCards(const int *const cards, const int size)
167 {
168     if (size < 0 || (cards == nullptr))
169         return;
170     int sz = size;
171     if (sz > maxCards)
172         sz = maxCards;
173     for (int f = 0; f < sz; f ++)
174         mCards[f] = cards[f];
175 }
176 
addCard(const int card)177 void Item::addCard(const int card)
178 {
179     for (int f = 0; f < maxCards; f ++)
180     {
181         if (mCards[f] == 0)
182         {
183             mCards[f] = card;
184             return;
185         }
186     }
187 }
188 
setOptions(const ItemOptionsList * const options)189 void Item::setOptions(const ItemOptionsList *const options)
190 {
191     delete2(mOptions)
192     mOptions = ItemOptionsList::copy(options);
193 }
194 
updateColor()195 void Item::updateColor()
196 {
197     if (Net::getNetworkType() != ServerType::TMWATHENA)
198         setId(mId, ItemColorManager::getColorFromCards(&mCards[0]));
199 }
200