summaryrefslogtreecommitdiff
path: root/src/resources
diff options
context:
space:
mode:
authorPrzemysław Grzywacz <nexather@gmail.com>2013-05-04 21:57:58 +0200
committerPrzemysław Grzywacz <nexather@gmail.com>2013-05-04 21:57:58 +0200
commitbd1fdd87eed48ba3ffcc413936d6a6a60a429a97 (patch)
tree159fcd36797021939967c770febd59d9fbe1ee19 /src/resources
parent0ef59afb6ee029a4e2247684f3f32f5bd064eb0b (diff)
downloadmana-bd1fdd87eed48ba3ffcc413936d6a6a60a429a97.tar.gz
mana-bd1fdd87eed48ba3ffcc413936d6a6a60a429a97.tar.bz2
mana-bd1fdd87eed48ba3ffcc413936d6a6a60a429a97.tar.xz
mana-bd1fdd87eed48ba3ffcc413936d6a6a60a429a97.zip
Client-side settings are now available from settings.xml
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/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.cpp191
-rw-r--r--src/resources/settingsmanager.h35
-rw-r--r--src/resources/specialdb.cpp71
-rw-r--r--src/resources/specialdb.h9
14 files changed, 595 insertions, 408 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/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..3cbb115c
--- /dev/null
+++ b/src/resources/settingsmanager.cpp
@@ -0,0 +1,191 @@
+/*
+ * 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 "resources/attributes.h"
+#include "resources/monsterdb.h"
+#include "resources/hairdb.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
+{
+ std::string mSettingsFile;
+ std::set<std::string> mIncludedFiles;
+
+ static void loadFile(const std::string &filename);
+
+ void load()
+ {
+ // initialize managers
+ Attributes::init();
+ hairDB.init();
+ MonsterDB::init();
+ SpecialDB::init();
+ NPCDB::init();
+ EmoteDB::init();
+ StatusEffect::init();
+ Units::init();
+
+ // load stuff from settings
+ loadFile("settings.xml");
+
+ Attributes::checkStatus();
+ hairDB.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();
+ 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 "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 "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();