diff options
author | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-03-15 17:28:16 +0100 |
---|---|---|
committer | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-03-15 17:28:16 +0100 |
commit | 21e8d502d07c6cae9580a34dde7587d58e6d3a28 (patch) | |
tree | fd8c9fa711d0e2e60f50333f82dbe43ebd9214a5 /src/net | |
parent | 25a2abd09e3b76115ed0b6b1a02cdddc6c1c5bfc (diff) | |
download | mana-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/net')
-rw-r--r-- | src/net/manaserv/beinghandler.cpp | 39 | ||||
-rw-r--r-- | src/net/manaserv/beinghandler.h | 8 | ||||
-rw-r--r-- | src/net/manaserv/playerhandler.cpp | 33 | ||||
-rw-r--r-- | src/net/manaserv/playerhandler.h | 4 | ||||
-rw-r--r-- | src/net/playerhandler.h | 13 | ||||
-rw-r--r-- | src/net/tmwa/beinghandler.cpp | 57 | ||||
-rw-r--r-- | src/net/tmwa/beinghandler.h | 3 | ||||
-rw-r--r-- | src/net/tmwa/charserverhandler.cpp | 6 | ||||
-rw-r--r-- | src/net/tmwa/gamehandler.cpp | 15 | ||||
-rw-r--r-- | src/net/tmwa/gamehandler.h | 7 | ||||
-rw-r--r-- | src/net/tmwa/playerhandler.cpp | 75 | ||||
-rw-r--r-- | src/net/tmwa/playerhandler.h | 4 |
12 files changed, 180 insertions, 84 deletions
diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp index 6e9b3645..220ecfba 100644 --- a/src/net/manaserv/beinghandler.cpp +++ b/src/net/manaserv/beinghandler.cpp @@ -89,37 +89,6 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) } } -Vector BeingHandler::giveSpeedInPixelsPerTicks(float speedInTilesPerSeconds) -{ - Vector speedInTicks; - Game *game = Game::instance(); - Map *map = 0; - if (game) - { - map = game->getCurrentMap(); - if (map) - { - speedInTicks.x = speedInTilesPerSeconds - * (float)map->getTileWidth() - / 1000 * (float) MILLISECONDS_IN_A_TICK; - speedInTicks.y = speedInTilesPerSeconds - * (float)map->getTileHeight() - / 1000 * (float) MILLISECONDS_IN_A_TICK; - } - } - - if (!game || !map) - { - speedInTicks.x = speedInTicks.y = 0; - logger->log("Manaserv::BeingHandler: Speed wasn't given back" - " because game/Map not initialized."); - } - // We don't use z for now. - speedInTicks.z = 0; - - return speedInTicks; -} - static void handleLooks(Being *being, Net::MessageIn &msg) { // Order of sent slots. Has to be in sync with the server code. @@ -237,12 +206,10 @@ void BeingHandler::handleBeingsMoveMessage(Net::MessageIn &msg) * The being's speed is transfered in tiles per second * 10 * to keep it transferable in a Byte. * We set it back to tiles per second and in a float. - * Then, we translate it in pixels per ticks, to correspond - * with the Being::logic() function calls - * @see MILLISECONDS_IN_A_TICK */ - being->setWalkSpeed( - giveSpeedInPixelsPerTicks((float) speed / 10)); + float speedTilesSeconds = (float) speed / 10; + being->setMoveSpeed(Vector(speedTilesSeconds, speedTilesSeconds, + 0)); } // Ignore messages from the server for the local player diff --git a/src/net/manaserv/beinghandler.h b/src/net/manaserv/beinghandler.h index 2e9eb333..04c766d9 100644 --- a/src/net/manaserv/beinghandler.h +++ b/src/net/manaserv/beinghandler.h @@ -35,14 +35,6 @@ class BeingHandler : public MessageHandler void handleMessage(Net::MessageIn &msg); - /** - * Translate a given speed in tiles per seconds - * into pixels per ticks. - * Used to optimize Being::logic() calls. - * @see MILLISECONDS_IN_A_TICKS - */ - static Vector giveSpeedInPixelsPerTicks(float speedInTilesPerSeconds); - private: void handleBeingAttackMessage(Net::MessageIn &msg); void handleBeingEnterMessage(Net::MessageIn &msg); diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp index c071ca04..38eb2678 100644 --- a/src/net/manaserv/playerhandler.cpp +++ b/src/net/manaserv/playerhandler.cpp @@ -412,10 +412,37 @@ int PlayerHandler::getJobLocation() return -1; } -Vector PlayerHandler::getDefaultWalkSpeed() +Vector PlayerHandler::getDefaultMoveSpeed() { - // Return translation in pixels per ticks. - return ManaServ::BeingHandler::giveSpeedInPixelsPerTicks(6.0f); + // Return default speed at 6 tiles per second. + return Vector(6.0f, 6.0f, 0.0f); +} + +Vector PlayerHandler::getPixelsPerTickMoveSpeed(Vector speed, Map *map) +{ + // We don't use z for now. + speed.z = 0; + + Game *game = Game::instance(); + if (game && !map) + map = game->getCurrentMap(); + + if (!map) + { + logger->log("Manaserv::PlayerHandler: Speed wasn't given back" + " because Map not initialized."); + speed.x = speed.y = 0; + return speed; + } + + speed.x = speed.x + * (float)map->getTileWidth() + / 1000 * (float) MILLISECONDS_IN_A_TICK; + speed.y = speed.y + * (float)map->getTileHeight() + / 1000 * (float) MILLISECONDS_IN_A_TICK; + + return speed; } } // namespace ManaServ diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h index 5796b0d3..6069c6da 100644 --- a/src/net/manaserv/playerhandler.h +++ b/src/net/manaserv/playerhandler.h @@ -65,7 +65,9 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler int getJobLocation(); - Vector getDefaultWalkSpeed(); + Vector getDefaultMoveSpeed(); + + Vector getPixelsPerTickMoveSpeed(Vector speed, Map *map = 0); private: void handleMapChangeMessage(Net::MessageIn &msg); diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h index d7676a92..23277062 100644 --- a/src/net/playerhandler.h +++ b/src/net/playerhandler.h @@ -62,7 +62,18 @@ class PlayerHandler virtual int getJobLocation() = 0; - virtual Vector getDefaultWalkSpeed() = 0; + /** + * Get the original default movement speed. + * Example: + * In ticks per tiles for eAthena + * In pixels per second for Manaserv + */ + virtual Vector getDefaultMoveSpeed() = 0; + + /** + * Convert the original speed in pixel per tick for internal use. + */ + virtual Vector getPixelsPerTickMoveSpeed(Vector speed, Map *map = 0) = 0; }; } // namespace Net diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp index 61491692..ddb15428 100644 --- a/src/net/tmwa/beinghandler.cpp +++ b/src/net/tmwa/beinghandler.cpp @@ -20,11 +20,13 @@ */ #include "net/tmwa/beinghandler.h" +#include "net/tmwa/playerhandler.h" #include "actorspritemanager.h" #include "being.h" #include "client.h" #include "effectmanager.h" +#include "game.h" #include "guild.h" #include "localplayer.h" #include "log.h" @@ -101,7 +103,8 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) return; int id; - short job, speed, gender; + short job, gender; + float speed; Uint16 headTop, headMid, headBottom; Uint16 shoes, gloves; Uint16 weapon, shield; @@ -114,13 +117,18 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) Being *srcBeing, *dstBeing; int hairStyle, hairColor, flag; + // Prepare useful translation variables + Map *map = Game::instance()->getCurrentMap(); + int tileWidth = map->getTileWidth(); + int tileHeight = map->getTileHeight(); + switch (msg.getId()) { case SMSG_BEING_VISIBLE: case SMSG_BEING_MOVE: // Information about a being in range id = msg.readInt32(); - speed = msg.readInt16(); + speed = (float)msg.readInt16(); stunMode = msg.readInt16(); // opt1 statusEffects = msg.readInt16(); // opt2 statusEffects |= ((Uint32)msg.readInt16()) << 16; // option @@ -146,15 +154,14 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) if (msg.getId() == SMSG_BEING_VISIBLE) { dstBeing->clearPath(); - dstBeing->setActionTime(tick_time); dstBeing->setAction(Being::STAND); } - // Prevent division by 0 when calculating frame - if (speed == 0) { speed = 150; } + if (speed == 0) + speed = 150.0f; // In ticks per tile * 10 - dstBeing->setWalkSpeed(Vector(speed, speed, 0)); + dstBeing->setMoveSpeed(Vector(speed / 10, speed / 10)); dstBeing->setSubtype(job); hairStyle = msg.readInt16(); weapon = msg.readInt16(); @@ -206,7 +213,12 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) Uint16 srcX, srcY, dstX, dstY; msg.readCoordinatePair(srcX, srcY, dstX, dstY); dstBeing->setAction(Being::STAND); - dstBeing->setTileCoords(srcX, srcY); + Vector pos(srcX * tileWidth + tileWidth / 2, + srcY * tileHeight + tileHeight / 2); + dstBeing->setPosition(pos); + // We turn the destination back to a pixel one. + dstX = dstX * tileWidth + tileWidth / 2; + dstY = dstY * tileHeight + tileHeight / 2; dstBeing->setDestination(dstX, dstY); } else @@ -214,7 +226,9 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) Uint8 dir; Uint16 x, y; msg.readCoordinates(x, y, dir); - dstBeing->setTileCoords(x, y); + Vector pos(x * tileWidth + tileWidth / 2, + y * tileHeight + tileHeight / 2); + dstBeing->setPosition(pos); dstBeing->setDirection(dir); } @@ -256,9 +270,10 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) msg.readInt32(); // Server tick dstBeing->setAction(Being::STAND); - dstBeing->setTileCoords(srcX, srcY); - dstBeing->setDestination(dstX, dstY); - + dstBeing->setPosition(Vector(srcX * tileWidth + tileWidth / 2, + srcY * tileHeight + tileHeight / 2)); + dstBeing->setDestination(dstX * tileWidth + tileWidth / 2, + dstY * tileHeight + tileHeight / 2); break; case SMSG_BEING_REMOVE: @@ -519,7 +534,12 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) } } - dstBeing->setWalkSpeed(Vector(speed, speed, 0)); + // The original speed is ticks per tile * 10 + if (speed) + dstBeing->setMoveSpeed(Vector(speed / 10, speed / 10)); + else + dstBeing->setMoveSpeed(Net::getPlayerHandler()->getDefaultMoveSpeed()); + dstBeing->setSubtype(job); hairStyle = msg.readInt16(); weapon = msg.readInt16(); @@ -561,15 +581,18 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) { Uint16 srcX, srcY, dstX, dstY; msg.readCoordinatePair(srcX, srcY, dstX, dstY); - dstBeing->setTileCoords(srcX, srcY); - dstBeing->setDestination(dstX, dstY); + dstBeing->setPosition(Vector(srcX * tileWidth + tileWidth / 2, + srcY * tileHeight + tileHeight / 2)); + dstBeing->setDestination(dstX * tileWidth + tileWidth / 2, + dstY * tileHeight + tileHeight / 2); } else { Uint8 dir; Uint16 x, y; msg.readCoordinates(x, y, dir); - dstBeing->setTileCoords(x, y); + dstBeing->setPosition(Vector(x * tileWidth + tileWidth / 2, + y * tileHeight + tileHeight / 2)); dstBeing->setDirection(dir); } @@ -598,7 +621,6 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) msg.readInt8(); // Lv msg.readInt8(); // unknown - dstBeing->setActionTime(tick_time); dstBeing->reset(); dstBeing->setStunMode(stunMode); @@ -628,7 +650,8 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) Uint16 x, y; x = msg.readInt16(); y = msg.readInt16(); - dstBeing->setTileCoords(x, y); + dstBeing->setPosition(Vector(x * tileWidth + tileWidth / 2, + y * tileHeight + tileHeight / 2)); if (dstBeing->getCurrentAction() == Being::MOVE) dstBeing->setAction(Being::STAND); } diff --git a/src/net/tmwa/beinghandler.h b/src/net/tmwa/beinghandler.h index ab833af0..32b4a7bd 100644 --- a/src/net/tmwa/beinghandler.h +++ b/src/net/tmwa/beinghandler.h @@ -22,6 +22,9 @@ #ifndef NET_TA_BEINGHANDLER_H #define NET_TA_BEINGHANDLER_H +#include "vector.h" + +#include "net/net.h" #include "net/tmwa/messagehandler.h" namespace TmwAthena { diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index 1063ee39..e6dc84a2 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -185,7 +185,11 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg) mNetwork->disconnect(); Client::setState(STATE_CHANGE_MAP); - player_node->setTileCoords(x, y); + Map *map = player_node->getMap(); + int tileWidth = map->getTileWidth(); + int tileHeight = map->getTileHeight(); + player_node->setPosition(Vector(x * tileWidth + tileWidth / 2, + y * tileHeight + tileHeight / 2)); player_node->setMap(0); } break; diff --git a/src/net/tmwa/gamehandler.cpp b/src/net/tmwa/gamehandler.cpp index 63f5fcec..a72c12da 100644 --- a/src/net/tmwa/gamehandler.cpp +++ b/src/net/tmwa/gamehandler.cpp @@ -76,7 +76,8 @@ void GameHandler::handleMessage(Net::MessageIn &msg) x, y, direction); // Switch now or we'll have problems Client::setState(STATE_GAME); - player_node->setTileCoords(x, y); + // Stores the position until the map is loaded. + mTileX = x; mTileY = y; } break; case SMSG_SERVER_PING: @@ -111,7 +112,17 @@ void GameHandler::event(Channels channel, const Mana::Event &event) { if (event.getName() == EVENT_ENGINESINITALIZED) { - Game::instance()->changeMap(mMap); + Game *game = Game::instance(); + game->changeMap(mMap); + Map *map = game->getCurrentMap(); + int tileWidth = map->getTileWidth(); + int tileHeight = map->getTileHeight(); + if (mTileX && mTileY) + { + player_node->setPosition(Vector(mTileX * tileWidth + tileWidth / 2, + mTileY * tileHeight + tileHeight / 2)); + mTileX = mTileY = 0; + } } else if (event.getName() == EVENT_MAPLOADED) { diff --git a/src/net/tmwa/gamehandler.h b/src/net/tmwa/gamehandler.h index 18317445..7aa18b12 100644 --- a/src/net/tmwa/gamehandler.h +++ b/src/net/tmwa/gamehandler.h @@ -65,8 +65,13 @@ class GameHandler : public MessageHandler, public Net::GameHandler, bool canUseMagicBar() const { return true; } private: - std::string mMap; + std::string mMap; ///< Keeps the map filename. int mCharID; /// < Saved for map-server switching + /** + * Keeps the local character position until the map is loaded + * to permit the translation in pixels. + */ + int mTileX, mTileY; }; } // namespace TmwAthena diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index b82968a3..181ff39c 100644 --- a/src/net/tmwa/playerhandler.cpp +++ b/src/net/tmwa/playerhandler.cpp @@ -20,7 +20,9 @@ */ #include "net/tmwa/playerhandler.h" +#include "net/tmwa/beinghandler.h" +#include "client.h" #include "event.h" #include "game.h" #include "localplayer.h" @@ -198,20 +200,23 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) float scrollOffsetX = 0.0f; float scrollOffsetY = 0.0f; - /* Scroll if neccessary */ + /* Scroll if necessary */ + Map *map = game->getCurrentMap(); + int tileWidth = map->getTileWidth(); + int tileHeight = map->getTileHeight(); + int tileX = player_node->getTileX(); + int tileY = player_node->getTileY(); if (!sameMap - || (abs(x - player_node->getTileX()) > MAP_TELEPORT_SCROLL_DISTANCE) - || (abs(y - player_node->getTileY()) > MAP_TELEPORT_SCROLL_DISTANCE)) + || (abs(x - tileX) > MAP_TELEPORT_SCROLL_DISTANCE) + || (abs(y - tileY) > MAP_TELEPORT_SCROLL_DISTANCE)) { - Map *map = game->getCurrentMap(); - scrollOffsetX = (x - player_node->getTileX()) - * map->getTileWidth(); - scrollOffsetY = (y - player_node->getTileY()) - * map->getTileHeight(); + scrollOffsetX = (x - tileX) * tileWidth; + scrollOffsetY = (y - tileY) * tileHeight; } player_node->setAction(Being::STAND); - player_node->setTileCoords(x, y); + player_node->setPosition(Vector(x * tileWidth + tileWidth / 2, + y * tileHeight + tileHeight / 2)); logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX, (int) scrollOffsetY); @@ -228,7 +233,8 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) switch (type) { case 0x0000: - player_node->setWalkSpeed(Vector(value, value, 0)); + player_node->setMoveSpeed(Vector(value / 10, + value / 10, 0)); break; case 0x0004: break; // manner case 0x0005: PlayerInfo::setAttribute(HP, value); break; @@ -552,8 +558,12 @@ void PlayerHandler::setDirection(char direction) void PlayerHandler::setDestination(int x, int y, int direction) { + // The destination coordinates are received in pixel, so we translate them + // into tiles. + Map *map = Game::instance()->getCurrentMap(); MessageOut outMsg(CMSG_PLAYER_CHANGE_DEST); - outMsg.writeCoordinates(x, y, direction); + outMsg.writeCoordinates(x / map->getTileWidth(), y / map->getTileHeight(), + direction); } void PlayerHandler::changeAction(Being::Action action) @@ -602,11 +612,50 @@ int PlayerHandler::getJobLocation() return JOB; } -Vector PlayerHandler::getDefaultWalkSpeed() +Vector PlayerHandler::getDefaultMoveSpeed() { // Return an normalized speed for any side // as the offset is calculated elsewhere. - return Vector(150, 150, 0); + // in ticks per tile. + return Vector(15.0f, 15.0f, 0.0f); +} + +Vector PlayerHandler::getPixelsPerTickMoveSpeed(Vector speed, Map *map) +{ + Game *game = Game::instance(); + + if (game && !map) + map = game->getCurrentMap(); + + if (!map) + { + logger->log("TmwAthena::PlayerHandler: Speed not given back" + " because Map not yet initialized."); + return Vector(0.0f, 0.0f, 0.0f); + } + + if (speed.x == 0 || speed.y == 0) + { + logger->log("TmwAthena::PlayerHandler: " + "Invalid Speed given from server."); + speed = getDefaultMoveSpeed(); + } + + Vector speedInTicks; + + // We don't use z for now. + speedInTicks.z = 0; + + speedInTicks.x = ((1 / speed.x) * 1000) / MILLISECONDS_IN_A_TICK; + speedInTicks.x = speedInTicks.x + * (float)map->getTileWidth() + / 1000 * (float) MILLISECONDS_IN_A_TICK; + speedInTicks.y = ((1 / speed.y) * 1000) / MILLISECONDS_IN_A_TICK; + speedInTicks.y = speedInTicks.y + * (float)map->getTileHeight() + / 1000 * (float) MILLISECONDS_IN_A_TICK; + + return speedInTicks; } } // namespace TmwAthena diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h index cb352110..4df74350 100644 --- a/src/net/tmwa/playerhandler.h +++ b/src/net/tmwa/playerhandler.h @@ -58,7 +58,9 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler int getJobLocation(); - Vector getDefaultWalkSpeed(); + Vector getDefaultMoveSpeed(); + + Vector getPixelsPerTickMoveSpeed(Vector speed, Map *map = 0); }; } // namespace TmwAthena |