summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2006-12-30 13:29:03 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2006-12-30 13:29:03 +0000
commit7d23129b8f16dfa73e3842ac8e91c61e5a3393aa (patch)
tree49132223612cd4286fbf265b9b61bcc8d756f1ea
parent6134c13fbbaf2e5516dd924425352416f66ece9b (diff)
downloadmanaserv-7d23129b8f16dfa73e3842ac8e91c61e5a3393aa.tar.gz
manaserv-7d23129b8f16dfa73e3842ac8e91c61e5a3393aa.tar.bz2
manaserv-7d23129b8f16dfa73e3842ac8e91c61e5a3393aa.tar.xz
manaserv-7d23129b8f16dfa73e3842ac8e91c61e5a3393aa.zip
Made attack code pixel-based and faster. Split State::update. Improved
interface of MapComposite iterators.
-rw-r--r--ChangeLog16
-rw-r--r--src/Makefile.am4
-rw-r--r--src/being.cpp105
-rw-r--r--src/being.h16
-rw-r--r--src/game-server/mapcomposite.cpp (renamed from src/mapcomposite.cpp)47
-rw-r--r--src/game-server/mapcomposite.hpp (renamed from src/mapcomposite.h)17
-rw-r--r--src/game-server/state.cpp311
-rw-r--r--src/game-server/state.hpp64
-rw-r--r--src/object.h13
-rw-r--r--src/player.cpp1
10 files changed, 279 insertions, 315 deletions
diff --git a/ChangeLog b/ChangeLog
index 2ac87b7b..575de9f7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2006-12-30 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/mapcomposite.h, src/mapcomposite.cpp: Moved to src/game-server
+ directory and changed header extension to hpp.
+ * src/Makefile.am: Updated accordingly.
+ * src/object.h, src/being.h: Changed definition of directions.
+ * src/being.cpp: Relied on MapComposite iterators to scan only beings
+ in the vincinity one time instead of all objects of the map four times.
+ Used a pixel-based zone instead of tile-based zone for damaging.
+ * src/player.cpp: Removed useless dependency.
+ * src/game-server/mapcomposite.hpp, src/game-server/mapcomposite.cpp:
+ Added a radius parameter to iterator creators. Removed unused and
+ inefficient getObjectsOnTile.
+ * src/game-server/state.hpp, src/game-server/state.cpp: Split update
+ function into updateMap and informPlayer. Simplified code a bit.
+
2006-12-29 Guillaume Melquiond <guillaume.melquiond@gmail.com>
* src/account.h, src/account.cpp, src/accountclient.h,
diff --git a/src/Makefile.am b/src/Makefile.am
index c92b516b..49e49fb4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -94,8 +94,6 @@ tmwserv_game_SOURCES = \
item.cpp \
map.h \
map.cpp \
- mapcomposite.h \
- mapcomposite.cpp \
mapreader.h \
mapreader.cpp \
object.h \
@@ -116,6 +114,8 @@ tmwserv_game_SOURCES = \
game-server/gamehandler.cpp \
game-server/itemmanager.hpp \
game-server/itemmanager.cpp \
+ game-server/mapcomposite.hpp \
+ game-server/mapcomposite.cpp \
game-server/mapmanager.hpp \
game-server/mapmanager.cpp \
game-server/state.hpp \
diff --git a/src/being.cpp b/src/being.cpp
index 6f8b7028..cece203a 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -21,7 +21,7 @@
*/
#include "being.h"
-#include "mapcomposite.h"
+#include "game-server/mapcomposite.hpp"
#include "utils/logger.h"
void Being::damage(Damage damage)
@@ -35,78 +35,53 @@ void Being::damage(Damage damage)
LOG_DEBUG("Being " << getPublicID() << " got hit", 0);
}
-void Being::performAttack(MapComposite* map)
+void Being::performAttack(MapComposite *map)
{
- std::list<ObjectPtr> victimList;
- std::list<Point> attackZone;
+ int SHORT_RANGE = 32;
+ Point ppos = getPosition();
+ int dir = getDirection();
- Point attackPoint = getPosition();
+ /* TODO: calculate real attack power and damage properties based on
+ character equipment and stats. */
+ Damage damage = 1;
- unsigned char direction = getDirection();
- if (direction & UP)
+ for (MovingObjectIterator i(map->getAroundObjectIterator(this, SHORT_RANGE)); i; ++i)
{
- attackPoint.y -= 32;
- attackPoint.x -= 32;
- attackZone.push_back(attackPoint);
- attackPoint.x += 32;
- attackZone.push_back(attackPoint);
- attackPoint.x += 32;
- attackZone.push_back(attackPoint);
- }
- else if (direction & RIGHT)
- {
- attackPoint.x += 32;
- attackPoint.y -= 32;
- attackZone.push_back(attackPoint);
- attackPoint.y += 32;
- attackZone.push_back(attackPoint);
- attackPoint.y += 32;
- attackZone.push_back(attackPoint);
- }
- else if (direction & DOWN)
- {
- attackPoint.y += 32;
- attackPoint.x -= 32;
- attackZone.push_back(attackPoint);
- attackPoint.x += 32;
- attackZone.push_back(attackPoint);
- attackPoint.x += 32;
- attackZone.push_back(attackPoint);
- }
- else {
- attackPoint.x -= 32;
- attackPoint.y -= 32;
- attackZone.push_back(attackPoint);
- attackPoint.y += 32;
- attackZone.push_back(attackPoint);
- attackPoint.y += 32;
- attackZone.push_back(attackPoint);
- }
-
- attackZone.push_back(attackPoint); // point player is facing
-
- // get enemies to hurt
- for (std::list<Point>::iterator i = attackZone.begin(),
- i_end = attackZone.end(); i != i_end; ++i)
- {
- std::list<ObjectPtr> newVictimList = map->getObjectsOnTile((*i));
- victimList.splice(victimList.end(), newVictimList);
- }
+ MovingObject *o = *i;
+ if (o == this)
+ {
+ continue;
+ }
- // apply damage to victims
- Damage damage;
+ int type = o->getType();
+ Point opos = o->getPosition();
+ int dx = opos.x - ppos.x, dy = opos.y - ppos.y;
- /* TODO: calculate real attack power and damage properties based on
- * character equipment and stats
- */
- damage = 1;
+ if ((type != OBJECT_PLAYER && type != OBJECT_MONSTER) ||
+ (std::abs(dx) > SHORT_RANGE || std::abs(dy) > SHORT_RANGE))
+ {
+ continue;
+ }
- for (std::list<ObjectPtr>::iterator i = victimList.begin(),
- i_end = victimList.end(); i != i_end; ++i)
- {
- if ((*i)->getType() == OBJECT_PLAYER || (*i)->getType() == OBJECT_MONSTER)
+ // basic triangle-shaped damage zone
+ switch (dir)
{
- static_cast<Being*>(&**i)->damage(damage);
+ case DIRECTION_UP:
+ if (!(dy <= dx && dx <= -dy)) continue;
+ break;
+ case DIRECTION_DOWN:
+ if (!(-dy <= dx && dx <= dy)) continue;
+ break;
+ case DIRECTION_LEFT:
+ if (!(dx <= dy && dy <= -dx)) continue;
+ break;
+ case DIRECTION_RIGHT:
+ if (!(-dx <= dy && dy <= dx)) continue;
+ break;
+ default:
+ break;
}
+
+ static_cast< Being * >(o)->damage(damage);
}
}
diff --git a/src/being.h b/src/being.h
index 80d5d696..760bea73 100644
--- a/src/being.h
+++ b/src/being.h
@@ -90,16 +90,12 @@ typedef enum {
/**
* Beings and actors directions
*/
-typedef enum {
- DIRECTION_NORTH,
- DIRECTION_NORTHWEST,
- DIRECTION_NORTHEAST,
- DIRECTION_WEST,
- DIRECTION_EAST,
- DIRECTION_SOUTH,
- DIRECTION_SOUTHWEST,
- DIRECTION_SOUTHEAST
-} SpriteDirection;
+enum {
+ DIRECTION_DOWN = 1,
+ DIRECTION_UP,
+ DIRECTION_LEFT,
+ DIRECTION_RIGHT
+};
/**
* Raw statistics of a Player.
diff --git a/src/mapcomposite.cpp b/src/game-server/mapcomposite.cpp
index 35038abf..1591ad9f 100644
--- a/src/mapcomposite.cpp
+++ b/src/game-server/mapcomposite.cpp
@@ -21,13 +21,11 @@
* $Id$
*/
-#include "mapcomposite.h"
-
#include <algorithm>
#include <cassert>
-#include "defines.h"
#include "map.h"
+#include "game-server/mapcomposite.hpp"
/* TODO: Implement overlapping map zones instead of strict partitioning.
Purpose: to decrease the number of zone changes, as overlapping allows for
@@ -36,6 +34,8 @@
uniquely defined any longer. */
/* Pixel-based width and height of the squares used in partitioning the map.
+ Squares should be big enough so that a moving object cannot cross several
+ ones in one world tick.
TODO: Tune for decreasing server load. The higher the value, the closer we
regress to quadratic behavior; the lower the value, the more we waste time
in dealing with zone changes. */
@@ -349,10 +349,9 @@ void MapComposite::deallocate(MovingObject *obj)
buckets[id / 256]->deallocate(id % 256);
}
-void MapComposite::fillRegion(MapRegion &r, Point const &p) const
+void MapComposite::fillRegion(MapRegion &r, Point const &p, int radius) const
{
- int radius = AROUND_AREA,
- ax = p.x > radius ? (p.x - radius) / zoneDiam : 0,
+ int ax = p.x > radius ? (p.x - radius) / zoneDiam : 0,
ay = p.y > radius ? (p.y - radius) / zoneDiam : 0,
bx = std::max((p.x + radius) / zoneDiam, mapWidth - 1),
by = std::max((p.y + radius) / zoneDiam, mapHeight - 1);
@@ -365,17 +364,17 @@ void MapComposite::fillRegion(MapRegion &r, Point const &p) const
}
}
-ZoneIterator MapComposite::getAroundObjectIterator(Object *obj) const
+ZoneIterator MapComposite::getAroundObjectIterator(Object *obj, int radius) const
{
MapRegion r;
- fillRegion(r, obj->getPosition());
+ fillRegion(r, obj->getPosition(), radius);
return ZoneIterator(r, this);
}
-ZoneIterator MapComposite::getAroundPlayerIterator(Player *obj) const
+ZoneIterator MapComposite::getAroundPlayerIterator(Player *obj, int radius) const
{
MapRegion r1;
- fillRegion(r1, obj->getOldPosition());
+ fillRegion(r1, obj->getOldPosition(), radius);
MapRegion r2 = r1;
for (MapRegion::iterator i = r1.begin(), i_end = r1.end(); i != i_end; ++i)
{
@@ -393,35 +392,9 @@ ZoneIterator MapComposite::getAroundPlayerIterator(Player *obj) const
r2.swap(r3);
}
}
- fillRegion(r2, obj->getPosition());
+ fillRegion(r2, obj->getPosition(), radius);
return ZoneIterator(r2, this);
}
-
-std::list<ObjectPtr> MapComposite::getObjectsOnTile(const Point &tile) const
-{
- std::list<ObjectPtr> objectList;
-
- Objects::const_iterator i;
-
- // convert pixel coordinates to tile coordinates
- int tX = (int)((tile.x) / 32);
- int tY = (int)((tile.y) / 32);
-
- for (i = objects.begin(); i != objects.end(); ++i)
- {
- // convert object coordinates to tile coordinates
- Point objectPoint = (*i)->getPosition();
- int oX = (int)((objectPoint.x) / 32);
- int oY = (int)((objectPoint.y) / 32);
-
- if (oX == tX && oY == tY)
- {
- objectList.push_back (*i);
- }
- }
-
- return objectList;
-}
bool MapComposite::insert(ObjectPtr obj)
{
diff --git a/src/mapcomposite.h b/src/game-server/mapcomposite.hpp
index 7961f4da..663271dd 100644
--- a/src/mapcomposite.h
+++ b/src/game-server/mapcomposite.hpp
@@ -23,11 +23,11 @@
#ifndef _TMW_SERVER_MAPCOMPOSITE_
#define _TMW_SERVER_MAPCOMPOSITE_
+
+#include <vector>
#include "object.h"
#include "player.h"
-
-#include <list>
class Map;
class MapComposite;
@@ -180,18 +180,13 @@ class MapComposite {
/**
* Gets an iterator on the objects around a given object.
*/
- ZoneIterator getAroundObjectIterator(Object *) const;
-
- /**
- * Gets all objects on a tile
- */
- std::list<ObjectPtr> getObjectsOnTile(Point const &) const;
+ ZoneIterator getAroundObjectIterator(Object *, int radius) const;
/**
* Gets an iterator on the objects around the old and new positions of
* a player (including the ones that were but are now elsewhere).
*/
- ZoneIterator getAroundPlayerIterator(Player *) const;
+ ZoneIterator getAroundPlayerIterator(Player *, int radius) const;
private:
MapComposite(MapComposite const &);
@@ -207,9 +202,9 @@ class MapComposite {
void deallocate(MovingObject *);
/**
- * Fills a region of zones with the vision range around a point.
+ * Fills a region of zones within the range of a point.
*/
- void fillRegion(MapRegion &, Point const &) const;
+ void fillRegion(MapRegion &, Point const &, int) const;
Map *map; /**< Actual map. */
diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp
index 3bb2e478..95e093c2 100644
--- a/src/game-server/state.cpp
+++ b/src/game-server/state.cpp
@@ -24,10 +24,11 @@
#include <cassert>
#include "controller.h"
+#include "defines.h"
#include "map.h"
-#include "mapcomposite.h"
#include "point.h"
#include "game-server/gamehandler.hpp"
+#include "game-server/mapcomposite.hpp"
#include "game-server/mapmanager.hpp"
#include "game-server/state.hpp"
#include "net/messageout.hpp"
@@ -56,182 +57,190 @@ State::~State()
}
}
-void
-State::update()
+void State::updateMap(MapComposite *map)
{
- /*
- * Update game state (update AI, etc.)
- */
- for (std::map< unsigned, MapComposite * >::iterator m = maps.begin(),
- m_end = maps.end(); m != m_end; ++m)
+ // 1. update object status.
+ for (ObjectIterator i(map->getWholeMapIterator()); i; ++i)
{
- MapComposite *map = m->second;
+ (*i)->update();
+ }
- for (ObjectIterator o(map->getWholeMapIterator()); o; ++o)
+ // 2. perform attacks.
+ for (MovingObjectIterator i(map->getWholeMapIterator()); i; ++i)
+ {
+ MovingObject *o = *i;
+ if (o->getUpdateFlags() & ATTACK)
{
- (*o)->update();
- if ((*o)->getType() == OBJECT_PLAYER || (*o)->getType() == OBJECT_MONSTER)
- {
- static_cast< Being * >(*o)->clearHitsTaken();
- }
+ static_cast< Being * >(o)->performAttack(map);
}
+ }
+
+ // 3. move objects around and update zones.
+ for (MovingObjectIterator i(map->getWholeMapIterator()); i; ++i)
+ {
+ (*i)->move();
+ }
+ map->update();
+}
+
+void State::informPlayer(MapComposite *map, Player *p)
+{
+ MessageOut moveMsg(GPMSG_BEINGS_MOVE);
+ MessageOut damageMsg(GPMSG_BEINGS_DAMAGE);
+ Point pold = p->getOldPosition(), ppos = p->getPosition();
+ int pid = p->getPublicID(), pflags = p->getUpdateFlags();
+
+ for (MovingObjectIterator i(map->getAroundPlayerIterator(p, AROUND_AREA)); i; ++i)
+ {
+ MovingObject *o = *i;
- for (MovingObjectIterator o(map->getWholeMapIterator()); o; ++o)
+ Point oold = o->getOldPosition(), opos = o->getPosition();
+ int otype = o->getType();
+ int oid = o->getPublicID(), oflags = o->getUpdateFlags();
+ int flags = 0;
+
+ // Send attack messages.
+ if ((oflags & ATTACK) && oid != pid && ppos.inRangeOf(opos))
{
- if ((*o)->getUpdateFlags() & ATTACK)
- {
- static_cast< Being * >(*o)->performAttack(m->second);
- }
+ MessageOut AttackMsg(GPMSG_BEING_ATTACK);
+ AttackMsg.writeShort(oid);
+ gameHandler->sendTo(p, AttackMsg);
}
- for (MovingObjectIterator o(map->getWholeMapIterator()); o; ++o)
+ // Send damage messages.
+ if (otype == OBJECT_PLAYER || otype == OBJECT_MONSTER)
{
- (*o)->move();
+ Being *victim = static_cast< Being * >(o);
+ Hits const &hits = victim->getHitsTaken();
+ for (Hits::const_iterator j = hits.begin(),
+ j_end = hits.end(); j != j_end; ++j)
+ {
+ damageMsg.writeShort(oid);
+ damageMsg.writeShort(*j);
+ }
}
- map->update();
+ /* Check whether this player and this moving object were around
+ the last time and whether they will be around the next time. */
+ bool wereInRange = pold.inRangeOf(oold) &&
+ !((pflags | oflags) & NEW_ON_MAP);
+ bool willBeInRange = ppos.inRangeOf(opos);
- /*
- * Inform clients about changes in the game state
- */
- for (PlayerIterator p(map->getWholeMapIterator()); p; ++p)
+ // Send enter/leaver messages.
+ if (!wereInRange)
{
- MessageOut moveMsg(GPMSG_BEINGS_MOVE);
- MessageOut damageMsg(GPMSG_BEINGS_DAMAGE);
-
- for (MovingObjectIterator o(map->getAroundPlayerIterator(*p)); o; ++o)
+ // o was outside p's range.
+ if (!willBeInRange)
{
+ // Nothing to report: o will not be inside p's range.
+ continue;
+ }
+ flags |= MOVING_DESTINATION;
- Point os = (*o)->getOldPosition();
- Point on = (*o)->getPosition();
-
- int flags = 0;
-
- // Send attack messages
- if ( (*o)->getUpdateFlags() & ATTACK
- && (*o)->getPublicID() != (*p)->getPublicID()
- && (*p)->getPosition().inRangeOf(on)
- )
+ MessageOut enterMsg(GPMSG_BEING_ENTER);
+ enterMsg.writeByte(otype);
+ enterMsg.writeShort(oid);
+ switch (otype) {
+ case OBJECT_PLAYER:
{
- MessageOut AttackMsg (GPMSG_BEING_ATTACK);
- AttackMsg.writeShort((*o)->getPublicID());
-
- LOG_DEBUG("Sending attack packet from " << (*o)->getPublicID()
- << " to " << (*p)->getPublicID(), 0);
+ Player *q = static_cast< Player * >(o);
+ enterMsg.writeString(q->getName());
+ enterMsg.writeByte(q->getHairStyle());
+ enterMsg.writeByte(q->getHairColor());
+ enterMsg.writeByte(q->getGender());
+ } break;
+ case OBJECT_MONSTER:
+ {
+ enterMsg.writeShort(0); // TODO: The monster ID
+ } break;
+ default:
+ assert(false); // TODO
+ }
+ gameHandler->sendTo(p, enterMsg);
+ }
+ else if (!willBeInRange)
+ {
+ // o is no longer visible from p.
+ MessageOut leaveMsg(GPMSG_BEING_LEAVE);
+ leaveMsg.writeShort(oid);
+ gameHandler->sendTo(p, leaveMsg);
+ continue;
+ }
+ else if (oold.x == opos.x && oold.y == opos.y)
+ {
+ // o does not move, nothing to report.
+ continue;
+ }
- gameHandler->sendTo(*p, AttackMsg);
- }
+ /* At this point, either o has entered p's range, either o is
+ moving inside p's range. Report o's movements. */
- // Send damage messages
+ Point odst = o->getDestination();
+ if (opos.x != odst.x || opos.y != odst.y)
+ {
+ flags |= MOVING_POSITION;
+ if (oflags & NEW_DESTINATION)
+ {
+ flags |= MOVING_DESTINATION;
+ }
+ }
+ else
+ {
+ // No need to synchronize on the very last step.
+ flags |= MOVING_DESTINATION;
+ }
- if ((*o)->getType() == OBJECT_PLAYER || (*o)->getType() == OBJECT_MONSTER)
- {
- Being *victim = static_cast< Being * >(*o);
- Hits const &hits = victim->getHitsTaken();
- for (Hits::const_iterator i = hits.begin(),
- i_end = hits.end(); i != i_end; ++i)
- {
- damageMsg.writeShort(victim->getPublicID());
- damageMsg.writeShort((*i));
- }
- }
-
- // Send move messages
-
- /* 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)->getOldPosition().inRangeOf(os) &&
- !(((*p)->getUpdateFlags() | (*o)->getUpdateFlags()) & NEW_ON_MAP);
- bool willBeInRange = (*p)->getPosition().inRangeOf(on);
- if (!wereInRange)
- {
- // o was outside p's range.
- if (!willBeInRange)
- {
- // Nothing to report: o will not be inside p's range.
- continue;
- }
- flags |= MOVING_DESTINATION;
-
- int type = (*o)->getType();
- MessageOut enterMsg(GPMSG_BEING_ENTER);
- enterMsg.writeByte(type);
- enterMsg.writeShort((*o)->getPublicID());
- switch (type) {
- case OBJECT_PLAYER:
- {
- Player *q = static_cast< Player * >(*o);
- enterMsg.writeString(q->getName());
- enterMsg.writeByte(q->getHairStyle());
- enterMsg.writeByte(q->getHairColor());
- enterMsg.writeByte(q->getGender());
- } break;
- case OBJECT_MONSTER:
- {
- enterMsg.writeShort(0); // TODO: The monster ID
- } break;
- default:
- assert(false); // TODO
- }
- gameHandler->sendTo(*p, enterMsg);
- }
- else if (!willBeInRange)
- {
- // o is no longer visible from p.
- MessageOut leaveMsg(GPMSG_BEING_LEAVE);
- leaveMsg.writeShort((*o)->getPublicID());
- gameHandler->sendTo(*p, leaveMsg);
- continue;
- }
- else if (os.x == on.x && os.y == on.y)
- {
- // o does not move, nothing to report.
- continue;
- }
+ // Send move messages.
+ moveMsg.writeShort(oid);
+ moveMsg.writeByte(flags);
+ if (flags & MOVING_POSITION)
+ {
+ moveMsg.writeCoordinates(opos.x / 32, opos.y / 32);
+ }
+ if (flags & MOVING_DESTINATION)
+ {
+ moveMsg.writeShort(odst.x);
+ moveMsg.writeShort(odst.y);
+ }
+ }
- /* At this point, either o has entered p's range, either o is
- moving inside p's range. Report o's movements. */
+ // Do not send a packet if nothing happened in p's range.
+ if (moveMsg.getLength() > 2)
+ gameHandler->sendTo(p, moveMsg);
- Point od = (*o)->getDestination();
- if (on.x != od.x || on.y != od.y)
- {
- flags |= MOVING_POSITION;
- if ((*o)->getUpdateFlags() & NEW_DESTINATION)
- {
- flags |= MOVING_DESTINATION;
- }
- }
- else
- {
- // no need to synchronize on the very last step
- flags |= MOVING_DESTINATION;
- }
+ if (damageMsg.getLength() > 2)
+ gameHandler->sendTo(p, damageMsg);
+}
- moveMsg.writeShort((*o)->getPublicID());
- moveMsg.writeByte(flags);
- if (flags & MOVING_POSITION)
- {
- moveMsg.writeCoordinates(on.x / 32, on.y / 32);
- }
- if (flags & MOVING_DESTINATION)
- {
- moveMsg.writeShort(od.x);
- moveMsg.writeShort(od.y);
- }
- }
+void State::update()
+{
+ /*
+ * Update game state (update AI, etc.)
+ */
+ for (std::map< unsigned, MapComposite * >::iterator m = maps.begin(),
+ m_end = maps.end(); m != m_end; ++m)
+ {
+ MapComposite *map = m->second;
- // Don't send a packet if nothing happened in p's range.
- if (moveMsg.getLength() > 2)
- gameHandler->sendTo(*p, moveMsg);
+ updateMap(map);
- if (damageMsg.getLength() > 2)
- gameHandler->sendTo(*p, damageMsg);
+ /*
+ * Inform clients about changes in the game state
+ */
+ for (PlayerIterator p(map->getWholeMapIterator()); p; ++p)
+ {
+ informPlayer(map, *p);
}
- for (ObjectIterator o(map->getWholeMapIterator()); o; ++o)
+ for (ObjectIterator i(map->getWholeMapIterator()); i; ++i)
{
- (*o)->clearUpdateFlags();
+ Object *o = *i;
+ o->clearUpdateFlags();
+ int type = o->getType();
+ if (type == OBJECT_PLAYER || type == OBJECT_MONSTER)
+ {
+ static_cast< Being * >(o)->clearHitsTaken();
+ }
}
}
}
@@ -278,7 +287,7 @@ State::removeObject(ObjectPtr objectPtr)
msg.writeShort(obj->getPublicID());
Point objectPos = obj->getPosition();
- for (PlayerIterator p(map->getAroundObjectIterator(obj)); p; ++p)
+ for (PlayerIterator p(map->getAroundObjectIterator(obj, AROUND_AREA)); p; ++p)
{
if (*p != obj && objectPos.inRangeOf((*p)->getPosition()))
{
@@ -321,7 +330,7 @@ void State::sayAround(Object *obj, std::string text)
MapComposite *map = m->second;
Point speakerPosition = obj->getPosition();
- for (PlayerIterator i(map->getAroundObjectIterator(obj)); i; ++i)
+ for (PlayerIterator i(map->getAroundObjectIterator(obj, AROUND_AREA)); i; ++i)
{
if (speakerPosition.inRangeOf((*i)->getPosition()))
{
diff --git a/src/game-server/state.hpp b/src/game-server/state.hpp
index 36bd87d0..7fcfcf2f 100644
--- a/src/game-server/state.hpp
+++ b/src/game-server/state.hpp
@@ -37,39 +37,49 @@ class MapComposite;
*/
class State
{
- /**
- * List of maps.
- */
- std::map<unsigned int, MapComposite *> maps;
+ /**
+ * List of maps.
+ */
+ std::map<unsigned int, MapComposite *> maps;
- public:
- State();
- ~State();
+ /**
+ * Updates object states on the map.
+ */
+ void updateMap(MapComposite *);
- /**
- * Update game state (contains core server logic).
- */
- void update();
+ /**
+ * Informs a player of what happened around.
+ */
+ void informPlayer(MapComposite *, Player *);
- /**
- * Load map into game world.
- */
- MapComposite *loadMap(unsigned mapId);
+ public:
+ State();
+ ~State();
- /**
- * Add object to the map.
- */
- void addObject(ObjectPtr objectPtr);
+ /**
+ * Updates game state (contains core server logic).
+ */
+ void update();
- /**
- * Remove an object from the map.
- */
- void removeObject(ObjectPtr objectPtr);
+ /**
+ * Loads map into game world.
+ */
+ MapComposite *loadMap(unsigned mapId);
- /**
- * Say around an object.
- */
- void sayAround(Object *, std::string text);
+ /**
+ * Adds object to the map.
+ */
+ void addObject(ObjectPtr objectPtr);
+
+ /**
+ * Removes an object from the map.
+ */
+ void removeObject(ObjectPtr objectPtr);
+
+ /**
+ * Says something around an object.
+ */
+ void sayAround(Object *, std::string text);
};
extern State *gameState;
diff --git a/src/object.h b/src/object.h
index 23d97434..3e296d54 100644
--- a/src/object.h
+++ b/src/object.h
@@ -26,7 +26,6 @@
#include <vector>
-#include "defines.h"
#include "point.h"
#include "utils/countedptr.h"
@@ -136,20 +135,12 @@ class MovingObject: public Object
{
public:
/**
- * Directions, to be used as bitmask values
- */
- static const char DOWN = 1;
- static const char LEFT = 2;
- static const char UP = 4;
- static const char RIGHT = 8;
-
- /**
* Proxy constructor.
*/
MovingObject(int type, int id)
: Object(type),
mPublicID(id),
- mDirection(DOWN),
+ mDirection(0),
mActionTime(0)
{}
@@ -174,7 +165,7 @@ class MovingObject: public Object
/**
* Sete object direction
*/
- void setDirection(unsigned char direction)
+ void setDirection(int direction)
{ mDirection = direction; }
/**
diff --git a/src/player.cpp b/src/player.cpp
index d91bfcab..e7d84d3e 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -23,7 +23,6 @@
#include <cassert>
#include "defines.h"
-#include "mapcomposite.h"
#include "player.h"
/**