diff options
Diffstat (limited to 'src/resources')
-rw-r--r-- | src/resources/attributes.cpp | 188 | ||||
-rw-r--r-- | src/resources/attributes.h | 13 | ||||
-rw-r--r-- | src/resources/emotedb.cpp | 116 | ||||
-rw-r--r-- | src/resources/emotedb.h | 9 | ||||
-rw-r--r-- | src/resources/hairdb.cpp | 79 | ||||
-rw-r--r-- | src/resources/hairdb.h | 12 | ||||
-rw-r--r-- | src/resources/itemdb.cpp | 288 | ||||
-rw-r--r-- | src/resources/itemdb.h | 34 | ||||
-rw-r--r-- | src/resources/monsterdb.cpp | 188 | ||||
-rw-r--r-- | src/resources/monsterdb.h | 10 | ||||
-rw-r--r-- | src/resources/npcdb.cpp | 71 | ||||
-rw-r--r-- | src/resources/npcdb.h | 11 | ||||
-rw-r--r-- | src/resources/settingsmanager.cpp | 212 | ||||
-rw-r--r-- | src/resources/settingsmanager.h | 35 | ||||
-rw-r--r-- | src/resources/specialdb.cpp | 71 | ||||
-rw-r--r-- | src/resources/specialdb.h | 9 |
16 files changed, 766 insertions, 580 deletions
diff --git a/src/resources/attributes.cpp b/src/resources/attributes.cpp index c4c67fba..58bff6f1 100644 --- a/src/resources/attributes.cpp +++ b/src/resources/attributes.cpp @@ -29,7 +29,6 @@ #include "utils/gettext.h" #include "utils/stringutils.h" -#include "utils/xml.h" #include <list> #include <map> @@ -238,120 +237,121 @@ namespace Attributes { } } - void load() + void init() { - logger->log("Initializing attributes database..."); + if (attributes.size()) + unload(); + } - XML::Document doc(DEFAULT_ATTRIBUTESDB_FILE); - xmlNodePtr rootNode = doc.rootNode(); + /** + * Read attribute node + */ + void readAttributeNode(xmlNodePtr node, const std::string &filename) + { + int id = XML::getProperty(node, "id", 0); - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "attributes")) + if (!id) { - logger->log("Attributes: Error while loading " - DEFAULT_ATTRIBUTESDB_FILE ". Using Built-ins."); - loadBuiltins(); - fillLabels(); + logger->log("Attributes: Invalid or missing stat ID in " + DEFAULT_ATTRIBUTESDB_FILE "!"); return; } + else if (attributes.find(id) != attributes.end()) + { + logger->log("Attributes: Redefinition of stat ID %d", id); + } + + std::string name = XML::getProperty(node, "name", ""); - for_each_xml_child_node(node, rootNode) + if (name.empty()) { - if (xmlStrEqual(node->name, BAD_CAST "attribute")) - { - int id = XML::getProperty(node, "id", 0); + logger->log("Attributes: Invalid or missing stat name in " + DEFAULT_ATTRIBUTESDB_FILE "!"); + return; + } + + // Create the attribute. + Attribute a; + a.id = id; + a.name = name; + a.description = XML::getProperty(node, "desc", ""); + a.modifiable = XML::getBoolProperty(node, "modifiable", false); + a.scope = XML::getProperty(node, "scope", "none"); + a.playerInfoId = getPlayerInfoIdFromAttrType( + XML::getProperty(node, "player-info", "")); + + attributes[id] = a; - if (!id) + unsigned int count = 0; + for_each_xml_child_node(effectNode, node) + { + if (!xmlStrEqual(effectNode->name, BAD_CAST "modifier")) + continue; + ++count; + std::string tag = XML::getProperty(effectNode, "tag", ""); + if (tag.empty()) + { + if (name.empty()) { - logger->log("Attributes: Invalid or missing stat ID in " - DEFAULT_ATTRIBUTESDB_FILE "!"); + logger->log("Attribute modifier in attribute %u:%s: " + "Empty name definition " + "on empty tag definition, skipping.", + a.id, a.name.c_str()); + --count; continue; } - else if (attributes.find(id) != attributes.end()) - { - logger->log("Attributes: Redefinition of stat ID %d", id); - } - - std::string name = XML::getProperty(node, "name", ""); + tag = name.substr(0, name.size() > 3 ? 3 : name.size()); + tag = toLower(tag) + toString(count); + } + std::string effect = XML::getProperty(effectNode, "effect", ""); + if (effect.empty()) + { if (name.empty()) { - logger->log("Attributes: Invalid or missing stat name in " - DEFAULT_ATTRIBUTESDB_FILE "!"); + logger->log("Attribute modifier in attribute %u:%s: " + "Empty name definition " + "on empty effect definition, skipping.", + a.id, a.name.c_str()); + --count; continue; } + else + effect = name + " %+f"; + } + tags.insert(std::make_pair(tag, effect)); + } + logger->log("Found %d tags for attribute %d.", count, id); - // Create the attribute. - Attribute a; - a.id = id; - a.name = name; - a.description = XML::getProperty(node, "desc", ""); - a.modifiable = XML::getBoolProperty(node, "modifiable", false); - a.scope = XML::getProperty(node, "scope", "none"); - a.playerInfoId = getPlayerInfoIdFromAttrType( - XML::getProperty(node, "player-info", "")); - - attributes[id] = a; - - unsigned int count = 0; - for_each_xml_child_node(effectNode, node) - { - if (!xmlStrEqual(effectNode->name, BAD_CAST "modifier")) - continue; - ++count; - std::string tag = XML::getProperty(effectNode, "tag", ""); - if (tag.empty()) - { - if (name.empty()) - { - logger->log("Attribute modifier in attribute %u:%s: " - "Empty name definition " - "on empty tag definition, skipping.", - a.id, a.name.c_str()); - --count; - continue; - } - tag = name.substr(0, name.size() > 3 ? 3 : name.size()); - tag = toLower(tag) + toString(count); - } - - std::string effect = XML::getProperty(effectNode, "effect", ""); - if (effect.empty()) - { - if (name.empty()) - { - logger->log("Attribute modifier in attribute %u:%s: " - "Empty name definition " - "on empty effect definition, skipping.", - a.id, a.name.c_str()); - --count; - continue; - } - else - effect = name + " %+f"; - } - tags.insert(std::make_pair(tag, effect)); - } - logger->log("Found %d tags for attribute %d.", count, id); - - }// End attribute - else if (xmlStrEqual(node->name, BAD_CAST "points")) - { - creationPoints = XML::getProperty(node, "start",DEFAULT_POINTS); - attributeMinimum = XML::getProperty(node, "minimum", - DEFAULT_MIN_PTS); - attributeMaximum = XML::getProperty(node, "maximum", - DEFAULT_MAX_PTS); - logger->log("Loaded points: start: %i, min: %i, max: %i.", - creationPoints, attributeMinimum, attributeMaximum); - } - else - { - continue; - } - } + } + + /** + * Read points node + */ + void readPointsNode(xmlNodePtr node, const std::string &filename) + { + creationPoints = XML::getProperty(node, "start",DEFAULT_POINTS); + attributeMinimum = XML::getProperty(node, "minimum", + DEFAULT_MIN_PTS); + attributeMaximum = XML::getProperty(node, "maximum", + DEFAULT_MAX_PTS); + logger->log("Loaded points: start: %i, min: %i, max: %i.", + creationPoints, attributeMinimum, attributeMaximum); + } + + /** + * Check if all the data loaded by readPointsNode and readAttributeNode is ok + */ + void checkStatus() + { logger->log("Found %d tags for %d attributes.", int(tags.size()), int(attributes.size())); + if (attributes.size() == 0) + { + loadBuiltins(); + } + fillLabels(); // Sanity checks on starting points diff --git a/src/resources/attributes.h b/src/resources/attributes.h index 7124ba94..41093af2 100644 --- a/src/resources/attributes.h +++ b/src/resources/attributes.h @@ -24,9 +24,18 @@ #include <string> #include <vector> -namespace Attributes { +#include "utils/xml.h" - void load(); +namespace Attributes +{ + + void init(); + + void readAttributeNode(xmlNodePtr node, const std::string &filename); + + void readPointsNode(xmlNodePtr node, const std::string &filename); + + void checkStatus(); void unload(); diff --git a/src/resources/emotedb.cpp b/src/resources/emotedb.cpp index 00721ac4..04dd4bbb 100644 --- a/src/resources/emotedb.cpp +++ b/src/resources/emotedb.cpp @@ -1,7 +1,7 @@ /* * Emote database * Copyright (C) 2009 Aethyra Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -29,8 +29,6 @@ #include "resources/image.h" #include "resources/imageset.h" -#include "utils/xml.h" - namespace { Emotes mEmotes; @@ -39,7 +37,7 @@ namespace int mLastEmote = 0; } -void EmoteDB::load() +void EmoteDB::init() { if (mLoaded) unload(); @@ -51,74 +49,66 @@ void EmoteDB::load() mLastEmote = 0; - logger->log("Initializing emote database..."); +} + +void EmoteDB::readEmoteNode(xmlNodePtr node, const std::string &filename) +{ + int id = XML::getProperty(node, "id", -1); + if (id == -1) + { + logger->log("Emote Database: Emote with missing ID in %s!", filename.c_str()); + return; + } + + Emote *currentEmote = new Emote; + + currentEmote->name = XML::getProperty(node, "name", "unknown"); + currentEmote->effect = XML::getProperty(node, "effectid", -1); + + if (currentEmote->effect == -1) + { + logger->log("Emote Database: Warning: Emote %s has no attached effect in %s!", + currentEmote->name.c_str(), filename.c_str()); + delete currentEmote; + return; + } - XML::Document doc("emotes.xml"); - xmlNodePtr rootNode = doc.rootNode(); + const std::string imageName = XML::getProperty(node, "image", ""); + const int width = XML::getProperty(node, "width", 0); + const int height = XML::getProperty(node, "height", 0); - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "emotes")) + if (imageName.empty() || width <= 0 || height <= 0) { - logger->log("Emote Database: Error while loading emotes.xml!"); + logger->log("Emote Database: Warning: Emote %s has bad imageset values in %s", + currentEmote->name.c_str(), filename.c_str()); + delete currentEmote; return; } - //iterate <emote>s - for_each_xml_child_node(emoteNode, rootNode) + ImageSet *is = ResourceManager::getInstance()->getImageSet(imageName, + width, + height); + if (!is || !(is->size() > 0)) + { + logger->log("Emote Database: Error loading imageset for emote %s in %s", + currentEmote->name.c_str(), filename.c_str()); + delete is; + delete currentEmote; + return; + } + else { - if (!xmlStrEqual(emoteNode->name, BAD_CAST "emote")) - continue; - - int id = XML::getProperty(emoteNode, "id", -1); - if (id == -1) - { - logger->log("Emote Database: Emote with missing ID in emotes.xml!"); - continue; - } - - Emote *currentEmote = new Emote; - - currentEmote->name = XML::getProperty(emoteNode, "name", "unknown"); - currentEmote->effect = XML::getProperty(emoteNode, "effectid", -1); - - if (currentEmote->effect == -1) - { - logger->log("Emote Database: Warning: Emote with no attached effect!"); - delete currentEmote; - continue; - } - - const std::string imageName = XML::getProperty(emoteNode, "image", ""); - const int width = XML::getProperty(emoteNode, "width", 0); - const int height = XML::getProperty(emoteNode, "height", 0); - - if (imageName.empty() || width <= 0 || height <= 0) - { - logger->log("Emote Database: Warning: Emote with bad imageset values"); - delete currentEmote; - continue; - } - - ImageSet *is = ResourceManager::getInstance()->getImageSet(imageName, - width, - height); - if (!is || !(is->size() > 0)) - { - logger->log("Emote Database: Error loading imageset"); - delete is; - delete currentEmote; - continue; - } - else - { - // For now we just use the first image in the animation - currentEmote->sprite = new ImageSprite(is->get(0)); - } - - mEmotes[id] = currentEmote; - if (id > mLastEmote) - mLastEmote = id; + // For now we just use the first image in the animation + currentEmote->sprite = new ImageSprite(is->get(0)); } + mEmotes[id] = currentEmote; + if (id > mLastEmote) + mLastEmote = id; +} + +void EmoteDB::checkStatus() +{ mLoaded = true; } diff --git a/src/resources/emotedb.h b/src/resources/emotedb.h index a1e991ec..33195d82 100644 --- a/src/resources/emotedb.h +++ b/src/resources/emotedb.h @@ -1,7 +1,7 @@ /* * Emote database * Copyright (C) 2009 Aethyra Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -25,6 +25,7 @@ #include <list> #include <map> #include <string> +#include "utils/xml.h" class ImageSprite; @@ -42,7 +43,11 @@ typedef std::map<int, Emote*> Emotes; */ namespace EmoteDB { - void load(); + void init(); + + void readEmoteNode(xmlNodePtr node, const std::string &filename); + + void checkStatus(); void unload(); diff --git a/src/resources/hairdb.cpp b/src/resources/hairdb.cpp index 26ad966e..2e9747a2 100644 --- a/src/resources/hairdb.cpp +++ b/src/resources/hairdb.cpp @@ -1,7 +1,7 @@ /* * Hair database * Copyright (C) 2008 Aethyra Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -23,58 +23,32 @@ #include "log.h" -#include "utils/xml.h" - #include <assert.h> #define COLOR_WHITE "#ffffff" -#define HAIR_XML_FILE "hair.xml" -void HairDB::load() + +void HairDB::init() { if (mLoaded) unload(); // Default entry mHairColors[0] = COLOR_WHITE; +} - XML::Document *doc = new XML::Document(HAIR_XML_FILE); - xmlNodePtr root = doc->rootNode(); - - if (!root || (!xmlStrEqual(root->name, BAD_CAST "colors") - && !xmlStrEqual(root->name, BAD_CAST "hair"))) - { - logger->log("HairDb: Failed to find any old <colors> or new " - "<hair> nodes."); - delete doc; - mLoaded = true; - return; - } +void HairDB::readHairColorNode(xmlNodePtr node, const std::string &filename) +{ + int id = XML::getProperty(node, "id", 0); - // Old colors.xml file style. The hair style will be declared - // in the items.xml file. - if (xmlStrEqual(root->name, BAD_CAST "colors")) - { - loadHairColorsNode(root); - } - else if (xmlStrEqual(root->name, BAD_CAST "hair")) - { - // Loading new format: hair styles + colors. - for_each_xml_child_node(node, root) - { - if (xmlStrEqual(node->name, BAD_CAST "styles")) - { - loadHairStylesNode(root); - } - else if (xmlStrEqual(node->name, BAD_CAST "colors")) - { - loadHairColorsNode(node); - } - } - } + if (mHairColors.find(id) != mHairColors.end()) + logger->log("HairDb: Redefinition of color Id %d in %s", id, filename.c_str()); - delete doc; + mHairColors[id] = XML::getProperty(node, "value", COLOR_WHITE); +} +void HairDB::checkStatus() +{ mLoaded = true; } @@ -91,27 +65,6 @@ void HairDB::unload() mLoaded = false; } -void HairDB::loadHairColorsNode(xmlNodePtr colorsNode) -{ - for_each_xml_child_node(node, colorsNode) - { - if (xmlStrEqual(node->name, BAD_CAST "color")) - { - int id = XML::getProperty(node, "id", 0); - - if (mHairColors.find(id) != mHairColors.end()) - logger->log("HairDb: Redefinition of color Id %d", id); - - mHairColors[id] = XML::getProperty(node, "value", COLOR_WHITE); - } - } -} - -void HairDB::loadHairStylesNode(xmlNodePtr stylesNode) -{ - // TODO: Add support of the races.xml file. -} - void HairDB::addHairStyle(int id) { // TODO: Adapt the sprite handling with hair styles separated from items. @@ -128,8 +81,10 @@ void HairDB::addHairStyle(int id) const std::string &HairDB::getHairColor(int id) { if (!mLoaded) - load(); - + { + // no idea if this can happen, but that check existed before + logger->log("WARNING: HairDB::getHairColor() called before settings were loaded!"); + } ColorConstIterator it = mHairColors.find(id); if (it != mHairColors.end()) return it->second; diff --git a/src/resources/hairdb.h b/src/resources/hairdb.h index 700bd8b7..502d7c21 100644 --- a/src/resources/hairdb.h +++ b/src/resources/hairdb.h @@ -1,7 +1,7 @@ /* * Hair database * Copyright (C) 2008 Aethyra Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -26,6 +26,7 @@ #include <map> #include <string> +#include "utils/xml.h" /** * Hair information database. @@ -40,10 +41,11 @@ class HairDB ~HairDB() { unload(); } - /** - * Loads the color data from <code>hair.xml</code>. - */ - void load(); + void init(); + + void readHairColorNode(xmlNodePtr node, const std::string &filename); + + void checkStatus(); /** * Clear the color data diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index 4db7b085..8c1a8d15 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 <libxml/tree.h> @@ -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,70 +322,59 @@ 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..."); +void TaItemDB::readItemNode(xmlNodePtr node, const std::string &filename) +{ + TaItemInfo *itemInfo = new TaItemInfo; - mUnknown = new TaItemInfo; - loadEmptyItemDefinition(); + loadCommonRef(itemInfo, node, filename); - XML::Document doc(ITEMS_DB_FILE); - xmlNodePtr rootNode = doc.rootNode(); + // 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; - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items")) + // Load nano description + std::vector<std::string> 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<ItemStat>::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<std::string> 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<ItemStat>::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() +{ + mUnknown = new TaItemInfo; + loadEmptyItemDefinition(); checkHairWeaponsRacesSpecialIds(); @@ -423,136 +410,125 @@ static void initTriggerTable() } } -void ManaServItemDB::load() +void ManaServItemDB::init() { if (mLoaded) unload(); // Initialize the trigger table for effect descriptions initTriggerTable(); +} - logger->log("Initializing ManaServ item database..."); - - mUnknown = new ManaServItemInfo; - loadEmptyItemDefinition(); +void ManaServItemDB::readItemNode(xmlNodePtr node, const std::string &filename) +{ + ManaServItemInfo *itemInfo = new ManaServItemInfo; - XML::Document doc(ITEMS_DB_FILE); - xmlNodePtr rootNode = doc.rootNode(); + loadCommonRef(itemInfo, node, filename); - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items")) - { - logger->log("ItemDB: Error while loading " ITEMS_DB_FILE "!"); - return; - } + // We default eqippable and activatable to false as their actual value will be set + // within the <equip> and <effect> sub-nodes.. + itemInfo->mActivatable = false; + itemInfo->mEquippable = false; - for_each_xml_child_node(node, rootNode) + // Load <equip>, and <effect> sub nodes. + std::vector<std::string> effect; + for_each_xml_child_node(itemChild, node) { - if (!xmlStrEqual(node->name, BAD_CAST "item")) - continue; - - ManaServItemInfo *itemInfo = new ManaServItemInfo; - - loadCommonRef(itemInfo, node); - - // We default eqippable and activatable to false as their actual value will be set - // within the <equip> and <effect> sub-nodes.. - itemInfo->mActivatable = false; - itemInfo->mEquippable = false; - - // Load <equip>, and <effect> sub nodes. - std::vector<std::string> effect; - for_each_xml_child_node(itemChild, node) + 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")) { - if (xmlStrEqual(itemChild->name, BAD_CAST "equip")) + 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<std::string, const char* >::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<std::string, const char* >::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) { - 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<ItemStat>::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: incomplete modifier definition in %s, skipping.", 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); + std::list<ItemStat>::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 in %s, skipping.", attribute.c_str(), filename.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)); } + 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() +{ + mUnknown = new ManaServItemInfo; + loadEmptyItemDefinition(); 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 @@ -82,11 +82,6 @@ class ItemDB {} /** - * Loads the item data from <code>items.xml</code>. - */ - virtual void load() = 0; - - /** * Frees item data. */ virtual void unload(); @@ -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 <code>items.xml</code>. - */ - 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 <code>items.xml</code>. - */ - 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/monsterdb.cpp b/src/resources/monsterdb.cpp index 241cc053..8415b6ae 100644 --- a/src/resources/monsterdb.cpp +++ b/src/resources/monsterdb.cpp @@ -1,7 +1,7 @@ /* * The Mana Client * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -29,131 +29,135 @@ #include "utils/dtor.h" #include "utils/gettext.h" -#include "utils/xml.h" #include "configuration.h" #define OLD_TMWATHENA_OFFSET 1002 + namespace { BeingInfos mMonsterInfos; bool mLoaded = false; + int mMonsterIdOffset; } -void MonsterDB::load() + +/** + * Initialize MonsterDB + * + * If it was initialized before, unload() will be called first. + */ +void MonsterDB::init() { if (mLoaded) unload(); - logger->log("Initializing monster database..."); + // This used to be read from offset attribute of monsters root tag, however + // I couldn't find any place it was used, so for now the default values are set + mMonsterIdOffset = Net::getNetworkType() == ServerInfo::TMWATHENA ? OLD_TMWATHENA_OFFSET : 0; +} - XML::Document doc("monsters.xml"); - xmlNodePtr rootNode = doc.rootNode(); +/** + * Read <monster> node from settings. + */ +void MonsterDB::readMonsterNode(xmlNodePtr node, const std::string &filename) +{ + BeingInfo *currentInfo = new BeingInfo; - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "monsters")) - { - logger->error("Monster Database: Error while loading monster.xml!"); - } + currentInfo->setWalkMask(Map::BLOCKMASK_WALL + | Map::BLOCKMASK_CHARACTER + | Map::BLOCKMASK_MONSTER); + currentInfo->setBlockType(Map::BLOCKTYPE_MONSTER); + + currentInfo->setName(XML::getProperty(node, "name", _("unnamed"))); - int offset = XML::getProperty(rootNode, "offset", Net::getNetworkType() == - ServerInfo::TMWATHENA ? OLD_TMWATHENA_OFFSET : 0); + currentInfo->setTargetCursorSize(XML::getProperty(node, + "targetCursor", "medium")); - //iterate <monster>s - for_each_xml_child_node(monsterNode, rootNode) + SpriteDisplay display; + + //iterate <sprite>s and <sound>s + for_each_xml_child_node(spriteNode, node) { - if (!xmlStrEqual(monsterNode->name, BAD_CAST "monster")) + if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite")) { - continue; + SpriteReference currentSprite; + currentSprite.sprite = (const char*)spriteNode->xmlChildrenNode->content; + currentSprite.variant = XML::getProperty(spriteNode, "variant", 0); + display.sprites.push_back(currentSprite); } - - BeingInfo *currentInfo = new BeingInfo; - - currentInfo->setWalkMask(Map::BLOCKMASK_WALL - | Map::BLOCKMASK_CHARACTER - | Map::BLOCKMASK_MONSTER); - currentInfo->setBlockType(Map::BLOCKTYPE_MONSTER); - - currentInfo->setName(XML::getProperty(monsterNode, "name", _("unnamed"))); - - currentInfo->setTargetCursorSize(XML::getProperty(monsterNode, - "targetCursor", "medium")); - - SpriteDisplay display; - - //iterate <sprite>s and <sound>s - for_each_xml_child_node(spriteNode, monsterNode) + else if (xmlStrEqual(spriteNode->name, BAD_CAST "sound")) { - if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite")) + std::string event = XML::getProperty(spriteNode, "event", ""); + const char *soundFile; + soundFile = (const char*) spriteNode->xmlChildrenNode->content; + + if (event == "hit") + { + currentInfo->addSound(SOUND_EVENT_HIT, soundFile); + } + else if (event == "miss") { - SpriteReference currentSprite; - currentSprite.sprite = (const char*)spriteNode->xmlChildrenNode->content; - currentSprite.variant = XML::getProperty(spriteNode, "variant", 0); - display.sprites.push_back(currentSprite); + currentInfo->addSound(SOUND_EVENT_MISS, soundFile); } - else if (xmlStrEqual(spriteNode->name, BAD_CAST "sound")) + else if (event == "hurt") { - std::string event = XML::getProperty(spriteNode, "event", ""); - const char *filename; - filename = (const char*) spriteNode->xmlChildrenNode->content; - - if (event == "hit") - { - currentInfo->addSound(SOUND_EVENT_HIT, filename); - } - else if (event == "miss") - { - currentInfo->addSound(SOUND_EVENT_MISS, filename); - } - else if (event == "hurt") - { - currentInfo->addSound(SOUND_EVENT_HURT, filename); - } - else if (event == "die") - { - currentInfo->addSound(SOUND_EVENT_DIE, filename); - } - else - { - logger->log("MonsterDB: Warning, sound effect %s for " - "unknown event %s of monster %s", - filename, event.c_str(), - currentInfo->getName().c_str()); - } + currentInfo->addSound(SOUND_EVENT_HURT, soundFile); } - else if (xmlStrEqual(spriteNode->name, BAD_CAST "attack")) + else if (event == "die") { - const int id = XML::getProperty(spriteNode, "id", 0); - int effectId = XML::getProperty(spriteNode, "effect-id", -1); - int hitEffectId = - XML::getProperty(spriteNode, "hit-effect-id", - paths.getIntValue("hitEffectId")); - int criticalHitEffectId = - XML::getProperty(spriteNode, "critical-hit-effect-id", - paths.getIntValue("criticalHitEffectId")); - const std::string missileParticleFilename = - XML::getProperty(spriteNode, "missile-particle", ""); - - const std::string spriteAction = XML::getProperty(spriteNode, - "action", - "attack"); - - currentInfo->addAttack(id, spriteAction, effectId, - hitEffectId, criticalHitEffectId, - missileParticleFilename); + currentInfo->addSound(SOUND_EVENT_DIE, soundFile); } - else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx")) + else { - display.particles.push_back( - (const char*) spriteNode->xmlChildrenNode->content); + logger->log("MonsterDB: Warning, sound effect %s for " + "unknown event %s of monster %s in %s", + soundFile, event.c_str(), + currentInfo->getName().c_str(), + filename.c_str()); } } - currentInfo->setDisplay(display); - - mMonsterInfos[XML::getProperty(monsterNode, "id", 0) + offset] = currentInfo; + else if (xmlStrEqual(spriteNode->name, BAD_CAST "attack")) + { + const int id = XML::getProperty(spriteNode, "id", 0); + int effectId = XML::getProperty(spriteNode, "effect-id", -1); + int hitEffectId = + XML::getProperty(spriteNode, "hit-effect-id", + paths.getIntValue("hitEffectId")); + int criticalHitEffectId = + XML::getProperty(spriteNode, "critical-hit-effect-id", + paths.getIntValue("criticalHitEffectId")); + const std::string missileParticleFilename = + XML::getProperty(spriteNode, "missile-particle", ""); + + const std::string spriteAction = XML::getProperty(spriteNode, + "action", + "attack"); + + currentInfo->addAttack(id, spriteAction, effectId, + hitEffectId, criticalHitEffectId, + missileParticleFilename); + } + else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx")) + { + display.particles.push_back( + (const char*) spriteNode->xmlChildrenNode->content); + } } + currentInfo->setDisplay(display); + + mMonsterInfos[XML::getProperty(node, "id", 0) + mMonsterIdOffset] = currentInfo; - mLoaded = true; + +} + +/** + * Check if everything was loaded correctly + */ +void MonsterDB::checkStatus() +{ + // there is nothing to check for now } void MonsterDB::unload() diff --git a/src/resources/monsterdb.h b/src/resources/monsterdb.h index 8ea3afdf..5b2f3c2d 100644 --- a/src/resources/monsterdb.h +++ b/src/resources/monsterdb.h @@ -1,7 +1,7 @@ /* * The Mana Client * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -22,6 +22,8 @@ #ifndef MONSTER_DB_H #define MONSTER_DB_H +#include "utils/xml.h" + class BeingInfo; /** @@ -29,7 +31,11 @@ class BeingInfo; */ namespace MonsterDB { - void load(); + void init(); + + void readMonsterNode(xmlNodePtr node, const std::string &filename); + + void checkStatus(); void unload(); diff --git a/src/resources/npcdb.cpp b/src/resources/npcdb.cpp index 45b36dfe..7d0f72b0 100644 --- a/src/resources/npcdb.cpp +++ b/src/resources/npcdb.cpp @@ -1,7 +1,7 @@ /* * The Mana Client * Copyright (C) 2008-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -35,61 +35,52 @@ namespace bool mLoaded = false; } -void NPCDB::load() + +void NPCDB::init() { if (mLoaded) unload(); - logger->log("Initializing NPC database..."); - - XML::Document doc("npcs.xml"); - xmlNodePtr rootNode = doc.rootNode(); +} - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "npcs")) +void NPCDB::readNPCNode(xmlNodePtr node, const std::string &filename) +{ + int id = XML::getProperty(node, "id", 0); + if (id == 0) { - logger->error("NPC Database: Error while loading npcs.xml!"); + logger->log("NPC Database: NPC with missing ID in %s", filename.c_str()); + return; } - //iterate <npc>s - for_each_xml_child_node(npcNode, rootNode) - { - if (!xmlStrEqual(npcNode->name, BAD_CAST "npc")) - continue; + BeingInfo *currentInfo = new BeingInfo; + + currentInfo->setTargetCursorSize(XML::getProperty(node, + "targetCursor", "medium")); - int id = XML::getProperty(npcNode, "id", 0); - if (id == 0) + SpriteDisplay display; + for_each_xml_child_node(spriteNode, node) + { + if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite")) { - logger->log("NPC Database: NPC with missing ID in npcs.xml!"); - continue; + SpriteReference currentSprite; + currentSprite.sprite = (const char*)spriteNode->xmlChildrenNode->content; + currentSprite.variant = XML::getProperty(spriteNode, "variant", 0); + display.sprites.push_back(currentSprite); } - - BeingInfo *currentInfo = new BeingInfo; - - currentInfo->setTargetCursorSize(XML::getProperty(npcNode, - "targetCursor", "medium")); - - SpriteDisplay display; - for_each_xml_child_node(spriteNode, npcNode) + else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx")) { - if (xmlStrEqual(spriteNode->name, BAD_CAST "sprite")) - { - SpriteReference currentSprite; - currentSprite.sprite = (const char*)spriteNode->xmlChildrenNode->content; - currentSprite.variant = XML::getProperty(spriteNode, "variant", 0); - display.sprites.push_back(currentSprite); - } - else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx")) - { - std::string particlefx = (const char*)spriteNode->xmlChildrenNode->content; - display.particles.push_back(particlefx); - } + std::string particlefx = (const char*)spriteNode->xmlChildrenNode->content; + display.particles.push_back(particlefx); } + } - currentInfo->setDisplay(display); + currentInfo->setDisplay(display); - mNPCInfos[id] = currentInfo; - } + mNPCInfos[id] = currentInfo; +} +void NPCDB::checkStatus() +{ mLoaded = true; } diff --git a/src/resources/npcdb.h b/src/resources/npcdb.h index 16af7a5f..a3718a7b 100644 --- a/src/resources/npcdb.h +++ b/src/resources/npcdb.h @@ -1,7 +1,7 @@ /* * The Mana Client * Copyright (C) 2008-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers + * Copyright (C) 2009-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -22,6 +22,9 @@ #ifndef NPC_DB_H #define NPC_DB_H +#include <string> +#include "utils/xml.h" + class BeingInfo; /** @@ -29,7 +32,11 @@ class BeingInfo; */ namespace NPCDB { - void load(); + void init(); + + void readNPCNode(xmlNodePtr node, const std::string &filename); + + void checkStatus(); void unload(); diff --git a/src/resources/settingsmanager.cpp b/src/resources/settingsmanager.cpp new file mode 100644 index 00000000..940ebb59 --- /dev/null +++ b/src/resources/settingsmanager.cpp @@ -0,0 +1,212 @@ +/* + * The Mana Server + * Copyright (C) 2013 The Mana World Development Team + * + * This file is part of The Mana Server. + * + * The Mana Server 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. + * + * The Mana Server 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 The Mana Server. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "resources/settingsmanager.h" + +#include "configuration.h" +#include "resources/attributes.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" +#include "statuseffect.h" +#include "units.h" + +#include "net/manaserv/itemhandler.h" +#include "net/net.h" + +#include "utils/xml.h" +#include "utils/path.h" +#include "log.h" + +namespace SettingsManager +{ + static std::string mSettingsFile; + static std::set<std::string> mIncludedFiles; + + static void loadFile(const std::string &filename); + + void load() + { + // initialize managers + paths.clear(); + Attributes::init(); + hairDB.init(); + itemDb->init(); + MonsterDB::init(); + SpecialDB::init(); + NPCDB::init(); + EmoteDB::init(); + StatusEffect::init(); + Units::init(); + + // load stuff from settings + loadFile("settings.xml"); + + Attributes::checkStatus(); + hairDB.checkStatus(); + itemDb->checkStatus(); + MonsterDB::checkStatus(); + SpecialDB::checkStatus(); + NPCDB::checkStatus(); + EmoteDB::checkStatus(); + StatusEffect::checkStatus(); + Units::checkStatus(); + + if (Net::getNetworkType() == ServerInfo::MANASERV) + { + Attributes::informItemDB(); + } + } + + void unload() + { + StatusEffect::unload(); + EmoteDB::unload(); + NPCDB::unload(); + SpecialDB::unload(); + MonsterDB::unload(); + itemDb->unload(); + hairDB.unload(); + Attributes::unload(); + } + + /** + * Loads a settings file. + */ + static void loadFile(const std::string &filename) + { + logger->log("Loading game settings from %s", filename.c_str()); + + XML::Document doc(filename); + xmlNodePtr node = doc.rootNode(); + + // add file to include set + mIncludedFiles.insert(filename); + + // FIXME: check root node's name when bjorn decides it's time + if (!node /*|| !xmlStrEqual(node->name, BAD_CAST "settings") */) + { + logger->log("Settings Manager: %s is not a valid settings file!", filename.c_str()); + return; + } + + + // go through every node + for_each_xml_child_node(childNode, node) + { + if (childNode->type != XML_ELEMENT_NODE) + continue; + + if (xmlStrEqual(childNode->name, BAD_CAST "include")) + { + // include an other file + const std::string includeFile = XML::getProperty(childNode, "file", std::string()); + + // check if file property was given + if (!includeFile.empty()) + { + // build absolute path path + const utils::splittedPath splittedPath = utils::splitFileNameAndPath(filename); + const std::string realIncludeFile = utils::cleanPath( + utils::joinPaths(splittedPath.path, includeFile)); + + // check if we're not entering a loop + if (mIncludedFiles.find(realIncludeFile) != mIncludedFiles.end()) + { + logger->log("Circular include loop detecting while including %s from %s", includeFile.c_str(), filename.c_str()); + } + else + { + // include that file + loadFile(realIncludeFile); + } + } + } + else if (xmlStrEqual(childNode->name, BAD_CAST "option")) + { + // options from paths.xml + std::string name = XML::getProperty(childNode, "name", std::string()); + std::string value = XML::getProperty(childNode, "value", std::string()); + + if (!name.empty()) + paths.setValue(name, value); + else + logger->log("Warning: option without a name found in %s", filename.c_str()); + } + else if (xmlStrEqual(childNode->name, BAD_CAST "attribute")) + { + // map config + Attributes::readAttributeNode(childNode, filename); + } + else if (xmlStrEqual(childNode->name, BAD_CAST "points")) + { + Attributes::readPointsNode(childNode, filename); + } + else if (xmlStrEqual(childNode->name, BAD_CAST "color")) + { + 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); + } + else if (xmlStrEqual(childNode->name, BAD_CAST "special-set")) + { + SpecialDB::readSpecialSetNode(childNode, filename); + } + else if (xmlStrEqual(childNode->name, BAD_CAST "npc")) + { + NPCDB::readNPCNode(childNode, filename); + } + else if (xmlStrEqual(childNode->name, BAD_CAST "emote")) + { + EmoteDB::readEmoteNode(childNode, filename); + } + else if (xmlStrEqual(childNode->name, BAD_CAST "status-effect") || xmlStrEqual(childNode->name, BAD_CAST "stun-effect")) + { + StatusEffect::readStatusEffectNode(childNode, filename); + } + else if (xmlStrEqual(childNode->name, BAD_CAST "unit")) + { + Units::readUnitNode(childNode, filename); + } + else + { + // compatibility stuff with older configs/games + if (xmlStrEqual(node->name, BAD_CAST "specials") && xmlStrEqual(childNode->name, BAD_CAST "set")) + { + // specials.xml:/specials/set + SpecialDB::readSpecialSetNode(childNode, filename); + } + } + } + + mIncludedFiles.erase(filename); + } + +} + diff --git a/src/resources/settingsmanager.h b/src/resources/settingsmanager.h new file mode 100644 index 00000000..25feb86b --- /dev/null +++ b/src/resources/settingsmanager.h @@ -0,0 +1,35 @@ +/* + * The Mana Client + * Copyright (C) 2013 The Mana Developers + * + * This file is part of The Mana 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/>. + */ + +#ifndef SETTINGSMANAGER_HPP +#define SETTINGSMANAGER_HPP + +#include <string> +#include <list> +#include <set> + +namespace SettingsManager +{ + void load(); + void unload(); +} + + +#endif // SETTINGSMANAGER_HPP diff --git a/src/resources/specialdb.cpp b/src/resources/specialdb.cpp index c75f4b1b..6601b586 100644 --- a/src/resources/specialdb.cpp +++ b/src/resources/specialdb.cpp @@ -1,6 +1,6 @@ /* * The Mana Client - * Copyright (C) 2010-2012 The Mana Developers + * Copyright (C) 2010-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -23,7 +23,6 @@ #include "log.h" #include "utils/dtor.h" -#include "utils/xml.h" namespace @@ -41,63 +40,51 @@ SpecialInfo::TargetMode SpecialDB::targetModeFromString(const std::string& str) return SpecialInfo::TARGET_BEING; } -void SpecialDB::load() + +void SpecialDB::init() { if (mLoaded) unload(); +} - logger->log("Initializing special database..."); - - XML::Document doc("specials.xml"); - xmlNodePtr root = doc.rootNode(); - - if (!root || !xmlStrEqual(root->name, BAD_CAST "specials")) - { - logger->log("Error loading specials file specials.xml"); - return; - } - - std::string setName; +void SpecialDB::readSpecialSetNode(xmlNodePtr node, const std::string &filename) +{ + std::string setName = XML::getProperty(node, "name", "Actions"); - for_each_xml_child_node(set, root) + for_each_xml_child_node(special, node) { - if (xmlStrEqual(set->name, BAD_CAST "set") || - xmlStrEqual(set->name, BAD_CAST "special-set")) + if (xmlStrEqual(special->name, BAD_CAST "special")) { - setName = XML::getProperty(set, "name", "Actions"); + SpecialInfo *info = new SpecialInfo(); + int id = XML::getProperty(special, "id", 0); + info->id = id; + info->set = setName; + info->name = XML::getProperty(special, "name", ""); + info->icon = XML::getProperty(special, "icon", ""); + + info->targetMode = targetModeFromString(XML::getProperty(special, "target", "being")); + info->rechargeable = XML::getBoolProperty(special, "rechargeable", true); + info->rechargeNeeded = 0; + info->rechargeCurrent = 0; - for_each_xml_child_node(special, set) + if (mSpecialInfos.find(id) != mSpecialInfos.end()) { - if (xmlStrEqual(special->name, BAD_CAST "special")) - { - SpecialInfo *info = new SpecialInfo(); - int id = XML::getProperty(special, "id", 0); - info->id = id; - info->set = setName; - info->name = XML::getProperty(special, "name", ""); - info->icon = XML::getProperty(special, "icon", ""); - - info->targetMode = targetModeFromString(XML::getProperty(special, "target", "being")); - - info->rechargeable = XML::getBoolProperty(special, "rechargeable", true); - info->rechargeNeeded = 0; - info->rechargeCurrent = 0; - - if (mSpecialInfos.find(id) != mSpecialInfos.end()) - { - logger->log("SpecialDB: Duplicate special ID %d (ignoring)", id); - } else { - mSpecialInfos[id] = info; - } - } + logger->log("SpecialDB: Duplicate special ID %d in %s, ignoring", id, filename.c_str()); + } else { + mSpecialInfos[id] = info; } } } +} + +void SpecialDB::checkStatus() +{ mLoaded = true; } + void SpecialDB::unload() { diff --git a/src/resources/specialdb.h b/src/resources/specialdb.h index dc1c26b6..f6987b71 100644 --- a/src/resources/specialdb.h +++ b/src/resources/specialdb.h @@ -1,6 +1,6 @@ /* * The Mana Client - * Copyright (C) 2010-2012 The Mana Developers + * Copyright (C) 2010-2013 The Mana Developers * * This file is part of The Mana Client. * @@ -23,6 +23,7 @@ #include <string> #include <map> +#include "utils/xml.h" struct SpecialInfo { @@ -48,7 +49,11 @@ struct SpecialInfo */ namespace SpecialDB { - void load(); + void init(); + + void readSpecialSetNode(xmlNodePtr node, const std::string &filename); + + void checkStatus(); void unload(); |