ManaPlus
beingrecv.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/beingrecv.h"
24 
25 #include "actormanager.h"
26 #include "effectmanager.h"
27 #include "game.h"
28 #include "notifymanager.h"
29 #include "party.h"
30 
31 #include "being/mercenaryinfo.h"
32 
33 #include "const/utils/timer.h"
34 
36 
38 
39 #include "input/keyboardconfig.h"
40 
41 #include "gui/viewport.h"
42 
45 #include "gui/windows/okdialog.h"
47 
48 #include "net/character.h"
49 #include "net/charserverhandler.h"
50 #include "net/messagein.h"
51 #include "net/serverfeatures.h"
52 
53 #include "net/ea/beingrecv.h"
54 
56 #include "net/eathena/sp.h"
57 #include "net/eathena/sprite.h"
58 
59 #include "resources/iteminfo.h"
60 #include "resources/db/itemdb.h"
61 
62 #include "resources/map/map.h"
63 
64 #include "utils/checkutils.h"
65 #include "utils/foreach.h"
66 #include "utils/timer.h"
67 
68 #include "debug.h"
69 
70 extern int serverVersion;
71 extern OkDialog *deathNotice;
72 
73 namespace EAthena
74 {
75 
76 static void setBasicFields(Being *restrict const dstBeing,
77  const uint8_t gender,
78  const int hairStyle,
79  const ItemColor hairColor,
80  const uint32_t weapon,
81  const uint16_t headBottom,
82  const uint16_t headMid,
83  const uint16_t headTop,
84  const uint16_t shoes,
85  const uint16_t gloves,
86  const bool notMove) A_NONNULL(1);
87 static void setBasicFields(Being *restrict const dstBeing,
88  const uint8_t gender,
89  const int hairStyle,
90  const ItemColor hairColor,
91  const uint32_t weapon,
92  const uint16_t headBottom,
93  const uint16_t headMid,
94  const uint16_t headTop,
95  const uint16_t shoes,
96  const uint16_t gloves,
97  const bool updateSlots)
98 {
99  const ActorTypeT actorType = dstBeing->getType();
100  switch (actorType)
101  {
102  case ActorType::Player:
103  dstBeing->setGender(Being::intToGender(gender));
104  dstBeing->setHairColor(hairColor);
105  // Set these after the gender, as the sprites may be gender-specific
106  if (hairStyle == 0)
107  {
108  dstBeing->updateSprite(SPRITE_HAIR_COLOR,
109  0,
110  std::string());
111  }
112  else
113  {
114  dstBeing->updateSprite(SPRITE_HAIR_COLOR,
115  hairStyle * -1,
116  ItemDB::get(-hairStyle).getDyeColorsString(hairColor));
117  }
118  if (updateSlots)
119  {
120  dstBeing->updateSprite(SPRITE_WEAPON,
121  headBottom,
122  std::string());
123  dstBeing->updateSprite(SPRITE_HEAD_BOTTOM,
124  headMid,
125  std::string());
126  dstBeing->updateSprite(SPRITE_CLOTHES_COLOR,
127  headTop,
128  std::string());
129  dstBeing->updateSprite(SPRITE_HAIR,
130  shoes,
131  std::string());
132  dstBeing->updateSprite(SPRITE_SHOES,
133  gloves,
134  std::string());
135  dstBeing->updateSprite(SPRITE_BODY,
136  weapon,
137  std::string());
138  dstBeing->setWeaponId(weapon);
139  }
140  break;
141  case ActorType::Npc:
143  {
144  dstBeing->setGender(Being::intToGender(gender));
145  }
146  if (dstBeing->getAllowNpcEquipment())
147  {
148  dstBeing->setHairColor(hairColor);
149  dstBeing->setHairStyle(SPRITE_HAIR_COLOR, -hairStyle);
150  // for npc not checking updateSlots flag,
151  // probably because npc missing visible packet if moving
152  dstBeing->updateSprite(SPRITE_WEAPON,
153  headBottom,
154  std::string());
155  dstBeing->updateSprite(SPRITE_HEAD_BOTTOM,
156  headMid,
157  std::string());
158  dstBeing->updateSprite(SPRITE_CLOTHES_COLOR,
159  headTop,
160  std::string());
161  dstBeing->updateSprite(SPRITE_HAIR,
162  shoes,
163  std::string());
164  dstBeing->updateSprite(SPRITE_SHOES,
165  gloves,
166  std::string());
167  dstBeing->updateSprite(SPRITE_BODY,
168  weapon,
169  std::string());
170  dstBeing->setWeaponId(weapon);
171  }
172  break;
173  default:
174  case ActorType::Monster:
175  case ActorType::Portal:
176  case ActorType::Pet:
181  break;
183  case ActorType::Avatar:
184  case ActorType::Unknown:
185  reportAlways("Wrong being type detected: %d",
186  CAST_S32(actorType));
187  break;
188  }
189 }
190 
192 {
193  if (actorManager == nullptr)
194  return;
195 
196  Being *const dstBeing = actorManager->findBeing(
197  msg.readBeingId("being id"));
198  const uint8_t type = msg.readUInt8("type");
199 
200  const int id = msg.readInt16("id1");
201  unsigned int id2 = msg.readInt16("id2");
202  if (type != 2)
203  id2 = 1;
204 
205  if ((localPlayer == nullptr) || (dstBeing == nullptr))
206  return;
207 
208  processBeingChangeLookContinue(msg, dstBeing, type, id, id2, nullptr);
209 }
210 
212 {
213  Being *dstBeing = nullptr;
214  int cards[maxCards];
215 
216  if (actorManager == nullptr)
217  { // here can be look from char server
219  const BeingId id = msg.readBeingId("being id");
220 
221  FOR_EACH (Net::Characters::iterator, it, chars)
222  {
223  const Net::Character *const character = *it;
224  if (character->dummy != nullptr &&
225  character->dummy->getId() == id)
226  {
227  dstBeing = character->dummy;
228  break;
229  }
230  }
231  }
232  else
233  {
234  dstBeing = actorManager->findBeing(
235  msg.readBeingId("being id"));
236  }
237 
238  const uint8_t type = msg.readUInt8("type");
239 
240  const int id = msg.readInt16("id1");
241  unsigned int id2 = msg.readInt16("id2");
242  if (type != 2)
243  id2 = 1;
244 
245  for (int f = 0; f < maxCards; f ++)
246  cards[f] = msg.readUInt16("card");
247 
248  if (dstBeing == nullptr)
249  return;
250 
251  processBeingChangeLookContinue(msg, dstBeing, type, id, id2, &cards[0]);
252 }
253 
255  Being *const dstBeing,
256  const uint8_t type,
257  const int id,
258  const int id2,
259  const int *const cards)
260 {
261  if (dstBeing->getType() == ActorType::Player)
262  dstBeing->setOtherTime();
263 
264  switch (type)
265  {
266  // here should be used SPRITE_* constants
267  // but for now they conflicting with sprites
268  // SPRITE_* is same with server LOOK_*
269  case 0: // change race
270  dstBeing->setSubtype(fromInt(id, BeingTypeId),
271  dstBeing->getLook());
272  break;
273  case 1: // eAthena LOOK_HAIR
274  dstBeing->setHairColor(fromInt(id, ItemColor));
276  id * -1);
277  break;
278  case 2: // LOOK_WEAPON Weapon ID in id, Shield ID in id2
279  dstBeing->setSpriteCards(SPRITE_BODY,
280  id,
281  CardsList(cards));
282  dstBeing->setWeaponId(id);
283  dstBeing->setSpriteId(SPRITE_FLOOR,
284  id2);
285  if (localPlayer != nullptr)
287  break;
288  case 3: // LOOK_HEAD_BOTTOM
289  dstBeing->setSpriteCards(SPRITE_WEAPON,
290  id,
291  CardsList(cards));
292  if (localPlayer != nullptr)
294  break;
295  case 4: // LOOK_HEAD_TOP Change upper headgear for eAthena, hat for us
297  id,
298  CardsList(cards));
299  if (localPlayer != nullptr)
301  break;
302  case 5: // LOOK_HEAD_MID Change middle headgear for eathena,
303  // armor for us
305  id,
306  CardsList(cards));
307  if (localPlayer != nullptr)
309  break;
310  case 6: // eAthena LOOK_HAIR_COLOR
311  dstBeing->setHairColor(fromInt(id, ItemColor));
313  ItemDB::get(dstBeing->getSpriteID(
314  SPRITE_HAIR_COLOR)).getDyeColorsString(
315  fromInt(id, ItemColor)));
316  break;
317  case 7: // Clothes color. Now used as look
318  dstBeing->setLook(CAST_U8(id));
319  break;
320  case 8: // eAthena LOOK_SHIELD
321  dstBeing->setSpriteCards(SPRITE_FLOOR,
322  id,
323  CardsList(cards));
324  if (localPlayer != nullptr)
326  break;
327  case 9: // eAthena LOOK_SHOES
328  dstBeing->setSpriteCards(SPRITE_HAIR,
329  id,
330  CardsList(cards));
331  if (localPlayer != nullptr)
333  break;
334  case 10: // LOOK_GLOVES
335  dstBeing->setSpriteCards(SPRITE_SHOES,
336  id,
337  CardsList(cards));
338  if (localPlayer != nullptr)
340  break;
341  case 11: // LOOK_FLOOR
342  dstBeing->setSpriteCards(SPRITE_SHIELD,
343  id,
344  CardsList(cards));
345  if (localPlayer != nullptr)
347  break;
348  case 12: // LOOK_ROBE
350  id,
351  CardsList(cards));
352  if (localPlayer != nullptr)
354  break;
355  case 13: // COSTUME_HEAD_TOP
357  id,
358  CardsList(cards));
359  if (localPlayer != nullptr)
361  break;
362  case 14: // COSTUME_HEAD_MID
363  dstBeing->setSpriteCards(SPRITE_ROBE,
364  id,
365  CardsList(cards));
366  if (localPlayer != nullptr)
368  break;
369  case 15: // COSTUME_HEAD_LOW
370  dstBeing->setSpriteCards(SPRITE_EVOL2,
371  id,
372  CardsList(cards));
373  if (localPlayer != nullptr)
375  break;
376  case 16: // COSTUME_GARMENT
377  dstBeing->setSpriteCards(SPRITE_EVOL3,
378  id,
379  CardsList(cards));
380  if (localPlayer != nullptr)
382  break;
383  case 17: // ARMOR
384  dstBeing->setSpriteCards(SPRITE_EVOL4,
385  id,
386  CardsList(cards));
387  if (localPlayer != nullptr)
389  break;
390  case 18:
391  dstBeing->setSpriteCards(SPRITE_EVOL5,
392  id,
393  CardsList(cards));
394  if (localPlayer != nullptr)
396  break;
397  case 19:
398  dstBeing->setSpriteCards(SPRITE_EVOL6,
399  id,
400  CardsList(cards));
401  if (localPlayer != nullptr)
403  break;
404  default:
406  break;
407  }
408 }
409 
411 {
412  if (actorManager == nullptr)
413  return;
414 
415  // need set type based on id
417  if (msg.getVersion() >= 20091103)
418  {
419  msg.readInt16("len");
420  type = static_cast<BeingTypeT>(
421  msg.readUInt8("object type"));
422  }
423 
424  // Information about a being in range
425  const BeingId id = msg.readBeingId("being id");
426  if (msg.getVersion() >= 20131223)
427  msg.readBeingId("char id");
428  BeingId spawnId;
429  if (id == Ea::BeingRecv::mSpawnId)
430  spawnId = Ea::BeingRecv::mSpawnId;
431  else
432  spawnId = BeingId_zero;
434 
435  int16_t speed = msg.readInt16("speed");
436  const uint32_t opt1 = msg.readInt16("opt1");
437  // probably wrong effect usage
438  const uint32_t opt2 = msg.readInt16("opt2");
439  uint32_t option;
440  if (msg.getVersion() >= 20080102)
441  option = msg.readInt32("option");
442  else
443  option = msg.readInt16("option");
444  const int16_t job = msg.readInt16("class");
445 
446  Being *dstBeing = actorManager->findBeing(id);
447 
448  if ((dstBeing != nullptr) && dstBeing->getType() == ActorType::Monster
449  && !dstBeing->isAlive())
450  {
451  actorManager->destroy(dstBeing);
452  actorManager->erase(dstBeing);
453  dstBeing = nullptr;
454  }
455 
456  if (dstBeing == nullptr)
457  {
458  if (actorManager->isBlocked(id) == true)
459  return;
460 
461  dstBeing = createBeing2(msg, id, job, type);
462  if (dstBeing == nullptr)
463  return;
464  }
465  else
466  {
467  // undeleting marked for deletion being
468  if (dstBeing->getType() == ActorType::Npc)
469  actorManager->undelete(dstBeing);
470  }
471 
472  if (dstBeing->getType() == ActorType::Player)
473  dstBeing->setMoveTime();
474 
475  if (spawnId != BeingId_zero)
476  {
477  dstBeing->setAction(BeingAction::SPAWN, 0);
478  }
479  else
480  {
481  dstBeing->clearPath();
482  dstBeing->setActionTime(tick_time);
483  dstBeing->setAction(BeingAction::STAND, 0);
484  }
485 
486  // Prevent division by 0 when calculating frame
487  if (speed == 0)
488  speed = 150;
489 
490  dstBeing->setWalkSpeed(speed);
491  dstBeing->setSubtype(fromInt(job, BeingTypeId), 0);
492  if (dstBeing->getType() == ActorType::Monster && (localPlayer != nullptr))
493  localPlayer->checkNewName(dstBeing);
494 
495  const int hairStyle = msg.readInt16("hair style");
496  uint32_t weapon;
497  if (msg.getVersion() >= 7)
498  weapon = CAST_U32(msg.readInt32("weapon"));
499  else
500  weapon = CAST_U32(msg.readInt16("weapon"));
501  const uint16_t headBottom = msg.readInt16("head bottom");
502  if (msg.getVersion() < 7)
503  msg.readInt16("shield");
504  const uint16_t headTop = msg.readInt16("head top");
505  const uint16_t headMid = msg.readInt16("head mid");
506  const ItemColor hairColor = fromInt(msg.readInt16("hair color"),
507  ItemColor);
508  const uint16_t shoes = msg.readInt16("shoes or clothes color?");
509 
510  const uint16_t gloves = msg.readInt16("head dir / gloves");
511  // may be use robe as gloves?
512  if (msg.getVersion() >= 20101124)
513  msg.readInt16("robe");
514  msg.readInt32("guild id");
515  msg.readInt16("guild emblem");
516  dstBeing->setManner(msg.readInt16("manner"));
517  uint32_t opt3;
518  if (msg.getVersion() >= 7)
519  opt3 = msg.readInt32("opt3");
520  else
521  opt3 = msg.readInt16("opt3");
522  dstBeing->setKarma(msg.readUInt8("karma"));
523  const uint8_t gender = CAST_U8(msg.readUInt8("gender") & 3);
524 
525  setBasicFields(dstBeing,
526  gender,
527  hairStyle,
528  hairColor,
529  weapon,
530  headBottom,
531  headMid,
532  headTop,
533  shoes,
534  gloves,
535  true);
536 
537  uint8_t dir;
538  uint16_t x, y;
539  msg.readCoordinates(x, y, dir, "position");
540  msg.readInt8("xs");
541  msg.readInt8("ys");
542  applyPlayerAction(msg, dstBeing, msg.readUInt8("action type"));
543  dstBeing->setTileCoords(x, y);
544 
545  if (job == 45 && (socialWindow != nullptr) && (outfitWindow != nullptr))
546  {
547  const int num = socialWindow->getPortalIndex(x, y);
548  if (num >= 0)
549  {
551  OutfitWindow::keyName(num)));
552  }
553  else
554  {
555  dstBeing->setName("");
556  }
557  }
558 
559  dstBeing->setDirection(dir);
560 
561  const int level = CAST_S32(msg.readInt16("level"));
562  if (level != 0)
563  dstBeing->setLevel(level);
564  if (msg.getVersion() >= 20080102)
565  msg.readInt16("font");
566 
567  if (msg.getVersion() >= 20120221)
568  {
569  const int maxHP = msg.readInt32("max hp");
570  const int hp = msg.readInt32("hp");
571  dstBeing->setMaxHP(maxHP);
572  dstBeing->setHP(hp);
573  msg.readInt8("is boss");
574  }
575 
576  if (serverVersion == 0 ||
577  serverVersion >= 16)
578  {
579  if (msg.getVersion() >= 20150513)
580  {
581  msg.readInt16("body2");
582  }
583  if (msg.getVersion() >= 20131223)
584  {
585  msg.readString(24, "name");
586  }
587  }
588  else
589  {
590  if (msg.getVersion() >= 20150513)
591  {
592  msg.readInt16("body2");
593  msg.readString(24, "name");
594  }
595  }
596 
597  dstBeing->setStatusEffectOpitons(option,
598  opt1,
599  opt2,
600  opt3);
601 }
602 
604 {
605  if (actorManager == nullptr)
606  return;
607 
608  if (msg.getVersion() >= 20091103)
609  msg.readInt16("len");
610  BeingTypeT type;
611  if (msg.getVersion() >= 20071106)
612  {
613  type = static_cast<BeingTypeT>(
614  msg.readUInt8("object type"));
615  }
616  else
617  {
618  // need detect type based on id
619  type = BeingType::MONSTER;
620  }
621 
622  // Information about a being in range
623  const BeingId id = msg.readBeingId("being id");
624  if (msg.getVersion() >= 20131223)
625  msg.readBeingId("char id");
626  BeingId spawnId;
627  if (id == Ea::BeingRecv::mSpawnId)
628  spawnId = Ea::BeingRecv::mSpawnId;
629  else
630  spawnId = BeingId_zero;
632  int16_t speed = msg.readInt16("speed");
633  const uint32_t opt1 = msg.readInt16("opt1");
634  // probably wrong effect usage
635  const uint32_t opt2 = msg.readInt16("opt2");
636  uint32_t option;
637  if (msg.getVersion() >= 7)
638  option = msg.readInt32("option");
639  else
640  option = msg.readInt16("option");
641  const int16_t job = msg.readInt16("class");
642 
643  Being *dstBeing = actorManager->findBeing(id);
644 
645  if ((dstBeing != nullptr) && dstBeing->getType() == ActorType::Monster
646  && !dstBeing->isAlive())
647  {
648  actorManager->destroy(dstBeing);
649  actorManager->erase(dstBeing);
650  dstBeing = nullptr;
651  }
652 
653  if (dstBeing == nullptr)
654  {
655  if (actorManager->isBlocked(id) == true)
656  return;
657 
658  dstBeing = createBeing2(msg, id, job, type);
659  if (dstBeing == nullptr)
660  return;
661  }
662  else
663  {
664  // undeleting marked for deletion being
665  if (dstBeing->getType() == ActorType::Npc)
666  actorManager->undelete(dstBeing);
667  }
668 
669  if (dstBeing->getType() == ActorType::Player)
670  dstBeing->setMoveTime();
671 
672  if (spawnId != BeingId_zero)
673  dstBeing->setAction(BeingAction::SPAWN, 0);
674 
675  // Prevent division by 0 when calculating frame
676  if (speed == 0)
677  speed = 150;
678 
679  dstBeing->setWalkSpeed(speed);
680  dstBeing->setSubtype(fromInt(job, BeingTypeId), 0);
681  if (dstBeing->getType() == ActorType::Monster && (localPlayer != nullptr))
682  localPlayer->checkNewName(dstBeing);
683 
684  const int hairStyle = msg.readInt16("hair style");
685  uint32_t weapon;
686  if (msg.getVersion() >= 7)
687  weapon = CAST_U32(msg.readInt32("weapon"));
688  else
689  weapon = CAST_U32(msg.readInt16("weapon"));
690  const uint16_t headBottom = msg.readInt16("head bottom");
691  msg.readInt32("tick");
692  if (msg.getVersion() < 7)
693  msg.readInt16("shield");
694  const uint16_t headTop = msg.readInt16("head top");
695  const uint16_t headMid = msg.readInt16("head mid");
696  const ItemColor hairColor = fromInt(
697  msg.readInt16("hair color"), ItemColor);
698  const uint16_t shoes = msg.readInt16("shoes or clothes color?");
699 
700  const uint16_t gloves = msg.readInt16("head dir / gloves");
701  // may be use robe as gloves?
702  if (msg.getVersion() >= 20101124)
703  msg.readInt16("robe");
704  msg.readInt32("guild id");
705  msg.readInt16("guild emblem");
706  dstBeing->setManner(msg.readInt16("manner"));
707  uint32_t opt3;
708  if (msg.getVersion() >= 7)
709  opt3 = msg.readInt32("opt3");
710  else
711  opt3 = msg.readInt16("opt3");
712  dstBeing->setKarma(msg.readUInt8("karma"));
713  const uint8_t gender = CAST_U8(msg.readUInt8("gender") & 3);
714 
715  setBasicFields(dstBeing,
716  gender,
717  hairStyle,
718  hairColor,
719  weapon,
720  headBottom,
721  headMid,
722  headTop,
723  shoes,
724  gloves,
726 
727  uint16_t srcX, srcY, dstX, dstY;
728  msg.readCoordinatePair(srcX, srcY, dstX, dstY, "move path");
729  msg.readUInt8("(sx<<4) | (sy&0x0f)");
730  msg.readInt8("xs");
731  msg.readInt8("ys");
732  dstBeing->setAction(BeingAction::STAND, 0);
733  dstBeing->setTileCoords(srcX, srcY);
734  if (localPlayer != nullptr)
735  localPlayer->followMoveTo(dstBeing, srcX, srcY, dstX, dstY);
736  if (serverFeatures->haveMove3())
737  dstBeing->setCachedDestination(dstX, dstY);
738  else
739  dstBeing->setDestination(dstX, dstY);
740 
741  // because server don't send direction in move packet, we fixing it
742 
743  uint8_t d = 0;
744  if (localPlayer != nullptr &&
745  srcX == dstX &&
746  srcY == dstY)
747  { // if player did one step from invisible area to visible,
748  // move path is broken
749  int x2 = localPlayer->getTileX();
750  int y2 = localPlayer->getTileY();
751  if (abs(x2 - srcX) > abs(y2 - srcY))
752  y2 = srcY;
753  else
754  x2 = srcX;
755  d = dstBeing->calcDirection(x2, y2);
756  }
757  else
758  {
759  d = dstBeing->calcDirection(dstX, dstY);
760  }
761  if ((d != 0u) && dstBeing->getDirection() != d)
762  dstBeing->setDirection(d);
763 
764  const int level = CAST_S32(msg.readInt16("level"));
765  if (level != 0)
766  dstBeing->setLevel(level);
767  if (msg.getVersion() >= 20080102)
768  msg.readInt16("font");
769  if (msg.getVersion() >= 20120221)
770  {
771  const int maxHP = msg.readInt32("max hp");
772  const int hp = msg.readInt32("hp");
773  dstBeing->setMaxHP(maxHP);
774  dstBeing->setHP(hp);
775  msg.readInt8("is boss");
776  }
777  if (serverVersion == 0 ||
778  serverVersion >= 16)
779  {
780  if (msg.getVersion() >= 20150513)
781  {
782  msg.readInt16("body2");
783  }
784  if (msg.getVersion() >= 20131223)
785  {
786  msg.readString(24, "name");
787  }
788  }
789  else
790  {
791  if (msg.getVersion() >= 20150513)
792  {
793  msg.readInt16("body2");
794  msg.readString(24, "name");
795  }
796  }
797 
798  dstBeing->setStatusEffectOpitons(option,
799  opt1,
800  opt2,
801  opt3);
802 }
803 
805 {
806  if (actorManager == nullptr)
807  return;
808 
809  // need get type from id
811  if (msg.getVersion() >= 20091103)
812  {
813  msg.readInt16("len");
814  type = static_cast<BeingTypeT>(
815  msg.readUInt8("object type"));
816  }
817 
818  // Information about a being in range
819  const BeingId id = msg.readBeingId("being id");
820  if (msg.getVersion() >= 20131223)
821  {
822  msg.readBeingId("char id");
823  }
825  const BeingId spawnId = id;
826  int16_t speed = msg.readInt16("speed");
827  const uint32_t opt1 = msg.readInt16("opt1");
828  // probably wrong effect usage
829  const uint32_t opt2 = msg.readInt16("opt2");
830  uint32_t option;
831  if (msg.getVersion() >= 20080102)
832  option = msg.readInt32("option");
833  else
834  option = msg.readInt16("option");
835  const int16_t job = msg.readInt16("class");
836 
837  Being *dstBeing = actorManager->findBeing(id);
838 
839  if ((dstBeing != nullptr) && dstBeing->getType() == ActorType::Monster
840  && !dstBeing->isAlive())
841  {
842  actorManager->destroy(dstBeing);
843  actorManager->erase(dstBeing);
844  dstBeing = nullptr;
845  }
846 
847  if (dstBeing == nullptr)
848  {
849  if (actorManager->isBlocked(id) == true)
850  return;
851 
852  dstBeing = createBeing2(msg, id, job, type);
853  if (dstBeing == nullptr)
854  return;
855  }
856  else
857  {
858  // undeleting marked for deletion being
859  if (dstBeing->getType() == ActorType::Npc)
860  actorManager->undelete(dstBeing);
861  }
862 
863  if (dstBeing->getType() == ActorType::Player)
864  dstBeing->setMoveTime();
865 
866  if (spawnId != BeingId_zero)
867  dstBeing->setAction(BeingAction::SPAWN, 0);
868 
869  // Prevent division by 0 when calculating frame
870  if (speed == 0)
871  speed = 150;
872 
873  dstBeing->setWalkSpeed(speed);
874  dstBeing->setSubtype(fromInt(job, BeingTypeId), 0);
875  if (dstBeing->getType() == ActorType::Monster && (localPlayer != nullptr))
876  localPlayer->checkNewName(dstBeing);
877 
878  const int hairStyle = msg.readInt16("hair style");
879  uint32_t weapon;
880  if (msg.getVersion() >= 7)
881  weapon = CAST_U32(msg.readInt32("weapon"));
882  else
883  weapon = CAST_U32(msg.readInt16("weapon"));
884  const uint16_t headBottom = msg.readInt16("head bottom");
885  if (msg.getVersion() < 7)
886  msg.readInt16("shield");
887  const uint16_t headTop = msg.readInt16("head top");
888  const uint16_t headMid = msg.readInt16("head mid");
889  const ItemColor hairColor = fromInt(
890  msg.readInt16("hair color"), ItemColor);
891  const uint16_t shoes = msg.readInt16("shoes or clothes color?");
892  const uint16_t gloves = msg.readInt16("head dir / gloves");
893  // may be use robe as gloves?
894  if (msg.getVersion() >= 20101124)
895  msg.readInt16("robe");
896  msg.readInt32("guild id");
897  msg.readInt16("guild emblem");
898  dstBeing->setManner(msg.readInt16("manner"));
899  uint32_t opt3;
900  if (msg.getVersion() >= 7)
901  opt3 = msg.readInt32("opt3");
902  else
903  opt3 = msg.readInt16("opt3");
904 
905  dstBeing->setKarma(msg.readUInt8("karma"));
906  const uint8_t gender = CAST_U8(msg.readUInt8("gender") & 3);
907 
908  setBasicFields(dstBeing,
909  gender,
910  hairStyle,
911  hairColor,
912  weapon,
913  headBottom,
914  headMid,
915  headTop,
916  shoes,
917  gloves,
918  true);
919 
920  uint8_t dir;
921  uint16_t x, y;
922  msg.readCoordinates(x, y, dir, "position");
923  msg.readInt8("xs");
924  msg.readInt8("ys");
925  dstBeing->setTileCoords(x, y);
926 
927  if (job == 45 && (socialWindow != nullptr) && (outfitWindow != nullptr))
928  {
929  const int num = socialWindow->getPortalIndex(x, y);
930  if (num >= 0)
931  {
933  OutfitWindow::keyName(num)));
934  }
935  else
936  {
937  dstBeing->setName("");
938  }
939  }
940 
941  dstBeing->setDirection(dir);
942 
943  const int level = CAST_S32(msg.readInt16("level"));
944  if (level != 0)
945  dstBeing->setLevel(level);
946  if (msg.getVersion() >= 20080102)
947  msg.readInt16("font");
948  if (msg.getVersion() >= 20120221)
949  {
950  const int maxHP = msg.readInt32("max hp");
951  const int hp = msg.readInt32("hp");
952  dstBeing->setMaxHP(maxHP);
953  dstBeing->setHP(hp);
954  msg.readInt8("is boss");
955  }
956  if (serverVersion == 0 ||
957  serverVersion >= 16)
958  {
959  if (msg.getVersion() >= 20150513)
960  {
961  msg.readInt16("body2");
962  }
963  if (msg.getVersion() >= 20131223)
964  {
965  msg.readString(24, "name");
966  }
967  }
968  else
969  {
970  if (msg.getVersion() >= 20150513)
971  {
972  msg.readInt16("body2");
973  msg.readString(24, "name");
974  }
975  }
976 
977  dstBeing->setStatusEffectOpitons(option,
978  opt1,
979  opt2,
980  opt3);
981 }
982 
984 {
985  const int16_t type = msg.readInt16("type");
986  const int flags = msg.readInt32("flags");
987  if (type == 0x28)
988  {
989  // +++ need get other flags from here
990  MapTypeProperty2 props;
991  props.data = CAST_U32(flags);
992  const Game *const game = Game::instance();
993  if (game == nullptr)
994  return;
995  Map *const map = game->getCurrentMap();
996  if (map == nullptr)
997  return;
998  map->setPvpMode(props.bits.party | (props.bits.guild * 2));
999  }
1000 }
1001 
1003 {
1004  const int16_t type = msg.readInt16("type");
1005  if (type == 19)
1007  else
1009 }
1010 
1012 {
1013  const BeingId srcId = msg.readBeingId("src id");
1014  const BeingId dstId = msg.readBeingId("dst id");
1015  const int dstX = msg.readInt16("dst x");
1016  const int dstY = msg.readInt16("dst y");
1017  const int skillId = msg.readInt16("skill id");
1018  msg.readInt32("property"); // can be used to trigger effect
1019  const int castTime = msg.readInt32("cast time");
1020  if (msg.getVersion() >= 20091124)
1021  msg.readInt8("dispossable");
1022 
1024  srcId, dstId,
1025  dstX, dstY,
1026  skillId,
1027  1,
1028  0,
1030  castTime);
1031 }
1032 
1034 {
1035  msg.readInt16("len"); // for now unused
1036  const BeingId srcId = msg.readBeingId("src id");
1037  const BeingId dstId = msg.readBeingId("dst id");
1038  const int dstX = msg.readInt16("dst x");
1039  const int dstY = msg.readInt16("dst y");
1040  const int skillId = msg.readInt16("skill id");
1041  const int skillLevel = msg.readInt16("skill level");
1042  msg.readInt32("property"); // can be used to trigger effect
1043  const int castTime = msg.readInt32("cast time");
1044  const int range = msg.readInt32("skill range");
1045  const SkillType2::SkillType2 inf2 =
1046  static_cast<SkillType2::SkillType2>(msg.readInt32("inf2"));
1047 
1049  srcId, dstId,
1050  dstX, dstY,
1051  skillId,
1052  skillLevel,
1053  range,
1054  inf2,
1055  castTime);
1056 }
1057 
1059  const BeingId srcId,
1060  const BeingId dstId,
1061  const int dstX,
1062  const int dstY,
1063  const int skillId,
1064  const int skillLevel,
1065  const int range,
1066  const SkillType2::SkillType2 inf2,
1067  const int castTime)
1068 {
1069  if (effectManager == nullptr)
1070  return;
1071 
1072  if (srcId == BeingId_zero)
1073  {
1075  return;
1076  }
1077  Being *const srcBeing = actorManager->findBeing(srcId);
1078  if (dstId != BeingId_zero)
1079  { // being to being
1080  Being *const dstBeing = actorManager->findBeing(dstId);
1081  if (srcBeing != nullptr)
1082  {
1083  srcBeing->handleSkillCasting(dstBeing, skillId, skillLevel);
1084  if (dstBeing != nullptr)
1085  {
1086  srcBeing->addCast(dstBeing->getTileX(),
1087  dstBeing->getTileY(),
1088  skillId,
1089  skillLevel,
1090  range,
1091  castTime / MILLISECONDS_IN_A_TICK);
1092  }
1093  }
1094  }
1095  else if (dstX != 0 || dstY != 0)
1096  { // being to position
1097  if (srcBeing != nullptr)
1098  srcBeing->setAction(BeingAction::CAST, skillId);
1100  skillLevel,
1101  dstX, dstY,
1102  castTime);
1103  if (srcBeing != nullptr)
1104  {
1105  srcBeing->addCast(dstX, dstY,
1106  skillId,
1107  skillLevel,
1108  range,
1109  castTime / MILLISECONDS_IN_A_TICK);
1110  }
1111  }
1112  if ((localPlayer != nullptr) &&
1113  srcBeing == localPlayer &&
1114  (inf2 & SkillType2::FreeCastAny) == 0)
1115  {
1117  }
1118 }
1119 
1121 {
1122  BLOCK_START("BeingRecv::processBeingStatusChange")
1123  if (actorManager == nullptr)
1124  {
1125  BLOCK_END("BeingRecv::processBeingStatusChange")
1126  return;
1127  }
1128 
1129  // Status change
1130  const uint16_t status = msg.readInt16("status");
1131  const BeingId id = msg.readBeingId("being id");
1132  const Enable flag = fromBool(
1133  msg.readUInt8("flag: 0: stop, 1: start"), Enable);
1134  if (msg.getVersion() >= 20120618)
1135  msg.readInt32("total");
1136  if (msg.getVersion() >= 20090121)
1137  {
1138  msg.readInt32("left");
1139  msg.readInt32("val1");
1140  msg.readInt32("val2");
1141  msg.readInt32("val3");
1142  }
1143 
1144  const IsStart start = msg.getVersion() == 20090121 ?
1146 
1147  Being *const dstBeing = actorManager->findBeing(id);
1148  if (dstBeing != nullptr)
1149  dstBeing->setStatusEffect(status, flag, start);
1150  BLOCK_END("BeingRecv::processBeingStatusChange")
1151 }
1152 
1154 {
1155  BLOCK_START("BeingRecv::processBeingMove2")
1156  if (actorManager == nullptr)
1157  {
1158  BLOCK_END("BeingRecv::processBeingMove2")
1159  return;
1160  }
1161 
1162  /*
1163  * A simplified movement packet, used by the
1164  * later versions of eAthena for both mobs and
1165  * players
1166  */
1167  Being *const dstBeing = actorManager->findBeing(
1168  msg.readBeingId("being id"));
1169 
1170  uint16_t srcX, srcY, dstX, dstY;
1171  msg.readCoordinatePair(srcX, srcY, dstX, dstY, "move path");
1172  msg.readUInt8("(sx<<4) | (sy&0x0f)");
1173  msg.readInt32("tick");
1174 
1175  /*
1176  * This packet doesn't have enough info to actually
1177  * create a new being, so if the being isn't found,
1178  * we'll just pretend the packet didn't happen
1179  */
1180 
1181  if (dstBeing == nullptr)
1182  {
1183  BLOCK_END("BeingRecv::processBeingMove2")
1184  return;
1185  }
1186 
1187  dstBeing->setTileCoords(srcX, srcY);
1188  if (localPlayer != nullptr)
1189  localPlayer->followMoveTo(dstBeing, srcX, srcY, dstX, dstY);
1190  if (serverFeatures->haveMove3())
1191  dstBeing->setCachedDestination(dstX, dstY);
1192  else
1193  dstBeing->setDestination(dstX, dstY);
1194  if (dstBeing->getType() == ActorType::Player)
1195  dstBeing->setMoveTime();
1196  BLOCK_END("BeingRecv::processBeingMove2")
1197 }
1198 
1200 {
1201  BLOCK_START("BeingRecv::processBeingAction2")
1202  if (actorManager == nullptr)
1203  {
1204  BLOCK_END("BeingRecv::processBeingAction2")
1205  return;
1206  }
1207 
1208  Being *const srcBeing = actorManager->findBeing(
1209  msg.readBeingId("src being id"));
1210  Being *const dstBeing = actorManager->findBeing(
1211  msg.readBeingId("dst being id"));
1212 
1213  msg.readInt32("tick");
1214  const int srcSpeed = msg.readInt32("src speed");
1215  msg.readInt32("dst speed");
1216  int param1;
1217  if (msg.getVersion() >= 20071113)
1218  param1 = msg.readInt32("damage");
1219  else
1220  param1 = msg.readInt16("damage");
1221  if (msg.getVersion() >= 20131223)
1222  msg.readUInt8("is sp damaged");
1223  msg.readInt16("count");
1224  const AttackTypeT type = static_cast<AttackTypeT>(
1225  msg.readUInt8("action"));
1226  if (msg.getVersion() >= 20071113)
1227  msg.readInt32("left damage");
1228  else
1229  msg.readInt16("left damage");
1230 
1231  switch (type)
1232  {
1233  case AttackType::HIT: // Damage
1234  case AttackType::CRITICAL: // Critical Damage
1235  case AttackType::MULTI: // Critical Damage
1237  case AttackType::REFLECT: // Reflected Damage
1238  case AttackType::FLEE: // Lucky Dodge
1239  case AttackType::SPLASH:
1240  case AttackType::SKILL:
1241  case AttackType::REPEATE:
1242  if (srcBeing != nullptr)
1243  {
1244  if (srcSpeed != 0 && srcBeing->getType() == ActorType::Player)
1245  srcBeing->setAttackDelay(srcSpeed);
1246  // attackid=1, type
1247  srcBeing->handleAttack(dstBeing, param1, 1);
1248  if (srcBeing->getType() == ActorType::Player)
1249  srcBeing->setAttackTime();
1250  }
1251  if (dstBeing != nullptr)
1252  {
1253  // level not present, using 1
1254  dstBeing->takeDamage(srcBeing, param1,
1255  static_cast<AttackTypeT>(type), 1, 1);
1256  }
1257  break;
1258 
1259  case AttackType::PICKUP:
1260  break;
1261 
1263  break;
1264 
1265  case AttackType::SIT:
1266  if (srcBeing != nullptr)
1267  {
1268  srcBeing->setAction(BeingAction::SIT, 0);
1269  if (srcBeing->getType() == ActorType::Player)
1270  {
1271  srcBeing->setMoveTime();
1272  if (localPlayer != nullptr)
1274  }
1275  }
1276  break;
1277 
1278  case AttackType::STAND:
1279  if (srcBeing != nullptr)
1280  {
1281  srcBeing->setAction(BeingAction::STAND, 0);
1282  if (srcBeing->getType() == ActorType::Player)
1283  {
1284  srcBeing->setMoveTime();
1285  if (localPlayer != nullptr)
1286  {
1287  localPlayer->imitateAction(srcBeing,
1289  }
1290  }
1291  }
1292  break;
1293  default:
1294  case AttackType::MISS:
1295  case AttackType::SKILLMISS:
1297  break;
1298  }
1299  BLOCK_END("BeingRecv::processBeingAction2")
1300 }
1301 
1303 {
1304  Being *const dstBeing = actorManager->findBeing(
1305  msg.readBeingId("being id"));
1306  int hp;
1307  int maxHP;
1308  if (msg.getVersion() >= 20100126)
1309  {
1310  hp = msg.readInt32("hp");
1311  maxHP = msg.readInt32("max hp");
1312  }
1313  else
1314  {
1315  hp = msg.readInt16("hp");
1316  maxHP = msg.readInt16("max hp");
1317  }
1318  if (dstBeing != nullptr)
1319  {
1320  dstBeing->setHP(hp);
1321  dstBeing->setMaxHP(maxHP);
1322  }
1323 }
1324 
1326 {
1327  Being *const dstBeing = actorManager->findBeing(
1328  msg.readBeingId("monster id"));
1329  const int hp = msg.readInt32("hp");
1330  const int maxHP = msg.readInt32("max hp");
1331  if (dstBeing != nullptr)
1332  {
1333  dstBeing->setHP(hp);
1334  dstBeing->setMaxHP(maxHP);
1335  }
1336 }
1337 
1339 {
1340  const int id = msg.readInt16("skill id");
1341  msg.readInt16("inf");
1342  msg.readInt16("unused");
1343  const int level = msg.readInt16("skill level");
1344  msg.readInt16("sp");
1345  msg.readInt16("range");
1346  msg.readString(24, "skill name");
1347  msg.readInt8("unused");
1348 
1349  if (localPlayer != nullptr)
1350  {
1351  localPlayer->handleSkill(localPlayer, 0, id, level);
1353  }
1354 }
1355 
1357 {
1359  // +++ here need window with rank tables.
1360  msg.readInt16("rank type");
1361  for (int f = 0; f < 10; f ++)
1362  msg.readString(24, "name");
1363  for (int f = 0; f < 10; f ++)
1364  msg.readInt32("points");
1365  msg.readInt32("my points");
1366 }
1367 
1369 {
1371  // +++ here need window with rank tables.
1372  for (int f = 0; f < 10; f ++)
1373  msg.readString(24, "name");
1374  for (int f = 0; f < 10; f ++)
1375  msg.readInt32("points");
1376 }
1377 
1379 {
1381  // +++ here need window with rank tables.
1382  for (int f = 0; f < 10; f ++)
1383  msg.readString(24, "name");
1384  for (int f = 0; f < 10; f ++)
1385  msg.readInt32("points");
1386 }
1387 
1389 {
1391  // +++ here need window with rank tables.
1392  for (int f = 0; f < 10; f ++)
1393  msg.readString(24, "name");
1394  for (int f = 0; f < 10; f ++)
1395  msg.readInt32("points");
1396 }
1397 
1399 {
1401  // +++ here need window with rank tables.
1402  for (int f = 0; f < 10; f ++)
1403  msg.readString(24, "name");
1404  for (int f = 0; f < 10; f ++)
1405  msg.readInt32("points");
1406 }
1407 
1409 {
1410  BLOCK_START("BeingRecv::processBeingChangeDirection")
1411  if (actorManager == nullptr)
1412  {
1413  BLOCK_END("BeingRecv::processBeingChangeDirection")
1414  return;
1415  }
1416 
1417  Being *const dstBeing = actorManager->findBeing(
1418  msg.readBeingId("being id"));
1419 
1420  msg.readInt16("head direction");
1421 
1422  const uint8_t dir = Net::MessageIn::fromServerDirection(
1423  CAST_U8(msg.readUInt8("player direction") & 0x0FU));
1424 
1425  if (dstBeing == nullptr)
1426  {
1427  BLOCK_END("BeingRecv::processBeingChangeDirection")
1428  return;
1429  }
1430 
1431  dstBeing->setDirection(dir);
1432  if (localPlayer != nullptr)
1433  localPlayer->imitateDirection(dstBeing, dir);
1434  BLOCK_END("BeingRecv::processBeingChangeDirection")
1435 }
1436 
1438 {
1439  if ((effectManager == nullptr) || (actorManager == nullptr))
1440  return;
1441 
1442  const BeingId id = msg.readBeingId("being id");
1443  Being *const being = actorManager->findBeing(id);
1444  if (being == nullptr)
1445  return;
1446 
1447  const int effectType = msg.readInt32("effect type");
1448 
1450  effectManager->trigger(effectType, being, 0);
1451 
1452  // +++ need dehard code effectType == 3
1453  if (effectType == 3 && being->getType() == ActorType::Player
1454  && (socialWindow != nullptr))
1455  { // reset received damage
1456  socialWindow->resetDamage(being->getName());
1457  }
1458 }
1459 
1461 {
1463  // +++ need somhow show this effects.
1464  // type is not same with self/misc effect.
1465  msg.readBeingId("account id");
1466  msg.readInt32("effect type");
1467  msg.readInt32("num"); // effect variable
1468 }
1469 
1471 {
1473  // +++ need play this effect.
1474  msg.readString(24, "sound effect name");
1475  msg.readUInt8("type");
1476  msg.readInt32("unused");
1477  msg.readInt32("source being id");
1478 }
1479 
1481 {
1483  msg.readInt16("skill id");
1484  msg.readInt32("src id");
1485  msg.readInt16("val");
1486  msg.readInt16("x");
1487  msg.readInt16("y");
1488  msg.readInt32("tick");
1489 }
1490 
1492 {
1493  if (msg.getVersion() >= 20110718)
1494  msg.readInt16("len");
1495  const BeingId id = msg.readBeingId("skill unit id");
1496  const BeingId creatorId = msg.readBeingId("creator accound id");
1497  const int x = msg.readInt16("x");
1498  const int y = msg.readInt16("y");
1499  int job = 0;
1500  if (msg.getVersion() >= 20121212)
1501  job = msg.readInt32("job");
1502  if (msg.getVersion() >= 20110718)
1503  msg.readUInt8("radius");
1504  msg.readUInt8("visible");
1505  int level = 0;
1506  if (msg.getVersion() >= 20130731)
1507  level = msg.readUInt8("level");
1508  Being *const dstBeing = createBeing2(msg,
1509  id,
1510  job,
1512  if (dstBeing == nullptr)
1513  return;
1514  dstBeing->setAction(BeingAction::STAND, 0);
1515  dstBeing->setTileCoords(x, y);
1516  dstBeing->setLevel(level);
1517  dstBeing->setCreatorId(creatorId);
1518 }
1519 
1521 {
1522  BLOCK_START("BeingRecv::processPlayerStop")
1523  if (actorManager == nullptr)
1524  {
1525  BLOCK_END("BeingRecv::processPlayerStop")
1526  return;
1527  }
1528 
1529  // Change in players' flags
1530  const BeingId id = msg.readBeingId("account id");
1531  Being *const dstBeing = actorManager->findBeing(id);
1532  if (dstBeing == nullptr)
1533  {
1534  msg.readInt16("opt1");
1535  msg.readInt16("opt2");
1536  if (msg.getVersion() >= 7)
1537  msg.readInt32("option");
1538  else
1539  msg.readInt16("option");
1540  msg.readUInt8("karma");
1541  return;
1542  }
1543 
1544  const uint32_t opt1 = msg.readInt16("opt1");
1545  const uint32_t opt2 = msg.readInt16("opt2");
1546  uint32_t option;
1547  if (msg.getVersion() >= 7)
1548  option = msg.readInt32("option");
1549  else
1550  option = msg.readInt16("option");
1551  dstBeing->setKarma(msg.readUInt8("karma"));
1552 
1553  dstBeing->setStatusEffectOpitons(option,
1554  opt1,
1555  opt2);
1556  BLOCK_END("BeingRecv::processPlayerStop")
1557 }
1558 
1560 {
1561  if (actorManager == nullptr)
1562  return;
1563 
1564  // look like this function unused on server
1565 
1566  const BeingId id = msg.readBeingId("account id");
1567  Being *const dstBeing = actorManager->findBeing(id);
1568  if (dstBeing == nullptr)
1569  return;
1570 
1571  const uint32_t option = msg.readInt32("option");
1572  dstBeing->setLevel(msg.readInt32("level"));
1573  msg.readInt32("showEFST");
1574  dstBeing->setStatusEffectOpiton0(option);
1575 }
1576 
1578 {
1579  BLOCK_START("BeingRecv::processBeingResurrect")
1580  if (actorManager == nullptr ||
1581  localPlayer == nullptr)
1582  {
1583  BLOCK_END("BeingRecv::processBeingResurrect")
1584  return;
1585  }
1586 
1587  // A being changed mortality status
1588 
1589  const BeingId id = msg.readBeingId("being id");
1590  msg.readInt16("unused");
1591  Being *const dstBeing = actorManager->findBeing(id);
1592  if (dstBeing == nullptr)
1593  {
1594  DEBUGLOGSTR("insible player?");
1595  BLOCK_END("BeingRecv::processBeingResurrect")
1596  return;
1597  }
1598 
1599  // If this is player's current target, clear it.
1600  if (dstBeing == localPlayer->getTarget())
1601  localPlayer->stopAttack(false);
1602  if (dstBeing == localPlayer &&
1603  deathNotice != nullptr)
1604  {
1605  deathNotice->scheduleDelete();
1606  deathNotice = nullptr;
1607  }
1608 
1609  dstBeing->setAction(BeingAction::STAND, 0);
1610  BLOCK_END("BeingRecv::processBeingResurrect")
1611 }
1612 
1614 {
1615  BLOCK_START("BeingRecv::processPlayerGuilPartyInfo")
1616  if (actorManager == nullptr)
1617  {
1618  BLOCK_END("BeingRecv::processPlayerGuilPartyInfo")
1619  return;
1620  }
1621 
1622  const BeingId beingId = msg.readBeingId("being id");
1623  const std::string name = msg.readString(24, "char name");
1624  actorManager->updateNameId(name, beingId);
1625  Being *const dstBeing = actorManager->findBeing(beingId);
1626  if (dstBeing != nullptr)
1627  {
1628  if (beingId == localPlayer->getId())
1629  {
1631  }
1632  dstBeing->setName(name);
1633  dstBeing->setPartyName(msg.readString(24, "party name"));
1634  dstBeing->setGuildName(msg.readString(24, "guild name"));
1635  dstBeing->setGuildPos(msg.readString(24, "guild pos"));
1636  dstBeing->addToCache();
1637  }
1638  else
1639  {
1640  msg.readString(24, "party name");
1641  msg.readString(24, "guild name");
1642  msg.readString(24, "guild pos");
1643  }
1644  BLOCK_END("BeingRecv::processPlayerGuilPartyInfo")
1645 }
1646 
1648 {
1649  const BeingId id = msg.readBeingId("skill unit id");
1650  if (actorManager == nullptr)
1651  return;
1652  Being *const dstBeing = actorManager->findBeing(id);
1653  if (dstBeing == nullptr)
1654  return;
1655  actorManager->destroy(dstBeing);
1656 }
1657 
1659 {
1660  uint16_t x, y;
1661  uint8_t dir;
1662  if (msg.getVersion() < 20071106)
1663  {
1664  msg.readBeingId("npc id");
1665  msg.skip(8, "unused");
1666  msg.readInt16("class?"); // 111
1667  msg.skip(30, "unused");
1668  msg.readCoordinates(x, y, dir, "position");
1669  msg.readUInt8("sx");
1670  msg.readUInt8("sy");
1671  msg.skip(3, "unused");
1672  return;
1673  }
1674  const BeingTypeT type = static_cast<BeingTypeT>(
1675  msg.readUInt8("object type"));
1676  const BeingId id = msg.readBeingId("npc id");
1677  msg.skip(8, "unused");
1678  const uint16_t job = msg.readInt16("class?"); // 111
1679  msg.skip(30, "unused");
1680  msg.readCoordinates(x, y, dir, "position");
1681  msg.readUInt8("sx");
1682  msg.readUInt8("sy");
1683  msg.skip(3, "unused");
1684 
1685  Being *const dstBeing = createBeing2(msg, id, job, type);
1686  if (dstBeing == nullptr)
1687  return;
1688  dstBeing->setSubtype(fromInt(job, BeingTypeId), 0);
1689  dstBeing->setTileCoords(x, y);
1690  dstBeing->setDirection(dir);
1691 }
1692 
1694 {
1695  const BeingId id = msg.readBeingId("account id");
1696  const int type = msg.readInt16("type");
1697  const int value = msg.readInt32("value");
1698 
1699  Being *const dstBeing = actorManager->findBeing(id);
1700  if (dstBeing == nullptr)
1701  return;
1702 
1703  if (type != Sp::MANNER)
1704  {
1706  return;
1707  }
1708  dstBeing->setManner(value);
1709 }
1710 
1712 {
1713  BLOCK_START("BeingRecv::processBeingSelfEffect")
1714  if ((effectManager == nullptr) || (actorManager == nullptr))
1715  {
1716  BLOCK_END("BeingRecv::processBeingSelfEffect")
1717  return;
1718  }
1719 
1720  const BeingId id = msg.readBeingId("being id");
1721  Being *const being = actorManager->findBeing(id);
1722  if (being == nullptr)
1723  {
1724  DEBUGLOGSTR("insible player?");
1725  msg.readInt32("effect type");
1726  BLOCK_END("BeingRecv::processBeingSelfEffect")
1727  return;
1728  }
1729 
1730  const int effectType = msg.readInt32("effect type");
1732  effectManager->trigger(effectType, being, 0);
1733 
1734  BLOCK_END("BeingRecv::processBeingSelfEffect")
1735 }
1736 
1738 {
1739  const int len = msg.readInt16("len");
1740  if (len < 12)
1741  return;
1742  Being *const dstBeing = actorManager->findBeing(
1743  msg.readBeingId("monster id"));
1744  const int attackRange = msg.readInt32("range");
1745  if (dstBeing != nullptr)
1746  dstBeing->setAttackRange(attackRange);
1747 }
1748 
1750 {
1751  const int len = msg.readInt16("len");
1752  if (len < 14)
1753  return;
1754 
1755  Being *const dstBeing = actorManager->findBeing(
1756  msg.readBeingId("player id"));
1757  const int groupId = msg.readInt32("group id");
1758  uint16_t mount = 0;
1759  mount = msg.readInt16("mount");
1760  int language = -1;
1761  if (serverVersion >= 17 && len > 14)
1762  language = msg.readInt16("language");
1763  if (dstBeing != nullptr)
1764  {
1765  if (serverVersion <= 17 ||
1766  dstBeing != localPlayer)
1767  {
1768  dstBeing->setGroupId(groupId);
1769  if (groupId != 0)
1770  dstBeing->setGM(true);
1771  else
1772  dstBeing->setGM(false);
1773  }
1774  dstBeing->setHorse(mount);
1775  dstBeing->setLanguageId(language);
1776  if (dstBeing == localPlayer)
1778  }
1779 }
1780 
1782 {
1784 
1785  msg.readInt16("class");
1786  msg.readInt16("level");
1787  msg.readInt16("size");
1788  msg.readInt32("hp");
1789  msg.readInt16("def");
1790  msg.readInt16("race");
1791  msg.readInt16("mdef");
1792  msg.readInt16("ele");
1793 }
1794 
1796 {
1798 
1799  msg.readBeingId("being id");
1800  msg.readUInt8("type");
1801  msg.readInt32("class");
1802 }
1803 
1805 {
1806  Being *const dstBeing = actorManager->findBeing(
1807  msg.readBeingId("being id"));
1808  const int balls = msg.readInt16("spirits amount");
1809  if (dstBeing != nullptr)
1810  dstBeing->setSpiritBalls(balls);
1811 }
1812 
1814 {
1816 
1817  msg.readInt32("src being id");
1818  msg.readInt32("dst being id");
1819  msg.readInt32("flag");
1820 }
1821 
1823 {
1825 
1826  msg.readBeingId("being id");
1827  msg.readInt32("wait");
1828 }
1829 
1831 {
1833 
1834  msg.readBeingId("being id");
1835 }
1836 
1838 {
1839  Being *const dstBeing = actorManager->findBeing(
1840  msg.readBeingId("being id"));
1841  const int x = msg.readInt16("x");
1842  const int y = msg.readInt16("y");
1843  if (dstBeing == nullptr)
1844  return;
1845  if (localPlayer == dstBeing)
1846  {
1847  localPlayer->stopAttack(false);
1849  if (viewport != nullptr)
1851  }
1852 
1853  dstBeing->setAction(BeingAction::STAND, 0);
1854  dstBeing->setTileCoords(x, y);
1855 }
1856 
1858 {
1860 
1861  msg.readString(24, "map name");
1862  msg.readInt32("monster id");
1863  msg.readUInt8("start");
1864  msg.readUInt8("result");
1865 }
1866 
1868 {
1870 
1871  msg.readUInt8("which");
1872 }
1873 
1875 {
1877 
1878  msg.readUInt8("info type");
1879  msg.readInt32("x");
1880  msg.readInt32("y");
1881  msg.readInt16("min hours");
1882  msg.readInt16("min minutes");
1883  msg.readInt16("max hours");
1884  msg.readInt16("max minutes");
1885  msg.readString(24, "monster name"); // really can be used 51 byte?
1886 }
1887 
1889 {
1891 
1892  msg.readBeingId("account id");
1893  msg.readInt16("font");
1894 }
1895 
1897 {
1899 
1900  msg.readBeingId("account id");
1901  msg.readInt16("shields");
1902  msg.readInt16("unused");
1903 }
1904 
1906 {
1908 
1909  msg.readBeingId("account id");
1910  msg.readInt16("charm type");
1911  msg.readInt16("charm count");
1912 }
1913 
1915 {
1917 
1918  const int count = (msg.readInt16("len") - 45) / 31;
1919  msg.readString(24, "name");
1920  msg.readInt16("job");
1921  msg.readInt16("head");
1922  msg.readInt16("accessory");
1923  msg.readInt16("accessory2");
1924  msg.readInt16("accessory3");
1925  if (msg.getVersion() >= 20101124)
1926  msg.readInt16("robe");
1927  msg.readInt16("hair color");
1928  msg.readInt16("body color");
1929  msg.readUInt8("gender");
1930  for (int f = 0; f < count; f ++)
1931  {
1932  msg.readInt16("index");
1933  msg.readInt16("item id");
1934  msg.readUInt8("item type");
1935  msg.readInt32("location");
1936  msg.readInt32("wear state");
1937  msg.readInt8("refine");
1938  for (int d = 0; d < maxCards; d ++)
1939  msg.readUInt16("card");
1940  msg.readInt32("hire expire date (?)");
1941  msg.readInt16("equip type");
1942  msg.readInt16("item sprite number");
1943  msg.readUInt8("flags");
1944  }
1945 }
1946 
1948 {
1949  BLOCK_START("BeingRecv::processPvpSet")
1950  const BeingId id = msg.readBeingId("being id");
1951  const int rank = msg.readInt32("rank");
1952  msg.readInt32("num");
1953  if (actorManager != nullptr)
1954  {
1955  Being *const dstBeing = actorManager->findBeing(id);
1956  if (dstBeing != nullptr)
1957  dstBeing->setPvpRank(rank);
1958  }
1959  BLOCK_END("BeingRecv::processPvpSet")
1960 }
1961 
1963 {
1964  BLOCK_START("BeingRecv::processNameResponse2")
1965  if ((actorManager == nullptr) || (localPlayer == nullptr))
1966  {
1967  BLOCK_END("BeingRecv::processNameResponse2")
1968  return;
1969  }
1970 
1971  const int len = msg.readInt16("len");
1972  const BeingId beingId = msg.readBeingId("account id");
1973  const std::string str = msg.readString(len - 8, "name");
1974  actorManager->updateNameId(str, beingId);
1975  Being *const dstBeing = actorManager->findBeing(beingId);
1976  if (dstBeing != nullptr)
1977  {
1978  if (beingId == localPlayer->getId())
1979  {
1981  }
1982  else
1983  {
1984  dstBeing->setName(str);
1985  dstBeing->updateGuild();
1986  dstBeing->addToCache();
1987 
1988  if (dstBeing->getType() == ActorType::Player)
1989  dstBeing->updateColors();
1990 
1991  if (localPlayer != nullptr)
1992  {
1993  const Party *const party = localPlayer->getParty();
1994  if (party != nullptr && party->isMember(dstBeing->getId()))
1995  {
1996  PartyMember *const member = party->getMember(
1997  dstBeing->getId());
1998 
1999  if (member != nullptr)
2000  member->setName(dstBeing->getName());
2001  }
2002  localPlayer->checkNewName(dstBeing);
2003  }
2004  }
2005  }
2006  BLOCK_END("BeingRecv::processNameResponse2")
2007 }
2008 
2010  const BeingId id,
2011  const int32_t job,
2012  const BeingTypeT beingType)
2013 {
2014  if (actorManager == nullptr)
2015  return nullptr;
2016 
2018  switch (beingType)
2019  {
2020  case BeingType::PC:
2021  type = ActorType::Player;
2022  break;
2023  case BeingType::NPC:
2024  case BeingType::NPC_EVENT:
2025  type = ActorType::Npc;
2026  break;
2027  case BeingType::MONSTER:
2028  type = ActorType::Monster;
2029  break;
2030  case BeingType::MERSOL:
2031  type = ActorType::Mercenary;
2032  break;
2033  case BeingType::PET:
2034  type = ActorType::Pet;
2035  break;
2036  case BeingType::HOMUN:
2037  type = ActorType::Homunculus;
2038  break;
2039  case BeingType::SKILL:
2040  type = ActorType::SkillUnit;
2041  break;
2042  case BeingType::ELEMENTAL:
2043  type = ActorType::Elemental;
2044  break;
2045  case BeingType::ITEM:
2046  logger->log("not supported object type: %d, job: %d",
2047  CAST_S32(beingType), CAST_S32(job));
2048  break;
2049  case BeingType::CHAT:
2050  default:
2051  UNIMPLEMENTEDPACKETFIELD(CAST_S32(beingType));
2052  type = ActorType::Monster;
2053  logger->log("not supported object type: %d, job: %d",
2054  CAST_S32(beingType), CAST_S32(job));
2055  break;
2056  }
2057  if (job == 45 && beingType == BeingType::NPC_EVENT)
2058  type = ActorType::Portal;
2059 
2060  Being *const being = actorManager->createBeing(
2061  id, type, fromInt(job, BeingTypeId));
2062  if (beingType == BeingType::MERSOL)
2063  {
2064  const MercenaryInfo *const info = PlayerInfo::getMercenary();
2065  if ((info != nullptr) && info->id == id)
2067  }
2068  else if (beingType == BeingType::PET)
2069  {
2070  if (PlayerInfo::getPetBeingId() == id)
2071  PlayerInfo::setPetBeing(being);
2072  }
2073  return being;
2074 }
2075 
2077 {
2078  msg.readInt32("id?");
2079 }
2080 
2082 {
2083  const int id = msg.readInt32("char id");
2084  if (actorManager == nullptr)
2085  {
2086  msg.readString(24, "name");
2087  return;
2088  }
2089  actorManager->addChar(id, msg.readString(24, "name"));
2090 }
2091 
2093 {
2094  const BeingId id = msg.readBeingId("graffiti id");
2095  const BeingId creatorId = msg.readBeingId("creator id");
2096  const int x = msg.readInt16("x");
2097  const int y = msg.readInt16("y");
2098  const int job = msg.readUInt8("job");
2099  msg.readUInt8("visible");
2100  msg.readUInt8("is content");
2101  const std::string text = msg.readString(80, "text");
2102 
2103  Being *const dstBeing = createBeing2(msg, id, job, BeingType::SKILL);
2104  if (dstBeing == nullptr)
2105  return;
2106 
2107  dstBeing->setAction(BeingAction::STAND, 0);
2108  dstBeing->setTileCoords(x, y);
2109  dstBeing->setShowName(true);
2110  dstBeing->setName(text);
2111  dstBeing->setCreatorId(creatorId);
2112 }
2113 
2115 {
2116  BLOCK_START("BeingRecv::processSkillDamage")
2117  if (actorManager == nullptr)
2118  {
2119  BLOCK_END("BeingRecv::processSkillDamage")
2120  return;
2121  }
2122 
2123  const int id = msg.readInt16("skill id");
2124  Being *const srcBeing = actorManager->findBeing(
2125  msg.readBeingId("src being id"));
2126  Being *const dstBeing = actorManager->findBeing(
2127  msg.readBeingId("dst being id"));
2128  msg.readInt32("tick");
2129  msg.readInt32("src speed");
2130  msg.readInt32("dst speed");
2131  int param1;
2132  if (msg.getVersion() >= 3)
2133  param1 = msg.readInt32("damage");
2134  else
2135  param1 = msg.readInt16("damage");
2136  const int level = msg.readInt16("skill level");
2137  msg.readInt16("div");
2138  msg.readUInt8("skill hit/type?");
2139  if (srcBeing != nullptr)
2140  srcBeing->handleSkill(dstBeing, param1, id, level);
2141  if (dstBeing != nullptr)
2142  dstBeing->takeDamage(srcBeing, param1, AttackType::SKILL, id, level);
2143  BLOCK_END("BeingRecv::processSkillDamage")
2144 }
2145 
2147 {
2149  // 0 position
2150  // 1 no position
2151  // 3 monster
2152  msg.readUInt8("navigate type");
2153  msg.readUInt8("transportation flag");
2154  msg.readUInt8("hide window");
2155  msg.readString(16, "map name");
2156  msg.readInt16("x");
2157  msg.readInt16("y");
2158  msg.readInt16("mob id");
2159 }
2160 
2162  Being *const being,
2163  const uint8_t type)
2164 {
2165  if (being == nullptr)
2166  return;
2167  switch (type)
2168  {
2169  case 0:
2170  being->setAction(BeingAction::STAND, 0);
2172  break;
2173 
2174  case 1:
2175  if (being->getCurrentAction() != BeingAction::DEAD)
2176  {
2177  being->setAction(BeingAction::DEAD, 0);
2178  being->recalcSpritesOrder();
2179  }
2180  break;
2181 
2182  case 2:
2183  being->setAction(BeingAction::SIT, 0);
2185  break;
2186 
2187  default:
2189  break;
2190  }
2191 }
2192 
2193 } // namespace EAthena
void processBeingFont(Net::MessageIn &msg)
Definition: beingrecv.cpp:1888
#define CAST_U32
Definition: cast.h:30
int getSpriteID(const int slot) const
Definition: being.cpp:4864
void processBeingAction2(Net::MessageIn &msg)
Definition: beingrecv.cpp:1199
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
static bool enabled
virtual unsigned char readUInt8(const char *const str)
Definition: messagein.cpp:74
uint16_t getLook() const
Definition: being.h:915
void processBeingSlide(Net::MessageIn &msg)
Definition: beingrecv.cpp:1837
const ItemInfo & get(const int id)
Definition: itemdb.cpp:814
int getTileY() const
Definition: being.h:173
#define CAST_U8
Definition: cast.h:26
void setShowName(const bool doShowName)
Definition: being.cpp:1164
void setPetBeing(Being *const being)
Definition: playerinfo.cpp:556
void setAttackRange(const int range)
Definition: being.h:836
BeingId mSpawnId
Definition: beingrecv.cpp:58
Definition: party.h:61
void setLanguageId(const int lang)
Definition: being.cpp:5525
void processSkillGroundNoDamage(Net::MessageIn &msg)
Definition: beingrecv.cpp:1480
volatile int tick_time
Definition: timer.cpp:52
void setDestination(const int dstX, const int dstY)
Definition: being.cpp:538
virtual BeingId readBeingId(const char *const str)=0
OutfitWindow * outfitWindow
void setPvpMode(const int mode)
Definition: map.cpp:1348
void setTileCoords(const int x, const int y)
Definition: being.cpp:4980
void processBeingSpecialEffectNum(Net::MessageIn &msg)
Definition: beingrecv.cpp:1460
#define fromInt(val, name)
Definition: intdefines.h:45
void updateColors()
Definition: being.cpp:2636
void setGuildName(const std::string &name)
Definition: being.cpp:1194
void processNavigateTo(Net::MessageIn &msg)
Definition: beingrecv.cpp:2146
BeingId getId() const
Definition: actorsprite.h:63
void setOtherTime()
Definition: being.h:711
void processBeingHp(Net::MessageIn &msg)
Definition: beingrecv.cpp:1302
void destroy(ActorSprite *const actor)
void processBossMapInfo(Net::MessageIn &msg)
Definition: beingrecv.cpp:1874
void setCachedDestination(const int dstX, const int dstY)
Definition: being.h:148
void setGuildPos(const std::string &pos)
Definition: being.cpp:1204
#define BLOCK_START(name)
Definition: perfomance.h:78
uint8_t calcDirection(const int dstX, const int dstY) const
Definition: being.cpp:1738
int BeingId
Definition: beingid.h:29
void processPkRanksList(Net::MessageIn &msg)
Definition: beingrecv.cpp:1398
virtual int16_t readInt16(const char *const str)=0
virtual void setGroupId(const int id)
Definition: being.h:1080
void processBeingChangeLookCards(Net::MessageIn &msg)
Definition: beingrecv.cpp:211
void processClassChange(Net::MessageIn &msg)
Definition: beingrecv.cpp:1795
void processGraffiti(Net::MessageIn &msg)
Definition: beingrecv.cpp:2092
void processBeingVisible(Net::MessageIn &msg)
Definition: beingrecv.cpp:410
virtual bool haveNpcGender() const =0
#define BLOCK_END(name)
Definition: perfomance.h:79
void setAttackDelay(const int n)
Definition: being.h:763
ActorType ::T ActorTypeT
Definition: actortype.h:42
Party * getParty() const
Definition: being.h:323
uint16_t ItemColor
Definition: itemcolor.h:29
bool msg(InputEvent &event)
Definition: chat.cpp:38
uint8_t getDirection() const
Definition: being.h:487
void processBeingMove(Net::MessageIn &msg)
Definition: beingrecv.cpp:603
void processBeingViewEquipment(Net::MessageIn &msg)
Definition: beingrecv.cpp:1914
void processGladiatorFeelRequest(Net::MessageIn &msg)
Definition: beingrecv.cpp:1867
void notify(const unsigned int message)
#define A_NONNULL(...)
Definition: localconsts.h:179
void setWalkSpeed(const int speed)
Definition: being.h:445
uint32_t party
Map * getCurrentMap() const
Definition: game.h:106
virtual void readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction, const char *const str)
Definition: messagein.cpp:131
virtual signed char readInt8(const char *const str)
Definition: messagein.cpp:87
void setSpiritBalls(const unsigned int balls)
Definition: being.cpp:5444
static GenderT intToGender(const uint8_t sex) A_CONST
Definition: being.h:936
void processMobInfo(Net::MessageIn &msg)
Definition: beingrecv.cpp:1737
void processComboDelay(Net::MessageIn &msg)
Definition: beingrecv.cpp:1822
void playCastingDstTileEffect(const int id, const int level, const int x, const int y, const int delay) const
void setPartyName(const std::string &name)
Definition: being.cpp:5216
bool isMember(const PartyMember *const member) const
Definition: party.cpp:230
void processSolveCharName(Net::MessageIn &msg)
Definition: beingrecv.cpp:2081
void setSpriteColor(const unsigned int slot, const int id, const std::string &color)
Definition: being.cpp:2863
void setHairColorSpriteID(const unsigned int slot, const int id)
Definition: being.cpp:3264
void processNameResponse2(Net::MessageIn &msg)
Definition: beingrecv.cpp:1962
Logger * logger
Definition: logger.cpp:95
BeingType ::T BeingTypeT
Definition: beingtype.h:40
MercenaryInfo * getMercenary()
Definition: playerinfo.cpp:545
void freezeMoving(const int timeWaitTicks)
void addToCache() const
Definition: being.cpp:3486
virtual void setDirection(const uint8_t direction)
Definition: being.cpp:1661
void setHP(const int hp)
Definition: being.cpp:4309
void processPlayerStatusChange(Net::MessageIn &msg)
Definition: beingrecv.cpp:1520
static std::string getKeyShortString(const std::string &key)
MapTypeProperty2Bits bits
Net::ServerFeatures * serverFeatures
Definition: net.cpp:94
void returnCamera()
Definition: viewport.cpp:1110
void processAlchemistRanksList(Net::MessageIn &msg)
Definition: beingrecv.cpp:1378
void processBeingSoundEffect(Net::MessageIn &msg)
Definition: beingrecv.cpp:1470
void setHorse(const int horseId)
Definition: being.cpp:5395
void updateGuild()
Definition: being.cpp:1304
#define CAST_S32
Definition: cast.h:29
void setActionTime(const int actionTime)
Definition: being.h:134
void processBeingResurrect(Net::MessageIn &msg)
Definition: beingrecv.cpp:1577
void setStatusEffectOpiton0(const uint32_t option)
void processMonsterHp(Net::MessageIn &msg)
Definition: beingrecv.cpp:1325
OkDialog * deathNotice
void processSkillDamage(Net::MessageIn &msg)
Definition: beingrecv.cpp:2114
void processBeingChangeLookContinue(const Net::MessageIn &msg, Being *const dstBeing, const uint8_t type, const int id, const int id2, const int *const cards)
Definition: beingrecv.cpp:254
int getPortalIndex(const int x, const int y)
#define fromBool(val, name)
Definition: booldefines.h:48
void processTaekwonRanksList(Net::MessageIn &msg)
Definition: beingrecv.cpp:1388
bool info(InputEvent &event)
Definition: commands.cpp:56
void processMonsterInfo(Net::MessageIn &msg)
Definition: beingrecv.cpp:1781
virtual void readCoordinatePair(uint16_t &srcX, uint16_t &srcY, uint16_t &dstX, uint16_t &dstY, const char *const str)
Definition: messagein.cpp:163
void navigateClean()
std::list< Character * > Characters
Definition: character.h:60
#define DEBUGLOGSTR(str)
Definition: logger.h:44
Definition: game.h:62
const bool IsStart_true
Definition: isstart.h:29
void pingResponse()
void undelete(const ActorSprite *const actor)
void setPvpRank(const unsigned int rank)
Definition: being.h:745
void processBeingSpecialEffect(Net::MessageIn &msg)
Definition: beingrecv.cpp:1437
LocalPlayer * localPlayer
virtual void skip(const unsigned int length, const char *const str)
Definition: messagein.cpp:201
void handleSkill(Being *const victim, const int damage, const int skillId, const int skillLevel)
Definition: being.cpp:1048
bool isAlive() const
Definition: being.h:481
void addCast(const int dstX, const int dstY, const int skillId, const int skillLevel, const int range, const int waitTimeTicks)
Definition: being.cpp:5339
BeingActionT getCurrentAction() const
Definition: being.h:475
Being * findBeing(const BeingId id) const
void stopAttack(const bool keepAttack)
PartyMember * getMember(const BeingId id) const
Definition: party.cpp:99
static const int MILLISECONDS_IN_A_TICK
Definition: timer.h:29
ActorTypeT getType() const
Definition: being.h:115
bool isBlocked(const BeingId id) const
void processPlayerStatusChange2(Net::MessageIn &msg)
Definition: beingrecv.cpp:1559
void setName(const std::string &name)
Definition: avatar.h:58
void imitateOutfit(const Being *const player, const int sprite) const
void resetDamage(const std::string &name)
bool Enable
Definition: enable.h:29
int serverVersion
Definition: client.cpp:119
void setSpriteId(const unsigned int slot, const int id)
Definition: being.cpp:2762
void setGM(const bool gm)
Definition: being.cpp:3639
virtual void setAction(const BeingActionT &action, const int attackId)
Definition: being.cpp:1525
void processWddingEffect(Net::MessageIn &msg)
Definition: beingrecv.cpp:1830
void processSkillAutoCast(Net::MessageIn &msg)
Definition: beingrecv.cpp:1338
unsigned int getVersion() const
Definition: messagein.h:127
void processBeingSpawn(Net::MessageIn &msg)
Definition: beingrecv.cpp:804
const bool IsStart_false
Definition: isstart.h:29
SocialWindow * socialWindow
AttackType ::T AttackTypeT
Definition: attacktype.h:46
void setManner(const int manner)
Definition: being.h:1034
const std::string & getName() const
Definition: being.h:231
void processBeingRemoveSkill(Net::MessageIn &msg)
Definition: beingrecv.cpp:1647
void imitateDirection(const Being *const being, const unsigned char dir)
Definition: map.h:68
void processBladeStop(Net::MessageIn &msg)
Definition: beingrecv.cpp:1813
void processBeingSelfEffect(Net::MessageIn &msg)
Definition: beingrecv.cpp:1711
void takeDamage(Being *const attacker, const int amount, const AttackTypeT type, const int attackId, const int level)
Definition: being.cpp:665
virtual void scheduleDelete()
Definition: window.cpp:826
void checkNewName(Being *const being)
void processSkillCasting2(Net::MessageIn &msg)
Definition: beingrecv.cpp:1033
void processSkillEntry(Net::MessageIn &msg)
Definition: beingrecv.cpp:1491
SkillDialog * skillDialog
Definition: skilldialog.cpp:65
void imitateAction(const Being *const being, const BeingActionT &action)
void applyPlayerAction(Net::MessageIn &msg, Being *const being, const uint8_t type)
Definition: beingrecv.cpp:2161
static std::string keyName(const int number)
void setCreatorId(const BeingId id)
Definition: being.h:1022
void setSubtype(const BeingTypeId subtype, const uint16_t look)
Definition: being.cpp:369
void setKarma(const int karma)
Definition: being.h:1028
void erase(ActorSprite *const actor)
void processBeingChangeLook2(Net::MessageIn &msg)
Definition: beingrecv.cpp:191
void setStatusEffectOpitons(const uint32_t option, const uint32_t opt1, const uint32_t opt2, const uint32_t opt3)
void processMapTypeProperty(Net::MessageIn &msg)
Definition: beingrecv.cpp:983
void followMoveTo(const Being *const being, const int x, const int y)
void processPvpSet(Net::MessageIn &msg)
Definition: beingrecv.cpp:1947
void processBeingChangeDirection(Net::MessageIn &msg)
Definition: beingrecv.cpp:1408
void setName(const std::string &name)
Definition: being.cpp:1134
void handleSkillCasting(Being *const victim, const int skillId, const int skillLevel)
Definition: being.cpp:1023
virtual uint16_t readUInt16(const char *const str)=0
static Net::Characters mCharacters
void processSpiritBalls(Net::MessageIn &msg)
Definition: beingrecv.cpp:1804
Definition: sp.h:34
void processPlayerGuilPartyInfo(Net::MessageIn &msg)
Definition: beingrecv.cpp:1613
void processBeingMove2(Net::MessageIn &msg)
Definition: beingrecv.cpp:1153
void processMapType(Net::MessageIn &msg)
Definition: beingrecv.cpp:1002
virtual int32_t readInt32(const char *const str)=0
void processSkillCastingContinue(Net::MessageIn &msg, const BeingId srcId, const BeingId dstId, const int dstX, const int dstY, const int skillId, const int skillLevel, const int range, const SkillType2::SkillType2 inf2, const int castTime)
Definition: beingrecv.cpp:1058
static Game * instance()
Definition: game.h:81
void recalcSpritesOrder()
Definition: being.cpp:4334
void setMercenaryBeing(Being *const being)
Definition: playerinfo.cpp:522
void processRanksList(Net::MessageIn &msg)
Definition: beingrecv.cpp:1356
#define restrict
Definition: localconsts.h:176
virtual std::string readString(int length, const char *const dstr)
Definition: messagein.cpp:219
void processBeingStatusChange(Net::MessageIn &msg)
Definition: beingrecv.cpp:1120
#define UNIMPLEMENTEDPACKET
Definition: logger.h:55
BeingId getPetBeingId()
Definition: playerinfo.cpp:577
int getTileX() const
Definition: being.h:167
void setLook(const uint16_t look)
Definition: being.cpp:4974
const BeingId BeingId_zero
Definition: beingid.h:29
void setHairColor(const unsigned int slot, const ItemColor color)
Definition: being.cpp:3362
static uint8_t fromServerDirection(const uint8_t serverDir)
Definition: messagein.cpp:101
void log(const char *const log_text,...)
Definition: logger.cpp:243
virtual bool haveMove3() const =0
void setServerLanguage(const int lang)
Definition: playerinfo.cpp:664
void updateNameId(const std::string &name, const BeingId beingId)
Being * createBeing2(Net::MessageIn &msg, const BeingId id, const int32_t job, const BeingTypeT beingType)
Definition: beingrecv.cpp:2009
void processBlacksmithRanksList(Net::MessageIn &msg)
Definition: beingrecv.cpp:1368
void processSkillCasting(Net::MessageIn &msg)
Definition: beingrecv.cpp:1011
void processSkillCancel(Net::MessageIn &msg)
Definition: beingrecv.cpp:2076
void processBeingStatUpdate1(Net::MessageIn &msg)
Definition: beingrecv.cpp:1693
void setStatusEffect(const int32_t index, const Enable active, const IsStart start)
bool trigger(const int id, Being *const being, const int rotation)
void handleAttack(Being *const victim, const int damage, const int attackId)
Definition: being.cpp:961
void processBeingCharm(Net::MessageIn &msg)
Definition: beingrecv.cpp:1905
int BeingTypeId
Definition: beingtypeid.h:29
Definition: being.h:93
static void setBasicFields(Being *const dstBeing, const uint8_t gender, const int hairStyle, const ItemColor hairColor, const uint32_t weapon, const uint16_t headBottom, const uint16_t headMid, const uint16_t headTop, const uint16_t shoes, const uint16_t gloves, const bool notMove)
Definition: beingrecv.cpp:87
void setWeaponId(const int id)
Definition: being.cpp:3108
EffectManager * effectManager
#define reportAlways(...)
Definition: checkutils.h:252
void addChar(const int32_t id, const std::string &name)
LocalPlayer * dummy
Definition: character.h:55
void processStarsKill(Net::MessageIn &msg)
Definition: beingrecv.cpp:1857
Being * createBeing(const BeingId id, const ActorTypeT type, const BeingTypeId subtype)
void setSpriteCards(const unsigned int slot, const int id, const CardsList &cards)
Definition: being.cpp:3021
#define maxCards
Definition: cards.h:24
ActorManager * actorManager
void processBeingAttrs(Net::MessageIn &msg)
Definition: beingrecv.cpp:1749
Viewport * viewport
Definition: viewport.cpp:35
#define UNIMPLEMENTEDPACKETFIELD(field)
Definition: logger.h:58
void processBeingMilleniumShield(Net::MessageIn &msg)
Definition: beingrecv.cpp:1896
void processBeingFakeName(Net::MessageIn &msg)
Definition: beingrecv.cpp:1658
void setLevel(const int n)
Definition: being.h:594
Being * getTarget() const
void setMoveTime()
Definition: being.h:699
void setAttackTime()
Definition: being.h:702
void clearPath()
Definition: being.cpp:552
void setMaxHP(const int hp)
Definition: being.cpp:4318