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 #ifndef BEING_BEING_H 25 #define BEING_BEING_H 26 27 #include "position.h" 28 29 #include "enums/being/badgeindex.h" 30 #include "enums/being/reachable.h" 31 32 #include "enums/gui/usercolorid.h" 33 34 #include "enums/simpletypes/move.h" 35 36 #include "enums/being/visiblenamepos.h" 37 38 #include "resources/beinginfo.h" 39 #include "resources/beingslot.h" 40 41 #include "being/actorsprite.h" 42 43 #include "enums/being/attacktype.h" 44 #include "enums/being/badgedrawtype.h" 45 #include "enums/being/beingaction.h" 46 #include "enums/being/gender.h" 47 48 #include "listeners/configlistener.h" 49 50 #include "localconsts.h" 51 52 static const int DEFAULT_BEING_WIDTH = 32; 53 static const int DEFAULT_BEING_HEIGHT = 32; 54 55 class AnimatedSprite; 56 class BeingCacheEntry; 57 class CastingEffect; 58 class Color; 59 class Equipment; 60 class FlashText; 61 class Guild; 62 class ItemInfo; 63 class Particle; 64 class Party; 65 class SpeechBubble; 66 class Text; 67 68 struct ChatObject; 69 struct HorseInfo; 70 struct MissileInfo; 71 struct SkillInfo; 72 struct ParticleInfo; 73 74 extern volatile time_t cur_time; 75 76 struct NextSoundInfo final 77 { NextSoundInfofinal78 NextSoundInfo() noexcept2 : 79 sound(nullptr), 80 x(0), 81 y(0), 82 time(0) 83 { 84 } 85 86 A_DELETE_COPY(NextSoundInfo) 87 88 const SoundInfo *sound; 89 int x; 90 int y; 91 int time; 92 }; 93 94 class Being notfinal : public ActorSprite, 95 public ConfigListener 96 { 97 public: 98 friend class ActorManager; 99 friend class BeingEquipBackend; 100 friend class LocalPlayer; 101 102 /** 103 * Constructor. 104 * 105 * @param id a unique being id 106 * @param subtype partly determines the type of the being 107 * @param map the map the being is on 108 */ 109 Being(const BeingId id, 110 const ActorTypeT type); 111 112 A_DELETE_COPY(Being) 113 114 ~Being() override; 115 getType()116 ActorTypeT getType() const restrict2 noexcept2 override final 117 A_WARN_UNUSED 118 { return mType; } 119 120 /** 121 * Removes all path nodes from this being. 122 */ 123 void clearPath() restrict2; 124 125 /** 126 * Returns the time spent in the current action. 127 */ getActionTime()128 int getActionTime() const restrict2 noexcept2 A_WARN_UNUSED 129 { return mActionTime; } 130 131 /** 132 * Set the current action time. 133 * @see Ea::BeingHandler that set it to tick time. 134 */ setActionTime(const int actionTime)135 void setActionTime(const int actionTime) restrict2 noexcept2 136 { mActionTime = actionTime; } 137 138 /** 139 * Makes this being take the next tile of its path. 140 */ 141 virtual void nextTile() restrict2; 142 143 /** 144 * Creates a path for the being from current position to ex and ey 145 */ 146 void setDestination(const int dstX, 147 const int dstY) restrict2; 148 setCachedDestination(const int dstX,const int dstY)149 void setCachedDestination(const int dstX, 150 const int dstY) restrict2 noexcept2 151 { mCachedX = dstX; mCachedY = dstY; } 152 getCachedX()153 int getCachedX() const noexcept2 A_WARN_UNUSED 154 { return mCachedX; } 155 getCachedY()156 int getCachedY() const noexcept2 A_WARN_UNUSED 157 { return mCachedY; } 158 159 /** 160 * Returns the destination for this being. 161 */ getDestination()162 const Vector &getDestination() const restrict2 noexcept2 A_WARN_UNUSED 163 { return mDest; } 164 165 /** 166 * Returns the tile x coord 167 */ getTileX()168 int getTileX() const restrict2 noexcept2 override A_WARN_UNUSED 169 { return mX; } 170 171 /** 172 * Returns the tile y coord 173 */ getTileY()174 int getTileY() const restrict2 noexcept2 override A_WARN_UNUSED 175 { return mY; } 176 177 /** 178 * Sets the tile x and y coord 179 */ 180 virtual void setTileCoords(const int x, const int y) restrict2; 181 182 /** 183 * Puts a "speech balloon" above this being for the specified amount 184 * of time. 185 * 186 * @param text The text that should appear. 187 * @param time The amount of time the text should stay in milliseconds. 188 */ 189 void setSpeech(const std::string &restrict text) restrict2; 190 191 /** 192 * Puts a damage bubble above this being. 193 * 194 * @param attacker the attacking being 195 * @param amount the amount of damage recieved (0 means miss) 196 * @param type the attack type 197 * @param attackId the attack id 198 * @param level the skill level 199 */ 200 void takeDamage(Being *restrict const attacker, 201 const int amount, 202 const AttackTypeT type, 203 const int attackId, 204 const int level) restrict2; 205 206 /** 207 * Handles an attack of another being by this being. 208 * 209 * @param victim the victim being 210 * @param damage the amount of damage dealt (0 means miss) 211 * @param attackId the attack id 212 */ 213 void handleAttack(Being *restrict const victim, 214 const int damage, 215 const int attackId) restrict2; 216 217 void handleSkillCasting(Being *restrict const victim, 218 const int skillId, 219 const int skillLevel) restrict2; 220 221 void handleSkill(Being *restrict const victim, 222 const int damage, 223 const int skillId, 224 const int skillLevel) restrict2; 225 getEquippedWeapon()226 const ItemInfo *getEquippedWeapon() const restrict2 A_WARN_UNUSED 227 { return mEquippedWeapon; } 228 229 /** 230 * Returns the name of the being. 231 */ getName()232 const std::string &getName() const restrict2 noexcept2 A_WARN_UNUSED 233 { return mName; } 234 getExtName()235 const std::string &getExtName() const restrict2 noexcept2 A_WARN_UNUSED 236 { return mExtName; } 237 238 /** 239 * Sets the name for the being. 240 * 241 * @param name The name that should appear. 242 */ 243 void setName(const std::string &restrict name) restrict2; 244 getShowName()245 bool getShowName() const noexcept2 A_WARN_UNUSED 246 { return mShowName; } 247 248 void setShowName(const bool doShowName) restrict2; 249 250 /** 251 * Sets the name of the party the being is in. Shown in BeingPopup. 252 */ 253 void setPartyName(const std::string &restrict name) restrict2; 254 getPartyName()255 const std::string &getPartyName() const restrict2 noexcept2 256 A_WARN_UNUSED 257 { return mPartyName; } 258 getGuildName()259 const std::string &getGuildName() const restrict2 noexcept2 260 A_WARN_UNUSED 261 { return mGuildName; } 262 getClanName()263 const std::string &getClanName() const restrict2 noexcept2 264 A_WARN_UNUSED 265 { return mClanName; } 266 267 /** 268 * Sets the name of the primary guild the being is in. Shown in 269 * BeingPopup (eventually). 270 */ 271 void setGuildName(const std::string &restrict name) restrict2; 272 273 void setGuildPos(const std::string &restrict pos) restrict2; 274 275 void setClanName(const std::string &restrict name) restrict2; 276 277 /** 278 * Adds a guild to the being. 279 */ 280 void addGuild(Guild *restrict const guild) restrict2; 281 282 /** 283 * Removers a guild from the being. 284 */ 285 void removeGuild(const int id) restrict2; 286 287 /** 288 * Returns a pointer to the specified guild that the being is in. 289 */ 290 const Guild *getGuild(const std::string &restrict guildName) 291 const restrict2 A_WARN_UNUSED; 292 293 /** 294 * Returns a pointer to the specified guild that the being is in. 295 */ 296 const Guild *getGuild(const int id) const restrict2 A_WARN_UNUSED; 297 298 /** 299 * Returns a pointer to the specified guild that the being is in. 300 */ 301 Guild *getGuild() const restrict2 A_WARN_UNUSED; 302 303 /** 304 * Returns all guilds the being is in. 305 */ getGuilds()306 const std::map<int, Guild*> &getGuilds() const restrict2 noexcept2 307 A_WARN_UNUSED 308 { return mGuilds; } 309 310 /** 311 * Removes all guilds the being is in. 312 */ 313 void clearGuilds() restrict2; 314 315 /** 316 * Get number of guilds the being belongs to. 317 */ getNumberOfGuilds()318 int16_t getNumberOfGuilds() const restrict2 A_WARN_UNUSED 319 { return CAST_S16(mGuilds.size()); } 320 isInParty()321 bool isInParty() const restrict2 noexcept2 A_WARN_UNUSED 322 { return mParty != nullptr; } 323 324 void setParty(Party *restrict const party) restrict2; 325 326 void setGuild(Guild *restrict const guild) restrict2; 327 328 void updateGuild() restrict2; 329 getParty()330 Party *getParty() const restrict2 noexcept2 A_WARN_UNUSED 331 { return mParty; } 332 333 void setSprite(const unsigned int slot, 334 const int id, 335 std::string color, 336 ItemColor colorId) restrict2; 337 338 void setSpriteColor(const unsigned int slot, 339 const int id, 340 const std::string &color) restrict2; 341 342 void setSpriteColorId(const unsigned int slot, 343 const int id, 344 ItemColor colorId) restrict2; 345 346 void setSpriteCards(const unsigned int slot, 347 const int id, 348 const CardsList &restrict cards) restrict2; 349 350 void setSpriteId(const unsigned int slot, 351 const int id) restrict2; 352 353 void unSetSprite(const unsigned int slot) restrict2; 354 355 void setWeaponId(const int id) restrict2; 356 357 void setTempSprite(const unsigned int slot, 358 const int id) restrict2; 359 360 void setHairTempSprite(const unsigned int slot, 361 const int id) restrict2; 362 363 void updateSprite(const unsigned int slot, 364 const int id, 365 const std::string &restrict color) 366 restrict2; 367 368 void setHairColorSpriteID(const unsigned int slot, 369 const int id) restrict2; 370 371 void setSpriteColor(const unsigned int slot, 372 const std::string &restrict color) restrict2; 373 374 /** 375 * Get the number of layers used to draw the being 376 */ getNumberOfLayers()377 int getNumberOfLayers() const restrict2 override A_WARN_UNUSED 378 { return CompoundSprite::getNumberOfLayers(); } 379 380 /** 381 * Performs being logic. 382 */ 383 void logic() restrict2 override; 384 385 void botLogic() restrict2; 386 387 /** 388 * Draws the speech text above the being. 389 */ 390 void drawSpeech(const int offsetX, 391 const int offsetY) restrict2; 392 393 /** 394 * Draws the emotion picture above the being. 395 */ 396 void drawEmotion(Graphics *restrict const graphics, 397 const int offsetX, 398 const int offsetY) const restrict2 A_NONNULL(2); 399 getSubType()400 BeingTypeId getSubType() const restrict2 noexcept2 A_WARN_UNUSED 401 { return mSubType; } 402 403 /** 404 * Set Being's subtype (mostly for view for monsters and NPCs) 405 */ 406 void setSubtype(const BeingTypeId subtype, 407 const uint16_t look) restrict2; 408 getInfo()409 const BeingInfo *getInfo() const restrict2 noexcept2 A_WARN_UNUSED 410 { return mInfo; } 411 412 TargetCursorSizeT getTargetCursorSize() const restrict2 override final 413 A_WARN_UNUSED; 414 getTargetOffsetX()415 int getTargetOffsetX() const restrict2 override A_WARN_UNUSED 416 { 417 if (mInfo == nullptr) 418 return 0; 419 return mInfo->getTargetOffsetX(); 420 } 421 getTargetOffsetY()422 int getTargetOffsetY() const restrict2 override A_WARN_UNUSED 423 { 424 if (mInfo == nullptr) 425 return 0; 426 return mInfo->getTargetOffsetY(); 427 } 428 429 /** 430 * Gets the way the object is blocked by other objects. 431 */ getBlockWalkMask()432 virtual unsigned char getBlockWalkMask() const restrict2 A_WARN_UNUSED 433 { 434 if (mInfo == nullptr) 435 return 0; 436 return mInfo->getBlockWalkMask(); 437 } 438 439 /** 440 * Gets the way the monster blocks pathfinding for other objects 441 */ getBlockType()442 BlockTypeT getBlockType() const restrict2 override A_WARN_UNUSED 443 { 444 if (mInfo == nullptr) 445 return BlockType::NONE; 446 return mInfo->getBlockType(); 447 } 448 449 /** 450 * Sets the walk speed in pixels per second. 451 */ setWalkSpeed(const int speed)452 void setWalkSpeed(const int speed) restrict2 453 { mWalkSpeed = speed; mSpeed = speed; } 454 455 /** 456 * Gets the walk speed in pixels per second. 457 */ getWalkSpeed()458 int getWalkSpeed() const restrict2 noexcept2 A_WARN_UNUSED 459 { return mWalkSpeed; } 460 461 /** 462 * Sets the attack speed. 463 */ setAttackSpeed(const int speed)464 void setAttackSpeed(const int speed) restrict2 noexcept2 465 { mAttackSpeed = speed; } 466 467 /** 468 * Gets the attack speed. 469 */ getAttackSpeed()470 int getAttackSpeed() const restrict2 noexcept2 A_WARN_UNUSED 471 { return mAttackSpeed; } 472 473 /** 474 * Sets the current action. 475 */ 476 virtual void setAction(const BeingActionT &restrict action, 477 const int attackId) restrict2; 478 479 /** 480 * Get the being's action currently performed. 481 */ getCurrentAction()482 BeingActionT getCurrentAction() const restrict2 noexcept2 A_WARN_UNUSED 483 { return mAction; } 484 485 /** 486 * Returns whether this being is still alive. 487 */ isAlive()488 bool isAlive() const restrict2 noexcept2 A_WARN_UNUSED 489 { return mAction != BeingAction::DEAD; } 490 491 /** 492 * Returns the current direction. 493 */ getDirection()494 uint8_t getDirection() const restrict2 noexcept2 A_WARN_UNUSED 495 { return mDirection; } 496 497 /** 498 * Sets the current direction. 499 */ 500 virtual void setDirection(const uint8_t direction) restrict2; 501 setDirectionDelayed(const uint8_t direction)502 void setDirectionDelayed(const uint8_t direction) restrict2 noexcept2 503 { mDirectionDelayed = direction; } 504 getDirectionDelayed()505 uint8_t getDirectionDelayed() const restrict2 noexcept2 A_WARN_UNUSED 506 { return mDirectionDelayed; } 507 508 /** 509 * Returns the direction the being is facing. 510 */ getSpriteDirection()511 SpriteDirection::Type getSpriteDirection() const restrict2 noexcept2 512 A_WARN_UNUSED 513 { return mSpriteDirection; } 514 515 void setPixelPositionF(const Vector &restrict pos) restrict2 override; 516 517 /** 518 * Overloaded method provided for convenience. 519 * 520 * @see setPosition(const Vector &pos) 521 */ setPixelPositionF(const float x,const float y,const float z)522 inline void setPixelPositionF(const float x, 523 const float y, 524 const float z) restrict2 A_INLINE 525 { setPixelPositionF(Vector(x, y, z)); } 526 527 /** 528 * Returns the horizontal size of the current base sprite of the being. 529 */ getWidth()530 int getWidth() const restrict2 override final A_WARN_UNUSED 531 { return std::max(CompoundSprite::getWidth(), DEFAULT_BEING_WIDTH); } 532 533 /** 534 * Returns the vertical size of the current base sprite of the being. 535 */ getHeight()536 int getHeight() const restrict2 override final A_WARN_UNUSED 537 { return std::max(CompoundSprite::getHeight(), DEFAULT_BEING_HEIGHT); } 538 539 /** 540 * Shoots a missile particle from this being, to target being 541 */ 542 void fireMissile(Being *restrict const victim, 543 const MissileInfo &restrict missile) const restrict2; 544 545 /** 546 * Returns the path this being is following. An empty path is returned 547 * when this being isn't following any path currently. 548 */ getPath()549 const Path &getPath() const restrict2 noexcept2 A_WARN_UNUSED 550 { return mPath; } 551 getDistance()552 int getDistance() const restrict2 noexcept2 A_WARN_UNUSED 553 { return mDistance; } 554 setDistance(const int n)555 void setDistance(const int n) restrict2 noexcept2 556 { mDistance = n; } 557 558 /** 559 * Set the Emoticon type and time displayed above 560 * the being. 561 */ 562 void setEmote(const uint8_t emotion, 563 const int emote_time) restrict2; 564 565 void setState(const uint8_t state) restrict2; 566 567 void drawPlayerSprites(Graphics *restrict const graphics, 568 const int posX, 569 const int posY) const 570 restrict2 A_NONNULL(2); 571 572 void drawSpritesSDL(Graphics *restrict const graphics, 573 const int posX, 574 const int posY) const 575 restrict2 override final A_NONNULL(2); 576 577 void drawHpBar(Graphics *restrict const graphics, 578 const int maxHP, 579 const int hp, 580 const int damage, 581 const UserColorIdT color1, 582 const UserColorIdT color2, 583 const int x, 584 const int y, 585 const int width, 586 const int height) const restrict2 A_NONNULL(2); 587 588 void optionChanged(const std::string &restrict value) 589 restrict2 override; 590 591 void flashName(const int time) restrict2; 592 getDamageTaken()593 int getDamageTaken() const restrict2 noexcept2 A_WARN_UNUSED 594 { return mDamageTaken; } 595 setDamageTaken(const int damage)596 void setDamageTaken(const int damage) restrict2 noexcept2 597 { mDamageTaken = damage; } 598 599 void updateName() restrict2; 600 setLevel(const int n)601 void setLevel(const int n) restrict2 noexcept2 602 { mLevel = n; } 603 getLevel()604 virtual int getLevel() const restrict2 A_WARN_UNUSED 605 { return mLevel; } 606 setReachable(const ReachableT n)607 void setReachable(const ReachableT n) restrict2 noexcept2 608 { mReachable = n; } 609 getReachable()610 ReachableT getReachable() const restrict2 noexcept2 A_WARN_UNUSED 611 { return mReachable; } 612 613 static void reReadConfig(); 614 615 static BeingCacheEntry* getCacheEntry(const BeingId id) A_WARN_UNUSED; 616 617 void addToCache() const restrict2; 618 619 bool updateFromCache() restrict2; 620 621 /** 622 * Sets the gender of this being. 623 */ 624 virtual void setGender(const GenderT gender) restrict2; 625 getGender()626 GenderT getGender() const restrict2 noexcept2 A_WARN_UNUSED 627 { return mGender; } 628 629 /** 630 * Return sprite sit action for current environment. 631 */ 632 std::string getSitAction() const restrict2 A_WARN_UNUSED; 633 634 std::string getCastAction() const restrict2 A_WARN_UNUSED; 635 636 std::string getCastAction(const SkillInfo *restrict const skill) const 637 restrict2 A_WARN_UNUSED; 638 639 std::string getMoveAction() const restrict2 A_WARN_UNUSED; 640 641 std::string getDeadAction() const restrict2 A_WARN_UNUSED; 642 643 std::string getStandAction() const restrict2 A_WARN_UNUSED; 644 645 std::string getSpawnAction() const restrict2 A_WARN_UNUSED; 646 647 std::string getWeaponAttackAction(const ItemInfo *restrict const 648 weapon) const 649 restrict2 A_WARN_UNUSED; 650 651 std::string getAttackAction() const restrict2 A_WARN_UNUSED; 652 653 std::string getAttackAction(const Attack *restrict const attack1) const 654 restrict2 A_WARN_UNUSED; 655 656 /** 657 * Whether or not this player is a GM. 658 */ isGM()659 bool isGM() const restrict2 noexcept2 A_WARN_UNUSED 660 { return mIsGM; } 661 662 /** 663 * Triggers whether or not to show the name as a GM name. 664 */ 665 void setGM(const bool gm) restrict2; 666 canTalk()667 bool canTalk() const restrict2 noexcept2 A_WARN_UNUSED 668 { return mType == ActorType::Npc; } 669 670 void talkTo() const restrict2; 671 672 void draw(Graphics *restrict const graphics, 673 const int offsetX, 674 const int offsetY) const 675 restrict2 override final A_NONNULL(2); 676 677 void drawPlayer(Graphics *restrict const graphics, 678 const int offsetX, 679 const int offsetY) const 680 restrict2 A_NONNULL(2); 681 682 void drawOther(Graphics *restrict const graphics, 683 const int offsetX, 684 const int offsetY) const 685 restrict2 A_NONNULL(2); 686 687 void drawNpc(Graphics *restrict const graphics, 688 const int offsetX, 689 const int offsetY) const 690 restrict2 A_NONNULL(2); 691 692 void drawMonster(Graphics *restrict const graphics, 693 const int offsetX, 694 const int offsetY) const 695 restrict2 A_NONNULL(2); 696 697 void drawPortal(Graphics *restrict const graphics, 698 const int offsetX, 699 const int offsetY) const 700 restrict2 A_NONNULL(2); 701 702 void drawBasic(Graphics *restrict const graphics, 703 const int x, 704 const int y) const restrict2 A_NONNULL(2); 705 setMoveTime()706 void setMoveTime() restrict2 noexcept2 707 { mMoveTime = cur_time; } 708 setAttackTime()709 void setAttackTime() restrict2 noexcept2 710 { mAttackTime = cur_time; } 711 setTalkTime()712 void setTalkTime() restrict2 noexcept2 713 { mTalkTime = cur_time; } 714 setTestTime()715 void setTestTime() restrict2 noexcept2 716 { mTestTime = cur_time; } 717 setOtherTime()718 void setOtherTime() restrict2 noexcept2 719 { mOtherTime = cur_time; } 720 getMoveTime()721 time_t getMoveTime() const restrict2 noexcept2 722 { return mMoveTime; } 723 getAttackTime()724 time_t getAttackTime() const restrict2 noexcept2 725 { return mAttackTime; } 726 getTalkTime()727 time_t getTalkTime() const restrict2 noexcept2 728 { return mTalkTime; } 729 getTestTime()730 time_t getTestTime() const restrict2 noexcept2 731 { return mTestTime; } 732 getOtherTime()733 time_t getOtherTime() const restrict2 noexcept2 734 { return mOtherTime; } 735 736 void resetCounters() restrict2; 737 738 void updateColors() restrict2; 739 setEnemy(const bool n)740 void setEnemy(const bool n) restrict2 noexcept2 741 { mEnemy = n; } 742 getIp()743 const std::string &getIp() const restrict2 noexcept2 A_WARN_UNUSED 744 { return mIp; } 745 setIp(const std::string & restrict ip)746 void setIp(const std::string &restrict ip) restrict2 noexcept2 747 { mIp = ip; } 748 getPvpRank()749 unsigned int getPvpRank() const restrict2 noexcept2 A_WARN_UNUSED 750 { return mPvpRank; } 751 setPvpRank(const unsigned int rank)752 void setPvpRank(const unsigned int rank) restrict2 noexcept2 753 { mPvpRank = rank; } 754 755 void setHP(const int hp) restrict2; 756 757 void setMaxHP(const int hp) restrict2; 758 getHP()759 int getHP() const restrict2 noexcept2 A_WARN_UNUSED 760 { return mHP; } 761 getMaxHP()762 int getMaxHP() const restrict2 noexcept2 A_WARN_UNUSED 763 { return mMaxHP; } 764 765 uint8_t calcDirection(const int dstX, 766 const int dstY) const restrict2 A_WARN_UNUSED; 767 768 uint8_t calcDirection() const restrict2 A_WARN_UNUSED; 769 setAttackDelay(const int n)770 void setAttackDelay(const int n) restrict2 noexcept2 771 { mAttackDelay = n; } 772 getAttackDelay()773 int getAttackDelay() const restrict2 noexcept2 A_WARN_UNUSED 774 { return mAttackDelay; } 775 getMinHit()776 int getMinHit() const restrict2 noexcept2 A_WARN_UNUSED 777 { return mMinHit; } 778 setMinHit(const int n)779 void setMinHit(const int n) restrict2 noexcept2 780 { mMinHit = n; } 781 getMaxHit()782 int getMaxHit() const restrict2 noexcept2 A_WARN_UNUSED 783 { return mMaxHit; } 784 setMaxHit(const int n)785 void setMaxHit(const int n) restrict2 noexcept2 786 { mMaxHit = n; } 787 getCriticalHit()788 int getCriticalHit() const restrict2 A_WARN_UNUSED 789 { return mCriticalHit; } 790 setCriticalHit(const int n)791 void setCriticalHit(const int n) restrict2 noexcept2 792 { mCriticalHit = n; } 793 794 void updateHit(const int amount) restrict2; 795 796 Equipment *getEquipment() restrict2 A_WARN_UNUSED; 797 798 void undressItemById(const int id) restrict2; 799 getGoodStatus()800 int getGoodStatus() const restrict2 noexcept2 A_WARN_UNUSED 801 { return mGoodStatus; } 802 setGoodStatus(const int n)803 void setGoodStatus(const int n) restrict2 noexcept2 804 { mGoodStatus = n; } 805 806 std::string getGenderSign() const restrict2 A_WARN_UNUSED; 807 808 std::string getGenderSignWithSpace() const restrict2 A_WARN_UNUSED; 809 810 void updateComment() restrict2; 811 getComment()812 const std::string getComment() const restrict2 noexcept2 A_WARN_UNUSED 813 { return mComment; } 814 setComment(const std::string & restrict n)815 void setComment(const std::string &restrict n) restrict2 noexcept2 816 { mComment = n; } 817 818 static void clearCache(); 819 820 static std::string loadComment(const std::string &restrict name, 821 const ActorTypeT &restrict type) 822 A_WARN_UNUSED; 823 824 static void saveComment(const std::string &restrict name, 825 const std::string &restrict comment, 826 const ActorTypeT &restrict type); 827 isAdvanced()828 bool isAdvanced() const restrict2 noexcept2 A_WARN_UNUSED 829 { return mAdvanced; } 830 setAdvanced(const bool n)831 void setAdvanced(const bool n) restrict2 832 { mAdvanced = n; addToCache(); } 833 834 bool isBuyShopEnabled() const restrict2 A_WARN_UNUSED; 835 836 bool isSellShopEnabled() const restrict2 A_WARN_UNUSED; 837 838 void enableShop(const bool b) restrict2; 839 840 /** 841 * Sets the attack range. 842 */ setAttackRange(const int range)843 void setAttackRange(const int range) restrict2 noexcept2 844 { mAttackRange = range; } 845 846 /* 847 void attack(Being *restrict target = nullptr, 848 bool keep = false, 849 bool dontChangeEquipment = false) restrict2; 850 851 void attack2(Being *restrict target = nullptr, 852 bool keep = false, 853 bool dontChangeEquipment = false) restrict2; 854 */ 855 856 void updatePercentHP() restrict2; 857 setRaceName(const std::string & restrict name)858 void setRaceName(const std::string &restrict name) restrict2 noexcept2 859 { mRaceName = name; } 860 getRaceName()861 std::string getRaceName() const restrict2 noexcept2 A_WARN_UNUSED 862 { return mRaceName; } 863 864 int getSpriteID(const int slot) const restrict2 A_WARN_UNUSED; 865 866 const BeingSlot &getSpriteSlot(const int slot) const 867 restrict2 A_WARN_UNUSED; 868 869 ItemColor getSpriteColor(const int slot) const restrict2 A_WARN_UNUSED; 870 871 void setHairStyle(const unsigned int slot, 872 const int id) restrict2; 873 874 void setHairColor(const unsigned int slot, 875 const ItemColor color) restrict2; 876 setHairColor(const ItemColor color)877 void setHairColor(const ItemColor color) restrict2 noexcept2 878 { mHairColor = color; } 879 880 void setSpriteSlot(const unsigned int slot, 881 const BeingSlot &beingSlot); 882 getHairColor()883 ItemColor getHairColor() const noexcept2 A_WARN_UNUSED 884 { return mHairColor; } 885 886 void recalcSpritesOrder() restrict2; 887 888 static int getHitEffect(const Being *restrict const attacker, 889 const AttackTypeT type, 890 const int attackId, 891 const int level); 892 getHoverCursor()893 CursorT getHoverCursor() const restrict2 A_WARN_UNUSED 894 { 895 return mInfo != nullptr ? 896 mInfo->getHoverCursor() : Cursor::CURSOR_POINTER; 897 } 898 899 void addAfkEffect() restrict2; 900 901 void removeAfkEffect() restrict2; 902 903 void updateAwayEffect() restrict2; 904 905 void addSpecialEffect(const int effect) restrict2; 906 907 void removeSpecialEffect() restrict2; 908 909 void addEffect(const std::string &restrict name) restrict2; 910 setOwner(Being * restrict const owner)911 void setOwner(Being *restrict const owner) restrict2 noexcept2 912 { mOwner = owner; } 913 getOwner()914 Being *getOwner() const restrict2 noexcept2 915 { return mOwner; } 916 917 void playSfx(const SoundInfo &sound, 918 Being *const being, 919 const bool main, 920 const int x, const int y) const restrict2; 921 getLook()922 uint16_t getLook() const restrict2 noexcept2 923 { return mLook; } 924 925 void setLook(const uint16_t look) restrict2; 926 genderToInt(const GenderT sex)927 constexpr2 static uint8_t genderToInt(const GenderT sex) 928 A_CONST A_WARN_UNUSED 929 { 930 switch (sex) 931 { 932 case Gender::FEMALE: 933 case Gender::UNSPECIFIED: 934 default: 935 return 0; 936 case Gender::MALE: 937 return 1; 938 } 939 } 940 intToGender(const uint8_t sex)941 constexpr2 static GenderT intToGender(const uint8_t sex) 942 A_CONST A_WARN_UNUSED 943 { 944 switch (sex) 945 { 946 case 0: 947 default: 948 return Gender::FEMALE; 949 case 1: 950 return Gender::MALE; 951 } 952 } 953 954 NextSoundInfo mNextSound; 955 956 /** 957 * Sets the new path for this being. 958 */ 959 void setPath(const Path &restrict path) restrict2; 960 getSortPixelY()961 int getSortPixelY() const restrict2 override A_WARN_UNUSED 962 { return CAST_S32(mPos.y) - mYDiff - mSortOffsetY; } 963 964 void setMap(Map *restrict const map) restrict2 override; 965 966 void recreateItemParticles() restrict2; 967 incUsage()968 void incUsage() restrict2 noexcept2 969 { mUsageCounter ++; } 970 decUsage()971 int decUsage() restrict2 noexcept2 972 { return --mUsageCounter; } 973 getLastAttackX()974 virtual int getLastAttackX() const restrict2 975 { return mLastAttackX; } 976 getLastAttackY()977 virtual int getLastAttackY() const restrict2 978 { return mLastAttackY; } 979 980 void drawHomunculus(Graphics *restrict const graphics, 981 const int offsetX, 982 const int offsetY) const 983 restrict2 A_NONNULL(2); 984 985 void drawMercenary(Graphics *restrict const graphics, 986 const int offsetX, 987 const int offsetY) const 988 restrict2 A_NONNULL(2); 989 990 void drawElemental(Graphics *restrict const graphics, 991 const int offsetX, 992 const int offsetY) const 993 restrict2 A_NONNULL(2); 994 995 void setTrickDead(const bool b) restrict2 override final; 996 997 void setChat(ChatObject *restrict const obj) restrict2; 998 getChat()999 ChatObject *getChat() const restrict2 noexcept2 1000 { return mChat; } 1001 1002 void setRiding(const bool b) restrict2 override final; 1003 1004 void setHorse(const int horseId) restrict2; 1005 1006 void removeHorse() restrict2; 1007 1008 void setSellBoard(const std::string &restrict text) restrict2; 1009 getSellBoard()1010 std::string getSellBoard() const restrict2 noexcept2 A_WARN_UNUSED 1011 { return mSellBoard; } 1012 1013 void setBuyBoard(const std::string &restrict text) restrict2; 1014 getBuyBoard()1015 std::string getBuyBoard() const restrict2 noexcept2 A_WARN_UNUSED 1016 { return mBuyBoard; } 1017 1018 void setSpiritBalls(const unsigned int balls) restrict2; 1019 getSpiritBalls()1020 unsigned int getSpiritBalls() const restrict2 noexcept2 A_WARN_UNUSED 1021 { return mSpiritBalls; } 1022 1023 void stopCast(const bool b) override final; 1024 setCreatorId(const BeingId id)1025 void setCreatorId(const BeingId id) 1026 { mCreatorId = id; } 1027 getCreatorId()1028 BeingId getCreatorId() const noexcept2 A_WARN_UNUSED 1029 { return mCreatorId; } 1030 setKarma(const int karma)1031 void setKarma(const int karma) restrict2 noexcept2 1032 { mKarma = karma; } 1033 getKarma()1034 int getKarma() const restrict2 noexcept2 A_WARN_UNUSED 1035 { return mKarma; } 1036 setManner(const int manner)1037 void setManner(const int manner) restrict2 noexcept2 1038 { mManner = manner; } 1039 getManner()1040 int getManner() const restrict2 noexcept2 A_WARN_UNUSED 1041 { return mManner; } 1042 disableBotAi()1043 void disableBotAi() restrict2 noexcept2 1044 { mBotAi = false; } 1045 enableBotAi()1046 void enableBotAi() restrict2 noexcept2 1047 { mBotAi = true; } 1048 getAreaSize()1049 int getAreaSize() const restrict2 noexcept2 A_WARN_UNUSED 1050 { return mAreaSize; } 1051 setAreaSize(const int areaSize)1052 void setAreaSize(const int areaSize) restrict2 noexcept2 1053 { mAreaSize = areaSize; } 1054 1055 void setTeamId(const uint16_t teamId) restrict2; 1056 1057 void showTeamBadge(const bool show) restrict2; 1058 1059 void showGuildBadge(const bool show) restrict2; 1060 1061 void showClanBadge(const bool show) restrict2; 1062 1063 void showGmBadge(const bool show) restrict2; 1064 1065 void showPartyBadge(const bool show) restrict2; 1066 1067 void showNameBadge(const bool show) restrict2; 1068 1069 void showShopBadge(const bool show) restrict2; 1070 1071 void showInactiveBadge(const bool show) restrict2; 1072 1073 void showAwayBadge(const bool show) restrict2; 1074 1075 void showBadges(const bool show) restrict2; 1076 1077 void setLanguageId(const int lang) restrict2 noexcept2; 1078 getLanguageId()1079 int getLanguageId() restrict2 noexcept2 A_WARN_UNUSED 1080 { return mLanguageId; } 1081 getTeamId()1082 uint16_t getTeamId() const restrict2 noexcept2 A_WARN_UNUSED 1083 { return mTeamId; } 1084 1085 virtual void setGroupId(const int id); 1086 getGroupId()1087 int getGroupId() const noexcept2 A_WARN_UNUSED 1088 { return mGroupId; } 1089 1090 void serverRemove() restrict2 noexcept2; 1091 1092 void addCast(const int dstX, 1093 const int dstY, 1094 const int skillId, 1095 const int skillLevel, 1096 const int range, 1097 const int waitTimeTicks); 1098 1099 void fixDirectionOffsets(int &offsetX, 1100 int &offsetY) const; 1101 getAllowNpcEquipment()1102 bool getAllowNpcEquipment() const noexcept2 A_WARN_UNUSED 1103 { return mAllowNpcEquipment; } 1104 1105 static Being *createBeing(const BeingId id, 1106 const ActorTypeT type, 1107 const BeingTypeId subtype, 1108 Map *const map); 1109 1110 protected: 1111 void drawPlayerSpriteAt(Graphics *restrict const graphics, 1112 const int x, 1113 const int y) const restrict2 A_NONNULL(2); 1114 1115 void drawOtherSpriteAt(Graphics *restrict const graphics, 1116 const int x, 1117 const int y) const restrict2 A_NONNULL(2); 1118 1119 void drawNpcSpriteAt(Graphics *restrict const graphics, 1120 const int x, 1121 const int y) const restrict2 A_NONNULL(2); 1122 1123 void drawPortalSpriteAt(Graphics *restrict const graphics, 1124 const int x, 1125 const int y) const restrict2 A_NONNULL(2); 1126 1127 void drawMonsterSpriteAt(Graphics *restrict const graphics, 1128 const int x, 1129 const int y) const restrict2 A_NONNULL(2); 1130 1131 void drawHomunculusSpriteAt(Graphics *restrict const graphics, 1132 const int x, 1133 const int y) const restrict2 A_NONNULL(2); 1134 1135 void drawMercenarySpriteAt(Graphics *restrict const graphics, 1136 const int x, 1137 const int y) const restrict2 A_NONNULL(2); 1138 1139 void drawElementalSpriteAt(Graphics *restrict const graphics, 1140 const int x, 1141 const int y) const restrict2 A_NONNULL(2); 1142 1143 void drawCompound(Graphics *const graphics, 1144 const int posX, 1145 const int posY) const A_NONNULL(2); 1146 1147 /** 1148 * Updates name's location. 1149 */ 1150 virtual void updateCoords() restrict2; 1151 1152 void showName() restrict2; 1153 1154 void addItemParticles(const int id, 1155 const SpriteDisplay &restrict display) restrict2; 1156 1157 void addItemParticlesCards(const int id, 1158 const SpriteDisplay &restrict display, 1159 const CardsList &restrict cards) restrict2; 1160 1161 void removeAllItemsParticles() restrict2; 1162 1163 void removeItemParticles(const int id) restrict2; 1164 1165 void createSpeechBubble() restrict2; 1166 1167 void setDefaultNameColor(const UserColorIdT defaultColor) restrict2; 1168 1169 void updateBadgesCount() restrict2; 1170 1171 static int getDefaultEffectId(const AttackTypeT &restrict type); 1172 1173 BeingInfo *restrict mInfo; 1174 AnimatedSprite *restrict mEmotionSprite; 1175 AnimatedSprite *restrict mAnimationEffect; 1176 CastingEffect *restrict mCastingEffect; 1177 AnimatedSprite *restrict mBadges[BadgeIndex::BadgeIndexSize]; 1178 1179 std::string mSpriteAction; 1180 std::string mName; /**< Name of being */ 1181 std::string mExtName; /**< Full name of being */ 1182 std::string mRaceName; 1183 std::string mPartyName; 1184 std::string mGuildName; 1185 std::string mClanName; 1186 std::string mSpeech; 1187 1188 /** 1189 * Holds a text object when the being displays it's name, 0 otherwise 1190 */ 1191 FlashText *restrict mDispName; 1192 const Color *restrict mNameColor; 1193 1194 /** Engine-related infos about weapon. */ 1195 const ItemInfo *restrict mEquippedWeapon; 1196 1197 Path mPath; 1198 Text *restrict mText; 1199 const Color *restrict mTextColor; 1200 1201 Vector mDest; /**< destination coordinates. */ 1202 1203 typedef std::map<int, ParticleInfo*> SpriteParticleInfo; 1204 typedef SpriteParticleInfo::iterator SpriteParticleInfoIter; 1205 1206 STD_VECTOR<BeingSlot> mSlots; 1207 SpriteParticleInfo mSpriteParticles; 1208 1209 // Character guild information 1210 std::map<int, Guild*> mGuilds; 1211 Party *mParty; 1212 1213 int mActionTime; /**< Time spent in current action */ 1214 int mEmotionTime; /**< Time until emotion disappears */ 1215 1216 /** Time until the last speech sentence disappears */ 1217 int mSpeechTime; 1218 int mAttackSpeed; /**< Attack speed */ 1219 1220 int mLevel; 1221 int mGroupId; 1222 int mAttackRange; 1223 int mLastAttackX; 1224 int mLastAttackY; 1225 1226 int mPreStandTime; 1227 1228 GenderT mGender; 1229 BeingActionT mAction; 1230 BeingTypeId mSubType; /**< Subtype (graphical view, basically) */ 1231 uint8_t mDirection; /**< Facing direction */ 1232 uint8_t mDirectionDelayed; /**< Facing direction */ 1233 SpriteDirection::Type mSpriteDirection; /**< Facing direction */ 1234 bool mShowName; 1235 bool mIsGM; 1236 1237 protected: 1238 void postInit(const BeingTypeId subType, 1239 Map *const map); 1240 1241 void updateBadgesPosition(); 1242 1243 /** 1244 * Calculates the offset in the given directions. 1245 * If walking in direction 'neg' the value is negated. 1246 */ 1247 template<signed char pos, signed char neg> 1248 int getOffset() const restrict2 A_WARN_UNUSED; 1249 1250 int searchSlotValue(const STD_VECTOR<int> &restrict slotRemap, 1251 const int val) const restrict2 A_WARN_UNUSED; 1252 1253 static void searchSlotValueItr(STD_VECTOR<int>::iterator &restrict it, 1254 int &idx, 1255 STD_VECTOR<int> &restrict slotRemap, 1256 const int val); 1257 1258 void addSpiritBalls(const unsigned int balls, 1259 const int effectId) restrict2; 1260 1261 void removeSpiritBalls(const unsigned int balls) restrict2; 1262 1263 void dumpSprites() const restrict2; 1264 1265 void drawBeingCursor(Graphics *const graphics, 1266 const int offsetX, 1267 const int offsetY) const A_NONNULL(2); 1268 1269 void drawCasting(Graphics *const graphics, 1270 const int offsetX, 1271 const int offsetY) const A_NONNULL(2); 1272 1273 void updateBotFollow(int dstX, 1274 int dstY, 1275 const int divX, 1276 const int divY); 1277 1278 void moveBotTo(int dstX, 1279 int dstY); 1280 1281 void updateBotDirection(const int dstX, 1282 const int dstY); 1283 1284 void botFixOffset(int &restrict dstX, 1285 int &restrict dstY) const; 1286 1287 const ActorTypeT mType; 1288 1289 /** Speech Bubble components */ 1290 SpeechBubble *restrict mSpeechBubble; 1291 1292 /** 1293 * Walk speed for x and y movement values. 1294 * In pixels per second. 1295 * @see MILLISECONDS_IN_A_TICK 1296 */ 1297 int mWalkSpeed; 1298 int mSpeed; 1299 std::string mIp; 1300 int *restrict mSpriteRemap A_NONNULLPOINTER; 1301 int *restrict mSpriteHide A_NONNULLPOINTER; 1302 int *restrict mSpriteDraw A_NONNULLPOINTER; 1303 std::string mComment; 1304 std::string mBuyBoard; 1305 std::string mSellBoard; 1306 Being *restrict mOwner; 1307 Particle *restrict mSpecialParticle; 1308 ChatObject *restrict mChat; 1309 HorseInfo *restrict mHorseInfo; 1310 STD_VECTOR<AnimatedSprite*> mDownHorseSprites; 1311 STD_VECTOR<AnimatedSprite*> mUpHorseSprites; 1312 STD_VECTOR<Particle*> mSpiritParticles; 1313 1314 int mX; // position in tiles 1315 int mY; // position in tiles 1316 int mCachedX; 1317 int mCachedY; 1318 int mSortOffsetY; // caculated offset in pixels based on mPixelOffsetY 1319 int mPixelOffsetY; // tile height offset in pixels 1320 // calculated between tiles 1321 int mFixedOffsetY; // fixed tile height offset in pixels for tile 1322 uint8_t mOldHeight; 1323 1324 int mDamageTaken; 1325 int mHP; 1326 int mMaxHP; 1327 int mDistance; 1328 ReachableT mReachable; 1329 int mGoodStatus; 1330 1331 static time_t mUpdateConfigTime; 1332 static unsigned int mConfLineLim; 1333 static int mSpeechType; 1334 static bool mHighlightMapPortals; 1335 static bool mHighlightMonsterAttackRange; 1336 static bool mLowTraffic; 1337 static bool mDrawHotKeys; 1338 static bool mShowBattleEvents; 1339 static bool mShowMobHP; 1340 static bool mShowOwnHP; 1341 static bool mShowGender; 1342 static bool mShowLevel; 1343 static bool mShowPlayersStatus; 1344 static bool mEnableReorderSprites; 1345 static bool mHideErased; 1346 static Move mMoveNames; 1347 static bool mUseDiagonal; 1348 static BadgeDrawType::Type mShowBadges; 1349 static int mAwayEffect; 1350 static VisibleNamePos::Type mVisibleNamePos; 1351 1352 time_t mMoveTime; 1353 time_t mAttackTime; 1354 time_t mTalkTime; 1355 time_t mOtherTime; 1356 time_t mTestTime; 1357 int mAttackDelay; 1358 int mMinHit; 1359 int mMaxHit; 1360 int mCriticalHit; 1361 unsigned int mPvpRank; 1362 unsigned int mNumber; 1363 unsigned int mSpiritBalls; 1364 int mUsageCounter; 1365 int mKarma; 1366 int mManner; 1367 int mAreaSize; 1368 int mCastEndTime; 1369 int mLanguageId; 1370 int mBadgesX; 1371 int mBadgesY; 1372 BeingId mCreatorId; 1373 uint16_t mTeamId; 1374 uint16_t mLook; 1375 uint16_t mBadgesCount; 1376 ItemColor mHairColor; 1377 bool mErased; 1378 bool mEnemy; 1379 bool mGotComment; 1380 bool mAdvanced; 1381 bool mShop; 1382 bool mAway; 1383 bool mInactive; 1384 bool mNeedPosUpdate; 1385 bool mBotAi; 1386 bool mAllowNpcEquipment; 1387 }; 1388 1389 extern std::list<BeingCacheEntry*> beingInfoCache; 1390 1391 #endif // BEING_BEING_H 1392