summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/being.cpp32
-rw-r--r--src/gui/viewport.cpp39
-rw-r--r--src/map.cpp34
-rw-r--r--src/map.h8
-rw-r--r--src/net/manaserv/playerhandler.h3
-rw-r--r--src/net/playerhandler.h6
-rw-r--r--src/net/tmwa/playerhandler.h3
7 files changed, 111 insertions, 14 deletions
diff --git a/src/being.cpp b/src/being.cpp
index 2c8414d8..6b971dbf 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -198,21 +198,37 @@ void Being::setDestination(int dstX, int dstY)
return;
// If the destination is unwalkable, don't bother trying to get there
- if (!mMap->getWalk(dstX / 32, dstY / 32))
+ int tileWidth = mMap->getTileWidth();
+ int tileHeight = mMap->getTileHeight();
+ if (!mMap->getWalk(dstX / tileWidth, dstY / tileHeight))
return;
- Position dest = mMap->checkNodeOffsets(getCollisionRadius(), getWalkMask(),
- dstX, dstY);
- Path thisPath = mMap->findPixelPath((int) mPos.x, (int) mPos.y,
- dest.x, dest.y,
- getCollisionRadius(), getWalkMask());
+ Position dest(dstX, dstY);
+ Path thisPath;
+ if (Net::getPlayerHandler()->usePixelPrecision())
+ {
+ dest = mMap->checkNodeOffsets(getCollisionRadius(), getWalkMask(),
+ dstX, dstY);
+ thisPath = mMap->findPixelPath((int) mPos.x, (int) mPos.y,
+ dest.x, dest.y,
+ getCollisionRadius(), getWalkMask());
+ }
+ else
+ {
+ // We center the destination.
+ dest.x = (dstX / tileWidth) * tileWidth + tileWidth / 2;
+ dest.y = (dstY / tileHeight) * tileHeight + tileHeight / 2;
+ // and find a tile centered pixel path
+ thisPath = mMap->findTilePath((int) mPos.x, (int) mPos.y,
+ dest.x, dest.y, getWalkMask());
+ }
if (thisPath.empty())
{
// If there is no path but the destination is on the same walkable tile,
// we accept it.
- if ((int)mPos.x / 32 == dest.x / 32
- && (int)mPos.y / 32 == dest.y / 32)
+ if ((int)mPos.x / tileWidth == dest.x / tileWidth
+ && (int)mPos.y / tileHeight == dest.y / tileHeight)
{
mDest.x = dest.x;
mDest.y = dest.y;
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index 459edab5..19bed735 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -37,6 +37,7 @@
#include "gui/beingpopup.h"
#include "net/net.h"
+#include "net/playerhandler.h"
#include "resources/resourcemanager.h"
@@ -270,12 +271,38 @@ void Viewport::_drawDebugPath(Graphics *graphics)
(int) playerPos.y - (int) mPixelViewY - playerRadius,
playerRadius * 2, playerRadius * 2));
- debugPath = mMap->findPixelPath(
- (int) playerPos.x,
- (int) playerPos.y,
- mMouseX + (int) mPixelViewX,
- mMouseY + (int) mPixelViewY,
- playerRadius, 0xFF);
+ // Prepare the walkmask corresponding to the protocol
+ unsigned char walkMask = 0;
+ switch (Net::getNetworkType())
+ {
+ case ServerInfo::TMWATHENA:
+ walkMask = Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER;
+ break;
+ case ServerInfo::MANASERV:
+ default:
+ walkMask = Map::BLOCKMASK_WALL;
+ break;
+ }
+
+ // Adapt the path finding to the precision requested
+ if (Net::getPlayerHandler()->usePixelPrecision())
+ {
+ debugPath = mMap->findPixelPath(
+ (int) playerPos.x,
+ (int) playerPos.y,
+ mMouseX + (int) mPixelViewX,
+ mMouseY + (int) mPixelViewY,
+ playerRadius, walkMask);
+ }
+ else
+ {
+ debugPath = mMap->findTilePath(
+ (int) playerPos.x,
+ (int) playerPos.y,
+ mMouseX + (int) mPixelViewX,
+ mMouseY + (int) mPixelViewY,
+ walkMask);
+ }
// We draw the path proposed by mouse
_drawPath(graphics, debugPath, gcn::Color(128, 0, 128));
diff --git a/src/map.cpp b/src/map.cpp
index 87c902f6..69793299 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -710,6 +710,40 @@ Position Map::checkNodeOffsets(int radius, unsigned char walkMask,
return Position(tx * 32 + fx, ty * 32 + fy);
}
+Path Map::findTilePath(int startPixelX, int startPixelY, int endPixelX,
+ int endPixelY, unsigned char walkMask, int maxCost)
+{
+ Path myPath = findPath(startPixelX / mTileWidth, startPixelY / mTileHeight,
+ endPixelX / mTileWidth, endPixelY / mTileHeight,
+ walkMask, maxCost);
+
+ // Don't compute empty coordinates.
+ if (myPath.empty())
+ return myPath;
+
+ // Convert the map path to pixels over tiles
+ // And add interpolation between the starting and ending offsets
+ Path::iterator it = myPath.begin();
+ while (it != myPath.end())
+ {
+ // A position that is valid on the start and end tile is not
+ // necessarily valid on all the tiles in between, so check the offsets.
+ *it = Position(it->x * mTileWidth + mTileWidth / 2,
+ it->y * mTileHeight + mTileHeight / 2);
+ it++;
+ }
+
+ // Remove the last path node, as it's more clever to go to the destination.
+ // It also permit to avoid zigzag at the end of the path,
+ // especially with mouse.
+ Position destination((endPixelX / mTileWidth) * mTileWidth + mTileWidth / 2,
+ (endPixelY / mTileHeight) * mTileHeight + mTileHeight / 2);
+ myPath.pop_back();
+ myPath.push_back(destination);
+
+ return myPath;
+}
+
Path Map::findPixelPath(int startPixelX, int startPixelY, int endPixelX,
int endPixelY,
int radius, unsigned char walkMask, int maxCost)
diff --git a/src/map.h b/src/map.h
index 22ca68c4..fae8af50 100644
--- a/src/map.h
+++ b/src/map.h
@@ -287,6 +287,14 @@ class Map : public Properties
/**
* Find a pixel path from one location to the next.
+ * Path node are centered on their corresponding tiles in that case.
+ */
+ Path findTilePath(int startPixelX, int startPixelY, int endPixelX,
+ int endPixelY, unsigned char walkMask,
+ int maxCost = 20);
+
+ /**
+ * Find a pixel path from one location to the next.
*/
Path findPixelPath(int startPixelX, int startPixelY,
int destPixelX, int destPixelY,
diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h
index 6069c6da..8bba1580 100644
--- a/src/net/manaserv/playerhandler.h
+++ b/src/net/manaserv/playerhandler.h
@@ -69,6 +69,9 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
Vector getPixelsPerTickMoveSpeed(Vector speed, Map *map = 0);
+ bool usePixelPrecision()
+ { return true; }
+
private:
void handleMapChangeMessage(Net::MessageIn &msg);
};
diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h
index 23277062..5d94a093 100644
--- a/src/net/playerhandler.h
+++ b/src/net/playerhandler.h
@@ -74,6 +74,12 @@ class PlayerHandler
* Convert the original speed in pixel per tick for internal use.
*/
virtual Vector getPixelsPerTickMoveSpeed(Vector speed, Map *map = 0) = 0;
+
+ /**
+ * Tells whether the client has to use pixel paths.
+ * Return false when tiles-center positions only are to be used.
+ */
+ virtual bool usePixelPrecision() = 0;
};
} // namespace Net
diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h
index 4df74350..42eb85f2 100644
--- a/src/net/tmwa/playerhandler.h
+++ b/src/net/tmwa/playerhandler.h
@@ -61,6 +61,9 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler
Vector getDefaultMoveSpeed();
Vector getPixelsPerTickMoveSpeed(Vector speed, Map *map = 0);
+
+ bool usePixelPrecision()
+ { return false; }
};
} // namespace TmwAthena