diff options
author | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-04-26 23:40:37 +0200 |
---|---|---|
committer | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-04-26 23:40:37 +0200 |
commit | 2d0e84449b14615bdacb6f897791628662bbfd39 (patch) | |
tree | 08019ae6c24c6da25e25da027d04ad008c25d6a2 /src/localplayer.cpp | |
parent | 42605753159d7b63276351311e0fd43874a3366b (diff) | |
parent | 0056412ed33b941d72a175dcd3f025abcd8fc02b (diff) | |
download | mana-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.cpp | 359 |
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) |