summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--src/object.h14
-rw-r--r--src/state.cpp36
3 files changed, 39 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index ac82ca27..fc99d77c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,10 @@
wall for testing purpose.
* src/gamehandler.cpp, src/defines.h: Send being identifier instead of
being name when saying around.
+ * src/object.h: Added a field indicating if an object just appeared.
+ * src/state.cpp: Improved update logic by taking into account beings
+ that just appeared. Moved "change map" message from AddObject to
+ InformPlayer.
2006-08-26 Bjørn Lindeijer <bjorn@lindeijer.nl>
diff --git a/src/object.h b/src/object.h
index 05b1f45d..ecd06985 100644
--- a/src/object.h
+++ b/src/object.h
@@ -43,6 +43,7 @@ class Object
Object(int type, int id)
: mType(type),
mID(id),
+ mNew(true),
mNeedUpdate(false)
{}
@@ -142,12 +143,25 @@ class Object
void setMapId(unsigned int mapId)
{ mMapId = mapId; }
+ /**
+ * Tells if the object just appeared.
+ */
+ bool isNew() const
+ { return mNew; }
+
+ /**
+ * Sets the age of the object.
+ */
+ void setNew(bool n)
+ { mNew = n; }
+
private:
int mType; /**< Object type */
int mID; /** Object unique ID (wrt its type and its map at least) */
unsigned int mX; /**< x coordinate */
unsigned int mY; /**< y coordinate */
unsigned int mMapId; /**< id of the map being is on */
+ bool mNew; /**< true if the object just appeared */
protected:
bool mNeedUpdate; /**< update() must be invoked if true */
diff --git a/src/state.cpp b/src/state.cpp
index 87e85015..a32d082e 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -73,19 +73,23 @@ State::update()
{
std::pair<unsigned, unsigned> ps = (*p)->getXY();
std::pair<unsigned, unsigned> pn = (*p)->getNextPosition();
- MessageOut msg;
- msg.writeShort(GPMSG_BEINGS_MOVE);
+ bool po = !(*p)->isNew();
+ MessageOut msg(GPMSG_BEINGS_MOVE);
for (Movings::iterator o = movings.begin(),
o_end = movings.end(); o != o_end; ++o)
{
std::pair<unsigned, unsigned> os = (*o)->getXY();
std::pair<unsigned, unsigned> on = (*o)->getNextPosition();
+ bool oo = po && !(*o)->isNew(); // Are p and o both old?
- bool were = areAround(ps.first, ps.second, os.first, os.second);
+ /* Look whether p and o "were" around the last time and whether
+ they "will" be around the next time. p has to be informed when
+ this proximity changes or if o will move in range. */
+ bool were = areAround(ps.first, ps.second, os.first, os.second) && oo;
bool will = areAround(pn.first, pn.second, on.first, on.second);
bool has_moved = os.first != on.first || os.second != on.second;
- if (!(will && has_moved) && !(were != will))
+ if (!(will && has_moved) && (were == will))
continue;
std::pair<unsigned, unsigned> od = (*o)->getDestination();
@@ -105,6 +109,7 @@ State::update()
{
std::pair<unsigned, unsigned> pos = (*o)->getNextPosition();
(*o)->setXY(pos.first, pos.second);
+ (*o)->setNew(false);
}
}
}
@@ -115,6 +120,7 @@ State::addObject(ObjectPtr objectPtr)
unsigned mapId = objectPtr->getMapId();
if (!loadMap(mapId)) return;
maps[mapId].objects.push_back(objectPtr);
+ objectPtr->setNew(true);
if (objectPtr->getType() != OBJECT_PLAYER) return;
Players &players = maps[mapId].players;
PlayerPtr playerPtr(objectPtr);
@@ -139,17 +145,6 @@ State::addObject(ObjectPtr objectPtr)
// Add the new player to the list
players.push_back(playerPtr);
-
- /* Since the player doesn't know yet where on the world he is after
- * connecting to the map server, we send him an initial change map message.
- */
- Storage &store = Storage::instance("tmw");
- MessageOut mapChangeMessage(GPMSG_PLAYER_MAP_CHANGE);
- mapChangeMessage.writeString(store.getMapNameFromId(mapId));
- mapChangeMessage.writeShort(playerPtr->getX());
- mapChangeMessage.writeShort(playerPtr->getY());
- mapChangeMessage.writeByte(0);
- gameHandler->sendTo(playerPtr, mapChangeMessage);
}
void
@@ -196,6 +191,17 @@ State::informPlayer(PlayerPtr playerPtr)
if (m == maps.end()) return;
Players &players = m->second.players;
+ /* Since the player doesn't know yet where on the world he is after
+ * connecting to the map server, we send him an initial change map message.
+ */
+ Storage &store = Storage::instance("tmw");
+ MessageOut mapChangeMessage(GPMSG_PLAYER_MAP_CHANGE);
+ mapChangeMessage.writeString(store.getMapNameFromId(mapId));
+ mapChangeMessage.writeShort(playerPtr->getX());
+ mapChangeMessage.writeShort(playerPtr->getY());
+ mapChangeMessage.writeByte(0);
+ gameHandler->sendTo(playerPtr, mapChangeMessage);
+
/* Here the player is informed about all the other players on the map.
* However, the player should only be told about other players within
* visual range. See also notes at addObject and removeObject.