ManaPlus
iteminfo.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-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/iteminfo.h"
25 
27 
29 
31 
32 #include "resources/itemmenuitem.h"
33 
34 #include "resources/db/colordb.h"
35 #include "resources/db/itemdb.h"
36 
37 #include "utils/checkutils.h"
38 #include "utils/dtor.h"
39 #include "utils/stringutils.h"
40 
41 #include "debug.h"
42 
44  mDisplay(),
45  mMissile(),
46  mName(),
47  mNameEn(),
48  mDescription(),
49  mEffect(),
50  mUseButton(),
51  mUseButton2(),
52  mType(ItemDbType::UNUSABLE),
53  mWeight(0),
54  mView(0),
55  mId(0),
56  mIsRemoveSprites(false),
57  mSpriteToItemReplaceList(),
58  mAttackAction(SpriteAction::INVALID),
59  mSkyAttackAction(SpriteAction::INVALID),
60  mWaterAttackAction(SpriteAction::INVALID),
61  mRideAttackAction(SpriteAction::INVALID),
62  mAttackRange(0),
63  mMissileParticle(),
64  mAnimationFiles(),
65  mSounds(),
66  mTags(),
67  mColorsList(nullptr),
68  mIconColorsList(nullptr),
69  mInventoryMenu(),
70  mStorageMenu(),
71  mCartMenu(),
72  mColorsListName(),
73  mIconColorsListName(),
74  mCardColor(ItemColor_zero),
75  mHitEffectId(-1),
76  mCriticalHitEffectId(-1),
77  mMissEffectId(-1),
78  maxFloorOffsetX(mapTileSize),
79  maxFloorOffsetY(mapTileSize),
80  mPickupCursor(Cursor::CURSOR_POINTER),
81  mProtected(false)
82 {
83  for (int f = 0; f < 10; f ++)
84  {
85  mSpriteToItemReplaceMap[f] = nullptr;
86  mDrawBefore[f] = -1;
87  mDrawAfter[f] = -1;
88  mDrawPriority[f] = 0;
89  }
90 }
91 
93 {
96  for (int f = 0; f < 10; f ++)
97  mSpriteToItemReplaceMap[f] = nullptr;
98 }
99 
100 const std::string &ItemInfo::getSprite(const GenderT gender,
101  const BeingTypeId race) const
102 {
103  if (mView != 0)
104  {
105  // Forward the request to the item defining how to view this item
106  return ItemDB::get(mView).getSprite(gender, race);
107  }
108  static const std::string empty;
109  std::map<int, std::string>::const_iterator i =
110  mAnimationFiles.find(CAST_S32(gender) +
111  toInt(race, int) * 4);
112 
113  if (i != mAnimationFiles.end())
114  return i->second;
115  i = mAnimationFiles.find(CAST_S32(gender));
116  if (i != mAnimationFiles.end())
117  return i->second;
118  return empty;
119 }
120 
121 void ItemInfo::setAttackAction(const std::string &attackAction)
122 {
123  if (attackAction.empty())
124  mAttackAction = SpriteAction::ATTACK; // (Equal to unarmed animation)
125  else
126  mAttackAction = attackAction;
127 }
128 
129 void ItemInfo::setSkyAttackAction(const std::string &attackAction)
130 {
131  if (attackAction.empty())
133  else
134  mSkyAttackAction = attackAction;
135 }
136 
137 void ItemInfo::setWaterAttackAction(const std::string &attackAction)
138 {
139  if (attackAction.empty())
141  else
142  mWaterAttackAction = attackAction;
143 }
144 
145 void ItemInfo::setRideAttackAction(const std::string &attackAction)
146 {
147  if (attackAction.empty())
149  else
150  mRideAttackAction = attackAction;
151 }
152 
154  const std::string &filename, const int delay)
155 {
156  mSounds[event].push_back(SoundInfo(
157  filename,
158  delay));
159 }
160 
162 {
163  static const SoundInfo empty("", 0);
164  std::map<ItemSoundEvent::Type, SoundInfoVect>::const_iterator i;
165 
166  i = mSounds.find(event);
167 
168  if (i == mSounds.end())
169  return empty;
170  return (!i->second.empty()) ? i->second[CAST_U32(rand())
171  % i->second.size()] : empty;
172 }
173 
175  const int direction)
176 {
177  if (direction < 0 || direction >= 10)
178  return nullptr;
179 
180  SpriteToItemMap *spMap = mSpriteToItemReplaceMap[direction];
181 
182  if (spMap == nullptr)
183  {
184  spMap = new SpriteToItemMap;
185  mSpriteToItemReplaceMap[direction] = spMap;
186  mSpriteToItemReplaceList.push_back(spMap);
187  }
188 
189  SpriteToItemMap::iterator it = spMap->find(sprite);
190  if (it == spMap->end())
191  {
192  IntMap tmp;
193  (*mSpriteToItemReplaceMap[direction])[sprite] = tmp;
194  it = mSpriteToItemReplaceMap[direction]->find(sprite);
195  }
196  return &it->second;
197 }
198 
199 void ItemInfo::setColorsList(const std::string &name)
200 {
201  if (name.empty())
202  {
203  mColorsList = nullptr;
204  mColorsListName.clear();
205  }
206  else
207  {
209  mColorsListName = name;
210  }
211 }
212 
213 void ItemInfo::setIconColorsList(const std::string &name)
214 {
215  if (name.empty())
216  {
217  mIconColorsList = nullptr;
218  mIconColorsListName.clear();
219  }
220  else
221  {
223  mIconColorsListName = name;
224  }
225 }
226 
227 std::string ItemInfo::getDyeColorsString(const ItemColor color) const
228 {
229  if ((mColorsList == nullptr) || mColorsListName.empty())
230  return "";
231 
232  const std::map <ItemColor, ItemColorData>::const_iterator
233  it = mColorsList->find(color);
234  if (it == mColorsList->end())
235  return "";
236 
237  return it->second.color;
238 }
239 
240 std::string ItemInfo::getDyeIconColorsString(const ItemColor color) const
241 {
242  if ((mIconColorsList == nullptr) || mIconColorsListName.empty())
243  return "";
244 
245  const std::map <ItemColor, ItemColorData>::const_iterator
246  it = mIconColorsList->find(color);
247  if (it == mIconColorsList->end())
248  return "";
249 
250  return it->second.color;
251 }
252 
253 const std::string ItemInfo::getDescription(const ItemColor color) const
254 {
255  return replaceColors(mDescription, color);
256 }
257 
258 const std::string ItemInfo::getName(const ItemColor color) const
259 {
260  return replaceColors(mName, color);
261 }
262 
263 const std::string ItemInfo::getNameEn(const ItemColor color) const
264 {
265  return replaceColors(mNameEn, color);
266 }
267 
268 const std::string ItemInfo::replaceColors(std::string str,
269  const ItemColor color) const
270 {
271  std::string name;
272  if ((mColorsList != nullptr) && !mColorsListName.empty())
273  {
274  const std::map <ItemColor, ItemColorData>::const_iterator
275  it = mColorsList->find(color);
276  if (it == mColorsList->end())
277  name = "unknown";
278  else
279  name = it->second.name;
280  }
281  else
282  {
283  name = "unknown";
284  }
285 
286  str = replaceAll(str, "%color%", name);
287  if (!name.empty())
288  name[0] = CAST_S8(toupper(name[0]));
289 
290  return replaceAll(str, "%Color%", name);
291 }
292 
294  const
295 {
296  if (direction < 0 || direction >= 10)
297  return nullptr;
298 
299  const SpriteToItemMap *const spMap = mSpriteToItemReplaceMap[direction];
300  if (spMap != nullptr)
301  return spMap;
302  if (direction == SpriteDirection::UPLEFT
303  || direction == SpriteDirection::UPRIGHT)
304  {
306  }
307 
308  if (direction == SpriteDirection::DOWNLEFT
309  || direction == SpriteDirection::DOWNRIGHT)
310  {
312  }
313 
314  return nullptr;
315 }
316 
317 void ItemInfo::setSpriteOrder(int *const ptr,
318  const int direction,
319  const int n,
320  const int def)
321 {
322  switch (direction)
323  {
324  case -1:
325  {
326  for (int f = 0; f < 10; f ++)
327  {
328  if (ptr[f] == def)
329  ptr[f] = n;
330  }
331  return;
332  }
333  case -2:
334  {
335  ptr[SpriteDirection::DOWN] = n;
336  ptr[SpriteDirection::DOWNLEFT] = n;
338  return;
339  }
340  case -3:
341  {
342  ptr[SpriteDirection::UP] = n;
343  ptr[SpriteDirection::UPLEFT] = n;
344  ptr[SpriteDirection::UPRIGHT] = n;
345  return;
346  }
347  default:
348  break;
349  }
350  if (direction < 0 || direction >= 9)
351  return;
352 
353  if (direction == SpriteDirection::UP)
354  {
355  if (ptr[SpriteDirection::UPLEFT] == def)
356  ptr[SpriteDirection::UPLEFT] = n;
357  if (ptr[SpriteDirection::UPRIGHT] == def)
358  ptr[SpriteDirection::UPRIGHT] = n;
359  }
360  else if (direction == SpriteDirection::DOWN)
361  {
362  if (ptr[SpriteDirection::DOWNLEFT] == def)
363  ptr[SpriteDirection::DOWNLEFT] = n;
364  if (ptr[SpriteDirection::DOWNRIGHT] == def)
366  }
367  ptr[direction] = n;
368 }
369 
370 void ItemInfo::setDrawBefore(const int direction, const int n)
371 {
372  setSpriteOrder(&mDrawBefore[0], direction, n, -1);
373 }
374 
375 void ItemInfo::setDrawAfter(const int direction, const int n)
376 {
377  setSpriteOrder(&mDrawAfter[0], direction, n, -1);
378 }
379 
380 void ItemInfo::setDrawPriority(const int direction, const int n)
381 {
382  setSpriteOrder(&mDrawPriority[0], direction, n, 0);
383 }
384 
385 int ItemInfo::getDrawBefore(const int direction) const
386 {
387  if (direction < 0 || direction >= 10)
388  return -1;
389  return mDrawBefore[direction];
390 }
391 
392 int ItemInfo::getDrawAfter(const int direction) const
393 {
394  if (direction < 0 || direction >= 10)
395  return -1;
396  return mDrawAfter[direction];
397 }
398 
399 int ItemInfo::getDrawPriority(const int direction) const
400 {
401  if (direction < 0 || direction >= 10)
402  return 0;
403  return mDrawPriority[direction];
404 }
405 
406 void ItemInfo::setSprite(const std::string &animationFile,
407  const GenderT gender,
408  const int race)
409 {
410  mAnimationFiles[CAST_S32(gender) + race * 4] = animationFile;
411 }
412 
413 std::string ItemInfo::getColorName(const ItemColor idx) const
414 {
415  if (mColorsList == nullptr)
416  return std::string();
417 
418  const std::map <ItemColor, ItemColorData>::const_iterator
419  it = mColorsList->find(idx);
420  if (it == mColorsList->end())
421  {
422  reportAlways("Color %d for palette %s not found",
423  CAST_S32(idx),
424  mColorsListName.c_str())
425  return std::string();
426  }
427  return it->second.name;
428 }
429 
430 std::string ItemInfo::getColor(const ItemColor idx) const
431 {
432  if (mColorsList == nullptr)
433  return std::string();
434 
435  const std::map <ItemColor, ItemColorData>::const_iterator
436  it = mColorsList->find(idx);
437  if (it == mColorsList->end())
438  {
439  reportAlways("Color %d for palette %s not found",
440  CAST_S32(idx),
441  mColorsListName.c_str())
442  return std::string();
443  }
444  return it->second.color;
445 }
446 
447 std::string ItemInfo::getIconColorName(const ItemColor idx) const
448 {
449  if (mIconColorsList == nullptr)
450  return std::string();
451 
452  const std::map <ItemColor, ItemColorData>::const_iterator
453  it = mIconColorsList->find(idx);
454  if (it == mIconColorsList->end())
455  {
456  reportAlways("Color %d for palette %s not found",
457  CAST_S32(idx),
458  mColorsListName.c_str())
459  return std::string();
460  }
461  return it->second.name;
462 }
463 
464 std::string ItemInfo::getIconColor(const ItemColor idx) const
465 {
466  if (mIconColorsList == nullptr)
467  return std::string();
468 
469  const std::map <ItemColor, ItemColorData>::const_iterator
470  it = mIconColorsList->find(idx);
471  if (it == mIconColorsList->end())
472  {
473  reportAlways("Color %d for palette %s not found",
474  CAST_S32(idx),
475  mColorsListName.c_str())
476  return std::string();
477  }
478  return it->second.color;
479 }
480 
481 const std::string ItemInfo::getLink() const
482 {
483  return strprintf("[@@%d|%[email protected]@]", mId, mName.c_str());
484 }
int BeingTypeId
Definition: beingtypeid.h:30
#define CAST_S8
Definition: cast.h:26
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
#define reportAlways(...)
Definition: checkutils.h:253
std::string mName
Definition: iteminfo.h:345
const std::string & getSprite(const GenderT gender, const BeingTypeId race) const
Definition: iteminfo.cpp:100
const std::string & getDescription() const
Definition: iteminfo.h:100
std::string getColor(const ItemColor idx) const
Definition: iteminfo.cpp:430
int mDrawPriority[10]
Definition: iteminfo.h:335
const std::string & getName() const
Definition: iteminfo.h:74
int mDrawBefore[10]
Definition: iteminfo.h:333
std::string getIconColorName(const ItemColor idx) const
Definition: iteminfo.cpp:447
void setRideAttackAction(const std::string &attackAction)
Definition: iteminfo.cpp:145
int getDrawAfter(const int direction) const
Definition: iteminfo.cpp:392
void setSkyAttackAction(const std::string &attackAction)
Definition: iteminfo.cpp:129
std::string getDyeColorsString(const ItemColor color) const
Definition: iteminfo.cpp:227
int getDrawBefore(const int direction) const
Definition: iteminfo.cpp:385
const std::string & getNameEn() const
Definition: iteminfo.h:83
std::string getColorName(const ItemColor idx) const
Definition: iteminfo.cpp:413
std::string mRideAttackAction
Definition: iteminfo.h:369
IntMap * addReplaceSprite(const int sprite, const int direction)
Definition: iteminfo.cpp:174
std::string getIconColor(const ItemColor idx) const
Definition: iteminfo.cpp:464
int mId
Definition: iteminfo.h:354
~ItemInfo()
Definition: iteminfo.cpp:92
std::string mIconColorsListName
Definition: iteminfo.h:387
int mView
Definition: iteminfo.h:353
SpriteToItemMap * mSpriteToItemReplaceMap[10]
Definition: iteminfo.h:357
std::string mDescription
Definition: iteminfo.h:347
const SoundInfo & getSound(const ItemSoundEvent::Type event) const
Definition: iteminfo.cpp:161
void setIconColorsList(const std::string &name)
Definition: iteminfo.cpp:213
int getDrawPriority(const int direction) const
Definition: iteminfo.cpp:399
void setColorsList(const std::string &name)
Definition: iteminfo.cpp:199
const std::map< ItemColor, ItemColorData > * mColorsList
Definition: iteminfo.h:381
void setSprite(const std::string &animationFile, const GenderT gender, const int race)
Definition: iteminfo.cpp:406
int mDrawAfter[10]
Definition: iteminfo.h:334
void setDrawAfter(const int direction, const int n)
Definition: iteminfo.cpp:375
std::map< int, std::string > mAnimationFiles
Definition: iteminfo.h:376
std::map< ItemSoundEvent::Type, SoundInfoVect > mSounds
Definition: iteminfo.h:379
const std::map< ItemColor, ItemColorData > * mIconColorsList
Definition: iteminfo.h:382
void setAttackAction(const std::string &attackAction)
Definition: iteminfo.cpp:121
const std::string getLink() const
Definition: iteminfo.cpp:481
std::string mWaterAttackAction
Definition: iteminfo.h:368
void addSound(const ItemSoundEvent::Type event, const std::string &filename, const int delay)
Definition: iteminfo.cpp:153
const SpriteToItemMap * getSpriteToItemReplaceMap(const int directions) const
Definition: iteminfo.cpp:293
void setDrawPriority(const int direction, const int n)
Definition: iteminfo.cpp:380
std::string mNameEn
Definition: iteminfo.h:346
std::string mColorsListName
Definition: iteminfo.h:386
static void setSpriteOrder(int *const ptr, const int direction, const int n, const int def)
Definition: iteminfo.cpp:317
void setWaterAttackAction(const std::string &attackAction)
Definition: iteminfo.cpp:137
ItemInfo()
Definition: iteminfo.cpp:43
const std::string replaceColors(std::string str, const ItemColor color) const
Definition: iteminfo.cpp:268
std::string getDyeIconColorsString(const ItemColor color) const
Definition: iteminfo.cpp:240
std::string mSkyAttackAction
Definition: iteminfo.h:367
void setDrawBefore(const int direction, const int n)
Definition: iteminfo.cpp:370
std::vector< SpriteToItemMap * > mSpriteToItemReplaceList
Definition: iteminfo.h:359
std::string mAttackAction
Definition: iteminfo.h:366
static const int mapTileSize
Definition: map.h:27
void delete_all(Container &c)
Definition: dtor.h:56
Gender ::T GenderT
Definition: gender.h:35
#define toInt(val, name)
Definition: intdefines.h:47
std::map< int, int > IntMap
Definition: intmap.h:27
uint16_t ItemColor
Definition: itemcolor.h:30
const ItemColor ItemColor_zero
Definition: itemcolor.h:30
std::map< int, IntMap > SpriteToItemMap
Definition: iteminfo.h:43
#define nullptr
Definition: localconsts.h:45
const std::map< ItemColor, ItemColorData > * getColorsList(const std::string &name)
Definition: colordb.cpp:219
Definition: cursor.h:27
@ CURSOR_POINTER
Definition: cursor.h:29
const ItemInfo & get(const int id)
Definition: itemdb.cpp:792
static const std::string ATTACKWATER("attackwater")
static const std::string ATTACKSKY("attacksky")
static const std::string INVALID
Definition: spriteaction.h:72
static const std::string ATTACKRIDE("attackride")
static const std::string ATTACK("attack")
std::vector< std::string > mSounds
Definition: sounddb.cpp:37
std::string empty
Definition: podict.cpp:26
std::string & replaceAll(std::string &context, const std::string &from, const std::string &to)
std::string strprintf(const char *const format,...)