diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/accounthandler.cpp | 11 | ||||
-rw-r--r-- | src/controller.cpp | 10 | ||||
-rw-r--r-- | src/dalstorage.cpp | 13 | ||||
-rw-r--r-- | src/gamehandler.cpp | 8 | ||||
-rw-r--r-- | src/object.cpp | 104 | ||||
-rw-r--r-- | src/object.h | 78 | ||||
-rw-r--r-- | src/point.h | 12 | ||||
-rw-r--r-- | src/state.cpp | 32 |
9 files changed, 93 insertions, 179 deletions
@@ -12,6 +12,10 @@ * src/messageout.cpp, src/messageout.h, src/state.cpp, src/defines.h: Removed pixel-based synchronisation. Added variable length move messages. Changed default buffer size of outgoing packets. + * src/src/accounthandler.cpp, src/point.h, src/object.cpp, + src/controller.cpp, src/dalstorage.cpp, src/object.h, src/state.cpp, + src/gamehandler.cpp: Made Point a POD type. Simplified server algorithm + for moving objects; it now matches the one in the client. 2006-08-28 Eugenio Favalli <elvenprogrammer@gmail.com> diff --git a/src/accounthandler.cpp b/src/accounthandler.cpp index 9e35505c..717f5581 100644 --- a/src/accounthandler.cpp +++ b/src/accounthandler.cpp @@ -181,9 +181,8 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message) PlayerPtr selectedChar = computer.getCharacter(); result.writeByte(ERRMSG_OK); - selectedChar->setDestination(selectedChar->getX(), - selectedChar->getY()); - selectedChar->setSpeed(21); // TODO + selectedChar->setDestination(selectedChar->getPosition()); + selectedChar->setSpeed(150); // TODO LOG_INFO(selectedChar->getName() << " is trying to enter the servers.", 1); @@ -663,9 +662,9 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, newCharacter->setHairStyle(hairStyle); newCharacter->setHairColor(hairColor); newCharacter->setMapId((int) config.getValue("defaultMap", 1)); - newCharacter->setXY(Point( - (int) config.getValue("startX", 0), - (int) config.getValue("startY", 0))); + Point startingPos = { (int) config.getValue("startX", 0), + (int) config.getValue("startY", 0) }; + newCharacter->setPosition(startingPos); computer.getAccount()->addCharacter(newCharacter); LOG_INFO("Character " << name << " was created for " diff --git a/src/controller.cpp b/src/controller.cpp index a73b7a5f..b6900c48 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -56,12 +56,12 @@ void Controller::update() { if (mBeing.get()) { - unsigned int randomX = rand() % 320 + 720; - unsigned int randomY = rand() % 320 + 840; + Point randomPos = { rand() % 320 + 720, + rand() % 320 + 840 }; - LOG_INFO("Setting new random destination " << randomX << "," - << randomY << " for being " << mBeing->getPublicID(), 2); - mBeing->setDestination(randomX, randomY); + LOG_INFO("Setting new random destination " << randomPos.x << "," + << randomPos.y << " for being " << mBeing->getPublicID(), 2); + mBeing->setDestination(randomPos); } mCountDown = 10 + rand() % 10; diff --git a/src/dalstorage.cpp b/src/dalstorage.cpp index b1c4fc0c..87387352 100644 --- a/src/dalstorage.cpp +++ b/src/dalstorage.cpp @@ -261,8 +261,9 @@ DALStorage::getAccount(const std::string& userName) player->setHairColor(toUshort(strCharInfo[k][5])); player->setLevel(toUshort(strCharInfo[k][6])); player->setMoney(toUint(strCharInfo[k][7])); - player->setXY(Point(toUshort(strCharInfo[k][8]), - toUshort(strCharInfo[k][9]))); + Point pos = { toUshort(strCharInfo[k][8]), + toUshort(strCharInfo[k][9]) }; + player->setPosition(pos); for (int i = 0; i < NB_RSTAT; ++i) player->setRawStat(i, toUshort(strCharInfo[k][11 + i])); @@ -641,8 +642,8 @@ void DALStorage::flush(AccountPtr const &account) << (int)(*it)->getHairColor() << ", " << (int)(*it)->getLevel() << ", " << (*it)->getMoney() << ", " - << (*it)->getX() << ", " - << (*it)->getY() << ", " + << (*it)->getPosition().x << ", " + << (*it)->getPosition().y << ", " << (*it)->getMapId() << ", " << (*it)->getRawStat(STAT_STR) << ", " << (*it)->getRawStat(STAT_AGI) << ", " @@ -673,8 +674,8 @@ void DALStorage::flush(AccountPtr const &account) << " hair_color = " << (int)(*it)->getHairColor() << ", " << " level = " << (int)(*it)->getLevel() << ", " << " money = " << (*it)->getMoney() << ", " - << " x = " << (*it)->getX() << ", " - << " y = " << (*it)->getY() << ", " + << " x = " << (*it)->getPosition().x << ", " + << " y = " << (*it)->getPosition().y << ", " << " map_id = " << (*it)->getMapId() << ", " << " str = " << (*it)->getRawStat(STAT_STR) << ", " << " agi = " << (*it)->getRawStat(STAT_AGI) << ", " diff --git a/src/gamehandler.cpp b/src/gamehandler.cpp index 9b30299e..cb38eacc 100644 --- a/src/gamehandler.cpp +++ b/src/gamehandler.cpp @@ -196,8 +196,8 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) { unsigned x = message.readShort(); unsigned y = message.readShort(); - - computer.getCharacter()->setDestination(x, y); + Point dst = {x, y}; + computer.getCharacter()->setDestination(dst); // no response should be required } break; @@ -231,7 +231,7 @@ void GameHandler::sayAround(GameClient &computer, std::string const &text) msg.writeString(text); unsigned speakerMapId = beingPtr->getMapId(); - Point speakerPosition = beingPtr->getXY(); + Point speakerPosition = beingPtr->getPosition(); for (NetComputers::iterator i = clients.begin(), i_end = clients.end(); i != i_end; ++i) @@ -244,7 +244,7 @@ void GameHandler::sayAround(GameClient &computer, std::string const &text) continue; } - if (speakerPosition.inRangeOf(listener->getXY())) + if (speakerPosition.inRangeOf(listener->getPosition())) { (*i)->send(msg); } diff --git a/src/object.cpp b/src/object.cpp index 075b22fa..038a53dc 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -20,9 +20,6 @@ * $Id$ */ -#include <cassert> -#include <cmath> - #include "object.h" #include "map.h" @@ -30,95 +27,44 @@ void MovingObject::move() { - unsigned mSrcX = getX(), mSrcY = getY(); - if (mSrcX == mDstX && mSrcY == mDstY) { - mNewX = mDstX; - mNewY = mDstY; + mOld = getPosition(); + if (mActionTime > 100) + { + // current move has not yet ended + mActionTime -= 100; return; } Map *map = MapManager::instance().getMap(getMapId()); - int tileW = map->getTileWidth(), tileH = map->getTileHeight(); - int tileD = (int) std::sqrt((double)(tileW * tileW + tileH * tileH)); - int tileSX = mSrcX / tileW, fracSX = mSrcX % tileW - tileW / 2; - int tileSY = mSrcY / tileH, fracSY = mSrcY % tileH - tileH / 2; - int tileDX = mDstX / tileW, fracDX = mDstX % tileW - tileW / 2; - int tileDY = mDstY / tileH, fracDY = mDstY % tileH - tileH / 2; - std::list<PATH_NODE> path; - if (tileSX != tileDX || tileSY != tileDY) { + int tileSX = mOld.x / 32, tileSY = mOld.y / 32; + int tileDX = mDst.x / 32, tileDY = mDst.y / 32; + if (tileSX != tileDX || tileSY != tileDY) + { path = map->findPath(tileSX, tileSY, tileDX, tileDY); if (path.empty()) { - mNewX = mDstX = mSrcX; - mNewY = mDstY = mSrcY; + // no path was found + mDst = mOld; return; } + // last tile center is skipped path.pop_back(); } - int tileCX = tileSX, tileCY = tileSY, fracCX = fracSX, fracCY = fracSY; - int left = mSpeed; - int vecX = 0, vecY = 0, cost = 0; - - for (std::list<PATH_NODE>::const_iterator it = path.begin(), - it_end = path.end(); it != it_end; ++it) + Point pos; + do { - int tileNX = it->x, tileNY = it->y; - assert((tileNX != tileCX || tileNY != tileCY) && - (tileNX != tileDX || tileNY != tileDY)); - - if (fracCX != 0 || fracCY != 0) { - // not at the tile center, move toward the next tile center - vecX = -fracCX + tileW * (tileNX - tileCX); - vecY = -fracCY + tileH * (tileNY - tileCY); - cost = (int) std::sqrt((double)(vecX * vecX + vecY * vecY)); - } else { - // at a tile center and toward the next tile center - assert(abs(tileNX - tileCX) <= 1 && abs(tileNY - tileCY) <= 1); - if (tileNX != tileCX) { - vecX = tileW * (tileNX - tileCX); - if (tileNY != tileCY) { - vecY = tileH * (tileNY - tileCY); - cost = tileD; - } else { - vecY = 0; - cost = tileW; - } - } else { - assert(tileNY != tileCY); - vecX = 0; - vecY = tileH * (tileNY - tileCY); - cost = tileH; - } + mActionTime += mSpeed; + if (path.empty()) + { + // skip last tile center + setPosition(mDst); + return; } - - if (cost > left) break; - // enough movement left to reach the next tile center - tileCX = tileNX; - tileCY = tileNY; - fracCX = 0; - fracCY = 0; - vecX = 0; - vecY = 0; - left -= cost; - } - - if ((vecX == 0 && vecY == 0) && (fracCX != fracDX || fracCY != fracDY)) { - // walk toward the destination - vecX = fracDX - fracCX + tileW * (tileDX - tileCX); - vecY = fracDY - fracCY + tileH * (tileDY - tileCY); - cost = (int) std::sqrt((double)(vecX * vecX + vecY * vecY)); + pos.x = path.front().x * 32 + 16; + pos.y = path.front().y * 32 + 16; + path.pop_front(); } - - if (cost <= left) { - // enough movement left to perform the last step - mNewX = mDstX; - mNewY = mDstY; - return; - } - - // linear interpolation along the vector - assert(cost > 0); - mNewX = tileCX * tileW + tileW / 2 + fracCX + vecX * left / cost; - mNewY = tileCY * tileH + tileH / 2 + fracCY + vecY * left / cost; + while (mActionTime < 100); + setPosition(pos); } diff --git a/src/object.h b/src/object.h index d57b3596..bb800013 100644 --- a/src/object.h +++ b/src/object.h @@ -60,53 +60,20 @@ class Object { return mType; } /** - * Set the x coordinate. + * Sets the coordinates. * - * @param x the new x coordinate. + * @param p the coordinates. */ - void setX(unsigned int x) - { mX = x; } + void setPosition(const Point &p) + { mPos = p; } /** - * Get the x coordinate. + * Gets the coordinates. * - * @return the x coordinate. + * @return the coordinates. */ - unsigned int getX() const - { return mX; } - - /** - * Set the y coordinate. - * - * @param y the new y coordinate. - */ - void setY(unsigned int y) - { mY = y; } - - /** - * Get the y coordinate. - * - * @return the y coordinate. - */ - unsigned int getY() const - { return mY; } - - /** - * Set the coordinates. - * - * @param x the x coordinate. - * @param y the y coordinate. - */ - void setXY(const Point &p) - { mX = p.x; mY = p.y; } - - /** - * Get the coordinates. - * - * @return the coordinates as a pair. - */ - Point getXY() const - { return Point(mX, mY); } + Point const &getPosition() const + { return mPos; } /** * Update the internal status. @@ -142,8 +109,7 @@ class Object private: int mType; /**< Object type */ - unsigned int mX; /**< x coordinate */ - unsigned int mY; /**< y coordinate */ + Point mPos; /**< coordinates */ unsigned int mMapId; /**< id of the map being is on */ bool mNew; /**< true if the object just appeared */ @@ -161,26 +127,27 @@ class MovingObject: public Object * Proxy constructor. */ MovingObject(int type, int id) - : Object(type), mPublicID(id) + : Object(type), mPublicID(id), + mActionTime(0) {} /** * Gets the destination coordinates of the object. */ - Point getDestination() const - { return Point(mDstX, mDstY); } + Point const &getDestination() const + { return mDst; } /** * Sets the destination coordinates of the object. */ - void setDestination(unsigned x, unsigned y) - { mDstX = x; mDstY = y; } + void setDestination(Point dst) + { mDst = dst; } /** - * Gets the next coordinates of the object. + * Gets the old coordinates of the object. */ - Point getNextPosition() const - { return Point(mNewX, mNewY); } + Point getOldPosition() const + { return mOld; } /** * Sets object speed. @@ -210,11 +177,10 @@ class MovingObject: public Object private: unsigned short mPublicID; /**< Object ID sent to clients (unique with respect to the map) */ - unsigned mDstX; /**< target x coordinate */ - unsigned mDstY; /**< target y coordinate */ - unsigned mNewX; /**< next x coordinate */ - unsigned mNewY; /**< next y coordinate */ - unsigned mSpeed; /**< speed */ + Point mDst; /**< target coordinates */ + Point mOld; /**< old coordinates */ + unsigned short mSpeed; /**< speed */ + unsigned short mActionTime; /**< delay until next action */ }; /** diff --git a/src/point.h b/src/point.h index bc894cdd..5ce87a53 100644 --- a/src/point.h +++ b/src/point.h @@ -31,16 +31,8 @@ class Point { public: - unsigned int x; /**< x coordinate */ - unsigned int y; /**< y coordinate */ - - /** - * Constructor. - */ - Point(unsigned int x, unsigned int y) - : x(x), - y(y) - {} + unsigned short x; /**< x coordinate */ + unsigned short y; /**< y coordinate */ /** * Check whether the given point is within range of this point. This is diff --git a/src/state.cpp b/src/state.cpp index f2f5b090..5ce00dd9 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -42,9 +42,10 @@ State::State() { // TODO: Unique object numbering BeingPtr being = BeingPtr(new Being(OBJECT_MONSTER, 1000 + i)); - being->setSpeed(21); + being->setSpeed(150); being->setMapId(1); - being->setXY(Point(720, 900)); + Point pos = { 720, 900 }; + being->setPosition(pos); Controller *controller = new Controller(); controller->possess(being); addObject(ObjectPtr(being)); @@ -92,15 +93,15 @@ State::update() for (Movings::iterator o = movings.begin(), o_end = movings.end(); o != o_end; ++o) { - Point os = (*o)->getXY(); - Point on = (*o)->getNextPosition(); + Point os = (*o)->getOldPosition(); + Point on = (*o)->getPosition(); /* Check whether this player and this moving object were around * the last time and whether they will be around the next time. */ - bool wereInRange = (*p)->getXY().inRangeOf(os) && - !(*p)->isNew() && !(*o)->isNew(); - bool willBeInRange = (*p)->getNextPosition().inRangeOf(on); + bool wereInRange = (*p)->getOldPosition().inRangeOf(os) && + !(*p)->isNew() && !(*o)->isNew(); + bool willBeInRange = (*p)->getPosition().inRangeOf(on); int flags = 0; @@ -154,7 +155,7 @@ State::update() moving inside p's range. Report o's movements. */ Point od = (*o)->getDestination(); - if (on.x != od.x || on.y != od.y) + if (on.x != od.x || on.y != od.y || on.x != os.x || on.y != os.y) { flags |= MOVING_POSITION; } @@ -162,6 +163,11 @@ State::update() // TODO: updates destination only on changes. flags |= MOVING_DESTINATION; + if (!(flags & (MOVING_POSITION | MOVING_DESTINATION))) + { + continue; + } + msg.writeShort((*o)->getPublicID()); msg.writeByte(flags); if (flags & MOVING_POSITION) @@ -183,7 +189,6 @@ State::update() for (Movings::iterator o = movings.begin(), o_end = movings.end(); o != o_end; ++o) { - (*o)->setXY((*o)->getNextPosition()); (*o)->setNew(false); } } @@ -222,7 +227,7 @@ State::removeObject(ObjectPtr objectPtr) MessageOut msg(GPMSG_BEING_LEAVE); msg.writeShort(PlayerPtr(objectPtr)->getPublicID()); - Point objectPosition = objectPtr->getXY(); + Point objectPosition = objectPtr->getPosition(); Players &players = maps[mapId].players; Players::iterator p_end = players.end(), j = p_end; for (Players::iterator p = players.begin(); p != p_end; ++p) @@ -231,7 +236,7 @@ State::removeObject(ObjectPtr objectPtr) { j = p; } - else if (objectPosition.inRangeOf((*p)->getXY())) + else if (objectPosition.inRangeOf((*p)->getPosition())) { gameHandler->sendTo(*p, msg); } @@ -256,8 +261,9 @@ State::informPlayer(PlayerPtr playerPtr) Storage &store = Storage::instance("tmw"); MessageOut mapChangeMessage(GPMSG_PLAYER_MAP_CHANGE); mapChangeMessage.writeString(store.getMapNameFromId(mapId)); - mapChangeMessage.writeShort(playerPtr->getX()); - mapChangeMessage.writeShort(playerPtr->getY()); + Point pos = playerPtr->getPosition(); + mapChangeMessage.writeShort(pos.x); + mapChangeMessage.writeShort(pos.y); mapChangeMessage.writeByte(0); gameHandler->sendTo(playerPtr, mapChangeMessage); } |