summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrzemysław Grzywacz <nexather@gmail.com>2013-05-07 17:45:26 +0200
committerPrzemysław Grzywacz <nexather@gmail.com>2013-05-07 17:45:26 +0200
commit92c09d42b782deff9dcb9dcc6b408fdd36bc4f37 (patch)
treeba6fc1735e766e32bf3eb76531b8ea506b9bd241
parentbd1fdd87eed48ba3ffcc413936d6a6a60a429a97 (diff)
downloadmana-92c09d42b782deff9dcb9dcc6b408fdd36bc4f37.tar.gz
mana-92c09d42b782deff9dcb9dcc6b408fdd36bc4f37.tar.bz2
mana-92c09d42b782deff9dcb9dcc6b408fdd36bc4f37.tar.xz
mana-92c09d42b782deff9dcb9dcc6b408fdd36bc4f37.zip
items.xml can be used from settings.xml
-rw-r--r--src/client.cpp24
-rw-r--r--src/resources/itemdb.cpp284
-rw-r--r--src/resources/itemdb.h34
-rw-r--r--src/resources/settingsmanager.cpp10
4 files changed, 165 insertions, 187 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 0d2c4bca..6b8ebca1 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -761,13 +761,12 @@ int Client::exec()
// TODO remove this as soon as inventoryhandler stops using this event
Event::trigger(Event::ClientChannel, Event::LoadingDatabases);
- // load game settings
-
-
// Load XML databases
- SettingsManager::load();
-
CharDB::load();
+
+ if (itemDb)
+ delete itemDb;
+
switch (Net::getNetworkType())
{
case ServerInfo::TMWATHENA:
@@ -781,17 +780,10 @@ int Client::exec()
itemDb = 0;
break;
}
- if (!itemDb || !itemDb->isLoaded())
- {
- // Warn and return to login screen
- errorMessage =
- _("This server is missing needed world data. "
- "Please contact the administrator(s).");
- showOkDialog(_("ItemDB: Error while loading "
- ITEMS_DB_FILE "!"), errorMessage,
- STATE_CHOOSE_SERVER);
- break;
- }
+ assert(itemDb);
+
+ // load settings.xml
+ SettingsManager::load();
ActorSprite::load();
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 4db7b085..b802457e 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -31,7 +31,6 @@
#include "utils/dtor.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
-#include "utils/xml.h"
#include "configuration.h"
#include <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,71 +322,60 @@ static char const *const fields[][2] =
{ "mp", N_("MP %+d") }
};
-void TaItemDB::load()
+void TaItemDB::init()
{
if (mLoaded)
unload();
- logger->log("Initializing TmwAthena item database...");
-
mUnknown = new TaItemInfo;
loadEmptyItemDefinition();
+}
+
+void TaItemDB::readItemNode(xmlNodePtr node, const std::string &filename)
+{
+ TaItemInfo *itemInfo = new TaItemInfo;
- XML::Document doc(ITEMS_DB_FILE);
- xmlNodePtr rootNode = doc.rootNode();
+ loadCommonRef(itemInfo, node, filename);
- if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items"))
+ // Everything not unusable or usable is equippable by the Ta type system.
+ itemInfo->mEquippable = itemInfo->mType != ITEM_UNUSABLE
+ && itemInfo->mType != ITEM_USABLE;
+ itemInfo->mActivatable = itemInfo->mType == ITEM_USABLE;
+
+ // Load nano description
+ std::vector<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()
+{
checkHairWeaponsRacesSpecialIds();
mLoaded = true;
@@ -423,7 +410,7 @@ static void initTriggerTable()
}
}
-void ManaServItemDB::load()
+void ManaServItemDB::init()
{
if (mLoaded)
unload();
@@ -431,129 +418,118 @@ void ManaServItemDB::load()
// Initialize the trigger table for effect descriptions
initTriggerTable();
- logger->log("Initializing ManaServ item database...");
-
mUnknown = new ManaServItemInfo;
loadEmptyItemDefinition();
+}
- XML::Document doc(ITEMS_DB_FILE);
- xmlNodePtr rootNode = doc.rootNode();
-
- if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items"))
- {
- logger->log("ItemDB: Error while loading " ITEMS_DB_FILE "!");
- return;
- }
-
- for_each_xml_child_node(node, rootNode)
- {
- if (!xmlStrEqual(node->name, BAD_CAST "item"))
- continue;
-
- ManaServItemInfo *itemInfo = new ManaServItemInfo;
+void ManaServItemDB::readItemNode(xmlNodePtr node, const std::string &filename)
+{
+ ManaServItemInfo *itemInfo = new ManaServItemInfo;
- loadCommonRef(itemInfo, node);
+ loadCommonRef(itemInfo, node, filename);
- // We default eqippable and activatable to false as their actual value will be set
- // within the <equip> and <effect> sub-nodes..
- itemInfo->mActivatable = false;
- itemInfo->mEquippable = false;
+ // 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)
+ // 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"))
{
- if (xmlStrEqual(itemChild->name, BAD_CAST "equip"))
+ // The fact that there is a way to equip is enough.
+ // Discard any details, but mark the item as equippable.
+ itemInfo->mEquippable = true;
+ }
+ else if (xmlStrEqual(itemChild->name, BAD_CAST "effect"))
+ {
+ std::string trigger = XML::getProperty(
+ itemChild, "trigger", "");
+ if (trigger.empty())
{
- // The fact that there is a way to equip is enough.
- // Discard any details, but mark the item as equippable.
- itemInfo->mEquippable = true;
+ logger->log("Found empty trigger effect label in %s, skipping.", filename.c_str());
+ continue;
}
- else if (xmlStrEqual(itemChild->name, BAD_CAST "effect"))
- {
- std::string trigger = XML::getProperty(
- itemChild, "trigger", "");
- if (trigger.empty())
- {
- logger->log("Found empty trigger effect label, skipping.");
- continue;
- }
- if (trigger == "activation")
- itemInfo->mActivatable = true;
+ if (trigger == "activation")
+ itemInfo->mActivatable = true;
- std::map<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)
+ {
+ logger->log("Warning: incomplete modifier definition in %s, skipping.", filename.c_str());
+ continue;
+ }
+ std::list<ItemStat>::const_iterator
+ it = extraStats.begin(),
+ it_end = extraStats.end();
+ while (it != it_end && !(*it == attribute))
+ ++it;
+ if (it == extraStats.end())
{
- std::string attribute = XML::getProperty(
- effectChild, "attribute", "");
- double value = XML::getFloatProperty(
- effectChild, "value", 0.0);
- int duration = XML::getProperty(
- effectChild, "duration", 0);
- if (attribute.empty() || !value)
- {
- logger->log("Warning: incomplete modifier definition, skipping.");
- continue;
- }
- std::list<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: unknown modifier tag %s in %s, skipping.", attribute.c_str(), filename.c_str());
+ continue;
}
- else if (xmlStrEqual(effectChild->name, BAD_CAST "modifier"))
- effect.push_back(strprintf("Provides an autoattack%s.",
- triggerLabel->second));
- else if (xmlStrEqual(effectChild->name, BAD_CAST "consumes"))
- effect.push_back(strprintf("This will be consumed%s.",
- triggerLabel->second));
- else if (xmlStrEqual(effectChild->name, BAD_CAST "label"))
- effect.push_back(
- (const char*)effectChild->xmlChildrenNode->content);
+ effect.push_back(
+ strprintf(strprintf(
+ duration ?
+ strprintf("%%s%%s. This effect lasts %d ticks.", duration).c_str()
+ : "%s%s.", it->mFormat.c_str(), triggerLabel->second).c_str(), value));
}
+ else if (xmlStrEqual(effectChild->name, BAD_CAST "modifier"))
+ effect.push_back(strprintf("Provides an autoattack%s.",
+ triggerLabel->second));
+ else if (xmlStrEqual(effectChild->name, BAD_CAST "consumes"))
+ effect.push_back(strprintf("This will be consumed%s.",
+ triggerLabel->second));
+ else if (xmlStrEqual(effectChild->name, BAD_CAST "label"))
+ effect.push_back(
+ (const char*)effectChild->xmlChildrenNode->content);
}
+ }
- // FIXME: Load hair styles through the races.xml file
- if (itemInfo->mType == ITEM_SPRITE_HAIR)
- hairDB.addHairStyle(itemInfo->mId);
+ // FIXME: Load hair styles through the races.xml file
+ if (itemInfo->mType == ITEM_SPRITE_HAIR)
+ hairDB.addHairStyle(itemInfo->mId);
- // Set Item Type based on subnodes info
- // TODO: Improve it once the itemTypes are loaded through xml
- itemInfo->mType = ITEM_UNUSABLE;
- if (itemInfo->mActivatable)
- itemInfo->mType = ITEM_USABLE;
- else if (itemInfo->mEquippable)
- itemInfo->mType = ITEM_EQUIPMENT_TORSO;
- } // end for_each_xml_child_node(itemChild, node)
+ // Set Item Type based on subnodes info
+ // TODO: Improve it once the itemTypes are loaded through xml
+ itemInfo->mType = ITEM_UNUSABLE;
+ if (itemInfo->mActivatable)
+ itemInfo->mType = ITEM_USABLE;
+ else if (itemInfo->mEquippable)
+ itemInfo->mType = ITEM_EQUIPMENT_TORSO;
+ } // end for_each_xml_child_node(itemChild, node)
- itemInfo->mEffect = effect;
+ itemInfo->mEffect = effect;
- checkItemInfo(itemInfo);
+ checkItemInfo(itemInfo);
- addItem(itemInfo);
- }
+ addItem(itemInfo);
+}
+void ManaServItemDB::checkStatus()
+{
mLoaded = true;
}
diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h
index d7859ad3..2f19339d 100644
--- a/src/resources/itemdb.h
+++ b/src/resources/itemdb.h
@@ -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/settingsmanager.cpp b/src/resources/settingsmanager.cpp
index 3cbb115c..b2d1fe80 100644
--- a/src/resources/settingsmanager.cpp
+++ b/src/resources/settingsmanager.cpp
@@ -21,8 +21,9 @@
#include "resources/settingsmanager.h"
#include "resources/attributes.h"
-#include "resources/monsterdb.h"
#include "resources/hairdb.h"
+#include "resources/itemdb.h"
+#include "resources/monsterdb.h"
#include "resources/specialdb.h"
#include "resources/npcdb.h"
#include "resources/emotedb.h"
@@ -48,6 +49,7 @@ namespace SettingsManager
// initialize managers
Attributes::init();
hairDB.init();
+ itemDb->init();
MonsterDB::init();
SpecialDB::init();
NPCDB::init();
@@ -60,6 +62,7 @@ namespace SettingsManager
Attributes::checkStatus();
hairDB.checkStatus();
+ itemDb->checkStatus();
MonsterDB::checkStatus();
SpecialDB::checkStatus();
NPCDB::checkStatus();
@@ -80,6 +83,7 @@ namespace SettingsManager
NPCDB::unload();
SpecialDB::unload();
MonsterDB::unload();
+ itemDb->unload();
hairDB.unload();
Attributes::unload();
}
@@ -149,6 +153,10 @@ namespace SettingsManager
{
hairDB.readHairColorNode(childNode, filename);
}
+ else if (xmlStrEqual(childNode->name, BAD_CAST "item"))
+ {
+ itemDb->readItemNode(childNode, filename);
+ }
else if (xmlStrEqual(childNode->name, BAD_CAST "monster"))
{
MonsterDB::readMonsterNode(childNode, filename);