00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gui/skill.h"
00023
00024 #include "gui/table.h"
00025
00026 #include "gui/widgets/button.h"
00027 #include "gui/widgets/label.h"
00028 #include "gui/widgets/layout.h"
00029 #include "gui/widgets/listbox.h"
00030 #include "gui/widgets/scrollarea.h"
00031 #include "gui/widgets/windowcontainer.h"
00032
00033 #include "localplayer.h"
00034 #include "log.h"
00035
00036 #include "utils/dtor.h"
00037 #include "utils/gettext.h"
00038 #include "utils/strprintf.h"
00039 #include "utils/xml.h"
00040
00041 static const char *SKILLS_FILE = _("skills.xml");
00042
00043 struct SkillInfo
00044 {
00045 std::string name;
00046 bool modifiable;
00047 };
00048
00049 static const SkillInfo fakeSkillInfo = {
00050 _("Mystery Skill"),
00051 false
00052 };
00053
00054 std::vector<SkillInfo> skill_db;
00055
00056 static void initSkillinfo();
00057
00058 class SkillGuiTableModel : public StaticTableModel
00059 {
00060 public:
00061 SkillGuiTableModel(SkillDialog *dialog) :
00062 StaticTableModel(0, 3)
00063 {
00064 mEntriesNr = 0;
00065 mDialog = dialog;
00066 update();
00067 }
00068
00069 virtual int getRows(void)
00070 {
00071 return mEntriesNr;
00072 }
00073
00074 virtual int getColumnWidth(int index)
00075 {
00076 if (index == 0)
00077 return 160;
00078
00079 return 35;
00080 }
00081
00082 virtual int getRowHeight()
00083 {
00084 return 12;
00085 }
00086
00087 virtual void update()
00088 {
00089 mEntriesNr = mDialog->getSkills().size();
00090 resize();
00091
00092 for (int i = 0; i < mEntriesNr; i++)
00093 {
00094 SKILL *skill = mDialog->getSkills()[i];
00095 SkillInfo const *info;
00096 char tmp[128];
00097
00098 if (skill->id >= 0
00099 && (unsigned int) skill->id < skill_db.size())
00100 info = &skill_db[skill->id];
00101 else
00102 info = &fakeSkillInfo;
00103
00104 sprintf(tmp, "%c%s", info->modifiable? ' ' : '*', info->name.c_str());
00105 gcn::Label *name_label = new Label(tmp);
00106
00107 sprintf(tmp, "Lv:%i", skill->lv);
00108 gcn::Label *lv_label = new Label(tmp);
00109
00110 sprintf(tmp, "Sp:%i", skill->sp);
00111 gcn::Label *sp_label = new Label(tmp);
00112
00113 set(i, 0, name_label);
00114 set(i, 1, lv_label);
00115 set(i, 2, sp_label);
00116 }
00117 }
00118
00119 private:
00120 SkillDialog *mDialog;
00121 int mEntriesNr;
00122 };
00123
00124
00125 SkillDialog::SkillDialog():
00126 Window(_("Skills"))
00127 {
00128 initSkillinfo();
00129 mTableModel = new SkillGuiTableModel(this);
00130 mTable = new GuiTable(mTableModel);
00131 mTable->setOpaque(false);
00132 mTable->setLinewiseSelection(true);
00133 mTable->setWrappingEnabled(true);
00134 mTable->setActionEventId("skill");
00135 mTable->addActionListener(this);
00136
00137 setWindowName("Skills");
00138 setCloseButton(true);
00139 setDefaultSize(255, 260, ImageRect::CENTER);
00140
00141 setMinHeight(50 + mTableModel->getHeight());
00142 setMinWidth(200);
00143
00144 ScrollArea *skillScrollArea = new ScrollArea(mTable);
00145 mPointsLabel = new Label(strprintf(_("Skill points: %d"), 0));
00146 mIncButton = new Button(_("Up"), "inc", this);
00147 mUseButton = new Button(_("Use"), "use", this);
00148 mUseButton->setEnabled(false);
00149
00150 skillScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
00151
00152 place(0, 0, skillScrollArea, 5).setPadding(3);
00153 place(0, 1, mPointsLabel, 2);
00154 place(3, 2, mIncButton);
00155 place(4, 2, mUseButton);
00156
00157 Layout &layout = getLayout();
00158 layout.setRowHeight(0, Layout::AUTO_SET);
00159
00160 center();
00161 loadWindowState();
00162 }
00163
00164 SkillDialog::~SkillDialog()
00165 {
00166 delete_all(mSkillList);
00167 }
00168
00169 void SkillDialog::action(const gcn::ActionEvent &event)
00170 {
00171 if (event.getId() == "inc")
00172 {
00173
00174 int selectedSkill = mTable->getSelectedRow();
00175 if (selectedSkill >= 0)
00176 player_node->raiseSkill(mSkillList[selectedSkill]->id);
00177 }
00178 else if (event.getId() == "skill" && mTable->getSelectedRow() > -1)
00179 {
00180 SKILL *skill = mSkillList[mTable->getSelectedRow()];
00181 SkillInfo const *info;
00182
00183 if (skill->id >= 0 && (unsigned int) skill->id < skill_db.size())
00184 info = &skill_db[skill->id];
00185 else
00186 info = &fakeSkillInfo;
00187
00188 mIncButton->setEnabled(player_node->mSkillPoint > 0 &&
00189 info->modifiable);
00190 }
00191 else if (event.getId() == "close")
00192 setVisible(false);
00193 }
00194
00195 void SkillDialog::update()
00196 {
00197 mPointsLabel->setCaption(strprintf(_("Skill points: %d"),
00198 player_node->mSkillPoint));
00199
00200 int selectedSkill = mTable->getSelectedRow();
00201
00202 if (selectedSkill >= 0)
00203 {
00204 int skillId = mSkillList[selectedSkill]->id;
00205 bool modifiable;
00206
00207 if (skillId >= 0 && (unsigned int) skillId < skill_db.size())
00208 modifiable = skill_db[skillId].modifiable;
00209 else
00210 modifiable = false;
00211
00212 mIncButton->setEnabled(modifiable
00213 && player_node->mSkillPoint > 0);
00214 }
00215 else
00216 mIncButton->setEnabled(false);
00217
00218 mTableModel->update();
00219 setMinHeight(50 + mTableModel->getHeight());
00220 }
00221
00222 int SkillDialog::getNumberOfElements()
00223 {
00224 return mSkillList.size();
00225 }
00226
00227 bool SkillDialog::hasSkill(int id)
00228 {
00229 for (unsigned int i = 0; i < mSkillList.size(); i++)
00230 {
00231 if (mSkillList[i]->id == id)
00232 return true;
00233 }
00234 return false;
00235 }
00236
00237 void SkillDialog::addSkill(int id, int lvl, int mp)
00238 {
00239 SKILL *tmp = new SKILL;
00240 tmp->id = id;
00241 tmp->lv = lvl;
00242 tmp->sp = mp;
00243 mSkillList.push_back(tmp);
00244 }
00245
00246 void SkillDialog::setSkill(int id, int lvl, int mp)
00247 {
00248 for (unsigned int i = 0; i < mSkillList.size(); i++)
00249 {
00250 if (mSkillList[i]->id == id)
00251 {
00252 mSkillList[i]->lv = lvl;
00253 mSkillList[i]->sp = mp;
00254 }
00255 }
00256 }
00257
00258 void SkillDialog::cleanList()
00259 {
00260 delete_all(mSkillList);
00261 mSkillList.clear();
00262 }
00263
00264 static void initSkillinfo()
00265 {
00266 SkillInfo emptySkillInfo = { "", false };
00267
00268 XML::Document doc(SKILLS_FILE);
00269 xmlNodePtr root = doc.rootNode();
00270
00271 if (!root || !xmlStrEqual(root->name, BAD_CAST "skills"))
00272 {
00273 logger->log("Error loading skills file: %s", SKILLS_FILE);
00274 skill_db.resize(2, emptySkillInfo);
00275 skill_db[1].name = "Basic";
00276 skill_db[1].modifiable = true;
00277 return;
00278 }
00279
00280 for_each_xml_child_node(node, root)
00281 {
00282 if (xmlStrEqual(node->name, BAD_CAST "skill"))
00283 {
00284 int index = atoi(XML::getProperty(node, "id", "-1").c_str());
00285 std::string name = XML::getProperty(node, "name", "");
00286 bool modifiable = !atoi(XML::getProperty(node, "fixed", "0").c_str());
00287
00288 if (index >= 0)
00289 {
00290 skill_db.resize(index + 1, emptySkillInfo);
00291 skill_db[index].name = name;
00292 skill_db[index].modifiable = modifiable;
00293 }
00294 }
00295 }
00296 }
00297