summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--src/accounthandler.cpp11
-rw-r--r--src/controller.cpp10
-rw-r--r--src/dalstorage.cpp13
-rw-r--r--src/gamehandler.cpp8
-rw-r--r--src/object.cpp104
-rw-r--r--src/object.h78
-rw-r--r--src/point.h12
-rw-r--r--src/state.cpp32
9 files changed, 93 insertions, 179 deletions
diff --git a/ChangeLog b/ChangeLog
index d317866a..b4152785 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);
}