diff options
author | Erik Schilling <ablu.erikschilling@googlemail.com> | 2012-04-03 13:29:05 +0200 |
---|---|---|
committer | Erik Schilling <ablu.erikschilling@googlemail.com> | 2012-04-04 16:22:11 +0200 |
commit | f8e816d9185c09d1c17d921b775e483d132982e5 (patch) | |
tree | 3ab299ab6057db3bfd8feb24130a6fcb7e64a60d /src/game-server/specialmanager.cpp | |
parent | e4baa92aae537921dd17873328a95ab17afcfdfc (diff) | |
download | manaserv-f8e816d9185c09d1c17d921b775e483d132982e5.tar.gz manaserv-f8e816d9185c09d1c17d921b775e483d132982e5.tar.bz2 manaserv-f8e816d9185c09d1c17d921b775e483d132982e5.tar.xz manaserv-f8e816d9185c09d1c17d921b775e483d132982e5.zip |
Enhanced special support
- Made the current charge being saved.
- Added script binds:
- chr_set_special_recharge_speed
- chr_get_special_recharge_speed
- chr_set_special_mana
- chr_get_special_mana
- get_special_info
- Added special info lua class. Functions:
- name
- needed_mana
- rechargeable
- on_use
- on_recharged
- category
Further the engine no longer sets charge to 0 after using of specials
this allows more flexbilillity (like failing specials).
Changes on the xml database:
- recharge renamed to rechargeable (needed by client and server)
- needed - the needed mana to trigger a special (server only)
- rechargespeed - the defailt recharge speed in mana per tick (server only)
- target - the type of target (either being or point) (server and client)
I also made the lua engine pushing nil instead of a 0 light userdata when
the pointer was 0.
Database update needed.
Change is tested.
Mana-Mantis: #167, #156
Reviewed-by: bjorn.
Diffstat (limited to 'src/game-server/specialmanager.cpp')
-rw-r--r-- | src/game-server/specialmanager.cpp | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/src/game-server/specialmanager.cpp b/src/game-server/specialmanager.cpp new file mode 100644 index 00000000..32669bca --- /dev/null +++ b/src/game-server/specialmanager.cpp @@ -0,0 +1,177 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#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 <set> " + "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 int SpecialManager::getId(const std::string &set, + const std::string &name) const +{ + std::string key = utils::toLower(set) + "_" + utils::toLower(name); + return getId(key); +} + +unsigned int 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; +} |