summaryrefslogtreecommitdiff
path: root/src/resources/db/itemdb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/resources/db/itemdb.cpp')
-rw-r--r--src/resources/db/itemdb.cpp1232
1 files changed, 0 insertions, 1232 deletions
diff --git a/src/resources/db/itemdb.cpp b/src/resources/db/itemdb.cpp
deleted file mode 100644
index 274b44bb2..000000000
--- a/src/resources/db/itemdb.cpp
+++ /dev/null
@@ -1,1232 +0,0 @@
-/*
- * The ManaPlus Client
- * Copyright (C) 2004-2009 The Mana World Development Team
- * Copyright (C) 2009-2010 The Mana Developers
- * Copyright (C) 2011-2017 The ManaPlus Developers
- *
- * This file is part of The ManaPlus Client.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "resources/db/itemdb.h"
-
-#include "const/resources/map/map.h"
-
-#include "configuration.h"
-
-#include "enums/resources/spritedirection.h"
-
-#include "fs/virtfs/tools.h"
-
-#include "resources/iteminfo.h"
-#include "resources/itemmenuitem.h"
-#include "resources/itemtypemapdata.h"
-
-#include "resources/db/itemfielddb.h"
-
-#include "resources/item/itemfieldtype.h"
-
-#include "resources/sprite/spritereference.h"
-
-#ifdef TMWA_SUPPORT
-#include "net/net.h"
-#endif // TMWA_SUPPORT
-
-#include "utils/checkutils.h"
-#include "utils/delete2.h"
-#include "utils/dtor.h"
-#include "utils/foreach.h"
-#include "utils/stdmove.h"
-#include "utils/stringmap.h"
-
-#include "utils/translation/podict.h"
-
-#include "debug.h"
-
-namespace
-{
- ItemDB::ItemInfos mItemInfos;
- ItemDB::NamedItemInfos mNamedItemInfos;
- ItemInfo *mUnknown = nullptr;
- bool mLoaded = false;
- bool mConstructed = false;
- StringVect mTagNames;
- StringIntMap mTags;
- std::map<std::string, ItemSoundEvent::Type> mSoundNames;
- int mNumberOfHairstyles = 1;
-} // namespace
-
-// Forward declarations
-static void loadSpriteRef(ItemInfo *const itemInfo,
- XmlNodeConstPtr node) A_NONNULL(1);
-static void loadSoundRef(ItemInfo *const itemInfo,
- XmlNodeConstPtr node) A_NONNULL(1);
-static void loadFloorSprite(SpriteDisplay &display,
- XmlNodeConstPtrConst node);
-static void loadReplaceSprite(ItemInfo *const itemInfo,
- XmlNodeConstPtr replaceNode) A_NONNULL(1);
-static void loadOrderSprite(ItemInfo *const itemInfo,
- XmlNodeConstPtr node,
- const bool drawAfter) A_NONNULL(1);
-static int parseSpriteName(const std::string &name);
-static int parseDirectionName(const std::string &name);
-
-static ItemDbTypeT itemTypeFromString(const std::string &name)
-{
- const size_t sz = sizeof(itemTypeMap) / sizeof(itemTypeMap[0]);
- for (size_t f = 0; f < sz; f ++)
- {
- const ItemTypeMap &type = itemTypeMap[f];
- if (type.name == name)
- return type.type;
- }
- logger->log("Unknown item type: " + name);
- return ItemDbType::UNUSABLE;
-}
-
-static std::string useButtonFromItemType(const ItemDbTypeT &type)
-{
- const size_t sz = sizeof(itemTypeMap) / sizeof(itemTypeMap[0]);
- for (size_t f = 0; f < sz; f ++)
- {
- const ItemTypeMap &item = itemTypeMap[f];
- if (item.type == type)
- {
- if (item.useButton.empty())
- return std::string();
- return gettext(item.useButton.c_str());
- }
- }
- logger->log("Unknown item type");
- return std::string();
-}
-
-static std::string useButton2FromItemType(const ItemDbTypeT &type)
-{
- const size_t sz = sizeof(itemTypeMap) / sizeof(itemTypeMap[0]);
- for (size_t f = 0; f < sz; f ++)
- {
- const ItemTypeMap &item = itemTypeMap[f];
- if (item.type == type)
- {
- if (item.useButton2.empty())
- return std::string();
- return gettext(item.useButton2.c_str());
- }
- }
- logger->log("Unknown item type");
- return std::string();
-}
-
-static void readFields(std::string &effect,
- XmlNodeConstPtr node,
- const ItemFieldDb::FieldInfos &fields)
-{
- if (translator == nullptr)
- return;
-
- FOR_EACH (ItemFieldDb::FieldInfos::const_iterator, it, fields)
- {
- const std::string fieldName = (*it).first;
- const ItemFieldType *const field = (*it).second;
-
- std::string value = XML::getProperty(node,
- fieldName.c_str(),
- "");
- if (value.empty())
- continue;
- if (!effect.empty())
- effect.append(" / ");
- if (field->sign && isDigit(value))
- value = std::string("+").append(value);
- const std::string format = translator->getStr(field->description);
- effect.append(strprintf(format.c_str(),
- value.c_str()));
- }
-}
-
-static void initStatic()
-{
- mConstructed = true;
- mSoundNames["hit"] = ItemSoundEvent::HIT;
- mSoundNames["strike"] = ItemSoundEvent::MISS;
- mSoundNames["miss"] = ItemSoundEvent::MISS;
- mSoundNames["use"] = ItemSoundEvent::USE;
- mSoundNames["equip"] = ItemSoundEvent::EQUIP;
- mSoundNames["unequip"] = ItemSoundEvent::UNEQUIP;
- mSoundNames["drop"] = ItemSoundEvent::DROP;
- mSoundNames["pickup"] = ItemSoundEvent::PICKUP;
- mSoundNames["take"] = ItemSoundEvent::TAKE;
- mSoundNames["put"] = ItemSoundEvent::PUT;
- mSoundNames["usecard"] = ItemSoundEvent::USECARD;
-}
-
-void ItemDB::load()
-{
- if (mLoaded)
- unload();
-
- logger->log1("Initializing item database...");
-
- if (!mConstructed)
- initStatic();
-
- int tagNum = 0;
-
- mTags.clear();
- mTagNames.clear();
- mTagNames.push_back("All");
- mTagNames.push_back("Usable");
- mTagNames.push_back("Unusable");
- mTagNames.push_back("Equipment");
- mTags["All"] = tagNum ++;
- mTags["Usable"] = tagNum ++;
- mTags["Unusable"] = tagNum ++;
- mTags["Equipment"] = tagNum ++;
-
- mUnknown = new ItemInfo;
- // TRANSLATORS: item name
- mUnknown->setName(_("Unknown item"));
- mUnknown->setDisplay(SpriteDisplay());
- std::string errFile = paths.getStringValue("spriteErrorFile");
- mUnknown->setSprite(errFile, Gender::MALE, 0);
- mUnknown->setSprite(errFile, Gender::FEMALE, 0);
- mUnknown->setSprite(errFile, Gender::OTHER, 0);
- mUnknown->addTag(mTags["All"]);
- loadXmlFile(paths.getStringValue("itemsFile"),
- tagNum,
- SkipError_false);
- loadXmlFile(paths.getStringValue("itemsPatchFile"),
- tagNum,
- SkipError_true);
-
- StringVect list;
- VirtFs::getFilesInDir(paths.getStringValue("itemsPatchDir"),
- list,
- ".xml");
- FOR_EACH (StringVectCIter, it, list)
- loadXmlFile(*it, tagNum, SkipError_true);
-
- // Hairstyles are encoded as negative numbers. Count how far negative
- // we can go.
- int hairstyles = 1;
- while (ItemDB::exists(-hairstyles) &&
- ItemDB::get(-hairstyles).getSprite(Gender::MALE,
- BeingTypeId_zero) != paths.getStringValue("spriteErrorFile"))
- {
- hairstyles ++;
- }
- mNumberOfHairstyles = hairstyles;
-
- int races = 100;
- while (ItemDB::exists(-races) &&
- ItemDB::get(-races).getSprite(Gender::MALE, BeingTypeId_zero) !=
- paths.getStringValue("spriteErrorFile"))
- {
- races ++;
- }
-}
-
-static void loadMenu(XmlNodePtrConst parentNode,
- STD_VECTOR<ItemMenuItem> &menu)
-{
- for_each_xml_child_node(node, parentNode)
- {
- if (xmlNameEqual(node, "menu"))
- {
- const std::string name1 = XML::langProperty(node,
- "name1", "");
- const std::string name2 = XML::langProperty(node,
- "name2", "");
- const std::string command1 = XML::getProperty(node,
- "command1", "");
- const std::string command2 = XML::getProperty(node,
- "command2", command1);
- menu.push_back(ItemMenuItem(name1,
- name2,
- command1,
- command2));
- }
- }
-}
-
-static bool getIsEquipment(const ItemDbTypeT type)
-{
- switch (type)
- {
- case ItemDbType::EQUIPMENT_ONE_HAND_WEAPON:
- case ItemDbType::EQUIPMENT_TWO_HANDS_WEAPON:
- case ItemDbType::EQUIPMENT_TORSO:
- case ItemDbType::EQUIPMENT_ARMS:
- case ItemDbType::EQUIPMENT_HEAD:
- case ItemDbType::EQUIPMENT_LEGS:
- case ItemDbType::EQUIPMENT_SHIELD:
- case ItemDbType::EQUIPMENT_RING:
- case ItemDbType::EQUIPMENT_NECKLACE:
- case ItemDbType::EQUIPMENT_FEET:
- case ItemDbType::EQUIPMENT_AMMO:
- case ItemDbType::EQUIPMENT_CHARM:
- return true;
- case ItemDbType::UNUSABLE:
- case ItemDbType::USABLE:
- case ItemDbType::CARD:
- case ItemDbType::SPRITE_RACE:
- case ItemDbType::SPRITE_HAIR:
- default:
- return false;
- }
-}
-
-void ItemDB::loadXmlFile(const std::string &fileName,
- int &tagNum,
- const SkipError skipError)
-{
- if (fileName.empty())
- {
- mLoaded = true;
- return;
- }
-
- XML::Document doc(fileName,
- UseVirtFs_true,
- skipError);
- XmlNodeConstPtrConst rootNode = doc.rootNode();
-
- if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "items"))
- {
- logger->log("ItemDB: Error while loading %s!", fileName.c_str());
- mLoaded = true;
- return;
- }
-
- const ItemFieldDb::FieldInfos &requiredFields =
- ItemFieldDb::getRequiredFields();
- const ItemFieldDb::FieldInfos &addFields =
- ItemFieldDb::getAddFields();
-
- for_each_xml_child_node(node, rootNode)
- {
- if (xmlNameEqual(node, "include"))
- {
- const std::string name = XML::getProperty(node, "name", "");
- if (!name.empty())
- loadXmlFile(name, tagNum, skipError);
- continue;
- }
- if (!xmlNameEqual(node, "item"))
- continue;
-
- const int id = XML::getProperty(node, "id", 0);
- ItemInfo *itemInfo = nullptr;
-
- if (id == 0)
- {
- reportAlways("ItemDB: Invalid or missing item ID in %s!",
- fileName.c_str());
- continue;
- }
- else if (mItemInfos.find(id) != mItemInfos.end())
- {
- logger->log("ItemDB: Redefinition of item ID %d", id);
- itemInfo = mItemInfos[id];
- }
- if (itemInfo == nullptr)
- itemInfo = new ItemInfo;
-
- const std::string typeStr = XML::getProperty(node, "type", "");
- int weight = XML::getProperty(node, "weight", 0);
- int view = XML::getProperty(node, "view", 0);
- const int cardColor = XML::getProperty(node, "cardColor", -1);
- const int inherit = XML::getProperty(node, "inherit", -1);
-
- std::string name = XML::langProperty(node, "name", "");
- std::string nameEn = XML::getProperty(node, "name", "");
- std::string image = XML::getProperty(node, "image", "");
- std::string floor = XML::getProperty(node, "floor", "");
- std::string description = XML::langProperty(node, "description", "");
- std::string attackAction = XML::getProperty(node, "attack-action", "");
- std::string skyAttackAction = XML::getProperty(
- node, "skyattack-action", "");
- std::string waterAttackAction = XML::getProperty(
- node, "waterattack-action", "");
- std::string rideAttackAction = XML::getProperty(
- node, "rideattack-action", "");
- std::string drawBefore = XML::getProperty(node, "drawBefore", "");
- std::string drawAfter = XML::getProperty(node, "drawAfter", "");
- const int maxFloorOffset = XML::getIntProperty(
- node, "maxFloorOffset", mapTileSize, 0, mapTileSize);
- const int maxFloorOffsetX = XML::getIntProperty(
- node, "maxFloorOffsetX", maxFloorOffset, 0, mapTileSize);
- const int maxFloorOffsetY = XML::getIntProperty(
- node, "maxFloorOffsetY", maxFloorOffset, 0, mapTileSize);
- std::string useButton = XML::langProperty(node, "useButton", "");
- std::string useButton2 = XML::langProperty(node, "useButton2", "");
- std::string colors = XML::getProperty(node, "colors", "");
- std::string iconColors = XML::getProperty(node, "iconColors", "");
- if (iconColors.empty())
- iconColors = colors;
-
- // check for empty hair palete
- if (id <= -1 && id > -100)
- {
- if (colors.empty())
- colors = "hair";
- if (iconColors.empty())
- iconColors = "hair";
- }
-
- std::string tags[3];
- tags[0] = XML::getProperty(node, "tag",
- XML::getProperty(node, "tag1", ""));
- tags[1] = XML::getProperty(node, "tag2", "");
- tags[2] = XML::getProperty(node, "tag3", "");
-
- const int drawPriority = XML::getProperty(node, "drawPriority", 0);
-
- int attackRange = XML::getProperty(node, "attack-range", 0);
- std::string missileParticle = XML::getProperty(
- node, "missile-particle", "");
- float missileZ = XML::getFloatProperty(
- node, "missile-z", 32.0f);
- int missileLifeTime = XML::getProperty(
- node, "missile-lifetime", 500);
- float missileSpeed = XML::getFloatProperty(
- node, "missile-speed", 7.0f);
- float missileDieDistance = XML::getFloatProperty(
- node, "missile-diedistance", 8.0f);
- int hitEffectId = XML::getProperty(node, "hit-effect-id",
- paths.getIntValue("hitEffectId"));
- int criticalEffectId = XML::getProperty(
- node, "critical-hit-effect-id",
- paths.getIntValue("criticalHitEffectId"));
- int missEffectId = XML::getProperty(node, "miss-effect-id",
- paths.getIntValue("missEffectId"));
-
- SpriteDisplay display;
- display.image = image;
- if (!floor.empty())
- display.floor = STD_MOVE(floor);
- else
- display.floor = image;
-
- const ItemInfo *inheritItemInfo = nullptr;
-
- if (inherit >= 0)
- {
- if (mItemInfos.find(inherit) != mItemInfos.end())
- {
- inheritItemInfo = mItemInfos[inherit];
- }
- else
- {
- reportAlways("Inherit item %d from not existing item %d",
- id,
- inherit);
- }
- }
-
- itemInfo->setId(id);
- if (name.empty() && (inheritItemInfo != nullptr))
- name = inheritItemInfo->getName();
- // TRANSLATORS: item info name
- itemInfo->setName(name.empty() ? _("unnamed") : name);
- if (nameEn.empty())
- {
- // TRANSLATORS: item info name
- itemInfo->setNameEn(name.empty() ? _("unnamed") : name);
- }
- else
- {
- itemInfo->setNameEn(nameEn);
- }
-
- if (description.empty() && (inheritItemInfo != nullptr))
- description = inheritItemInfo->getDescription();
- itemInfo->setDescription(description);
- if (typeStr.empty())
- {
- if (inheritItemInfo != nullptr)
- itemInfo->setType(inheritItemInfo->getType());
- else
- itemInfo->setType(itemTypeFromString("other"));
- }
- else
- {
- itemInfo->setType(itemTypeFromString(typeStr));
- }
- itemInfo->setType(itemTypeFromString(typeStr));
- if (useButton.empty() && (inheritItemInfo != nullptr))
- useButton = inheritItemInfo->getUseButton();
- if (useButton.empty())
- useButton = useButtonFromItemType(itemInfo->getType());
- itemInfo->setUseButton(useButton);
- if (useButton2.empty() && (inheritItemInfo != nullptr))
- useButton2 = inheritItemInfo->getUseButton();
- if (useButton2.empty())
- useButton2 = useButton2FromItemType(itemInfo->getType());
- itemInfo->setUseButton2(useButton2);
- itemInfo->addTag(mTags["All"]);
- itemInfo->setProtected(XML::getBoolProperty(
- node, "sellProtected", false));
- if (cardColor != -1)
- itemInfo->setCardColor(fromInt(cardColor, ItemColor));
- else if (inheritItemInfo != nullptr)
- itemInfo->setCardColor(inheritItemInfo->getCardColor());
-
- switch (itemInfo->getType())
- {
- case ItemDbType::USABLE:
- itemInfo->addTag(mTags["Usable"]);
- break;
- case ItemDbType::CARD:
- case ItemDbType::UNUSABLE:
- itemInfo->addTag(mTags["Unusable"]);
- break;
- default:
- case ItemDbType::EQUIPMENT_ONE_HAND_WEAPON:
- case ItemDbType::EQUIPMENT_TWO_HANDS_WEAPON:
- case ItemDbType::EQUIPMENT_TORSO:
- case ItemDbType::EQUIPMENT_ARMS:
- case ItemDbType::EQUIPMENT_HEAD:
- case ItemDbType::EQUIPMENT_LEGS:
- case ItemDbType::EQUIPMENT_SHIELD:
- case ItemDbType::EQUIPMENT_RING:
- case ItemDbType::EQUIPMENT_NECKLACE:
- case ItemDbType::EQUIPMENT_FEET:
- case ItemDbType::EQUIPMENT_AMMO:
- case ItemDbType::EQUIPMENT_CHARM:
- case ItemDbType::SPRITE_RACE:
- case ItemDbType::SPRITE_HAIR:
- itemInfo->addTag(mTags["Equipment"]);
- break;
- }
- for (int f = 0; f < 3; f++)
- {
- if (!tags[f].empty())
- {
- if (mTags.find(tags[f]) == mTags.end())
- {
- mTagNames.push_back(tags[f]);
- mTags[tags[f]] = tagNum ++;
- }
- itemInfo->addTag(mTags[tags[f]]);
- }
- }
-
- std::string effect;
- readFields(effect, node, requiredFields);
- readFields(effect, node, addFields);
- std::string temp = XML::langProperty(node, "effect", "");
- if (!effect.empty() && !temp.empty())
- effect.append(" / ");
- effect.append(temp);
-
- if (inheritItemInfo != nullptr)
- {
- if (view == 0)
- view = inheritItemInfo->getView();
- if (weight == 0)
- weight = inheritItemInfo->getWeight();
- if (attackAction.empty())
- attackAction = inheritItemInfo->getAttackAction();
- if (skyAttackAction.empty())
- skyAttackAction = inheritItemInfo->getSkyAttackAction();
- if (waterAttackAction.empty())
- waterAttackAction = inheritItemInfo->getWaterAttackAction();
- if (rideAttackAction.empty())
- rideAttackAction = inheritItemInfo->getRideAttackAction();
- if (attackRange == 0)
- attackRange = inheritItemInfo->getAttackRange();
- if (hitEffectId == 0)
- hitEffectId = inheritItemInfo->getHitEffectId();
- if (criticalEffectId == 0)
- criticalEffectId = inheritItemInfo->getCriticalHitEffectId();
- if (missEffectId == 0)
- missEffectId = inheritItemInfo->getMissEffectId();
- if (colors.empty())
- colors = inheritItemInfo->getColorsListName();
- if (iconColors.empty())
- iconColors = inheritItemInfo->getIconColorsListName();
- if (effect.empty())
- effect = inheritItemInfo->getEffect();
-
- const MissileInfo &inheritMissile =
- inheritItemInfo->getMissileConst();
- if (missileParticle.empty())
- missileParticle = inheritMissile.particle;
- if (missileZ == 32.0F)
- missileZ = inheritMissile.z;
- if (missileLifeTime == 500)
- missileLifeTime = inheritMissile.lifeTime;
- if (missileSpeed == 7.0F)
- missileSpeed = inheritMissile.speed;
- if (missileDieDistance == 8.0F)
- missileDieDistance = inheritMissile.dieDistance;
- }
-
- itemInfo->setView(view);
- itemInfo->setWeight(weight);
- itemInfo->setAttackAction(attackAction);
- itemInfo->setSkyAttackAction(skyAttackAction);
- itemInfo->setWaterAttackAction(waterAttackAction);
- itemInfo->setRideAttackAction(rideAttackAction);
- itemInfo->setAttackRange(attackRange);
- itemInfo->setHitEffectId(hitEffectId);
- itemInfo->setCriticalHitEffectId(criticalEffectId);
- itemInfo->setMissEffectId(missEffectId);
- itemInfo->setDrawBefore(-1, parseSpriteName(drawBefore));
- itemInfo->setDrawAfter(-1, parseSpriteName(drawAfter));
- itemInfo->setDrawPriority(-1, drawPriority);
- itemInfo->setColorsList(colors);
- itemInfo->setIconColorsList(iconColors);
- itemInfo->setMaxFloorOffsetX(maxFloorOffsetX);
- itemInfo->setMaxFloorOffsetY(maxFloorOffsetY);
- itemInfo->setPickupCursor(XML::getProperty(
- node, "pickupCursor", "pickup"));
- itemInfo->setEffect(effect);
-
- MissileInfo &missile = itemInfo->getMissile();
- missile.particle = STD_MOVE(missileParticle);
- missile.z = missileZ;
- missile.lifeTime = missileLifeTime;
- missile.speed = missileSpeed;
- missile.dieDistance = missileDieDistance;
-
- for_each_xml_child_node(itemChild, node)
- {
- if (xmlNameEqual(itemChild, "sprite"))
- {
- loadSpriteRef(itemInfo, itemChild);
- }
- else if (xmlNameEqual(itemChild, "particlefx"))
- {
- if (XmlHaveChildContent(itemChild))
- display.particles.push_back(XmlChildContent(itemChild));
- }
- else if (xmlNameEqual(itemChild, "sound"))
- {
- loadSoundRef(itemInfo, itemChild);
- }
- else if (xmlNameEqual(itemChild, "floor"))
- {
- loadFloorSprite(display, itemChild);
- }
- else if (xmlNameEqual(itemChild, "replace"))
- {
- loadReplaceSprite(itemInfo, itemChild);
- }
- else if (xmlNameEqual(itemChild, "drawAfter"))
- {
- loadOrderSprite(itemInfo, itemChild, true);
- }
- else if (xmlNameEqual(itemChild, "drawBefore"))
- {
- loadOrderSprite(itemInfo, itemChild, false);
- }
- else if (xmlNameEqual(itemChild, "inventory"))
- {
- loadMenu(itemChild, itemInfo->getInventoryMenu());
- }
- else if (xmlNameEqual(itemChild, "storage"))
- {
- loadMenu(itemChild, itemInfo->getStorageMenu());
- }
- else if (xmlNameEqual(itemChild, "cart"))
- {
- loadMenu(itemChild, itemInfo->getCartMenu());
- }
- }
-
-/*
- logger->log("start dump item: %d", id);
- if (itemInfo->isRemoveSprites())
- {
- for (int f = 0; f < 10; f ++)
- {
- logger->log("dir: %d", f);
- SpriteToItemMap *const spriteToItems
- = itemInfo->getSpriteToItemReplaceMap(f);
- if (!spriteToItems)
- {
- logger->log("null");
- continue;
- }
- for (SpriteToItemMapCIter itr = spriteToItems->begin(),
- itr_end = spriteToItems->end(); itr != itr_end; ++ itr)
- {
- const int remSprite = itr->first;
- const IntMap &itemReplacer = itr->second;
- logger->log("sprite: %d", remSprite);
-
- for (IntMapCIter repIt = itemReplacer.begin(),
- repIt_end = itemReplacer.end();
- repIt != repIt_end; ++ repIt)
- {
- logger->log("from %d to %d", repIt->first,
- repIt->second);
- }
- }
- }
- }
-
- logger->log("--------------------------------");
- logger->log("end dump item");
-*/
-
- itemInfo->setDisplay(display);
-
- mItemInfos[id] = itemInfo;
- if (!name.empty())
- {
- temp = normalize(name);
- mNamedItemInfos[temp] = itemInfo;
- }
- if (!nameEn.empty())
- {
- temp = normalize(nameEn);
- mNamedItemInfos[temp] = itemInfo;
- }
-
- if (!attackAction.empty())
- {
- if (attackRange == 0)
- {
- reportAlways("ItemDB: Missing attack range from weapon %i!",
- id);
- }
- }
-
- STD_VECTOR<ItemMenuItem> &inventoryMenu = itemInfo->getInventoryMenu();
-
- if (inventoryMenu.empty())
- {
- std::string name1 = itemInfo->getUseButton();
- std::string name2 = itemInfo->getUseButton2();
- const bool isEquipment = getIsEquipment(itemInfo->getType());
-
- if (isEquipment)
- {
- if (name1.empty())
- {
- // TRANSLATORS: popup menu item
- name1 = _("Equip");
- }
- if (name2.empty())
- {
- // TRANSLATORS: popup menu item
- name2 = _("Unequip");
- }
- }
- else
- {
- if (name1.empty())
- {
- // TRANSLATORS: popup menu item
- name1 = _("Use");
- }
- if (name2.empty())
- {
- // TRANSLATORS: popup menu item
- name2 = _("Use");
- }
- }
- inventoryMenu.push_back(ItemMenuItem(
- name1,
- name2,
- "useinv 'INVINDEX'",
- "useinv 'INVINDEX'"));
- }
-
-#define CHECK_PARAM(param) \
- if (param.empty()) \
- { \
- logger->log("ItemDB: Missing " #param " attribute for item %i!", \
- id); \
- }
-
- if (id >= 0 && typeStr != "other")
- {
- CHECK_PARAM(name)
- CHECK_PARAM(description)
- CHECK_PARAM(image)
- }
-#undef CHECK_PARAM
- }
-
- mLoaded = true;
-}
-
-const StringVect &ItemDB::getTags()
-{
- return mTagNames;
-}
-
-int ItemDB::getTagId(const std::string &tagName)
-{
- return mTags[tagName];
-}
-
-void ItemDB::unload()
-{
- logger->log1("Unloading item database...");
-
- delete2(mUnknown);
-
- delete_all(mItemInfos);
- mItemInfos.clear();
- mNamedItemInfos.clear();
- mTags.clear();
- mTagNames.clear();
- mLoaded = false;
-}
-
-bool ItemDB::exists(const int id)
-{
- if (!mLoaded)
- return false;
-
- const ItemInfos::const_iterator i = mItemInfos.find(id);
- return i != mItemInfos.end();
-}
-
-bool ItemDB::exists(const std::string &name)
-{
- if (!mLoaded)
- return false;
-
- const NamedItemInfos::const_iterator i = mNamedItemInfos.find(
- normalize(name));
- return i != mNamedItemInfos.end();
-}
-
-const ItemInfo &ItemDB::get(const int id)
-{
- if (!mLoaded)
- load();
-
- const ItemInfos::const_iterator i = mItemInfos.find(id);
-
- if (i == mItemInfos.end())
- {
- reportAlways("ItemDB: Warning, unknown item ID# %d", id);
- return *mUnknown;
- }
-
- return *(i->second);
-}
-
-const ItemInfo &ItemDB::get(const std::string &name)
-{
- if (!mLoaded)
- load();
-
- const NamedItemInfos::const_iterator i = mNamedItemInfos.find(
- normalize(name));
-
- if (i == mNamedItemInfos.end())
- {
- if (!name.empty())
- {
- reportAlways("ItemDB: Warning, unknown item name \"%s\"",
- name.c_str());
- }
- return *mUnknown;
- }
-
- return *(i->second);
-}
-
-const ItemDB::ItemInfos &ItemDB::getItemInfos()
-{
- return mItemInfos;
-}
-
-const ItemInfo &ItemDB::getEmpty()
-{
- return *mUnknown;
-}
-
-static int parseSpriteName(const std::string &name)
-{
- int id = -1;
- if (name == "race" || name == "type")
- {
- id = 0;
- }
- else if (name == "shoes" || name == "boot" || name == "boots")
- {
- id = 1;
- }
- else if (name == "bottomclothes" || name == "bottom" || name == "pants")
- {
- id = 2;
- }
- else if (name == "topclothes" || name == "top"
- || name == "torso" || name == "body")
- {
- id = 3;
- }
- else if (name == "misc1")
- {
- id = 4;
- }
- else if (name == "misc2" || name == "scarf" || name == "scarfs")
- {
- id = 5;
- }
- else if (name == "hair")
- {
- id = 6;
- }
- else if (name == "hat" || name == "hats")
- {
- id = 7;
- }
- else if (name == "wings")
- {
- id = 8;
- }
- else if (name == "glove" || name == "gloves")
- {
- id = 9;
- }
- else if (name == "weapon" || name == "weapons")
- {
- id = 10;
- }
- else if (name == "shield" || name == "shields")
- {
- id = 11;
- }
- else if (name == "amulet" || name == "amulets")
- {
- id = 12;
- }
- else if (name == "ring" || name == "rings")
- {
- id = 13;
- }
-
- return id;
-}
-
-static int parseDirectionName(const std::string &name)
-{
- int id = -1;
- if (name == "down")
- {
-#ifdef TMWA_SUPPORT
- if (Net::getNetworkType() == ServerType::TMWATHENA)
- id = -2;
- else
-#endif
- id = SpriteDirection::DOWN;
- }
- else if (name == "downleft" || name == "leftdown")
- {
- id = SpriteDirection::DOWNLEFT;
- }
- else if (name == "left")
- {
- id = SpriteDirection::LEFT;
- }
- else if (name == "upleft" || name == "leftup")
- {
- id = SpriteDirection::UPLEFT;
- }
- else if (name == "up")
- {
-#ifdef TMWA_SUPPORT
- if (Net::getNetworkType() == ServerType::TMWATHENA)
- id = -3;
- else
-#endif
- id = SpriteDirection::UP;
- }
- else if (name == "upright" || name == "rightup")
- {
- id = SpriteDirection::UPRIGHT;
- }
- else if (name == "right")
- {
- id = SpriteDirection::RIGHT;
- }
- else if (name == "downright" || name == "rightdown")
- {
- id = SpriteDirection::DOWNRIGHT;
- }
- else if (name == "downall")
- {
- id = -2;
- }
- else if (name == "upall")
- {
- id = -3;
- }
- // hack for died action.
- else if (name == "died")
- {
- id = 9;
- }
-
- return id;
-}
-
-static void loadSpriteRef(ItemInfo *const itemInfo, XmlNodeConstPtr node)
-{
- const std::string gender = XML::getProperty(node, "gender", "unisex");
- if ((node == nullptr) || !XmlHaveChildContent(node))
- return;
-
- const std::string filename = XmlChildContent(node);
-
- const int race = XML::getProperty(node, "race", 0);
- if (gender == "male" || gender == "unisex")
- itemInfo->setSprite(filename, Gender::MALE, race);
- if (gender == "female" || gender == "unisex")
- itemInfo->setSprite(filename, Gender::FEMALE, race);
- if (gender == "other" || gender == "unisex")
- itemInfo->setSprite(filename, Gender::OTHER, race);
-}
-
-static void loadSoundRef(ItemInfo *const itemInfo, XmlNodeConstPtr node)
-{
- if (node == nullptr ||
- !XmlHaveChildContent(node))
- {
- return;
- }
- const std::string event = XML::getProperty(node, "event", "");
- const int delay = XML::getProperty(node, "delay", 0);
-
- const std::map<std::string, ItemSoundEvent::Type>::const_iterator
- it = mSoundNames.find(event);
- if (it != mSoundNames.end())
- {
- const std::string filename = XmlChildContent(node);
- itemInfo->addSound((*it).second, filename, delay);
- }
- else
- {
- reportAlways("ItemDB: Ignoring unknown sound event '%s'",
- event.c_str());
- }
-}
-
-static void loadFloorSprite(SpriteDisplay &display,
- XmlNodeConstPtrConst floorNode)
-{
- if (floorNode == nullptr)
- return;
- for_each_xml_child_node(spriteNode, floorNode)
- {
- if (!XmlHaveChildContent(spriteNode))
- continue;
- if (xmlNameEqual(spriteNode, "sprite"))
- {
- SpriteReference *const currentSprite = new SpriteReference;
- currentSprite->sprite = XmlChildContent(spriteNode);
- currentSprite->variant
- = XML::getProperty(spriteNode, "variant", 0);
- display.sprites.push_back(currentSprite);
- }
- else if (xmlNameEqual(spriteNode, "particlefx"))
- {
- display.particles.push_back(XmlChildContent(spriteNode));
- }
- }
-}
-
-static void loadReplaceSprite(ItemInfo *const itemInfo,
- XmlNodeConstPtr replaceNode)
-{
- if (replaceNode == nullptr)
- return;
- const std::string removeSprite = XML::getProperty(
- replaceNode, "sprite", "");
- const int direction = parseDirectionName(XML::getProperty(
- replaceNode, "direction", "all"));
-
- itemInfo->setRemoveSprites();
-
- switch (direction)
- {
- case -1:
- {
- if (removeSprite.empty())
- { // remove all sprites
- for (int f = 0; f < 10; f ++)
- {
- for (int sprite = 0; sprite < 13; sprite ++)
- itemInfo->addReplaceSprite(sprite, f);
- }
- }
- else
- { // replace only given sprites
- for (int f = 0; f < 10; f ++)
- {
- IntMap *const mapList = itemInfo->addReplaceSprite(
- parseSpriteName(removeSprite), f);
- if (mapList == nullptr)
- continue;
- for_each_xml_child_node(itemNode, replaceNode)
- {
- if (xmlNameEqual(itemNode, "item"))
- {
- const int from = XML::getProperty(
- itemNode, "from", 0);
- const int to = XML::getProperty(
- itemNode, "to", 1);
- (*mapList)[from] = to;
- }
- }
- }
- }
- break;
- }
- case -2:
- {
- itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::DOWN);
- itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::DOWNLEFT);
- itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::DOWNRIGHT);
-
- for_each_xml_child_node(itemNode, replaceNode)
- {
- if (xmlNameEqual(itemNode, "item"))
- {
- const int from = XML::getProperty(itemNode, "from", 0);
- const int to = XML::getProperty(itemNode, "to", 1);
- IntMap *mapList = itemInfo->addReplaceSprite(
- parseSpriteName(removeSprite), SpriteDirection::DOWN);
- if (mapList != nullptr)
- (*mapList)[from] = to;
-
- mapList = itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::DOWNLEFT);
- if (mapList != nullptr)
- (*mapList)[from] = to;
-
- mapList = itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::DOWNRIGHT);
- if (mapList != nullptr)
- (*mapList)[from] = to;
- }
- }
- break;
- }
- case -3:
- {
- itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::UP);
- itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::UPLEFT);
- itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::UPRIGHT);
-
- for_each_xml_child_node(itemNode, replaceNode)
- {
- if (xmlNameEqual(itemNode, "item"))
- {
- const int from = XML::getProperty(itemNode, "from", 0);
- const int to = XML::getProperty(itemNode, "to", 1);
- IntMap *mapList = itemInfo->addReplaceSprite(
- parseSpriteName(removeSprite), SpriteDirection::UP);
- if (mapList != nullptr)
- (*mapList)[from] = to;
-
- mapList = itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::UPLEFT);
- if (mapList != nullptr)
- (*mapList)[from] = to;
-
- mapList = itemInfo->addReplaceSprite(parseSpriteName(
- removeSprite), SpriteDirection::UPRIGHT);
- if (mapList != nullptr)
- (*mapList)[from] = to;
- }
- }
- break;
- }
- default:
- {
- IntMap *const mapList = itemInfo->addReplaceSprite(
- parseSpriteName(removeSprite), direction);
- if (mapList == nullptr)
- return;
- for_each_xml_child_node(itemNode, replaceNode)
- {
- if (xmlNameEqual(itemNode, "item"))
- {
- const int from = XML::getProperty(itemNode, "from", 0);
- const int to = XML::getProperty(itemNode, "to", 1);
- (*mapList)[from] = to;
- }
- }
- break;
- }
- }
-}
-
-static void loadOrderSprite(ItemInfo *const itemInfo,
- XmlNodeConstPtr node,
- const bool drawAfter)
-{
- const int sprite = parseSpriteName(XML::getProperty(node, "name", ""));
- const int priority = XML::getProperty(node, "priority", 0);
-
- const int direction = parseDirectionName(XML::getProperty(
- node, "direction", "all"));
- if (drawAfter)
- itemInfo->setDrawAfter(direction, sprite);
- else
- itemInfo->setDrawBefore(direction, sprite);
- itemInfo->setDrawPriority(direction, priority);
-}
-
-std::string ItemDB::getNamesStr(const STD_VECTOR<int> &parts)
-{
- std::string str;
- FOR_EACH (STD_VECTOR<int>::const_iterator, it, parts)
- {
- const int id = *it;
- if (exists(id))
- {
- if (!str.empty())
- str.append(",");
- str.append(get(id).getName());
- }
- }
- return str;
-}
-
-int ItemDB::getNumOfHairstyles()
-{
- return mNumberOfHairstyles;
-}
-
-#ifdef UNITTESTS
-ItemDB::NamedItemInfos &ItemDB::getNamedItemInfosTest()
-{
- return mNamedItemInfos;
-}
-
-ItemDB::ItemInfos &ItemDB::getItemInfosTest()
-{
- return mItemInfos;
-}
-#endif // UNITTESTS