/* * The Mana Server * Copyright (C) 2004-2010 The Mana World Development Team * Copyright (C) 2010-2012 The Mana Developers * * 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 . */ #include "specialmanager.h" #include "utils/xml.h" #include "utils/logger.h" static SpecialManager::TargetMode getTargetByString(const std::string &str) { std::string strLower = utils::toLower(str); if (strLower == "being") return SpecialManager::TARGET_BEING; else if (strLower == "point") return SpecialManager::TARGET_POINT; LOG_WARN("Unknown targetmode " << str << " assuming being."); return SpecialManager::TARGET_BEING; } void SpecialManager::readSpecialNode(xmlNodePtr specialNode, const std::string &setName) { std::string name = utils::toLower( XML::getProperty(specialNode, "name", std::string())); int id = XML::getProperty(specialNode, "id", 0); if (id <= 0 || name.empty()) { LOG_WARN("Invalid special (empty name or id <= 0) in set: " << setName); return; } SpecialsInfo::iterator it = mSpecialsInfo.find(id); if (it != mSpecialsInfo.end()) { LOG_WARN("SpecialManager: The same id: " << id << " is given for special names: " << it->first << " and " << name); LOG_WARN("The special reference: " << id << ": '" << name << "' will be ignored."); return; } bool rechargeable = XML::getBoolProperty(specialNode, "rechargeable", true); int neededMana = XML::getProperty(specialNode, "needed", 0); int defaultRechargeSpeed = XML::getProperty(specialNode, "rechargespeed", 0); if (rechargeable && neededMana <= 0) { LOG_WARN("Invalid special '" << name << "' (rechargable but no needed attribute) in set: " << setName); return; } SpecialInfo *newInfo = new SpecialManager::SpecialInfo; newInfo->setName = setName; newInfo->name = name; newInfo->id = id; newInfo->rechargeable = rechargeable; newInfo->neededMana = neededMana; newInfo->defaultRechargeSpeed = defaultRechargeSpeed; newInfo->target = getTargetByString(XML::getProperty(specialNode, "target", std::string())); mSpecialsInfo[newInfo->id] = newInfo; std::string keyName = setName + "_" + newInfo->name; mNamedSpecialsInfo[keyName] = newInfo; } void SpecialManager::initialize() { clear(); XML::Document doc(mSpecialFile); xmlNodePtr rootNode = doc.rootNode(); if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "specials")) { LOG_ERROR("Special Manager: " << mSpecialFile << " is not a valid database file!"); return; } LOG_INFO("Loading special reference: " << mSpecialFile); for_each_xml_child_node(setNode, rootNode) { // The server will prefix the core name with the set, so we need one. if (!xmlStrEqual(setNode->name, BAD_CAST "set")) continue; std::string setName = XML::getProperty(setNode, "name", std::string()); if (setName.empty()) { LOG_WARN("The " << mSpecialFile << " file is containing unamed " "tags and will be ignored."); continue; } setName = utils::toLower(setName); for_each_xml_child_node(specialNode, setNode) { if (!xmlStrEqual(specialNode->name, BAD_CAST "special")) continue; readSpecialNode(specialNode, setName); } } } void SpecialManager::clear() { for (SpecialsInfo::iterator it = mSpecialsInfo.begin(), it_end = mSpecialsInfo.end(); it != it_end; ++it) { delete it->second; } mSpecialsInfo.clear(); mNamedSpecialsInfo.clear(); } unsigned SpecialManager::getId(const std::string &set, const std::string &name) const { std::string key = utils::toLower(set) + "_" + utils::toLower(name); return getId(key); } unsigned SpecialManager::getId(const std::string &specialName) const { if (mNamedSpecialsInfo.contains(specialName)) return mNamedSpecialsInfo.value(specialName)->id; else return 0; } const std::string SpecialManager::getSpecialName(int id) const { SpecialsInfo::const_iterator it = mSpecialsInfo.find(id); return it != mSpecialsInfo.end() ? it->second->name : ""; } const std::string SpecialManager::getSetName(int id) const { SpecialsInfo::const_iterator it = mSpecialsInfo.find(id); return it != mSpecialsInfo.end() ? it->second->setName : ""; } SpecialManager::SpecialInfo *SpecialManager::getSpecialInfo(int id) { SpecialsInfo::const_iterator it = mSpecialsInfo.find(id); return it != mSpecialsInfo.end() ? it->second : 0; }