Mana
Loading...
Searching...
No Matches
ministatuswindow.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
23
24#include "configuration.h"
25#include "game.h"
26#include "graphics.h"
27#include "playerinfo.h"
28#include "sprite.h"
29#include "statuseffect.h"
30
31#include "gui/gui.h"
32#include "gui/statuswindow.h"
33#include "gui/textpopup.h"
34
36
37#include "net/net.h"
38#include "net/playerhandler.h"
39#include "net/gamehandler.h"
40
41#include "net/tmwa/protocol.h"
42
44#include "resources/theme.h"
45
46#include "utils/gettext.h"
47#include "utils/stringutils.h"
48#include "utils/time.h"
49
50#include <algorithm>
51
52static constexpr int ICON_SPACING = 3;
53
55 Popup("MiniStatus")
56{
57 setPadding(3);
58 setMinHeight(0);
59
62
63 mHpBar = new ProgressBar(0, 100, 20, Theme::PROG_HP);
65
66 if (Net::getGameHandler()->canUseMagicBar())
67 {
68 mMpBar = new ProgressBar(0, 100, 20,
69 Net::getPlayerHandler()->canUseMagic()
71
73 }
74 else
75 mMpBar = nullptr;
76
77 mXpBar = new ProgressBar(0, 100, 20, Theme::PROG_EXP);
79
80 // Add the progressbars to the window
81
82 mHpBar->setPosition(0, 3);
83 if (mMpBar)
84 mMpBar->setPosition(mHpBar->getWidth() + 3, 3);
85 mXpBar->setPosition(mMpBar ? mMpBar->getX() + mMpBar->getWidth() + 3 :
86 mHpBar->getX() + mHpBar->getWidth() + 3, 3);
87
88 add(mHpBar);
89 if (mMpBar)
90 add(mMpBar);
91 add(mXpBar);
92
93 updateSize();
94
95 auto stateIt = config.windows.find(getPopupName());
96 setVisible(stateIt != config.windows.end() ? stateIt->second.visible.value_or(true)
97 : true);
98
99 mTextPopup = new TextPopup();
100
101 addMouseListener(this);
102}
103
105
107{
108 const auto game = Game::instance();
109 const int tileWidth = game->getCurrentTileWidth();
110 const int tileHeight = game->getCurrentTileHeight();
111
112 int iconX = mXpBar->getX() + mXpBar->getWidth() + ICON_SPACING + tileWidth / 2;
113 int iconY = ICON_SPACING + tileHeight;
114
115 for (auto &icon : mStatusIcons)
116 {
117 icon.sprite->draw(graphics,
118 iconX - icon.sprite->getWidth() / 2,
119 iconY - icon.sprite->getHeight());
120 iconX += ICON_SPACING + icon.sprite->getWidth();
121 }
122}
123
125{
126 if (channel == Event::AttributesChannel)
127 {
128 if (event.getType() == Event::UpdateAttribute)
129 {
130 int id = event.getInt("id");
131 if (id == HP || id == MAX_HP)
132 {
134 }
135 else if (id == MP || id == MAX_MP)
136 {
138 }
139 else if (id == EXP || id == EXP_NEEDED)
140 {
142 }
143 }
144 if (event.getType() == Event::UpdateStat)
145 {
147 event.getInt("id") == TmwAthena::MATK)
148 {
150 }
151 }
152 }
153 else if (channel == Event::ActorSpriteChannel)
154 {
155 if (event.getType() == Event::UpdateStatusEffect)
156 {
157 const int id = event.getInt("index");
158 const bool newStatus = event.getBool("newStatus");
159
160 auto effect = StatusEffectDB::getStatusEffect(id);
161 if (!effect)
162 return;
163
164 effect->deliverMessage(newStatus);
165 effect->playSfx(newStatus);
166
167 Sprite *sprite = newStatus ? effect->getIconSprite() : nullptr;
168 auto it = std::find_if(mStatusIcons.begin(), mStatusIcons.end(),
169 [id](const StatusIcon &icon) {
170 return icon.effectId == id;
171 });
172
173 if (!sprite && it != mStatusIcons.end())
174 mStatusIcons.erase(it);
175 else if (sprite && it == mStatusIcons.end())
176 mStatusIcons.push_back(StatusIcon{id, std::unique_ptr<Sprite>(sprite)});
177
178 updateSize();
179 }
180 }
181}
182
184{
185 Popup::logic();
186
187 // Displays the number of monsters to next lvl
188 // (disabled for now but interesting idea)
189 /*
190 if (config.getValue("xpBarMonsterCounterExp", 0)!=0)
191 {
192 updatedText << " | "
193 << (int)(((float)local_player->mXpForNextLevel - (float)local_player->mXp)
194 / (float)config.getValue("xpBarMonsterCounterExp", 0))
195 << " "
196 << config.getValue("xpBarMonsterCounterName", "Monsters") <<" left...";
197 }
198 */
199
200 for (auto &icon : mStatusIcons)
201 icon.sprite->update(Time::deltaTimeMs());
202}
203
205{
206 drawChildren(graphics);
207
208 drawIcons(static_cast<Graphics*>(graphics));
209}
210
211void MiniStatusWindow::mouseMoved(gcn::MouseEvent &event)
212{
214
215 std::string tooltip1;
216 std::string tooltip2;
217
218 if (event.getSource() == mXpBar)
219 {
220 const int xp = PlayerInfo::getAttribute(EXP);
221 const int xpNeeded = PlayerInfo::getAttribute(EXP_NEEDED);
222 tooltip1 = strprintf("%u/%u", xp, xpNeeded);
223 tooltip2 = strprintf("%s: %u", _("Need"), xpNeeded - xp);
224 }
225 else if (event.getSource() == mHpBar)
226 {
227 const int hp = PlayerInfo::getAttribute(HP);
228 const int maxHp = PlayerInfo::getAttribute(MAX_HP);
229 tooltip1 = strprintf("%u/%u", hp, maxHp);
230 }
231 else if (event.getSource() == mMpBar)
232 {
233 const int mp = PlayerInfo::getAttribute(MP);
234 const int maxMp = PlayerInfo::getAttribute(MAX_MP);
235 tooltip1 = strprintf("%u/%u", mp, maxMp);
236 }
237 else
238 {
239 // Check if the mouse is over one of the status icons
240 const auto game = Game::instance();
241 const int tileWidth = game->getCurrentTileWidth();
242 const int tileHeight = game->getCurrentTileHeight();
243
244 int iconX = mXpBar->getX() + mXpBar->getWidth() + ICON_SPACING + tileWidth / 2;
245 int iconY = ICON_SPACING + tileHeight;
246
247 for (const auto &icon : mStatusIcons)
248 {
249 int spriteX = iconX + icon.sprite->getOffsetX() - icon.sprite->getWidth() / 2;
250 int spriteY = iconY + icon.sprite->getOffsetY() - icon.sprite->getHeight();
251
252 if (event.getX() >= spriteX &&
253 event.getX() < spriteX + icon.sprite->getWidth() &&
254 event.getY() >= spriteY &&
255 event.getY() < spriteY + icon.sprite->getHeight())
256 {
257 auto effect = StatusEffectDB::getStatusEffect(icon.effectId);
258 if (effect)
259 tooltip1 = effect->name;
260 break;
261 }
262
263 iconX += ICON_SPACING + icon.sprite->getWidth();
264 }
265 }
266
267 if (tooltip1.empty())
268 {
269 mTextPopup->setVisible(false);
270 }
271 else
272 {
273 mTextPopup->show(event.getX() + getX(),
274 event.getY() + getY(),
275 tooltip1,
276 tooltip2);
277 }
278}
279
280void MiniStatusWindow::mouseExited(gcn::MouseEvent &event)
281{
282 Popup::mouseExited(event);
283
284 mTextPopup->setVisible(false);
285}
286
288{
289 int width = mXpBar->getX() + mXpBar->getWidth();
290 int height = mXpBar->getY() + mXpBar->getHeight();
291
292 // Increase width based on the size of the status icons
293 if (!mStatusIcons.empty())
294 {
295 width += ICON_SPACING;
296 for (const auto &icon : mStatusIcons)
297 width += ICON_SPACING + icon.sprite->getWidth();
298 }
299
300 setContentSize(width, height);
301}
void listen(Event::Channel channel)
Definition event.h:42
@ UpdateAttribute
Definition event.h:99
@ UpdateStatusEffect
Definition event.h:101
@ UpdateStat
Definition event.h:100
Channel
Definition event.h:45
@ AttributesChannel
Definition event.h:47
@ ActorSpriteChannel
Definition event.h:46
static Game * instance()
Provides access to the game instance.
Definition game.h:53
A central point of control for graphics.
Definition graphics.h:78
int getWidth() const
Returns the logical width of the screen.
Definition graphics.h:221
ProgressBar * mHpBar
~MiniStatusWindow() override
void mouseMoved(gcn::MouseEvent &mouseEvent) override
void mouseExited(gcn::MouseEvent &event) override
ProgressBar * mMpBar
TextPopup * mTextPopup
std::vector< StatusIcon > mStatusIcons
void drawIcons(Graphics *graphics)
void draw(gcn::Graphics *graphics) override
void logic() override
void event(Event::Channel channel, const Event &event) override
ProgressBar * mXpBar
A light version of the Window class.
Definition popup.h:48
void setPadding(int padding)
Definition popup.h:134
void setMinHeight(int height)
Sets the minimum height of the popup.
Definition popup.cpp:163
void add(gcn::Widget *widget) override
Definition popup.cpp:69
void mouseMoved(gcn::MouseEvent &event) override
Definition popup.cpp:205
void setContentSize(int width, int height)
Sets the size of this popup.
Definition popup.cpp:127
const std::string & getPopupName() const
Definition popup.h:142
A progress bar.
Definition progressbar.h:34
Animates a sprite by adding playback state.
Definition sprite.h:37
static const StatusEffect * getStatusEffect(int id)
Retrieves a status effect.
static void updateMPBar(ProgressBar *bar, bool showMax=false)
static void updateHPBar(ProgressBar *bar, bool showMax=false)
static void updateXPBar(ProgressBar *bar, bool percent=true)
A popup that displays information about an item.
Definition textpopup.h:36
void show(int x, int y, const std::string &str1, const std::string &str2=std::string())
Sets the text to be displayed.
Definition textpopup.cpp:54
@ PROG_HP
Definition theme.h:270
@ PROG_EXP
Definition theme.h:273
@ PROG_MP
Definition theme.h:271
@ PROG_NO_MP
Definition theme.h:272
Config config
Global settings (config.xml)
Definition client.cpp:97
Graphics * graphics
Definition client.cpp:104
#define _(s)
Definition gettext.h:38
ServerType getNetworkType()
Definition net.cpp:200
GameHandler * getGameHandler()
Definition net.cpp:75
PlayerHandler * getPlayerHandler()
Definition net.cpp:110
int getAttribute(int id)
Returns the value of the given attribute.
unsigned deltaTimeMs()
The time in milliseconds since the last frame, but never more than 1000.
Definition time.cpp:39
@ EXP
Definition playerinfo.h:33
@ HP
Definition playerinfo.h:31
@ MAX_HP
Definition playerinfo.h:31
@ EXP_NEEDED
Definition playerinfo.h:33
@ MP
Definition playerinfo.h:32
@ MAX_MP
Definition playerinfo.h:32
std::string strprintf(char const *format,...)
A safe version of sprintf that returns a std::string of the result.
std::map< std::string, WindowState > windows