summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game.cpp63
-rw-r--r--src/localplayer.cpp212
2 files changed, 147 insertions, 128 deletions
diff --git a/src/game.cpp b/src/game.cpp
index 357092ae..60b13a06 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -147,7 +147,15 @@ EffectManager *effectManager = NULL;
ChatTab *localChatTab = NULL;
-const int MAX_TIME = 10000;
+/**
+ * Tells the max tick value,
+ * setting it back to zero (and start again).
+ */
+const int MAX_TICK_VALUE = 10000;
+/**
+ * Set the milliseconds value of a tick time.
+ */
+const int MILLISECONDS_IN_A_TICK = 10;
/**
* Listener used for exiting handling.
@@ -167,16 +175,19 @@ namespace {
/**
* Advances game logic counter.
+ * Called every 10 milliseconds by SDL_AddTimer()
+ * @see MILLISECONDS_IN_A_TICK value
*/
Uint32 nextTick(Uint32 interval, void *param)
{
tick_time++;
- if (tick_time == MAX_TIME) tick_time = 0;
+ if (tick_time == MAX_TICK_VALUE) tick_time = 0;
return interval;
}
/**
* Updates fps.
+ * Called every seconds by SDL_AddTimer()
*/
Uint32 nextSecond(Uint32 interval, void *param)
{
@@ -186,12 +197,17 @@ Uint32 nextSecond(Uint32 interval, void *param)
return interval;
}
+/**
+ * @return the elapsed time in milliseconds
+ * between two tick values.
+ */
int get_elapsed_time(int start_time)
{
if (start_time <= tick_time)
- return (tick_time - start_time) * 10;
+ return (tick_time - start_time) * MILLISECONDS_IN_A_TICK;
else
- return (tick_time + (MAX_TIME - start_time)) * 10;
+ return (tick_time + (MAX_TICK_VALUE - start_time))
+ * MILLISECONDS_IN_A_TICK;
}
/**
@@ -302,7 +318,7 @@ Game::Game():
// Initialize logic and seconds counters
tick_time = 0;
- mLogicCounterId = SDL_AddTimer(10, nextTick, NULL);
+ mLogicCounterId = SDL_AddTimer(MILLISECONDS_IN_A_TICK, nextTick, NULL);
mSecondsCounterId = SDL_AddTimer(1000, nextSecond, NULL);
// Initialize frame limiting
@@ -421,7 +437,7 @@ void Game::optionChanged(const std::string &name)
mMinFrameTime = fpsLimit ? 1000 / fpsLimit : 0;
// Reset draw time to current time
- mDrawTime = tick_time * 10;
+ mDrawTime = tick_time * MILLISECONDS_IN_A_TICK;
}
void Game::logic()
@@ -429,7 +445,7 @@ void Game::logic()
// mDrawTime has a higher granularity than gameTime in order to be able to
// work with minimum frame durations in milliseconds.
int gameTime = tick_time;
- mDrawTime = tick_time * 10;
+ mDrawTime = tick_time * MILLISECONDS_IN_A_TICK;
while (!done)
{
@@ -461,18 +477,18 @@ void Game::logic()
mDrawTime += mMinFrameTime;
// Make sure to wrap mDrawTime, since tick_time will wrap.
- if (mDrawTime > MAX_TIME * 10)
- mDrawTime -= MAX_TIME * 10;
+ if (mDrawTime > MAX_TICK_VALUE * MILLISECONDS_IN_A_TICK)
+ mDrawTime -= MAX_TICK_VALUE * MILLISECONDS_IN_A_TICK;
}
else
{
- SDL_Delay(10);
+ SDL_Delay(MILLISECONDS_IN_A_TICK);
}
}
else
{
- SDL_Delay(10);
- mDrawTime = tick_time * 10;
+ SDL_Delay(MILLISECONDS_IN_A_TICK);
+ mDrawTime = tick_time * MILLISECONDS_IN_A_TICK;
}
// Handle network stuff
@@ -959,29 +975,8 @@ void Game::handleInput()
direction |= Being::RIGHT;
}
-#ifdef TMWSERV_SUPPORT
- // First if player is pressing key for the direction he is already
- // going
- if (direction == player_node->getWalkingDir())
- {
- player_node->setWalkingDir(direction);
- }
- // 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
- else if (direction && direction != player_node->getWalkingDir())
- {
- player_node->stopWalking(false);
- player_node->setWalkingDir(direction);
- }
- // Else, he is not pressing a key, stop (sending to server)
- else
- {
- player_node->stopWalking(true);
- }
-#else
player_node->setWalkingDir(direction);
-#endif
+
// Attacking monsters
if (keyboard.isKeyActive(keyboard.KEY_ATTACK) ||
(joystick && joystick->buttonPressed(0)))
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);
}
}