summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-08-26 01:07:04 +0200
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-08-26 01:07:04 +0200
commit0f520050cf42cd20a2845e8900249f3e965db4fd (patch)
tree8de89137671ace1826552345ec590379dd40bde7 /src
parent37dc13f9a2375c7d6ecccf25f63c607b5bb15928 (diff)
downloadmanaserv-0f520050cf42cd20a2845e8900249f3e965db4fd.tar.gz
manaserv-0f520050cf42cd20a2845e8900249f3e965db4fd.tar.bz2
manaserv-0f520050cf42cd20a2845e8900249f3e965db4fd.tar.xz
manaserv-0f520050cf42cd20a2845e8900249f3e965db4fd.zip
Rewrote the skill manager the same way as the item manager.
This will permit better handling of both skills names and id. This is needed to start reworking on the auto-attack system.
Diffstat (limited to 'src')
-rw-r--r--src/game-server/main-game.cpp4
-rw-r--r--src/game-server/skillmanager.cpp241
-rw-r--r--src/game-server/skillmanager.h55
3 files changed, 169 insertions, 131 deletions
diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp
index 0b786555..6b4ae8fa 100644
--- a/src/game-server/main-game.cpp
+++ b/src/game-server/main-game.cpp
@@ -88,6 +88,7 @@ utils::StringFilter *stringFilter; /**< Slang's Filter */
AttributeManager *attributeManager = new AttributeManager(DEFAULT_ATTRIBUTEDB_FILE);
ItemManager *itemManager = new ItemManager(DEFAULT_ITEMSDB_FILE, DEFAULT_EQUIPDB_FILE);
MonsterManager *monsterManager = new MonsterManager(DEFAULT_MONSTERSDB_FILE);
+SkillManager *skillManager = new SkillManager(DEFAULT_SKILLSDB_FILE);
/** Core game message handler */
GameHandler *gameHandler;
@@ -193,7 +194,7 @@ static void initializeServer()
exit(EXIT_MAP_FILE_NOT_FOUND);
}
attributeManager->initialize();
- SkillManager::initialize(DEFAULT_SKILLSDB_FILE);
+ skillManager->initialize();
itemManager->initialize();
monsterManager->initialize();
StatusManager::initialize(DEFAULT_STATUSDB_FILE);
@@ -250,6 +251,7 @@ static void deinitializeServer()
delete stringFilter;
monsterManager->deinitialize();
itemManager->deinitialize();
+ delete skillManager; skillManager = 0;
MapManager::deinitialize();
StatusManager::deinitialize();
diff --git a/src/game-server/skillmanager.cpp b/src/game-server/skillmanager.cpp
index 75f5f53c..66d9b939 100644
--- a/src/game-server/skillmanager.cpp
+++ b/src/game-server/skillmanager.cpp
@@ -20,174 +20,169 @@
#include "game-server/skillmanager.h"
-#include "utils/string.h" // for the toUpper function
#include "utils/logger.h"
-#include "utils/xml.h"
#include <map>
-typedef std::map< std::string, int > SkillMap;
-static SkillMap skillMap;
-static std::string skillReferenceFile;
-static std::string defaultSkillKey = std::string();
-
-void SkillManager::initialize(const std::string &file)
+void SkillManager::clear()
{
- skillReferenceFile = file;
- reload();
+ for (SkillsInfo::iterator it = mSkillsInfo.begin(),
+ it_end = mSkillsInfo.end(); it != it_end; ++it)
+ {
+ delete it->second;
+ }
+
+ mSkillsInfo.clear();
+ mNamedSkillsInfo.clear();
}
-void SkillManager::reload()
+void SkillManager::initialize()
{
- /*
- skillMap["UNARMED"] = 100;
- skillMap["KNIFE"] = 101;
- */
+ clear();
- XML::Document doc(skillReferenceFile);
+ XML::Document doc(mSkillFile);
xmlNodePtr rootNode = doc.rootNode();
if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skills"))
{
- LOG_ERROR("Skill Manager: " << skillReferenceFile
+ LOG_ERROR("Skill Manager: " << mSkillFile
<< " is not a valid database file!");
return;
}
- LOG_INFO("Loading skill reference: " << skillReferenceFile);
+ LOG_INFO("Loading skill reference: " << mSkillFile);
- for_each_xml_child_node(setnode, rootNode)
+ for_each_xml_child_node(setNode, rootNode)
{
- if (!xmlStrEqual(setnode->name, BAD_CAST "set"))
+ // The server will prefix the core name with the set, so we need one.
+ if (!xmlStrEqual(setNode->name, BAD_CAST "set"))
continue;
- // we don't care about sets server-sided (yet?)
- for_each_xml_child_node(skillnode, setnode)
+ std::string setName = XML::getProperty(setNode, "name", std::string());
+ if (setName.empty())
{
- if (xmlStrEqual(skillnode->name, BAD_CAST "skill"))
- {
- std::string name = XML::getProperty(skillnode, "name",
- std::string());
- name = utils::toUpper(name);
- int id = XML::getProperty(skillnode, "id", 0);
- if (id > 0 && !name.empty())
- {
- bool duplicateKey = false;
- for (SkillMap::iterator i = skillMap.begin();
- i != skillMap.end(); i++)
- {
- if (id == i->second)
- {
- LOG_ERROR("SkillManager: The same id: " << id
- << " is given for skill names: " << i->first
- << " and " << name);
- LOG_ERROR("The skill reference: " << "'" << name
- << "': " << id << " will be ignored.");
-
- duplicateKey = true;
- break;
- }
- }
-
- if (!duplicateKey)
- {
- if (XML::getBoolProperty(skillnode, "default", false))
- {
- if (!defaultSkillKey.empty())
- {
- LOG_WARN("SkillManager: "
- "Default Skill Key already defined as "
- << defaultSkillKey
- << ". Redefinit it as: " << name);
- }
- else
- {
- LOG_INFO("SkillManager: Defining " << name
- << " as default weapon-type key.");
- }
- defaultSkillKey = name;
- }
- skillMap[name] = id;
- }
- }
- }
+ LOG_WARN("The " << mSkillFile << " file is containing unamed <set> "
+ "tags and will be ignored.");
+ continue;
}
+
+ setName = utils::toLower(setName);
+
+ for_each_xml_child_node(skillNode, setNode)
+ readSkillNode(skillNode, setName);
}
- if (::utils::Logger::mVerbosity >= ::utils::Logger::Debug)
+ printDebugSkillTable();
+
+ if (!mDefaultSkillId)
+ LOG_WARN("SkillManager: No default weapon-type id was given during "
+ "Skill map loading. "
+ "Players won't be able to earn XP when unarmed.");
+
+ LOG_INFO("Loaded " << mSkillsInfo.size() << " skills from "
+ << mSkillFile);
+}
+
+void SkillManager::readSkillNode(xmlNodePtr skillNode,
+ const std::string& setName)
+{
+ if (!xmlStrEqual(skillNode->name, BAD_CAST "skill"))
+ return;
+
+ SkillInfo *skillInfo = new SkillInfo;
+ skillInfo->setName = setName;
+ skillInfo->skillName = XML::getProperty(skillNode, "name", std::string());
+ skillInfo->skillName = utils::toLower(skillInfo->skillName);
+ int id = XML::getProperty(skillNode, "id", 0);
+
+ if (id <= 0 || skillInfo->skillName.empty())
{
- LOG_DEBUG("Skill map in " << skillReferenceFile << ":"
- << std::endl << "-----");
- for (SkillMap::iterator i = skillMap.begin(); i != skillMap.end(); i++)
+ LOG_WARN("Invalid skill (empty name or id <= 0) in set: " << setName);
+ return;
+ }
+ skillInfo->id = (unsigned)id;
+
+ SkillsInfo::iterator it = mSkillsInfo.find(skillInfo->id);
+ if (it != mSkillsInfo.end())
+ {
+ LOG_WARN("SkillManager: The same id: " << skillInfo->id
+ << " is given for skill names: " << it->first
+ << " and " << skillInfo->skillName);
+ LOG_WARN("The skill reference: " << skillInfo->id
+ << ": '" << skillInfo->skillName << "' will be ignored.");
+ return;
+ }
+
+ if (XML::getBoolProperty(skillNode, "default", false))
+ {
+ if (mDefaultSkillId)
{
- if (!defaultSkillKey.compare(i->first))
- {
- LOG_DEBUG("'" << i->first << "': " << i->second
- << " (Default)");
- }
- else
- {
- LOG_DEBUG("'" << i->first << "': " << i->second);
- }
+ LOG_WARN("SkillManager: "
+ "Default Skill id already defined as "
+ << mDefaultSkillId
+ << ". Redefinit it as: " << skillInfo->id);
}
- LOG_DEBUG("-----");
+ else
+ {
+ LOG_INFO("SkillManager: Defining skill id: " << skillInfo->id
+ << " as default weapon-type id.");
+ }
+ mDefaultSkillId = skillInfo->id;
}
- if (defaultSkillKey.empty())
- LOG_WARN("SkillManager: No default weapon-type id was given during "
- "Skill map loading. Defaults will fall back to id 0.");
+ mSkillsInfo.insert(
+ std::make_pair<unsigned int, SkillInfo*>(skillInfo->id, skillInfo));
- LOG_INFO("Loaded " << skillMap.size() << " skill references from "
- << skillReferenceFile);
+ std::string keyName = setName + "_" + skillInfo->skillName;
+ mNamedSkillsInfo.insert(keyName, skillInfo);
}
-int SkillManager::getIdFromString(const std::string &name)
+void SkillManager::printDebugSkillTable()
{
- // Check if the name is an integer value.
- if (utils::isNumeric(name))
+ if (::utils::Logger::mVerbosity >= ::utils::Logger::Debug)
{
- int val = 0;
- val = utils::stringToInt(name);
- if (val)
+ std::string lastSet;
+ LOG_DEBUG("Skill map in " << mSkillFile << ":"
+ << std::endl << "-----");
+ for (SkillsInfo::iterator it = mSkillsInfo.begin();
+ it != mSkillsInfo.end(); ++it)
{
- for (SkillMap::iterator i = skillMap.begin(); i != skillMap.end(); i++)
+ if (!lastSet.compare(it->second->setName))
{
- if (i->second == val)
- return val;
+ lastSet = it->second->setName;
+ LOG_DEBUG("Skill set: " << lastSet);
}
- LOG_WARN("SkillManager::getIdFromString(): Numeric weapon-type id "
- << val << " not found into " << skillReferenceFile);
- SkillMap::iterator i = skillMap.find(defaultSkillKey);
- if (i != skillMap.end())
+ if (it->first == mDefaultSkillId)
{
- LOG_WARN("Id defaulted to " << defaultSkillKey << ": "
- << i->second);
- return i->second;
+ LOG_DEBUG("'" << it->first << "': " << it->second->skillName
+ << " (Default)");
}
else
{
- LOG_WARN("Id defaulted to 0.");
- return 0;
+ LOG_DEBUG("'" << it->first << "': " << it->second->skillName);
}
}
- else
- {
- LOG_WARN("SkillManager: Invalid skill id " << name);
- return 0;
- }
+ LOG_DEBUG("-----");
}
+}
- // Convert to upper case for easier finding
- SkillMap::iterator i = skillMap.find(utils::toUpper(name));
- if (i == skillMap.end())
- {
- LOG_WARN("SkillManager: No weapon-type name corresponding to "
- << utils::toUpper(name) << " into " << skillReferenceFile);
- return 0;
- }
- else
- {
- return i->second;
- }
+unsigned int SkillManager::getId(const std::string& set,
+ const std::string &name) const
+{
+ std::string key = utils::toLower(set) + "_" + utils::toLower(name);
+ SkillInfo *skillInfo = mNamedSkillsInfo.find(key);
+ return skillInfo ? skillInfo->id : 0;
+}
+
+const std::string SkillManager::getSkillName(unsigned int id) const
+{
+ SkillsInfo::const_iterator it = mSkillsInfo.find(id);
+ return it != mSkillsInfo.end() ? it->second->skillName : "";
+}
+
+const std::string SkillManager::getSetName(unsigned int id) const
+{
+ SkillsInfo::const_iterator it = mSkillsInfo.find(id);
+ return it != mSkillsInfo.end() ? it->second->setName : "";
}
diff --git a/src/game-server/skillmanager.h b/src/game-server/skillmanager.h
index c6a73a5c..1912e2fc 100644
--- a/src/game-server/skillmanager.h
+++ b/src/game-server/skillmanager.h
@@ -22,14 +22,24 @@
#ifndef SKILLMANAGER_H
#define SKILLMANAGER_H
-#include <string>
+#include "utils/string.h"
+#include "utils/xml.h"
-namespace SkillManager
+class SkillManager
{
+ public:
+ SkillManager(const std::string & skillFile):
+ mSkillFile(skillFile),
+ mDefaultSkillId(0)
+ {}
+
+ ~SkillManager()
+ { clear(); }
+
/**
* Loads skill reference file.
*/
- void initialize(const std::string &);
+ void initialize();
/**
* Reloads skill reference file.
@@ -37,12 +47,43 @@ namespace SkillManager
void reload();
/**
- * Gets the skill ID of a skill string
- * (not case-sensitive to reduce wall-bashing)
+ * Gets the skill Id from a set and a skill string.
*/
- int getIdFromString(const std::string &name);
-}
+ unsigned int getId(const std::string& set, const std::string &name) const;
+ const std::string getSkillName(unsigned int id) const;
+ const std::string getSetName(unsigned int id) const;
+
+ private:
+ struct SkillInfo {
+ SkillInfo():
+ id(0)
+ {}
+
+ unsigned int id;
+ std::string setName;
+ std::string skillName;
+ };
+
+ /*
+ * Clears up the skill maps.
+ */
+ void clear();
+
+ void readSkillNode(xmlNodePtr skillNode, const std::string& setName);
+
+ void printDebugSkillTable();
+
+ // The skill file (skills.xml)
+ std::string mSkillFile;
+ // The skill map
+ typedef std::map<unsigned int, SkillInfo*> SkillsInfo;
+ SkillsInfo mSkillsInfo;
+ // A map used to get skills per name.
+ utils::NameMap<SkillInfo*> mNamedSkillsInfo;
+ // The default skill id
+ unsigned int mDefaultSkillId;
+};
#endif // SKILLMANAGER_H