diff options
author | Bertram <bertram@cegetel.net> | 2009-10-29 01:07:11 +0100 |
---|---|---|
committer | Bertram <bertram@cegetel.net> | 2009-10-29 01:07:11 +0100 |
commit | 45223500f7a5f661adea71e57010b018bac2cf32 (patch) | |
tree | 9bb009e84d4a1f8de9415a6d36395d1b0ed6150f | |
parent | 3350289ca6aa76c4b7249374af2f3f08fbecbe93 (diff) | |
download | mana-45223500f7a5f661adea71e57010b018bac2cf32.tar.gz mana-45223500f7a5f661adea71e57010b018bac2cf32.tar.bz2 mana-45223500f7a5f661adea71e57010b018bac2cf32.tar.xz mana-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?
-rw-r--r-- | src/being.cpp | 3 | ||||
-rw-r--r-- | src/localplayer.cpp | 47 |
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); |