diff options
author | Ira Rice <irarice@gmail.com> | 2008-11-02 00:33:31 +0000 |
---|---|---|
committer | Ira Rice <irarice@gmail.com> | 2008-11-02 00:33:31 +0000 |
commit | 5cf18a062ffca03196b83fe6fda8ea3e54079c57 (patch) | |
tree | 00fa520012a6ed4a0fee66a1d65364bf81ccaeb5 /src | |
parent | 494e35cda96863f676409d304a916d9308040eab (diff) | |
download | mana-5cf18a062ffca03196b83fe6fda8ea3e54079c57.tar.gz mana-5cf18a062ffca03196b83fe6fda8ea3e54079c57.tar.bz2 mana-5cf18a062ffca03196b83fe6fda8ea3e54079c57.tar.xz mana-5cf18a062ffca03196b83fe6fda8ea3e54079c57.zip |
Ported a patch from TMW by fate which de-hardcodes skills, as well as removes the server sending out view id's for
gloves and boots (which weren't needed.) Here's the full log:
* Updated GUI table and model to better handle NULL widgets during initialisation
* On SMSG_MOVE et al., ignore boots and glove information-- that information is incorrect and we're guaranteed to
already have the correct information anyway.
* Properly decode `is dead' information for PCs, so that dead players, when encountered, will be lying on the ground,
dead, rather than standing.
* Use `skills.xml' file from client data to determine skill names
* Report client version number (hereby bumped to 1) in unused charserver slot (ignored by vanilla eAthena)
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/skill.cpp | 181 | ||||
-rw-r--r-- | src/gui/skill.h | 18 | ||||
-rw-r--r-- | src/gui/table.cpp | 12 | ||||
-rw-r--r-- | src/gui/table_model.cpp | 10 | ||||
-rw-r--r-- | src/gui/table_model.h | 5 | ||||
-rw-r--r-- | src/main.cpp | 3 | ||||
-rw-r--r-- | src/net/beinghandler.cpp | 14 | ||||
-rw-r--r-- | src/net/network.h | 4 | ||||
-rw-r--r-- | src/net/skillhandler.cpp | 1 |
9 files changed, 184 insertions, 64 deletions
diff --git a/src/gui/skill.cpp b/src/gui/skill.cpp index 8cf1e06d..32c961bd 100644 --- a/src/gui/skill.cpp +++ b/src/gui/skill.cpp @@ -18,63 +18,119 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: skill.cpp 3754 2007-11-20 15:19:50Z b_lindeijer $ + * $Id$ */ +#include <algorithm> + #include <guichan/widgets/label.hpp> #include "skill.h" #include "button.h" #include "listbox.h" -#include "scrollarea.h" #include "windowcontainer.h" #include "../localplayer.h" #include "../utils/dtor.h" +#include "../utils/xml.h" +#include "log.h" + +#define SKILLS_FILE "skills.xml" -const char *skill_db[] = { - // 0-99 - "", "Basic", "Sword", "Two hand", "HP regeneration", "Bash", "Provoke", "Magnum", "Endure", "MP regeneration", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "MAX weight", "Discount", "Overcharge", "", - "Identify", "", "", "", "", "", "", "", "Double", "Miss", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - // 100-199 - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "First aid", "Play as dead", "Moving recovery", "Fatal blow", "Auto berserk", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", +struct SkillInfo { + std::string name; + bool modifiable; +}; + +std::vector<SkillInfo> skill_db; + +static void initSkillinfo(void); + +class SkillGuiTableModel : public StaticTableModel +{ +public: + SkillGuiTableModel(SkillDialog *dialog) : + StaticTableModel(0, 3) + { + mEntriesNr = 0; + mDialog = dialog; + update(); + } + + virtual int + getRows(void) { return mEntriesNr; } + + virtual int + getColumnWidth(int index) + { + switch (index) { + case 0: return 160; + default: return 35; + } + } + + virtual int + getRowHeight(void) + { + return 12; + } + + virtual void + update(void) + { + mEntriesNr = mDialog->getSkills().size(); + resize(); + + for (int i = 0; i < mEntriesNr; i++) { + SKILL *skill = mDialog->getSkills()[i]; + SkillInfo *info = &skill_db[skill->id]; + char tmp[128]; + + sprintf(tmp, "%c%s", info->modifiable? ' ' : '*', info->name.c_str()); + gcn::Label *name_label = new gcn::Label(std::string(tmp)); + + sprintf(tmp, "Lv:%i", skill->lv); + gcn::Label *lv_label = new gcn::Label(std::string(tmp)); + + sprintf(tmp, "Sp:%i", skill->sp); + gcn::Label *sp_label = new gcn::Label(std::string(tmp)); + + set(i, 0, name_label); + set(i, 1, lv_label); + set(i, 2, sp_label); + } + } + + +private: + SkillDialog *mDialog; + int mEntriesNr; }; SkillDialog::SkillDialog(): Window("Skills") { + initSkillinfo(); + mTableModel = new SkillGuiTableModel(this); + mTable.setModel(mTableModel); + mTable.setLinewiseSelection(true); + setWindowName("Skills"); setCloseButton(true); setDefaultSize(windowContainer->getWidth() - 255, 25, 240, 240); - mSkillListBox = new ListBox(this); - ScrollArea *skillScrollArea = new ScrollArea(mSkillListBox); +// mSkillListBox = new ListBox(this); + skillScrollArea = new ScrollArea(&mTable); mPointsLabel = new gcn::Label("Skill Points:"); mIncButton = new Button("Up", "inc", this); mUseButton = new Button("Use", "use", this); mUseButton->setEnabled(false); - mSkillListBox->setActionEventId("skill"); +// mSkillListBox->setActionEventId("skill"); + mTable.setActionEventId("skill"); skillScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER); skillScrollArea->setDimension(gcn::Rectangle(5, 5, 230, 180)); @@ -88,7 +144,8 @@ SkillDialog::SkillDialog(): add(mIncButton); add(mUseButton); - mSkillListBox->addActionListener(this); +// mSkillListBox->addActionListener(this); + mTable.addActionListener(this); setLocationRelativeTo(getParent()); loadWindowState(); @@ -96,7 +153,6 @@ SkillDialog::SkillDialog(): SkillDialog::~SkillDialog() { - cleanList(); } void SkillDialog::action(const gcn::ActionEvent &event) @@ -104,7 +160,7 @@ void SkillDialog::action(const gcn::ActionEvent &event) if (event.getId() == "inc") { // Increment skill - int selectedSkill = mSkillListBox->getSelected(); + int selectedSkill = mTable.getSelectedRow();//mSkillListBox->getSelected(); if (selectedSkill >= 0) { player_node->raiseSkill(mSkillList[selectedSkill]->id); @@ -113,7 +169,7 @@ void SkillDialog::action(const gcn::ActionEvent &event) else if (event.getId() == "skill") { mIncButton->setEnabled( - mSkillListBox->getSelected() > -1 && + mTable.getSelectedRow() > -1 && player_node->mSkillPoint > 0); } else if (event.getId() == "close") @@ -130,8 +186,13 @@ void SkillDialog::update() mPointsLabel->setCaption(tmp); } - mIncButton->setEnabled(mSkillListBox->getSelected() > -1 && - player_node->mSkillPoint > 0); + int selectedSkill = mTable.getSelectedRow(); + + mIncButton->setEnabled(selectedSkill > -1 + && skill_db[mSkillList[selectedSkill]->id].modifiable + && player_node->mSkillPoint > 0); + + mTableModel->update(); } int SkillDialog::getNumberOfElements() @@ -139,20 +200,6 @@ int SkillDialog::getNumberOfElements() return mSkillList.size(); } -std::string SkillDialog::getElementAt(int i) -{ - if (i >= 0 && i < (int)mSkillList.size()) - { - char tmp[128]; - sprintf(tmp, "%s Lv: %i Sp: %i", - skill_db[mSkillList[i]->id], - mSkillList[i]->lv, - mSkillList[i]->sp); - return tmp; - } - return ""; -} - bool SkillDialog::hasSkill(int id) { for (unsigned int i = 0; i < mSkillList.size(); i++) { @@ -184,6 +231,42 @@ void SkillDialog::setSkill(int id, int lvl, int mp) void SkillDialog::cleanList() { - delete_all(mSkillList); + for_each(mSkillList.begin(), mSkillList.end(), make_dtor(mSkillList)); mSkillList.clear(); } + +static void +initSkillinfo(void) +{ + SkillInfo emptySkillInfo = { "", false }; + + XML::Document doc(SKILLS_FILE); + xmlNodePtr root = doc.rootNode(); + + if (!root || !xmlStrEqual(root->name, BAD_CAST "skills")) + { + logger->log("Error loading skills file: " + SKILLS_FILE); + skill_db.resize(2, emptySkillInfo); + skill_db[1].name = "Basic"; + skill_db[1].modifiable = true; + return; + } + + for_each_xml_child_node(node, root) + { + if (xmlStrEqual(node->name, BAD_CAST "skill")) + { + int index = atoi(XML::getProperty(node, "id", "-1").c_str()); + std::string name = XML::getProperty(node, "name", ""); + bool modifiable = !atoi(XML::getProperty(node, "fixed", "0").c_str()); + + if (index >= 0) { + skill_db.resize(index + 1, emptySkillInfo); + skill_db[index].name = name; + skill_db[index].modifiable = modifiable; + } + } + } +} + diff --git a/src/gui/skill.h b/src/gui/skill.h index 6bd6c51b..92badc8a 100644 --- a/src/gui/skill.h +++ b/src/gui/skill.h @@ -18,7 +18,7 @@ * along with The Mana World; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: skill.h 3494 2007-08-20 05:29:12Z joshlangley $ + * $Id$ */ #ifndef _TMW_SKILL_H @@ -26,9 +26,11 @@ #include <vector> -#include <guichan/listmodel.hpp> #include <guichan/actionlistener.hpp> +#include <guichan/listmodel.hpp> +#include "scrollarea.h" +#include "table.h" #include "window.h" #include "../guichanfwd.h" @@ -38,13 +40,14 @@ struct SKILL { short lv, sp; }; +class SkillGuiTableModel; + /** * The skill dialog. * * \ingroup Interface */ -class SkillDialog : public Window, public gcn::ActionListener, - public gcn::ListModel +class SkillDialog : public Window, public gcn::ActionListener { public: /** @@ -62,15 +65,18 @@ class SkillDialog : public Window, public gcn::ActionListener, void update(); int getNumberOfElements(); - std::string getElementAt(int); bool hasSkill(int id); void addSkill(int id, int lv, int sp); void setSkill(int id, int lv, int sp); void cleanList(); + const std::vector<SKILL*>& getSkills(void) const { return mSkillList; } + private: - gcn::ListBox *mSkillListBox; + GuiTable mTable;//gcn::ListBox *mSkillListBox; + ScrollArea *skillScrollArea; + SkillGuiTableModel *mTableModel; gcn::Label *mPointsLabel; gcn::Button *mIncButton; gcn::Button *mUseButton; diff --git a/src/gui/table.cpp b/src/gui/table.cpp index 89a93825..8d2ab86a 100644 --- a/src/gui/table.cpp +++ b/src/gui/table.cpp @@ -102,11 +102,14 @@ GuiTable::setModel(TableModel *new_model) mModel->removeListener(this); } + mModel = new_model; installActionListeners(); - new_model->installListener(this); - recomputeDimensions(); + if (new_model) { + new_model->installListener(this); + recomputeDimensions(); + } } @@ -187,6 +190,9 @@ GuiTable::uninstallActionListeners(void) void GuiTable::installActionListeners(void) { + if (!mModel) + return; + int rows = mModel->getRows(); int columns = mModel->getColumns(); @@ -367,7 +373,7 @@ GuiTable::getWidgetAt(int x, int y) if (row > -1 && column > -1) { gcn::Widget *w = mModel->getElementAt(row, column); - if (w->isFocusable()) + if (w && w->isFocusable()) return w; else return NULL; // Grab the event locally diff --git a/src/gui/table_model.cpp b/src/gui/table_model.cpp index 78df0636..57da29d9 100644 --- a/src/gui/table_model.cpp +++ b/src/gui/table_model.cpp @@ -71,10 +71,18 @@ StaticTableModel::~StaticTableModel(void) } void +StaticTableModel::resize(void) +{ + mRows = getRows(); + mColumns = getColumns(); + mTableModel.resize(mRows * mColumns, NULL); +} + +void StaticTableModel::set(int row, int column, gcn::Widget *widget) { if (row >= mRows || row < 0 - || column >= mColumns || row > 0) + || column >= mColumns || column < 0) // raise exn? return; diff --git a/src/gui/table_model.h b/src/gui/table_model.h index 48ef1c0d..69e41cd3 100644 --- a/src/gui/table_model.h +++ b/src/gui/table_model.h @@ -120,6 +120,11 @@ public: */ virtual void fixRowHeight(int height); + /** + * Resizes the table model + */ + virtual void resize(void); + virtual int getRows(); virtual int getColumns(); virtual int getRowHeight(); diff --git a/src/main.cpp b/src/main.cpp index d41acba0..db7b16d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -623,7 +623,8 @@ void charLogin(Network *network, LoginData *loginData) outMsg.writeInt32(loginData->account_ID); outMsg.writeInt32(loginData->session_ID1); outMsg.writeInt32(loginData->session_ID2); - outMsg.writeInt16(0); // unknown + // [Fate] The next word is unused by the old char server, so we squeeze in tmw client version information + outMsg.writeInt16(TMW_CLIENT_PROTOCOL_VERSION); outMsg.writeInt8(loginData->sex); // We get 4 useless bytes before the real answer comes in diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp index 85e18e5a..f19fd39c 100644 --- a/src/net/beinghandler.cpp +++ b/src/net/beinghandler.cpp @@ -406,8 +406,8 @@ void BeingHandler::handleMessage(MessageIn *msg) headTop = msg->readInt16(); headMid = msg->readInt16(); hairColor = msg->readInt16(); - shoes = msg->readInt16(); - gloves = msg->readInt16(); + msg->readInt16(); // clothes color + msg->readInt16(); // head direction msg->readInt32(); // guild msg->readInt32(); // emblem msg->readInt16(); // manner @@ -450,9 +450,15 @@ void BeingHandler::handleMessage(MessageIn *msg) if (msg->getId() == SMSG_PLAYER_UPDATE_1) { - if (msg->readInt8() == 2) + switch (msg->readInt8()) { - dstBeing->setAction(Being::SIT); + case 1: + dstBeing->setAction(Being::DEAD); + break; + + case 2: + dstBeing->setAction(Being::SIT); + break; } } else if (msg->getId() == SMSG_PLAYER_MOVE) diff --git a/src/net/network.h b/src/net/network.h index 53800b1e..826e6776 100644 --- a/src/net/network.h +++ b/src/net/network.h @@ -29,6 +29,10 @@ #include <SDL_thread.h> #include <string> +#define TMW_CLIENT_PROTOCOL_VERSION 1 + /***< Protocol version, reported to the eAthena char and mapserver who + can adjust the protocol accordingly */ + class MessageHandler; class MessageIn; diff --git a/src/net/skillhandler.cpp b/src/net/skillhandler.cpp index 1f9403f4..3685d04b 100644 --- a/src/net/skillhandler.cpp +++ b/src/net/skillhandler.cpp @@ -73,6 +73,7 @@ void SkillHandler::handleMessage(MessageIn *msg) } } } + skillDialog->update(); break; case SMSG_SKILL_FAILED: |