diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game-server/main-game.cpp | 4 | ||||
-rw-r--r-- | src/game-server/skillmanager.cpp | 241 | ||||
-rw-r--r-- | src/game-server/skillmanager.h | 55 |
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 |