summaryrefslogtreecommitdiff
path: root/src/game-server
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2011-03-19 15:10:17 +0100
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2011-03-20 15:13:01 +0100
commit4059cb4fa545dda8b035a1033f5fefb99e978682 (patch)
tree37e526f9f80cbb9dda55ab19ae6d076c51c957da /src/game-server
parent318cb3a18ac4aa906b18ffd170bf0b1033c62d33 (diff)
downloadmanaserv-4059cb4fa545dda8b035a1033f5fefb99e978682.tar.gz
manaserv-4059cb4fa545dda8b035a1033f5fefb99e978682.tar.bz2
manaserv-4059cb4fa545dda8b035a1033f5fefb99e978682.tar.xz
manaserv-4059cb4fa545dda8b035a1033f5fefb99e978682.zip
Introduced separate functions for item database loading
This splits the huge ItemManager::reload() into readEquipSlotsFile() and readItemsFile(), the latter of which is further split up into multiple functions for reading the different elements. Just to keep the amount of nesting down and increase the readability. Removes the need for huge eye-catching comment blocks. Reviewed-by: Freeyorp
Diffstat (limited to 'src/game-server')
-rw-r--r--src/game-server/item.h8
-rw-r--r--src/game-server/itemmanager.cpp601
-rw-r--r--src/game-server/itemmanager.h27
3 files changed, 337 insertions, 299 deletions
diff --git a/src/game-server/item.h b/src/game-server/item.h
index f03e951a..d779e1f0 100644
--- a/src/game-server/item.h
+++ b/src/game-server/item.h
@@ -212,7 +212,6 @@ class ItemClass
private:
-
/**
* Add an effect to a trigger
* @param effect The effect to be run when the trigger is hit.
@@ -267,9 +266,8 @@ class ItemClass
};
/**
-* Class for an item stack laying on the floor in the game world
-*/
-
+ * Class for an item stack laying on the floor in the game world
+ */
class Item : public Actor
{
public:
@@ -289,4 +287,4 @@ class Item : public Actor
int mLifetime;
};
-#endif
+#endif // ITEM_H
diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp
index 3e7c673a..3aa98b55 100644
--- a/src/game-server/itemmanager.cpp
+++ b/src/game-server/itemmanager.cpp
@@ -28,7 +28,6 @@
#include "scripting/script.h"
#include "utils/logger.h"
#include "utils/string.h"
-#include "utils/xml.h"
#include <map>
#include <set>
@@ -36,300 +35,20 @@
void ItemManager::initialize()
{
- mVisibleEquipSlotCount = 0;
reload();
}
void ItemManager::reload()
{
- std::string absPathFile;
- xmlNodePtr rootNode;
-
- // ####################################################################
- // ### Load the equip slots that a character has available to them. ###
- // ####################################################################
-
- absPathFile = ResourceManager::resolve(mEquipCharSlotReferenceFile);
- if (absPathFile.empty()) {
- LOG_ERROR("Item Manager: Could not find " << mEquipCharSlotReferenceFile << "!");
- return;
- }
-
- XML::Document doc(absPathFile, false);
- rootNode = doc.rootNode();
-
- if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "equip-slots"))
- {
- LOG_ERROR("Item Manager: Error while parsing equip slots database ("
- << absPathFile << ")!");
- return;
- }
-
- LOG_INFO("Loading equip slots: " << absPathFile);
-
- {
- unsigned int totalCount = 0, slotCount = 0, visibleSlotCount = 0;
- for_each_xml_child_node(node, rootNode)
- {
- if (xmlStrEqual(node->name, BAD_CAST "slot"))
- {
- const std::string name = XML::getProperty(node, "name",
- std::string());
- const int count = XML::getProperty(node, "count", 0);
- if (name.empty() || !count || count < 0)
- LOG_WARN("Item Manager: equip slot has no name or zero count");
- else
- {
- bool visible = XML::getProperty(node, "visible", "false") != "false";
- if (visible)
- {
- visibleEquipSlots.push_back(equipSlots.size());
- if (++visibleSlotCount > 7)
- LOG_WARN("Item Manager: More than 7 visible equip slot!"
- "This will not work with current netcode!");
- }
- equipSlots.push_back(std::pair<std::string, unsigned int>
- (name, count));
- totalCount += count;
- ++slotCount;
- }
- }
- }
- LOG_INFO("Loaded '" << slotCount << "' slot types with '"
- << totalCount << "' slots.");
- }
-
- // ####################################
- // ### Load the main item database. ###
- // ####################################
-
- absPathFile = ResourceManager::resolve(mItemReferenceFile);
- if (absPathFile.empty()) {
- LOG_ERROR("Item Manager: Could not find " << mItemReferenceFile << "!");
- return;
- }
-
- XML::Document doc2(absPathFile, false);
- rootNode = doc2.rootNode();
-
- if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items"))
- {
- LOG_ERROR("Item Manager: Error while parsing item database ("
- << absPathFile << ")!");
- return;
- }
-
- LOG_INFO("Loading item reference: " << absPathFile);
-
- unsigned nbItems = 0;
- for_each_xml_child_node(node, rootNode)
- {
- if (!xmlStrEqual(node->name, BAD_CAST "item"))
- continue;
-
- int id = XML::getProperty(node, "id", 0);
- if (id < 1)
- {
- LOG_WARN("Item Manager: Item ID: " << id << " is invalid in "
- << mItemReferenceFile << ", and will be ignored.");
- continue;
- }
-
-
- // Type is mostly unused, but still serves for
- // hairsheets and race sheets.
- std::string sItemType = XML::getProperty(node, "type", std::string());
- if (sItemType == "hairsprite" || sItemType == "racesprite")
- continue;
-
- ItemClass *item;
- ItemClasses::iterator i = itemClasses.find(id);
-
- unsigned int maxPerSlot = XML::getProperty(node, "max-per-slot", 0);
- if (!maxPerSlot)
- {
- LOG_WARN("Item Manager: Missing max-per-slot property for "
- "item " << id << " in " << mItemReferenceFile << '.');
- maxPerSlot = 1;
- }
-
- if (i == itemClasses.end())
- {
- item = new ItemClass(id, maxPerSlot);
- itemClasses[id] = item;
- }
- else
- {
- LOG_WARN("Multiple defintions of item '" << id << "'!");
- item = i->second;
- }
-
- std::string name = XML::getProperty(node, "name", "unnamed");
- item->setName(name);
-
- int value = XML::getProperty(node, "value", 0);
- // Should have multiple value definitions for multiple currencies?
- item->mCost = value;
-
- for_each_xml_child_node(subnode, node)
- {
- if (xmlStrEqual(subnode->name, BAD_CAST "equip"))
- {
- ItemEquipInfo req;
- for_each_xml_child_node(equipnode, subnode)
- if (xmlStrEqual(equipnode->name, BAD_CAST "slot"))
- {
- std::string slot = XML::getProperty(equipnode, "type",
- std::string());
- if (slot.empty())
- {
- LOG_WARN("Item Manager: empty equip slot definition!");
- continue;
- }
- req.push_back(std::make_pair(getEquipIdFromName(slot),
- XML::getProperty(equipnode, "required",
- 1)));
- }
- if (req.empty())
- {
- LOG_WARN("Item Manager: empty equip requirement "
- "definition for item " << id << "!");
- continue;
- }
- item->mEquip.push_back(req);
- }
- else if (xmlStrEqual(subnode->name, BAD_CAST "effect"))
- {
- std::pair< ItemTriggerType, ItemTriggerType> triggerTypes;
- {
- const std::string triggerName = XML::getProperty(
- subnode, "trigger", std::string());
- const std::string dispellTrigger = XML::getProperty(
- subnode, "dispell", std::string());
- // label -> { trigger (apply), trigger (cancel (default)) }
- // The latter can be overridden.
- static std::map<const std::string,
- std::pair<ItemTriggerType, ItemTriggerType> >
- triggerTable;
- if (triggerTable.empty())
- {
- /*
- * The following is a table of all triggers for item
- * effects.
- * The first element defines the trigger used for this
- * trigger, and the second defines the default
- * trigger to use for dispelling.
- */
- triggerTable["existence"].first = ITT_IN_INVY;
- triggerTable["existence"].second = ITT_LEAVE_INVY;
- triggerTable["activation"].first = ITT_ACTIVATE;
- triggerTable["activation"].second = ITT_NULL;
- triggerTable["equip"].first = ITT_EQUIP;
- triggerTable["equip"].second = ITT_UNEQUIP;
- triggerTable["leave-inventory"].first = ITT_LEAVE_INVY;
- triggerTable["leave-inventory"].second = ITT_NULL;
- triggerTable["unequip"].first = ITT_UNEQUIP;
- triggerTable["unequip"].second = ITT_NULL;
- triggerTable["equip-change"].first = ITT_EQUIPCHG;
- triggerTable["equip-change"].second = ITT_NULL;
- triggerTable["null"].first = ITT_NULL;
- triggerTable["null"].second = ITT_NULL;
- }
- std::map<const std::string, std::pair<ItemTriggerType,
- ItemTriggerType> >::iterator
- it = triggerTable.find(triggerName);
-
- if (it == triggerTable.end()) {
- LOG_WARN("Item Manager: Unable to find effect trigger type \""
- << triggerName << "\", skipping!");
- continue;
- }
- triggerTypes = it->second;
- if (!dispellTrigger.empty())
- {
- if ((it = triggerTable.find(dispellTrigger))
- == triggerTable.end())
- LOG_WARN("Item Manager: Unable to find dispell effect "
- "trigger type \"" << dispellTrigger << "\"!");
- else
- triggerTypes.second = it->second.first;
- }
- }
- for_each_xml_child_node(effectnode, subnode)
- {
- if (xmlStrEqual(effectnode->name, BAD_CAST "modifier"))
- {
- std::string tag = XML::getProperty(effectnode, "attribute", std::string());
- if (tag.empty())
- {
- LOG_WARN("Item Manager: Warning, modifier found "
- "but no attribute specified!");
- continue;
- }
- unsigned int duration = XML::getProperty(effectnode,
- "duration",
- 0);
- ModifierLocation location = attributeManager->getLocation(tag);
- double value = XML::getFloatProperty(effectnode, "value", 0.0);
- item->addEffect(new ItemEffectAttrMod(location.attributeId,
- location.layer,
- value, id,
- duration),
- triggerTypes.first, triggerTypes.second);
- }
- else if (xmlStrEqual(effectnode->name, BAD_CAST "autoattack"))
- {
- // TODO - URGENT
- }
- // Having a dispell for the next three is nonsensical.
- else if (xmlStrEqual(effectnode->name, BAD_CAST "cooldown"))
- {
- LOG_WARN("Item Manager: Cooldown property not implemented yet!");
- // TODO: Also needs unique items before this action will work
- }
- else if (xmlStrEqual(effectnode->name, BAD_CAST "g-cooldown"))
- {
- LOG_WARN("Item Manager: G-Cooldown property not implemented yet!");
- // TODO
- }
- else if (xmlStrEqual(effectnode->name, BAD_CAST "consumes"))
- item->addEffect(new ItemEffectConsumes(), triggerTypes.first);
- else if (xmlStrEqual(effectnode->name, BAD_CAST "script"))
- {
- std::string src = XML::getProperty(effectnode, "src", std::string());
- if (src.empty())
- {
- LOG_WARN("Item Manager: Empty src definition for script effect, skipping!");
- continue;
- }
- std::string func = XML::getProperty(effectnode, "function", std::string());
- if (func.empty())
- {
- LOG_WARN ("Item Manager: Empty func definition for script effect, skipping!");
- continue;
- }
- for_each_xml_child_node(scriptnode, effectnode)
- {
- // TODO: Load variables from variable subnodes
- }
- std::string dfunc = XML::getProperty(effectnode, "dispell-function", std::string());
- // STUB
- item->addEffect(new ItemEffectScript(), triggerTypes.first, triggerTypes.second);
- }
- }
- }
- // More properties go here
- }
- ++nbItems;
- }
-
- LOG_INFO("Loaded " << nbItems << " items from "
- << absPathFile << ".");
+ mVisibleEquipSlotCount = 0;
+ readEquipSlotsFile();
+ readItemsFile();
}
void ItemManager::deinitialize()
{
- for (ItemClasses::iterator i = itemClasses.begin(), i_end = itemClasses.end(); i != i_end; ++i)
+ for (ItemClasses::iterator i = itemClasses.begin(),
+ i_end = itemClasses.end(); i != i_end; ++i)
{
delete i->second;
}
@@ -339,7 +58,7 @@ void ItemManager::deinitialize()
ItemClass *ItemManager::getItem(int itemId) const
{
ItemClasses::const_iterator i = itemClasses.find(itemId);
- return i != itemClasses.end() ? i->second : NULL;
+ return i != itemClasses.end() ? i->second : 0;
}
ItemClass *ItemManager::getItemByName(std::string name) const
@@ -348,7 +67,7 @@ ItemClass *ItemManager::getItemByName(std::string name) const
for (ItemClasses::const_iterator i = itemClasses.begin(),
i_end = itemClasses.end(); i != i_end; ++i)
{
- if(utils::toLower(i->second->getName()) == name)
+ if (utils::toLower(i->second->getName()) == name)
{
return i->second;
}
@@ -384,11 +103,15 @@ unsigned int ItemManager::getMaxSlotsFromId(unsigned int id) const
unsigned int ItemManager::getVisibleSlotCount() const
{
if (!mVisibleEquipSlotCount)
+ {
for (VisibleEquipSlots::const_iterator it = visibleEquipSlots.begin(),
it_end = visibleEquipSlots.end();
it != it_end;
++it)
+ {
mVisibleEquipSlotCount += equipSlots.at(*it).second;
+ }
+ }
return mVisibleEquipSlotCount;
}
@@ -398,7 +121,309 @@ bool ItemManager::isEquipSlotVisible(unsigned int id) const
it_end = visibleEquipSlots.end();
it != it_end;
++it)
+ {
if (*it == id)
return true;
+ }
return false;
}
+
+void ItemManager::readEquipSlotsFile()
+{
+ std::string absPathFile = ResourceManager::resolve(mEquipSlotsFile);
+ if (absPathFile.empty()) {
+ LOG_ERROR("Item Manager: Could not find " << mEquipSlotsFile << "!");
+ return;
+ }
+
+ XML::Document doc(absPathFile, false);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "equip-slots"))
+ {
+ LOG_ERROR("Item Manager: Error while parsing equip slots database ("
+ << absPathFile << ")!");
+ return;
+ }
+
+ LOG_INFO("Loading equip slots: " << absPathFile);
+
+ unsigned totalCount = 0;
+ unsigned slotCount = 0;
+ unsigned visibleSlotCount = 0;
+
+ for_each_xml_child_node(node, rootNode)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "slot"))
+ {
+ const std::string name = XML::getProperty(node, "name",
+ std::string());
+ const int count = XML::getProperty(node, "count", 0);
+
+ if (name.empty() || count <= 0)
+ {
+ LOG_WARN("Item Manager: equip slot has no name or zero count");
+ }
+ else
+ {
+ bool visible = XML::getProperty(node, "visible", "false") != "false";
+ if (visible)
+ {
+ visibleEquipSlots.push_back(equipSlots.size());
+ if (++visibleSlotCount > 7)
+ LOG_WARN("Item Manager: More than 7 visible equip slot!"
+ "This will not work with current netcode!");
+ }
+ equipSlots.push_back(std::pair<std::string, unsigned int>
+ (name, count));
+ totalCount += count;
+ ++slotCount;
+ }
+ }
+ }
+
+ LOG_INFO("Loaded '" << slotCount << "' slot types with '"
+ << totalCount << "' slots.");
+}
+
+void ItemManager::readItemsFile()
+{
+ std::string absPathFile = ResourceManager::resolve(mItemsFile);
+ if (absPathFile.empty())
+ {
+ LOG_ERROR("Item Manager: Could not find " << mItemsFile << "!");
+ return;
+ }
+
+ XML::Document doc2(absPathFile, false);
+ xmlNodePtr rootNode = doc2.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "items"))
+ {
+ LOG_ERROR("Item Manager: Error while parsing item database ("
+ << absPathFile << ")!");
+ return;
+ }
+
+ LOG_INFO("Loading item reference: " << absPathFile);
+
+ for_each_xml_child_node(node, rootNode)
+ {
+ if (xmlStrEqual(node->name, BAD_CAST "item"))
+ {
+ readItemNode(node);
+ }
+ }
+
+ LOG_INFO("Loaded " << itemClasses.size() << " items from "
+ << absPathFile << ".");
+}
+
+void ItemManager::readItemNode(xmlNodePtr itemNode)
+{
+ const int id = XML::getProperty(itemNode, "id", 0);
+ if (id < 1)
+ {
+ LOG_WARN("Item Manager: Item ID: " << id << " is invalid in "
+ << mItemsFile << ", and will be ignored.");
+ return;
+ }
+
+ // Type is mostly unused, but still serves for
+ // hairsheets and race sheets.
+ std::string sItemType = XML::getProperty(itemNode, "type", std::string());
+ if (sItemType == "hairsprite" || sItemType == "racesprite")
+ return;
+
+ ItemClass *item;
+ ItemClasses::iterator i = itemClasses.find(id);
+
+ unsigned int maxPerSlot = XML::getProperty(itemNode, "max-per-slot", 0);
+ if (!maxPerSlot)
+ {
+ LOG_WARN("Item Manager: Missing max-per-slot property for "
+ "item " << id << " in " << mItemsFile << '.');
+ maxPerSlot = 1;
+ }
+
+ if (i == itemClasses.end())
+ {
+ item = new ItemClass(id, maxPerSlot);
+ itemClasses[id] = item;
+ }
+ else
+ {
+ LOG_WARN("Multiple defintions of item '" << id << "'!");
+ item = i->second;
+ }
+
+ std::string name = XML::getProperty(itemNode, "name", "unnamed");
+ item->setName(name);
+
+ int value = XML::getProperty(itemNode, "value", 0);
+ // Should have multiple value definitions for multiple currencies?
+ item->mCost = value;
+
+ for_each_xml_child_node(subNode, itemNode)
+ {
+ if (xmlStrEqual(subNode->name, BAD_CAST "equip"))
+ {
+ readEquipNode(subNode, item);
+ }
+ else if (xmlStrEqual(subNode->name, BAD_CAST "effect"))
+ {
+ readEffectNode(subNode, item);
+ }
+ // More properties go here
+ }
+}
+
+void ItemManager::readEquipNode(xmlNodePtr equipNode, ItemClass *item)
+{
+ ItemEquipInfo req;
+ for_each_xml_child_node(subNode, equipNode)
+ {
+ if (xmlStrEqual(subNode->name, BAD_CAST "slot"))
+ {
+ std::string slot = XML::getProperty(subNode, "type", std::string());
+ if (slot.empty())
+ {
+ LOG_WARN("Item Manager: empty equip slot definition!");
+ continue;
+ }
+ req.push_back(std::make_pair(getEquipIdFromName(slot),
+ XML::getProperty(subNode, "required", 1)));
+ }
+ }
+ if (req.empty())
+ {
+ LOG_WARN("Item Manager: empty equip requirement "
+ "definition for item " << item->getDatabaseID() << "!");
+ return;
+ }
+ item->mEquip.push_back(req);
+}
+
+void ItemManager::readEffectNode(xmlNodePtr effectNode, ItemClass *item)
+{
+ std::pair<ItemTriggerType, ItemTriggerType> triggerTypes;
+ {
+ const std::string triggerName = XML::getProperty(
+ effectNode, "trigger", std::string());
+ const std::string dispellTrigger = XML::getProperty(
+ effectNode, "dispell", std::string());
+ // label -> { trigger (apply), trigger (cancel (default)) }
+ // The latter can be overridden.
+ static std::map<const std::string,
+ std::pair<ItemTriggerType, ItemTriggerType> >
+ triggerTable;
+ if (triggerTable.empty())
+ {
+ /*
+ * The following is a table of all triggers for item
+ * effects.
+ * The first element defines the trigger used for this
+ * trigger, and the second defines the default
+ * trigger to use for dispelling.
+ */
+ triggerTable["existence"].first = ITT_IN_INVY;
+ triggerTable["existence"].second = ITT_LEAVE_INVY;
+ triggerTable["activation"].first = ITT_ACTIVATE;
+ triggerTable["activation"].second = ITT_NULL;
+ triggerTable["equip"].first = ITT_EQUIP;
+ triggerTable["equip"].second = ITT_UNEQUIP;
+ triggerTable["leave-inventory"].first = ITT_LEAVE_INVY;
+ triggerTable["leave-inventory"].second = ITT_NULL;
+ triggerTable["unequip"].first = ITT_UNEQUIP;
+ triggerTable["unequip"].second = ITT_NULL;
+ triggerTable["equip-change"].first = ITT_EQUIPCHG;
+ triggerTable["equip-change"].second = ITT_NULL;
+ triggerTable["null"].first = ITT_NULL;
+ triggerTable["null"].second = ITT_NULL;
+ }
+ std::map<const std::string, std::pair<ItemTriggerType,
+ ItemTriggerType> >::iterator
+ it = triggerTable.find(triggerName);
+
+ if (it == triggerTable.end()) {
+ LOG_WARN("Item Manager: Unable to find effect trigger type \""
+ << triggerName << "\", skipping!");
+ return;
+ }
+ triggerTypes = it->second;
+ if (!dispellTrigger.empty())
+ {
+ if ((it = triggerTable.find(dispellTrigger)) == triggerTable.end())
+ LOG_WARN("Item Manager: Unable to find dispell effect "
+ "trigger type \"" << dispellTrigger << "\"!");
+ else
+ triggerTypes.second = it->second.first;
+ }
+ }
+
+ for_each_xml_child_node(subNode, effectNode)
+ {
+ if (xmlStrEqual(subNode->name, BAD_CAST "modifier"))
+ {
+ std::string tag = XML::getProperty(subNode, "attribute", std::string());
+ if (tag.empty())
+ {
+ LOG_WARN("Item Manager: Warning, modifier found "
+ "but no attribute specified!");
+ continue;
+ }
+ unsigned int duration = XML::getProperty(subNode,
+ "duration",
+ 0);
+ ModifierLocation location = attributeManager->getLocation(tag);
+ double value = XML::getFloatProperty(subNode, "value", 0.0);
+ item->addEffect(new ItemEffectAttrMod(location.attributeId,
+ location.layer,
+ value,
+ item->getDatabaseID(),
+ duration),
+ triggerTypes.first, triggerTypes.second);
+ }
+ else if (xmlStrEqual(subNode->name, BAD_CAST "autoattack"))
+ {
+ // TODO - URGENT
+ }
+ // Having a dispell for the next three is nonsensical.
+ else if (xmlStrEqual(subNode->name, BAD_CAST "cooldown"))
+ {
+ LOG_WARN("Item Manager: Cooldown property not implemented yet!");
+ // TODO: Also needs unique items before this action will work
+ }
+ else if (xmlStrEqual(subNode->name, BAD_CAST "g-cooldown"))
+ {
+ LOG_WARN("Item Manager: G-Cooldown property not implemented yet!");
+ // TODO
+ }
+ else if (xmlStrEqual(subNode->name, BAD_CAST "consumes"))
+ {
+ item->addEffect(new ItemEffectConsumes(), triggerTypes.first);
+ }
+ else if (xmlStrEqual(subNode->name, BAD_CAST "script"))
+ {
+ std::string src = XML::getProperty(subNode, "src", std::string());
+ if (src.empty())
+ {
+ LOG_WARN("Item Manager: Empty src definition for script effect, skipping!");
+ continue;
+ }
+ std::string func = XML::getProperty(subNode, "function", std::string());
+ if (func.empty())
+ {
+ LOG_WARN("Item Manager: Empty func definition for script effect, skipping!");
+ continue;
+ }
+ for_each_xml_child_node(scriptSubNode, subNode)
+ {
+ // TODO: Load variables from variable subnodes
+ }
+ std::string dfunc = XML::getProperty(subNode, "dispell-function", std::string());
+ // STUB
+ item->addEffect(new ItemEffectScript(), triggerTypes.first, triggerTypes.second);
+ }
+ }
+}
diff --git a/src/game-server/itemmanager.h b/src/game-server/itemmanager.h
index 00739785..c7033047 100644
--- a/src/game-server/itemmanager.h
+++ b/src/game-server/itemmanager.h
@@ -21,6 +21,8 @@
#ifndef ITEMMANAGER_H
#define ITEMMANAGER_H
+#include "utils/xml.h"
+
#include <string>
#include <map>
#include <vector>
@@ -31,9 +33,12 @@ class ItemManager
{
public:
ItemManager(const std::string &itemFile, const std::string &equipFile) :
- mItemReferenceFile(itemFile),
- mEquipCharSlotReferenceFile(equipFile),
- mItemDatabaseVersion(0) {}
+ mItemsFile(itemFile),
+ mEquipSlotsFile(equipFile),
+ mVisibleEquipSlotCount(0),
+ mItemDatabaseVersion(0)
+ {}
+
/**
* Loads item reference file.
*/
@@ -78,6 +83,15 @@ class ItemManager
bool isEquipSlotVisible(unsigned int id) const;
private:
+ /** Loads the equip slots that a character has available to them. */
+ void readEquipSlotsFile();
+
+ /** Loads the main item database. */
+ void readItemsFile();
+ void readItemNode(xmlNodePtr itemNode);
+ void readEquipNode(xmlNodePtr equipNode, ItemClass *item);
+ void readEffectNode(xmlNodePtr effectNode, ItemClass *item);
+
typedef std::map< int, ItemClass * > ItemClasses;
// Map a string (name of slot) with (str-id, max-per-equip-slot)
typedef std::vector< std::pair< std::string, unsigned int > > EquipSlots;
@@ -88,11 +102,12 @@ class ItemManager
EquipSlots equipSlots;
VisibleEquipSlots visibleEquipSlots;
- std::string mItemReferenceFile;
- std::string mEquipCharSlotReferenceFile;
+ std::string mItemsFile;
+ std::string mEquipSlotsFile;
mutable unsigned int mVisibleEquipSlotCount; // Cache
- unsigned int mItemDatabaseVersion; /**< Version of the loaded items database file.*/
+ /** Version of the loaded items database file.*/
+ unsigned int mItemDatabaseVersion;
};
extern ItemManager *itemManager;