3
* Copyright (C) 2004-2009 The Mana World Development Team
4
* Copyright (C) 2009-2010 The Mana Developers
5
* Copyright (C) 2011-2013 The ManaPlus Developers
7
* This file is part of The ManaPlus Client.
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program. If not, see <http://www.gnu.org/licenses/>.
26
#include "equipment.h"
28
#include "resources/beinginfo.h"
30
#include <guichan/color.hpp>
32
#include <SDL_types.h>
37
#include "localconsts.h"
39
static const unsigned int FIRST_IGNORE_EMOTE = 14;
40
static const unsigned int STATUS_EFFECTS = 32;
42
static const unsigned int SPEECH_TIME = 500;
43
static const unsigned int SPEECH_MIN_TIME = 200;
44
static const unsigned int SPEECH_MAX_TIME = 800;
46
static const int DEFAULT_BEING_WIDTH = 32;
47
static const int DEFAULT_BEING_HEIGHT = 32;
50
class BeingCacheEntry;
64
extern volatile int cur_time;
70
GENDER_UNSPECIFIED = 2,
85
const SoundInfo *sound;
91
class Being : public ActorSprite, public ConfigListener
94
friend class BeingEquipBackend;
95
friend class LocalPlayer;
102
FLAG_GENDER_OTHER = 32,
104
FLAG_GENDER_MALE = 128,
105
FLAG_SPECIAL = 128 + 64
109
* Action the being is currently performing
110
* WARNING: Has to be in sync with the same enum in the Being class
140
MISS = 0xffff // pseudo value for miss attacks
151
* Directions, to be used as bitmask values
164
* @param id a unique being id
165
* @param subtype partly determines the type of the being
166
* @param map the map the being is on
168
Being(const int id, const Type type, const uint16_t subtype,
175
Type getType() const A_WARN_UNUSED
179
* Removes all path nodes from this being.
184
* Returns the time spent in the current action.
186
int getActionTime() const A_WARN_UNUSED
187
{ return mActionTime; }
190
* Set the current action time.
191
* @see Ea::BeingHandler that set it to tick time.
193
void setActionTime(const int actionTime)
194
{ mActionTime = actionTime; }
197
* Makes this being take the next tile of its path.
198
* TODO: Used by eAthena only?
200
virtual void nextTile();
203
* Get the current X pixel offset.
204
* TODO: Used by eAthena only?
206
int getXOffset() const A_WARN_UNUSED
207
{ return getOffset(LEFT, RIGHT); }
210
* Get the current Y pixel offset.
211
* TODO: Used by eAthena only?
213
int getYOffset() const A_WARN_UNUSED
214
{ return getOffset(UP, DOWN); }
217
* Creates a path for the being from current position to ex and ey
219
void setDestination(const int dstX, const int dstY);
222
* Returns the destination for this being.
224
const Vector &getDestination() const A_WARN_UNUSED
228
* Returns the tile x coord
230
int getTileX() const A_WARN_UNUSED
234
* Returns the tile y coord
236
int getTileY() const A_WARN_UNUSED
240
* Sets the tile x and y coord
242
void setTileCoords(const int x, const int y)
246
* Puts a "speech balloon" above this being for the specified amount
249
* @param text The text that should appear.
250
* @param time The amount of time the text should stay in milliseconds.
252
void setSpeech(const std::string &text,
253
const std::string &channel = "",
257
* Puts a damage bubble above this being.
259
* @param attacker the attacking being
260
* @param damage the amount of damage recieved (0 means miss)
261
* @param type the attack type
264
void takeDamage(Being *const attacker, const int damage,
265
const AttackType type, const int attackId = 1);
268
* Handles an attack of another being by this being.
270
* @param victim the victim being
271
* @param damage the amount of damage dealt (0 means miss)
272
* @param type the attack type
274
void handleAttack(Being *const victim, const int damage,
275
const int attackId = 1);
277
virtual void handleSkill(Being *const victim, const int damage,
278
const int skillId, const int skillLevel);
280
const ItemInfo *getEquippedWeapon() const A_WARN_UNUSED
281
{ return mEquippedWeapon; }
284
* Returns the name of the being.
286
const std::string &getName() const A_WARN_UNUSED
290
* Sets the name for the being.
292
* @param name The name that should appear.
294
void setName(const std::string &name);
296
bool getShowName() const A_WARN_UNUSED
297
{ return mShowName; }
299
void setShowName(const bool doShowName);
302
* Sets the name of the party the being is in. Shown in BeingPopup.
304
void setPartyName(const std::string &name)
305
{ mPartyName = name; }
307
const std::string &getPartyName() const A_WARN_UNUSED
308
{ return mPartyName; }
310
const std::string &getGuildName() const A_WARN_UNUSED
311
{ return mGuildName; }
314
* Sets the name of the primary guild the being is in. Shown in
315
* BeingPopup (eventually).
317
void setGuildName(const std::string &name);
319
void setGuildPos(const std::string &pos);
322
* Adds a guild to the being.
324
void addGuild(Guild *const guild);
327
* Removers a guild from the being.
329
void removeGuild(const int id);
332
* Returns a pointer to the specified guild that the being is in.
334
Guild *getGuild(const std::string &guildName) const A_WARN_UNUSED;
337
* Returns a pointer to the specified guild that the being is in.
339
Guild *getGuild(const int id) const A_WARN_UNUSED;
342
* Returns a pointer to the specified guild that the being is in.
344
Guild *getGuild() const A_WARN_UNUSED;
347
* Returns all guilds the being is in.
349
const std::map<int, Guild*> &getGuilds() const A_WARN_UNUSED
353
* Removes all guilds the being is in.
358
* Get number of guilds the being belongs to.
360
int16_t getNumberOfGuilds() const A_WARN_UNUSED
361
{ return static_cast<int16_t>(mGuilds.size()); }
363
bool isInParty() const A_WARN_UNUSED
366
void setParty(Party *const party);
368
void setGuild(Guild *const guild);
372
Party *getParty() const A_WARN_UNUSED
375
int getSpritesCount() const A_WARN_UNUSED
376
{ return static_cast<int>(size()); }
379
* Sets visible equipments for this being.
381
void setSprite(const unsigned int slot, const int id,
382
std::string color = "",
383
const unsigned char colorId = 1,
384
const bool isWeapon = false,
385
const bool isTempSprite = false);
387
void setSpriteID(const unsigned int slot, const int id);
389
void setSpriteColor(const unsigned int slot,
390
const std::string &color = "");
393
* Get the number of hairstyles implemented
395
static int getNumOfHairstyles() A_WARN_UNUSED
396
{ return mNumberOfHairstyles; }
399
* Get the number of races implemented
401
static int getNumOfRaces() A_WARN_UNUSED
402
{ return mNumberOfRaces; }
405
* Get the number of layers used to draw the being
407
int getNumberOfLayers() const A_WARN_UNUSED
408
{ return CompoundSprite::getNumberOfLayers(); }
411
* Performs being logic.
413
virtual void logic() override;
416
* Draws the speech text above the being.
418
void drawSpeech(const int offsetX, const int offsetY);
421
* Draws the emotion picture above the being.
423
void drawEmotion(Graphics *const graphics, const int offsetX,
426
uint16_t getSubType() const
430
* Set Being's subtype (mostly for view for monsters and NPCs)
432
void setSubtype(const uint16_t subtype, const uint8_t look);
434
const BeingInfo *getInfo() const A_WARN_UNUSED
437
TargetCursorSize getTargetCursorSize() const A_WARN_UNUSED;
439
int getTargetOffsetX() const A_WARN_UNUSED
443
return mInfo->getTargetOffsetX();
446
int getTargetOffsetY() const A_WARN_UNUSED
450
return mInfo->getTargetOffsetY();
454
* Gets the way the object is blocked by other objects.
456
virtual unsigned char getWalkMask() const A_WARN_UNUSED
460
return mInfo->getWalkMask();
464
* Gets the way the monster blocks pathfinding for other objects
466
Map::BlockType getBlockType() const A_WARN_UNUSED
469
return Map::BLOCKTYPE_NONE;
470
return mInfo->getBlockType();
474
* Sets the walk speed.
475
* in pixels per second for eAthena,
476
* in tiles per second for Manaserv.
478
void setWalkSpeed(const Vector &speed)
479
{ mWalkSpeed = speed; }
482
* Gets the walk speed.
483
* in pixels per second for eAthena,
484
* in tiles per second for Manaserv (0.1 precision).
486
Vector getWalkSpeed() const A_WARN_UNUSED
487
{ return mWalkSpeed; }
490
* Sets the attack speed.
491
* @todo In what unit?
493
void setAttackSpeed(const int speed)
494
{ mAttackSpeed = speed; }
497
* Gets the attack speed.
498
* @todo In what unit?
500
int getAttackSpeed() const A_WARN_UNUSED
501
{ return mAttackSpeed; }
504
* Sets the current action.
506
virtual void setAction(const Action &action, const int attackType = 0);
509
* Get the being's action currently performed.
511
Action getCurrentAction() const A_WARN_UNUSED
515
* Returns whether this being is still alive.
517
bool isAlive() const A_WARN_UNUSED
518
{ return mAction != DEAD; }
521
* Returns the current direction.
523
uint8_t getDirection() const A_WARN_UNUSED
524
{ return mDirection; }
527
* Sets the current direction.
529
virtual void setDirection(const uint8_t direction);
531
virtual void setDirectionDelayed(const uint8_t direction)
532
{ mDirectionDelayed = direction; }
534
uint8_t getDirectionDelayed() const A_WARN_UNUSED
535
{ return mDirectionDelayed; }
538
* Returns the direction the being is facing.
540
SpriteDirection getSpriteDirection() const A_WARN_UNUSED
541
{ return static_cast<SpriteDirection>(mSpriteDirection); }
543
void setPosition(const Vector &pos);
546
* Overloaded method provided for convenience.
548
* @see setPosition(const Vector &pos)
550
inline void setPosition(const float x, const float y,
551
const float z = 0.0f)
552
{ setPosition(Vector(x, y, z)); }
555
* Returns the horizontal size of the current base sprite of the being.
557
virtual int getWidth() const override A_WARN_UNUSED
558
{ return std::max(CompoundSprite::getWidth(), DEFAULT_BEING_WIDTH); }
561
* Returns the vertical size of the current base sprite of the being.
563
virtual int getHeight() const override A_WARN_UNUSED
564
{ return std::max(CompoundSprite::getHeight(), DEFAULT_BEING_HEIGHT); }
567
* Returns the being's pixel radius used to detect collisions.
569
virtual int getCollisionRadius() const A_WARN_UNUSED
573
* Shoots a missile particle from this being, to target being
575
void fireMissile(Being *const target,
576
const std::string &particle) const;
579
* Returns the path this being is following. An empty path is returned
580
* when this being isn't following any path currently.
582
const Path &getPath() const A_WARN_UNUSED
585
int getDistance() const A_WARN_UNUSED
586
{ return mDistance; }
588
void setDistance(const int n)
592
* Set the Emoticon type and time displayed above
595
void setEmote(const uint8_t emotion, const int emote_time);
597
void setState(const uint8_t state);
599
virtual void drawSprites(Graphics *const graphics,
600
int posX, int posY) const override;
602
virtual void drawSpritesSDL(Graphics *const graphics,
603
int posX, int posY) const override;
605
void drawHpBar(Graphics *const graphics, const int x, const int y,
606
const int maxHP, const int hp, const int damage,
607
const int color1, const int color2, const int width,
608
const int height) const;
612
virtual void optionChanged(const std::string &value) override;
614
void flashName(const int time);
616
int getDamageTaken() const A_WARN_UNUSED
617
{ return mDamageTaken; }
619
void setDamageTaken(const int damage)
620
{ mDamageTaken = damage; }
624
void setLevel(const int n)
627
virtual int getLevel() const A_WARN_UNUSED
630
void setIsReachable(const int n)
631
{ mIsReachable = n; }
633
int isReachable() const A_WARN_UNUSED
634
{ return mIsReachable; }
636
static void reReadConfig();
638
static BeingCacheEntry* getCacheEntry(const int id) A_WARN_UNUSED;
640
void addToCache() const;
642
bool updateFromCache();
645
* Sets the gender of this being.
647
virtual void setGender(const Gender gender);
649
Gender getGender() const A_WARN_UNUSED
653
* Return sprite sit action for current environment.
655
std::string getSitAction() const A_WARN_UNUSED;
657
std::string getMoveAction() const A_WARN_UNUSED;
659
std::string getDeadAction() const A_WARN_UNUSED;
661
std::string getStandAction() const A_WARN_UNUSED;
663
std::string getSpawnAction() const A_WARN_UNUSED;
665
std::string getWeaponAttackAction(const ItemInfo *const weapon) const;
667
std::string getAttackAction(const Attack *const attack) const;
670
* Whether or not this player is a GM.
672
bool isGM() const A_WARN_UNUSED
676
* Triggers whether or not to show the name as a GM name.
678
void setGM(const bool gm);
680
bool canTalk() const A_WARN_UNUSED
681
{ return mType == NPC; }
685
bool draw(Graphics *const graphics,
686
const int offsetX, const int offsetY) const override;
688
bool drawSpriteAt(Graphics *const graphics,
689
const int x, const int y) const;
692
{ mMoveTime = cur_time; }
695
{ mAttackTime = cur_time; }
698
{ mTalkTime = cur_time; }
701
{ mTestTime = cur_time; }
704
{ mOtherTime = cur_time; }
706
unsigned int getMoveTime() const
707
{ return mMoveTime; }
709
unsigned int getAttackTime() const
710
{ return mAttackTime; }
712
unsigned int getTalkTime() const
713
{ return mTalkTime; }
715
unsigned int getTestTime() const
716
{ return mTestTime; }
718
unsigned int getOtherTime() const
719
{ return mOtherTime; }
721
void resetCounters();
723
virtual void updateColors();
725
void setEnemy(const bool n)
728
const std::string &getIp() const A_WARN_UNUSED
731
void setIp(std::string ip)
734
unsigned int getPvpRank() const A_WARN_UNUSED
737
void setPvpRank(const unsigned int rank)
740
void setHP(const int n);
742
void setMaxHP(const int hp);
744
int getHP() const A_WARN_UNUSED
747
uint8_t calcDirection(const int dstX,
748
const int dstY) const A_WARN_UNUSED;
750
uint8_t calcDirection() const A_WARN_UNUSED;
752
void setAttackDelay(const int n)
753
{ mAttackDelay = n; }
755
int getAttackDelay() const A_WARN_UNUSED
756
{ return mAttackDelay; }
758
int getMinHit() const A_WARN_UNUSED
761
void setMinHit(const int n)
764
int getMaxHit() const A_WARN_UNUSED
767
void setMaxHit(const int n)
770
int getCriticalHit() const A_WARN_UNUSED
771
{ return mCriticalHit; }
773
void setCriticalHit(const int n)
774
{ mCriticalHit = n; }
776
void updateHit(const int amount);
778
Equipment *getEquipment() A_WARN_UNUSED;
780
void undressItemById(const int id);
782
int getGoodStatus() const A_WARN_UNUSED
783
{ return mGoodStatus; }
785
void setGoodStatus(const int n)
788
std::string getGenderSign() const A_WARN_UNUSED;
790
std::string getGenderSignWithSpace() const A_WARN_UNUSED;
792
void updateComment();
794
const std::string getComment() const A_WARN_UNUSED
797
void setComment(std::string n)
800
static void clearCache();
802
static std::string loadComment(const std::string &name,
803
const int type) A_WARN_UNUSED;
805
static void saveComment(const std::string &name,
806
const std::string &comment, const int type);
808
bool isAdvanced() const A_WARN_UNUSED
809
{ return mAdvanced; }
811
void setAdvanced(const bool n)
812
{ mAdvanced = n; addToCache(); }
814
bool isShopEnabled() const A_WARN_UNUSED
817
void enableShop(const bool b)
821
* Sets the attack range.
823
void setAttackRange(const int range)
824
{ mAttackRange = range; }
826
void attack(Being *target = nullptr, bool keep = false,
827
bool dontChangeEquipment = false);
829
void attack2(Being *target = nullptr, bool keep = false,
830
bool dontChangeEquipment = false);
832
void updatePercentHP();
834
void setRaceName(std::string name)
835
{ mRaceName = name; }
837
std::string getRaceName() const A_WARN_UNUSED
838
{ return mRaceName; }
840
int getSpriteID(const int slot) const A_WARN_UNUSED;
842
void setHairStyle(const unsigned int slot, const int id);
844
void setHairColor(const unsigned int slot,
845
const unsigned char color);
847
void setHairColor(const unsigned char color)
848
{ mHairColor = color; }
850
unsigned char getHairColor() const A_WARN_UNUSED
851
{ return mHairColor; }
853
void recalcSpritesOrder();
855
int getHitEffect(const Being *const attacker,
856
const AttackType type,
857
const int attackId) const A_WARN_UNUSED;
859
Cursor::Cursor getHoverCursor() const A_WARN_UNUSED
860
{ return mInfo ? mInfo->getHoverCursor() : Cursor::CURSOR_POINTER; }
864
void removeAfkEffect();
866
void updateAwayEffect();
868
void addSpecialEffect(const int effect);
870
void removeSpecialEffect();
872
void addEffect(const std::string &name);
874
void addPet(const int id);
883
void setPet(Being *const pet)
886
void setOwner(Being *const owner)
889
void playSfx(const SoundInfo &sound, Being *const being,
890
const bool main, const int x, const int y);
895
void setLook(const int look);
897
static uint8_t genderToInt(const Gender sex) A_WARN_UNUSED;
899
static Gender intToGender(uint8_t sex) A_WARN_UNUSED;
901
NextSoundInfo mNextSound;
905
* Sets the new path for this being.
907
void setPath(const Path &path);
910
* Updates name's location.
912
virtual void updateCoords();
916
static int getDefaultEffectId(const int type);
919
AnimatedSprite *mEmotionSprite;
920
AnimatedSprite* mAnimationEffect;
922
std::string mSpriteAction;
923
std::string mName; /**< Name of character */
924
std::string mRaceName;
925
std::string mPartyName;
926
std::string mGuildName;
930
* Holds a text object when the being displays it's name, 0 otherwise
932
FlashText *mDispName;
933
const gcn::Color *mNameColor;
935
/** Engine-related infos about weapon. */
936
const ItemInfo *mEquippedWeapon;
938
static int mNumberOfHairstyles; /** Number of hair styles in use */
939
static int mNumberOfRaces; /** Number of races in use */
943
const gcn::Color *mTextColor;
945
Vector mDest; /**< destination coordinates. */
947
StringVect mSpriteColors;
948
std::vector<int> mSpriteIDs;
949
std::vector<int> mSpriteColorsIds;
951
// Character guild information
952
std::map<int, Guild*> mGuilds;
955
int mActionTime; /**< Time spent in current action */
956
int mEmotionTime; /**< Time until emotion disappears */
958
/** Time until the last speech sentence disappears */
960
int mAttackSpeed; /**< Attack speed */
965
Action mAction; /**< Action the being is performing */
966
uint16_t mSubType; /**< Subtype (graphical view, basically) */
967
uint8_t mDirection; /**< Facing direction */
968
uint8_t mDirectionDelayed; /**< Facing direction */
969
uint8_t mSpriteDirection; /**< Facing direction */
975
* Calculates the offset in the given directions.
976
* If walking in direction 'neg' the value is negated.
977
* TODO: Used by eAthena only?
979
int getOffset(const signed char pos,
980
const signed char neg) const A_WARN_UNUSED;
982
int searchSlotValue(const std::vector<int> &slotRemap,
983
const int val) const A_WARN_UNUSED;
985
void searchSlotValueItr(std::vector<int>::iterator &it, int &idx,
986
std::vector<int> &slotRemap,
987
const int val) const;
989
void dumpSprites() const;
993
/** Speech Bubble components */
994
SpeechBubble *mSpeechBubble;
997
* Walk speed for x and y movement values.
998
* In pixels per second for eAthena,
999
* In pixels per ticks for Manaserv.
1000
* @see MILLISECONDS_IN_A_TICK
1006
std::string mComment;
1009
Particle *mSpecialParticle;
1011
int mX, mY; /**< Position in tile */
1017
int mIsReachable; /**< 0 - unknown, 1 - reachable, 2 - not reachable*/
1020
static int mUpdateConfigTime;
1021
static unsigned int mConfLineLim;
1022
static int mSpeechType;
1023
static bool mHighlightMapPortals;
1024
static bool mHighlightMonsterAttackRange;
1025
static bool mLowTraffic;
1026
static bool mDrawHotKeys;
1027
static bool mShowBattleEvents;
1028
static bool mShowMobHP;
1029
static bool mShowOwnHP;
1030
static bool mShowGender;
1031
static bool mShowLevel;
1032
static bool mShowPlayersStatus;
1033
static bool mEnableReorderSprites;
1034
static bool mHideErased;
1035
static bool mMoveNames;
1036
static int mAwayEffect;
1038
unsigned int mMoveTime;
1039
unsigned int mAttackTime;
1040
unsigned int mTalkTime;
1041
unsigned int mOtherTime;
1042
unsigned int mTestTime;
1047
unsigned int mPvpRank;
1048
unsigned int mNumber;
1051
unsigned char mHairColor;
1061
extern std::list<BeingCacheEntry*> beingInfoCache;