summaryrefslogtreecommitdiff
path: root/src/localplayer.cpp
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-04-26 23:40:37 +0200
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-04-26 23:40:37 +0200
commit2d0e84449b14615bdacb6f897791628662bbfd39 (patch)
tree08019ae6c24c6da25e25da027d04ad008c25d6a2 /src/localplayer.cpp
parent42605753159d7b63276351311e0fd43874a3366b (diff)
parent0056412ed33b941d72a175dcd3f025abcd8fc02b (diff)
downloadmana-2d0e84449b14615bdacb6f897791628662bbfd39.tar.gz
mana-2d0e84449b14615bdacb6f897791628662bbfd39.tar.bz2
mana-2d0e84449b14615bdacb6f897791628662bbfd39.tar.xz
mana-2d0e84449b14615bdacb6f897791628662bbfd39.zip
Made the client use a unique kind of movement code.
This is fixng many issues and (hopefully) will make the movement rendering much smoother. Merge branch 'master' of gitorious.org:~bertram/mana/mana-movement-code-merge Conflicts: src/being.cpp src/net/manaserv/beinghandler.cpp Resolves: TMW-Mantis #946. Reviewed-by: Thorbjorn.
Diffstat (limited to 'src/localplayer.cpp')
-rw-r--r--src/localplayer.cpp359
1 files changed, 117 insertions, 242 deletions
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index d710a51f..99e42411 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -69,7 +69,7 @@ LocalPlayer *player_node = NULL;
LocalPlayer::LocalPlayer(int id, int subtype):
Being(id, PLAYER, subtype, 0),
- mAttackRange(0),
+ mAttackRange(ATTACK_RANGE_NOT_SET),
mTargetTime(-1),
mLastTarget(-1),
mTarget(NULL),
@@ -114,14 +114,10 @@ void LocalPlayer::logic()
{
if (mMessageTime == 0)
{
- //const Vector &pos = getPosition();
-
MessagePair info = mMessages.front();
particleEngine->addTextRiseFadeOutEffect(
info.first,
- /*(int) pos.x,
- (int) pos.y - 48,*/
getPixelX(),
getPixelY() - 48,
&userPalette->getColor(info.second),
@@ -157,15 +153,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 +538,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 +592,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 +604,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->getTileX() * tileWidth + tileWidth / 2,
+ item->getTileY() * tileHeight + tileHeight / 2);
+ mPickUpTarget = item;
}
}
@@ -711,17 +659,40 @@ void LocalPlayer::setTarget(Being *target)
void LocalPlayer::setDestination(int x, int y)
{
+ int srcX = x;
+ int srcY = y;
+ int dstX = (int)mDest.x;
+ int dstY = (int)mDest.y;
+ int tileWidth = mMap->getTileWidth();
+ int tileHeight = mMap->getTileHeight();
+ if (!Net::getPlayerHandler()->usePixelPrecision())
+ {
+ // For tile-based clients, we accept positions on the same tile.
+ srcX = srcX / tileWidth;
+ srcY = srcY / tileHeight;
+ dstX = dstX / tileWidth;
+ dstY = dstY / tileHeight;
+ }
+
// Only send a new message to the server when destination changes
- if (x != mDest.x || y != mDest.y)
+ if (srcX != dstX || srcY != dstY)
{
Being::setDestination(x, y);
+ // Note: Being::setDestination() updates mDest, so we get the new
+ // destination.
+ dstX = (int)mDest.x;
+ dstY = (int)mDest.y;
+
+ if (!Net::getPlayerHandler()->usePixelPrecision())
+ {
+ dstX = dstX / tileWidth;
+ dstY = dstY / tileHeight;
+ }
- // 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 (srcX == dstX && srcY == dstY)
+ Net::getPlayerHandler()->setDestination(x, y, mDirection);
}
mPickUpTarget = NULL;
@@ -732,29 +703,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 +731,7 @@ void LocalPlayer::setWalkingDir(int dir)
{
startWalking(dir);
}
- else if (mAction == MOVE && (Net::getNetworkType() == ServerInfo::MANASERV))
+ else if (mAction == MOVE)
{
nextTile(dir);
}
@@ -779,13 +747,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 +763,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 +816,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 +834,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 +865,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()
@@ -1035,69 +934,45 @@ void LocalPlayer::pickedUp(const ItemInfo &itemInfo, int amount,
}
}
-int LocalPlayer::getAttackRange()
+void LocalPlayer::setAttackRange(int range)
{
- if (mAttackRange > -1)
+ // When the range is more than the minimal, we accept it
+ if (range > ATTACK_RANGE_NOT_SET)
{
- return mAttackRange;
+ mAttackRange = range;
}
- else
+ else if (Net::getNetworkType() == ServerInfo::TMWATHENA)
{
- if (Net::getNetworkType() == ServerInfo::TMWATHENA)
+ // TODO: Fix this to be more generic
+ Item *weapon = PlayerInfo::getEquipment(TmwAthena::EQUIP_FIGHT1_SLOT);
+ if (weapon)
{
- // TODO: Fix this to be more generic
- Item *weapon = PlayerInfo::getEquipment(
- TmwAthena::EQUIP_FIGHT1_SLOT);
- if (weapon)
- {
- const ItemInfo info = weapon->getInfo();
- return info.getAttackRange();
- }
+ const ItemInfo info = weapon->getInfo();
+ if (info.getAttackRange() > ATTACK_RANGE_NOT_SET)
+ mAttackRange = info.getAttackRange();
}
- return 48; // unarmed range
}
}
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)