diff options
Diffstat (limited to 'src/being.cpp')
-rw-r--r-- | src/being.cpp | 196 |
1 files changed, 44 insertions, 152 deletions
diff --git a/src/being.cpp b/src/being.cpp index 37cb6987..3593bb94 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -56,11 +56,6 @@ #include <cassert> #include <cmath> -namespace { -const bool debug_movement = true; -} - - #define BEING_EFFECTS_FILE "effects.xml" #define HAIR_FILE "hair.xml" @@ -157,169 +152,66 @@ void Being::setDestination(Uint16 destX, Uint16 destY) #endif #ifdef TMWSERV_SUPPORT -void Being::adjustCourse(int srcX, int srcY, int dstX, int dstY) + +void Being::adjustCourse(int srcX, int srcY) +{ + setDestination(srcX, srcY, mDest.x, mDest.y); +} + +void Being::setDestination(int dstX, int dstY) { - if (debug_movement) - printf("%p adjustCourse(%d, %d, %d, %d)\n", - (void*) this, srcX, srcY, dstX, dstY); + setDestination(mPos.x, mPos.y, dstX, dstY); +} +void Being::setDestination(int srcX, int srcY, int dstX, int dstY) +{ mDest.x = dstX; mDest.y = dstY; - // Find a path to the destination when it is at least a tile away - if (mMap && fabsf((mDest - mPos).length()) > 32) { - setPath(mMap->findPath((int) mPos.x / 32, (int) mPos.y / 32, - dstX / 32, dstY / 32, getWalkMask())); - } else { - setPath(Path()); - } + Path thisPath; - // TODO: Evaluate the implementation of this method - /* - if (mX / 32 == dstX / 32 && mY / 32 == dstY / 32) + if (mMap) { - // The being is already on the last tile of the path. - Path p; - p.push_back(Position(dstX, dstY)); - setPath(p); - return; - } - - Path p1; - int p1_size, p1_length; - Uint16 *p1_dist; - int onPath = -1; - if (srcX / 32 == dstX / 32 && srcY / 32 == dstY / 32) - { - p1_dist = new Uint16[1]; - p1_size = 1; - p1_dist[0] = 0; - p1_length = 0; - } - else - { - p1 = mMap->findPath(srcX / 32, srcY / 32, dstX / 32, dstY / 32, getWalkMask()); - if (p1.empty()) - { - // No path, but don't teleport since it could be user input. - setPath(p1); - return; - } - p1_size = p1.size(); - p1_dist = new Uint16[p1_size]; - int j = 0; - // Remove last tile so that it can be replaced by the exact destination. - p1.pop_back(); - for (Path::iterator i = p1.begin(), i_end = p1.end(); i != i_end; ++i) - { - // Get distance from source to tile i. - p1_dist[j] = mMap->getMetaTile(i->x, i->y)->Gcost; - // Check if the being is already walking on the path. - if (i->x == mX / 32 && i->y == mY / 32) - { - onPath = j; - } - // Do not set any offset for intermediate steps. - i->x = i->x * 32; - i->y = i->y * 32; - ++j; - } - p1_length = mMap->getMetaTile(dstX / 32, dstY / 32)->Gcost; - p1_dist[p1_size - 1] = p1_length; - } - p1.push_back(Position(dstX, dstY)); - - if (mX / 32 == srcX / 32 && mY / 32 == srcY / 32) + thisPath = mMap->findPath((int) srcX / 32, (int) srcY / 32, + dstX / 32, dstY / 32, getWalkMask()); + } + if (thisPath.empty()) { - // The being is at the start of the path. - setPath(p1); - delete[] p1_dist; + setPath(Path()); return; } - if (onPath >= 0) - { - // The being is already on the path, but it needs to be slowed down. - for (int j = onPath; j >= 0; --j) - { - p1.pop_front(); - } - int r = p1_length - p1_dist[onPath]; // remaining length - assert(r > 0); - setPath(p1, p1_length * 1024 / r); - delete[] p1_dist; - return; - } + // FIXME: Look into making this code neater. + // Interpolate the offsets. Also convert from tile based to pixel based - Path bestPath; - int bestRating = -1, bestStart = 0, bestLength = 0; - int j = 0; + // Note: I divided the offsets by 32 then muilpied it back to get the top left + // Conner of where the tile is. (If you know a better way then please change it) - for (Path::iterator i = p1.begin(), i_end = p1.end(); i != i_end; ++i) - { - // Look if it is worth passing by tile i. - Path p2 = mMap->findPath(mX / 32, mY / 32, i->x / 32, i->y / 32, getWalkMask()); - if (!p2.empty()) - { - int l1 = mMap->getMetaTile(i->x / 32, i->y / 32)->Gcost; - int l2 = p1_length - p1_dist[j]; - int r = l1 + l2 / 2; // TODO: tune rating formula - assert(r > 0); - if (bestRating < 0 || r < bestRating) - { - bestPath.swap(p2); - bestRating = r; - bestStart = j; - bestLength = l1 + l2; - } - } - ++j; - } + // Find the starting offset + int startX = srcX - ((srcX / 32) * 32 + 16); + int startY = srcY - ((srcY / 32) * 32 + 16); - if (bestRating < 0) - { - // Unable to reach the path? Still, don't teleport since it could be - // user input instead of server command. - setPath(p1); - delete[] p1_dist; - return; - } + // Find the ending offset + int endX = dstX - ((dstX / 32) * 32 + 16); + int endY = dstY - ((dstY / 32) * 32 + 16); - bestPath.pop_back(); - for (Path::iterator i = bestPath.begin(), i_end = bestPath.end(); i != i_end; ++i) - { - i->x = i->x * 32; - i->y = i->y * 32; - } + // Find the distance, and divide it by the number of steps + int changeX = (endX - startX) / thisPath.size(); + int changeY = (endY - startY) / thisPath.size(); - // Concatenate paths. - for (int j = bestStart; j > 0; --j) + // Convert the map path to pixels over tiles + // And add interpolation between the starting and ending offsets + Path::iterator it = thisPath.begin(); + int i = 0; + while(it != thisPath.end()) { - p1.pop_front(); + it->x = (it->x * 32 + 16) + startX + (changeX * i); + it->y = (it->y * 32 + 16) + startY + (changeY * i); + i++; + it++; } - p1.splice(p1.begin(), bestPath); - - assert(bestLength > 0); - setPath(p1, p1_length * 1024 / bestLength); - delete[] p1_dist; - */ -} - -void Being::adjustCourse(int srcX, int srcY) -{ - if (debug_movement) - printf("%p adjustCourse(%d, %d)\n", (void*) this, srcX, srcY); - - if (!mPath.empty()) - adjustCourse(srcX, srcY, mPath.back().x * 32, mPath.back().y * 32); -} - -void Being::setDestination(int destX, int destY) -{ - if (debug_movement) - printf("%p setDestination(%d, %d)\n", (void*) this, destX, destY); - adjustCourse((int) mPos.x, (int) mPos.y, destX, destY); + setPath(thisPath); } #endif // TMWSERV_SUPPORT @@ -332,7 +224,7 @@ void Being::setPath(const Path &path) { mPath = path; #ifdef TMWSERV_SUPPORT - std::cout << this << " New path: " << path << std::endl; +// std::cout << this << " New path: " << path << std::endl; #else if (mAction != WALK && mAction != DEAD) { @@ -668,8 +560,8 @@ void Being::logic() #ifdef TMWSERV_SUPPORT const Vector dest = (mPath.empty()) ? - mDest : Vector(mPath.front().x * 32 + 16, - mPath.front().y * 32 + 16); + mDest : Vector(mPath.front().x, + mPath.front().y); Vector dir = dest - mPos; const float length = dir.length(); |