summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mana.cbp99
-rw-r--r--src/client.cpp2
-rw-r--r--src/gui/specialswindow.cpp177
-rw-r--r--src/gui/specialswindow.h20
-rw-r--r--src/gui/windowmenu.cpp2
-rw-r--r--src/net/manaserv/generalhandler.cpp1
-rw-r--r--src/resources/specialdb.cpp132
-rw-r--r--src/resources/specialdb.h72
-rw-r--r--src/utils/xml.cpp10
-rw-r--r--src/utils/xml.h13
10 files changed, 369 insertions, 159 deletions
diff --git a/mana.cbp b/mana.cbp
index 692e3a76..15ef4cde 100644
--- a/mana.cbp
+++ b/mana.cbp
@@ -11,6 +11,7 @@
<Option object_output=".objs\" />
<Option type="0" />
<Option compiler="gcc" />
+ <Option parameters="-u -d C:\mana\data" />
<Option projectResourceIncludeDirsRelation="0" />
<Compiler>
<Add option="-O3" />
@@ -128,7 +129,6 @@
<Unit filename="src\effectmanager.h" />
<Unit filename="src\emoteshortcut.cpp" />
<Unit filename="src\emoteshortcut.h" />
- <Unit filename="src\engine.h" />
<Unit filename="src\equipment.h" />
<Unit filename="src\flooritem.cpp" />
<Unit filename="src\flooritem.h" />
@@ -243,9 +243,9 @@
<Unit filename="src\gui\unregisterdialog.cpp" />
<Unit filename="src\gui\unregisterdialog.h" />
<Unit filename="src\gui\updatewindow.cpp" />
+ <Unit filename="src\gui\updatewindow.h" />
<Unit filename="src\gui\userpalette.cpp" />
<Unit filename="src\gui\userpalette.h" />
- <Unit filename="src\gui\updatewindow.h" />
<Unit filename="src\gui\viewport.cpp" />
<Unit filename="src\gui\viewport.h" />
<Unit filename="src\gui\widgets\avatarlistbox.cpp" />
@@ -360,7 +360,6 @@
<Unit filename="src\keyboardconfig.h" />
<Unit filename="src\localplayer.cpp" />
<Unit filename="src\localplayer.h" />
- <Unit filename="src\lockedarray.h" />
<Unit filename="src\log.cpp" />
<Unit filename="src\log.h" />
<Unit filename="src\main.cpp" />
@@ -379,52 +378,6 @@
<Unit filename="src\net\chathandler.h" />
<Unit filename="src\net\download.cpp" />
<Unit filename="src\net\download.h" />
- <Unit filename="src\net\tmwa\adminhandler.cpp" />
- <Unit filename="src\net\tmwa\adminhandler.h" />
- <Unit filename="src\net\tmwa\beinghandler.cpp" />
- <Unit filename="src\net\tmwa\beinghandler.h" />
- <Unit filename="src\net\tmwa\buysellhandler.cpp" />
- <Unit filename="src\net\tmwa\buysellhandler.h" />
- <Unit filename="src\net\tmwa\charserverhandler.cpp" />
- <Unit filename="src\net\tmwa\charserverhandler.h" />
- <Unit filename="src\net\tmwa\chathandler.cpp" />
- <Unit filename="src\net\tmwa\chathandler.h" />
- <Unit filename="src\net\tmwa\gamehandler.cpp" />
- <Unit filename="src\net\tmwa\gamehandler.h" />
- <Unit filename="src\net\tmwa\generalhandler.cpp" />
- <Unit filename="src\net\tmwa\generalhandler.h" />
- <Unit filename="src\net\tmwa\gui\guildtab.cpp" />
- <Unit filename="src\net\tmwa\gui\guildtab.h" />
- <Unit filename="src\net\tmwa\gui\partytab.cpp" />
- <Unit filename="src\net\tmwa\gui\partytab.h" />
- <Unit filename="src\net\tmwa\guildhandler.cpp" />
- <Unit filename="src\net\tmwa\guildhandler.h" />
- <Unit filename="src\net\tmwa\inventoryhandler.cpp" />
- <Unit filename="src\net\tmwa\inventoryhandler.h" />
- <Unit filename="src\net\tmwa\itemhandler.cpp" />
- <Unit filename="src\net\tmwa\itemhandler.h" />
- <Unit filename="src\net\tmwa\loginhandler.cpp" />
- <Unit filename="src\net\tmwa\loginhandler.h" />
- <Unit filename="src\net\tmwa\messagehandler.cpp" />
- <Unit filename="src\net\tmwa\messagehandler.h" />
- <Unit filename="src\net\tmwa\messagein.cpp" />
- <Unit filename="src\net\tmwa\messagein.h" />
- <Unit filename="src\net\tmwa\messageout.cpp" />
- <Unit filename="src\net\tmwa\messageout.h" />
- <Unit filename="src\net\tmwa\network.cpp" />
- <Unit filename="src\net\tmwa\network.h" />
- <Unit filename="src\net\tmwa\npchandler.cpp" />
- <Unit filename="src\net\tmwa\npchandler.h" />
- <Unit filename="src\net\tmwa\partyhandler.cpp" />
- <Unit filename="src\net\tmwa\partyhandler.h" />
- <Unit filename="src\net\tmwa\playerhandler.cpp" />
- <Unit filename="src\net\tmwa\playerhandler.h" />
- <Unit filename="src\net\tmwa\protocol.h" />
- <Unit filename="src\net\tmwa\specialhandler.cpp" />
- <Unit filename="src\net\tmwa\specialhandler.h" />
- <Unit filename="src\net\tmwa\token.h" />
- <Unit filename="src\net\tmwa\tradehandler.cpp" />
- <Unit filename="src\net\tmwa\tradehandler.h" />
<Unit filename="src\net\gamehandler.h" />
<Unit filename="src\net\generalhandler.h" />
<Unit filename="src\net\guildhandler.h" />
@@ -492,6 +445,52 @@
<Unit filename="src\net\playerhandler.h" />
<Unit filename="src\net\serverinfo.h" />
<Unit filename="src\net\specialhandler.h" />
+ <Unit filename="src\net\tmwa\adminhandler.cpp" />
+ <Unit filename="src\net\tmwa\adminhandler.h" />
+ <Unit filename="src\net\tmwa\beinghandler.cpp" />
+ <Unit filename="src\net\tmwa\beinghandler.h" />
+ <Unit filename="src\net\tmwa\buysellhandler.cpp" />
+ <Unit filename="src\net\tmwa\buysellhandler.h" />
+ <Unit filename="src\net\tmwa\charserverhandler.cpp" />
+ <Unit filename="src\net\tmwa\charserverhandler.h" />
+ <Unit filename="src\net\tmwa\chathandler.cpp" />
+ <Unit filename="src\net\tmwa\chathandler.h" />
+ <Unit filename="src\net\tmwa\gamehandler.cpp" />
+ <Unit filename="src\net\tmwa\gamehandler.h" />
+ <Unit filename="src\net\tmwa\generalhandler.cpp" />
+ <Unit filename="src\net\tmwa\generalhandler.h" />
+ <Unit filename="src\net\tmwa\gui\guildtab.cpp" />
+ <Unit filename="src\net\tmwa\gui\guildtab.h" />
+ <Unit filename="src\net\tmwa\gui\partytab.cpp" />
+ <Unit filename="src\net\tmwa\gui\partytab.h" />
+ <Unit filename="src\net\tmwa\guildhandler.cpp" />
+ <Unit filename="src\net\tmwa\guildhandler.h" />
+ <Unit filename="src\net\tmwa\inventoryhandler.cpp" />
+ <Unit filename="src\net\tmwa\inventoryhandler.h" />
+ <Unit filename="src\net\tmwa\itemhandler.cpp" />
+ <Unit filename="src\net\tmwa\itemhandler.h" />
+ <Unit filename="src\net\tmwa\loginhandler.cpp" />
+ <Unit filename="src\net\tmwa\loginhandler.h" />
+ <Unit filename="src\net\tmwa\messagehandler.cpp" />
+ <Unit filename="src\net\tmwa\messagehandler.h" />
+ <Unit filename="src\net\tmwa\messagein.cpp" />
+ <Unit filename="src\net\tmwa\messagein.h" />
+ <Unit filename="src\net\tmwa\messageout.cpp" />
+ <Unit filename="src\net\tmwa\messageout.h" />
+ <Unit filename="src\net\tmwa\network.cpp" />
+ <Unit filename="src\net\tmwa\network.h" />
+ <Unit filename="src\net\tmwa\npchandler.cpp" />
+ <Unit filename="src\net\tmwa\npchandler.h" />
+ <Unit filename="src\net\tmwa\partyhandler.cpp" />
+ <Unit filename="src\net\tmwa\partyhandler.h" />
+ <Unit filename="src\net\tmwa\playerhandler.cpp" />
+ <Unit filename="src\net\tmwa\playerhandler.h" />
+ <Unit filename="src\net\tmwa\protocol.h" />
+ <Unit filename="src\net\tmwa\specialhandler.cpp" />
+ <Unit filename="src\net\tmwa\specialhandler.h" />
+ <Unit filename="src\net\tmwa\token.h" />
+ <Unit filename="src\net\tmwa\tradehandler.cpp" />
+ <Unit filename="src\net\tmwa\tradehandler.h" />
<Unit filename="src\net\tradehandler.h" />
<Unit filename="src\net\worldinfo.h" />
<Unit filename="src\openglgraphics.cpp" />
@@ -552,6 +551,8 @@
<Unit filename="src\resources\resourcemanager.h" />
<Unit filename="src\resources\soundeffect.cpp" />
<Unit filename="src\resources\soundeffect.h" />
+ <Unit filename="src\resources\specialdb.cpp" />
+ <Unit filename="src\resources\specialdb.h" />
<Unit filename="src\resources\spritedef.cpp" />
<Unit filename="src\resources\spritedef.h" />
<Unit filename="src\resources\wallpaper.cpp" />
diff --git a/src/client.cpp b/src/client.cpp
index 35292d22..ea35f76d 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -70,6 +70,7 @@
#include "resources/image.h"
#include "resources/itemdb.h"
#include "resources/monsterdb.h"
+#include "resources/specialdb.h"
#include "resources/npcdb.h"
#include "resources/resourcemanager.h"
@@ -743,6 +744,7 @@ int Client::exec()
ItemDB::load();
Being::load(); // Hairstyles
MonsterDB::load();
+ SpecialDB::load();
NPCDB::load();
EmoteDB::load();
StatusEffect::load();
diff --git a/src/gui/specialswindow.cpp b/src/gui/specialswindow.cpp
index 44551825..4f9a9652 100644
--- a/src/gui/specialswindow.cpp
+++ b/src/gui/specialswindow.cpp
@@ -20,7 +20,6 @@
#include "gui/specialswindow.h"
-#include "localplayer.h"
#include "log.h"
#include "gui/setup.h"
@@ -42,6 +41,8 @@
#include "net/net.h"
#include "net/specialhandler.h"
+#include "resources/specialdb.h"
+
#include "utils/dtor.h"
#include "utils/gettext.h"
#include "utils/stringutils.h"
@@ -54,31 +55,24 @@
class SpecialEntry;
-struct SpecialInfo
-{
- unsigned short id;
- std::string name;
- std::string icon;
- SpecialEntry *display;
-};
class SpecialEntry : public Container
{
public:
SpecialEntry(SpecialInfo *info);
- void update();
+ void update(int current, int needed);
protected:
friend class SpecialsWindow;
SpecialInfo *mInfo;
private:
- Icon *mIcon;
- Label *mNameLabel;
- Label *mLevelLabel;
- Label *mTechLabel;
- Button *mUse;
+ Icon *mIcon; // icon to display
+ Label *mNameLabel; // name to display
+ Label *mLevelLabel; // level number label (only shown when applicable)
+ Button *mUse; // use button (only shown when applicable)
+ ProgressBar *mRechargeBar; // recharge bar (only shown when applicable)
};
SpecialsWindow::SpecialsWindow():
@@ -102,7 +96,6 @@ SpecialsWindow::SpecialsWindow():
SpecialsWindow::~SpecialsWindow()
{
// Clear gui
- loadSpecials("");
}
void SpecialsWindow::action(const gcn::ActionEvent &event)
@@ -127,91 +120,70 @@ void SpecialsWindow::action(const gcn::ActionEvent &event)
}
}
-std::string SpecialsWindow::update(int id)
-{
- // TODO
-
- return std::string();
-}
-
-void SpecialsWindow::loadSpecials(const std::string &file)
+void SpecialsWindow::draw(gcn::Graphics *graphics)
{
- // TODO: mTabs->clear();
- while (mTabs->getSelectedTabIndex() != -1)
+ // update the progress bars
+ std::map<int, Special> specialData = player_node->getSpecialStatus();
+ bool foundNew = false;
+ unsigned int found = 0; // number of entries in specialData which match mEntries
+
+ for (std::map<int, Special>::iterator i = specialData.begin();
+ i != specialData.end();
+ i++)
{
- mTabs->removeTabWithIndex(mTabs->getSelectedTabIndex());
- }
-
- for (SpecialMap::iterator it = mSpecials.begin(); it != mSpecials.end(); it++)
- {
- delete (*it).second->display;
+ std::map<int, SpecialEntry *>::iterator e = mEntries.find(i->first);
+ if (e == mEntries.end())
+ {
+ // found a new special - abort update and rebuild from scratch
+ foundNew = true;
+ break;
+ } else {
+ // update progress bar of special
+ e->second->update(i->second.currentMana, i->second.neededMana);
+ found++;
+ }
}
- delete_all(mSpecials);
- mSpecials.clear();
+ // a rebuild is needed when a) the number of specials changed or b) an existing entry isn't found anymore
+ if (foundNew || found != mEntries.size()) rebuild(specialData);
- if (file.length() == 0)
- return;
+ Window::draw(graphics);
+}
- XML::Document doc(file);
- xmlNodePtr root = doc.rootNode();
+void SpecialsWindow::rebuild(const std::map<int, Special> &specialData)
+{
+ make_dtor(mEntries);
+ mEntries.clear();
+ int vPos = 0; //vertical position of next placed element
- if (!root || !xmlStrEqual(root->name, BAD_CAST "specials"))
+ for (std::map<int, Special>::const_iterator i = specialData.begin();
+ i != specialData.end();
+ i++)
{
- logger->log("Error loading specials file: %s", file.c_str());
- return;
- }
-
- int setCount = 0;
- std::string setName;
- ScrollArea *scroll;
- FlowContainer *container;
+ logger->log("Updating special GUI for %d", i->first);
- for_each_xml_child_node(set, root)
- {
- if (xmlStrEqual(set->name, BAD_CAST "set"))
+ SpecialInfo* info = SpecialDB::get(i->first);
+ if (info)
{
- setCount++;
- setName = XML::getProperty(set, "name", strprintf(_("Specials Set %d"), setCount));
-
- container = new FlowContainer(SPECIALS_WIDTH, SPECIALS_HEIGHT);
- container->setOpaque(false);
- scroll = new ScrollArea(container);
- scroll->setOpaque(false);
- scroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
- scroll->setVerticalScrollPolicy(ScrollArea::SHOW_ALWAYS);
-
- mTabs->addTab(setName, scroll);
- for_each_xml_child_node(node, set)
- {
- if (xmlStrEqual(node->name, BAD_CAST "special"))
- {
- int id = atoi(XML::getProperty(node, "id", "-1").c_str());
- if (id == -1)
- continue;
- std::string name = XML::getProperty(node, "name", strprintf(_("Special %d"), id));
- std::string icon = XML::getProperty(node, "icon", "");
-
- SpecialInfo *special = new SpecialInfo;
- special->id = id;
- special->name = name;
- special->icon = icon;
- special->display = new SpecialEntry(special);
-
- container->add(special->display);
-
- mSpecials[id] = special;
- }
- }
+ info->rechargeCurrent = i->second.currentMana;
+ info->rechargeNeeded = i->second.neededMana;
+ SpecialEntry* entry = new SpecialEntry(info);
+ entry->setPosition(0, vPos);
+ vPos += entry->getHeight();
+ add(entry);
+ mEntries[i->first] = entry;
+ } else {
+ logger->log("Warning: No info available of special %d", i->first);
}
}
}
+
SpecialEntry::SpecialEntry(SpecialInfo *info) :
mInfo(info),
mIcon(NULL),
- mNameLabel(new Label(info->name)),
- mLevelLabel(new Label("999")),
- mUse(new Button("Use", "use", specialsWindow))
+ mLevelLabel(NULL),
+ mUse(NULL),
+ mRechargeBar(NULL)
{
setFrameSize(1);
setOpaque(false);
@@ -225,21 +197,42 @@ SpecialEntry::SpecialEntry(SpecialInfo *info) :
mIcon->setPosition(1, 0);
add(mIcon);
+
+ mNameLabel = new Label(info->name);
mNameLabel->setPosition(35, 0);
add(mNameLabel);
- mLevelLabel->setPosition(getWidth() - mLevelLabel->getWidth(), 0);
- add(mLevelLabel);
+ if (info->hasLevel)
+ {
+ mLevelLabel = new Label(toString(info->level));
+ mLevelLabel->setPosition(getWidth() - mLevelLabel->getWidth(), 0);
+ add(mLevelLabel);
+ }
+
- mNameLabel->setWidth(mLevelLabel->getX() - mNameLabel->getX() - 1);
+ if (info->isActive)
+ {
+ mUse = new Button("Use", "use", specialsWindow);
+ mUse->setPosition(getWidth() - mUse->getWidth(), 13);
+ add(mUse);
+ }
- mUse->setPosition(getWidth() - mUse->getWidth(), 13);
- add(mUse);
+ if (info->hasRechargeBar)
+ {
+ float progress = (float)info->rechargeCurrent / (float)info->rechargeNeeded;
+ mRechargeBar = new ProgressBar(progress, 100, 10, Theme::PROG_MP);
+ mRechargeBar->setSmoothProgress(false);
+ mRechargeBar->setPosition(0, 13);
+ add(mRechargeBar);
+ }
- update();
}
-void SpecialEntry::update()
+void SpecialEntry::update(int current, int needed)
{
- // TODO
+ if (mRechargeBar)
+ {
+ float progress = (float)current / (float)needed;
+ mRechargeBar->setProgress(progress);
+ }
}
diff --git a/src/gui/specialswindow.h b/src/gui/specialswindow.h
index 81384856..634727e5 100644
--- a/src/gui/specialswindow.h
+++ b/src/gui/specialswindow.h
@@ -25,6 +25,8 @@
#include "guichanfwd.h"
+#include "localplayer.h"
+
#include "gui/widgets/window.h"
#include <guichan/actionlistener.hpp>
@@ -36,7 +38,7 @@ class ScrollArea;
class Tab;
class TabbedArea;
-struct SpecialInfo;
+struct SpecialEntry;
class SpecialsWindow : public Window, public gcn::ActionListener {
public:
@@ -49,20 +51,14 @@ class SpecialsWindow : public Window, public gcn::ActionListener {
*/
void action(const gcn::ActionEvent &actionEvent);
- /**
- * Update the given special's display
- */
- std::string update(int id);
-
- void loadSpecials(const std::string &file);
-
- bool hasSpecials() { return !mSpecials.empty(); }
+ void draw(gcn::Graphics *graphics);
private:
- std::vector<gcn::Button *> mSpellButtons;
- typedef std::map<int, SpecialInfo*> SpecialMap;
- SpecialMap mSpecials;
+ // (re)constructs the list of specials
+ void rebuild(const std::map<int, Special> &specialData);
+
TabbedArea *mTabs;
+ std::map<int, SpecialEntry *> mEntries;
};
extern SpecialsWindow *specialsWindow;
diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp
index 5af5a202..76e6bc1f 100644
--- a/src/gui/windowmenu.cpp
+++ b/src/gui/windowmenu.cpp
@@ -58,7 +58,7 @@ WindowMenu::WindowMenu():
if (skillDialog->hasSkills())
addButton(N_("Skills"), x, h);
- if (specialsWindow->hasSpecials())
+ // if (specialsWindow->hasSpecials())
addButton(N_("Specials"), x, h);
addButton(N_("Social"), x, h);
diff --git a/src/net/manaserv/generalhandler.cpp b/src/net/manaserv/generalhandler.cpp
index 0d3073f1..bf892b3a 100644
--- a/src/net/manaserv/generalhandler.cpp
+++ b/src/net/manaserv/generalhandler.cpp
@@ -167,7 +167,6 @@ void GeneralHandler::guiWindowsLoaded()
{
inventoryWindow->setSplitAllowed(true);
skillDialog->loadSkills("mana-skills.xml");
- specialsWindow->loadSpecials("specials.xml");
player_node->setExpNeeded(100);
diff --git a/src/resources/specialdb.cpp b/src/resources/specialdb.cpp
new file mode 100644
index 00000000..ac591c4f
--- /dev/null
+++ b/src/resources/specialdb.cpp
@@ -0,0 +1,132 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "resources/specialdb.h"
+
+#include "log.h"
+
+#include "utils/dtor.h"
+#include "utils/xml.h"
+
+
+namespace
+{
+ SpecialInfos mSpecialInfos;
+ bool mLoaded = false;
+}
+
+SpecialInfo::TargetMode SpecialDB::targetModeFromString(const std::string& str)
+{
+ if (str=="self") return SpecialInfo::TARGET_SELF;
+ else if (str=="friend") return SpecialInfo::TARGET_FRIEND;
+ else if (str=="enemy") return SpecialInfo::TARGET_ENEMY;
+ else if (str=="being") return SpecialInfo::TARGET_BEING;
+ else if (str=="point") return SpecialInfo::TARGET_POINT;
+
+ logger->log("SpecialDB: Warning, unknown target mode \"%s\"", str.c_str() );
+ return SpecialInfo::TARGET_SELF;
+}
+
+void SpecialDB::load()
+{
+ if (mLoaded)
+ unload();
+
+ logger->log("Initializing special database...");
+
+ XML::Document doc("specials.xml");
+ xmlNodePtr root = doc.rootNode();
+
+ if (!root || !xmlStrEqual(root->name, BAD_CAST "specials"))
+ {
+ logger->log("Error loading specials file specials.xml");
+ return;
+ }
+
+ std::string setName;
+
+ for_each_xml_child_node(set, root)
+ {
+ if (xmlStrEqual(set->name, BAD_CAST "set"))
+ {
+ setName = XML::getProperty(set, "name", "Actions");
+
+
+ for_each_xml_child_node(special, set)
+ {
+ if (xmlStrEqual(special->name, BAD_CAST "special"))
+ {
+ SpecialInfo *info = new SpecialInfo();
+ int id = XML::getProperty(special, "id", 0);
+ info->id = id;
+ info->set = setName;
+ info->name = XML::getProperty(special, "name", "");
+ info->icon = XML::getProperty(special, "icon", "");
+
+ info->isActive = XML::getBoolProperty(special, "active", false);
+ info->targetMode = targetModeFromString(XML::getProperty(special, "target", "self"));
+
+ info->level = XML::getProperty(special, "level", -1);
+ info->hasLevel = info->level > -1;
+
+ info->hasRechargeBar = XML::getBoolProperty(special, "recharge", false);
+ info->rechargeNeeded = 0;
+ info->rechargeCurrent = 0;
+
+ if (mSpecialInfos.find(id) != mSpecialInfos.end())
+ {
+ logger->log("SpecialDB: Duplicate special ID %d (ignoring)", id);
+ } else {
+ mSpecialInfos[id] = info;
+ }
+ }
+ }
+ }
+ }
+
+ mLoaded = true;
+}
+
+void SpecialDB::unload()
+{
+
+ delete_all(mSpecialInfos);
+ mSpecialInfos.clear();
+
+ mLoaded = false;
+}
+
+
+SpecialInfo *SpecialDB::get(int id)
+{
+
+ SpecialInfos::iterator i = mSpecialInfos.find(id);
+
+ if (i == mSpecialInfos.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return i->second;
+ }
+ return NULL;
+}
+
diff --git a/src/resources/specialdb.h b/src/resources/specialdb.h
new file mode 100644
index 00000000..38612c2a
--- /dev/null
+++ b/src/resources/specialdb.h
@@ -0,0 +1,72 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2010 The Mana Developers
+ *
+ * This file is part of The Mana Client.
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SPECIAL_DB_H
+#define SPECIAL_DB_H
+
+#include <string>
+#include <map>
+
+struct SpecialInfo
+{
+ enum TargetMode
+ {
+ TARGET_SELF, // no target selection
+ TARGET_FRIEND, // target friendly being
+ TARGET_ENEMY, // target hostile being
+ TARGET_BEING, // target any being
+ TARGET_POINT // target map location
+ };
+ int id;
+ std::string set; // tab on which the special is shown
+ std::string name; // displayed name of special
+ std::string icon; // filename of graphical icon
+
+ bool isActive; // true when the special can be used
+ TargetMode targetMode; // target mode
+
+ bool hasLevel; // true when the special has levels
+ int level; // level of special when applicable
+
+ bool hasRechargeBar; // true when the special has a recharge bar
+ int rechargeNeeded; // maximum recharge when applicable
+ int rechargeCurrent; // current recharge when applicable
+};
+
+/**
+ * Special information database.
+ */
+namespace SpecialDB
+{
+ void load();
+
+ void unload();
+
+ /** gets the special info for ID. Will return 0 when it is
+ * a server-specific special.
+ */
+ SpecialInfo *get(int id);
+
+ SpecialInfo::TargetMode targetModeFromString(const std::string& str);
+}
+
+typedef std::map<int, SpecialInfo *> SpecialInfos;
+
+#endif
diff --git a/src/utils/xml.cpp b/src/utils/xml.cpp
index 341f34c0..94e0e38d 100644
--- a/src/utils/xml.cpp
+++ b/src/utils/xml.cpp
@@ -27,6 +27,7 @@
#include <iostream>
#include <fstream>
+#include <cstring>
namespace XML
{
@@ -135,6 +136,15 @@ namespace XML
return def;
}
+ bool getBoolProperty(xmlNodePtr node, const char* name, bool def)
+ {
+ xmlChar *prop = xmlGetProp(node, BAD_CAST name);
+
+ if (xmlStrEqual(prop, BAD_CAST "true" ) ) return true;
+ if (xmlStrEqual(prop, BAD_CAST "false") ) return false;
+ return def;
+ }
+
xmlNodePtr findFirstChildByName(xmlNodePtr parent, const char *name)
{
for_each_xml_child_node(child, parent)
diff --git a/src/utils/xml.h b/src/utils/xml.h
index 72745501..253c4e09 100644
--- a/src/utils/xml.h
+++ b/src/utils/xml.h
@@ -69,14 +69,14 @@ namespace XML
};
/**
- * Gets an integer property from an xmlNodePtr.
+ * Gets an floating point property from an xmlNodePtr.
*/
- int getProperty(xmlNodePtr node, const char *name, int def);
+ double getFloatProperty(xmlNodePtr node, const char *name, double def);
/**
- * Gets an floating point property from an xmlNodePtr.
+ * Gets an integer property from an xmlNodePtr.
*/
- double getFloatProperty(xmlNodePtr node, const char *name, double def);
+ int getProperty(xmlNodePtr node, const char *name, int def);
/**
* Gets a string property from an xmlNodePtr.
@@ -85,6 +85,11 @@ namespace XML
const std::string &def);
/**
+ * Gets a boolean property from an xmlNodePtr.
+ */
+ bool getBoolProperty(xmlNodePtr node, const char *name, bool def);
+
+ /**
* Finds the first child node with the given name
*/
xmlNodePtr findFirstChildByName(xmlNodePtr parent, const char *name);