summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/being.cpp33
-rw-r--r--src/localplayer.cpp125
-rw-r--r--src/localplayer.h9
3 files changed, 108 insertions, 59 deletions
diff --git a/src/being.cpp b/src/being.cpp
index d15c27b3..ef71b748 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -528,12 +528,24 @@ void Being::logic()
Vector dir = dest - mPos;
const float length = dir.length();
- // When we're over 2 pixels from our destination, move to it
- // TODO: Should be possible to make it even pixel exact, but this solves
- // the jigger caused by moving too far.
- if (length > 2.0f) {
+ // When we've not reached our destination, move to it.
+ if (length > 0.0f)
+ {
const float speed = mWalkSpeed / 100.0f;
- setPosition(mPos + (dir / (length / speed)));
+
+ // Test if we don't miss the destination by a move too far:
+ if ((dir / (length / speed)).length() > dir.length())
+ {
+ setPosition(mPos + dir);
+
+ // Also, if the destination is reached, try to get the next
+ // path point, if existing.
+ if (!mPath.empty())
+ mPath.pop_front();
+ }
+ // Otherwise, go to it using the nominal speed.
+ else
+ setPosition(mPos + (dir / (length / speed)));
if (mAction != WALK)
setAction(WALK);
@@ -548,11 +560,14 @@ void Being::logic()
direction |= (dir.y > 0) ? DOWN : UP;
setDirection(direction);
}
- else if (!mPath.empty()) {
- // TODO: Pop as soon as there is a direct unblocked line to the next
- // point on the path.
+ else if (!mPath.empty())
+ {
+ // If the current path node has been reached,
+ // remove it and go to the next one.
mPath.pop_front();
- } else if (mAction == WALK) {
+ }
+ else if (mAction == WALK)
+ {
setAction(STAND);
}
}
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 2744f106..65f1fcc7 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -73,10 +73,10 @@
#include <cassert>
#ifdef TMWSERV_SUPPORT
-// This is shorter then it really needs to be for normal use
-// But if we ever wanted to increase player speed, having this lower
-// Won't hurt
-const short walkingKeyboardDelay = 40;
+// This is the minimal delay between to permitted
+// setDestination() calls using the keyboard.
+// TODO: This can fine tuned later on when running is added...
+const short walkingKeyboardDelay = 1000;
#endif
LocalPlayer *player_node = NULL;
@@ -263,9 +263,10 @@ void LocalPlayer::setGMLevel(int level)
setGM(true);
}
-#ifdef EATHENA_SUPPORT
-void LocalPlayer::nextStep()
+
+void LocalPlayer::nextStep(unsigned char dir = 0)
{
+#ifdef EATHENA_SUPPORT
// TODO: Fix picking up when reaching target (this method is obsolete)
// TODO: Fix holding walking button to keep walking smoothly
if (mPath.empty())
@@ -274,7 +275,7 @@ void LocalPlayer::nextStep()
pickUp(mPickUpTarget);
if (mWalkingDir)
- walk(mWalkingDir);
+ startWalking(mWalkingDir);
}
// TODO: Fix automatically walking within range of target, when wanted
@@ -294,8 +295,66 @@ void LocalPlayer::nextStep()
Player::nextStep();
-}
+#else // TMWSERV_SUPPORT
+ if (!mMap || !dir)
+ return;
+
+ const Vector &pos = getPosition();
+
+ // Compute where the next step will set.
+
+ 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
+ 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;
+
+ // Choose a straight direction when diagonal target is blocked
+ 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 1 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; 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 (dir)
+ {
+ // If the being can't move, just change direction
+ Net::getPlayerHandler()->setDirection(dir);
+ setDirection(dir);
+ }
#endif
+}
+
#ifdef TMWSERV_SUPPORT
bool LocalPlayer::checkInviteRights(const std::string &guildName)
@@ -497,11 +556,17 @@ void LocalPlayer::setWalkingDir(int dir)
// If we're not already walking, start walking.
if (mAction != WALK && dir)
{
- walk(dir);
+ startWalking(dir);
+ }
+#ifdef TMWSERV_SUPPORT
+ else if (mAction == WALK)
+ {
+ nextStep(dir);
}
+#endif
}
-void LocalPlayer::walk(unsigned char dir)
+void LocalPlayer::startWalking(unsigned char dir)
{
// This function is called by setWalkingDir(),
// but also by nextStep() for eAthena...
@@ -535,48 +600,14 @@ void LocalPlayer::walk(unsigned char dir)
if (dir & RIGHT)
dx++;
+#ifdef EATHENA_SUPPORT
// 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;
@@ -585,13 +616,15 @@ void LocalPlayer::walk(unsigned char dir)
{
setDestination(getTileX() + dx, getTileY() + dy);
}
-#endif
else if (dir)
{
// If the being can't move, just change direction
Net::getPlayerHandler()->setDirection(dir);
setDirection(dir);
}
+#else // TMWSERV_SUPPORT
+ nextStep(dir);
+#endif
}
void LocalPlayer::stopWalking(bool sendToServer)
diff --git a/src/localplayer.h b/src/localplayer.h
index e0d5675d..28a1c286 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -122,13 +122,14 @@ class LocalPlayer : public Player
virtual void setAction(Action action, int attackType = 0);
-#ifdef EATHENA_SUPPORT
/**
* Adds a new step when walking before calling super. Also, when
* specified it picks up an item at the end of a path.
*/
- virtual void nextStep();
-#endif
+ virtual void nextStep()
+ { nextStep(0); }
+
+ virtual void nextStep(unsigned char dir);
/**
* Returns the player's inventory.
@@ -386,7 +387,7 @@ class LocalPlayer : public Player
// Colors don't change for local player
virtual void updateColors() {}
- void walk(unsigned char dir);
+ void startWalking(unsigned char dir);
bool mInStorage; /**< Whether storage is currently accessible */