summaryrefslogtreecommitdiff
path: root/src/net/beinghandler.cpp
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2008-08-28 18:01:15 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2008-08-28 18:01:15 +0000
commitb506fe0ff8a2039167aa7c349087af4dd03e1921 (patch)
tree36989bca6fa259815f92e1d3553b4cc97d8f8133 /src/net/beinghandler.cpp
parentb98b6256262da9aafd9e8e1f93744db321d4d1ad (diff)
downloadmana-client-b506fe0ff8a2039167aa7c349087af4dd03e1921.tar.gz
mana-client-b506fe0ff8a2039167aa7c349087af4dd03e1921.tar.bz2
mana-client-b506fe0ff8a2039167aa7c349087af4dd03e1921.tar.xz
mana-client-b506fe0ff8a2039167aa7c349087af4dd03e1921.zip
Applied patch put together by Jaxad0127 with changes from the Aethyra project.
Improves compatibility with the newer version of eAthena and works around an initialization bug.
Diffstat (limited to 'src/net/beinghandler.cpp')
-rw-r--r--src/net/beinghandler.cpp145
1 files changed, 122 insertions, 23 deletions
diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp
index be8412d9..c43c674f 100644
--- a/src/net/beinghandler.cpp
+++ b/src/net/beinghandler.cpp
@@ -40,11 +40,13 @@
const int EMOTION_TIME = 150; /**< Duration of emotion icon */
-BeingHandler::BeingHandler()
+BeingHandler::BeingHandler(bool enableSync):
+ mSync(enableSync)
{
static const Uint16 _messages[] = {
SMSG_BEING_VISIBLE,
SMSG_BEING_MOVE,
+ SMSG_BEING_MOVE2,
SMSG_BEING_REMOVE,
SMSG_BEING_ACTION,
SMSG_BEING_LEVELUP,
@@ -55,6 +57,8 @@ BeingHandler::BeingHandler()
SMSG_PLAYER_UPDATE_1,
SMSG_PLAYER_UPDATE_2,
SMSG_PLAYER_MOVE,
+ SMSG_PLAYER_STOP,
+ SMSG_PLAYER_MOVE_TO_ATTACK,
0x0119,
0
};
@@ -66,6 +70,8 @@ void BeingHandler::handleMessage(MessageIn *msg)
Uint32 id;
Uint16 job, speed;
Uint16 headTop, headMid, headBottom;
+ Uint16 shoes, gloves, cape, misc1, misc2;
+ Uint16 weapon, shield;
Sint16 param1;
Sint8 type;
Being *srcBeing, *dstBeing;
@@ -78,8 +84,8 @@ void BeingHandler::handleMessage(MessageIn *msg)
// Information about a being in range
id = msg->readInt32();
speed = msg->readInt16();
- msg->readInt16(); // unknown
- msg->readInt16(); // unknown
+ msg->readInt16(); // opt1
+ msg->readInt16(); // opt2
msg->readInt16(); // option
job = msg->readInt16(); // class
@@ -122,8 +128,10 @@ void BeingHandler::handleMessage(MessageIn *msg)
headTop = msg->readInt16();
headMid = msg->readInt16();
hairColor = msg->readInt16();
- msg->readInt16(); // clothes color -not used
+ msg->readInt16(); // clothes color - not used
msg->readInt16(); // head dir
+ shoes = 0;
+ gloves = 0;
msg->readInt16(); // guild
msg->readInt16(); // unknown
msg->readInt16(); // unknown
@@ -133,9 +141,11 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setGender(1 - msg->readInt8()); // gender
// Set these after the gender, as the sprites may be gender-specific
- dstBeing->setSprite(Being::BOTTOMCLOTHES_SPRITE, headBottom);
- dstBeing->setSprite(Being::TOPCLOTHES_SPRITE, headMid);
- dstBeing->setSprite(Being::HAT_SPRITE, headTop);
+ dstBeing->setSprite(Being::BOTTOMCLOTHES_SPRITE, headBottom);
+ dstBeing->setSprite(Being::TOPCLOTHES_SPRITE, headMid);
+ dstBeing->setSprite(Being::HAT_SPRITE, headTop);
+ dstBeing->setSprite(Being::SHOE_SPRITE, shoes);
+ dstBeing->setSprite(Being::GLOVES_SPRITE, gloves);
dstBeing->setHairStyle(hairStyle, hairColor);
if (msg->getId() == SMSG_BEING_MOVE)
@@ -159,6 +169,33 @@ void BeingHandler::handleMessage(MessageIn *msg)
msg->readInt8(); // unknown / sit
break;
+ case SMSG_BEING_MOVE2:
+ /*
+ * A simplified movement packet, used by the
+ * later versions of eAthena for both mobs and
+ * players
+ */
+ dstBeing = beingManager->findBeing(msg->readInt32());
+
+ Uint16 srcX, srcY, dstX, dstY;
+ msg->readCoordinatePair(srcX, srcY, dstX, dstY);
+ msg->readInt32(); // Server tick
+
+ /*
+ * This packet doesn't have enough info to actually
+ * create a new being, so if the being isn't found,
+ * we'll just pretend the packet didn't happen
+ */
+
+ if (dstBeing) {
+ dstBeing->setAction(Being::STAND);
+ dstBeing->mX = srcX;
+ dstBeing->mY = srcY;
+ dstBeing->setDestination(dstX, dstY);
+ }
+
+ break;
+
case SMSG_BEING_REMOVE:
// A being should be removed or has died
dstBeing = beingManager->findBeing(msg->readInt32());
@@ -166,6 +203,11 @@ void BeingHandler::handleMessage(MessageIn *msg)
if (!dstBeing)
break;
+ if (dstBeing == player_node->getTarget())
+ {
+ player_node->stopAttack();
+ }
+
if (msg->readInt8() == 1)
{
dstBeing->setAction(Being::DEAD);
@@ -175,10 +217,6 @@ void BeingHandler::handleMessage(MessageIn *msg)
beingManager->destroyBeing(dstBeing);
}
- if (dstBeing == player_node->getTarget())
- {
- player_node->stopAttack();
- }
break;
case SMSG_BEING_ACTION:
@@ -257,7 +295,7 @@ void BeingHandler::handleMessage(MessageIn *msg)
case SMSG_BEING_CHANGE_LOOKS2:
{
/*
- * SMSG_BEING_CHANGE_LOOKS (0x00c3) and
+ * SMSG_BEING_CHANGE_LOOKS (0x00c3) and
* SMSG_BEING_CHANGE_LOOKS2 (0x01d7) do basically the same
* thing. The difference is that ...LOOKS carries a single
* 8 bit value, where ...LOOKS2 carries two 16 bit values.
@@ -288,7 +326,7 @@ void BeingHandler::handleMessage(MessageIn *msg)
case 1: // eAthena LOOK_HAIR
dstBeing->setHairStyle(id, -1);
break;
- case 2: // Weapon ID in id, Shield ID in id2
+ case 2: // Weapon ID in id, Shield ID in id2
dstBeing->setSprite(Being::WEAPON_SPRITE, id);
dstBeing->setSprite(Being::SHIELD_SPRITE, id2);
break;
@@ -304,9 +342,24 @@ void BeingHandler::handleMessage(MessageIn *msg)
case 6: // eAthena LOOK_HAIR_COLOR
dstBeing->setHairStyle(-1, id);
break;
+ case 8: // eAthena LOOK_SHIELD
+ dstBeing->setSprite(Being::SHIELD_SPRITE, id);
+ break;
case 9: // eAthena LOOK_SHOES
dstBeing->setSprite(Being::SHOE_SPRITE, id);
break;
+ case 10: // LOOK_GLOVES
+ dstBeing->setSprite(Being::GLOVES_SPRITE, id);
+ break;
+ case 11: // LOOK_CAPE
+ dstBeing->setSprite(Being::CAPE_SPRITE, id);
+ break;
+ case 12:
+ dstBeing->setSprite(Being::MISC1_SPRITE, id);
+ break;
+ case 13:
+ dstBeing->setSprite(Being::MISC2_SPRITE, id);
+ break;
default:
logger->log("SMSG_BEING_CHANGE_LOOKS: unsupported type: "
"%d, id: %d", type, id);
@@ -328,9 +381,9 @@ void BeingHandler::handleMessage(MessageIn *msg)
// An update about a player, potentially including movement.
id = msg->readInt32();
speed = msg->readInt16();
- msg->readInt16(); // option 1
- msg->readInt16(); // option 2
- msg->readInt16(); // option
+ cape = msg->readInt16();
+ misc1 = msg->readInt16();
+ misc2 = msg->readInt16();
job = msg->readInt16();
dstBeing = beingManager->findBeing(id);
@@ -343,9 +396,9 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setWalkSpeed(speed);
dstBeing->mJob = job;
hairStyle = msg->readInt16();
- dstBeing->setSprite(Being::WEAPON_SPRITE, msg->readInt16());
- dstBeing->setSprite(Being::SHIELD_SPRITE, msg->readInt16());
- headBottom = msg->readInt16();
+ weapon = msg->readInt16();
+ shield = msg->readInt16();
+ headBottom = msg->readInt16();
if (msg->getId() == SMSG_PLAYER_MOVE)
{
@@ -355,7 +408,9 @@ void BeingHandler::handleMessage(MessageIn *msg)
headTop = msg->readInt16();
headMid = msg->readInt16();
hairColor = msg->readInt16();
- msg->readInt16(); // clothes color - not used
+ shoes = 0;
+ gloves = 0;
+ msg->readInt16(); // clothes color - not used
msg->readInt16(); // head dir
msg->readInt32(); // guild
msg->readInt32(); // emblem
@@ -364,9 +419,18 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setGender(1 - msg->readInt8()); // gender
// Set these after the gender, as the sprites may be gender-specific
- dstBeing->setSprite(Being::BOTTOMCLOTHES_SPRITE, headBottom);
+ dstBeing->setSprite(Being::WEAPON_SPRITE, weapon);
+ dstBeing->setSprite(Being::SHIELD_SPRITE, shield);
+ dstBeing->setSprite(Being::BOTTOMCLOTHES_SPRITE, headBottom);
dstBeing->setSprite(Being::TOPCLOTHES_SPRITE, headMid);
dstBeing->setSprite(Being::HAT_SPRITE, headTop);
+ dstBeing->setSprite(Being::SHOE_SPRITE, shoes);
+ // Compensation for the unpatched TMW server
+ if (gloves > 10)
+ dstBeing->setSprite(Being::GLOVES_SPRITE, gloves);
+ dstBeing->setSprite(Being::CAPE_SPRITE, cape);
+ dstBeing->setSprite(Being::MISC1_SPRITE, misc1);
+ dstBeing->setSprite(Being::MISC2_SPRITE, misc2);
dstBeing->setHairStyle(hairStyle, hairColor);
if (msg->getId() == SMSG_PLAYER_MOVE)
@@ -384,8 +448,7 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setDirection(dir);
}
- msg->readInt8(); // unknown
- msg->readInt8(); // unknown
+ msg->readInt16(); // GM status
if (msg->getId() == SMSG_PLAYER_UPDATE_1)
{
@@ -406,6 +469,42 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->mFrame = 0;
break;
+ case SMSG_PLAYER_STOP:
+ /*
+ * Instruction from server to stop walking at x, y.
+ *
+ * Some people like having this enabled. Others absolutely
+ * despise it. So I'm setting to so that it only affects the
+ * local player if the person has set a key "EnableSync" to "1"
+ * in their config.xml file.
+ *
+ * This packet will be honored for all other beings, regardless
+ * of the config setting.
+ */
+
+ id = msg->readInt32();
+ if (mSync || id != player_node->getId()) {
+ dstBeing = beingManager->findBeing(id);
+ if (dstBeing) {
+ dstBeing->mX = msg->readInt16();
+ dstBeing->mY = msg->readInt16();
+ if (dstBeing->mAction == Being::WALK) {
+ dstBeing->mFrame = 0;
+ dstBeing->setAction(Being::STAND);
+ }
+ }
+ }
+ break;
+
+ case SMSG_PLAYER_MOVE_TO_ATTACK:
+ /*
+ * This is an *advisory* message, telling the client that
+ * it needs to move the character before attacking
+ * a target (out of range, obstruction in line of fire).
+ * We can safely ignore this...
+ */
+ break;
+
case 0x0119:
// Change in players look
logger->log("0x0119 %i %i %i %x %i", msg->readInt32(),