50static const float POS_DEST_DIFF_TOLERANCE = 48.0f;
55 static const Uint16 _messages[] =
84 if (job <= 25 || (job >= 4001 && job <= 4049))
86 if (job >= 46 && job <= 1000)
88 if (job > 1000 && job <= 2000)
96static Being *createBeing(
int id,
short job)
98 const auto type = typeFromJob(job);
107 outMsg.writeInt32(
id);
119static void updateBeingType(
Being *being,
short job)
121 const auto type = typeFromJob(job);
122 const bool typeChanged = being->
getType() != type;
129 outMsg.writeInt32(being->
getId());
133static void handleMoveMessage(
Map *map,
Being *dstBeing,
134 Uint16 srcX, Uint16 srcY,
135 Uint16 dstX, Uint16 dstY)
138 if (map && dstBeing && srcX && srcY && dstX && dstY)
147 if (std::abs(beingPos.
x - pos.
x) > POS_DEST_DIFF_TOLERANCE
148 || std::abs(beingPos.
y - pos.
y) > POS_DEST_DIFF_TOLERANCE)
155static void handlePosMessage(
Map *map,
Being *dstBeing, Uint16 x, Uint16 y,
159 if (map && dstBeing && x && y)
166 if (std::abs(beingPos.
x - pos.
x) > POS_DEST_DIFF_TOLERANCE
167 || std::abs(beingPos.
y - pos.
y) > POS_DEST_DIFF_TOLERANCE)
178static void applyStatusEffectsByOption1(
Being *being,
182 for (
auto &[opt,
id] : map)
183 being->setStatusEffect(id, option == opt);
186static void applyStatusEffectsByOption(
Being *being,
190 for (
auto &[opt,
id] : map)
192 const bool enabled = (option & opt) != 0;
201static void applyStatusEffects(
Being *being,
205 std::optional<uint16_t> opt3 = {})
223 Uint16 headTop, headMid, headBottom;
224 Uint16 shoes, gloves;
225 Uint16 weapon, shield;
234 Being *srcBeing, *dstBeing;
235 int hairStyle, hairColor, flag;
258 if (job == 0 &&
id >= 110000000)
263 dstBeing = createBeing(
id, job);
280 updateBeingType(dstBeing, job);
328 Uint16 srcX, srcY, dstX, dstY;
330 handleMoveMessage(map, dstBeing, srcX, srcY, dstX, dstY);
337 handlePosMessage(map, dstBeing, x, y, dir);
344 applyStatusEffects(dstBeing, opt0, opt1, opt2, opt3);
400 if (attackSpeed && srcBeing && srcBeing !=
local_player)
486 updateBeingType(dstBeing,
id);
491 const int hair =
id % 256;
534 Log::info(
"SMSG_BEING_CHANGE_LOOKS2: unsupported type: "
535 "%d, id: %d",
static_cast<int>(type),
id);
585 dstBeing = createBeing(
id, job);
592 if (party->isMember(
id))
601 updateBeingType(dstBeing, job);
641 Uint16 srcX, srcY, dstX, dstY;
643 handleMoveMessage(map, dstBeing, srcX, srcY, dstX, dstY);
650 handlePosMessage(map, dstBeing, x, y, dir);
655 dstBeing->
setGM(
true);
678 applyStatusEffects(dstBeing, opt0, opt1, opt2, opt3);
702 handlePosMessage(map, dstBeing, x, y);
728 applyStatusEffects(dstBeing, opt0, opt1, opt2);
ActorSpriteManager * actorSpriteManager
Being * createBeing(int id, ActorSprite::Type type, int subtype)
Create a Being and add it to the list of ActorSprites.
void destroyActor(ActorSprite *actor)
Immediately destroys the given actor.
Being * findBeing(int id) const
Returns a specific Being, by id;.
const Vector & getPosition() const
Returns the pixel position of this actor.
void setPosition(const Vector &pos) final
Sets the pixel position of this actor.
void setStatusEffect(int id, bool active)
void setSprite(unsigned slot, int id, const std::string &color=std::string(), bool isWeapon=false)
Sets visible equipments for this being.
void setDestination(int ex, int ey)
Creates a path for the being from current position to ex and ey.
void setGuildName(const std::string &name)
Sets the name of the primary guild the being is in.
void setMoveSpeed(const Vector &speed)
Sets the move speed.
void setDirection(uint8_t direction)
Sets the current direction.
Type getType() const final
Returns the type of the ActorSprite.
void setSpriteColor(unsigned slot, const std::string &color=std::string())
void setName(const std::string &name)
Sets the name for the being.
void setAttackSpeed(int speed)
Sets the attack speed.
void setGM(bool gm)
Triggers whether or not to show the name as a GM name.
void setGuildPos(const std::string &pos)
void setPartyName(const std::string &name)
Sets the name of the party the being is in.
virtual void setAction(Action action, int attackId=1)
Sets the current action.
void setType(Type type, int subtype)
Can be used to change the type of the being.
void setParty(Party *party)
void handleAttack(Being *victim, int damage, int attackId=1)
Handles an attack of another being by this being.
void setGender(Gender gender)
Sets the gender of this being.
void addGuild(Guild *guild)
Adds a guild to the being.
void takeDamage(Being *attacker, int damage, AttackType type, int attackId=1)
Puts a damage bubble above this being.
void clearPath()
Removes all path nodes from this being.
void setSpriteID(unsigned slot, int id)
void clearGuilds()
Removes all guilds the being is in.
bool trigger(int id, Being *being, int rotation=0)
Triggers a effect with the id, at the specified being, and with the given rotation in degree: 0° = Do...
Map * getCurrentMap()
Returns the currently active map.
static Game * instance()
Provides access to the game instance.
static Guild * getGuild(int id)
const std::string & getHairColor(int id) const
Being * getTarget() const
Returns the current target of the player.
Vector getTileCenter(int x, int y) const
Returns the tile center position in pixel coordinates.
const uint16_t * handledMessages
bool hasPermission(Being *being, unsigned int flags)
Tests whether the player in question is being ignored for any of the actions in the specified flags.
static const OptionsMap & opt2ToIdMap()
static const OptionsMap & opt0ToIdMap()
These map flags or indexes to their corresponding status effect ID.
static const OptionsMap & opt3ToIdMap()
std::map< uint16_t, int > OptionsMap
static const OptionsMap & opt1ToIdMap()
void handleMessage(MessageIn &msg) override
BeingHandler(bool enableSync)
Used for parsing an incoming message from eAthena.
std::string readString(int length=-1)
Reads a string.
void readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction)
Reads a special 3 byte block used by eAthena, containing x and y coordinates and direction.
uint16_t readInt16()
Reads an unsigned 16-bit integer from the message.
uint8_t readInt8()
Reads an unsigned 8-bit integer from the message.
void readCoordinatePair(uint16_t &srcX, uint16_t &srcY, uint16_t &dstX, uint16_t &dstY)
Reads a special 5 byte block used by eAthena, containing a source and destination coordinate pair.
uint16_t getId() const
Returns the message ID.
uint32_t readInt32()
Reads an unsigned 32-bit integer from the message.
HairDB hairDB
Hair styles and colors info database.
EffectManager * effectManager
LocalPlayer * local_player
Net::PlayerHandler * playerHandler
const Emote & get(int id)
void info(const char *log_text,...) LOG_PRINTF_ATTR
PlayerHandler * getPlayerHandler()
Warning: buffers and other variables are shared, so there can be only one connection active at a time...
@ SMSG_BEING_CHANGE_DIRECTION
@ SMSG_BEING_NAME_RESPONSE
@ SMSG_PLAYER_MOVE_TO_ATTACK
@ SMSG_BEING_CHANGE_LOOKS2
@ SMSG_PLAYER_GUILD_PARTY_INFO
@ SMSG_PLAYER_STATUS_CHANGE
@ SMSG_BEING_STATUS_CHANGE
Gender sexToGender(SEX sex)
PlayerRelationsManager player_relations