diff options
author | Philipp Sehmisch <tmw@crushnet.org> | 2007-03-02 23:30:17 +0000 |
---|---|---|
committer | Philipp Sehmisch <tmw@crushnet.org> | 2007-03-02 23:30:17 +0000 |
commit | af1ce69940a9c0b46907402e7d69e6ac9ea96912 (patch) | |
tree | 016a6a8a4734f794e56093e1611530749eb7fab0 /src/game-server | |
parent | 07782116ae9158c20165dd4d60bdb96017ac009f (diff) | |
download | manaserv-af1ce69940a9c0b46907402e7d69e6ac9ea96912.tar.gz manaserv-af1ce69940a9c0b46907402e7d69e6ac9ea96912.tar.bz2 manaserv-af1ce69940a9c0b46907402e7d69e6ac9ea96912.tar.xz manaserv-af1ce69940a9c0b46907402e7d69e6ac9ea96912.zip |
Implemented being death, removal of dead mobs and sitting.
Diffstat (limited to 'src/game-server')
-rw-r--r-- | src/game-server/being.cpp | 42 | ||||
-rw-r--r-- | src/game-server/being.hpp | 71 | ||||
-rw-r--r-- | src/game-server/gamehandler.cpp | 25 | ||||
-rw-r--r-- | src/game-server/object.hpp | 14 | ||||
-rw-r--r-- | src/game-server/player.cpp | 6 | ||||
-rw-r--r-- | src/game-server/player.hpp | 21 | ||||
-rw-r--r-- | src/game-server/state.cpp | 52 | ||||
-rw-r--r-- | src/game-server/testing.cpp | 1 |
8 files changed, 167 insertions, 65 deletions
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); |