diff options
Diffstat (limited to 'src/localplayer.cpp')
-rw-r--r-- | src/localplayer.cpp | 212 |
1 files changed, 118 insertions, 94 deletions
diff --git a/src/localplayer.cpp b/src/localplayer.cpp index b5ad79eb..14f85bfe 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -360,96 +360,6 @@ void LocalPlayer::pickUp(FloorItem *item) } } -void LocalPlayer::walk(unsigned char dir) -{ - // TODO: Evaluate the implementation of this method for tmwserv - if (!mMap || !dir) - return; - -#ifdef TMWSERV_SUPPORT - const Vector &pos = getPosition(); -#endif - - if (mAction == WALK && !mPath.empty()) - { - // Just finish the current action, otherwise we get out of sync -#ifdef TMWSERV_SUPPORT - Being::setDestination(pos.x, pos.y); -#else - Being::setDestination(getTileX(), getTileY()); -#endif - return; - } - - int dx = 0, dy = 0; - if (dir & UP) - dy--; - if (dir & DOWN) - dy++; - if (dir & LEFT) - dx--; - if (dir & RIGHT) - dx++; - - // Prevent skipping corners over colliding tiles -#ifdef TMWSERV_SUPPORT - if (dx && !mMap->getWalk(((int) pos.x + dx) / 32, - (int) pos.y / 32, getWalkMask())) - dx = 16 - (int) pos.x % 32; - if (dy && !mMap->getWalk((int) pos.x / 32, - ((int) pos.y + dy) / 32, getWalkMask())) - dy = 16 - (int) pos.y % 32; -#else - if (dx && !mMap->getWalk(getTileX() + dx, getTileY(), getWalkMask())) - dx = 0; - if (dy && !mMap->getWalk(getTileX(), getTileY() + dy, getWalkMask())) - dy = 0; -#endif - - // Choose a straight direction when diagonal target is blocked -#ifdef TMWSERV_SUPPORT - if (dx && dy && !mMap->getWalk((pos.x + dx) / 32, - (pos.y + dy) / 32, getWalkMask())) - dx = 16 - (int) pos.x % 32; - - int dScaler; // Distance to walk - - // Checks our path up to 2 tiles, if a blocking tile is found - // We go to the last good tile, and break out of the loop - for (dScaler = 1; dScaler <= 32 * 2; dScaler++) - { - if ( (dx || dy) && - !mMap->getWalk( ((int) pos.x + (dx * dScaler)) / 32, - ((int) pos.y + (dy * dScaler)) / 32, getWalkMask()) ) - { - dScaler--; - break; - } - } - - if (dScaler >= 0) - { - effectManager->trigger(15, (int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler)); - setDestination((int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler)); - } -#else - if (dx && dy && !mMap->getWalk(getTileX() + dx, getTileY() + dy, getWalkMask())) - dx = 0; - - // Walk to where the player can actually go - if ((dx || dy) && mMap->getWalk(getTileX() + dx, getTileY() + dy, getWalkMask())) - { - setDestination(getTileX() + dx, getTileY() + dy); - } -#endif - else if (dir) - { - // If the being can't move, just change direction - Net::getPlayerHandler()->setDirection(dir); - setDirection(dir); - } -} - Being *LocalPlayer::getTarget() const { return mTarget; @@ -550,16 +460,130 @@ void LocalPlayer::setDestination(Uint16 x, Uint16 y) void LocalPlayer::setWalkingDir(int dir) { + // This function is called by Game::handleInput() + +#ifdef TMWSERV_SUPPORT + // First if player is pressing key for the direction he is already + // going, do nothing more... + + // Else if he is pressing a key, and its different from what he has + // been pressing, stop (do not send this stop to the server) and + // start in the new direction + if (dir && (dir != getWalkingDir())) + player_node->stopWalking(false); + + // Else, he is not pressing a key, stop (sending to server) + else if (!dir) + { + player_node->stopWalking(true); + return; + } + + // If the delay to send another walk message to the server hasn't expired, + // don't do anything or we could get disconnected for spamming the server + if (get_elapsed_time(mLocalWalkTime) < walkingKeyboardDelay) + return; +#endif + mWalkingDir = dir; // If we're not already walking, start walking. - if (mAction != WALK && dir + if (mAction != WALK && dir) + { + walk(dir); + } +} + +void LocalPlayer::walk(unsigned char dir) +{ + // This function is called by setWalkingDir(), + // but also by nextStep() for eAthena... + + // TODO: Evaluate the implementation of this method for tmwserv + if (!mMap || !dir) + return; + #ifdef TMWSERV_SUPPORT - && get_elapsed_time(mLocalWalkTime) >= walkingKeyboardDelay + const Vector &pos = getPosition(); #endif - ) + + if (mAction == WALK && !mPath.empty()) { - walk(dir); + // Just finish the current action, otherwise we get out of sync +#ifdef TMWSERV_SUPPORT + Being::setDestination(pos.x, pos.y); +#else + Being::setDestination(getTileX(), getTileY()); +#endif + return; + } + + int dx = 0, dy = 0; + if (dir & UP) + dy--; + if (dir & DOWN) + dy++; + if (dir & LEFT) + dx--; + if (dir & RIGHT) + dx++; + + // Prevent skipping corners over colliding tiles +#ifdef TMWSERV_SUPPORT + if (dx && !mMap->getWalk(((int) pos.x + dx) / 32, + (int) pos.y / 32, getWalkMask())) + dx = 16 - (int) pos.x % 32; + if (dy && !mMap->getWalk((int) pos.x / 32, + ((int) pos.y + dy) / 32, getWalkMask())) + dy = 16 - (int) pos.y % 32; +#else + if (dx && !mMap->getWalk(getTileX() + dx, getTileY(), getWalkMask())) + dx = 0; + if (dy && !mMap->getWalk(getTileX(), getTileY() + dy, getWalkMask())) + dy = 0; +#endif + + // Choose a straight direction when diagonal target is blocked +#ifdef TMWSERV_SUPPORT + if (dx && dy && !mMap->getWalk((pos.x + dx) / 32, + (pos.y + dy) / 32, getWalkMask())) + dx = 16 - (int) pos.x % 32; + + int dScaler; // Distance to walk + + // Checks our path up to 2 tiles, if a blocking tile is found + // We go to the last good tile, and break out of the loop + for (dScaler = 1; dScaler <= 32 * 2; dScaler++) + { + if ( (dx || dy) && + !mMap->getWalk( ((int) pos.x + (dx * dScaler)) / 32, + ((int) pos.y + (dy * dScaler)) / 32, getWalkMask()) ) + { + dScaler--; + break; + } + } + + if (dScaler >= 0) + { + effectManager->trigger(15, (int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler)); + setDestination((int) pos.x + (dx * dScaler), (int) pos.y + (dy * dScaler)); + } +#else + if (dx && dy && !mMap->getWalk(getTileX() + dx, getTileY() + dy, getWalkMask())) + dx = 0; + + // Walk to where the player can actually go + if ((dx || dy) && mMap->getWalk(getTileX() + dx, getTileY() + dy, getWalkMask())) + { + setDestination(getTileX() + dx, getTileY() + dy); + } +#endif + else if (dir) + { + // If the being can't move, just change direction + Net::getPlayerHandler()->setDirection(dir); + setDirection(dir); } } |