diff options
Diffstat (limited to 'src/object.cpp')
-rw-r--r-- | src/object.cpp | 104 |
1 files changed, 25 insertions, 79 deletions
diff --git a/src/object.cpp b/src/object.cpp index 075b22fa..038a53dc 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -20,9 +20,6 @@ * $Id$ */ -#include <cassert> -#include <cmath> - #include "object.h" #include "map.h" @@ -30,95 +27,44 @@ void MovingObject::move() { - unsigned mSrcX = getX(), mSrcY = getY(); - if (mSrcX == mDstX && mSrcY == mDstY) { - mNewX = mDstX; - mNewY = mDstY; + mOld = getPosition(); + if (mActionTime > 100) + { + // current move has not yet ended + mActionTime -= 100; return; } Map *map = MapManager::instance().getMap(getMapId()); - int tileW = map->getTileWidth(), tileH = map->getTileHeight(); - int tileD = (int) std::sqrt((double)(tileW * tileW + tileH * tileH)); - int tileSX = mSrcX / tileW, fracSX = mSrcX % tileW - tileW / 2; - int tileSY = mSrcY / tileH, fracSY = mSrcY % tileH - tileH / 2; - int tileDX = mDstX / tileW, fracDX = mDstX % tileW - tileW / 2; - int tileDY = mDstY / tileH, fracDY = mDstY % tileH - tileH / 2; - std::list<PATH_NODE> path; - if (tileSX != tileDX || tileSY != tileDY) { + int tileSX = mOld.x / 32, tileSY = mOld.y / 32; + int tileDX = mDst.x / 32, tileDY = mDst.y / 32; + if (tileSX != tileDX || tileSY != tileDY) + { path = map->findPath(tileSX, tileSY, tileDX, tileDY); if (path.empty()) { - mNewX = mDstX = mSrcX; - mNewY = mDstY = mSrcY; + // no path was found + mDst = mOld; return; } + // last tile center is skipped path.pop_back(); } - int tileCX = tileSX, tileCY = tileSY, fracCX = fracSX, fracCY = fracSY; - int left = mSpeed; - int vecX = 0, vecY = 0, cost = 0; - - for (std::list<PATH_NODE>::const_iterator it = path.begin(), - it_end = path.end(); it != it_end; ++it) + Point pos; + do { - int tileNX = it->x, tileNY = it->y; - assert((tileNX != tileCX || tileNY != tileCY) && - (tileNX != tileDX || tileNY != tileDY)); - - if (fracCX != 0 || fracCY != 0) { - // not at the tile center, move toward the next tile center - vecX = -fracCX + tileW * (tileNX - tileCX); - vecY = -fracCY + tileH * (tileNY - tileCY); - cost = (int) std::sqrt((double)(vecX * vecX + vecY * vecY)); - } else { - // at a tile center and toward the next tile center - assert(abs(tileNX - tileCX) <= 1 && abs(tileNY - tileCY) <= 1); - if (tileNX != tileCX) { - vecX = tileW * (tileNX - tileCX); - if (tileNY != tileCY) { - vecY = tileH * (tileNY - tileCY); - cost = tileD; - } else { - vecY = 0; - cost = tileW; - } - } else { - assert(tileNY != tileCY); - vecX = 0; - vecY = tileH * (tileNY - tileCY); - cost = tileH; - } + mActionTime += mSpeed; + if (path.empty()) + { + // skip last tile center + setPosition(mDst); + return; } - - if (cost > left) break; - // enough movement left to reach the next tile center - tileCX = tileNX; - tileCY = tileNY; - fracCX = 0; - fracCY = 0; - vecX = 0; - vecY = 0; - left -= cost; - } - - if ((vecX == 0 && vecY == 0) && (fracCX != fracDX || fracCY != fracDY)) { - // walk toward the destination - vecX = fracDX - fracCX + tileW * (tileDX - tileCX); - vecY = fracDY - fracCY + tileH * (tileDY - tileCY); - cost = (int) std::sqrt((double)(vecX * vecX + vecY * vecY)); + pos.x = path.front().x * 32 + 16; + pos.y = path.front().y * 32 + 16; + path.pop_front(); } - - if (cost <= left) { - // enough movement left to perform the last step - mNewX = mDstX; - mNewY = mDstY; - return; - } - - // linear interpolation along the vector - assert(cost > 0); - mNewX = tileCX * tileW + tileW / 2 + fracCX + vecX * left / cost; - mNewY = tileCY * tileH + tileH / 2 + fracCY + vecY * left / cost; + while (mActionTime < 100); + setPosition(pos); } |