From 92c09d42b782deff9dcb9dcc6b408fdd36bc4f37 Mon Sep 17 00:00:00 2001 From: Przemysław Grzywacz Date: Tue, 7 May 2013 17:45:26 +0200 Subject: items.xml can be used from settings.xml --- src/client.cpp | 24 ++-- src/resources/itemdb.cpp | 284 +++++++++++++++++--------------------- src/resources/itemdb.h | 34 ++--- src/resources/settingsmanager.cpp | 10 +- 4 files changed, 165 insertions(+), 187 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 0d2c4bca..6b8ebca1 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -761,13 +761,12 @@ int Client::exec() // TODO remove this as soon as inventoryhandler stops using this event Event::trigger(Event::ClientChannel, Event::LoadingDatabases); - // load game settings - - // Load XML databases - SettingsManager::load(); - CharDB::load(); + + if (itemDb) + delete itemDb; + switch (Net::getNetworkType()) { case ServerInfo::TMWATHENA: @@ -781,17 +780,10 @@ int Client::exec() itemDb = 0; break; } - if (!itemDb || !itemDb->isLoaded()) - { - // Warn and return to login screen - errorMessage = - _("This server is missing needed world data. " - "Please contact the administrator(s)."); - showOkDialog(_("ItemDB: Error while loading " - ITEMS_DB_FILE "!"), errorMessage, - STATE_CHOOSE_SERVER); - break; - } + assert(itemDb); + + // load settings.xml + SettingsManager::load(); ActorSprite::load(); diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index 4db7b085..b802457e 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -31,7 +31,6 @@ #include "utils/dtor.h" #include "utils/gettext.h" #include "utils/stringutils.h" -#include "utils/xml.h" #include "configuration.h" #include @@ -189,18 +188,17 @@ void ItemDB::unload() mLoaded = false; } -void ItemDB::loadCommonRef(ItemInfo *itemInfo, xmlNodePtr node) +void ItemDB::loadCommonRef(ItemInfo *itemInfo, xmlNodePtr node, const std::string &filename) { int id = XML::getProperty(node, "id", 0); if (!id) { - logger->log("ItemDB: Invalid or missing item Id in " - ITEMS_DB_FILE "!"); + logger->log("ItemDB: Invalid or missing item Id in %s!", filename.c_str()); return; } else if (mItemInfos.find(id) != mItemInfos.end()) - logger->log("ItemDB: Redefinition of item Id %d", id); + logger->log("ItemDB: Redefinition of item Id %d in %s", id, filename.c_str()); int view = XML::getProperty(node, "view", 0); @@ -324,71 +322,60 @@ static char const *const fields[][2] = { "mp", N_("MP %+d") } }; -void TaItemDB::load() +void TaItemDB::init() { if (mLoaded) unload(); - logger->log("Initializing TmwAthena item database..."); - mUnknown = new TaItemInfo; loadEmptyItemDefinition(); +} + +void TaItemDB::readItemNode(xmlNodePtr node, const std::string &filename) +{ + TaItemInfo *itemInfo = new TaItemInfo; - XML::Document doc(ITEMS_DB_FILE); - xmlNodePtr rootNode = doc.rootNode(); + loadCommonRef(itemInfo, node, filename); - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items")) + // Everything not unusable or usable is equippable by the Ta type system. + itemInfo->mEquippable = itemInfo->mType != ITEM_UNUSABLE + && itemInfo->mType != ITEM_USABLE; + itemInfo->mActivatable = itemInfo->mType == ITEM_USABLE; + + // Load nano description + std::vector effect; + for (int i = 0; i < int(sizeof(fields) / sizeof(fields[0])); ++i) { - logger->error("ItemDB: Error while loading " ITEMS_DB_FILE "!"); - return; + int value = XML::getProperty(node, fields[i][0], 0); + if (!value) + continue; + effect.push_back(strprintf(gettext(fields[i][1]), value)); } - - for_each_xml_child_node(node, rootNode) + for (std::list::iterator it = extraStats.begin(); + it != extraStats.end(); it++) { - if (!xmlStrEqual(node->name, BAD_CAST "item")) + int value = XML::getProperty(node, it->mTag.c_str(), 0); + if (!value) continue; + effect.push_back(strprintf(it->mFormat.c_str(), value)); + } + std::string temp = XML::getProperty(node, "effect", ""); + if (!temp.empty()) + effect.push_back(temp); - TaItemInfo *itemInfo = new TaItemInfo; - - loadCommonRef(itemInfo, node); - - // Everything not unusable or usable is equippable by the Ta type system. - itemInfo->mEquippable = itemInfo->mType != ITEM_UNUSABLE - && itemInfo->mType != ITEM_USABLE; - itemInfo->mActivatable = itemInfo->mType == ITEM_USABLE; - - // Load nano description - std::vector effect; - for (int i = 0; i < int(sizeof(fields) / sizeof(fields[0])); ++i) - { - int value = XML::getProperty(node, fields[i][0], 0); - if (!value) - continue; - effect.push_back(strprintf(gettext(fields[i][1]), value)); - } - for (std::list::iterator it = extraStats.begin(); - it != extraStats.end(); it++) - { - int value = XML::getProperty(node, it->mTag.c_str(), 0); - if (!value) - continue; - effect.push_back(strprintf(it->mFormat.c_str(), value)); - } - std::string temp = XML::getProperty(node, "effect", ""); - if (!temp.empty()) - effect.push_back(temp); - - itemInfo->mEffect = effect; + itemInfo->mEffect = effect; - checkItemInfo(itemInfo); + checkItemInfo(itemInfo); - addItem(itemInfo); + addItem(itemInfo); - // Insert hairstyle id while letting the info as an item. - if (itemInfo->mType == ITEM_SPRITE_HAIR) - hairDB.addHairStyle(itemInfo->mId); - } + // Insert hairstyle id while letting the info as an item. + if (itemInfo->mType == ITEM_SPRITE_HAIR) + hairDB.addHairStyle(itemInfo->mId); +} +void TaItemDB::checkStatus() +{ checkHairWeaponsRacesSpecialIds(); mLoaded = true; @@ -423,7 +410,7 @@ static void initTriggerTable() } } -void ManaServItemDB::load() +void ManaServItemDB::init() { if (mLoaded) unload(); @@ -431,129 +418,118 @@ void ManaServItemDB::load() // Initialize the trigger table for effect descriptions initTriggerTable(); - logger->log("Initializing ManaServ item database..."); - mUnknown = new ManaServItemInfo; loadEmptyItemDefinition(); +} - XML::Document doc(ITEMS_DB_FILE); - xmlNodePtr rootNode = doc.rootNode(); - - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items")) - { - logger->log("ItemDB: Error while loading " ITEMS_DB_FILE "!"); - return; - } - - for_each_xml_child_node(node, rootNode) - { - if (!xmlStrEqual(node->name, BAD_CAST "item")) - continue; - - ManaServItemInfo *itemInfo = new ManaServItemInfo; +void ManaServItemDB::readItemNode(xmlNodePtr node, const std::string &filename) +{ + ManaServItemInfo *itemInfo = new ManaServItemInfo; - loadCommonRef(itemInfo, node); + loadCommonRef(itemInfo, node, filename); - // We default eqippable and activatable to false as their actual value will be set - // within the and sub-nodes.. - itemInfo->mActivatable = false; - itemInfo->mEquippable = false; + // We default eqippable and activatable to false as their actual value will be set + // within the and sub-nodes.. + itemInfo->mActivatable = false; + itemInfo->mEquippable = false; - // Load , and sub nodes. - std::vector effect; - for_each_xml_child_node(itemChild, node) + // Load , and sub nodes. + std::vector effect; + for_each_xml_child_node(itemChild, node) + { + if (xmlStrEqual(itemChild->name, BAD_CAST "equip")) { - if (xmlStrEqual(itemChild->name, BAD_CAST "equip")) + // The fact that there is a way to equip is enough. + // Discard any details, but mark the item as equippable. + itemInfo->mEquippable = true; + } + else if (xmlStrEqual(itemChild->name, BAD_CAST "effect")) + { + std::string trigger = XML::getProperty( + itemChild, "trigger", ""); + if (trigger.empty()) { - // The fact that there is a way to equip is enough. - // Discard any details, but mark the item as equippable. - itemInfo->mEquippable = true; + logger->log("Found empty trigger effect label in %s, skipping.", filename.c_str()); + continue; } - else if (xmlStrEqual(itemChild->name, BAD_CAST "effect")) - { - std::string trigger = XML::getProperty( - itemChild, "trigger", ""); - if (trigger.empty()) - { - logger->log("Found empty trigger effect label, skipping."); - continue; - } - if (trigger == "activation") - itemInfo->mActivatable = true; + if (trigger == "activation") + itemInfo->mActivatable = true; - std::map::const_iterator triggerLabel = - triggerTable.find(trigger); - if (triggerLabel == triggerTable.end()) - { - logger->log("Warning: unknown trigger %s in item %d!", - trigger.c_str(), itemInfo->mId); - continue; - } + std::map::const_iterator triggerLabel = + triggerTable.find(trigger); + if (triggerLabel == triggerTable.end()) + { + logger->log("Warning: unknown trigger %s in item %d!", + trigger.c_str(), itemInfo->mId); + continue; + } - for_each_xml_child_node(effectChild, itemChild) + for_each_xml_child_node(effectChild, itemChild) + { + if (xmlStrEqual(effectChild->name, BAD_CAST "modifier")) { - if (xmlStrEqual(effectChild->name, BAD_CAST "modifier")) + std::string attribute = XML::getProperty( + effectChild, "attribute", ""); + double value = XML::getFloatProperty( + effectChild, "value", 0.0); + int duration = XML::getProperty( + effectChild, "duration", 0); + if (attribute.empty() || !value) + { + logger->log("Warning: incomplete modifier definition in %s, skipping.", filename.c_str()); + continue; + } + std::list::const_iterator + it = extraStats.begin(), + it_end = extraStats.end(); + while (it != it_end && !(*it == attribute)) + ++it; + if (it == extraStats.end()) { - std::string attribute = XML::getProperty( - effectChild, "attribute", ""); - double value = XML::getFloatProperty( - effectChild, "value", 0.0); - int duration = XML::getProperty( - effectChild, "duration", 0); - if (attribute.empty() || !value) - { - logger->log("Warning: incomplete modifier definition, skipping."); - continue; - } - std::list::const_iterator - it = extraStats.begin(), - it_end = extraStats.end(); - while (it != it_end && !(*it == attribute)) - ++it; - if (it == extraStats.end()) - { - logger->log("Warning: unknown modifier tag %s, skipping.", attribute.c_str()); - continue; - } - effect.push_back( - strprintf(strprintf( - duration ? - strprintf("%%s%%s. This effect lasts %d ticks.", duration).c_str() - : "%s%s.", it->mFormat.c_str(), triggerLabel->second).c_str(), value)); + logger->log("Warning: unknown modifier tag %s in %s, skipping.", attribute.c_str(), filename.c_str()); + continue; } - else if (xmlStrEqual(effectChild->name, BAD_CAST "modifier")) - effect.push_back(strprintf("Provides an autoattack%s.", - triggerLabel->second)); - else if (xmlStrEqual(effectChild->name, BAD_CAST "consumes")) - effect.push_back(strprintf("This will be consumed%s.", - triggerLabel->second)); - else if (xmlStrEqual(effectChild->name, BAD_CAST "label")) - effect.push_back( - (const char*)effectChild->xmlChildrenNode->content); + effect.push_back( + strprintf(strprintf( + duration ? + strprintf("%%s%%s. This effect lasts %d ticks.", duration).c_str() + : "%s%s.", it->mFormat.c_str(), triggerLabel->second).c_str(), value)); } + else if (xmlStrEqual(effectChild->name, BAD_CAST "modifier")) + effect.push_back(strprintf("Provides an autoattack%s.", + triggerLabel->second)); + else if (xmlStrEqual(effectChild->name, BAD_CAST "consumes")) + effect.push_back(strprintf("This will be consumed%s.", + triggerLabel->second)); + else if (xmlStrEqual(effectChild->name, BAD_CAST "label")) + effect.push_back( + (const char*)effectChild->xmlChildrenNode->content); } + } - // FIXME: Load hair styles through the races.xml file - if (itemInfo->mType == ITEM_SPRITE_HAIR) - hairDB.addHairStyle(itemInfo->mId); + // FIXME: Load hair styles through the races.xml file + if (itemInfo->mType == ITEM_SPRITE_HAIR) + hairDB.addHairStyle(itemInfo->mId); - // Set Item Type based on subnodes info - // TODO: Improve it once the itemTypes are loaded through xml - itemInfo->mType = ITEM_UNUSABLE; - if (itemInfo->mActivatable) - itemInfo->mType = ITEM_USABLE; - else if (itemInfo->mEquippable) - itemInfo->mType = ITEM_EQUIPMENT_TORSO; - } // end for_each_xml_child_node(itemChild, node) + // Set Item Type based on subnodes info + // TODO: Improve it once the itemTypes are loaded through xml + itemInfo->mType = ITEM_UNUSABLE; + if (itemInfo->mActivatable) + itemInfo->mType = ITEM_USABLE; + else if (itemInfo->mEquippable) + itemInfo->mType = ITEM_EQUIPMENT_TORSO; + } // end for_each_xml_child_node(itemChild, node) - itemInfo->mEffect = effect; + itemInfo->mEffect = effect; - checkItemInfo(itemInfo); + checkItemInfo(itemInfo); - addItem(itemInfo); - } + addItem(itemInfo); +} +void ManaServItemDB::checkStatus() +{ mLoaded = true; } diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h index d7859ad3..2f19339d 100644 --- a/src/resources/itemdb.h +++ b/src/resources/itemdb.h @@ -81,11 +81,6 @@ class ItemDB virtual ~ItemDB() {} - /** - * Loads the item data from items.xml. - */ - virtual void load() = 0; - /** * Frees item data. */ @@ -102,12 +97,18 @@ class ItemDB const ItemInfo &get(int id); const ItemInfo &get(const std::string &name); + virtual void init() = 0; + + virtual void readItemNode(xmlNodePtr node, const std::string &filename) = 0; + + virtual void checkStatus() = 0; + protected: /** * Permits to load item definitions which are common * for each protocols to avoid code duplication. */ - void loadCommonRef(ItemInfo *itemInfo, xmlNodePtr node); + void loadCommonRef(ItemInfo *itemInfo, xmlNodePtr node, const std::string &filename); /** * Checks the items parameters consistency. @@ -164,16 +165,16 @@ class TaItemDB: public ItemDB { public: TaItemDB() : ItemDB() - { load(); } + { } ~TaItemDB() { unload(); } - /** - * Loads the item data from items.xml. - */ - void load(); + virtual void init(); + + virtual void readItemNode(xmlNodePtr node, const std::string &filename); + virtual void checkStatus(); private: /** * Check items id specific hard limits and log errors found. @@ -198,15 +199,16 @@ class ManaServItemDB: public ItemDB { public: ManaServItemDB() : ItemDB() - { load(); } + { } ~ManaServItemDB() { unload(); } - /** - * Loads the item data from items.xml. - */ - void load(); + virtual void init(); + + virtual void readItemNode(xmlNodePtr node, const std::string &filename); + + virtual void checkStatus(); private: void checkItemInfo(ItemInfo* itemInfo); diff --git a/src/resources/settingsmanager.cpp b/src/resources/settingsmanager.cpp index 3cbb115c..b2d1fe80 100644 --- a/src/resources/settingsmanager.cpp +++ b/src/resources/settingsmanager.cpp @@ -21,8 +21,9 @@ #include "resources/settingsmanager.h" #include "resources/attributes.h" -#include "resources/monsterdb.h" #include "resources/hairdb.h" +#include "resources/itemdb.h" +#include "resources/monsterdb.h" #include "resources/specialdb.h" #include "resources/npcdb.h" #include "resources/emotedb.h" @@ -48,6 +49,7 @@ namespace SettingsManager // initialize managers Attributes::init(); hairDB.init(); + itemDb->init(); MonsterDB::init(); SpecialDB::init(); NPCDB::init(); @@ -60,6 +62,7 @@ namespace SettingsManager Attributes::checkStatus(); hairDB.checkStatus(); + itemDb->checkStatus(); MonsterDB::checkStatus(); SpecialDB::checkStatus(); NPCDB::checkStatus(); @@ -80,6 +83,7 @@ namespace SettingsManager NPCDB::unload(); SpecialDB::unload(); MonsterDB::unload(); + itemDb->unload(); hairDB.unload(); Attributes::unload(); } @@ -149,6 +153,10 @@ namespace SettingsManager { hairDB.readHairColorNode(childNode, filename); } + else if (xmlStrEqual(childNode->name, BAD_CAST "item")) + { + itemDb->readItemNode(childNode, filename); + } else if (xmlStrEqual(childNode->name, BAD_CAST "monster")) { MonsterDB::readMonsterNode(childNode, filename); -- cgit v1.2.3-70-g09d2