From 45223500f7a5f661adea71e57010b018bac2cf32 Mon Sep 17 00:00:00 2001 From: Bertram Date: Thu, 29 Oct 2009 01:07:11 +0100 Subject: 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? --- src/being.cpp | 3 --- 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); -- cgit v1.2.3-70-g09d2