summaryrefslogtreecommitdiff
path: root/src/localplayer.cpp
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-03-15 17:28:16 +0100
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-03-15 17:28:16 +0100
commit21e8d502d07c6cae9580a34dde7587d58e6d3a28 (patch)
treefd8c9fa711d0e2e60f50333f82dbe43ebd9214a5 /src/localplayer.cpp
parent25a2abd09e3b76115ed0b6b1a02cdddc6c1c5bfc (diff)
downloadmana-21e8d502d07c6cae9580a34dde7587d58e6d3a28.tar.gz
mana-21e8d502d07c6cae9580a34dde7587d58e6d3a28.tar.bz2
mana-21e8d502d07c6cae9580a34dde7587d58e6d3a28.tar.xz
mana-21e8d502d07c6cae9580a34dde7587d58e6d3a28.zip
Basically merged the two movement algorithms into one.
This was made in favour of the manaserv way of doing things. I also added a way to keep the original server speed value so the pixel value can be recomputed at each map change, as this was necessary since the speed is given before the first map is loaded. The code is much more simpler now about movement handling, and we can already see improvements on other characters movements in The Mana World with this. Everything can't be perfect the first time; here are bugs identified so far: - Monsters direction isn't updated on TmwAthena for obscure reasons. - Remote players walking animation is sometimes reset on each steps. - When changing map, the local player sometimes walks randomly until the player reacts. Stay tuned!
Diffstat (limited to 'src/localplayer.cpp')
-rw-r--r--src/localplayer.cpp301
1 files changed, 79 insertions, 222 deletions
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 3e59e794..52168237 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -157,15 +157,8 @@ void LocalPlayer::logic()
else
{
// Find whether target is in range
- // TODO: Make this nicer, probably using getPosition() only
- const int rangeX =
- (Net::getNetworkType() == ServerInfo::MANASERV) ?
- abs(mTarget->getPosition().x - getPosition().x) :
- abs(mTarget->getTileX() - getTileX());
- const int rangeY =
- (Net::getNetworkType() == ServerInfo::MANASERV) ?
- abs(mTarget->getPosition().y - getPosition().y) :
- abs(mTarget->getTileY() - getTileY());
+ const int rangeX = abs(mTarget->getPosition().x - getPosition().x);
+ const int rangeY = abs(mTarget->getPosition().y - getPosition().y);
const int attackRange = getAttackRange();
const TargetCursorType targetType = rangeX > attackRange ||
@@ -549,56 +542,22 @@ Position LocalPlayer::getNextWalkPosition(unsigned char dir)
void LocalPlayer::nextTile(unsigned char dir = 0)
{
- if (Net::getNetworkType() == ServerInfo::TMWATHENA)
- {
- // TODO: Fix picking up when reaching target (this method is obsolete)
- // TODO: Fix holding walking button to keep walking smoothly
- if (mPath.empty())
- {
- if (mPickUpTarget)
- pickUp(mPickUpTarget);
-
- if (mWalkingDir)
- startWalking(mWalkingDir);
- }
-
- // TODO: Fix automatically walking within range of target, when wanted
- if (mGoingToTarget && mTarget && withinAttackRange(mTarget))
- {
- mAction = Being::STAND;
- attack(mTarget, true);
- mGoingToTarget = false;
- mPath.clear();
- return;
- }
- else if (mGoingToTarget && !mTarget)
- {
- mGoingToTarget = false;
- mPath.clear();
- }
+ if (!mMap || !dir)
+ return;
+ const Vector &pos = getPosition();
+ Position destination = getNextWalkPosition(dir);
- Being::nextTile();
+ if ((int)pos.x != destination.x
+ || (int)pos.y != destination.y)
+ {
+ setDestination(destination.x, destination.y);
}
- else
+ else if (dir != mDirection)
{
- if (!mMap || !dir)
- return;
-
- const Vector &pos = getPosition();
- Position destination = getNextWalkPosition(dir);
-
- if ((int)pos.x != destination.x
- || (int)pos.y != destination.y)
- {
- setDestination(destination.x, destination.y);
- }
- else if (dir != mDirection)
- {
- // If the being can't move, just change direction
- Net::getPlayerHandler()->setDirection(dir);
- setDirection(dir);
- }
+ // If the being can't move, just change direction
+ Net::getPlayerHandler()->setDirection(dir);
+ setDirection(dir);
}
}
@@ -637,9 +596,10 @@ void LocalPlayer::pickUp(FloorItem *item)
if (!item)
return;
- int dx = item->getTileX() - (int) getPosition().x / mMap->getTileWidth();
- int dy = item->getTileY() - ((int) getPosition().y - 1)
- / mMap->getTileHeight();
+ int tileWidth = mMap->getTileWidth();
+ int tileHeight = mMap->getTileHeight();
+ int dx = item->getTileX() - (int) getPosition().x / tileWidth;
+ int dy = item->getTileY() - ((int) getPosition().y - 1) / tileHeight;
if (dx * dx + dy * dy < 4)
{
@@ -648,17 +608,9 @@ void LocalPlayer::pickUp(FloorItem *item)
}
else
{
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- setDestination(item->getPixelX() + 16, item->getPixelY() + 16);
- mPickUpTarget = item;
- }
- else
- {
- setDestination(item->getTileX(), item->getTileY());
- mPickUpTarget = item;
- stopAttack();
- }
+ setDestination(item->getPixelX() + tileWidth / 2,
+ item->getPixelY() + tileHeight / 2);
+ mPickUpTarget = item;
}
}
@@ -716,12 +668,10 @@ void LocalPlayer::setDestination(int x, int y)
{
Being::setDestination(x, y);
- // Manaserv:
// If the destination given to being class is accepted,
// we inform the Server.
- if ((x == mDest.x && y == mDest.y)
- || Net::getNetworkType() == ServerInfo::TMWATHENA)
- Net::getPlayerHandler()->setDestination(x, y, mDirection);
+ if ((x == mDest.x && y == mDest.y))
+ Net::getPlayerHandler()->setDestination(x, y, mDirection);
}
mPickUpTarget = NULL;
@@ -732,29 +682,26 @@ void LocalPlayer::setWalkingDir(int dir)
{
// This function is called by Game::handleInput()
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- // 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,
- // and the current path hasn't been sent by mouse,
- // then let the path die (1/2 tile after that.)
- // This permit to avoid desyncs with other clients.
- else if (!dir)
- return;
+ // First if player is pressing key for the direction he is already
+ // going, do nothing more...
- // 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;
- }
+ // 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,
+ // and the current path hasn't been sent by mouse,
+ // then let the path die (1/2 tile after that.)
+ // This permit to avoid desyncs with other clients.
+ else if (!dir)
+ 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;
mWalkingDir = dir;
@@ -763,7 +710,7 @@ void LocalPlayer::setWalkingDir(int dir)
{
startWalking(dir);
}
- else if (mAction == MOVE && (Net::getNetworkType() == ServerInfo::MANASERV))
+ else if (mAction == MOVE)
{
nextTile(dir);
}
@@ -779,13 +726,8 @@ void LocalPlayer::startWalking(unsigned char dir)
if (mAction == MOVE && !mPath.empty())
{
// Just finish the current action, otherwise we get out of sync
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- const Vector &pos = getPosition();
- Being::setDestination(pos.x, pos.y);
- }
- else
- Being::setDestination(getTileX(), getTileY());
+ const Vector &pos = getPosition();
+ Being::setDestination(pos.x, pos.y);
return;
}
@@ -800,37 +742,9 @@ void LocalPlayer::startWalking(unsigned char dir)
dx++;
// Update the direction when the walk just start
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- setDirection(dir);
+ setDirection(dir);
- if (Net::getNetworkType() == ServerInfo::TMWATHENA)
- {
- // Prevent skipping corners over colliding tiles
- if (dx && !mMap->getWalk(getTileX() + dx, getTileY(), getWalkMask()))
- dx = 0;
- if (dy && !mMap->getWalk(getTileX(), getTileY() + dy, getWalkMask()))
- dy = 0;
-
- // Choose a straight direction when diagonal target is blocked
- 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);
- }
- else if (dir != mDirection)
- {
- // If the being can't move, just change direction
- Net::getPlayerHandler()->setDirection(dir);
- setDirection(dir);
- }
- }
- else
- nextTile(dir);
+ nextTile(dir);
}
void LocalPlayer::stopWalking(bool sendToServer)
@@ -881,15 +795,12 @@ void LocalPlayer::emote(Uint8 emotion)
void LocalPlayer::attack(Being *target, bool keep)
{
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- if (mLastAction != -1)
- return;
+ if (mLastAction != -1)
+ return;
- // Can only attack when standing still
- if (mAction != STAND && mAction != ATTACK)
- return;
- }
+ // Can only attack when standing still
+ if (mAction != STAND && mAction != ATTACK)
+ return;
mKeepAttacking = keep;
@@ -902,61 +813,28 @@ void LocalPlayer::attack(Being *target, bool keep)
setTarget(target);
}
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- Vector plaPos = this->getPosition();
- Vector tarPos = mTarget->getPosition();
- int dist_x = plaPos.x - tarPos.x;
- int dist_y = plaPos.y - tarPos.y;
+ Vector plaPos = this->getPosition();
+ Vector tarPos = mTarget->getPosition();
+ int dist_x = plaPos.x - tarPos.x;
+ int dist_y = plaPos.y - tarPos.y;
- if (abs(dist_y) >= abs(dist_x))
- {
- if (dist_y < 0)
- setDirection(DOWN);
- else
- setDirection(UP);
- }
+ if (abs(dist_y) >= abs(dist_x))
+ {
+ if (dist_y < 0)
+ setDirection(DOWN);
else
- {
- if (dist_x < 0)
- setDirection(RIGHT);
- else
- setDirection(LEFT);
- }
-
- mLastAction = tick_time;
+ setDirection(UP);
}
else
{
- int dist_x = target->getTileX() - getTileX();
- int dist_y = target->getTileY() - getTileY();
-
- // Must be standing to attack
- if (mAction != STAND)
- return;
-
- Uint8 direction = 0;
- if (abs(dist_y) >= abs(dist_x))
- {
- if (dist_y > 0)
- direction = DOWN;
- else
- direction = UP;
- }
+ if (dist_x < 0)
+ setDirection(RIGHT);
else
- {
- if (dist_x > 0)
- direction = RIGHT;
- else
- direction = LEFT;
- }
- Net::getPlayerHandler()->setDirection(direction);
- setDirection(direction);
-
- mActionTime = tick_time;
- mTargetTime = tick_time;
+ setDirection(LEFT);
}
+ mLastAction = tick_time;
+
setAction(ATTACK);
if (mEquippedWeapon)
@@ -966,11 +844,11 @@ void LocalPlayer::attack(Being *target, bool keep)
sound.playSfx(soundFile);
}
else
+ {
sound.playSfx(paths.getValue("attackSfxFile", "fist-swish.ogg"));
+ }
Net::getPlayerHandler()->attack(target->getId());
- if ((Net::getNetworkType() == ServerInfo::TMWATHENA) && !keep)
- stopAttack();
}
void LocalPlayer::stopAttack()
@@ -1060,44 +938,23 @@ int LocalPlayer::getAttackRange()
bool LocalPlayer::withinAttackRange(Being *target)
{
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- const Vector &targetPos = target->getPosition();
- const Vector &pos = getPosition();
- const int dx = abs(targetPos.x - pos.x);
- const int dy = abs(targetPos.y - pos.y);
- const int range = getAttackRange();
-
- return !(dx > range || dy > range);
- }
- else
- {
- int dist_x = abs(target->getTileX() - getTileX());
- int dist_y = abs(target->getTileY() - getTileY());
-
- if (dist_x > getAttackRange() || dist_y > getAttackRange())
- return false;
+ const Vector &targetPos = target->getPosition();
+ const Vector &pos = getPosition();
+ const int dx = abs(targetPos.x - pos.x);
+ const int dy = abs(targetPos.y - pos.y);
+ const int range = getAttackRange();
- return true;
- }
+ return !(dx > range || dy > range);
}
void LocalPlayer::setGotoTarget(Being *target)
{
mLastTarget = -1;
- if (Net::getNetworkType() == ServerInfo::MANASERV)
- {
- mTarget = target;
- mGoingToTarget = true;
- const Vector &targetPos = target->getPosition();
- setDestination(targetPos.x, targetPos.y);
- }
- else
- {
- setTarget(target);
- mGoingToTarget = true;
- setDestination(target->getTileX(), target->getTileY());
- }
+
+ mTarget = target;
+ mGoingToTarget = true;
+ const Vector &targetPos = target->getPosition();
+ setDestination(targetPos.x, targetPos.y);
}
void LocalPlayer::addMessageToQueue(const std::string &message, int color)