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/net | |
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/net')
-rw-r--r-- | src/net/manaserv/beinghandler.cpp | 38 | ||||
-rw-r--r-- | src/net/manaserv/beinghandler.h | 8 | ||||
-rw-r--r-- | src/net/manaserv/gamehandler.cpp | 3 | ||||
-rw-r--r-- | src/net/manaserv/itemhandler.cpp | 18 | ||||
-rw-r--r-- | src/net/manaserv/playerhandler.cpp | 31 | ||||
-rw-r--r-- | src/net/manaserv/playerhandler.h | 7 | ||||
-rw-r--r-- | src/net/playerhandler.h | 20 | ||||
-rw-r--r-- | src/net/tmwa/beinghandler.cpp | 108 | ||||
-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/inventoryhandler.cpp | 23 | ||||
-rw-r--r-- | src/net/tmwa/itemhandler.cpp | 14 | ||||
-rw-r--r-- | src/net/tmwa/playerhandler.cpp | 60 | ||||
-rw-r--r-- | src/net/tmwa/playerhandler.h | 7 |
15 files changed, 247 insertions, 118 deletions
diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp index 414f914d..f8cefecf 100644 --- a/src/net/manaserv/beinghandler.cpp +++ b/src/net/manaserv/beinghandler.cpp @@ -91,37 +91,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. @@ -246,11 +215,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/gamehandler.cpp b/src/net/manaserv/gamehandler.cpp index 040a5e6c..63f84fd1 100644 --- a/src/net/manaserv/gamehandler.cpp +++ b/src/net/manaserv/gamehandler.cpp @@ -141,7 +141,8 @@ void GameHandler::gameLoading() chatHandler->connect(); // Attack range from item DB - player_node->setAttackRange(-1); + // TODO: Deharcode it through equipment handling + player_node->setAttackRange(48); } } // namespace ManaServ diff --git a/src/net/manaserv/itemhandler.cpp b/src/net/manaserv/itemhandler.cpp index af3457db..d8365d79 100644 --- a/src/net/manaserv/itemhandler.cpp +++ b/src/net/manaserv/itemhandler.cpp @@ -26,8 +26,6 @@ #include "net/manaserv/manaserv_protocol.h" #include "net/manaserv/messagein.h" -#include "game.h" -#include "map.h" #include "log.h" namespace ManaServ { @@ -58,21 +56,7 @@ void ItemHandler::handleMessage(Net::MessageIn &msg) if (itemId) { - if (Game *game = Game::instance()) - { - if (Map *map = game->getCurrentMap()) - { - actorSpriteManager->createItem(id, itemId, - x / map->getTileWidth(), - y / map->getTileHeight()); - } - else - { - logger->log( - "ItemHandler: An item wasn't created " - "because of Game/Map not initialized..."); - } - } + actorSpriteManager->createItem(id, itemId, Vector(x, y)); } else if (FloorItem *item = actorSpriteManager->findItem(id)) { diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp index e86f9afa..4249bac8 100644 --- a/src/net/manaserv/playerhandler.cpp +++ b/src/net/manaserv/playerhandler.cpp @@ -412,10 +412,35 @@ int PlayerHandler::getJobLocation() return -1; } -Vector PlayerHandler::getDefaultWalkSpeed() +Vector PlayerHandler::getDefaultMoveSpeed() const { - // 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(const Vector &speed, Map *map) +{ + Vector speedInTicks; + + 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."); + return speedInTicks; + } + + speedInTicks.x = speed.x + * (float)map->getTileWidth() + / 1000 * (float) MILLISECONDS_IN_A_TICK; + speedInTicks.y = speed.y + * (float)map->getTileHeight() + / 1000 * (float) MILLISECONDS_IN_A_TICK; + + return speedInTicks; } } // namespace ManaServ diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h index 5796b0d3..3e3f8aad 100644 --- a/src/net/manaserv/playerhandler.h +++ b/src/net/manaserv/playerhandler.h @@ -65,7 +65,12 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler int getJobLocation(); - Vector getDefaultWalkSpeed(); + Vector getDefaultMoveSpeed() const; + + Vector getPixelsPerTickMoveSpeed(const Vector &speed, Map *map = 0); + + bool usePixelPrecision() + { return true; } private: void handleMapChangeMessage(Net::MessageIn &msg); diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h index d7676a92..f9396caf 100644 --- a/src/net/playerhandler.h +++ b/src/net/playerhandler.h @@ -62,7 +62,25 @@ class PlayerHandler virtual int getJobLocation() = 0; - virtual Vector getDefaultWalkSpeed() = 0; + /** + * Get the original default movement speed. + * Example: + * In ticks per tiles for eAthena + * In tiles per second for Manaserv + */ + virtual Vector getDefaultMoveSpeed() const = 0; + + /** + * Convert the original speed in pixel per tick for internal use. + */ + virtual Vector getPixelsPerTickMoveSpeed(const Vector &speed, + Map *map = 0) = 0; + + /** + * Tells whether the client has to use pixel paths. + * Return false when tiles-center positions only are to be used. + */ + virtual bool usePixelPrecision() = 0; }; } // namespace Net diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp index 61491692..960f08ed 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" @@ -37,9 +39,13 @@ #include "resources/emotedb.h" #include <iostream> +#include <cmath> namespace TmwAthena { +// Number of pixels where we decide that the position doesn't need to be reset. +static const float POS_DEST_DIFF_TOLERANCE = 48.0f; + BeingHandler::BeingHandler(bool enableSync): mSync(enableSync) { @@ -95,13 +101,58 @@ Being *createBeing(int id, short job) return being; } +static void handleMoveMessage(Map *map, Being *dstBeing, + Uint16 srcX, Uint16 srcY, + Uint16 dstX, Uint16 dstY) +{ + // Avoid dealing with flawed destination + if (map && dstBeing && srcX && srcY && dstX && dstY) + { + Vector pos = map->getTileCenter(srcX, srcY); + Vector dest = map->getTileCenter(dstX, dstY); + + // Don't set the position as the movement algorithm + // can guess it and it would break the animation played, + // when we're close enough. + if (std::abs(dest.x - pos.x) > POS_DEST_DIFF_TOLERANCE + || std::abs(dest.y - pos.y) > POS_DEST_DIFF_TOLERANCE) + dstBeing->setPosition(pos); + + dstBeing->setDestination(dest.x, dest.y); + } +} + +static void handlePosMessage(Map *map, Being *dstBeing, Uint16 x, Uint16 y, + Uint8 dir = 0) +{ + // Avoid dealing with flawed destination + if (map && dstBeing && x && y) + { + Vector pos = map->getTileCenter(x, y); + Vector beingPos = dstBeing->getPosition(); + // Don't set the position as the movement algorithm + // can guess it and it would break the animation played, + // when we're close enough. + if (std::abs(beingPos.x - pos.x) > POS_DEST_DIFF_TOLERANCE + || std::abs(beingPos.y - pos.y) > POS_DEST_DIFF_TOLERANCE) + dstBeing->setPosition(pos); + + // Set also the destination to the desired position. + dstBeing->setDestination(pos.x, pos.y); + + if (dir) + dstBeing->setDirection(dir); + } +} + void BeingHandler::handleMessage(Net::MessageIn &msg) { if (!actorSpriteManager) return; int id; - short job, speed, gender; + short job, gender; + float speed; Uint16 headTop, headMid, headBottom; Uint16 shoes, gloves; Uint16 weapon, shield; @@ -114,13 +165,16 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) Being *srcBeing, *dstBeing; int hairStyle, hairColor, flag; + // Prepare useful translation variables + Map *map = Game::instance()->getCurrentMap(); + 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 +200,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(); @@ -205,17 +258,14 @@ 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); - dstBeing->setDestination(dstX, dstY); + handleMoveMessage(map, dstBeing, srcX, srcY, dstX, dstY); } else { Uint8 dir; Uint16 x, y; msg.readCoordinates(x, y, dir); - dstBeing->setTileCoords(x, y); - dstBeing->setDirection(dir); + handlePosMessage(map, dstBeing, x, y, dir); } msg.readInt8(); // unknown @@ -235,6 +285,7 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) break; case SMSG_BEING_MOVE2: + { /* * A simplified movement packet, used by the * later versions of eAthena for both mobs and @@ -254,11 +305,8 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) Uint16 srcX, srcY, dstX, dstY; msg.readCoordinatePair(srcX, srcY, dstX, dstY); msg.readInt32(); // Server tick - - dstBeing->setAction(Being::STAND); - dstBeing->setTileCoords(srcX, srcY); - dstBeing->setDestination(dstX, dstY); - + handleMoveMessage(map, dstBeing, srcX, srcY, dstX, dstY); + } break; case SMSG_BEING_REMOVE: @@ -479,15 +527,17 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) } break; case SMSG_BEING_CHANGE_DIRECTION: + { if (!(dstBeing = actorSpriteManager->findBeing(msg.readInt32()))) { break; } msg.readInt16(); // unused - - dstBeing->setDirection(msg.readInt8()); - + Uint8 dir = msg.readInt8(); + if (dir) + dstBeing->setDirection(dir); + } break; case SMSG_PLAYER_UPDATE_1: @@ -519,7 +569,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,16 +616,14 @@ 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); + handleMoveMessage(map, dstBeing, srcX, srcY, dstX, dstY); } else { Uint8 dir; Uint16 x, y; msg.readCoordinates(x, y, dir); - dstBeing->setTileCoords(x, y); - dstBeing->setDirection(dir); + handlePosMessage(map, dstBeing, x, y, dir); } gmstatus = msg.readInt16(); @@ -598,9 +651,6 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) msg.readInt8(); // Lv msg.readInt8(); // unknown - dstBeing->setActionTime(tick_time); - dstBeing->reset(); - dstBeing->setStunMode(stunMode); dstBeing->setStatusEffectBlock(0, (statusEffects >> 16) & 0xffff); dstBeing->setStatusEffectBlock(16, statusEffects & 0xffff); @@ -628,9 +678,7 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) Uint16 x, y; x = msg.readInt16(); y = msg.readInt16(); - dstBeing->setTileCoords(x, y); - if (dstBeing->getCurrentAction() == Being::MOVE) - dstBeing->setAction(Being::STAND); + handlePosMessage(map, dstBeing, x, y); } } break; 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 0b3c7d38..2194c77d 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(Event::Channel channel, const Event &event) { if (event.getType() == Event::EnginesInitialized) { - 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.getType() == Event::MapLoaded) { diff --git a/src/net/tmwa/gamehandler.h b/src/net/tmwa/gamehandler.h index a1a2e7ec..016df18e 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/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp index 18e8febc..1340a091 100644 --- a/src/net/tmwa/inventoryhandler.cpp +++ b/src/net/tmwa/inventoryhandler.cpp @@ -24,6 +24,7 @@ #include "configuration.h" #include "equipment.h" #include "event.h" +#include "game.h" #include "inventory.h" #include "item.h" #include "itemshortcut.h" @@ -408,13 +409,33 @@ void InventoryHandler::handleMessage(Net::MessageIn &msg) flag = msg.readInt8(); if (!flag) + { SERVER_NOTICE(_("Unable to unequip.")) + } else + { mEquips.setEquipment(getSlot(equipType), -1); + // Reset the attack range to unarmed. + player_node->setAttackRange(ATTACK_RANGE_NOT_SET); + } break; case SMSG_PLAYER_ATTACK_RANGE: - player_node->setAttackRange(msg.readInt16()); + { + // The range is in tiles, so we translate it back to pixels + Map *map = Game::instance()->getCurrentMap(); + if (map) + { + player_node->setAttackRange(msg.readInt16() + * map->getTileWidth()); + } + else + { + logger->log("Couldn't set attacke range due to the lack" + "of an initialized map."); + player_node->setAttackRange(ATTACK_RANGE_NOT_SET); + } + } break; case SMSG_PLAYER_ARROW_EQUIP: diff --git a/src/net/tmwa/itemhandler.cpp b/src/net/tmwa/itemhandler.cpp index a8e98860..e452ccf2 100644 --- a/src/net/tmwa/itemhandler.cpp +++ b/src/net/tmwa/itemhandler.cpp @@ -21,12 +21,14 @@ #include "net/tmwa/itemhandler.h" -#include "actorspritemanager.h" - #include "net/messagein.h" #include "net/tmwa/protocol.h" +#include "actorspritemanager.h" +#include "game.h" +#include "map.h" + namespace TmwAthena { ItemHandler::ItemHandler() @@ -54,7 +56,13 @@ void ItemHandler::handleMessage(Net::MessageIn &msg) int y = msg.readInt16(); msg.skip(4); // amount,subX,subY / subX,subY,amount - actorSpriteManager->createItem(id, itemId, x, y); + Game *game = Game::instance(); + if (!game) + break; + + if (Map *map = game->getCurrentMap()) + actorSpriteManager->createItem(id, itemId, + map->getTileCenter(x, y)); } break; diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index ec004917..4bd637c3 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 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) * map->getTileWidth(); + scrollOffsetY = (y - tileY) * map->getTileHeight(); } player_node->setAction(Being::STAND); - player_node->setTileCoords(x, y); + Vector pos = map->getTileCenter(x, y); + player_node->setPosition(pos); + // Stop movement + player_node->setDestination(pos.x, pos.y); 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; @@ -553,8 +559,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) @@ -603,11 +613,35 @@ int PlayerHandler::getJobLocation() return JOB; } -Vector PlayerHandler::getDefaultWalkSpeed() +Vector PlayerHandler::getDefaultMoveSpeed() const { // 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(const Vector &speed, Map *map) +{ + Game *game = Game::instance(); + + if (game && !map) + map = game->getCurrentMap(); + + if (!map || speed.x == 0 || speed.y == 0) + { + logger->log("TmwAthena::PlayerHandler: Speed set to default: " + "Map not yet initialized or invalid speed."); + return getDefaultMoveSpeed(); + } + + Vector speedInTicks; + + // speedInTicks.z = 0; // We don't use z for now. + speedInTicks.x = 1 / speed.x * (float)map->getTileWidth(); + speedInTicks.y = 1 / speed.y * (float)map->getTileHeight(); + + return speedInTicks; } } // namespace TmwAthena diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h index cb352110..63812f47 100644 --- a/src/net/tmwa/playerhandler.h +++ b/src/net/tmwa/playerhandler.h @@ -58,7 +58,12 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler int getJobLocation(); - Vector getDefaultWalkSpeed(); + Vector getDefaultMoveSpeed() const; + + Vector getPixelsPerTickMoveSpeed(const Vector &speed, Map *map = 0); + + bool usePixelPrecision() + { return false; } }; } // namespace TmwAthena |