75 XmlNodeConstPtrConst node);
77 XmlNodeConstPtr replaceNode)
A_NONNULL(1);
87 for (
size_t f = 0; f < sz; f ++)
90 if (type.
name == name)
93 logger->
log(
"Unknown item type: " + name);
100 for (
size_t f = 0; f < sz; f ++)
103 if (item.
type == type)
106 return std::string();
111 return std::string();
117 for (
size_t f = 0; f < sz; f ++)
120 if (item.
type == type)
123 return std::string();
128 return std::string();
152 logger->
log1(
"Initializing item database...");
165 mTags[
"All"] = tagNum ++;
166 mTags[
"Usable"] = tagNum ++;
167 mTags[
"Unusable"] = tagNum ++;
168 mTags[
"Equipment"] = tagNum ++;
213 STD_VECTOR<ItemMenuItem> &
menu)
217 if (xmlNameEqual(node,
"menu"))
226 "command2", command1);
275 XmlNodeConstPtrConst rootNode = doc.
rootNode();
277 if ((rootNode ==
nullptr) || !xmlNameEqual(rootNode,
"items"))
291 if (xmlNameEqual(node,
"include"))
298 if (!xmlNameEqual(node,
"item"))
306 reportAlways(
"ItemDB: Invalid or missing item ID in %s!",
312 logger->
log(
"ItemDB: Redefinition of item ID %d",
id);
331 node,
"skyattack-action",
"");
333 node,
"waterattack-action",
"");
335 node,
"rideattack-action",
"");
341 node,
"maxFloorOffsetX", maxFloorOffset, 0,
mapTileSize);
343 node,
"maxFloorOffsetY", maxFloorOffset, 0,
mapTileSize);
348 if (iconColors.empty())
352 if (id <= -1 && id > -100)
356 if (iconColors.empty())
370 node,
"missile-particle",
"");
372 node,
"missile-z", 32.0F);
374 node,
"missile-lifetime", 500);
376 node,
"missile-speed", 7.0F);
378 node,
"missile-diedistance", 8.0F);
382 node,
"critical-hit-effect-id",
388 display.
image = image;
392 display.
floor = image;
394 const ItemInfo *inheritItemInfo =
nullptr;
404 reportAlways(
"Inherit item %d from not existing item %d",
411 if (name.empty() && (inheritItemInfo !=
nullptr))
412 name = inheritItemInfo->
getName();
414 itemInfo->setName(name.empty() ?
_(
"unnamed") : name);
418 itemInfo->setNameEn(name.empty() ?
_(
"unnamed") : name);
425 if (description.empty() && (inheritItemInfo !=
nullptr))
427 itemInfo->setDescription(description);
430 if (inheritItemInfo !=
nullptr)
440 if (useButton.empty() && (inheritItemInfo !=
nullptr))
442 if (useButton.empty())
445 if (useButton2.empty() && (inheritItemInfo !=
nullptr))
447 if (useButton2.empty())
449 itemInfo->setUseButton2(useButton2);
452 node,
"sellProtected",
false));
455 else if (inheritItemInfo !=
nullptr)
485 for (
int f = 0; f < 3; f++)
487 if (!tags[f].
empty())
492 mTags[tags[f]] = tagNum ++;
502 if (!effect.empty() && !temp.empty())
503 effect.append(
" / ");
506 if (inheritItemInfo !=
nullptr)
509 view = inheritItemInfo->
getView();
512 if (attackAction.empty())
514 if (skyAttackAction.empty())
516 if (waterAttackAction.empty())
518 if (rideAttackAction.empty())
520 if (attackRange == 0)
522 if (hitEffectId == 0)
524 if (criticalEffectId == 0)
526 if (missEffectId == 0)
530 if (iconColors.empty())
537 if (missileParticle.empty())
538 missileParticle = inheritMissile.
particle;
539 if (missileZ == 32.0F)
540 missileZ = inheritMissile.
z;
541 if (missileLifeTime == 500)
542 missileLifeTime = inheritMissile.
lifeTime;
543 if (missileSpeed == 7.0F)
544 missileSpeed = inheritMissile.
speed;
545 if (missileDieDistance == 8.0F)
551 itemInfo->setAttackAction(attackAction);
552 itemInfo->setSkyAttackAction(skyAttackAction);
553 itemInfo->setWaterAttackAction(waterAttackAction);
554 itemInfo->setRideAttackAction(rideAttackAction);
555 itemInfo->setAttackRange(attackRange);
556 itemInfo->setHitEffectId(hitEffectId);
557 itemInfo->setCriticalHitEffectId(criticalEffectId);
558 itemInfo->setMissEffectId(missEffectId);
561 itemInfo->setDrawPriority(-1, drawPriority);
563 itemInfo->setIconColorsList(iconColors);
564 itemInfo->setMaxFloorOffsetX(maxFloorOffsetX);
565 itemInfo->setMaxFloorOffsetY(maxFloorOffsetY);
567 node,
"pickupCursor",
"pickup"));
571 missile.
z = missileZ;
573 missile.
speed = missileSpeed;
578 if (xmlNameEqual(itemChild,
"sprite"))
582 else if (xmlNameEqual(itemChild,
"particlefx"))
584 if (XmlHaveChildContent(itemChild))
585 display.
particles.push_back(XmlChildContent(itemChild));
587 else if (xmlNameEqual(itemChild,
"sound"))
591 else if (xmlNameEqual(itemChild,
"floor"))
595 else if (xmlNameEqual(itemChild,
"replace"))
599 else if (xmlNameEqual(itemChild,
"drawAfter"))
603 else if (xmlNameEqual(itemChild,
"drawBefore"))
607 else if (xmlNameEqual(itemChild,
"inventory"))
611 else if (xmlNameEqual(itemChild,
"storage"))
615 else if (xmlNameEqual(itemChild,
"cart"))
619 else if (xmlNameEqual(itemChild,
"addStats"))
623 else if (xmlNameEqual(itemChild,
"requireStats"))
680 if (!attackAction.empty())
682 if (attackRange == 0)
684 reportAlways(
"ItemDB: Missing attack range from weapon %i!",
689 STD_VECTOR<ItemMenuItem> &inventoryMenu =
itemInfo->getInventoryMenu();
691 if (inventoryMenu.empty())
693 std::string name1 =
itemInfo->getUseButton();
694 std::string name2 =
itemInfo->getUseButton2();
707 name2 =
_(
"Unequip");
727 "useinv 'INVINDEX'"));
730 #define CHECK_PARAM(param) \
733 logger->log("ItemDB: Missing " #param " attribute for item %i!", \
737 if (
id >= 0 && typeStr !=
"other")
756 return mTags[tagName];
778 const ItemInfos::const_iterator i =
mItemInfos.find(
id);
797 const ItemInfos::const_iterator i =
mItemInfos.find(
id);
801 reportAlways(
"ItemDB: Warning, unknown item ID# %d",
id)
820 reportAlways(
"ItemDB: Warning, unknown item name \"%s\"",
842 if (name ==
"race" || name ==
"type")
846 else if (name ==
"shoes" || name ==
"boot" || name ==
"boots")
850 else if (name ==
"bottomclothes" || name ==
"bottom" || name ==
"pants")
854 else if (name ==
"topclothes" || name ==
"top"
855 || name ==
"torso" || name ==
"body")
859 else if (name ==
"misc1")
863 else if (name ==
"misc2" || name ==
"scarf" || name ==
"scarfs")
867 else if (name ==
"hair")
871 else if (name ==
"hat" || name ==
"hats")
875 else if (name ==
"wings")
879 else if (name ==
"glove" || name ==
"gloves")
883 else if (name ==
"weapon" || name ==
"weapons")
887 else if (name ==
"shield" || name ==
"shields")
891 else if (name ==
"amulet" || name ==
"amulets")
895 else if (name ==
"ring" || name ==
"rings")
915 else if (name ==
"downleft" || name ==
"leftdown")
919 else if (name ==
"left")
923 else if (name ==
"upleft" || name ==
"leftup")
927 else if (name ==
"up")
936 else if (name ==
"upright" || name ==
"rightup")
940 else if (name ==
"right")
944 else if (name ==
"downright" || name ==
"rightdown")
948 else if (name ==
"downall")
952 else if (name ==
"upall")
957 else if (name ==
"died")
968 if ((node ==
nullptr) || !XmlHaveChildContent(node))
971 const std::string filename = XmlChildContent(node);
974 if (gender ==
"male" || gender ==
"unisex")
976 if (gender ==
"female" || gender ==
"unisex")
982 if (node ==
nullptr ||
983 !XmlHaveChildContent(node))
988 const std::map<std::string, ItemSoundEvent::Type>::const_iterator
993 const std::string filename = XmlChildContent(node);
994 itemInfo->addSound((*it).second, filename, delay);
998 reportAlways(
"ItemDB: Ignoring unknown sound event '%s'",
1004 XmlNodeConstPtrConst floorNode)
1006 if (floorNode ==
nullptr)
1010 if (!XmlHaveChildContent(spriteNode))
1012 if (xmlNameEqual(spriteNode,
"sprite"))
1015 currentSprite->
sprite = XmlChildContent(spriteNode);
1018 display.
sprites.push_back(currentSprite);
1020 else if (xmlNameEqual(spriteNode,
"particlefx"))
1022 display.
particles.push_back(XmlChildContent(spriteNode));
1028 XmlNodeConstPtr replaceNode)
1030 if (replaceNode ==
nullptr)
1033 replaceNode,
"sprite",
"");
1035 replaceNode,
"direction",
"all"));
1043 if (removeSprite.empty())
1045 for (
int f = 0; f < 10; f ++)
1047 for (
int sprite = 0; sprite < 13; sprite ++)
1048 itemInfo->addReplaceSprite(sprite, f);
1053 for (
int f = 0; f < 10; f ++)
1057 if (mapList ==
nullptr)
1061 if (xmlNameEqual(itemNode,
"item"))
1064 itemNode,
"from", 0);
1067 (*mapList)[from] = to;
1085 if (xmlNameEqual(itemNode,
"item"))
1091 if (mapList !=
nullptr)
1092 (*mapList)[from] = to;
1096 if (mapList !=
nullptr)
1097 (*mapList)[from] = to;
1101 if (mapList !=
nullptr)
1102 (*mapList)[from] = to;
1118 if (xmlNameEqual(itemNode,
"item"))
1124 if (mapList !=
nullptr)
1125 (*mapList)[from] = to;
1129 if (mapList !=
nullptr)
1130 (*mapList)[from] = to;
1134 if (mapList !=
nullptr)
1135 (*mapList)[from] = to;
1144 if (mapList ==
nullptr)
1148 if (xmlNameEqual(itemNode,
"item"))
1152 (*mapList)[from] = to;
1161 XmlNodeConstPtr node,
1162 const bool drawAfter)
1168 node,
"direction",
"all"));
1170 itemInfo->setDrawAfter(direction, sprite);
1172 itemInfo->setDrawBefore(direction, sprite);
1173 itemInfo->setDrawPriority(direction, priority);
1179 FOR_EACH (STD_VECTOR<int>::const_iterator, it, parts)
static void loadXmlFile(const std::string &file, const std::string &name, BadgesInfos &arr, const SkipError skipError)
const BeingTypeId BeingTypeId_zero
#define reportAlways(...)
std::string getStringValue(const std::string &key) const
int getIntValue(const std::string &key) const
const std::string & getDescription() const
std::string getColorsListName() const
const std::string & getWaterAttackAction() const
const std::string & getName() const
const std::string & getUseButton() const
ItemColor getCardColor() const
int getCriticalHitEffectId() const
ItemDbTypeT getType() const
int getMissEffectId() const
const MissileInfo & getMissileConst() const
int getAttackRange() const
const std::string & getEffect() const
void setSprite(const std::string &animationFile, const GenderT gender, const int race)
std::string getIconColorsListName() const
const std::string & getRideAttackAction() const
int getHitEffectId() const
void addTag(const int tag)
void setDisplay(const SpriteDisplay &display)
const std::string & getAttackAction() const
const std::string & getSkyAttackAction() const
void setName(const std::string &name)
void log(const char *const log_text,...)
void log1(const char *const log_text)
static const int mapTileSize
void delete_all(Container &c)
#define FOR_EACH(type, iter, array)
#define fromInt(val, name)
std::map< int, int > IntMap
static std::string useButtonFromItemType(const ItemDbTypeT &type)
static int parseSpriteName(const std::string &name)
static void loadSpriteRef(ItemInfo *const itemInfo, const xmlNodePtr node)
#define CHECK_PARAM(param)
static bool getIsEquipment(const ItemDbTypeT type)
static void loadReplaceSprite(ItemInfo *const itemInfo, const xmlNodePtr replaceNode)
static std::string useButton2FromItemType(const ItemDbTypeT &type)
static void loadOrderSprite(ItemInfo *const itemInfo, const xmlNodePtr node, const bool drawAfter)
static void loadSoundRef(ItemInfo *const itemInfo, const xmlNodePtr node)
static void loadFloorSprite(SpriteDisplay &display, const xmlNode *const node)
static int parseDirectionName(const std::string &name)
static void loadMenu(xmlNode *const parentNode, std::vector< ItemMenuItem > &menu)
static ItemDbTypeT itemTypeFromString(const std::string &name)
ItemDbType ::T ItemDbTypeT
std::map< std::string, ItemFieldType * > ItemFieldInfos
ItemTypeMap itemTypeMap[]
void readItemStatsString(std::string &effect, const xmlNodePtr node, const ItemFieldInfos &fields)
#define for_each_xml_child_node(var, parent)
bool itemInfo(InputEvent &event)
AttributesT get(const std::string &key)
const EmoteSprite * getSprite(const int id, const bool allowNull)
const std::string & getName(const int id)
bool exists(const int id)
const StringVect & getTags()
const ItemInfo & getEmpty()
const ItemInfo & get(const int id)
int getTagId(const std::string &tagName)
const ItemDB::ItemInfos & getItemInfos()
std::string getNamesStr(const std::vector< int > &parts)
std::map< std::string, ItemInfo * > NamedItemInfos
void loadXmlFile(const std::string &fileName, int &tagNum, const SkipError skipError)
std::map< int, ItemInfo * > ItemInfos
@ EQUIPMENT_TWO_HANDS_WEAPON
@ EQUIPMENT_ONE_HAND_WEAPON
const ItemFieldInfos & getRequiredFields()
const ItemFieldInfos & getAddFields()
ServerTypeT getNetworkType()
void getFilesInDir(const std::string &dir, StringVect &list, const std::string &ext)
bool exists(std::string name)
std::string langProperty(const xmlNodePtr node, const char *const name, const std::string &def)
float getFloatProperty(const xmlNodePtr node, const char *const name, float def)
bool getBoolProperty(const xmlNodePtr node, const char *const name, const bool def)
int getProperty(const xmlNodePtr node, const char *const name, int def)
int getIntProperty(const xmlNodePtr node, const char *const name, int def, const int min, const int max)
ItemDB::NamedItemInfos mNamedItemInfos
std::map< std::string, ItemSoundEvent::Type > mSoundNames
ItemDB::ItemInfos mItemInfos
const bool SkipError_false
const bool SkipError_true
std::map< std::string, int > StringIntMap
std::string normalize(const std::string &name)
StringVect::const_iterator StringVectCIter
std::vector< std::string > StringVect
std::vector< SpriteReference * > sprites
const bool UseVirtFs_true