diff options
author | Jared Adams <jaxad0127@gmail.com> | 2009-07-07 11:23:14 -0600 |
---|---|---|
committer | Jared Adams <jaxad0127@gmail.com> | 2009-07-07 11:23:14 -0600 |
commit | 5662b7d9ad9eb6927df7ca83713d3b6108f59ddc (patch) | |
tree | 1e962203f7bf2440b558045967d0f93ccf21bbe4 | |
parent | 851f67cd9975b090b051decb1deab6b0489d14c5 (diff) | |
download | mana-client-5662b7d9ad9eb6927df7ca83713d3b6108f59ddc.tar.gz mana-client-5662b7d9ad9eb6927df7ca83713d3b6108f59ddc.tar.bz2 mana-client-5662b7d9ad9eb6927df7ca83713d3b6108f59ddc.tar.xz mana-client-5662b7d9ad9eb6927df7ca83713d3b6108f59ddc.zip |
Use tmw-skills.xml instead of hardcoding
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/gui/skilldialog.cpp | 365 | ||||
-rw-r--r-- | src/gui/skilldialog.h | 30 | ||||
-rw-r--r-- | src/gui/widgets/tabbedarea.cpp | 10 | ||||
-rw-r--r-- | src/gui/widgets/tabbedarea.h | 5 | ||||
-rw-r--r-- | src/gui/widgets/vertcontainer.cpp | 53 | ||||
-rw-r--r-- | src/gui/widgets/vertcontainer.h | 47 | ||||
-rw-r--r-- | src/localplayer.cpp | 66 | ||||
-rw-r--r-- | src/localplayer.h | 58 | ||||
-rw-r--r-- | src/net/tmwserv/generalhandler.cpp | 2 | ||||
-rw-r--r-- | src/net/tmwserv/playerhandler.cpp | 27 | ||||
-rw-r--r-- | src/net/tmwserv/protocol.h | 2 | ||||
-rw-r--r-- | tmw.cbp | 2 |
14 files changed, 354 insertions, 317 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 91fe8e06..a4594281 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -110,6 +110,8 @@ SET(SRCS gui/widgets/textfield.h gui/widgets/textpreview.cpp gui/widgets/textpreview.h + gui/widgets/vertcontainer.cpp + gui/widgets/vertcontainer.h gui/widgets/whispertab.cpp gui/widgets/whispertab.h gui/widgets/window.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 23de64bc..3637dc9f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -59,6 +59,8 @@ tmw_SOURCES = gui/widgets/avatar.cpp \ gui/widgets/textfield.h \ gui/widgets/textpreview.cpp \ gui/widgets/textpreview.h \ + gui/widgets/vertcontainer.cpp \ + gui/widgets/vertcontainer.h \ gui/widgets/whispertab.cpp \ gui/widgets/whispertab.h \ gui/widgets/window.cpp \ diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index f0cd01ce..a0b8f569 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -25,105 +25,66 @@ #include "gui/widgets/container.h" #include "gui/widgets/icon.h" #include "gui/widgets/label.h" +#include "gui/widgets/layouthelper.h" #include "gui/widgets/listbox.h" #include "gui/widgets/progressbar.h" #include "gui/widgets/scrollarea.h" +#include "gui/widgets/tab.h" #include "gui/widgets/tabbedarea.h" +#include "gui/widgets/vertcontainer.h" #include "gui/widgets/windowcontainer.h" #include "localplayer.h" +#include "log.h" #include "utils/dtor.h" #include "utils/gettext.h" #include "utils/stringutils.h" +#include "utils/xml.h" #include <string> #include <vector> -class SkillTab : public Container, public gcn::ActionListener +class SkillEntry; + +struct SkillInfo +{ + unsigned short id; + std::string name; + std::string icon; + bool modifiable; + SkillEntry *display; +}; + +class SkillEntry : public Container { public: - /** - * The type of this skill tab - */ - const std::string type; - - /** - * Constructor - */ - SkillTab(const std::string &type); - - /** - * Update this tab - */ - void update(); + SkillEntry(struct SkillInfo *info); - /** - * Called when receiving actions from widget. - */ - void action(const gcn::ActionEvent &event) {} + void update(); private: - /** - * Update the information of a skill at - * the given index - */ - void updateSkill(int index); - - /** - * Gets the number of skills in this particular - * type of tab. - */ - int getSkillNum(); - - /** - * Get the first enumeration of this skill tab's - * skill type. - */ - int getSkillBegin(); - - /** - * Get the icon associated with the given index - */ - Icon *getIcon(int index); - - std::vector<Icon *> mSkillIcons; - std::vector<gcn::Label *> mSkillNameLabels; - std::vector<gcn::Label *> mSkillLevelLabels; - std::vector<gcn::Label *> mSkillExpLabels; - std::vector<ProgressBar *> mSkillProgress; + struct SkillInfo *mInfo; + Icon *mIcon; + Label *mNameLabel; + Label *mLevelLabel; + Label *mExpLabel; + ProgressBar *mProgress; }; - SkillDialog::SkillDialog(): Window(_("Skills")) { setWindowName("Skills"); setCloseButton(true); + setResizable(true); setSaveVisible(true); setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425); - TabbedArea *panel = new TabbedArea; - panel->setDimension(gcn::Rectangle(5, 5, 270, 420)); - - SkillTab *tab; + mTabs = new TabbedArea(); - // Add each type of skill tab to the panel - tab = new SkillTab("Weapon"); - panel->addTab(_("Weapons"), tab); - mTabs.push_back(tab); - - tab = new SkillTab("Magic"); - panel->addTab(_("Magic"), tab); - mTabs.push_back(tab); - - tab = new SkillTab("Craft"); - panel->addTab(_("Crafts"), tab); - mTabs.push_back(tab); - - add(panel); - - update(); + place(0, 0, mTabs, 5, 5); + place(0, 5, new Label("TODO")); setLocationRelativeTo(getParent()); loadWindowState(); @@ -131,7 +92,7 @@ SkillDialog::SkillDialog(): SkillDialog::~SkillDialog() { - delete_all(mTabs); + //delete_all(mTabs); } void SkillDialog::action(const gcn::ActionEvent &event) @@ -145,174 +106,182 @@ void SkillDialog::action(const gcn::ActionEvent &event) } } -void SkillDialog::draw(gcn::Graphics *g) -{ - update(); - - Window::draw(g); -} - -void SkillDialog::update() +void SkillDialog::adjustTabSize() { - for(std::list<SkillTab*>::const_iterator i = mTabs.begin(); - i != mTabs.end(); ++i) - { - (*i)->update(); + gcn::Widget *content = mTabs->getCurrentWidget(); + if (content) { + int width = mTabs->getWidth() - 2 * content->getFrameSize(); + int height = mTabs->getContainerHeight() - 2 * content->getFrameSize(); + content->setSize(width, height); + content->setVisible(true); + content->logic(); } } -SkillTab::SkillTab(const std::string &type): type(type) +void SkillDialog::widgetResized(const gcn::Event &event) { - setOpaque(false); - setDimension(gcn::Rectangle(0, 0, 270, 420)); - int skillNum = getSkillNum(); - - mSkillIcons.resize(skillNum); - mSkillNameLabels.resize(skillNum); - mSkillLevelLabels.resize(skillNum); - mSkillExpLabels.resize(skillNum); - mSkillProgress.resize(skillNum); - - // Set the initial positions of the skill information - for (int a = 0; a < skillNum; a++) - { - mSkillIcons.at(a) = getIcon(a); - mSkillIcons.at(a)->setPosition(1, a*32); - add(mSkillIcons.at(a)); - - mSkillNameLabels.at(a) = new Label(""); - mSkillNameLabels.at(a)->setPosition(35, a*32 ); - add(mSkillNameLabels.at(a)); + Window::widgetResized(event); - mSkillProgress.at(a) = new ProgressBar(0.0f, 200, 20, gcn::Color(150, 150, 150)); - mSkillProgress.at(a)->setPosition(35, a*32 + 13); - add(mSkillProgress.at(a)); + adjustTabSize(); +} - mSkillExpLabels.at(a) = new Label(""); - mSkillExpLabels.at(a)->setPosition(45, a*32 + 16); - add(mSkillExpLabels.at(a)); +void SkillDialog::logic() +{ + Window::logic(); - mSkillLevelLabels.at(a) = new Label(""); - mSkillLevelLabels.at(a)->setPosition(165, a*32); - add(mSkillLevelLabels.at(a)); + Tab *tab = dynamic_cast<Tab*>(mTabs->getSelectedTab()); + if (tab != mCurrentTab) { + mCurrentTab = tab; + adjustTabSize(); } - - update(); } -int SkillTab::getSkillNum() +std::string SkillDialog::update(int id) { - int skillNum = 0; + SkillInfo *info = mSkills[id]; - if (type == "Weapon") - { - skillNum = CHAR_SKILL_WEAPON_NB; - return skillNum; - } - else if (type == "Magic") - { - skillNum = CHAR_SKILL_MAGIC_NB; - return skillNum; - } - else if (type == "Craft") + if (info) { - skillNum = CHAR_SKILL_CRAFT_NB; - return skillNum; + info->display->update(); + return info->name; } - else return skillNum; + else + return ""; } -int SkillTab::getSkillBegin() +void SkillDialog::loadSkills(const std::string &file, bool fixed) { - int skillBegin = 0; + // TODO: mTabs->clear(); + delete_all(mSkills); - if (type == "Weapon") - { - skillBegin = CHAR_SKILL_WEAPON_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; - } - else if (type == "Magic") + XML::Document doc(file); + xmlNodePtr root = doc.rootNode(); + + if (!root || !xmlStrEqual(root->name, BAD_CAST "skills")) { - skillBegin = CHAR_SKILL_MAGIC_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; + logger->log("Error loading skills file: %s", file.c_str()); + return; } - else if (type == "Craft") + + int setCount = 0; + std::string setName; + ScrollArea *scroll; + VertContainer *container; + std::string fixedDef = toString(fixed); + + for_each_xml_child_node(set, root) { - skillBegin = CHAR_SKILL_CRAFT_BEGIN - CHAR_SKILL_BEGIN; - return skillBegin; + if (xmlStrEqual(set->name, BAD_CAST "set")) + { + setCount++; + setName = XML::getProperty(set, "name", strprintf(_("Skill Set %d"), setCount)); + + container = new VertContainer(32); + 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 "skill")) + { + int id = atoi(XML::getProperty(node, "id", "-1").c_str()); + std::string name = XML::getProperty(node, "name", strprintf(_("Skill %d"), id)); + std::string icon = XML::getProperty(node, "icon", ""); + bool modifiable = !atoi(XML::getProperty(node, "fixed", fixedDef).c_str()); + + SkillInfo *skill = new SkillInfo; + skill->id = id; + skill->name = name; + skill->icon = icon; + skill->modifiable = modifiable; + skill->display = new SkillEntry(skill); + + container->add(skill->display); + + mSkills[id] = skill; + } + } + } } - else return skillBegin; -} -Icon* SkillTab::getIcon(int index) -{ - int skillBegin = getSkillBegin(); - std::string icon = LocalPlayer::getSkillInfo(index + skillBegin).icon; - return new Icon(icon); + adjustTabSize(); } -void SkillTab::updateSkill(int index) +SkillEntry::SkillEntry(struct SkillInfo *info) : mInfo(info), + mIcon(NULL), + mNameLabel(new Label(info->name)), + mProgress(new ProgressBar(0.0f, 200, 20, gcn::Color(150, 150, 150))), + mLevelLabel(new Label("999")) { - int skillBegin = getSkillBegin(); + setOpaque(false); + + if (!info->icon.empty()) + mIcon = new Icon(info->icon); - int baseLevel = player_node->getAttributeBase(index + - skillBegin + - CHAR_SKILL_BEGIN); + /*LayoutHelper h(this); + ContainerPlacer place = h.getPlacer(0, 0); - int effLevel = player_node->getAttributeEffective(index + - skillBegin + - CHAR_SKILL_BEGIN); - if(baseLevel <= 0) + if (mIcon) + place(0, 0, mIcon, 1, 2); + place(1, 0, mNameLabel, 3); + place(4, 0, mLevelLabel); + place(1, 1, mProgress, 4);*/ + + if (mIcon) { - mSkillProgress.at(index)->setVisible(false); - mSkillExpLabels.at(index)->setVisible(false); - mSkillLevelLabels.at(index)->setVisible(false); - mSkillNameLabels.at(index)->setVisible(false); - mSkillIcons.at(index)->setVisible(false); + mIcon->setPosition(1, 0); + add(mIcon); } - else - { - mSkillProgress.at(index)->setVisible(true); - mSkillExpLabels.at(index)->setVisible(true); - mSkillLevelLabels.at(index)->setVisible(true); - mSkillNameLabels.at(index)->setVisible(true); - mSkillIcons.at(index)->setVisible(true); - std::string skillLevel("Lvl: " + toString(baseLevel)); - if (effLevel < baseLevel) - { - skillLevel.append(" - " + toString(baseLevel - effLevel)); - } - else if (effLevel > baseLevel) - { - skillLevel.append(" + " + toString(effLevel - baseLevel)); - } - mSkillLevelLabels.at(index)->setCaption(skillLevel); - std::pair<int, int> exp = player_node->getExperience(index + skillBegin); - std::string sExp (toString(exp.first) + " / " + toString(exp.second)); + mNameLabel->setPosition(35, 0); + add(mNameLabel); + mLevelLabel->setPosition(165, 0); + add(mLevelLabel); - mSkillNameLabels.at(index)->setCaption(LocalPlayer::getSkillInfo(index + skillBegin).name); - mSkillNameLabels.at(index)->adjustSize(); - mSkillLevelLabels.at(index)->adjustSize(); - mSkillExpLabels.at(index)->setCaption(sExp); - mSkillExpLabels.at(index)->adjustSize(); - mSkillExpLabels.at(index)->setAlignment(gcn::Graphics::RIGHT); + mProgress->setPosition(35, 13); + add(mProgress); - // More intense red as exp grows - int color = 150 - (int)(150 * ((float) exp.first / exp.second)); - mSkillProgress.at(index)->setColor(244, color, color); - mSkillProgress.at(index)->setProgress((float) exp.first / exp.second); - } + update(); } -void SkillTab::update() +void SkillEntry::update() { - int skillNum = getSkillNum(); + int baseLevel = player_node->getAttributeBase(mInfo->id); + + int effLevel = player_node->getAttributeEffective(mInfo->id); + + if (baseLevel <= 0) + { + setVisible(false); + return; + } - // Update the skill information for reach skill - for (int a = 0; a < skillNum; a++) + setVisible(true); + + std::string skillLevel("Lvl: " + toString(baseLevel)); + if (effLevel < baseLevel) + { + skillLevel.append(" - " + toString(baseLevel - effLevel)); + } + else if (effLevel > baseLevel) { - updateSkill(a); + skillLevel.append(" + " + toString(effLevel - baseLevel)); } + mLevelLabel->setCaption(skillLevel); + + std::pair<int, int> exp = player_node->getExperience(mInfo->id); + std::string sExp (toString(exp.first) + " / " + toString(exp.second)); + + mLevelLabel->adjustSize(); + mProgress->setText(sExp); + + // More intense red as exp grows + int color = 150 - (int)(150 * ((float) exp.first / exp.second)); + mProgress->setColor(244, color, color); + mProgress->setProgress((float) exp.first / exp.second); } diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h index 56192273..fbd3c26d 100644 --- a/src/gui/skilldialog.h +++ b/src/gui/skilldialog.h @@ -29,10 +29,13 @@ #include <guichan/actionlistener.hpp> #include <list> +#include <map> -class ProgressBar; -class Icon; -class SkillTab; +class ScrollArea; +class Tab; +class TabbedArea; + +struct SkillInfo; /** * The skill dialog. @@ -52,17 +55,26 @@ class SkillDialog : public Window, public gcn::ActionListener void action(const gcn::ActionEvent &event); /** - * Update the tabs in this dialog + * Called when the widget changes size. Used for adapting the size of + * the tabbed area. */ - void update(); + void widgetResized(const gcn::Event &event); + + void logic(); /** - * Draw this window. - */ - void draw(gcn::Graphics *g); + * Update the given skill's display + */ + std::string update(int id); + + void loadSkills(const std::string &file, bool fixed = true); private: - std::list<SkillTab*> mTabs; + void adjustTabSize(); + + Tab *mCurrentTab; + TabbedArea *mTabs; + std::map<int, SkillInfo*> mSkills; }; extern SkillDialog *skillDialog; diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 07f46a94..bb5ae9a4 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -69,6 +69,16 @@ gcn::Widget *TabbedArea::getWidget(const std::string &name) const return NULL; } +gcn::Widget *TabbedArea::getCurrentWidget() +{ + gcn::Tab *tab = getSelectedTab(); + + if (tab) + return getWidget(tab->getCaption()); + else + return NULL; +} + void TabbedArea::addTab(const std::string &caption, gcn::Widget *widget) { Tab *tab = new Tab; diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index 6aaafe16..29ba2f76 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -63,6 +63,11 @@ class TabbedArea : public gcn::TabbedArea */ gcn::Widget *getWidget(const std::string &name) const; + /** + * Returns the widget for the current tab + */ + gcn::Widget *getCurrentWidget(); + using gcn::TabbedArea::addTab; /** diff --git a/src/gui/widgets/vertcontainer.cpp b/src/gui/widgets/vertcontainer.cpp new file mode 100644 index 00000000..9dd02cdc --- /dev/null +++ b/src/gui/widgets/vertcontainer.cpp @@ -0,0 +1,53 @@ +/* + * The Mana World + * Copyright (C) 2009 The Mana World Development Team + * + * This file is part of The Mana World. + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "gui/widgets/vertcontainer.h" + +VertContainer::VertContainer(int spacing): + mSpacing(spacing), + mCount(0) +{ + addWidgetListener(this); +} + +void VertContainer::add(gcn::Widget *widget) +{ + Container::add(widget); + widget->setPosition(0, mCount * mSpacing); + widget->setSize(getWidth(), mSpacing); + mCount++; + setHeight(mCount * mSpacing); +} + +void VertContainer::clear() +{ + Container::clear(); + + mCount = 0; +} + +void VertContainer::widgetResized(const gcn::Event &event) +{ + for (WidgetListIterator it = mWidgets.begin(); it != mWidgets.end(); it++) + { + (*it)->setWidth(getWidth()); + } +} diff --git a/src/gui/widgets/vertcontainer.h b/src/gui/widgets/vertcontainer.h new file mode 100644 index 00000000..9e15e66a --- /dev/null +++ b/src/gui/widgets/vertcontainer.h @@ -0,0 +1,47 @@ +/* + * The Mana World + * Copyright (C) 2009 The Mana World Development Team + * + * This file is part of The Mana World. + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef GUI_VERTCONTAINER_H +#define GUI_VERTCONTAINER_H + +#include "gui/widgets/container.h" + +#include <guichan/widgetlistener.hpp> + +/** + * A widget container. + * + * This container places it's contents veritcally. + */ +class VertContainer : public Container, public gcn::WidgetListener +{ + public: + VertContainer(int spacing); + virtual void add(gcn::Widget *widget); + virtual void clear(); + void widgetResized(const gcn::Event &event); + + private: + int mSpacing; + int mCount; +}; + +#endif diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 240f0a65..1c7f7a5a 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -41,6 +41,8 @@ #include "gui/palette.h" #ifdef EATHENA_SUPPORT #include "gui/storagewindow.h" +#else +#include "gui/skilldialog.h" #endif #include "net/inventoryhandler.h" @@ -103,10 +105,6 @@ LocalPlayer::LocalPlayer(int id, int job, Map *map): #endif mLastTarget(-1), #ifdef TMWSERV_SUPPORT - mAttributeBase(NB_CHARACTER_ATTRIBUTES, -1), - mAttributeEffective(NB_CHARACTER_ATTRIBUTES, -1), - mExpCurrent(CHAR_SKILL_NB, -1), - mExpNext(CHAR_SKILL_NB, -1), mCharacterPoints(-1), mCorrectionPoints(-1), mLevelProgress(0), @@ -793,52 +791,50 @@ void LocalPlayer::lowerAttribute(size_t attr) Net::GameServer::Player::lowerAttribute(attr + CHAR_ATTR_BEGIN); } -const struct LocalPlayer::SkillInfo& LocalPlayer::getSkillInfo(int skill) +void LocalPlayer::setAttributeBase(int num, int value) { - static const SkillInfo skills[CHAR_SKILL_NB + 1] = - { - { _("Unarmed"), "graphics/images/unarmed.png" }, // CHAR_SKILL_WEAPON_NONE - { _("Knife"), "graphics/images/knife.png" }, // CHAR_SKILL_WEAPON_KNIFE - { _("Sword"), "graphics/images/sword.png" }, // CHAR_SKILL_WEAPON_SWORD - { _("Polearm"), "graphics/images/polearm.png" }, // CHAR_SKILL_WEAPON_POLEARM - { _("Staff"), "graphics/images/staff.png" }, // CHAR_SKILL_WEAPON_STAFF - { _("Whip"), "graphics/images/whip.png" }, // CHAR_SKILL_WEAPON_WHIP - { _("Bow"), "graphics/images/bow.png" }, // CHAR_SKILL_WEAPON_BOW - { _("Shooting"), "graphics/images/shooting.png" }, // CHAR_SKILL_WEAPON_SHOOTING - { _("Mace"), "graphics/images/mace.png" }, // CHAR_SKILL_WEAPON_MACE - { _("Axe"), "graphics/images/axe.png" }, // CHAR_SKILL_WEAPON_AXE - { _("Thrown"), "graphics/images/thrown.png" }, // CHAR_SKILL_WEAPON_THROWN - { _("Magic"), "graphics/images/magic.png" }, // CHAR_SKILL_MAGIC_IAMJUSTAPLACEHOLDER - { _("Craft"), "graphics/images/craft.png" }, // CHAR_SKILL_CRAFT_IAMJUSTAPLACEHOLDER - { _("Unknown Skill"), "graphics/images/unknown.png" } - }; + int old = mAttributeBase[num]; - if ((skill < 0) || (skill > CHAR_SKILL_NB)) + mAttributeBase[num] = value; + if (skillDialog) { - return skills[CHAR_SKILL_NB]; - } - else - { - return skills[skill]; + if (skillDialog->update(num).empty() || !(value > old)) + return; + + Particle* effect = particleEngine->addEffect("graphics/particles/skillup.particle.xml", 0, 0); + this->controlParticle(effect); } } +void LocalPlayer::setAttributeEffective(int num, int value) +{ + mAttributeEffective[num] = value; + if (skillDialog) + skillDialog->update(num); +} + void LocalPlayer::setExperience(int skill, int current, int next) { - int diff = current - mExpCurrent.at(skill); - if (mMap && mExpCurrent.at(skill) != -1 && diff > 0) + std::pair<int, int> cur = getExperience(skill); + int diff = current - cur.first; + + cur = std::pair<int, int>(current, next); + + mSkillExp[skill] = cur; + std::string name; + if (skillDialog) + name = skillDialog->update(skill); + + if (mMap && cur.first != -1 && diff > 0 && !name.empty()) { - const std::string text = toString(diff) + " " + getSkillInfo(skill).name + " xp"; + const std::string text = strprintf("%d %s xp", diff, name.c_str()); mExpMessages.push_back(text); } - - mExpCurrent.at(skill) = current; - mExpNext.at(skill) = next; } std::pair<int, int> LocalPlayer::getExperience(int skill) { - return std::pair<int, int> (mExpCurrent.at(skill), mExpNext.at(skill)); + return mSkillExp[skill]; } #endif diff --git a/src/localplayer.h b/src/localplayer.h index 4053e81e..50dfbc98 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -84,39 +84,7 @@ enum CHAR_ATTR_END, CHAR_ATTR_NB = CHAR_ATTR_END - CHAR_ATTR_BEGIN, - CHAR_SKILL_BEGIN = CHAR_ATTR_END, - - CHAR_SKILL_WEAPON_BEGIN = CHAR_SKILL_BEGIN, - CHAR_SKILL_WEAPON_NONE = CHAR_SKILL_WEAPON_BEGIN, - CHAR_SKILL_WEAPON_KNIFE, - CHAR_SKILL_WEAPON_SWORD, - CHAR_SKILL_WEAPON_POLEARM, - CHAR_SKILL_WEAPON_STAFF, - CHAR_SKILL_WEAPON_WHIP, - CHAR_SKILL_WEAPON_BOW, - CHAR_SKILL_WEAPON_SHOOTING, - CHAR_SKILL_WEAPON_MACE, - CHAR_SKILL_WEAPON_AXE, - CHAR_SKILL_WEAPON_THROWN, - CHAR_SKILL_WEAPON_END, - CHAR_SKILL_WEAPON_NB = CHAR_SKILL_WEAPON_END - CHAR_SKILL_WEAPON_BEGIN, - - CHAR_SKILL_MAGIC_BEGIN = CHAR_SKILL_WEAPON_END, - CHAR_SKILL_MAGIC_IAMJUSTAPLACEHOLDER = CHAR_SKILL_MAGIC_BEGIN, - // add magic skills here - CHAR_SKILL_MAGIC_END, - CHAR_SKILL_MAGIC_NB = CHAR_SKILL_MAGIC_END - CHAR_SKILL_MAGIC_BEGIN, - - CHAR_SKILL_CRAFT_BEGIN = CHAR_SKILL_MAGIC_END, - CHAR_SKILL_CRAFT_IAMJUSTAPLACEHOLDER = CHAR_SKILL_CRAFT_BEGIN, - // add crafting skills here - CHAR_SKILL_CRAFT_END, - CHAR_SKILL_CRAFT_NB = CHAR_SKILL_CRAFT_END - CHAR_SKILL_CRAFT_BEGIN, - - CHAR_SKILL_END = CHAR_SKILL_CRAFT_END, - CHAR_SKILL_NB = CHAR_SKILL_END - CHAR_SKILL_BEGIN, - - NB_CHARACTER_ATTRIBUTES = CHAR_SKILL_END + NB_CHARACTER_ATTRIBUTES = CHAR_ATTR_END }; #endif @@ -371,17 +339,15 @@ class LocalPlayer : public Player void setMaxWeight(int value) { mMaxWeight = value; } - int getAttributeBase(int num) const + int getAttributeBase(int num) { return mAttributeBase[num]; } - void setAttributeBase(int num, int value) - { mAttributeBase[num] = value; } + void setAttributeBase(int num, int value); - int getAttributeEffective(int num) const + int getAttributeEffective(int num) { return mAttributeEffective[num]; } - void setAttributeEffective(int num, int value) - { mAttributeEffective[num] = value; } + void setAttributeEffective(int num, int value); int getCharacterPoints() const { return mCharacterPoints; } @@ -397,13 +363,6 @@ class LocalPlayer : public Player void setExperience(int skill, int current, int next); - struct SkillInfo { - std::string name; - std::string icon; - }; - - static const SkillInfo& getSkillInfo(int skill); - std::pair<int, int> getExperience(int skill); bool mUpdateName; /** Whether or not the name settings have changed */ @@ -424,10 +383,9 @@ class LocalPlayer : public Player int mLastTarget; /** Time stamp of last targeting action, -1 if none. */ // Character status: - std::vector<int> mAttributeBase; - std::vector<int> mAttributeEffective; - std::vector<int> mExpCurrent; - std::vector<int> mExpNext; + std::map<int, int> mAttributeBase; + std::map<int, int> mAttributeEffective; + std::map<int, std::pair<int, int> > mSkillExp; int mCharacterPoints; int mCorrectionPoints; int mLevelProgress; diff --git a/src/net/tmwserv/generalhandler.cpp b/src/net/tmwserv/generalhandler.cpp index 5886aafb..10b2c0f3 100644 --- a/src/net/tmwserv/generalhandler.cpp +++ b/src/net/tmwserv/generalhandler.cpp @@ -21,6 +21,7 @@ #include "gui/inventorywindow.h" #include "gui/partywindow.h" +#include "gui/skilldialog.h" #include "net/tmwserv/generalhandler.h" @@ -146,6 +147,7 @@ void GeneralHandler::guiWindowsLoaded() { inventoryWindow->setSplitAllowed(true); partyWindow->clearPartyName(); + skillDialog->loadSkills("tmw-skills.xml"); } void GeneralHandler::guiWindowsUnloaded() diff --git a/src/net/tmwserv/playerhandler.cpp b/src/net/tmwserv/playerhandler.cpp index 69a2bdb4..bbce3ae1 100644 --- a/src/net/tmwserv/playerhandler.cpp +++ b/src/net/tmwserv/playerhandler.cpp @@ -133,7 +133,7 @@ void PlayerHandler::handleMessage(MessageIn &msg) logger->log("ATTRIBUTE UPDATE:"); while (msg.getUnreadLength()) { - int stat = msg.readInt8(); + int stat = msg.readInt16(); int base = msg.readInt16(); int value = msg.readInt16(); logger->log("%d set to %d %d", stat, base, value); @@ -143,24 +143,11 @@ void PlayerHandler::handleMessage(MessageIn &msg) player_node->setMaxHp(base); player_node->setHp(value); } - else if (stat < NB_CHARACTER_ATTRIBUTES) + else { - if (stat >= CHAR_SKILL_BEGIN && stat < CHAR_SKILL_END - && player_node->getAttributeBase(stat) < base - && player_node->getAttributeBase(stat) > -1) - { - Particle* effect = particleEngine->addEffect("graphics/particles/skillup.particle.xml", 0, 0); - player_node->controlParticle(effect); - } - player_node->setAttributeBase(stat, base); player_node->setAttributeEffective(stat, value); } - else - { - logger->log("Warning: server wants to update unknown " - "attribute %d to %d", stat, value); - } } } break; @@ -173,15 +160,7 @@ void PlayerHandler::handleMessage(MessageIn &msg) int current = msg.readInt32(); int next = msg.readInt32(); - if (skill < CHAR_SKILL_NB) - { - player_node->setExperience(skill, current, next); - } - else - { - logger->log("Warning: server wants to update experience of unknown " - "skill %d to %d / %d", skill, current, next); - } + player_node->setExperience(skill, current, next); } } break; diff --git a/src/net/tmwserv/protocol.h b/src/net/tmwserv/protocol.h index e9fc5b8a..13a15256 100644 --- a/src/net/tmwserv/protocol.h +++ b/src/net/tmwserv/protocol.h @@ -83,7 +83,7 @@ enum { PGMSG_MOVE_ITEM = 0x0114, // B slot1, B slot2, B amount GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }* GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }* - GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { B attribute, W base value, W modified value }* + GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { W attribute, W base value, W modified value }* GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed }* GPMSG_LEVELUP = 0x0150, // W new level GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup @@ -470,6 +470,8 @@ <Unit filename="src/gui/widgets/textfield.h" /> <Unit filename="src/gui/widgets/textpreview.cpp" /> <Unit filename="src/gui/widgets/textpreview.h" /> + <Unit filename="src/gui/widgets/vertcontainer.cpp" /> + <Unit filename="src/gui/widgets/vertcontainer.h" /> <Unit filename="src/gui/widgets/whispertab.cpp" /> <Unit filename="src/gui/widgets/whispertab.h" /> <Unit filename="src/gui/widgets/window.cpp" /> |