summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-01-09 12:12:41 +0100
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-01-09 12:12:41 +0100
commit7f712f1c9d00182660298d123d120444ef6a4996 (patch)
tree920a248a636f9e251cd5eb42470b2c516fa82847
parent8ff3e6674c1d4fc05fc1ba87f42484689fca0879 (diff)
downloadmanaserv-7f712f1c9d00182660298d123d120444ef6a4996.tar.gz
manaserv-7f712f1c9d00182660298d123d120444ef6a4996.tar.bz2
manaserv-7f712f1c9d00182660298d123d120444ef6a4996.tar.xz
manaserv-7f712f1c9d00182660298d123d120444ef6a4996.zip
Fix being direction discrepancies by syncing the BeingDirection.
The server was actually using the bitmask enum while the the client still sent another one, creating discrepancies. A second problem is that the being direction was not properly initialized and not updated while it was moving. Reviewed-by: Jaxad.
-rw-r--r--src/game-server/being.cpp100
-rw-r--r--src/game-server/being.h13
-rw-r--r--src/game-server/gamehandler.cpp3
-rw-r--r--src/game-server/monster.cpp10
-rw-r--r--src/game-server/state.cpp1
-rw-r--r--src/manaserv_protocol.h10
-rw-r--r--src/scripting/lua.cpp2
7 files changed, 118 insertions, 21 deletions
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp
index 65736774..567e19a3 100644
--- a/src/game-server/being.cpp
+++ b/src/game-server/being.cpp
@@ -39,7 +39,7 @@ Being::Being(ThingType type):
Actor(type),
mAction(STAND),
mTarget(NULL),
- mDirection(0)
+ mDirection(DOWN)
{
const AttributeScopes &attr = attributeManager->getAttributeInfoForType(ATTR_BEING);
LOG_DEBUG("Being creation: initialisation of " << attr.size() << " attributes.");
@@ -202,6 +202,89 @@ Path Being::findPath()
return map->findPath(startX, startY, destX, destY, getWalkMask());
}
+void Being::updateDirection(const Point &currentPos, const Point &destPos)
+{
+ // We update the being direction on each tile to permit other beings
+ // entering in range to always see the being with a direction value.
+
+ // We first handle simple cases
+
+ // If the character has reached its destination,
+ // don't update the direction since it's only a matter of keeping
+ // the previous one.
+ if (currentPos == destPos)
+ return;
+
+ if (currentPos.x == destPos.x)
+ {
+ if (currentPos.y > destPos.y)
+ setDirection(UP);
+ else
+ setDirection(DOWN);
+ return;
+ }
+
+ if (currentPos.y == destPos.y)
+ {
+ if (currentPos.x > destPos.x)
+ setDirection(LEFT);
+ else
+ setDirection(RIGHT);
+ return;
+ }
+
+ // Now let's handle diagonal cases
+ // First, find the lower angle:
+ if (currentPos.x < destPos.x)
+ {
+ // Up-right direction
+ if (currentPos.y > destPos.y)
+ {
+ // Compute tan of the angle
+ if ((currentPos.y - destPos.y) / (destPos.x - currentPos.x) < 1)
+ // The angle is less than 45°, we look to the right
+ setDirection(RIGHT);
+ else
+ setDirection(UP);
+ return;
+ }
+ else // Down-right
+ {
+ // Compute tan of the angle
+ if ((destPos.y - currentPos.y) / (destPos.x - currentPos.x) < 1)
+ // The angle is less than 45°, we look to the right
+ setDirection(RIGHT);
+ else
+ setDirection(DOWN);
+ return;
+ }
+ }
+ else
+ {
+ // Up-left direction
+ if (currentPos.y > destPos.y)
+ {
+ // Compute tan of the angle
+ if ((currentPos.y - destPos.y) / (currentPos.x - destPos.x) < 1)
+ // The angle is less than 45°, we look to the right
+ setDirection(LEFT);
+ else
+ setDirection(UP);
+ return;
+ }
+ else // Down-left
+ {
+ // Compute tan of the angle
+ if ((destPos.y - currentPos.y) / (currentPos.x - destPos.x) < 1)
+ // The angle is less than 45°, we look to the right
+ setDirection(LEFT);
+ else
+ setDirection(DOWN);
+ return;
+ }
+ }
+}
+
void Being::move()
{
// Immobile beings cannot move.
@@ -229,6 +312,8 @@ void Being::move()
if (mAction == WALK)
setAction(STAND);
// Moving while staying on the same tile is free
+ // We only update the direction in that case.
+ updateDirection(mOld, mDst);
setPosition(mDst);
mMoveTime = 0;
return;
@@ -281,6 +366,9 @@ void Being::move()
getModifiedAttribute(ATTR_MOVE_SPEED_RAW) :
getModifiedAttribute(ATTR_MOVE_SPEED_RAW) * SQRT2;
+ // Update the being direction also
+ updateDirection(prev, next);
+
if (mPath.empty())
{
// skip last tile center
@@ -302,11 +390,11 @@ int Being::directionToAngle(int direction)
{
switch (direction)
{
- case DIRECTION_UP: return 90;
- case DIRECTION_DOWN: return 270;
- case DIRECTION_RIGHT: return 180;
- case DIRECTION_LEFT:
- default: return 0;
+ case UP: return 90;
+ case DOWN: return 270;
+ case RIGHT: return 180;
+ case LEFT:
+ default: return 0;
}
}
diff --git a/src/game-server/being.h b/src/game-server/being.h
index 07876a4a..11c5f753 100644
--- a/src/game-server/being.h
+++ b/src/game-server/being.h
@@ -127,10 +127,10 @@ class Being : public Actor
/**
* Sets the facing direction of the being.
*/
- void setDirection(int direction)
+ void setDirection(BeingDirection direction)
{ mDirection = direction; raiseUpdateFlags(UPDATEFLAG_DIRCHANGE); }
- int getDirection() const
+ BeingDirection getDirection() const
{ return mDirection; }
/**
@@ -320,8 +320,15 @@ class Being : public Actor
Being(const Being &rhs);
Being &operator=(const Being &rhs);
+ /**
+ * Update the being direction when moving so avoid directions desyncs
+ * with other clients.
+ */
+ void updateDirection(const Point &currentPos,
+ const Point &destPos);
+
Path mPath;
- unsigned char mDirection; /**< Facing direction. */
+ BeingDirection mDirection; /**< Facing direction. */
std::string mName;
Hits mHitsTaken; /**< List of punches taken since last update. */
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp
index a9097286..55c18c2c 100644
--- a/src/game-server/gamehandler.cpp
+++ b/src/game-server/gamehandler.cpp
@@ -419,7 +419,8 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
case PGMSG_DIRECTION_CHANGE:
{
- computer.character->setDirection(message.readInt8());
+ computer.character->setDirection(
+ (BeingDirection)message.readInt8());
} break;
case PGMSG_DISCONNECT:
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index 661aca5e..78268db1 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -112,10 +112,10 @@ Monster::Monster(MonsterClass *specy):
// Set positions relative to target from which the monster can attack
int dist = specy->getAttackDistance();
- mAttackPositions.push_back(AttackPosition(dist, 0, DIRECTION_LEFT));
- mAttackPositions.push_back(AttackPosition(-dist, 0, DIRECTION_RIGHT));
- mAttackPositions.push_back(AttackPosition(0, -dist, DIRECTION_DOWN));
- mAttackPositions.push_back(AttackPosition(0, dist, DIRECTION_UP));
+ mAttackPositions.push_back(AttackPosition(dist, 0, LEFT));
+ mAttackPositions.push_back(AttackPosition(-dist, 0, RIGHT));
+ mAttackPositions.push_back(AttackPosition(0, -dist, DOWN));
+ mAttackPositions.push_back(AttackPosition(0, dist, UP));
// Load default script
loadScript(specy->getScript());
@@ -224,7 +224,7 @@ void Monster::update()
Being *bestAttackTarget = mTarget = NULL;
int bestTargetPriority = 0;
Point bestAttackPosition;
- BeingDirection bestAttackDirection = DIRECTION_DOWN;
+ BeingDirection bestAttackDirection = DOWN;
// Iterate through objects nearby
int aroundArea = Configuration::getValue("game_visualRange", 448);
diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp
index bed47805..abfa2342 100644
--- a/src/game-server/state.cpp
+++ b/src/game-server/state.cpp
@@ -270,6 +270,7 @@ static void informPlayer(MapComposite *map, Character *p)
enterMsg.writeInt8(static_cast< Being *>(o)->getAction());
enterMsg.writeInt16(opos.x);
enterMsg.writeInt16(opos.y);
+ enterMsg.writeInt8(o->getDirection());
switch (otype)
{
case OBJECT_CHARACTER:
diff --git a/src/manaserv_protocol.h b/src/manaserv_protocol.h
index da95207c..f0dc22b2 100644
--- a/src/manaserv_protocol.h
+++ b/src/manaserv_protocol.h
@@ -103,7 +103,7 @@ enum {
PGMSG_LOWER_ATTRIBUTE = 0x0170, // W attribute
GPMSG_LOWER_ATTRIBUTE_RESPONSE = 0x0171, // B error, W attribute
PGMSG_RESPAWN = 0x0180, // -
- GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position
+ GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position, B direction
// character: S name, B hair style, B hair color, B gender, B item bitmask, { W item id }*
// monster: W type id
// npc: W type id
@@ -415,10 +415,10 @@ enum AttackType
*/
enum BeingDirection
{
- DIRECTION_UP = 1,
- DIRECTION_DOWN,
- DIRECTION_LEFT,
- DIRECTION_RIGHT
+ DOWN = 1,
+ LEFT = 2,
+ UP = 4,
+ RIGHT = 8
};
/**
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index 2635974e..3a615412 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -852,7 +852,7 @@ static int being_set_direction(lua_State *s)
{
Being *being = getBeing(s, 1);
- int dir = lua_tointeger(s, 2);
+ BeingDirection dir = (BeingDirection) lua_tointeger(s, 2);
if (being)
{