summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBertram <bertram@cegetel.net>2009-10-29 01:07:11 +0100
committerBertram <bertram@cegetel.net>2009-10-29 01:07:11 +0100
commit45223500f7a5f661adea71e57010b018bac2cf32 (patch)
tree9bb009e84d4a1f8de9415a6d36395d1b0ed6150f /src
parent3350289ca6aa76c4b7249374af2f3f08fbecbe93 (diff)
downloadmana-client-45223500f7a5f661adea71e57010b018bac2cf32.tar.gz
mana-client-45223500f7a5f661adea71e57010b018bac2cf32.tar.bz2
mana-client-45223500f7a5f661adea71e57010b018bac2cf32.tar.xz
mana-client-45223500f7a5f661adea71e57010b018bac2cf32.zip
Mostly fixed the walk on water bug... But...
The current code tells that the character must stop in the middle of a tile when the tile to the north is blocking. But even now with respecting this, the player is still on water. So, what to do? Correct the water tile?
Diffstat (limited to 'src')
-rw-r--r--src/being.cpp3
-rw-r--r--src/localplayer.cpp47
2 files changed, 29 insertions, 21 deletions
diff --git a/src/being.cpp b/src/being.cpp
index 6542a14b..feec617a 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -165,9 +165,6 @@ void Being::setDestination(int dstX, int dstY)
return;
}
- // FIXME: Look into making this code neater.
- // Interpolate the offsets. Also convert from tile based to pixel based
-
// Find the starting offset
float startX = (srcX % 32);
float startY = (srcY % 32);
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index bc5f55a4..a6e558e8 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -470,40 +470,51 @@ void LocalPlayer::setDestination(Uint16 x, Uint16 y)
#endif
{
#ifdef MANASERV_SUPPORT
+ // Pre-computing character's destination in tiles
+ const int tx = x / 32;
+ const int ty = y / 32;
+
// Check the walkability of the destination
// If the destination is a wall, don't go there!
- if (!mMap->getWalk(x / 32, y / 32))
+ if (!mMap->getWalk(tx, ty))
return;
+ // Pre-computing character's position useful variables.
+ Vector playerPosition = getPosition();
+ const int posX = (int)(playerPosition.x / 32);
+ const int posY = (int)(playerPosition.y / 32);
+ const int offsetY = (int)playerPosition.y % 32;
+
// check if we're finding a path to the seeked destination
// If the path is empty... and isn't on the same tile,
// then, it's an unvalid one.
- Vector playerPosition = getPosition();
- if (((int)(playerPosition.x / 32) != x / 32)
- || (((int)playerPosition.y / 32) != y / 32))
+ if (posX != tx || posY != ty)
{
- Path evaluatedPath = mMap->findPath(playerPosition.x / 32,
- playerPosition.y / 32,
- x / 32, y / 32,
- getWalkMask());
+ Path evaluatedPath = mMap->findPath(posX, posY, tx, ty,
+ getWalkMask());
if (evaluatedPath.empty())
return;
}
- // Fix coordinates so that the player does not seem to dig into walls.
- const int tx = x / 32;
- const int ty = y / 32;
+ // Pre-computing character's destination offsets.
int fx = x % 32;
int fy = y % 32;
- if (fx != 16 && !mMap->getWalk(tx + fx / 16 * 2 - 1, ty, getWalkMask()))
+ // Fix coordinates so that the player does not seem to dig into walls.
+ if (fx > 16 && !mMap->getWalk(tx + 1, ty, getWalkMask()))
fx = 16;
- if (fy != 16 && !mMap->getWalk(tx, ty + fy / 16 * 2 - 1, getWalkMask()))
- fy = 16;
- if (fx != 16 && fy != 16 && !mMap->getWalk(tx + fx / 16 * 2 - 1,
- ty + fy / 16 * 2 - 1,
- getWalkMask()))
+ else if (fx < 16 && !mMap->getWalk(tx - 1, ty, getWalkMask()))
fx = 16;
+ else if (fy > 16 && !mMap->getWalk(tx, ty + 1, getWalkMask()))
+ fy = 16;
+ else if (fy < 16 && !mMap->getWalk(tx, ty - 1, getWalkMask()))
+ fy = 16;
+
+ // Test also the current character's position, to avoid the corner case
+ // where a player can approach an obstacle by walking from slightly
+ // under, diagonally. First part to the walk on water bug.
+ if (offsetY < 16 && !mMap->getWalk(posX, posY - 1, getWalkMask()))
+ fy = 16;
x = tx * 32 + fx;
y = ty * 32 + fy;
@@ -637,7 +648,7 @@ void LocalPlayer::stopWalking(bool sendToServer)
#ifdef MANASERV_SUPPORT
mLocalWalkTime = 0;
#endif
- Being::setDestination(getPosition().x,getPosition().y);
+ setDestination(getPosition().x, getPosition().y);
if (sendToServer)
Net::getPlayerHandler()->setDestination(getPosition().x,
getPosition().y);