summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Sehmisch <tmw@crushnet.org>2007-03-02 23:30:17 +0000
committerPhilipp Sehmisch <tmw@crushnet.org>2007-03-02 23:30:17 +0000
commitaf1ce69940a9c0b46907402e7d69e6ac9ea96912 (patch)
tree016a6a8a4734f794e56093e1611530749eb7fab0
parent07782116ae9158c20165dd4d60bdb96017ac009f (diff)
downloadmanaserv-af1ce69940a9c0b46907402e7d69e6ac9ea96912.tar.gz
manaserv-af1ce69940a9c0b46907402e7d69e6ac9ea96912.tar.bz2
manaserv-af1ce69940a9c0b46907402e7d69e6ac9ea96912.tar.xz
manaserv-af1ce69940a9c0b46907402e7d69e6ac9ea96912.zip
Implemented being death, removal of dead mobs and sitting.
-rw-r--r--ChangeLog9
-rw-r--r--src/controller.cpp25
-rw-r--r--src/controller.h10
-rw-r--r--src/defines.h5
-rw-r--r--src/game-server/being.cpp42
-rw-r--r--src/game-server/being.hpp71
-rw-r--r--src/game-server/gamehandler.cpp25
-rw-r--r--src/game-server/object.hpp14
-rw-r--r--src/game-server/player.cpp6
-rw-r--r--src/game-server/player.hpp21
-rw-r--r--src/game-server/state.cpp52
-rw-r--r--src/game-server/testing.cpp1
-rw-r--r--src/point.h10
13 files changed, 217 insertions, 74 deletions
diff --git a/ChangeLog b/ChangeLog
index 32d3c387..c7044ee3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-03-03 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/controller.cpp, src/controller.h, src/defines.h,
+ src/gameserver/being.cpp, src/gameserver/being.hpp,
+ src/gameserver/gamehandler.cpp, src/gameserver/object.hpp,
+ src/gameserver/player.cpp, src/gameserver/player.hpp,
+ src/gameserver/state.cpp, src/gameserver/testing.cpp,
+ src/point.h: Implemented being death, removal of dead mobs and sitting.
+
2007-03-01 Bjørn Lindeijer <bjorn@lindeijer.nl>
* src/Makefile.am: Updated with new collision related module.
diff --git a/src/controller.cpp b/src/controller.cpp
index a243006c..42a64b66 100644
--- a/src/controller.cpp
+++ b/src/controller.cpp
@@ -31,16 +31,29 @@ void Controlled::update()
*/
if (mCountDown == 0)
{
- Point randomPos = { rand() % 320 + 720,
- rand() % 320 + 840 };
- setDestination(randomPos);
- mCountDown = 10 + rand() % 10;
+ if (mAction != DEAD)
+ {
+ Point randomPos = { rand() % 320 + 720,
+ rand() % 320 + 840 };
+ setDestination(randomPos);
+ mCountDown = 10 + rand() % 10;
- LOG_DEBUG("Setting new random destination " << randomPos.x << ","
- << randomPos.y << " for being " << getPublicID());
+ LOG_DEBUG("Setting new random destination " << randomPos.x << ","
+ << randomPos.y << " for being " << getPublicID());
+ }
+ else
+ {
+ raiseUpdateFlags(UPDATEFLAG_REMOVE);
+ }
}
else
{
mCountDown--;
}
}
+
+void Controlled::die()
+{
+ mCountDown = 600;
+ Being::die();
+}
diff --git a/src/controller.h b/src/controller.h
index adbc54a7..40e4b22b 100644
--- a/src/controller.h
+++ b/src/controller.h
@@ -34,13 +34,21 @@ class Controlled: public Being
/**
* Constructor.
*/
- Controlled(int type): Being(type, 65535), mCountDown(0) {}
+ Controlled(int type):
+ Being(type, 65535),
+ mCountDown(0)
+ {}
/**
* Performs one step of controller logic.
*/
void update();
+ /**
+ * Kills the being
+ */
+ virtual void die();
+
private:
/** Count down till next random movement (temporary). */
unsigned int mCountDown;
diff --git a/src/defines.h b/src/defines.h
index a452b9e0..589f0597 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -149,12 +149,14 @@ enum {
PGMSG_EQUIP = 0x0112, // B slot
GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }*
GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }*
- GPMSG_BEING_ENTER = 0x0200, // B type, W being id
+ GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position
// player: S name, B hair style, B hair color, B gender
// monster: W type id
GPMSG_BEING_LEAVE = 0x0201, // W being id
GPMSG_ITEM_APPEAR = 0x0202, // W item id, W*2 position
PGMSG_WALK = 0x0260, // W*2 destination
+ PGMSG_ACTION_CHANGE = 0x0270, // B Action
+ GPMSG_BEING_ACTION_CHANGE = 0x0271, // W being id, B action
GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, C position] [, W*2 destination] }*
GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }*
PGMSG_ATTACK = 0x0290, // B direction
@@ -164,7 +166,6 @@ enum {
PGMSG_USE_ITEM = 0x0300, // L item id
GPMSG_USE_RESPONSE = 0x0301, // B error
GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }*
- GPMSG_BEING_DEAD = 0xDEAD, // W being id
// Chat
CPMSG_ERROR = 0x0401, // B error
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp
index 7f2ec2f4..6924f3b9 100644
--- a/src/game-server/being.cpp
+++ b/src/game-server/being.cpp
@@ -29,13 +29,43 @@
void Being::damage(Damage damage)
{
+ if (mAction == DEAD) return;
+
int HPloss;
HPloss = damage; // TODO: Implement complex damage calculation here
+ if (HPloss > mHitpoints) HPloss = mHitpoints;
+
mHitpoints -= HPloss;
mHitsTaken.push_back(HPloss);
- LOG_DEBUG("Being " << getPublicID() << " got hit");
+ LOG_INFO("Being " << getPublicID() << " got hit");
+
+ if (mHitpoints == 0) die();
+}
+
+void Being::die()
+{
+ LOG_INFO("Being " << getPublicID() << " died");
+ setAction(DEAD);
+ // dead beings stay where they are
+ setDestination(getPosition());
+}
+
+void Being::move()
+{
+ MovingObject::move();
+ if (mAction == WALK || mAction == STAND)
+ {
+ if (mActionTime)
+ {
+ mAction = WALK;
+ }
+ else
+ {
+ mAction = STAND;
+ }
+ }
}
void Being::performAttack(MapComposite *map)
@@ -95,3 +125,13 @@ void Being::performAttack(MapComposite *map)
}
}
}
+
+void Being::setAction(Action action)
+{
+ mAction = action;
+ if (action != Being::ATTACK && // The players are informed about these actions
+ action != Being::WALK) // by other messages
+ {
+ raiseUpdateFlags(UPDATEFLAG_ACTIONCHANGE);
+ }
+}
diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp
index 327783ce..2eaffa16 100644
--- a/src/game-server/being.hpp
+++ b/src/game-server/being.hpp
@@ -65,31 +65,6 @@ struct BeingState
};
/**
- * Moves enum for beings and actors for others players vision.
- */
-enum
-{
- ACTION_DEFAULT = 0,
- ACTION_STAND,
- ACTION_WALK,
- ACTION_RUN,
- ACTION_JUMP,
- ACTION_CRAWL,
- ACTION_ATTACK,
- ACTION_ATTACK_SWING,
- ACTION_ATTACK_STAB,
- ACTION_ATTACK_BOW,
- ACTION_ATTACK_THROW,
- ACTION_CAST_MAGIC,
- ACTION_USE_ITEM,
- ACTION_SIT,
- ACTION_SLEEP,
- ACTION_HURT,
- ACTION_DEAD,
- ACTION_INVALID
-};
-
-/**
* Beings and actors directions
*/
enum
@@ -141,10 +116,24 @@ class Being : public MovingObject
{
public:
/**
+ * Moves enum for beings and actors for others players vision.
+ * WARNING: Has to be in sync with the same enum in the Being class
+ * of the client!
+ */
+ enum Action {
+ STAND,
+ WALK,
+ ATTACK,
+ SIT,
+ DEAD,
+ HURT
+ };
+ /**
* Proxy constructor.
*/
Being(int type, int id)
- : MovingObject(type, id)
+ : MovingObject(type, id),
+ mAction(STAND)
{}
/**
@@ -166,6 +155,12 @@ class Being : public MovingObject
{ return mStats.stats[numStat]; }
/**
+ * sets the hit points
+ */
+ void setHitpoints(int hp)
+ { mHitpoints = hp; }
+
+ /**
* Takes a damage structure, computes the real damage based on the
* stats, deducts the result from the hitpoints and adds the result to
* the HitsTaken list.
@@ -173,6 +168,11 @@ class Being : public MovingObject
void damage(Damage);
/**
+ * Kills the being
+ */
+ virtual void die();
+
+ /**
* Gets the damage list.
*/
Hits const &getHitsTaken() const
@@ -189,14 +189,29 @@ class Being : public MovingObject
*/
void performAttack(MapComposite *);
+ /**
+ * Sets the current action.
+ */
+ virtual void setAction(Action action);
+
+ virtual Action getAction() const
+ { return mAction; }
+
+ /**
+ * Moves the being toward its destination.
+ */
+ virtual void move();
+
+ protected:
+ int mHitpoints; /**< Hitpoints of the being */
+ Action mAction;
+
private:
Being(Being const &rhs);
Being &operator=(Being const &rhs);
Statistics mStats; /**< stats modifiers or computed stats */
- int mHitpoints; /**< Hitpoints of the being */
-
Hits mHitsTaken; /**< List of punches taken since last update */
};
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp
index 5801c6fe..768a2cd9 100644
--- a/src/game-server/gamehandler.cpp
+++ b/src/game-server/gamehandler.cpp
@@ -301,7 +301,30 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
LOG_DEBUG("Player " << computer.character->getPublicID()
<< " attacks");
computer.character->setDirection(message.readByte());
- computer.character->setAction(PLAYER_ATTACK);
+ computer.character->setAction(Being::ATTACK);
+ } break;
+
+ case PGMSG_ACTION_CHANGE:
+ {
+ Being::Action action = (Being::Action)message.readByte();
+ Being::Action current = (Being::Action)computer.character->getAction();
+
+ switch (action)
+ {
+ case Being::STAND:
+ {
+ if (current == Being::SIT)
+ computer.character->setAction(Being::STAND);
+ } break;
+ case Being::SIT:
+ {
+ if (current == Being::STAND)
+ computer.character->setAction(Being::SIT);
+ } break;
+ default:
+ break;
+ }
+
} break;
case PGMSG_DISCONNECT:
diff --git a/src/game-server/object.hpp b/src/game-server/object.hpp
index e0443f93..b067b34b 100644
--- a/src/game-server/object.hpp
+++ b/src/game-server/object.hpp
@@ -44,9 +44,11 @@ class MapComposite;
enum
{
- NEW_ON_MAP = 1,
- NEW_DESTINATION = 2,
- ATTACK = 4
+ UPDATEFLAG_NEW_ON_MAP = 1,
+ UPDATEFLAG_NEW_DESTINATION = 2,
+ UPDATEFLAG_ATTACK = 4,
+ UPDATEFLAG_ACTIONCHANGE = 8,
+ UPDATEFLAG_REMOVE = 16
};
/**
@@ -198,7 +200,7 @@ class MovingObject: public Object
* Sets the destination coordinates of the object.
*/
void setDestination(Point dst)
- { mDst = dst; raiseUpdateFlags(NEW_DESTINATION); mPath.clear(); }
+ { mDst = dst; raiseUpdateFlags(UPDATEFLAG_NEW_DESTINATION); mPath.clear(); }
/**
* Gets the old coordinates of the object.
@@ -239,7 +241,7 @@ class MovingObject: public Object
/**
* Moves the object toward its destination.
*/
- void move();
+ virtual void move();
/**
* Get public ID.
@@ -261,12 +263,12 @@ class MovingObject: public Object
Point mDst; /**< target coordinates */
Point mOld; /**< old coordinates */
unsigned short mSpeed; /**< speed */
- unsigned mSize; /**< radius of bounding circle */
std::list<PATH_NODE> mPath;
protected:
unsigned char mDirection; /**< Facing direction */
unsigned short mActionTime; /**< delay until next action */
+ unsigned mSize; /**< radius of bounding circle */
};
#endif // _TMWSERV_OBJECT_H_
diff --git a/src/game-server/player.cpp b/src/game-server/player.cpp
index f687cba6..5580d094 100644
--- a/src/game-server/player.cpp
+++ b/src/game-server/player.cpp
@@ -39,15 +39,15 @@ void Player::update()
setStat(STAT_SPEED, getRawStat(STAT_DEXTERITY));
// attacking
- if (mAction == PLAYER_ATTACK)
+ if (mAction == ATTACK)
{
// plausibility check of attack command
if (mActionTime <= 0)
{
// request perform attack
mActionTime = 1000;
- mAction = PLAYER_STAND;
- raiseUpdateFlags(ATTACK);
+ mAction = STAND;
+ raiseUpdateFlags(UPDATEFLAG_ATTACK);
}
}
}
diff --git a/src/game-server/player.hpp b/src/game-server/player.hpp
index 426738d7..bd1ec997 100644
--- a/src/game-server/player.hpp
+++ b/src/game-server/player.hpp
@@ -51,9 +51,11 @@ class Player : public Being, public PlayerData
Player(std::string const &name, int id = -1)
: Being(OBJECT_PLAYER, 65535),
PlayerData(name, id),
- mClient(NULL),
- mAction(PLAYER_STAND)
- {}
+ mClient(NULL)
+ {
+ mHitpoints=5;
+ mSize = 16;
+ }
/**
* Updates the internal status.
@@ -61,18 +63,6 @@ class Player : public Being, public PlayerData
void update();
/**
- * Sets next action.
- **/
- void setAction(int s)
- { mAction = s; }
-
- /**
- * Gets next action.
- **/
- int getAction() const
- { return mAction; }
-
- /**
* Gets client computer.
*/
GameClient *getClient() const
@@ -89,7 +79,6 @@ class Player : public Being, public PlayerData
Player &operator=(Player const &);
GameClient *mClient; /**< Client computer. */
- unsigned char mAction; /**< Player state. */
};
#endif // _TMWSERV_PLAYER_H_
diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp
index 58949ce7..09513b95 100644
--- a/src/game-server/state.cpp
+++ b/src/game-server/state.cpp
@@ -57,7 +57,7 @@ void State::updateMap(MapComposite *map)
for (MovingObjectIterator i(map->getWholeMapIterator()); i; ++i)
{
MovingObject *o = *i;
- if (o->getUpdateFlags() & ATTACK)
+ if (o->getUpdateFlags() & UPDATEFLAG_ATTACK)
{
static_cast< Being * >(o)->performAttack(map);
}
@@ -68,6 +68,17 @@ void State::updateMap(MapComposite *map)
{
(*i)->move();
}
+
+ // 4. remove dead beings
+ for (MovingObjectIterator i(map->getWholeMapIterator()); i; ++i)
+ {
+ if ((*i)->getUpdateFlags() & UPDATEFLAG_REMOVE)
+ {
+ DelayedEvent e = { EVENT_REMOVE};
+ enqueueEvent((*i), e);
+ }
+ }
+
map->update();
}
@@ -91,13 +102,30 @@ void State::informPlayer(MapComposite *map, Player *p)
if (willBeInRange)
{
// Send attack messages.
- if ((oflags & ATTACK) && oid != pid)
+ if ((oflags & UPDATEFLAG_ATTACK) && oid != pid)
{
MessageOut AttackMsg(GPMSG_BEING_ATTACK);
AttackMsg.writeShort(oid);
gameHandler->sendTo(p, AttackMsg);
}
+ // Send state change messages.
+ if ((oflags & UPDATEFLAG_ACTIONCHANGE))
+ {
+ MessageOut ActionMsg(GPMSG_BEING_ACTION_CHANGE);
+ ActionMsg.writeShort(oid);
+ ActionMsg.writeByte(static_cast< Being * >(o)->getAction());
+ gameHandler->sendTo(p, ActionMsg);
+ }
+
+ // Send leave messages of dead beings
+ if ((oflags & UPDATEFLAG_REMOVE))
+ {
+ MessageOut leaveMsg(GPMSG_BEING_LEAVE);
+ leaveMsg.writeShort(oid);
+ gameHandler->sendTo(p, leaveMsg);
+ }
+
// Send damage messages.
if (o->canFight())
{
@@ -114,7 +142,7 @@ void State::informPlayer(MapComposite *map, Player *p)
// Check if this player and this moving object were around.
bool wereInRange = pold.inRangeOf(oold, AROUND_AREA) &&
- !((pflags | oflags) & NEW_ON_MAP);
+ !((pflags | oflags) & UPDATEFLAG_NEW_ON_MAP);
// Send enter/leaver messages.
if (!wereInRange)
@@ -125,11 +153,14 @@ void State::informPlayer(MapComposite *map, Player *p)
// Nothing to report: o will not be inside p's range.
continue;
}
- flags |= MOVING_DESTINATION;
+ flags |= MOVING_POSITION;
MessageOut enterMsg(GPMSG_BEING_ENTER);
enterMsg.writeByte(otype);
enterMsg.writeShort(oid);
+ enterMsg.writeByte(static_cast< Being *>(o)->getAction());
+ enterMsg.writeShort(opos.x);
+ enterMsg.writeShort(opos.y);
switch (otype) {
case OBJECT_PLAYER:
{
@@ -147,6 +178,7 @@ void State::informPlayer(MapComposite *map, Player *p)
assert(false); // TODO
}
gameHandler->sendTo(p, enterMsg);
+ continue;
}
else if (!willBeInRange)
{
@@ -156,7 +188,7 @@ void State::informPlayer(MapComposite *map, Player *p)
gameHandler->sendTo(p, leaveMsg);
continue;
}
- else if (oold.x == opos.x && oold.y == opos.y)
+ else if (oold == opos)
{
// o does not move, nothing to report.
continue;
@@ -166,10 +198,10 @@ void State::informPlayer(MapComposite *map, Player *p)
moving inside p's range. Report o's movements. */
Point odst = o->getDestination();
- if (opos.x != odst.x || opos.y != odst.y)
+ if (opos != odst)
{
flags |= MOVING_POSITION;
- if (oflags & NEW_DESTINATION)
+ if (oflags & UPDATEFLAG_NEW_DESTINATION)
{
flags |= MOVING_DESTINATION;
}
@@ -210,11 +242,11 @@ void State::informPlayer(MapComposite *map, Player *p)
int oflags = o->getUpdateFlags();
bool willBeInRange = ppos.inRangeOf(opos, AROUND_AREA);
bool wereInRange = pold.inRangeOf(opos, AROUND_AREA) &&
- !((pflags | oflags) & NEW_ON_MAP);
+ !((pflags | oflags) & UPDATEFLAG_NEW_ON_MAP);
if (willBeInRange ^ wereInRange)
{
- if (oflags & NEW_ON_MAP)
+ if (oflags & UPDATEFLAG_NEW_ON_MAP)
{
MessageOut appearMsg(GPMSG_ITEM_APPEAR);
appearMsg.writeShort(o->getItemClass()->getDatabaseID());
@@ -329,7 +361,7 @@ void State::insert(Thing *ptr)
if (ptr->isVisible())
{
Object *obj = static_cast< Object * >(ptr);
- obj->raiseUpdateFlags(NEW_ON_MAP);
+ obj->raiseUpdateFlags(UPDATEFLAG_NEW_ON_MAP);
if (obj->getType() != OBJECT_PLAYER) return;
/* Since the player doesn't know yet where on the world he is after
diff --git a/src/game-server/testing.cpp b/src/game-server/testing.cpp
index 86f47f2c..4f269e29 100644
--- a/src/game-server/testing.cpp
+++ b/src/game-server/testing.cpp
@@ -37,6 +37,7 @@ void testingMap(int id)
Being *being = new Controlled(OBJECT_MONSTER);
being->setSpeed(150);
being->setSize(8);
+ being->setHitpoints(3);
being->setMapId(1);
Point pos = { 720, 900 };
being->setPosition(pos);
diff --git a/src/point.h b/src/point.h
index 74b8ab0e..edf208be 100644
--- a/src/point.h
+++ b/src/point.h
@@ -42,6 +42,16 @@ class Point
return std::abs(x - p.x) <= radius &&
std::abs(y - p.y) <= radius;
}
+
+ bool operator== (const Point &other) const
+ {
+ return (x == other.x && y == other.y);
+ }
+
+ bool operator!= (const Point &other) const
+ {
+ return (x != other.x || y != other.y);
+ }
};
/**