summaryrefslogtreecommitdiff
path: root/src/resources
diff options
context:
space:
mode:
Diffstat (limited to 'src/resources')
-rw-r--r--src/resources/attributes.cpp188
-rw-r--r--src/resources/attributes.h13
-rw-r--r--src/resources/emotedb.cpp116
-rw-r--r--src/resources/emotedb.h9
-rw-r--r--src/resources/hairdb.cpp79
-rw-r--r--src/resources/hairdb.h12
-rw-r--r--src/resources/itemdb.cpp288
-rw-r--r--src/resources/itemdb.h34
-rw-r--r--src/resources/monsterdb.cpp188
-rw-r--r--src/resources/monsterdb.h10
-rw-r--r--src/resources/npcdb.cpp71
-rw-r--r--src/resources/npcdb.h11
-rw-r--r--src/resources/settingsmanager.cpp212
-rw-r--r--src/resources/settingsmanager.h35
-rw-r--r--src/resources/specialdb.cpp71
-rw-r--r--src/resources/specialdb.h9
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();