00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gui/status.h"
00023 #include "gui/palette.h"
00024
00025 #include "localplayer.h"
00026 #include "units.h"
00027
00028 #include "gui/widgets/button.h"
00029 #include "gui/widgets/label.h"
00030 #include "gui/widgets/layout.h"
00031 #include "gui/widgets/progressbar.h"
00032 #include "gui/widgets/windowcontainer.h"
00033
00034 #include "net/net.h"
00035 #include "net/ea/playerhandler.h"
00036
00037 #include "utils/gettext.h"
00038 #include "utils/mathutils.h"
00039 #include "utils/strprintf.h"
00040 #include "utils/stringutils.h"
00041
00042 StatusWindow::StatusWindow(LocalPlayer *player):
00043 Window(player->getName()),
00044 mPlayer(player),
00045 mCurrency(0)
00046 {
00047 setWindowName("Status");
00048 setCloseButton(true);
00049 setSaveVisible(true);
00050 setDefaultSize(400, 345, ImageRect::CENTER);
00051
00052
00053
00054
00055
00056 mLvlLabel = new Label(strprintf(_("Level: %d"), 0));
00057 mJobLvlLabel = new Label(strprintf(_("Job: %d"), 0));
00058 mGpLabel = new Label(strprintf(_("Money: %s"),
00059 Units::formatCurrency(mCurrency).c_str()));
00060
00061 mHpLabel = new Label(_("HP:"));
00062 mHpBar = new ProgressBar(1.0f, 80, 15, 0, 171, 34);
00063
00064 mXpLabel = new Label(_("Exp:"));
00065 mXpBar = new ProgressBar(1.0f, 80, 15, 143, 192, 211);
00066
00067 mMpLabel = new Label(_("MP:"));
00068 mMpBar = new ProgressBar(1.0f, 80, 15, 26, 102, 230);
00069
00070 mJobLabel = new Label(_("Job:"));
00071 mJobBar = new ProgressBar(1.0f, 80, 15, 220, 135, 203);
00072
00073
00074
00075
00076
00077
00078 gcn::Label *mStatsTitleLabel = new Label(_("Stats"));
00079 gcn::Label *mStatsTotalLabel = new Label(_("Total"));
00080 gcn::Label *mStatsCostLabel = new Label(_("Cost"));
00081 mStatsTotalLabel->setAlignment(gcn::Graphics::CENTER);
00082
00083
00084 mStatsAttackLabel = new Label(_("Attack:"));
00085 mStatsDefenseLabel= new Label(_("Defense:"));
00086 mStatsMagicAttackLabel = new Label(_("M.Attack:"));
00087 mStatsMagicDefenseLabel = new Label(_("M.Defense:"));
00088
00089 mStatsAccuracyLabel = new Label(_("% Accuracy:"));
00090
00091 mStatsEvadeLabel = new Label(_("% Evade:"));
00092
00093 mStatsReflexLabel = new Label(_("% Reflex:"));
00094
00095 mStatsAttackPoints = new Label;
00096 mStatsDefensePoints = new Label;
00097 mStatsMagicAttackPoints = new Label;
00098 mStatsMagicDefensePoints = new Label;
00099 mStatsAccuracyPoints = new Label;
00100 mStatsEvadePoints = new Label;
00101 mStatsReflexPoints = new Label;
00102
00103
00104 for (int i = 0; i < 6; i++)
00105 {
00106 mStatsLabel[i] = new Label("0");
00107 mStatsLabel[i]->setAlignment(gcn::Graphics::CENTER);
00108 mStatsDisplayLabel[i] = new Label;
00109 mPointsLabel[i] = new Label("0");
00110 mPointsLabel[i]->setAlignment(gcn::Graphics::CENTER);
00111 }
00112 mRemainingStatsPointsLabel = new Label;
00113
00114
00115 mStatsButton[0] = new Button("+", "STR", this);
00116 mStatsButton[1] = new Button("+", "AGI", this);
00117 mStatsButton[2] = new Button("+", "VIT", this);
00118 mStatsButton[3] = new Button("+", "INT", this);
00119 mStatsButton[4] = new Button("+", "DEX", this);
00120 mStatsButton[5] = new Button("+", "LUK", this);
00121
00122
00123 ContainerPlacer place;
00124 place = getPlacer(0, 0);
00125
00126 place(0, 0, mLvlLabel, 3);
00127 place(5, 0, mJobLvlLabel, 3);
00128 place(8, 0, mGpLabel, 3);
00129 place(1, 1, mHpLabel).setPadding(3);
00130 place(2, 1, mHpBar, 3);
00131 place(6, 1, mXpLabel).setPadding(3);
00132 place(7, 1, mXpBar, 3);
00133 place(1, 2, mMpLabel).setPadding(3);
00134 place(2, 2, mMpBar, 3);
00135 place(6, 2, mJobLabel).setPadding(3);
00136 place(7, 2, mJobBar, 3);
00137 place.getCell().matchColWidth(0, 1);
00138 place = getPlacer(0, 3);
00139 place(0, 0, mStatsTitleLabel, 5);
00140 place(5, 1, mStatsTotalLabel, 5);
00141 place(12, 1, mStatsCostLabel, 5);
00142 for (int i = 0; i < 6; i++)
00143 {
00144 place(0, 2 + i, mStatsLabel[i], 7).setPadding(5);
00145 place(7, 2 + i, mStatsDisplayLabel[i]).setPadding(5);
00146 place(10, 2 + i, mStatsButton[i]);
00147 place(12, 2 + i, mPointsLabel[i]).setPadding(5);
00148 }
00149 place(14, 2, mStatsAttackLabel, 7).setPadding(5);
00150 place(14, 3, mStatsDefenseLabel, 7).setPadding(5);
00151 place(14, 4, mStatsMagicAttackLabel, 7).setPadding(5);
00152 place(14, 5, mStatsMagicDefenseLabel, 7).setPadding(5);
00153 place(14, 6, mStatsAccuracyLabel, 7).setPadding(5);
00154 place(14, 7, mStatsEvadeLabel, 7).setPadding(5);
00155 place(14, 8, mStatsReflexLabel, 7).setPadding(5);
00156 place(21, 2, mStatsAttackPoints, 3).setPadding(5);
00157 place(21, 3, mStatsDefensePoints, 3).setPadding(5);
00158 place(21, 4, mStatsMagicAttackPoints, 3).setPadding(5);
00159 place(21, 5, mStatsMagicDefensePoints, 3).setPadding(5);
00160 place(21, 6, mStatsAccuracyPoints, 3).setPadding(5);
00161 place(21, 7, mStatsEvadePoints, 3).setPadding(5);
00162 place(21, 8, mStatsReflexPoints, 3).setPadding(5);
00163 place(0, 8, mRemainingStatsPointsLabel, 3).setPadding(5);
00164
00165 Layout &layout = getLayout();
00166 layout.setRowHeight(0, Layout::AUTO_SET);
00167
00168 loadWindowState();
00169 }
00170
00171 void StatusWindow::update()
00172 {
00173
00174
00175 mLvlLabel->setCaption(strprintf(_("Level: %d"), mPlayer->getLevel()));
00176 mLvlLabel->adjustSize();
00177
00178 mJobLvlLabel->setCaption(strprintf(_("Job: %d"), mPlayer->mJobLevel));
00179 mJobLvlLabel->adjustSize();
00180
00181 if (mCurrency != mPlayer->getMoney()) {
00182 mCurrency = mPlayer->getMoney();
00183 mGpLabel->setCaption(strprintf(_("Money: %s"),
00184 Units::formatCurrency(mCurrency).c_str()));
00185 mGpLabel->adjustSize();
00186 }
00187
00188 updateHPBar(mHpBar, true);
00189
00190 updateMPBar(mMpBar, true);
00191
00192 updateXPBar(mXpBar, false);
00193
00194 updateJobBar(mJobBar, false);
00195
00196
00197
00198 static const char *attrNames[6] = {
00199 N_("Strength"),
00200 N_("Agility"),
00201 N_("Vitality"),
00202 N_("Intelligence"),
00203 N_("Dexterity"),
00204 N_("Luck")
00205 };
00206 int statusPoints = mPlayer->mStatsPointsToAttribute;
00207
00208
00209 for (int i = 0; i < 6; i++)
00210 {
00211 mStatsLabel[i]->setCaption(gettext(attrNames[i]));
00212 mStatsDisplayLabel[i]->setCaption(toString((int) mPlayer->mAttr[i]));
00213 mPointsLabel[i]->setCaption(toString((int) mPlayer->mAttrUp[i]));
00214
00215 mStatsLabel[i]->adjustSize();
00216 mStatsDisplayLabel[i]->adjustSize();
00217 mPointsLabel[i]->adjustSize();
00218
00219 mStatsButton[i]->setEnabled(mPlayer->mAttrUp[i] <= statusPoints);
00220 }
00221 mRemainingStatsPointsLabel->setCaption(
00222 strprintf(_("Remaining Status Points: %d"), statusPoints));
00223 mRemainingStatsPointsLabel->adjustSize();
00224
00225
00226
00227
00228 mStatsAttackPoints->setCaption(
00229 toString(mPlayer->ATK + mPlayer->ATK_BONUS));
00230 mStatsAttackPoints->adjustSize();
00231
00232
00233 mStatsDefensePoints->setCaption(
00234 toString(mPlayer->DEF + mPlayer->DEF_BONUS));
00235 mStatsDefensePoints->adjustSize();
00236
00237
00238 mStatsMagicAttackPoints->setCaption(
00239 toString(mPlayer->MATK + mPlayer->MATK_BONUS));
00240 mStatsMagicAttackPoints->adjustSize();
00241
00242
00243 mStatsMagicDefensePoints->setCaption(
00244 toString(mPlayer->MDEF + mPlayer->MDEF_BONUS));
00245 mStatsMagicDefensePoints->adjustSize();
00246
00247
00248 mStatsAccuracyPoints->setCaption(toString(mPlayer->HIT));
00249 mStatsAccuracyPoints->adjustSize();
00250
00251
00252 mStatsEvadePoints->setCaption(toString(mPlayer->FLEE));
00253 mStatsEvadePoints->adjustSize();
00254
00255
00256 mStatsReflexPoints->setCaption(toString(mPlayer->DEX / 4));
00257 mStatsReflexPoints->adjustSize();
00258 }
00259
00260 void StatusWindow::draw(gcn::Graphics *g)
00261 {
00262 update();
00263
00264 Window::draw(g);
00265 }
00266
00267 void StatusWindow::action(const gcn::ActionEvent &event)
00268 {
00269
00270
00271 if (event.getId().length() == 3)
00272 {
00273 if (event.getId() == "STR")
00274 Net::getPlayerHandler()->increaseStat(LocalPlayer::STR);
00275 if (event.getId() == "AGI")
00276 Net::getPlayerHandler()->increaseStat(LocalPlayer::AGI);
00277 if (event.getId() == "VIT")
00278 Net::getPlayerHandler()->increaseStat(LocalPlayer::VIT);
00279 if (event.getId() == "INT")
00280 Net::getPlayerHandler()->increaseStat(LocalPlayer::INT);
00281 if (event.getId() == "DEX")
00282 Net::getPlayerHandler()->increaseStat(LocalPlayer::DEX);
00283 if (event.getId() == "LUK")
00284 Net::getPlayerHandler()->increaseStat(LocalPlayer::LUK);
00285 }
00286 }
00287
00288 void StatusWindow::updateHPBar(ProgressBar *bar, bool showMax)
00289 {
00290 if (showMax)
00291 bar->setText(toString(player_node->getHp()) +
00292 "/" + toString(player_node->getMaxHp()));
00293 else
00294 bar->setText(toString(player_node->getHp()));
00295
00296
00297 float r1 = 255;
00298 float g1 = 255;
00299 float b1 = 255;
00300
00301 float r2 = 255;
00302 float g2 = 255;
00303 float b2 = 255;
00304
00305 float weight = 1.0f;
00306
00307 int curHP = player_node->getHp();
00308 int thresholdLevel = player_node->getMaxHp() / 4;
00309 int thresholdProgress = curHP % thresholdLevel;
00310 weight = 1-((float)thresholdProgress) / ((float)thresholdLevel);
00311
00312 if (curHP < (thresholdLevel))
00313 {
00314 gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_ONE_HALF);
00315 gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_QUARTER);
00316 r1 = color1.r; r2 = color2.r;
00317 g1 = color1.g; g2 = color2.g;
00318 b1 = color1.b; b2 = color2.b;
00319 }
00320 else if (curHP < (thresholdLevel*2))
00321 {
00322 gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS);
00323 gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_ONE_HALF);
00324 r1 = color1.r; r2 = color2.r;
00325 g1 = color1.g; g2 = color2.g;
00326 b1 = color1.b; b2 = color2.b;
00327 }
00328 else if (curHP < thresholdLevel*3)
00329 {
00330 gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL);
00331 gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_THREE_QUARTERS);
00332 r1 = color1.r; r2 = color2.r;
00333 g1 = color1.g; g2 = color2.g;
00334 b1 = color1.b; b2 = color2.b;
00335 }
00336 else
00337 {
00338 gcn::Color color1 = guiPalette->getColor(Palette::HPBAR_FULL);
00339 gcn::Color color2 = guiPalette->getColor(Palette::HPBAR_FULL);
00340 r1 = color1.r; r2 = color2.r;
00341 g1 = color1.g; g2 = color2.g;
00342 b1 = color1.b; b2 = color2.b;
00343 }
00344
00345
00346 if (weight>1.0f) weight=1.0f;
00347 if (weight<0.0f) weight=0.0f;
00348
00349
00350 r1 = (int) weightedAverage(r1, r2,weight);
00351 g1 = (int) weightedAverage(g1, g2, weight);
00352 b1 = (int) weightedAverage(b1, b2, weight);
00353
00354
00355 if (r1 > 255) r1 = 255;
00356 if (g1 > 255) g1 = 255;
00357 if (b1 > 255) b1 = 255;
00358
00359 bar->setColor(r1, g1, b1);
00360
00361 bar->setProgress((float) player_node->getHp() / (float) player_node->getMaxHp());
00362 }
00363
00364 void StatusWindow::updateMPBar(ProgressBar *bar, bool showMax)
00365 {
00366 if (showMax)
00367 bar->setText(toString(player_node->mMp) +
00368 "/" + toString(player_node->mMaxMp));
00369 else
00370 bar->setText(toString(player_node->mMp));
00371
00372 if (player_node->MATK <= 0)
00373 bar->setColor(100, 100, 100);
00374 else
00375 bar->setColor(26, 102, 230);
00376
00377 bar->setProgress((float) player_node->mMp / (float) player_node->mMaxMp);
00378 }
00379
00380 void StatusWindow::updateXPBar(ProgressBar *bar, bool percent)
00381 {
00382 if (player_node->mXpForNextLevel == 0) {
00383 bar->setText(_("Max level"));
00384 bar->setProgress(1.0);
00385 } else {
00386 if (percent)
00387 {
00388 float xp = (float) player_node->getXp() /
00389 player_node->mXpForNextLevel;
00390 bar->setText(toString((float) ((int) (xp * 10000.0f)) / 100.0f) +
00391 "%");
00392 }
00393 else
00394 bar->setText(toString(player_node->getXp()) +
00395 "/" + toString(player_node->mXpForNextLevel));
00396
00397 bar->setProgress((float) player_node->getXp() /
00398 (float) player_node->mXpForNextLevel);
00399 }
00400 }
00401
00402 void StatusWindow::updateJobBar(ProgressBar *bar, bool percent)
00403 {
00404 if (player_node->mJobXpForNextLevel == 0) {
00405 bar->setText(_("Max level"));
00406 bar->setProgress(1.0);
00407 } else {
00408 if (percent)
00409 {
00410 float xp = (float) player_node->mJobXp /
00411 player_node->mJobXpForNextLevel;
00412 bar->setText(toString((float) ((int) (xp * 10000.0f)) / 100.0f) +
00413 "%");
00414 }
00415 else
00416 bar->setText(toString(player_node->mJobXp) +
00417 "/" + toString(player_node->mJobXpForNextLevel));
00418
00419 bar->setProgress((float) player_node->mJobXp /
00420 (float) player_node->mJobXpForNextLevel);
00421 }
00422 }