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