ManaPlus
statuswindow.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
24 
25 #include "configuration.h"
26 #include "gamemodifiers.h"
27 #include "settings.h"
28 
29 #include "being/localplayer.h"
30 #include "being/playerinfo.h"
31 
32 #include "enums/gui/layouttype.h"
33 
34 #include "gui/windows/chatwindow.h"
35 
38 
39 #include "gui/widgets/button.h"
41 #include "gui/widgets/layout.h"
43 #include "gui/widgets/statspage.h"
45 #include "gui/widgets/tabbedarea.h"
47 
48 #include "net/inventoryhandler.h"
49 #include "net/playerhandler.h"
50 
51 #include "resources/db/groupdb.h"
52 #include "resources/db/unitsdb.h"
53 #include "resources/db/statdb.h"
54 
55 #include "resources/item/item.h"
56 
57 #include "utils/delete2.h"
58 #include "utils/dtor.h"
59 #include "utils/foreach.h"
60 #include "utils/gettext.h"
61 
62 #include "debug.h"
63 
65 
68  "?", Modal_false, nullptr, "status.xml"),
71  mPages(),
72  mTabs(CREATEWIDGETR(TabbedArea, this)),
73  // TRANSLATORS: status window label
74  mLvlLabel(new Label(this, strprintf(_("Level: %d"), 0))),
75  // TRANSLATORS: status window label
76  mMoneyLabel(new Label(this, strprintf(_("Money: %s"), ""))),
77  // TRANSLATORS: status window label
78  mHpLabel(new Label(this, _("HP:"))),
79  mMpLabel(nullptr),
80  // TRANSLATORS: status window label
81  mXpLabel(new Label(this, _("Exp:"))),
82  mHpBar(nullptr),
83  mMpBar(nullptr),
84  mXpBar(nullptr),
85  mJobLvlLabel(nullptr),
86  mJobLabel(nullptr),
87  mJobBar(nullptr),
88  mBasicStatsPage(new StatsPageBasic(this)),
89  // TRANSLATORS: status window button
90  mCopyButton(new Button(this, _("Copy to chat"), "copy", this))
91 {
92  setWindowName("Status");
93  if (setupWindow != nullptr)
95  setResizable(true);
96  setCloseButton(true);
97  setSaveVisible(true);
98  setStickyButtonLock(true);
100  (windowContainer->getHeight() - 500) / 2,
101  480,
102  500);
103 
104  mTabs->setSelectable(false);
107 
108  if ((localPlayer != nullptr) && !localPlayer->getRaceName().empty())
109  {
110  setCaption(strprintf("%s (%s)", localPlayer->getName().c_str(),
111  localPlayer->getRaceName().c_str()));
112  }
113 
115  if (max == 0)
116  max = 1;
117 
118  mHpBar = new ProgressBar(this,
120  / static_cast<float>(max),
121  80,
122  0,
124  "hpprogressbar.xml", "hpprogressbar_fill.xml");
127  mHpBar->setSelectable(false);
128 
129  const int64_t maxExp = PlayerInfo::getAttribute64(
131  mXpBar = new ProgressBar(this,
132  maxExp != 0 ?
133  static_cast<float>(PlayerInfo::getAttribute64(
135  static_cast<float>(maxExp) : static_cast<float>(0),
136  80,
137  0,
139  "xpprogressbar.xml", "xpprogressbar_fill.xml");
142  mXpBar->setSelectable(false);
143 
144  const bool job = serverConfig.getValueBool("showJob", true);
145 
147  // TRANSLATORS: status window label
148  mMpLabel = new Label(this, _("MP:"));
149  const bool useMagic = playerHandler->canUseMagic();
150  mMpBar = new ProgressBar(this,
151  max != 0 ? static_cast<float>(PlayerInfo::getAttribute(
152  Attributes::PLAYER_MAX_MP)) / static_cast<float>(max)
153  : static_cast<float>(0),
154  80,
155  0,
157  useMagic ? "mpprogressbar.xml" : "nompprogressbar.xml",
158  useMagic ? "mpprogressbar_fill.xml" : "nompprogressbar_fill.xml");
159  mMpBar->setSelectable(false);
160  if (useMagic)
161  {
164  }
165  else
166  {
169  }
170 
171  place(0, 0, mLvlLabel, 3, 1);
172  place(0, 1, mHpLabel, 1, 1).setPadding(3);
173  place(1, 1, mHpBar, 4, 1);
174  place(5, 1, mXpLabel, 1, 1).setPadding(3);
175  place(6, 1, mXpBar, 5, 1);
176  place(0, 2, mMpLabel, 1, 1).setPadding(3);
177  // 5, 2 and 6, 2 Job Progress Bar
178  if (job)
179  place(1, 2, mMpBar, 4, 1);
180  else
181  place(1, 2, mMpBar, 10, 1);
182 
183  if (job)
184  {
185  // TRANSLATORS: status window label
186  mJobLvlLabel = new Label(this, strprintf(_("Job: %d"), 0));
187  // TRANSLATORS: status window label
188  mJobLabel = new Label(this, _("Job:"));
189  mJobBar = new ProgressBar(this, 0.0F, 80, 0, ProgressColorId::PROG_JOB,
190  "jobprogressbar.xml", "jobprogressbar_fill.xml");
193  mJobBar->setSelectable(false);
194 
195  place(3, 0, mJobLvlLabel, 3, 1);
196  place(5, 2, mJobLabel, 1, 1).setPadding(3);
197  place(6, 2, mJobBar, 5, 1);
198  place(6, 0, mMoneyLabel, 3, 1);
199  }
200  else
201  {
202  mJobLvlLabel = nullptr;
203  mJobLabel = nullptr;
204  mJobBar = nullptr;
205  place(3, 0, mMoneyLabel, 3, 1);
206  }
207 
208  place(0, 3, mTabs, 11, 3);
209 
211 
212  place(0, 5, mCopyButton, 1, 1);
213 
214  loadWindowState();
215  enableVisibleSound(true);
216 
217  // Update bars
218  updateHPBar(mHpBar, true);
219  updateMPBar(mMpBar, true);
220  updateXPBar(mXpBar, false);
221 
222  // TRANSLATORS: status window label
223  mMoneyLabel->setCaption(strprintf(_("Money: %s"),
225  Attributes::MONEY)).c_str()));
227 
229  addTabs();
230 }
231 
233 {
236 }
237 
239 {
240  // TRANSLATORS: status window tab name
241  addTabBasic(_("Basic"));
242  const STD_VECTOR<std::string> &pages = StatDb::getPages();
243  FOR_EACH(STD_VECTOR<std::string>::const_iterator, it, pages)
244  {
245  addTab(*it);
246  }
247  mTabs->adjustSize();
248 }
249 
250 void StatusWindow::addTab(const std::string &name)
251 {
252  StatsPage *const page = new StatsPage(this, name);
253  mTabs->addTab(name,
254  page);
255  mPages.push_back(page);
256 }
257 
258 void StatusWindow::addTabBasic(const std::string &name)
259 {
260  mTabs->addTab(name,
262 }
263 
265 {
266  if (localPlayer == nullptr)
267  return;
268 
269  const int groupId = localPlayer->getGroupId();
270  const std::string &name = GroupDb::getName(groupId);
271  if (!name.empty())
272  {
273  // TRANSLATORS: status window label
274  mLvlLabel->setCaption(strprintf(_("Level: %d (%s %d)"),
276  name.c_str(),
277  groupId));
278  }
279  else
280  {
281  // TRANSLATORS: status window label
282  mLvlLabel->setCaption(strprintf(_("Level: %d"),
284  }
286 }
287 
289  const int64_t oldVal,
290  const int64_t newVal)
291 {
292  static bool blocked = false;
293 
294  PRAGMA45(GCC diagnostic push)
295  PRAGMA45(GCC diagnostic ignored "-Wswitch-enum")
296  switch (id)
297  {
300  updateHPBar(mHpBar, true);
301  break;
302 
305  updateMPBar(mMpBar, true);
306  break;
307 
310  updateXPBar(mXpBar, false);
311  break;
312 
313  case Attributes::MONEY:
314  // TRANSLATORS: status window label
315  mMoneyLabel->setCaption(strprintf(_("Money: %s"),
316  UnitsDb::formatCurrency64(newVal).c_str()));
318  break;
319 
321  // TRANSLATORS: status window label
322  mLvlLabel->setCaption(strprintf(_("Level: %d"),
323  CAST_S32(newVal)));
325  break;
326 
327  // +++ probable need use only some attributes here
331  if (blocked)
332  return;
333  if (mJobLvlLabel != nullptr)
334  {
335  int lvl = PlayerInfo::getAttribute(
337  const int64_t exp = PlayerInfo::getAttribute(
339  const int64_t expNeed = PlayerInfo::getAttribute(
341 
342  if (lvl == 0)
343  {
344  // possible server broken and don't send job level,
345  // then we fixing it.
346  if (expNeed < 20000)
347  {
348  lvl = 0;
349  }
350  else
351  {
352  lvl = CAST_S32((expNeed - 20000) / 150);
353  blocked = true;
355  lvl,
356  Notify_true);
357  blocked = false;
358  }
359  }
360 
361  if (id == Attributes::PLAYER_JOB_EXP &&
362  exp < oldVal &&
363  expNeed >= 20000)
364  { // possible job level up. but server broken and don't send
365  // new job exp limit, we fixing it
366  lvl ++;
367  blocked = true;
369  20000 + lvl * 150,
370  Notify_true);
372  lvl,
373  Notify_true);
374  blocked = false;
375  }
376 
377  // TRANSLATORS: status window label
378  mJobLvlLabel->setCaption(strprintf(_("Job: %d"), lvl));
380 
381  updateJobBar(mJobBar, false);
382  }
383  break;
384 
385  default:
386  break;
387  }
388  PRAGMA45(GCC diagnostic pop)
389 }
390 
392  const int needed)
393 {
394  mBasicStatsPage->setPointsNeeded(id, needed);
395 }
396 
397 void StatusWindow::updateHPBar(ProgressBar *const bar, const bool showMax)
398 {
399  if (bar == nullptr)
400  return;
401 
404  if (showMax)
405  bar->setText(toString(hp).append("/").append(toString(maxHp)));
406  else
407  bar->setText(toString(hp));
408 
409  float prog = 1.0;
410  if (maxHp > 0)
411  prog = static_cast<float>(hp) / static_cast<float>(maxHp);
412  bar->setProgress(prog);
413 }
414 
416  const bool showMax) const
417 {
418  if (bar == nullptr)
419  return;
420 
423  if (showMax)
424  bar->setText(toString(mp).append("/").append(toString(maxMp)));
425  else
426  bar->setText(toString(mp));
427 
428  float prog = 1.0F;
429  if (maxMp > 0)
430  prog = static_cast<float>(mp) / static_cast<float>(maxMp);
431 
432  if (playerHandler->canUseMagic())
433  {
437  }
438  else
439  {
443  }
444 
445  bar->setProgress(prog);
446 }
447 
449  const int64_t value,
450  const int64_t max,
451  const bool percent)
452 {
453  if (bar == nullptr)
454  return;
455 
456  if (max == 0)
457  {
458  // TRANSLATORS: status bar label
459  bar->setText(_("Max"));
460  bar->setProgress(1);
461  bar->setText(toString(CAST_U64(value)));
462  }
463  else
464  {
465  const float progress = static_cast<float>(value)
466  / static_cast<float>(max);
467  if (percent)
468  {
469  bar->setText(strprintf("%2.5f%%",
470  static_cast<double>(100 * progress)));
471  }
472  else
473  {
474  bar->setText(toString(
475  CAST_U64(value)).append(
476  "/").append(toString(
477  CAST_U64(max))));
478  }
479  bar->setProgress(progress);
480  }
481 }
482 
483 void StatusWindow::updateXPBar(ProgressBar *const bar, const bool percent)
484 {
485  if (bar == nullptr)
486  return;
487 
488  updateProgressBar(bar,
491  percent);
492 }
493 
495  const bool percent)
496 {
497  if (bar == nullptr)
498  return;
499 
500  updateProgressBar(bar,
503  percent);
504 }
505 
507  const AttributesT id,
508  const bool percent)
509 {
510  const std::pair<int, int> exp = PlayerInfo::getStatExperience(id);
511  updateProgressBar(bar, exp.first, exp.second, percent);
512 }
513 
515 {
516  if (bar == nullptr)
517  return;
518 
520  {
521  // TRANSLATORS: status bar label
522  bar->setText(_("Max"));
523  bar->setProgress(1.0);
524  }
525  else
526  {
527  const int totalWeight = PlayerInfo::getAttribute(
529  const int maxWeight = PlayerInfo::getAttribute(Attributes::MAX_WEIGHT);
530  float progress = 1.0F;
531  if (maxWeight != 0)
532  {
533  progress = static_cast<float>(totalWeight)
534  / static_cast<float>(maxWeight);
535  }
536  bar->setText(strprintf("%s/%s",
537  UnitsDb::formatWeight(totalWeight).c_str(),
538  UnitsDb::formatWeight(maxWeight).c_str()));
539  bar->setProgress(progress);
540  }
541 }
542 
544 {
545  if (bar == nullptr)
546  return;
547 
548  const int money = PlayerInfo::getAttribute(Attributes::MONEY);
549  bar->setText(UnitsDb::formatCurrency(money));
550  if (money > 0)
551  {
552  const float progress = static_cast<float>(money)
553  / static_cast<float>(1000000000);
554  bar->setProgress(progress);
555  }
556  else
557  {
558  bar->setProgress(1.0);
559  }
560 }
561 
563 {
564  if ((bar == nullptr) || (equipmentWindow == nullptr))
565  return;
566 
567  const Item *const item = equipmentWindow->getEquipment(
569 
570  if ((item != nullptr) && item->getQuantity() > 0)
571  bar->setText(toString(item->getQuantity()));
572  else
573  bar->setText("0");
574 }
575 
577 {
578  if (bar == nullptr)
579  return;
580 
581  const Inventory *const inv = PlayerInfo::getInventory();
582  if (inv == nullptr)
583  return;
584 
585  const int usedSlots = inv->getNumberOfSlotsUsed();
586  const int maxSlots = inv->getSize();
587 
588  if (maxSlots != 0)
589  {
590  bar->setProgress(static_cast<float>(usedSlots)
591  / static_cast<float>(maxSlots));
592  }
593 
594  bar->setText(strprintf("%d", usedSlots));
595 }
596 
597 std::string StatusWindow::translateLetter(const char *const letters)
598 {
599  char buf[2];
600  char *const str = gettext(letters);
601  if ((str == nullptr) || strlen(str) != 3)
602  return letters;
603 
604  buf[0] = str[1];
605  buf[1] = 0;
606  return std::string(buf);
607 }
608 
609 std::string StatusWindow::translateLetter2(const std::string &letters)
610 {
611  if (letters.size() < 5)
612  return "";
613 
614  return std::string(gettext(letters.substr(1, 1).c_str()));
615 }
616 
618  const bool percent A_UNUSED) const
619 {
620  if (bar == nullptr)
621  return;
626  .append(" ").append(translateLetter2(
631  .append(" ").append(translateLetter2(
634  .append(" ").append(translateLetter2(
636  .append(" ").append(translateLetter2(
641 
642  bar->setProgress(50);
644  {
646  255U));
647  }
648  else
649  {
651  255U));
652  }
653 }
654 
656 {
657  if (chatWindow == nullptr)
658  return;
659 
660  if (event.getId() == "copy")
661  {
663  true);
664  }
665 }
Net::PlayerHandler * playerHandler
Definition: net.cpp:89
Label * mJobLvlLabel
Definition: statuswindow.h:110
Label * mMpLabel
Definition: statuswindow.h:104
ChatWindow * chatWindow
Definition: chatwindow.cpp:88
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
void setDefaultSize()
Definition: window.cpp:1193
LayoutCell & place(const int x, const int y, Widget *const wg, const int w, const int h)
Definition: window.cpp:1379
#define _(s)
Definition: gettext.h:34
Label * mJobLabel
Definition: statuswindow.h:111
Label * mHpLabel
Definition: statuswindow.h:103
int getWidth() const
Definition: widget.h:220
std::string getRaceName() const
Definition: being.h:854
int getNumberOfSlotsUsed() const
Definition: inventory.h:163
void attributeChanged(const AttributesT id, const int64_t oldVal, const int64_t newVal)
ProgressBar * mMpBar
Definition: statuswindow.h:107
void addTabBasic(const std::string &name)
void addTab(const std::string &name)
static void updateWeightBar(ProgressBar *const bar)
void loadWindowState()
Definition: window.cpp:1082
WindowContainer * windowContainer
PRAGMA45(GCC diagnostic push) PRAGMA45(GCC diagnostic ignored "-Wunused-result") int TestLauncher
TabbedArea * mTabs
Definition: statuswindow.h:100
std::string formatWeight(const int value)
Definition: unitsdb.cpp:351
virtual bool canUseMagic() const =0
#define CAST_U64
Definition: cast.h:32
Inventory * getInventory()
Definition: playerinfo.cpp:192
Definition: window.h:98
const std::pair< int, int > getStatExperience(const AttributesT id)
Definition: playerinfo.cpp:173
Definition: button.h:94
static void updateInvSlotsBar(ProgressBar *const bar)
static void updateArrowsBar(ProgressBar *const bar)
std::string formatCurrency(const int value)
Definition: unitsdb.cpp:323
StatusWindow * statusWindow
Button * mCopyButton
Definition: statuswindow.h:115
Label * mMoneyLabel
Definition: statuswindow.h:102
#define delete2(var)
Definition: delete2.h:24
Configuration serverConfig
static void updateProgressBar(ProgressBar *const bar, const int64_t value, const int64_t max, const bool percent)
static std::string getMapDrawTypeString()
ProgressBar * mXpBar
Definition: statuswindow.h:108
ProgressBar * mJobBar
Definition: statuswindow.h:112
bool disableGameModifiers
Definition: settings.h:154
void registerWindowForReset(Window *const window)
std::string formatCurrency64(const int64_t value)
Definition: unitsdb.cpp:328
int64_t getAttribute64(const AttributesT id)
Definition: playerinfo.cpp:92
void updateStatusBar(ProgressBar *const bar, const bool percent) const
void setSelectable(const bool selectable)
Definition: widget.h:947
#define new
Definition: debug_new.h:147
static std::string getMoveTypeString()
Settings settings
Definition: settings.cpp:31
Widget * getWidgetContainer() const
Definition: tabbedarea.h:243
const std::string & getName(const int id)
Definition: groupdb.cpp:334
void updateMPBar(ProgressBar *bar, const bool showMax) const
void action(const ActionEvent &event)
#define CAST_S32
Definition: cast.h:29
Widget * getTabContainer() const
Definition: tabbedarea.h:240
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
void delete_all(Container &c)
Definition: dtor.h:55
void setCaption(const std::string &caption)
Definition: label.cpp:261
virtual int getProjectileSlot() const =0
Definition: label.h:87
ProgressBar * mHpBar
Definition: statuswindow.h:106
int getQuantity() const
Definition: item.h:104
static void updateHPBar(ProgressBar *const bar, const bool showMax)
void setBackgroundColor(const Color &color)
const Item * getEquipment(const int i) const
LocalPlayer * localPlayer
static std::string getQuickDropCounterString()
void setAttribute(const AttributesT id, const int64_t value, const Notify notify)
Definition: playerinfo.cpp:108
static void updateMoneyBar(ProgressBar *const bar)
const std::string & getId() const
Definition: actionevent.h:121
static std::string getMoveToTargetTypeString()
Definition: item.h:48
void setPointsNeeded(const AttributesT id, const int needed)
#define nullptr
Definition: localconsts.h:44
bool getValueBool(const std::string &key, const bool deflt) const
static std::string translateLetter(const char *const letters)
void setCloseButton(const bool flag)
Definition: window.cpp:744
std::vector< StatsPage * > mPages
Definition: statuswindow.h:98
int getGroupId() const
Definition: being.h:1083
static std::string getPickUpTypeString()
static std::string getAwayModeString()
const std::string & getName() const
Definition: being.h:231
void enableVisibleSound(bool b)
Definition: window.h:480
Net::InventoryHandler * inventoryHandler
Definition: net.cpp:82
Label * mLvlLabel
Definition: statuswindow.h:101
static std::string getFollowModeString()
LayoutCell & setPadding(int p)
Definition: layoutcell.h:59
void setText(const std::string &str)
Layout & getLayout()
Definition: window.cpp:1360
void setSaveVisible(const bool save)
Definition: window.h:299
std::vector< std::string > mPages
Definition: statdb.cpp:40
void setProgressPalette(const ProgressColorIdT progressPalette)
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
static std::string getTargetingTypeString()
#define A_UNUSED
Definition: localconsts.h:171
Label * mXpLabel
Definition: statuswindow.h:105
void adjustSize()
Definition: tabbedarea.cpp:559
static std::string getImitationModeString()
EquipmentWindow * equipmentWindow
static std::string getCrazyMoveTypeString()
Attributes ::T AttributesT
Definition: attributes.h:117
void updateLevelLabel()
int getHeight() const
Definition: widget.h:239
const char *const pages[SETUP_PAGES+1]
void setResizable(const bool resize)
Definition: window.cpp:622
void setStickyButtonLock(const bool sticky)
Definition: window.cpp:767
const Color & getThemeColor(const ThemeColorIdT type, const unsigned int alpha) const A_INLINE
Definition: widget2.h:44
SetupWindow * setupWindow
Definition: setupwindow.cpp:63
static std::string translateLetter2(const std::string &letters)
std::string getStatsStr() const
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:35
static std::string getMagicAttackTypeString()
static void updateXPBar(ProgressBar *const bar, const bool percent)
static void updateJobBar(ProgressBar *const bar, const bool percent)
StatsPageBasic * mBasicStatsPage
Definition: statuswindow.h:114
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:100
void setCaption(const std::string &caption)
Definition: window.h:530
void setColor(const Color &color1, const Color &color2)
void setRowHeight(const int n, const int h)
Definition: layoutcell.cpp:127
void adjustSize()
Definition: label.cpp:197
const std::vector< std::string > & getPages()
Definition: statdb.cpp:81
static std::string getAttackWeaponTypeString()
static std::string getAttackTypeString()
static std::string getPvpAttackTypeString()
void setProgress(const float progress)
void addInputText(const std::string &text, const bool space)
const bool Notify_true
Definition: notify.h:29
void addTab(Tab *const tab, Widget *const widget)
Definition: tabbedarea.cpp:229
static std::string getCameraModeString()
void setWindowName(const std::string &name)
Definition: window.h:354
unsigned getSize() const
Definition: inventory.h:75
void setPointsNeeded(const AttributesT id, const int needed)