summaryrefslogtreecommitdiff
path: root/src/game-server/specialmanager.cpp
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2012-04-03 13:29:05 +0200
committerErik Schilling <ablu.erikschilling@googlemail.com>2012-04-04 16:22:11 +0200
commitf8e816d9185c09d1c17d921b775e483d132982e5 (patch)
tree3ab299ab6057db3bfd8feb24130a6fcb7e64a60d /src/game-server/specialmanager.cpp
parente4baa92aae537921dd17873328a95ab17afcfdfc (diff)
downloadmanaserv-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.cpp177
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;
+}