GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
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-2019 The ManaPlus Developers |
||
6 |
* Copyright (C) 2019-2021 Andrei Karas |
||
7 |
* |
||
8 |
* This file is part of The ManaPlus Client. |
||
9 |
* |
||
10 |
* This program is free software; you can redistribute it and/or modify |
||
11 |
* it under the terms of the GNU General Public License as published by |
||
12 |
* the Free Software Foundation; either version 2 of the License, or |
||
13 |
* any later version. |
||
14 |
* |
||
15 |
* This program is distributed in the hope that it will be useful, |
||
16 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 |
* GNU General Public License for more details. |
||
19 |
* |
||
20 |
* You should have received a copy of the GNU General Public License |
||
21 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
22 |
*/ |
||
23 |
|||
24 |
#include "gui/windows/charselectdialog.h" |
||
25 |
|||
26 |
#include "client.h" |
||
27 |
#include "configuration.h" |
||
28 |
#include "pincodemanager.h" |
||
29 |
|||
30 |
#include "listeners/charrenamelistener.h" |
||
31 |
|||
32 |
#include "gui/windows/charcreatedialog.h" |
||
33 |
#include "gui/windows/chardeleteconfirm.h" |
||
34 |
#include "gui/windows/editdialog.h" |
||
35 |
#include "gui/windows/logindialog.h" |
||
36 |
#include "gui/windows/okdialog.h" |
||
37 |
#include "gui/windows/textdialog.h" |
||
38 |
|||
39 |
#include "gui/widgets/button.h" |
||
40 |
#include "gui/widgets/characterdisplay.h" |
||
41 |
#include "gui/widgets/characterviewnormal.h" |
||
42 |
#include "gui/widgets/characterviewsmall.h" |
||
43 |
#include "gui/widgets/containerplacer.h" |
||
44 |
#include "gui/widgets/createwidget.h" |
||
45 |
|||
46 |
#include "net/character.h" |
||
47 |
#include "net/charserverhandler.h" |
||
48 |
#include "net/logindata.h" |
||
49 |
#ifdef TMWA_SUPPORT |
||
50 |
#include "net/net.h" |
||
51 |
#endif // TMWA_SUPPORT |
||
52 |
#include "net/serverfeatures.h" |
||
53 |
|||
54 |
#include "utils/foreach.h" |
||
55 |
|||
56 |
#include "resources/db/unitsdb.h" |
||
57 |
|||
58 |
#include "debug.h" |
||
59 |
|||
60 |
// Character slots per row in the dialog |
||
61 |
static const int SLOTS_PER_ROW = 5; |
||
62 |
|||
63 |
1 |
CharSelectDialog::CharSelectDialog(LoginData &data) : |
|
64 |
// TRANSLATORS: char select dialog name |
||
65 |
✓✗ | 4 |
Window(strprintf(_("Account %s (last login time %s)"), |
66 |
data.username.c_str(), data.lastLogin.c_str()), |
||
67 |
Modal_false, |
||
68 |
nullptr, |
||
69 |
"char.xml"), |
||
70 |
ActionListener(), |
||
71 |
KeyListener(), |
||
72 |
mLoginData(&data), |
||
73 |
// TRANSLATORS: char select dialog. button. |
||
74 |
1 |
mSwitchLoginButton(new Button(this, _("Switch"), "switch", |
|
75 |
✓✗✓✗ |
1 |
BUTTON_SKIN, this)), |
76 |
// TRANSLATORS: char select dialog. button. |
||
77 |
1 |
mChangePasswordButton(new Button(this, _("Password"), "change_password", |
|
78 |
✓✗✓✗ |
1 |
BUTTON_SKIN, this)), |
79 |
// TRANSLATORS: char select dialog. button. |
||
80 |
✓✗✓✗ |
2 |
mPlayButton(new Button(this, _("Play"), "use", BUTTON_SKIN, this)), |
81 |
// TRANSLATORS: char select dialog. button. |
||
82 |
✓✗✓✗ |
2 |
mInfoButton(new Button(this, _("Info"), "info", BUTTON_SKIN, this)), |
83 |
// TRANSLATORS: char select dialog. button. |
||
84 |
✓✗✓✗ |
2 |
mDeleteButton(new Button(this, _("Delete"), "delete", BUTTON_SKIN, this)), |
85 |
// TRANSLATORS: char select dialog. button. |
||
86 |
mRenameButton(nullptr), |
||
87 |
mChangePinButton(nullptr), |
||
88 |
mCharacterView(nullptr), |
||
89 |
mCharacterEntries(0), |
||
90 |
mCharServerHandler(charServerHandler), |
||
91 |
mDeleteDialog(nullptr), |
||
92 |
mDeleteIndex(-1), |
||
93 |
mLocked(false), |
||
94 |
✓✗ | 1 |
mSmallScreen(mainGraphics->getWidth() < 470 |
95 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✓ |
45 |
|| mainGraphics->getHeight() < 370) |
96 |
{ |
||
97 |
✓✗ | 1 |
setCloseButton(true); |
98 |
✓✗ | 1 |
setFocusable(true); |
99 |
|||
100 |
1 |
ContainerPlacer placer(nullptr, nullptr); |
|
101 |
✓✗ | 1 |
placer = getPlacer(0, 0); |
102 |
|||
103 |
✓✗ | 1 |
placer(0, 0, mSwitchLoginButton, 1, 1); |
104 |
|||
105 |
1 |
int n = 1; |
|
106 |
✓✗ | 1 |
placer(n, 0, mChangePasswordButton, 1, 1); |
107 |
1 |
n ++; |
|
108 |
✓✗ | 1 |
placer(n, 0, mDeleteButton, 1, 1); |
109 |
1 |
n ++; |
|
110 |
#ifdef TMWA_SUPPORT |
||
111 |
✓✗✓✗ |
1 |
if (Net::getNetworkType() != ServerType::TMWATHENA) |
112 |
#endif |
||
113 |
{ |
||
114 |
1 |
mRenameButton = new Button(this, |
|
115 |
// TRANSLATORS: character rename button |
||
116 |
1 |
_("Rename"), |
|
117 |
"rename", |
||
118 |
BUTTON_SKIN, |
||
119 |
✓✗✓✗ ✓✗✓✗ |
7 |
this); |
120 |
✓✗ | 1 |
placer(n, 0, mRenameButton, 1, 1); |
121 |
n ++; |
||
122 |
} |
||
123 |
#ifdef TMWA_SUPPORT |
||
124 |
✓✗✓✗ |
1 |
if (serverFeatures->havePincode()) |
125 |
#endif |
||
126 |
{ |
||
127 |
1 |
mChangePinButton = new Button(this, |
|
128 |
// TRANSLATORS: change pincode button |
||
129 |
1 |
_("Change pin"), |
|
130 |
"changepin", |
||
131 |
BUTTON_SKIN, |
||
132 |
✓✗✓✗ ✓✗✓✗ |
7 |
this); |
133 |
✓✗ | 1 |
placer(n, 0, mChangePinButton, 1, 1); |
134 |
1 |
n ++; |
|
135 |
} |
||
136 |
✓✗ | 1 |
placer(n, 0, mInfoButton, 1, 1); |
137 |
n ++; |
||
138 |
|||
139 |
✓✓ | 19 |
for (int i = 0; i < CAST_S32(mLoginData->characterSlots); i++) |
140 |
{ |
||
141 |
✓✗✓✗ |
9 |
CharacterDisplay *const character = new CharacterDisplay(this, this); |
142 |
✓✗ | 9 |
character->setVisible(Visible_false); |
143 |
✓✗ | 9 |
mCharacterEntries.push_back(character); |
144 |
} |
||
145 |
|||
146 |
✓✗ | 1 |
placer(0, 2, mPlayButton, 1, 1); |
147 |
|||
148 |
✓✗ | 1 |
if (!mSmallScreen) |
149 |
{ |
||
150 |
1 |
mCharacterView = new CharacterViewNormal( |
|
151 |
✓✗✓✗ |
1 |
this, &mCharacterEntries, mPadding); |
152 |
✓✗ | 1 |
placer(0, 1, mCharacterView, 10, 1); |
153 |
1 |
int sz = 410 + 2 * mPadding; |
|
154 |
✓✗✓✗ ✗✓ |
4 |
if (config.getIntValue("fontSize") > 18) |
155 |
sz = 500 + 2 * mPadding; |
||
156 |
2 |
const int width = mCharacterView->getWidth() + 2 * mPadding; |
|
157 |
✓✗ | 1 |
if (sz < width) |
158 |
1 |
sz = width; |
|
159 |
✓✗✗✓ |
1 |
if (sz > mainGraphics->getWidth()) |
160 |
sz = mainGraphics->getWidth(); |
||
161 |
✓✗ | 1 |
reflowLayout(sz, 0); |
162 |
} |
||
163 |
else |
||
164 |
{ |
||
165 |
// TRANSLATORS: char select dialog name |
||
166 |
setCaption(strprintf(_("Account %s"), mLoginData->username.c_str())); |
||
167 |
mCharacterView = new CharacterViewSmall( |
||
168 |
this, &mCharacterEntries, mPadding); |
||
169 |
mCharacterView->setWidth(mainGraphics->getWidth() |
||
170 |
- 2 * getPadding()); |
||
171 |
placer(0, 1, mCharacterView, 10, 1); |
||
172 |
reflowLayout(0, 0); |
||
173 |
} |
||
174 |
✓✗ | 1 |
addKeyListener(this); |
175 |
✓✗ | 1 |
center(); |
176 |
|||
177 |
✓✗ | 1 |
charServerHandler->setCharSelectDialog(this); |
178 |
✓✗ | 1 |
mCharacterView->show(0); |
179 |
✓✗ | 1 |
updateState(); |
180 |
1 |
} |
|
181 |
|||
182 |
6 |
CharSelectDialog::~CharSelectDialog() |
|
183 |
{ |
||
184 |
1 |
mDeleteDialog = nullptr; |
|
185 |
2 |
} |
|
186 |
|||
187 |
1 |
void CharSelectDialog::postInit() |
|
188 |
{ |
||
189 |
1 |
Window::postInit(); |
|
190 |
1 |
setVisible(Visible_true); |
|
191 |
1 |
requestFocus(); |
|
192 |
1 |
} |
|
193 |
|||
194 |
void CharSelectDialog::action(const ActionEvent &event) |
||
195 |
{ |
||
196 |
// Check if a button of a character was pressed |
||
197 |
const Widget *const sourceParent = event.getSource()->getParent(); |
||
198 |
int selected = -1; |
||
199 |
for (unsigned int i = 0, fsz = CAST_U32( |
||
200 |
mCharacterEntries.size()); |
||
201 |
i < fsz; |
||
202 |
++i) |
||
203 |
{ |
||
204 |
if (mCharacterEntries[i] == sourceParent) |
||
205 |
{ |
||
206 |
selected = i; |
||
207 |
mCharacterView->show(i); |
||
208 |
updateState(); |
||
209 |
break; |
||
210 |
} |
||
211 |
} |
||
212 |
if (selected == -1) |
||
213 |
selected = mCharacterView->getSelected(); |
||
214 |
|||
215 |
const std::string &eventId = event.getId(); |
||
216 |
const bool blocked = pincodeManager.isBlocked(); |
||
217 |
|||
218 |
if (selected >= 0) |
||
219 |
{ |
||
220 |
if (blocked) |
||
221 |
return; |
||
222 |
if (eventId == "use") |
||
223 |
{ |
||
224 |
use(selected); |
||
225 |
return; |
||
226 |
} |
||
227 |
else if (eventId == "delete" |
||
228 |
&& (mCharacterEntries[selected]->getCharacter() != nullptr)) |
||
229 |
{ |
||
230 |
CREATEWIDGET(CharDeleteConfirm, this, selected); |
||
231 |
return; |
||
232 |
} |
||
233 |
else if (eventId == "rename" |
||
234 |
&& (mCharacterEntries[selected]->getCharacter() != nullptr)) |
||
235 |
{ |
||
236 |
const LocalPlayer *const player = mCharacterEntries[ |
||
237 |
selected]->getCharacter()->dummy; |
||
238 |
EditDialog *const dialog = CREATEWIDGETR(EditDialog, |
||
239 |
// TRANSLATORS: character rename dialog header. |
||
240 |
_("Please enter new name"), |
||
241 |
player->getName(), |
||
242 |
"OK", |
||
243 |
300, |
||
244 |
nullptr, |
||
245 |
Modal_true); |
||
246 |
charRenameListener.setId(player->getId()); |
||
247 |
charRenameListener.setDialog(dialog); |
||
248 |
dialog->addActionListener(&charRenameListener); |
||
249 |
} |
||
250 |
else if (eventId == "info") |
||
251 |
{ |
||
252 |
Net::Character *const character = mCharacterEntries[ |
||
253 |
selected]->getCharacter(); |
||
254 |
if (character == nullptr) |
||
255 |
return; |
||
256 |
|||
257 |
const LocalPlayer *const data = character->dummy; |
||
258 |
if (data == nullptr) |
||
259 |
return; |
||
260 |
|||
261 |
const std::string strExp = toString(CAST_U64( |
||
262 |
character->data.mAttributes[Attributes::PLAYER_EXP])); |
||
263 |
const std::string msg = strprintf( |
||
264 |
// TRANSLATORS: char select dialog. player info message. |
||
265 |
_("Hp: %u/%u\nMp: %u/%u\nLevel: %u\n" |
||
266 |
"Experience: %s\nMoney: %s"), |
||
267 |
CAST_U32( |
||
268 |
character->data.mAttributes[Attributes::PLAYER_HP]), |
||
269 |
CAST_U32( |
||
270 |
character->data.mAttributes[Attributes::PLAYER_MAX_HP]), |
||
271 |
CAST_U32( |
||
272 |
character->data.mAttributes[Attributes::PLAYER_MP]), |
||
273 |
CAST_U32( |
||
274 |
character->data.mAttributes[Attributes::PLAYER_MAX_MP]), |
||
275 |
CAST_U32( |
||
276 |
character->data.mAttributes[Attributes::PLAYER_BASE_LEVEL]), |
||
277 |
strExp.c_str(), |
||
278 |
UnitsDb::formatCurrency(CAST_S32( |
||
279 |
character->data.mAttributes[Attributes::MONEY])).c_str()); |
||
280 |
CREATEWIDGET(OkDialog, data->getName(), msg, |
||
281 |
// TRANSLATORS: ok dialog button |
||
282 |
_("OK"), |
||
283 |
DialogType::SILENCE, |
||
284 |
Modal_true, |
||
285 |
ShowCenter_true, |
||
286 |
nullptr, |
||
287 |
260); |
||
288 |
} |
||
289 |
} |
||
290 |
if (eventId == "switch") |
||
291 |
{ |
||
292 |
charServerHandler->clear(); |
||
293 |
close(); |
||
294 |
} |
||
295 |
else if (eventId == "change_password") |
||
296 |
{ |
||
297 |
if (blocked) |
||
298 |
return; |
||
299 |
client->setState(State::CHANGEPASSWORD); |
||
300 |
} |
||
301 |
else if (eventId == "change_email") |
||
302 |
{ |
||
303 |
if (blocked) |
||
304 |
return; |
||
305 |
client->setState(State::CHANGEEMAIL); |
||
306 |
} |
||
307 |
else if (eventId == "try delete character") |
||
308 |
{ |
||
309 |
if (blocked) |
||
310 |
return; |
||
311 |
if ((mDeleteDialog != nullptr) && mDeleteIndex != -1) |
||
312 |
{ |
||
313 |
if (serverFeatures->haveEmailOnDelete()) |
||
314 |
{ |
||
315 |
attemptCharacterDelete(mDeleteIndex, mDeleteDialog->getText()); |
||
316 |
mDeleteDialog = nullptr; |
||
317 |
} |
||
318 |
else if (mDeleteDialog->getText() == LoginDialog::savedPassword) |
||
319 |
{ |
||
320 |
attemptCharacterDelete(mDeleteIndex, ""); |
||
321 |
mDeleteDialog = nullptr; |
||
322 |
} |
||
323 |
else |
||
324 |
{ |
||
325 |
CREATEWIDGET(OkDialog, |
||
326 |
// TRANSLATORS: error header |
||
327 |
_("Error"), |
||
328 |
// TRANSLATORS: error message |
||
329 |
_("Incorrect password"), |
||
330 |
// TRANSLATORS: ok dialog button |
||
331 |
_("OK"), |
||
332 |
DialogType::ERROR, |
||
333 |
Modal_true, |
||
334 |
ShowCenter_true, |
||
335 |
nullptr, |
||
336 |
260); |
||
337 |
} |
||
338 |
} |
||
339 |
mDeleteIndex = -1; |
||
340 |
} |
||
341 |
else if (eventId == "changepin") |
||
342 |
{ |
||
343 |
if (blocked) |
||
344 |
return; |
||
345 |
pincodeManager.setState(PincodeState::Change); |
||
346 |
pincodeManager.updateState(); |
||
347 |
} |
||
348 |
} |
||
349 |
|||
350 |
void CharSelectDialog::use(const int selected) |
||
351 |
{ |
||
352 |
if ((mCharacterEntries[selected] != nullptr) |
||
353 |
&& (mCharacterEntries[selected]->getCharacter() != nullptr)) |
||
354 |
{ |
||
355 |
attemptCharacterSelect(selected); |
||
356 |
} |
||
357 |
else |
||
358 |
{ |
||
359 |
CharCreateDialog *const charCreateDialog = |
||
360 |
CREATEWIDGETR(CharCreateDialog, this, selected); |
||
361 |
mCharServerHandler->setCharCreateDialog(charCreateDialog); |
||
362 |
} |
||
363 |
} |
||
364 |
|||
365 |
void CharSelectDialog::keyPressed(KeyEvent &event) |
||
366 |
{ |
||
367 |
const InputActionT actionId = event.getActionId(); |
||
368 |
const bool blocked = pincodeManager.isBlocked(); |
||
369 |
PRAGMA45(GCC diagnostic push) |
||
370 |
PRAGMA45(GCC diagnostic ignored "-Wswitch-enum") |
||
371 |
switch (actionId) |
||
372 |
{ |
||
373 |
case InputAction::GUI_CANCEL: |
||
374 |
event.consume(); |
||
375 |
action(ActionEvent(mSwitchLoginButton, |
||
376 |
mSwitchLoginButton->getActionEventId())); |
||
377 |
break; |
||
378 |
|||
379 |
case InputAction::GUI_RIGHT: |
||
380 |
{ |
||
381 |
event.consume(); |
||
382 |
int idx = mCharacterView->getSelected(); |
||
383 |
if (idx >= 0) |
||
384 |
{ |
||
385 |
if ((idx + 1) % SLOTS_PER_ROW == 0) |
||
386 |
break; |
||
387 |
idx ++; |
||
388 |
mCharacterView->show(idx); |
||
389 |
updateState(); |
||
390 |
} |
||
391 |
break; |
||
392 |
} |
||
393 |
|||
394 |
case InputAction::GUI_LEFT: |
||
395 |
{ |
||
396 |
event.consume(); |
||
397 |
int idx = mCharacterView->getSelected(); |
||
398 |
if (idx >= 0) |
||
399 |
{ |
||
400 |
if (idx == 0 || idx % SLOTS_PER_ROW == 0) |
||
401 |
break; |
||
402 |
idx --; |
||
403 |
mCharacterView->show(idx); |
||
404 |
updateState(); |
||
405 |
} |
||
406 |
break; |
||
407 |
} |
||
408 |
|||
409 |
case InputAction::GUI_UP: |
||
410 |
{ |
||
411 |
event.consume(); |
||
412 |
int idx = mCharacterView->getSelected(); |
||
413 |
if (idx >= 0) |
||
414 |
{ |
||
415 |
if (idx < SLOTS_PER_ROW) |
||
416 |
break; |
||
417 |
idx -= SLOTS_PER_ROW; |
||
418 |
mCharacterView->show(idx); |
||
419 |
updateState(); |
||
420 |
} |
||
421 |
break; |
||
422 |
} |
||
423 |
|||
424 |
case InputAction::GUI_DOWN: |
||
425 |
{ |
||
426 |
event.consume(); |
||
427 |
int idx = mCharacterView->getSelected(); |
||
428 |
if (idx >= 0) |
||
429 |
{ |
||
430 |
if (idx >= mLoginData->characterSlots - SLOTS_PER_ROW) |
||
431 |
break; |
||
432 |
idx += SLOTS_PER_ROW; |
||
433 |
mCharacterView->show(idx); |
||
434 |
updateState(); |
||
435 |
} |
||
436 |
break; |
||
437 |
} |
||
438 |
|||
439 |
case InputAction::GUI_DELETE: |
||
440 |
{ |
||
441 |
if (blocked) |
||
442 |
return; |
||
443 |
event.consume(); |
||
444 |
const int idx = mCharacterView->getSelected(); |
||
445 |
if (idx >= 0 && (mCharacterEntries[idx] != nullptr) |
||
446 |
&& (mCharacterEntries[idx]->getCharacter() != nullptr)) |
||
447 |
{ |
||
448 |
CREATEWIDGET(CharDeleteConfirm, this, idx); |
||
449 |
} |
||
450 |
break; |
||
451 |
} |
||
452 |
|||
453 |
case InputAction::GUI_SELECT: |
||
454 |
{ |
||
455 |
if (blocked) |
||
456 |
return; |
||
457 |
event.consume(); |
||
458 |
use(mCharacterView->getSelected()); |
||
459 |
break; |
||
460 |
} |
||
461 |
default: |
||
462 |
break; |
||
463 |
} |
||
464 |
PRAGMA45(GCC diagnostic pop) |
||
465 |
} |
||
466 |
|||
467 |
/** |
||
468 |
* Communicate character deletion to the server. |
||
469 |
*/ |
||
470 |
void CharSelectDialog::attemptCharacterDelete(const int index, |
||
471 |
const std::string &email) |
||
472 |
{ |
||
473 |
if (mLocked) |
||
474 |
return; |
||
475 |
|||
476 |
if (mCharacterEntries[index] != nullptr) |
||
477 |
{ |
||
478 |
mCharServerHandler->deleteCharacter( |
||
479 |
mCharacterEntries[index]->getCharacter(), |
||
480 |
email); |
||
481 |
} |
||
482 |
lock(); |
||
483 |
} |
||
484 |
|||
485 |
void CharSelectDialog::askPasswordForDeletion(const int index) |
||
486 |
{ |
||
487 |
mDeleteIndex = index; |
||
488 |
if (serverFeatures->haveEmailOnDelete()) |
||
489 |
{ |
||
490 |
CREATEWIDGETV(mDeleteDialog, TextDialog, |
||
491 |
// TRANSLATORS: char deletion question. |
||
492 |
_("Enter your email for deleting character"), |
||
493 |
// TRANSLATORS: email label. |
||
494 |
_("Enter email:"), |
||
495 |
this, |
||
496 |
false); |
||
497 |
} |
||
498 |
else |
||
499 |
{ |
||
500 |
CREATEWIDGETV(mDeleteDialog, TextDialog, |
||
501 |
// TRANSLATORS: char deletion question. |
||
502 |
_("Enter password for deleting character"), |
||
503 |
// TRANSLATORS: email label. |
||
504 |
_("Enter password:"), |
||
505 |
this, |
||
506 |
true); |
||
507 |
} |
||
508 |
mDeleteDialog->setActionEventId("try delete character"); |
||
509 |
mDeleteDialog->addActionListener(this); |
||
510 |
} |
||
511 |
|||
512 |
/** |
||
513 |
* Communicate character selection to the server. |
||
514 |
*/ |
||
515 |
void CharSelectDialog::attemptCharacterSelect(const int index) |
||
516 |
{ |
||
517 |
if (mLocked || (mCharacterEntries[index] == nullptr)) |
||
518 |
return; |
||
519 |
|||
520 |
setVisible(Visible_false); |
||
521 |
if (mCharServerHandler != nullptr) |
||
522 |
{ |
||
523 |
mCharServerHandler->chooseCharacter( |
||
524 |
mCharacterEntries[index]->getCharacter()); |
||
525 |
} |
||
526 |
lock(); |
||
527 |
} |
||
528 |
|||
529 |
1 |
void CharSelectDialog::setCharacters(const Net::Characters &characters) |
|
530 |
{ |
||
531 |
// Reset previous characters |
||
532 |
✓✓ | 15 |
FOR_EACH (STD_VECTOR<CharacterDisplay*>::const_iterator, |
533 |
iter, mCharacterEntries) |
||
534 |
{ |
||
535 |
✓✗ | 9 |
if (*iter != nullptr) |
536 |
9 |
(*iter)->setCharacter(nullptr); |
|
537 |
} |
||
538 |
|||
539 |
✗✓ | 3 |
FOR_EACH (Net::Characters::const_iterator, i, characters) |
540 |
setCharacter(*i); |
||
541 |
1 |
updateState(); |
|
542 |
1 |
} |
|
543 |
|||
544 |
void CharSelectDialog::setCharacter(Net::Character *const character) |
||
545 |
{ |
||
546 |
if (character == nullptr) |
||
547 |
return; |
||
548 |
const int characterSlot = character->slot; |
||
549 |
if (characterSlot >= CAST_S32(mCharacterEntries.size())) |
||
550 |
{ |
||
551 |
logger->log("Warning: slot out of range: %d", character->slot); |
||
552 |
return; |
||
553 |
} |
||
554 |
|||
555 |
if (mCharacterEntries[characterSlot] != nullptr) |
||
556 |
mCharacterEntries[characterSlot]->setCharacter(character); |
||
557 |
} |
||
558 |
|||
559 |
void CharSelectDialog::lock() |
||
560 |
{ |
||
561 |
if (!mLocked) |
||
562 |
setLocked(true); |
||
563 |
} |
||
564 |
|||
565 |
void CharSelectDialog::unlock() |
||
566 |
{ |
||
567 |
setLocked(false); |
||
568 |
} |
||
569 |
|||
570 |
void CharSelectDialog::setLocked(const bool locked) |
||
571 |
{ |
||
572 |
mLocked = locked; |
||
573 |
|||
574 |
if (mSwitchLoginButton != nullptr) |
||
575 |
mSwitchLoginButton->setEnabled(!locked); |
||
576 |
if (mChangePasswordButton != nullptr) |
||
577 |
mChangePasswordButton->setEnabled(!locked); |
||
578 |
mPlayButton->setEnabled(!locked); |
||
579 |
if (mDeleteButton != nullptr) |
||
580 |
mDeleteButton->setEnabled(!locked); |
||
581 |
|||
582 |
for (size_t i = 0, sz = mCharacterEntries.size(); i < sz; ++i) |
||
583 |
{ |
||
584 |
if (mCharacterEntries[i] != nullptr) |
||
585 |
mCharacterEntries[i]->setActive(!mLocked); |
||
586 |
} |
||
587 |
} |
||
588 |
|||
589 |
bool CharSelectDialog::selectByName(const std::string &name, |
||
590 |
const SelectAction selAction) |
||
591 |
{ |
||
592 |
if (mLocked) |
||
593 |
return false; |
||
594 |
|||
595 |
for (size_t i = 0, sz = mCharacterEntries.size(); i < sz; ++i) |
||
596 |
{ |
||
597 |
if (mCharacterEntries[i] != nullptr) |
||
598 |
{ |
||
599 |
const Net::Character *const character |
||
600 |
= mCharacterEntries[i]->getCharacter(); |
||
601 |
if (character != nullptr) |
||
602 |
{ |
||
603 |
if (character->dummy != nullptr && |
||
604 |
character->dummy->getName() == name) |
||
605 |
{ |
||
606 |
mCharacterView->show(CAST_S32(i)); |
||
607 |
updateState(); |
||
608 |
if (selAction == Choose) |
||
609 |
attemptCharacterSelect(CAST_S32(i)); |
||
610 |
return true; |
||
611 |
} |
||
612 |
} |
||
613 |
} |
||
614 |
} |
||
615 |
|||
616 |
return false; |
||
617 |
} |
||
618 |
|||
619 |
void CharSelectDialog::close() |
||
620 |
{ |
||
621 |
client->setState(State::SWITCH_LOGIN); |
||
622 |
Window::close(); |
||
623 |
} |
||
624 |
|||
625 |
1 |
void CharSelectDialog::widgetResized(const Event &event) |
|
626 |
{ |
||
627 |
1 |
Window::widgetResized(event); |
|
628 |
1 |
mCharacterView->resize(); |
|
629 |
1 |
} |
|
630 |
|||
631 |
2 |
void CharSelectDialog::updateState() |
|
632 |
{ |
||
633 |
2 |
const int idx = mCharacterView->getSelected(); |
|
634 |
✗✓ | 2 |
if (idx == -1) |
635 |
{ |
||
636 |
mPlayButton->setEnabled(false); |
||
637 |
return; |
||
638 |
} |
||
639 |
4 |
mPlayButton->setEnabled(true); |
|
640 |
|||
641 |
✓✗✓✗ ✗✓ |
6 |
if (mCharacterEntries[idx] != nullptr && |
642 |
2 |
mCharacterEntries[idx]->getCharacter() != nullptr) |
|
643 |
{ |
||
644 |
// TRANSLATORS: char select dialog. button. |
||
645 |
mPlayButton->setCaption(_("Play")); |
||
646 |
|||
647 |
const LocalPlayer *const player = mCharacterEntries[ |
||
648 |
idx]->getCharacter()->dummy; |
||
649 |
if ((player != nullptr) && (mRenameButton != nullptr)) |
||
650 |
mRenameButton->setEnabled(player->getRename() ? true : false); |
||
651 |
} |
||
652 |
else |
||
653 |
{ |
||
654 |
// TRANSLATORS: char select dialog. button. |
||
655 |
10 |
mPlayButton->setCaption(_("Create")); |
|
656 |
} |
||
657 |
} |
||
658 |
|||
659 |
void CharSelectDialog::setName(const BeingId id, const std::string &newName) |
||
660 |
{ |
||
661 |
for (unsigned int i = 0, fsz = CAST_U32( |
||
662 |
mCharacterEntries.size()); |
||
663 |
i < fsz; |
||
664 |
++i) |
||
665 |
{ |
||
666 |
CharacterDisplay *const character = mCharacterEntries[i]; |
||
667 |
if (character == nullptr) |
||
668 |
continue; |
||
669 |
LocalPlayer *const player = character->getCharacter()->dummy; |
||
670 |
if ((player != nullptr) && player->getId() == id) |
||
671 |
{ |
||
672 |
player->setName(newName); |
||
673 |
character->update(); |
||
674 |
return; |
||
675 |
} |
||
676 |
} |
||
677 |
✓✗✓✗ |
3 |
} |
Generated by: GCOVR (Version 3.3) |