ManaPlus
skillrecv.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 
23 #include "net/eathena/skillrecv.h"
24 
25 #include "notifymanager.h"
26 
27 #include "being/localplayer.h"
28 #include "being/playerinfo.h"
29 
30 #include "const/net/skill.h"
31 
33 
35 
38 
40 
41 #include "net/messagein.h"
42 
43 #include "net/eathena/menu.h"
44 
45 #include "resources/iteminfo.h"
46 
47 #include "resources/db/itemdb.h"
48 
50 
51 #include "utils/gettext.h"
52 #include "utils/stringutils.h"
53 
54 #include "debug.h"
55 
56 static const unsigned int RFAIL = 10;
57 static const unsigned int RFAIL_SUMMON = 19;
58 static const unsigned int RFAIL_NEED_ITEM = 71;
59 static const unsigned int RFAIL_NEED_EQUIPMENT = 72;
60 static const unsigned int RFAIL_SPIRITS = 74;
61 
62 extern int serverVersion;
63 
64 namespace EAthena
65 {
66 
68 {
69  msg.readInt16("len");
70  const int sz = (serverVersion >= 15) ? 41 : 37;
71  const int skillCount = (msg.getLength() - 4) / sz;
72  int updateSkill = 0;
73 
74  if (skillDialog != nullptr)
76  for (int k = 0; k < skillCount; k++)
77  {
78  const int skillId = msg.readInt16("skill id");
79  const SkillType::SkillType inf = static_cast<SkillType::SkillType>(
80  msg.readInt32("inf"));
81  if (serverVersion >= 15)
82  msg.readInt32("inf2");
83  const int level = msg.readInt16("skill level");
84  const int sp = msg.readInt16("sp");
85  const int range = msg.readInt16("range");
86  const std::string name = msg.readString(24, "skill name");
87  const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable);
88  const int oldLevel = PlayerInfo::getSkillLevel(skillId);
89  if ((oldLevel != 0) && oldLevel != level)
90  updateSkill = skillId;
91  PlayerInfo::setSkillLevel(skillId, level);
92  if (skillDialog != nullptr)
93  {
94  if (!skillDialog->updateSkill(skillId, range, up, inf, sp))
95  {
97  skillId, name, level, range, up, inf, sp);
98  }
99  }
100  }
101  if (skillDialog != nullptr)
102  {
103  skillDialog->update();
105  if (updateSkill != 0)
106  skillDialog->playUpdateEffect(updateSkill);
107  }
108 }
109 
111 {
112  int updateSkill = 0;
113  const int skillId = msg.readInt16("skill id");
114  const SkillType::SkillType inf = static_cast<SkillType::SkillType>(
115  msg.readInt32("inf"));
116  const int level = msg.readInt16("skill level");
117  const int sp = msg.readInt16("sp");
118  const int range = msg.readInt16("range");
119  const std::string name = msg.readString(24, "skill name");
120  const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable);
121  const int oldLevel = PlayerInfo::getSkillLevel(skillId);
122  if ((oldLevel != 0) && oldLevel != level)
123  updateSkill = skillId;
124  PlayerInfo::setSkillLevel(skillId, level);
125  if (skillDialog != nullptr)
126  {
127  if (!skillDialog->updateSkill(skillId, range, up, inf, sp))
128  {
130  skillId, name, level, range, up, inf, sp);
131  }
132  skillDialog->update();
133  if (updateSkill != 0)
134  skillDialog->playUpdateEffect(updateSkill);
135  }
136 }
137 
139 {
140  int updateSkill = 0;
141  msg.readInt16("len"); // for now unused
142  const int skillId = msg.readInt16("skill id");
143  const SkillType::SkillType inf = static_cast<SkillType::SkillType>(
144  msg.readInt32("inf"));
145  msg.readInt32("inf2");
146  const int level = msg.readInt16("skill level");
147  const int sp = msg.readInt16("sp");
148  const int range = msg.readInt16("range");
149  const std::string name = msg.readString(24, "skill name");
150  const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable);
151  const int oldLevel = PlayerInfo::getSkillLevel(skillId);
152  if ((oldLevel != 0) && oldLevel != level)
153  updateSkill = skillId;
154  PlayerInfo::setSkillLevel(skillId, level);
155  if (skillDialog != nullptr)
156  {
157  if (!skillDialog->updateSkill(skillId, range, up, inf, sp))
158  {
160  skillId, name, level, range, up, inf, sp);
161  }
162  skillDialog->update();
163  if (updateSkill != 0)
164  skillDialog->playUpdateEffect(updateSkill);
165  }
166 }
167 
169 {
170  int updateSkill = 0;
171  const int skillId = msg.readInt16("skill id");
172  const SkillType::SkillType inf = static_cast<SkillType::SkillType>(
173  msg.readInt32("inf"));
174  const int level = msg.readInt16("skill level");
175  const int sp = msg.readInt16("sp");
176  const int range = msg.readInt16("range");
177  const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable);
178  const int oldLevel = PlayerInfo::getSkillLevel(skillId);
179  if ((oldLevel != 0) && oldLevel != level)
180  updateSkill = skillId;
181  PlayerInfo::setSkillLevel(skillId, level);
182  if (skillDialog != nullptr)
183  {
184  if (!skillDialog->updateSkill(skillId, range, up, inf, sp))
185  {
187  skillId, "", level, range, up, inf, sp);
188  }
189  skillDialog->update();
190  if (updateSkill != 0)
191  skillDialog->playUpdateEffect(updateSkill);
192  }
193 }
194 
196 {
197  int updateSkill = 0;
198  msg.readInt16("len"); // for now unused
199  const int skillId = msg.readInt16("skill id");
200  const SkillType::SkillType inf = static_cast<SkillType::SkillType>(
201  msg.readInt32("inf"));
202  msg.readInt32("inf2");
203  const int level = msg.readInt16("skill level");
204  const int sp = msg.readInt16("sp");
205  const int range = msg.readInt16("range");
206  const Modifiable up = fromBool(msg.readUInt8("up flag"), Modifiable);
207  const int oldLevel = PlayerInfo::getSkillLevel(skillId);
208  if ((oldLevel != 0) && oldLevel != level)
209  updateSkill = skillId;
210  PlayerInfo::setSkillLevel(skillId, level);
211  if (skillDialog != nullptr)
212  {
213  if (!skillDialog->updateSkill(skillId, range, up, inf, sp))
214  {
216  skillId, "", level, range, up, inf, sp);
217  }
218  skillDialog->update();
219  if (updateSkill != 0)
220  skillDialog->playUpdateEffect(updateSkill);
221  }
222 }
223 
225 {
226  int updateSkill = 0;
227  const int skillId = msg.readInt16("skill id");
228  const int oldLevel = PlayerInfo::getSkillLevel(skillId);
229  if (oldLevel != 0)
230  updateSkill = skillId;
231  PlayerInfo::setSkillLevel(skillId, 0);
232  if (skillDialog != nullptr)
233  {
234  skillDialog->removeSkill(skillId);
235  skillDialog->update();
236  if (updateSkill != 0)
237  skillDialog->playRemoveEffect(updateSkill);
238  }
239 }
240 
242 {
243  const int skillId = msg.readInt16("skill id");
244  const int duration = msg.readInt32("duration");
245  if (skillDialog != nullptr)
246  skillDialog->setSkillDuration(SkillOwner::Player, skillId, duration);
247 }
248 
250 {
251  int packetLen;
252  if (msg.getVersion() >= 20120604)
253  packetLen = 10;
254  else
255  packetLen = 6;
256  const int count = (msg.readInt16("len") - 4) / packetLen;
257  for (int f = 0; f < count; f ++)
258  {
259  const int skillId = msg.readInt16("skill id");
260  if (msg.getVersion() >= 20120604)
261  msg.readInt32("total");
262  const int duration = msg.readInt32("duration");
263  if (skillDialog != nullptr)
264  {
266  skillId, duration);
267  }
268  }
269 }
270 
272 {
273  // Action failed (ex. sit because you have not reached the
274  // right level)
275  const int skillId = msg.readInt16("skill id");
276  const int bskill = msg.readInt32("btype");
277  const signed char success = msg.readUInt8("success");
278  const signed char reason = msg.readUInt8("reason");
279  if (success != CAST_S32(SKILL_FAILED)
280  && bskill == CAST_S32(BSKILL_EMOTE))
281  {
282  logger->log("Action: %d/%d", bskill, success);
283  }
284 
285  if (localPlayer != nullptr)
286  localPlayer->stopCast(true);
287  std::string txt;
288  if (success == CAST_S32(SKILL_FAILED) && bskill != 0)
289  {
290  if ((localPlayer != nullptr) && bskill == CAST_S32(BSKILL_EMOTE)
291  && reason == CAST_S32(RFAIL_SKILLDEP))
292  {
294  }
295 
296  const SkillInfo *const info = skillDialog->getSkill(bskill);
297  if (info != nullptr)
298  {
299  txt = info->errorText;
300  }
301  else
302  {
303  // TRANSLATORS: skill error message
304  txt = strprintf(_("Unknown skill error: %d"), bskill);
305  }
306  }
307  else
308  {
309  const SkillInfo *const info = skillDialog->getSkill(skillId);
310  if (info != nullptr)
311  {
312  txt = info->errorText + ".";
313  }
314  else
315  {
316  // TRANSLATORS: skill error message
317  txt = strprintf(_("Unknown skill error: %d."), skillId);
318  }
319  }
320 
321  txt.append(" ");
322  switch (reason)
323  {
324  case RFAIL_SKILLDEP:
325  // TRANSLATORS: error message
326  txt.append(_("You have not yet reached a high enough lvl!"));
327  break;
328  case RFAIL_INSUFHP:
329  // TRANSLATORS: error message
330  txt.append(_("Insufficient HP!"));
331  break;
332  case RFAIL_INSUFSP:
333  // TRANSLATORS: error message
334  txt.append(_("Insufficient SP!"));
335  break;
336  case RFAIL_NOMEMO:
337  // TRANSLATORS: error message
338  txt.append(_("You have no memos!"));
339  break;
340  case RFAIL_SKILLDELAY:
341  // TRANSLATORS: error message
342  txt.append(_("You cannot do that right now!"));
343  break;
344  case RFAIL_ZENY:
345  // TRANSLATORS: error message
346  txt.append(_("Seems you need more money... ;-)"));
347  break;
348  case RFAIL_WEAPON:
349  // TRANSLATORS: error message
350  txt.append(_("You cannot use this skill with that "
351  "kind of weapon!"));
352  break;
353  case RFAIL_REDGEM:
354  // TRANSLATORS: error message
355  txt.append(_("You need another red gem!"));
356  break;
357  case RFAIL_BLUEGEM:
358  // TRANSLATORS: error message
359  txt.append(_("You need another blue gem!"));
360  break;
361  case RFAIL_OVERWEIGHT:
362  // TRANSLATORS: error message
363  txt.append(_("You're carrying to much to do this!"));
364  break;
365  case RFAIL_SUMMON:
366  // TRANSLATORS: error message
367  txt.append(_("Fail summon."));
368  break;
369  case RFAIL_SPIRITS:
370  // TRANSLATORS: error message
371  txt.append(_("Need spirits."));
372  break;
374  {
375  const int itemId = bskill >> 16U;
376  const int amount = bskill & 0xFFFFU;
377  const ItemInfo &info = ItemDB::get(itemId);
378  if (amount == 1)
379  {
380  // TRANSLATORS: skill error message
381  txt.append(strprintf(_("Need equipment %s."),
382  info.getLink().c_str()));
383  }
384  else
385  {
386  // TRANSLATORS: skill error message
387  txt.append(strprintf(_("Need equipment %s and amount %d"),
388  info.getLink().c_str(),
389  amount));
390  }
391  break;
392  }
393  case RFAIL_NEED_ITEM:
394  {
395  const int itemId = bskill >> 16U;
396  const int amount = bskill & 0xFFFFU;
397  const ItemInfo &info = ItemDB::get(itemId);
398  if (amount == 1)
399  {
400  // TRANSLATORS: skill error message
401  txt.append(strprintf(_("Need item %s."),
402  info.getLink().c_str()));
403  }
404  else
405  {
406  // TRANSLATORS: skill error message
407  txt.append(strprintf(_("Need item %s and amount %d"),
408  info.getLink().c_str(),
409  amount));
410  }
411  break;
412  }
413  case RFAIL:
414  {
415  // TRANSLATORS: error message
416  txt.append(_("Skill failed!"));
417  break;
418  }
419 
420  default:
421  UNIMPLEMENTEDPACKETFIELD(reason);
422  break;
423  }
424 
426 }
427 
429 {
430  const int skillId = msg.readInt16("skill id");
431 
433  // TRANSLATORS: warp select window name
434  _("Select warp target"),
435  // TRANSLATORS: warp select button
436  _("Warp"),
439  skillWarpListener.setSkill(skillId);
441  for (int f = 0; f < 4; f ++)
442  dialog->addText(msg.readString(16, "map name"));
443 }
444 
446 {
447  const int type = msg.readUInt8("type");
448  switch (type)
449  {
450  case 0:
452  break;
453  case 1:
455  break;
456  case 2:
458  break;
459  default:
461  break;
462  }
463 }
464 
466 {
468 
469  const int count = (msg.readInt16("len") - 8) / 8;
470  for (int f = 0; f < count; f ++)
471  {
472  msg.readInt16("item id");
473  for (int d = 0; d < 3; d ++)
474  msg.readInt16("material id");
475  }
476 }
477 
479 {
481 
482  msg.readInt16("flag");
483  msg.readInt16("item id");
484 }
485 
487 {
489 
490  msg.readBeingId("being id");
491 }
492 
494 {
496 
497  const int count = (msg.readInt16("len") - 4) / 2;
498  for (int f = 0; f < count; f ++)
499  msg.readInt16("item id");
500 }
501 
503 {
505 
506  for (int f = 0; f < 7; f ++)
507  msg.readInt32("skill id");
508 
510 }
511 
513 {
515 
516  msg.readBeingId("being id");
517  for (int f = 0; f < 5; f ++)
518  msg.readInt32("devotee id");
519  msg.readInt16("range");
520 }
521 
523 {
525 
526  msg.readInt32("skill level");
527  msg.readInt32("unused");
528 }
529 
531 {
532  msg.readBeingId("being id");
533  msg.readInt16("skill id");
534  msg.readInt16("skill level");
535  msg.readInt16("x");
536  msg.readInt16("y");
537  msg.readInt32("cast time");
538 }
539 
540 } // namespace EAthena
void processSkillItemListWindow(Net::MessageIn &msg)
Definition: skillrecv.cpp:522
unsigned char readUInt8(const char *const str)
Definition: messagein.cpp:98
#define _(s)
Definition: gettext.h:34
const ItemInfo & get(const int id)
Definition: itemdb.cpp:792
BeingId readBeingId(const char *const str)
Definition: messagein.cpp:211
void processSkillUnitUpdate(Net::MessageIn &msg)
Definition: skillrecv.cpp:486
void stopAdvert()
static const unsigned int RFAIL_NEED_ITEM
Definition: skillrecv.cpp:58
static const unsigned int RFAIL_SKILLDEP
Definition: skill.h:43
static const unsigned int RFAIL_REDGEM
Definition: skill.h:50
const std::string getLink() const
Definition: iteminfo.cpp:480
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:251
const bool AllowQuit_false
Definition: allowquit.h:29
bool updateSkill(const int id, const int range, const Modifiable modifiable, const SkillType::SkillType type, const int sp)
void removeSkill(const int id)
unsigned int getLength() const
Definition: messagein.h:58
void processPlayerSkills(Net::MessageIn &msg)
Definition: skillrecv.cpp:67
void processSkillAutoSpells(Net::MessageIn &msg)
Definition: skillrecv.cpp:502
void processSkillMemoMessage(Net::MessageIn &msg)
Definition: skillrecv.cpp:445
bool msg(InputEvent &event)
Definition: chat.cpp:38
void setSkillDuration(const SkillOwner::Type owner, const int id, const int duration)
void processSkillProduceEffect(Net::MessageIn &msg)
Definition: skillrecv.cpp:478
static const unsigned int RFAIL_BLUEGEM
Definition: skill.h:51
void notify(const unsigned int message)
void setSkill(const int skillId)
void hideSkills(const SkillOwner::Type owner)
static const unsigned int RFAIL_SPIRITS
Definition: skillrecv.cpp:60
bool Modifiable
Definition: modifiable.h:29
std::string errorText
Definition: skillinfo.h:54
Logger * logger
Definition: logger.cpp:88
void updateModelsHidden()
void processSkillFailed(Net::MessageIn &msg)
Definition: skillrecv.cpp:271
int16_t readInt16(const char *const str)
Definition: messagein.cpp:125
SkillInfo * getSkill(const int id) const
static const unsigned int RFAIL_SKILLDELAY
Definition: skill.h:47
#define CAST_S32
Definition: cast.h:29
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
void processSkillWarpPoint(Net::MessageIn &msg)
Definition: skillrecv.cpp:428
std::string update(const int id)
void addText(const std::string &text)
void stopCast(const bool b)
Definition: being.cpp:5522
#define fromBool(val, name)
Definition: booldefines.h:48
void processSkillUpdate(Net::MessageIn &msg)
Definition: skillrecv.cpp:168
bool info(InputEvent &event)
Definition: commands.cpp:56
static const unsigned int RFAIL_INSUFSP
Definition: skill.h:44
void processSkillDelete(Net::MessageIn &msg)
Definition: skillrecv.cpp:224
void processSkillScale(Net::MessageIn &msg)
Definition: skillrecv.cpp:530
static const unsigned int BSKILL_EMOTE
Definition: skill.h:36
LocalPlayer * localPlayer
static const unsigned int RFAIL_INSUFHP
Definition: skill.h:45
void processSkillCoolDown(Net::MessageIn &msg)
Definition: skillrecv.cpp:241
MenuTypeT menu
Definition: menu.cpp:27
static const unsigned int RFAIL_ZENY
Definition: skill.h:48
void playUpdateEffect(const int id) const
unsigned int getVersion() const
Definition: messagein.h:131
void setSkillLevel(const int id, const int value)
Definition: playerinfo.cpp:126
void processSkillUpdate2(Net::MessageIn &msg)
Definition: skillrecv.cpp:195
static const unsigned int RFAIL_SUMMON
Definition: skillrecv.cpp:57
static const unsigned int RFAIL_NEED_EQUIPMENT
Definition: skillrecv.cpp:59
SkillDialog * skillDialog
Definition: skilldialog.cpp:65
void processSkillProduceMixList(Net::MessageIn &msg)
Definition: skillrecv.cpp:465
int getSkillLevel(const int id)
Definition: playerinfo.cpp:118
void processSkillDevotionEffect(Net::MessageIn &msg)
Definition: skillrecv.cpp:512
void processSkillAdd(Net::MessageIn &msg)
Definition: skillrecv.cpp:110
static const unsigned int RFAIL_NOMEMO
Definition: skill.h:46
void setDialog(TextSelectDialog *const dialog)
void addSkill(const SkillOwner::Type owner, const int id, const std::string &name, const int level, const int range, const Modifiable modifiable, const SkillType::SkillType type, const int sp)
SkillWarpListener skillWarpListener
void processSkillAdd2(Net::MessageIn &msg)
Definition: skillrecv.cpp:138
std::string readString(int length, const char *const dstr)
Definition: messagein.cpp:355
#define UNIMPLEMENTEDPACKET
Definition: logger.h:55
static const unsigned int RFAIL_OVERWEIGHT
Definition: skill.h:52
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:35
void log(const char *const log_text,...)
Definition: logger.cpp:264
void processSkillCoolDownList(Net::MessageIn &msg)
Definition: skillrecv.cpp:249
int32_t readInt32(const char *const str)
Definition: messagein.cpp:169
void processSkillArrowCreateList(Net::MessageIn &msg)
Definition: skillrecv.cpp:493
void playRemoveEffect(const int id) const
static const unsigned int RFAIL
Definition: skillrecv.cpp:56
#define UNIMPLEMENTEDPACKETFIELD(field)
Definition: logger.h:58
static const unsigned int RFAIL_WEAPON
Definition: skill.h:49
int serverVersion
Definition: client.cpp:123
static const unsigned int SKILL_FAILED
Definition: skill.h:55