diff options
author | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2009-04-23 21:00:16 +0200 |
---|---|---|
committer | Bjørn Lindeijer <bjorn@lindeijer.nl> | 2009-04-26 17:18:21 +0200 |
commit | e726c34606f85347e70a0deb6b180db03b6d0c25 (patch) | |
tree | e78e5ba07dd9484abed035cc3e63744101bbef57 | |
parent | a3f72002fa02cd4c525f101c5f240a22d4480119 (diff) | |
download | manaserv-e726c34606f85347e70a0deb6b180db03b6d0c25.tar.gz manaserv-e726c34606f85347e70a0deb6b180db03b6d0c25.tar.bz2 manaserv-e726c34606f85347e70a0deb6b180db03b6d0c25.tar.xz manaserv-e726c34606f85347e70a0deb6b180db03b6d0c25.zip |
Merged MovingObject into the Being class
Also renamed Object to Actor, to make it sound a little less generic.
Cleans up a bit the rather big hierarchy of different object types we
have.
29 files changed, 621 insertions, 703 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 62cc50fa..d4fdd662 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -88,6 +88,8 @@ tmwserv_game_SOURCES = \ common/inventorydata.hpp \ game-server/accountconnection.hpp \ game-server/accountconnection.cpp \ + game-server/actor.hpp \ + game-server/actor.cpp \ game-server/attackzone.hpp \ game-server/attackzone.cpp \ game-server/being.hpp \ @@ -124,11 +126,8 @@ tmwserv_game_SOURCES = \ game-server/monster.cpp \ game-server/monstermanager.hpp \ game-server/monstermanager.cpp \ - game-server/movingobject.hpp \ - game-server/movingobject.cpp \ game-server/npc.hpp \ game-server/npc.cpp \ - game-server/object.hpp \ game-server/postman.hpp \ game-server/quest.hpp \ game-server/quest.cpp \ diff --git a/src/account-server/character.hpp b/src/account-server/character.hpp index fa8ce3e2..d63a0b0b 100644 --- a/src/account-server/character.hpp +++ b/src/account-server/character.hpp @@ -38,16 +38,10 @@ class Character Character(std::string const &name, int id = -1); /** - * Get and set methods + * Gets the database id of the character. */ - - /** Gets the database id of the character. */ - int - getDatabaseID() const { return mDatabaseID; } - - /** Sets the database id of the character. */ - void - setDatabaseID(int id) { mDatabaseID = id; } + int getDatabaseID() const { return mDatabaseID; } + void setDatabaseID(int id) { mDatabaseID = id; } /** Gets the account the character belongs to. */ Account *getAccount() const @@ -56,45 +50,35 @@ class Character /** Sets the account the character belongs to, and related fields. */ void setAccount(Account *ptr); - /** Gets the ID of the account the character belongs to. */ - int getAccountID() const - { return mAccountID; } - - /** Sets the ID of the account the character belongs to. */ - void setAccountID(int id) - { mAccountID = id; } - - /** Gets the name of the character. */ - std::string const & - getName() const { return mName; } - - /** Sets the name of the character. */ - void - setName(const std::string& name) { mName = name; } - - /** Gets the gender of the character (male / female). */ - int - getGender() const { return mGender; } - - /** Sets the gender of the character (male / female). */ - void - setGender(int gender) { mGender = gender; } + /** + * Gets the ID of the account the character belongs to. + */ + int getAccountID() const { return mAccountID; } + void setAccountID(int id) { mAccountID = id; } - /** Gets the hairstyle of the character. */ - int - getHairStyle() const { return mHairStyle; } + /** + * Gets the name of the character. + */ + std::string const &getName() const { return mName; } + void setName(const std::string& name) { mName = name; } - /** Sets the hairstyle of the character. */ - void - setHairStyle(int style) { mHairStyle = style; } + /** + * Gets the gender of the character (male / female). + */ + int getGender() const { return mGender; } + void setGender(int gender) { mGender = gender; } - /** Gets the haircolor of the character. */ - int - getHairColor() const { return mHairColor; } + /** + * Gets the hairstyle of the character. + */ + int getHairStyle() const { return mHairStyle; } + void setHairStyle(int style) { mHairStyle = style; } - /** Sets the haircolor of the character. */ - void - setHairColor(int color) { mHairColor = color; } + /** + * Gets the haircolor of the character. + */ + int getHairColor() const { return mHairColor; } + void setHairColor(int color) { mHairColor = color; } /** Gets the account level of the user. */ int getAccountLevel() const @@ -107,13 +91,11 @@ class Character void setAccountLevel(int l, bool force = false) { if (force) mAccountLevel = l; } - /** Gets the level of the character. */ - int - getLevel() const { return mLevel; } - - /** Sets the level of the character. */ - void - setLevel(int level) { mLevel = level; } + /** + * Gets the level of the character. + */ + int getLevel() const { return mLevel; } + void setLevel(int level) { mLevel = level; } /** Gets the value of a base attribute of the character. */ int getAttribute(int n) const @@ -132,21 +114,17 @@ class Character void receiveExperience(int skill, int value) { mExperience[skill] += value; } - /** Gets the Id of the map that the character is on. */ - int - getMapId() const { return mMapId; } - - /** Sets the Id of the map that the character is on. */ - void - setMapId(int mapId) { mMapId = mapId; } - - /** Gets the position of the character on the map. */ - Point const & - getPosition() const { return mPos; } + /** + * Gets the Id of the map that the character is on. + */ + int getMapId() const { return mMapId; } + void setMapId(int mapId) { mMapId = mapId; } - /** Sets the position of the character on the map. */ - void - setPosition(const Point &p) { mPos = p; } + /** + * Gets the position of the character on the map. + */ + Point const &getPosition() const { return mPos; } + void setPosition(const Point &p) { mPos = p; } /** Add a guild to the character */ void addGuild(const std::string &name) { mGuilds.push_back(name); } @@ -205,8 +183,6 @@ class Character //!< belongs to. }; -// Utility typedefs - /** * Type definition for a list of Characters. */ diff --git a/src/defines.h b/src/defines.h index 7ffb2422..57860edd 100644 --- a/src/defines.h +++ b/src/defines.h @@ -364,7 +364,7 @@ enum { GUILD_EVENT_OFFLINE_PLAYER }; -// Moving object flags +// Being flags enum { // Payload contains the current position. MOVING_POSITION = 1, diff --git a/src/game-server/actor.cpp b/src/game-server/actor.cpp new file mode 100644 index 00000000..cb0e7a8d --- /dev/null +++ b/src/game-server/actor.cpp @@ -0,0 +1,62 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "game-server/actor.hpp" + +#include "game-server/map.hpp" +#include "game-server/mapcomposite.hpp" + +#include <cassert> + +void Actor::setPosition(const Point &p) +{ + mPos = p; + + // Update blockmap + if (getMap()) + { + const Point &oldP = getPosition(); + if ((oldP.x / 32 != p.x / 32 || oldP.y / 32 != p.y / 32)) + { + getMap()->getMap()->freeTile(oldP.x / 32, oldP.y / 32, getBlockType()); + getMap()->getMap()->blockTile(p.x / 32, p.y / 32, getBlockType()); + } + } +} + +void Actor::setMap(MapComposite *map) +{ + assert (map); + MapComposite *oldMap = getMap(); + Point p = getPosition(); + + if (oldMap) + { + oldMap->getMap()->freeTile(p.x / 32, p.y / 32, getBlockType()); + } + Thing::setMap(map); + map->getMap()->blockTile(p.x / 32, p.y / 32, getBlockType()); + /* the last line might look illogical because the current position is + * invalid on the new map, but it is necessary to block the old position + * because the next call of setPosition() will automatically free the old + * position. When we don't block the position now the occupation counting + * will be off. + */ +} diff --git a/src/game-server/actor.hpp b/src/game-server/actor.hpp new file mode 100644 index 00000000..e2cc912a --- /dev/null +++ b/src/game-server/actor.hpp @@ -0,0 +1,145 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _TMWSERV_ACTOR_H_ +#define _TMWSERV_ACTOR_H_ + +#include "point.h" +#include "game-server/map.hpp" +#include "game-server/thing.hpp" + +/** + * Flags that are raised as necessary. They trigger messages that are sent to + * the clients. + */ +enum +{ + UPDATEFLAG_NEW_ON_MAP = 1, + UPDATEFLAG_NEW_DESTINATION = 2, + UPDATEFLAG_ATTACK = 4, + UPDATEFLAG_ACTIONCHANGE = 8, + UPDATEFLAG_LOOKSCHANGE = 16, + UPDATEFLAG_DIRCHANGE = 32, + UPDATEFLAG_HEALTHCHANGE = 64 +}; + +/** + * Generic client-visible object. Keeps track of position, size and what to + * update clients about. + */ +class Actor : public Thing +{ + public: + /** + * Constructor. + */ + Actor(ThingType type) + : Thing(type), + mActionTime(0), + mUpdateFlags(0), + mPublicID(65535), + mSize(0) + {} + + /** + * Sets the coordinates. Also updates the walkmap of the map the actor + * is on. + * + * @param p the coordinates. + */ + void setPosition(const Point &p); + + /** + * Gets the coordinates. + * + * @return the coordinates. + */ + const Point &getPosition() const + { return mPos; } + + /** + * Gets what changed in the actor. + */ + int getUpdateFlags() const + { return mUpdateFlags; } + + /** + * Sets some changes in the actor. + */ + void raiseUpdateFlags(int n) + { mUpdateFlags |= n; } + + /** + * Clears changes in the actor. + */ + void clearUpdateFlags() + { mUpdateFlags = 0; } + + /** + * Sets actor bounding circle radius. + */ + void setSize(int s) { mSize = s; } + int getSize() const { return mSize; } + + /** + * Get public ID. + * + * @return the public ID, 65535 if none yet. + */ + int getPublicID() const + { return mPublicID; } + + /** + * Set public ID. The actor shall not have any public ID yet. + */ + void setPublicID(int id) + { mPublicID = id; } + + /** + * Gets the way the actor blocks pathfinding for other actors. + */ + virtual unsigned char getWalkMask() const + { return 0x00; } //can walk through everything + + /** + * Overridden in order to update the walkmap. + */ + virtual void setMap(MapComposite *map); + + protected: + /** + * Gets the way the actor blocks pathfinding for other actors. + */ + virtual Map::BlockType getBlockType() const + { return Map::BLOCKTYPE_NONE; } + + unsigned short mActionTime; /**< Delay until next action. */ + + private: + char mUpdateFlags; /**< Changes in actor status. */ + + /** Actor ID sent to clients (unique with respect to the map). */ + unsigned short mPublicID; + + Point mPos; /**< Coordinates. */ + unsigned char mSize; /**< Radius of bounding circle. */ +}; + +#endif // _TMWSERV_ACTOR_H_ diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index ace30861..7319bcbe 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -30,9 +30,11 @@ #include "game-server/effect.hpp" #include "utils/logger.h" -Being::Being(int type, int id): - MovingObject(type, id), +Being::Being(ThingType type): + Actor(type), mAction(STAND), + mSpeed(0), + mDirection(0), mHpRegenTimer(0) { Attribute attr = { 0, 0 }; @@ -44,9 +46,10 @@ Being::Being(int type, int id): } } -int Being::damage(Object *, Damage const &damage) +int Being::damage(Actor *, Damage const &damage) { - if (mAction == DEAD) return 0; + if (mAction == DEAD) + return 0; int HPloss = damage.base; if (damage.delta) @@ -94,7 +97,8 @@ int Being::damage(Object *, Damage const &damage) void Being::died() { - if (mAction == DEAD) return; + if (mAction == DEAD) + return; LOG_DEBUG("Being " << getPublicID() << " died."); setAction(DEAD); @@ -110,9 +114,92 @@ void Being::died() } } +void Being::setDestination(const Point &dst) +{ + mDst = dst; + raiseUpdateFlags(UPDATEFLAG_NEW_DESTINATION); + mPath.clear(); +} + void Being::move() { - MovingObject::move(); + mOld = getPosition(); + + if (mActionTime > 100) + { + // Current move has not yet ended + mActionTime -= 100; + return; + } + + int tileSX = mOld.x / 32, tileSY = mOld.y / 32; + int tileDX = mDst.x / 32, tileDY = mDst.y / 32; + if (tileSX == tileDX && tileSY == tileDY) + { + // Moving while staying on the same tile is free + setPosition(mDst); + mActionTime = 0; + return; + } + + Map *map = getMap()->getMap(); + + /* If no path exists, the for-loop won't be entered. Else a path for the + * current destination has already been calculated. + * The tiles in this path have to be checked for walkability, + * in case there have been changes. The 'getWalk' method of the Map + * class has been used, because that seems to be the most logical + * place extra functionality will be added. + */ + for (std::list<PATH_NODE>::iterator pathIterator = mPath.begin(); + pathIterator != mPath.end(); pathIterator++) + { + if (!map->getWalk(pathIterator->x, pathIterator->y, getWalkMask())) + { + mPath.clear(); + break; + } + } + + if (mPath.empty()) + { + // No path exists: the walkability of cached path has changed, the + // destination has changed, or a path was never set. + mPath = map->findPath(tileSX, tileSY, tileDX, tileDY, getWalkMask()); + } + + if (mPath.empty()) + { + // no path was found + mDst = mOld; + mActionTime = 0; + return; + } + + PATH_NODE prev(tileSX, tileSY); + Point pos; + do + { + PATH_NODE next = mPath.front(); + mPath.pop_front(); + // 362 / 256 is square root of 2, used for walking diagonally + mActionTime += (prev.x != next.x && prev.y != next.y) + ? mSpeed * 362 / 256 : mSpeed; + if (mPath.empty()) + { + // skip last tile center + pos = mDst; + break; + } + // position the actor in the middle of the tile for pathfinding purposes + pos.x = next.x * 32 + 16; + pos.y = next.y * 32 + 16; + } + while (mActionTime < 100); + setPosition(pos); + + mActionTime = mActionTime > 100 ? mActionTime - 100 : 0; + if (mAction == WALK || mAction == STAND) { mAction = (mActionTime) ? WALK : STAND; @@ -179,51 +266,50 @@ void Being::performAttack(Damage const &damage, AttackZone const *attackZone) Effects::show(26, getMap(), Point(attPos.x + attSize.x / 2, attPos.y + attSize.y / 2)); } - for (MovingObjectIterator - i(getMap()->getAroundObjectIterator(this, attackZone->range)); i; ++i) + for (BeingIterator + i(getMap()->getAroundActorIterator(this, attackZone->range)); i; ++i) { - MovingObject *o = *i; - Point opos = o->getPosition(); + Being *b = *i; - if (o == this) continue; + if (b == this) + continue; - int type = o->getType(); - if (type != OBJECT_CHARACTER && type != OBJECT_MONSTER) continue; + const ThingType type = b->getType(); + if (type != OBJECT_CHARACTER && type != OBJECT_MONSTER) + continue; if (getMap()->getPvP() == PVP_NONE && type == OBJECT_CHARACTER && getType() == OBJECT_CHARACTER) continue; - LOG_DEBUG("Attack Zone:"<< - attPos.x<<":"<<attPos.y<< - " "<< - attSize.x<<"x"<<attSize.y); - LOG_DEBUG("Defender Zone:"<< - defPos.x<<":"<<defPos.y<< - " "<< - defSize.x<<"x"<<defSize.y); + LOG_DEBUG("Attack Zone:" << attPos.x << ":" << attPos.y << + " " << attSize.x << "x" << attSize.y); + LOG_DEBUG("Defender Zone:" << defPos.x << ":" << defPos.y << + " " << defSize.x << "x" << defSize.y); + + const Point &opos = b->getPosition(); switch (attackZone->shape) { case ATTZONESHAPE_CONE: if (Collision::diskWithCircleSector( - opos, o->getSize(), + opos, b->getSize(), ppos, attackZone->range, attackZone->angle / 2, attackAngle) ) { - victims.push_back(static_cast< Being * >(o)); + victims.push_back(b); } break; case ATTZONESHAPE_RECT: - defPos.x = opos.x - o->getSize(); - defPos.y = opos.y - o->getSize(); - defSize.x = o->getSize() * 2; - defSize.y = o->getSize() * 2; + defPos.x = opos.x - b->getSize(); + defPos.y = opos.y - b->getSize(); + defSize.x = b->getSize() * 2; + defSize.y = b->getSize() * 2; if (Collision::rectWithRect(attPos, attSize, defPos, defSize)) { - victims.push_back(static_cast< Being * >(o)); + victims.push_back(b); } break; default: @@ -319,18 +405,18 @@ void Being::update() int newHP = oldHP; int maxHP = getAttribute(BASE_ATTR_HP); - // regenerate HP + // Regenerate HP if (mAction != DEAD && ++mHpRegenTimer >= TICKS_PER_HP_REGENERATION) { mHpRegenTimer = 0; newHP += getModifiedAttribute(BASE_ATTR_HP_REGEN); } - //cap HP at maximum + // Cap HP at maximum if (newHP > maxHP) { newHP = maxHP; } - //only update HP when it actually changed to avoid network noise + // Only update HP when it actually changed to avoid network noise if (newHP != oldHP) { applyModifier(BASE_ATTR_HP, newHP - oldHP); @@ -352,7 +438,7 @@ void Being::update() ++i; } - //check if being died + // Check if being died if (getModifiedAttribute(BASE_ATTR_HP) <= 0 && mAction != DEAD) { died(); diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp index 9d088de8..500754e4 100644 --- a/src/game-server/being.hpp +++ b/src/game-server/being.hpp @@ -27,7 +27,7 @@ #include "limits.h" #include "defines.h" -#include "game-server/movingobject.hpp" +#include "game-server/actor.hpp" class Being; class MapComposite; @@ -102,10 +102,10 @@ typedef std::vector< AttributeModifier > AttributeModifiers; typedef std::vector<unsigned int> Hits; /** - * Generic Being (living object). - * Used for characters & monsters (all animated objects). + * Generic being (living actor). Keeps direction, destination and a few other + * relevant properties. Used for characters & monsters (all animated objects). */ -class Being : public MovingObject +class Being : public Actor { public: @@ -126,7 +126,7 @@ class Being : public MovingObject /** * Proxy constructor. */ - Being(int type, int id); + Being(ThingType type); /** * Cleans obsolete attribute modifiers. @@ -138,7 +138,7 @@ class Being : public MovingObject * stats, deducts the result from the hitpoints and adds the result to * the HitsTaken list. */ - virtual int damage(Object *source, Damage const &damage); + virtual int damage(Actor *source, Damage const &damage); /** * Changes status and calls all the "died" listeners. @@ -146,6 +146,51 @@ class Being : public MovingObject virtual void died(); /** + * Performs actions scheduled by the being. + */ + virtual void perform() {} + + /** + * Gets the destination coordinates of the being. + */ + Point const &getDestination() const + { return mDst; } + + /** + * Sets the destination coordinates of the being. + */ + void setDestination(const Point &dst); + + /** + * Sets the destination coordinates of the being to the current + * position. + */ + void clearDestination() + { setDestination(getPosition()); } + + /** + * Gets the old coordinates of the being. + */ + const Point &getOldPosition() const + { return mOld; } + + /** + * Sets the facing direction of the being. + */ + void setDirection(int direction) + { mDirection = direction; raiseUpdateFlags(UPDATEFLAG_DIRCHANGE); } + + int getDirection() const + { return mDirection; } + + /** + * Gets beings speed. + * @todo Document what kind of units actor speed is in! + */ + int getSpeed() const { return mSpeed; } + void setSpeed(int s) { mSpeed = s; } + + /** * Gets the damage list. */ Hits const &getHitsTaken() const @@ -221,7 +266,7 @@ class Being : public MovingObject virtual void modifiedAttribute(int) {} /** Gets the name of the being. */ - std::string const &getName() const + const std::string &getName() const { return mName; } /** Sets the name of the being. */ @@ -242,6 +287,12 @@ class Being : public MovingObject Being(Being const &rhs); Being &operator=(Being const &rhs); + std::list<PATH_NODE> mPath; + Point mOld; /**< Old coordinates. */ + Point mDst; /**< Target coordinates. */ + unsigned short mSpeed; /**< Speed. */ + unsigned char mDirection; /**< Facing direction. */ + std::string mName; Hits mHitsTaken; /**< List of punches taken since last update. */ AttributeModifiers mModifiers; /**< Currently modified attributes. */ diff --git a/src/game-server/buysell.cpp b/src/game-server/buysell.cpp index defc3506..a6b036d6 100644 --- a/src/game-server/buysell.cpp +++ b/src/game-server/buysell.cpp @@ -50,15 +50,17 @@ void BuySell::registerItem(int id, int amount, int cost) if (mSell) { int nb = Inventory(mChar).count(id); - if (nb == 0) return; - if (!amount || nb < amount) amount = nb; + if (nb == 0) + return; + if (!amount || nb < amount) + amount = nb; } TradedItem it = { id, amount, cost }; mItems.push_back(it); } -void BuySell::start(MovingObject *obj) +void BuySell::start(Actor *actor) { if (mItems.empty()) { @@ -67,7 +69,7 @@ void BuySell::start(MovingObject *obj) } MessageOut msg(mSell ? GPMSG_NPC_SELL : GPMSG_NPC_BUY); - msg.writeShort(obj->getPublicID()); + msg.writeShort(actor->getPublicID()); for (TradedItems::const_iterator i = mItems.begin(), i_end = mItems.end(); i != i_end; ++i) { diff --git a/src/game-server/buysell.hpp b/src/game-server/buysell.hpp index e4c1fb6f..b178b38d 100644 --- a/src/game-server/buysell.hpp +++ b/src/game-server/buysell.hpp @@ -25,7 +25,7 @@ #include <vector> class Character; -class MovingObject; +class Actor; class BuySell { @@ -50,7 +50,7 @@ class BuySell /** * Sends the item list to player. */ - void start(MovingObject *obj); + void start(Actor *actor); /** * Performs the trade. diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index b60cf4e1..1d32914f 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -53,7 +53,7 @@ const float Character::LEVEL_SKILL_PRECEDENCE_FACTOR = 0.75f; const AttackZone Character::UNARMED_ATTACK_ZONE = {ATTZONESHAPE_RECT, true, 48, 16}; Character::Character(MessageIn &msg): - Being(OBJECT_CHARACTER, 65535), + Being(OBJECT_CHARACTER), mClient(NULL), mTransactionHandler(NULL), mDatabaseID(-1), mGender(0), mHairStyle(0), mHairColor(0), mLevel(1), mLevelProgress(0), mUpdateLevelProgress(false), mRecalculateLevel(true), mParty(0), diff --git a/src/game-server/character.hpp b/src/game-server/character.hpp index 8e2cc954..33be114e 100644 --- a/src/game-server/character.hpp +++ b/src/game-server/character.hpp @@ -303,7 +303,7 @@ class Character : public Being { return mCorrectionPoints; } /** - * Gets the way the object is blocked by other things on the map + * Gets the way the actor is blocked by other things on the map */ virtual unsigned char getWalkMask() const { return 0x82; } // blocked by walls and monsters ( bin 1000 0010) @@ -379,7 +379,7 @@ class Character : public Being protected: /** - * Gets the way the object blocks pathfinding for other objects + * Gets the way the actor blocks pathfinding for other objects */ virtual Map::BlockType getBlockType() const { return Map::BLOCKTYPE_CHARACTER; } diff --git a/src/game-server/effect.hpp b/src/game-server/effect.hpp index 0a1da335..49a12596 100644 --- a/src/game-server/effect.hpp +++ b/src/game-server/effect.hpp @@ -22,13 +22,15 @@ #ifndef _TMWSERV_EFFECT_H #define _TMWSERV_EFFECT_H -#include "game-server/object.hpp" +#include "game-server/actor.hpp" -class Effect : public Object +class Effect : public Actor { public: Effect(int id) - : Object(OBJECT_EFFECT), mEffectId(id), mHasBeenShown(false) + : Actor(OBJECT_EFFECT) + , mEffectId(id) + , mHasBeenShown(false) {} int getEffectId() const diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index e1301712..2ce443c1 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -132,36 +132,37 @@ void GameHandler::updateCharacter(int charid, int partyid) } } -static MovingObject *findBeingNear(Object *p, int id) +static Actor *findActorNear(Actor *p, int id) { MapComposite *map = p->getMap(); Point const &ppos = p->getPosition(); // See map.hpp for tiles constants - for (MovingObjectIterator i(map->getAroundPointIterator(ppos, - DEFAULT_TILE_WIDTH * TILES_TO_BE_NEAR)); i; ++i) + const int pixelDist = DEFAULT_TILE_WIDTH * TILES_TO_BE_NEAR; + for (ActorIterator i(map->getAroundPointIterator(ppos, pixelDist)); i; ++i) { - MovingObject *o = *i; - if (o->getPublicID() != id) continue; - return ppos.inRangeOf(o->getPosition(), DEFAULT_TILE_WIDTH * - TILES_TO_BE_NEAR) ? o : NULL; + Actor *a = *i; + if (a->getPublicID() != id) + continue; + return ppos.inRangeOf(a->getPosition(), pixelDist) ? a : 0; } - return NULL; + return 0; } -static Character *findCharacterNear(Object *p, int id) +static Character *findCharacterNear(Actor *p, int id) { MapComposite *map = p->getMap(); Point const &ppos = p->getPosition(); // See map.hpp for tiles constants + const int pixelDist = DEFAULT_TILE_WIDTH * TILES_TO_BE_NEAR; for (CharacterIterator i(map->getAroundPointIterator(ppos, - DEFAULT_TILE_WIDTH * TILES_TO_BE_NEAR)); i; ++i) + pixelDist)); i; ++i) { - Character *o = *i; - if (o->getPublicID() != id) continue; - return ppos.inRangeOf(o->getPosition(), DEFAULT_TILE_WIDTH * - TILES_TO_BE_NEAR) ? o : NULL; + Character *c = *i; + if (c->getPublicID() != id) + continue; + return ppos.inRangeOf(c->getPosition(), pixelDist) ? c : 0; } - return NULL; + return 0; } void GameHandler::processMessage(NetComputer *comp, MessageIn &message) @@ -171,7 +172,8 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) if (computer.status == CLIENT_LOGIN) { - if (message.getId() != PGMSG_CONNECT) return; + if (message.getId() != PGMSG_CONNECT) + return; std::string magic_token = message.readString(MAGIC_TOKEN_LENGTH); computer.status = CLIENT_QUEUED; // Before the addPendingClient @@ -205,7 +207,7 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) case PGMSG_NPC_SELECT: { int id = message.readShort(); - MovingObject *o = findBeingNear(computer.character, id); + Actor *o = findActorNear(computer.character, id); if (!o || o->getType() != OBJECT_NPC) { sendError(comp, id, "Not close enough to NPC\n"); @@ -234,9 +236,9 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) { MapComposite *map = computer.character->getMap(); Point ipos(x, y); - for (FixedObjectIterator i(map->getAroundPointIterator(ipos, 0)); i; ++i) + for (FixedActorIterator i(map->getAroundPointIterator(ipos, 0)); i; ++i) { - Object *o = *i; + Actor *o = *i; Point opos = o->getPosition(); if (o->getType() == OBJECT_ITEM && opos.x == x && opos.y == y) { diff --git a/src/game-server/item.hpp b/src/game-server/item.hpp index 7acb1a7c..4da82cf7 100644 --- a/src/game-server/item.hpp +++ b/src/game-server/item.hpp @@ -24,7 +24,7 @@ #include <vector> -#include "game-server/object.hpp" +#include "game-server/actor.hpp" class AttackZone; class Being; @@ -292,11 +292,11 @@ class ItemClass AttackZone *mAttackZone; /**< Attack zone when used as a weapon */ }; -class Item : public Object +class Item : public Actor { public: Item(ItemClass *type, int amount) - : Object(OBJECT_ITEM), mType(type), mAmount(amount) + : Actor(OBJECT_ITEM), mType(type), mAmount(amount) {} ItemClass *getItemClass() const diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index 4994b901..d77f73ba 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -32,19 +32,19 @@ /* TODO: Implement overlapping map zones instead of strict partitioning. Purpose: to decrease the number of zone changes, as overlapping allows for - hysteresis effect and prevents an object from changing zone each server - tick. It requires storing the zone in the object since it will not be + hysteresis effect and prevents an actor from changing zone each server + tick. It requires storing the zone in the actor since it will not be 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. + Squares should be big enough so that an actor 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. */ static int const zoneDiam = 256; -void MapZone::insert(Object *obj) +void MapZone::insert(Actor *obj) { int type = obj->getType(); switch (type) @@ -88,9 +88,9 @@ void MapZone::insert(Object *obj) } } -void MapZone::remove(Object *obj) +void MapZone::remove(Actor *obj) { - std::vector< Object * >::iterator i_beg = objects.begin(), i, i_end; + std::vector< Actor * >::iterator i_beg = objects.begin(), i, i_end; int type = obj->getType(); switch (type) { @@ -188,17 +188,17 @@ void CharacterIterator::operator++() } } -MovingObjectIterator::MovingObjectIterator(ZoneIterator const &it) +BeingIterator::BeingIterator(ZoneIterator const &it) : iterator(it), pos(0) { while (iterator && (*iterator)->nbMovingObjects == 0) ++iterator; if (iterator) { - current = static_cast< MovingObject * >((*iterator)->objects[pos]); + current = static_cast< Being * >((*iterator)->objects[pos]); } } -void MovingObjectIterator::operator++() +void BeingIterator::operator++() { if (++pos == (*iterator)->nbMovingObjects) { @@ -207,11 +207,11 @@ void MovingObjectIterator::operator++() } if (iterator) { - current = static_cast< MovingObject * >((*iterator)->objects[pos]); + current = static_cast< Being * >((*iterator)->objects[pos]); } } -FixedObjectIterator::FixedObjectIterator(ZoneIterator const &it) +FixedActorIterator::FixedActorIterator(ZoneIterator const &it) : iterator(it), pos(0) { while (iterator && (*iterator)->nbMovingObjects == (*iterator)->objects.size()) ++iterator; @@ -222,7 +222,7 @@ FixedObjectIterator::FixedObjectIterator(ZoneIterator const &it) } } -void FixedObjectIterator::operator++() +void FixedActorIterator::operator++() { if (++pos == (*iterator)->objects.size()) { @@ -238,7 +238,7 @@ void FixedObjectIterator::operator++() } } -ObjectIterator::ObjectIterator(ZoneIterator const &it) +ActorIterator::ActorIterator(ZoneIterator const &it) : iterator(it), pos(0) { while (iterator && (*iterator)->objects.empty()) ++iterator; @@ -248,7 +248,7 @@ ObjectIterator::ObjectIterator(ZoneIterator const &it) } } -void ObjectIterator::operator++() +void ActorIterator::operator++() { if (++pos == (*iterator)->objects.size()) { @@ -348,7 +348,7 @@ MapContent::~MapContent() delete[] zones; } -bool MapContent::allocate(MovingObject *obj) +bool MapContent::allocate(Actor *obj) { // First, try allocating from the last used bucket. ObjectBucket *b = buckets[last_bucket]; @@ -389,7 +389,7 @@ bool MapContent::allocate(MovingObject *obj) return false; } -void MapContent::deallocate(MovingObject *obj) +void MapContent::deallocate(Actor *obj) { unsigned short id = obj->getPublicID(); buckets[id / 256]->deallocate(id % 256); @@ -449,7 +449,7 @@ ZoneIterator MapComposite::getAroundPointIterator(Point const &p, int radius) co return ZoneIterator(r, mContent); } -ZoneIterator MapComposite::getAroundObjectIterator(Object *obj, int radius) const +ZoneIterator MapComposite::getAroundActorIterator(Actor *obj, int radius) const { MapRegion r; mContent->fillRegion(r, obj->getPosition(), radius); @@ -463,7 +463,7 @@ ZoneIterator MapComposite::getInsideRectangleIterator(Rectangle const &p) const return ZoneIterator(r, mContent); } -ZoneIterator MapComposite::getAroundCharacterIterator(MovingObject *obj, int radius) const +ZoneIterator MapComposite::getAroundBeingIterator(Being *obj, int radius) const { MapRegion r1; mContent->fillRegion(r1, obj->getOldPosition(), radius); @@ -492,12 +492,12 @@ bool MapComposite::insert(Thing *ptr) { if (ptr->isVisible()) { - if (ptr->canMove() && !mContent->allocate(static_cast< MovingObject * >(ptr))) + if (ptr->canMove() && !mContent->allocate(static_cast< Being * >(ptr))) { return false; } - Object *obj = static_cast< Object * >(ptr); + Actor *obj = static_cast< Actor * >(ptr); mContent->getZone(obj->getPosition()).insert(obj); } @@ -510,7 +510,7 @@ void MapComposite::remove(Thing *ptr) { if (ptr->isVisible()) { - Object *obj = static_cast< Object * >(ptr); + Actor *obj = static_cast< Actor * >(ptr); mContent->getZone(obj->getPosition()).remove(obj); if (ptr->canMove()) @@ -518,7 +518,7 @@ void MapComposite::remove(Thing *ptr) std::stringstream str; str << "Deallocating " << ptr->getType(); LOG_INFO(str.str()); - mContent->deallocate(static_cast< MovingObject * >(ptr)); + mContent->deallocate(static_cast< Being * >(ptr)); } } @@ -542,7 +542,8 @@ void MapComposite::setMap(Map *m) mContent = new MapContent(m); std::string sPvP = m->getProperty ("pvp"); - if (sPvP == "") sPvP = Configuration::getValue("defaultPvp", ""); + if (sPvP == "") + sPvP = Configuration::getValue("defaultPvp", ""); if (sPvP == "free") mPvPRules = PVP_FREE; else if (sPvP == "none") mPvPRules = PVP_NONE; @@ -562,12 +563,11 @@ void MapComposite::update() i_end = mContent->things.end(); i != i_end; ++i) { if (!(*i)->canMove()) - { continue; - } - MovingObject *obj = static_cast< MovingObject * >(*i); - Point const &pos1 = obj->getOldPosition(), + Being *obj = static_cast< Being * >(*i); + + const Point &pos1 = obj->getOldPosition(), &pos2 = obj->getPosition(); MapZone &src = mContent->getZone(pos1), diff --git a/src/game-server/mapcomposite.hpp b/src/game-server/mapcomposite.hpp index 7242fad6..ccec1db1 100644 --- a/src/game-server/mapcomposite.hpp +++ b/src/game-server/mapcomposite.hpp @@ -25,11 +25,11 @@ #include <string> #include <vector> +class Actor; +class Being; +class Character; class Map; class MapComposite; -class MovingObject; -class Object; -class Character; class Point; class Rectangle; class Script; @@ -44,6 +44,7 @@ enum PvPRules PVP_FREE // unrestricted PvP on this map // [space for additional PvP modes] }; + /** * Ordered sets of zones of a map. */ @@ -81,47 +82,47 @@ struct CharacterIterator }; /** - * Iterates through the MovingObjects of a region. + * Iterates through the Beings of a region. */ -struct MovingObjectIterator +struct BeingIterator { ZoneIterator iterator; unsigned short pos; - MovingObject *current; + Being *current; - MovingObjectIterator(ZoneIterator const &); + BeingIterator(ZoneIterator const &); void operator++(); - MovingObject *operator*() const { return current; } + Being *operator*() const { return current; } operator bool() const { return iterator; } }; /** - * Iterates through the non-moving Objects of a region. + * Iterates through the non-moving Actors of a region. */ -struct FixedObjectIterator +struct FixedActorIterator { ZoneIterator iterator; unsigned short pos; - Object *current; + Actor *current; - FixedObjectIterator(ZoneIterator const &); + FixedActorIterator(ZoneIterator const &); void operator++(); - Object *operator*() const { return current; } + Actor *operator*() const { return current; } operator bool() const { return iterator; } }; /** - * Iterates through the Objects of a region. + * Iterates through the Actors of a region. */ -struct ObjectIterator +struct ActorIterator { ZoneIterator iterator; unsigned short pos; - Object *current; + Actor *current; - ObjectIterator(ZoneIterator const &); + ActorIterator(ZoneIterator const &); void operator++(); - Object *operator*() const { return current; } + Actor *operator*() const { return current; } operator bool() const { return iterator; } }; @@ -136,7 +137,7 @@ struct MapZone * Characters are stored first, then the remaining MovingObjects, then the * remaining Objects. */ - std::vector< Object * > objects; + std::vector< Actor * > objects; /** * Destinations of the objects that left this zone. @@ -146,8 +147,8 @@ struct MapZone MapRegion destinations; MapZone(): nbCharacters(0), nbMovingObjects(0) {} - void insert(Object *); - void remove(Object *); + void insert(Actor *); + void remove(Actor *); }; /** @@ -161,7 +162,7 @@ struct ObjectBucket unsigned bitmap[256 / int_bitsize]; /**< Bitmap of free locations. */ short free; /**< Number of empty places. */ short next_object; /**< Next object to look at. */ - MovingObject *objects[256]; + Actor *objects[256]; ObjectBucket(); int allocate(); @@ -177,14 +178,14 @@ struct MapContent ~MapContent(); /** - * Allocates a unique ID for a moving object on this map. + * Allocates a unique ID for an actor on this map. */ - bool allocate(MovingObject *); + bool allocate(Actor *); /** * Deallocates an ID. */ - void deallocate(MovingObject *); + void deallocate(Actor *); /** * Fills a region of zones within the range of a point. @@ -281,12 +282,12 @@ class MapComposite { return mName; } /** - * Inserts an object on the map. Sets its public ID if relevant. + * Inserts a thing on the map. Sets its public ID if relevant. */ bool insert(Thing *); /** - * Removes an object from the map. + * Removes a thing from the map. */ void remove(Thing *); @@ -296,7 +297,7 @@ class MapComposite void update(); /** - * Gets the PvP rules on the map + * Gets the PvP rules on the map. */ PvPRules getPvP() const { return mPvPRules; } @@ -317,15 +318,15 @@ class MapComposite ZoneIterator getAroundPointIterator(Point const &, int radius) const; /** - * Gets an iterator on the objects around a given object. + * Gets an iterator on the objects around a given actor. */ - ZoneIterator getAroundObjectIterator(Object *, int radius) const; + ZoneIterator getAroundActorIterator(Actor *, int radius) const; /** * Gets an iterator on the objects around the old and new positions of * a character (including the ones that were but are now elsewhere). */ - ZoneIterator getAroundCharacterIterator(MovingObject *, int radius) const; + ZoneIterator getAroundBeingIterator(Being *, int radius) const; /** * Gets everything related to the map. diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index 70e7ab1f..a5a5f2ec 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -58,7 +58,7 @@ struct MonsterTargetEventDispatch: EventDispatch static MonsterTargetEventDispatch monsterTargetEventDispatch; Monster::Monster(MonsterClass *specy): - Being(OBJECT_MONSTER, 65535), + Being(OBJECT_MONSTER), mSpecy(specy), mCountDown(0), mTargetListener(&monsterTargetEventDispatch), @@ -168,7 +168,7 @@ void Monster::update() // Iterate through objects nearby int aroundArea = Configuration::getValue("visualRange", 320); - for (MovingObjectIterator i(getMap()->getAroundCharacterIterator(this, aroundArea)); i; ++i) + for (BeingIterator i(getMap()->getAroundBeingIterator(this, aroundArea)); i; ++i) { // We only want to attack player characters if ((*i)->getType() != OBJECT_CHARACTER) continue; @@ -319,7 +319,7 @@ void Monster::forgetTarget(Thing *t) } } -int Monster::damage(Object *source, Damage const &damage) +int Monster::damage(Actor *source, Damage const &damage) { int HPLoss = Being::damage(source, damage); if (HPLoss && source && source->getType() == OBJECT_CHARACTER) diff --git a/src/game-server/monster.hpp b/src/game-server/monster.hpp index ab60fe0e..b7c5947f 100644 --- a/src/game-server/monster.hpp +++ b/src/game-server/monster.hpp @@ -249,7 +249,7 @@ class Monster : public Being /** * Calls the damage function in Being and updates the aggro list */ - virtual int damage(Object *source, Damage const &damage); + virtual int damage(Actor *source, Damage const &damage); /** * Removes a being from the anger list. @@ -257,7 +257,7 @@ class Monster : public Being void forgetTarget(Thing *being); /** - * Returns the way the object is blocked by other things on the map + * Returns the way the actor is blocked by other things on the map. */ virtual unsigned char getWalkMask() const { @@ -267,7 +267,7 @@ class Monster : public Being protected: /** - * Returns the way the object blocks pathfinding for other objects + * Returns the way the actor blocks pathfinding for other objects. */ virtual Map::BlockType getBlockType() const { return Map::BLOCKTYPE_MONSTER; } diff --git a/src/game-server/movingobject.cpp b/src/game-server/movingobject.cpp deleted file mode 100644 index 281513ff..00000000 --- a/src/game-server/movingobject.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <cassert> - -#include "game-server/map.hpp" -#include "game-server/mapcomposite.hpp" -#include "game-server/movingobject.hpp" - - -void MovingObject::setPosition(const Point &p) -{ - //update blockmap - if (getMap()) - { - Point oldP = getPosition(); - if ((oldP.x / 32 != p.x / 32 || oldP.y / 32 != p.y / 32)) - { - getMap()->getMap()->freeTile(oldP.x / 32, oldP.y / 32, getBlockType()); - getMap()->getMap()->blockTile(p.x / 32, p.y / 32, getBlockType()); - } - } - - Object::setPosition(p); -} - -void MovingObject::setMap(MapComposite *map) -{ - assert (map); - MapComposite *oldMap = getMap(); - Point p = getPosition(); - - if (oldMap) - { - oldMap->getMap()->freeTile(p.x / 32, p.y / 32, getBlockType()); - } - Object::setMap(map); - map->getMap()->blockTile(p.x / 32, p.y / 32, getBlockType()); - /* the last line might look illogical because the current position is - * invalid on the new map, but it is necessary to block the old position - * because the next call of setPosition() will automatically free the old - * position. When we don't block the position now the occupation counting - * will be off. - */ -} - -void MovingObject::setDestination(Point const &dst) -{ - mDst = dst; - raiseUpdateFlags(UPDATEFLAG_NEW_DESTINATION); - mPath.clear(); -} - -void MovingObject::move() -{ - mOld = getPosition(); - - if (mActionTime > 100) - { - // Current move has not yet ended - mActionTime -= 100; - return; - } - - int tileSX = mOld.x / 32, tileSY = mOld.y / 32; - int tileDX = mDst.x / 32, tileDY = mDst.y / 32; - if (tileSX == tileDX && tileSY == tileDY) - { - // Moving while staying on the same tile is free - setPosition(mDst); - mActionTime = 0; - return; - } - - Map *map = getMap()->getMap(); - - /* If no path exists, the for-loop won't be entered. Else a path for the - * current destination has already been calculated. - * The tiles in this path have to be checked for walkability, - * in case there have been changes. The 'getWalk' method of the Map - * class has been used, because that seems to be the most logical - * place extra functionality will be added. - */ - for (std::list<PATH_NODE>::iterator pathIterator = mPath.begin(); - pathIterator != mPath.end(); pathIterator++) - { - if (!map->getWalk(pathIterator->x, pathIterator->y, getWalkMask())) - { - mPath.clear(); - break; - } - } - - if (mPath.empty()) - { - // No path exists: the walkability of cached path has changed, the - // destination has changed, or a path was never set. - mPath = map->findPath(tileSX, tileSY, tileDX, tileDY, getWalkMask()); - } - - if (mPath.empty()) - { - // no path was found - mDst = mOld; - mActionTime = 0; - return; - } - - PATH_NODE prev(tileSX, tileSY); - Point pos; - do - { - PATH_NODE next = mPath.front(); - mPath.pop_front(); - // 362 / 256 is square root of 2, used for walking diagonally - mActionTime += (prev.x != next.x && prev.y != next.y) - ? mSpeed * 362 / 256 : mSpeed; - if (mPath.empty()) - { - // skip last tile center - pos = mDst; - break; - } - // position the object in the middle of the tile for pathfinding purposes - pos.x = next.x * 32 + 16; - pos.y = next.y * 32 + 16; - } - while (mActionTime < 100); - setPosition(pos); - - mActionTime = mActionTime > 100 ? mActionTime - 100 : 0; -} diff --git a/src/game-server/movingobject.hpp b/src/game-server/movingobject.hpp deleted file mode 100644 index 7e34e5fd..00000000 --- a/src/game-server/movingobject.hpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _TMWSERV_MOVINGOBJECT_H_ -#define _TMWSERV_MOVINGOBJECT_H_ - -#include "point.h" -#include "game-server/map.hpp" -#include "game-server/object.hpp" - - -/** - * Base class for in-game moving objects. This class adds a sense of direction, - * destination and size. - */ -class MovingObject : public Object -{ - public: - /** - * Proxy constructor. - */ - MovingObject(int type, int id) - : Object(type), - mPublicID(id), - mActionTime(0), - mDirection(0) - {} - - virtual ~MovingObject() {}; - - /** - * Updates the walkmap of the map the object is on before - * calling Object::setPosition - */ - virtual void setPosition(const Point &p); - - /** - * Gets the destination coordinates of the object. - */ - Point const &getDestination() const - { return mDst; } - - /** - * Sets the destination coordinates of the object. - */ - void setDestination(const Point &dst); - - /** - * Sets the destination coordinates of the object to the current position. - */ - void clearDestination() - { setDestination(getPosition()); } - - /** - * Gets the old coordinates of the object. - */ - Point getOldPosition() const - { return mOld; } - - /** - * Sets object direction. - */ - void setDirection(int direction) - { mDirection = direction; raiseUpdateFlags(UPDATEFLAG_DIRCHANGE); } - - /** - * Gets object direction. - */ - int getDirection() const - { return mDirection; } - - /** - * Gets object speed. - */ - int getSpeed() const - { return mSpeed; } - - /** - * Sets object speed. - */ - void setSpeed(int s) - { mSpeed = s; } - - /** - * Sets object bounding circle radius. - */ - void setSize(int s) - { mSize = s; } - - /** - * Gets object bounding circle radius. - */ - int getSize() - { return mSize; } - - /** - * Performs actions scheduled by the object. - */ - virtual void perform() {} - - /** - * Moves the object toward its destination. - */ - virtual void move(); - - /** - * Get public ID. - * - * @return the public ID, 65535 if none yet. - */ - int getPublicID() const - { return mPublicID; } - - /** - * Set public ID. The object shall not have any public ID yet. - */ - void setPublicID(int id) - { mPublicID = id; } - - /** - * Gets the way the object blocks pathfinding for other objects - */ - virtual unsigned char getWalkMask() const - { return 0x00; } //can walk through everything - - /** - * Sets the map this thing is located on. - */ - virtual void setMap(MapComposite *map); - - private: - /** Object ID sent to clients (unique with respect to the map). */ - unsigned short mPublicID; - - Point mDst; /**< Target coordinates. */ - Point mOld; /**< Old coordinates. */ - unsigned short mSpeed; /**< Speed. */ - std::list<PATH_NODE> mPath; - - protected: - unsigned short mActionTime; /**< Delay until next action. */ - unsigned char mDirection; /**< Facing direction. */ - unsigned char mSize; /**< Radius of bounding circle. */ - - /** - * Gets the way the object blocks pathfinding for other objects - */ - virtual Map::BlockType getBlockType() const - { return Map::BLOCKTYPE_NONE; } -}; - -#endif // _TMWSERV_MOVINGOBJECT_H_ diff --git a/src/game-server/npc.cpp b/src/game-server/npc.cpp index 7e144192..e45692b6 100644 --- a/src/game-server/npc.cpp +++ b/src/game-server/npc.cpp @@ -23,7 +23,10 @@ #include "scripting/script.hpp" NPC::NPC(const std::string &name, int id, Script *s): - Being(OBJECT_NPC, 65535), mScript(s), mID(id), mEnabled(true) + Being(OBJECT_NPC), + mScript(s), + mID(id), + mEnabled(true) { setName(name); } diff --git a/src/game-server/object.hpp b/src/game-server/object.hpp deleted file mode 100644 index 687b6ed7..00000000 --- a/src/game-server/object.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _TMWSERV_OBJECT_H_ -#define _TMWSERV_OBJECT_H_ - -#include "point.h" -#include "game-server/thing.hpp" - -/** - * Flags that are raised as necessary. They trigger messages that are sent to - * the clients. - */ -enum -{ - UPDATEFLAG_NEW_ON_MAP = 1, - UPDATEFLAG_NEW_DESTINATION = 2, - UPDATEFLAG_ATTACK = 4, - UPDATEFLAG_ACTIONCHANGE = 8, - UPDATEFLAG_LOOKSCHANGE = 16, - UPDATEFLAG_DIRCHANGE = 32, - UPDATEFLAG_HEALTHCHANGE = 64 -}; - -/** - * Generic client-visible object definition. Keeps track of position and what - * to update clients about. - */ -class Object : public Thing -{ - public: - /** - * Constructor. - */ - Object(int type) - : Thing(type), - mUpdateFlags(0), - mPos(Point(0, 0)) - {} - - /** - * Sets the coordinates. - * - * @param p the coordinates. - */ - virtual void setPosition(const Point &p) - { mPos = p; } - - /** - * Gets the coordinates. - * - * @return the coordinates. - */ - Point const &getPosition() const - { return mPos; } - - /** - * Gets what changed in the object. - */ - int getUpdateFlags() const - { return mUpdateFlags; } - - /** - * Sets some changes in the object. - */ - void raiseUpdateFlags(int n) - { mUpdateFlags |= n; } - - /** - * Clears changes in the object. - */ - void clearUpdateFlags() - { mUpdateFlags = 0; } - - private: - char mUpdateFlags; /**< Changes in object status. */ - Point mPos; /**< Coordinates. */ -}; - -#endif // _TMWSERV_OBJECT_H_ diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index dc7c78f2..f0997174 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -58,7 +58,7 @@ struct DelayedEvent MapComposite *map; }; -typedef std::map< Object *, DelayedEvent > DelayedEvents; +typedef std::map< Actor *, DelayedEvent > DelayedEvents; /** * List of delayed events. @@ -85,13 +85,13 @@ static void updateMap(MapComposite *map) } // 3. perform actions. - for (MovingObjectIterator i(map->getWholeMapIterator()); i; ++i) + for (BeingIterator i(map->getWholeMapIterator()); i; ++i) { (*i)->perform(); } // 4. move objects around and update zones. - for (MovingObjectIterator i(map->getWholeMapIterator()); i; ++i) + for (BeingIterator i(map->getWholeMapIterator()); i; ++i) { (*i)->move(); } @@ -106,7 +106,12 @@ static void serializeLooks(Character *ch, MessageOut &msg, bool full) Possessions const &poss = ch->getPossessions(); static int const nb_slots = 4; static int const slots[nb_slots] = - { EQUIP_FIGHT1_SLOT, EQUIP_HEAD_SLOT, EQUIP_TORSO_SLOT, EQUIP_LEGS_SLOT }; + { + EQUIP_FIGHT1_SLOT, + EQUIP_HEAD_SLOT, + EQUIP_TORSO_SLOT, + EQUIP_LEGS_SLOT + }; // Bitmask describing the changed entries. int changed = (1 << nb_slots) - 1; @@ -161,16 +166,16 @@ static void informPlayer(MapComposite *map, Character *p) { MessageOut moveMsg(GPMSG_BEINGS_MOVE); MessageOut damageMsg(GPMSG_BEINGS_DAMAGE); - Point pold = p->getOldPosition(), ppos = p->getPosition(); + const Point &pold = p->getOldPosition(), ppos = p->getPosition(); int pid = p->getPublicID(), pflags = p->getUpdateFlags(); int visualRange = Configuration::getValue("visualRange", 320); // Inform client about activities of other beings near its character - for (MovingObjectIterator i(map->getAroundCharacterIterator(p, visualRange)); i; ++i) + for (BeingIterator i(map->getAroundBeingIterator(p, visualRange)); i; ++i) { - MovingObject *o = *i; + Being *o = *i; - Point oold = o->getOldPosition(), opos = o->getPosition(); + const Point &oold = o->getOldPosition(), opos = o->getPosition(); int otype = o->getType(); int oid = o->getPublicID(), oflags = o->getUpdateFlags(); int flags = 0; @@ -371,12 +376,12 @@ static void informPlayer(MapComposite *map, Character *p) // Inform client about items on the ground around its character MessageOut itemMsg(GPMSG_ITEMS); - for (FixedObjectIterator i(map->getAroundCharacterIterator(p, visualRange)); i; ++i) + for (FixedActorIterator i(map->getAroundBeingIterator(p, visualRange)); i; ++i) { assert((*i)->getType() == OBJECT_ITEM || (*i)->getType() == OBJECT_EFFECT); - Object *o = *i; + Actor *o = *i; Point opos = o->getPosition(); int oflags = o->getUpdateFlags(); bool willBeInRange = ppos.inRangeOf(opos, visualRange); @@ -468,13 +473,13 @@ void GameState::update(int worldTime) */ } - for (ObjectIterator i(map->getWholeMapIterator()); i; ++i) + for (ActorIterator i(map->getWholeMapIterator()); i; ++i) { - Object *o = *i; - o->clearUpdateFlags(); - if (o->canFight()) + Actor *a = *i; + a->clearUpdateFlags(); + if (a->canFight()) { - static_cast< Being * >(o)->clearHitsTaken(); + static_cast< Being * >(a)->clearHitsTaken(); } } } @@ -488,7 +493,7 @@ void GameState::update(int worldTime) i_end = delayedEvents.end(); i != i_end; ++i) { DelayedEvent const &e = i->second; - Object *o = i->first; + Actor *o = i->first; switch (e.type) { case EVENT_REMOVE: @@ -531,13 +536,13 @@ bool GameState::insert(Thing *ptr) } // Check that coordinates are actually valid. - Object *obj = static_cast< Object * >(ptr); + Actor *obj = static_cast< Actor * >(ptr); Map *mp = map->getMap(); Point pos = obj->getPosition(); if (pos.x / 32 >= (unsigned)mp->getWidth() || pos.y / 32 >= (unsigned)mp->getHeight()) { - LOG_ERROR("Tried to insert an object at position " << pos.x << ',' + LOG_ERROR("Tried to insert an actor at position " << pos.x << ',' << pos.y << " outside map " << map->getID() << '.'); // Set an arbitrary small position. pos = Point(100, 100); @@ -546,8 +551,8 @@ bool GameState::insert(Thing *ptr) if (!map->insert(obj)) { - // The map is overloaded. No room to add a new object. - LOG_ERROR("Too many objects on map " << map->getID() << '.'); + // The map is overloaded, no room to add a new actor + LOG_ERROR("Too many actors on map " << map->getID() << '.'); return false; } @@ -583,7 +588,8 @@ bool GameState::insert(Thing *ptr) } obj->raiseUpdateFlags(UPDATEFLAG_NEW_ON_MAP); - if (obj->getType() != OBJECT_CHARACTER) return true; + if (obj->getType() != OBJECT_CHARACTER) + return true; /* Since the player does not know yet where in the world its character is, we send a map-change message, even if it is the first time it @@ -656,12 +662,12 @@ void GameState::remove(Thing *ptr) static_cast< Character * >(ptr)->getDatabaseID(), false); } - MovingObject *obj = static_cast< MovingObject * >(ptr); + Actor *obj = static_cast< Actor * >(ptr); MessageOut msg(GPMSG_BEING_LEAVE); msg.writeShort(obj->getPublicID()); Point objectPos = obj->getPosition(); - for (CharacterIterator p(map->getAroundObjectIterator(obj, visualRange)); p; ++p) + for (CharacterIterator p(map->getAroundActorIterator(obj, visualRange)); p; ++p) { if (*p != obj && objectPos.inRangeOf((*p)->getPosition(), visualRange)) { @@ -678,7 +684,7 @@ void GameState::remove(Thing *ptr) msg.writeShort(pos.x); msg.writeShort(pos.y); - for (CharacterIterator p(map->getAroundObjectIterator(obj, visualRange)); p; ++p) + for (CharacterIterator p(map->getAroundActorIterator(obj, visualRange)); p; ++p) { if (pos.inRangeOf((*p)->getPosition(), visualRange)) { @@ -722,7 +728,7 @@ void GameState::warp(Character *ptr, MapComposite *map, int x, int y) /** * Enqueues an event. It will be executed at end of update. */ -static void enqueueEvent(Object *ptr, DelayedEvent const &e) +static void enqueueEvent(Actor *ptr, DelayedEvent const &e) { std::pair< DelayedEvents::iterator, bool > p = delayedEvents.insert(std::make_pair(ptr, e)); @@ -733,13 +739,13 @@ static void enqueueEvent(Object *ptr, DelayedEvent const &e) } } -void GameState::enqueueInsert(Object *ptr) +void GameState::enqueueInsert(Actor *ptr) { DelayedEvent e = { EVENT_INSERT, 0, 0, 0 }; enqueueEvent(ptr, e); } -void GameState::enqueueRemove(Object *ptr) +void GameState::enqueueRemove(Actor *ptr) { DelayedEvent e = { EVENT_REMOVE, 0, 0, 0 }; enqueueEvent(ptr, e); @@ -751,12 +757,12 @@ void GameState::enqueueWarp(Character *ptr, MapComposite *m, int x, int y) enqueueEvent(ptr, e); } -void GameState::sayAround(Object *obj, std::string const &text) +void GameState::sayAround(Actor *obj, std::string const &text) { Point speakerPosition = obj->getPosition(); int visualRange = Configuration::getValue("visualRange", 320); - for (CharacterIterator i(obj->getMap()->getAroundObjectIterator(obj, visualRange)); i; ++i) + for (CharacterIterator i(obj->getMap()->getAroundActorIterator(obj, visualRange)); i; ++i) { if (speakerPosition.inRangeOf((*i)->getPosition(), visualRange)) { @@ -765,9 +771,10 @@ void GameState::sayAround(Object *obj, std::string const &text) } } -void GameState::sayTo(Object *destination, Object *source, std::string const &text) +void GameState::sayTo(Actor *destination, Actor *source, std::string const &text) { - if (destination->getType() != OBJECT_CHARACTER) return; //only characters will read it anyway + if (destination->getType() != OBJECT_CHARACTER) + return; //only characters will read it anyway MessageOut msg(GPMSG_SAY); if (source == NULL) { @@ -775,7 +782,7 @@ void GameState::sayTo(Object *destination, Object *source, std::string const &te } else if (!source->canMove()) { msg.writeShort(65535); } else { - msg.writeShort(static_cast< MovingObject * >(source)->getPublicID()); + msg.writeShort(static_cast< Actor * >(source)->getPublicID()); } msg.writeString(text); diff --git a/src/game-server/state.hpp b/src/game-server/state.hpp index f5595bc8..e08073b7 100644 --- a/src/game-server/state.hpp +++ b/src/game-server/state.hpp @@ -26,7 +26,7 @@ class MapComposite; class Thing; -class Object; +class Actor; class Character; namespace GameState @@ -37,8 +37,8 @@ namespace GameState void update(int worldTime); /** - * Inserts an object in the game world. - * @return false if the insertion failed and the object is in limbo. + * Inserts an thing in the game world. + * @return false if the insertion failed and the thing is in limbo. * @note No update may be in progress. */ bool insert(Thing *) @@ -48,7 +48,7 @@ namespace GameState ; /** - * Inserts an object in the game world. Deletes the object if the insertion + * Inserts a thing in the game world. Deletes the thing if the insertion * failed. * @return false if the insertion failed. * @note No update may be in progress. Invalid for characters. @@ -56,9 +56,9 @@ namespace GameState bool insertSafe(Thing *); /** - * Removes an object from the game world. + * Removes a thing from the game world. * @note No update may be in progress. - * @note The object is not destroyed by this call. + * @note The thing is not destroyed by this call. */ void remove(Thing *); @@ -73,14 +73,14 @@ namespace GameState * Enqueues an insert event. * @note The event will be executed at end of update. */ - void enqueueInsert(Object *); + void enqueueInsert(Actor *); /** * Enqueues a remove event. * @note The event will be executed at end of update. - * @note The object will be destroyed at that time. + * @note The thing will be destroyed at that time. */ - void enqueueRemove(Object *); + void enqueueRemove(Actor *); /** * Enqueues a warp event. @@ -89,15 +89,15 @@ namespace GameState void enqueueWarp(Character *, MapComposite *, int x, int y); /** - * Says something to an object + * Says something to an actor. * @note passing NULL as source generates a message from "Server:" */ - void sayTo(Object *destination, Object *source, std::string const &text); + void sayTo(Actor *destination, Actor *source, std::string const &text); /** - * Says something to everything around an object. + * Says something to everything around an actor. */ - void sayAround(Object *, std::string const &text); + void sayAround(Actor *, std::string const &text); /** * Says something to every player on the server. diff --git a/src/game-server/thing.hpp b/src/game-server/thing.hpp index 83c9da2a..b87ea657 100644 --- a/src/game-server/thing.hpp +++ b/src/game-server/thing.hpp @@ -27,9 +27,9 @@ class EventListener; class MapComposite; /** - * Object type enumeration. + * Types of things enumeration. */ -enum +enum ThingType { OBJECT_ITEM = 0, /**< A simple item. */ OBJECT_ACTOR, /**< An item that toggle map/quest actions (doors, @@ -53,14 +53,11 @@ class Thing /** * Constructor. */ - Thing(int type, MapComposite *map = NULL) + Thing(ThingType type, MapComposite *map = NULL) : mMap(map), mType(type) {} - /** - * Destructor. - */ virtual ~Thing(); /** @@ -68,17 +65,17 @@ class Thing * * @return the type of this thing. */ - int getType() const + ThingType getType() const { return mType; } /** - * Returns whether this thing is visible on the map or not. (Object) + * Returns whether this thing is visible on the map or not. (Actor) */ bool isVisible() const { return mType != OBJECT_OTHER; } /** - * Returns whether this thing can move on the map or not. (MovingObject) + * Returns whether this thing can move on the map or not. (Actor) */ bool canMove() const { return mType == OBJECT_CHARACTER || mType == OBJECT_MONSTER || @@ -93,8 +90,7 @@ class Thing /** * Updates the internal status. */ - virtual void - update() = 0; + virtual void update() = 0; /** * Gets the map this thing is located on. @@ -130,11 +126,11 @@ class Thing protected: typedef std::set< EventListener const * > Listeners; - Listeners mListeners; /**< List of event listeners. */ + Listeners mListeners; /**< List of event listeners. */ private: MapComposite *mMap; /**< Map the thing is on */ - char mType; /**< Type of this thing. */ + ThingType mType; /**< Type of this thing. */ }; #endif // _TMWSERV_THING_H_ diff --git a/src/game-server/trigger.cpp b/src/game-server/trigger.cpp index 027754d5..a648df49 100644 --- a/src/game-server/trigger.cpp +++ b/src/game-server/trigger.cpp @@ -23,12 +23,12 @@ #include "game-server/character.hpp" #include "game-server/mapcomposite.hpp" -#include "game-server/movingobject.hpp" +#include "game-server/actor.hpp" #include "game-server/state.hpp" #include "utils/logger.h" -void WarpAction::process(Object *obj) +void WarpAction::process(Actor *obj) { if (obj->getType() == OBJECT_CHARACTER) { @@ -36,11 +36,12 @@ void WarpAction::process(Object *obj) } } -void ScriptAction::process(Object *obj) +void ScriptAction::process(Actor *obj) { - LOG_DEBUG("Script trigger area activated: "<<mFunction<<"("<<obj<<", "<<mArg<<")"); - if (!mScript) return; - if (mFunction == "") return; + LOG_DEBUG("Script trigger area activated: " << mFunction + << "(" << obj << ", " << mArg << ")"); + if (!mScript || mFunction.empty()) + return; mScript->prepare(mFunction); mScript->push(obj); mScript->push(mArg); @@ -49,8 +50,8 @@ void ScriptAction::process(Object *obj) void TriggerArea::update() { - std::set<Object*> insideNow; - for (MovingObjectIterator i(getMap()->getInsideRectangleIterator(mZone)); i; ++i) + std::set<Actor*> insideNow; + for (BeingIterator i(getMap()->getInsideRectangleIterator(mZone)); i; ++i) { if (mZone.contains((*i)->getPosition())) //<-- Why is this additional condition necessary? Shouldn't getInsideRectangleIterator already exclude those outside of the zone? --Crush { diff --git a/src/game-server/trigger.hpp b/src/game-server/trigger.hpp index b6fa049c..c134263a 100644 --- a/src/game-server/trigger.hpp +++ b/src/game-server/trigger.hpp @@ -26,13 +26,13 @@ #include "game-server/thing.hpp" #include "scripting/script.hpp" -class Object; +class Actor; class TriggerAction { public: virtual ~TriggerAction() {} - virtual void process(Object *obj) = 0; + virtual void process(Actor *obj) = 0; }; class WarpAction : public TriggerAction @@ -41,7 +41,7 @@ class WarpAction : public TriggerAction WarpAction(MapComposite *m, int x, int y) : mMap(m), mX(x), mY(y) {} - virtual void process(Object *obj); + virtual void process(Actor *obj); private: MapComposite *mMap; @@ -54,12 +54,12 @@ class ScriptAction : public TriggerAction ScriptAction(Script *script, std::string function, int arg) : mScript(script), mFunction(function), mArg(arg) {} - virtual void process(Object *obj); + virtual void process(Actor *obj); private: - Script *mScript; //Script object to be called - std::string mFunction; //Name of the function called in the script object - int mArg; //Argument passed to script function (meaning is function-specific) + Script *mScript; // Script object to be called + std::string mFunction; // Name of the function called in the script object + int mArg; // Argument passed to script function (meaning is function-specific) }; class TriggerArea : public Thing @@ -77,7 +77,7 @@ class TriggerArea : public Thing Rectangle mZone; TriggerAction *mAction; bool mOnce; - std::set<Object *> mInside; + std::set<Actor *> mInside; }; #endif diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 2b148ef0..9ddc68e0 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -641,8 +641,8 @@ static int chr_set_quest(lua_State *s) } /** - * Creates a trigger area. Whenever an object enters this area - * a Lua function is called. + * Creates a trigger area. Whenever an actor enters this area, a Lua function + * is called. * tmw.trigger_create (x, y, width, height, function, id) */ static int trigger_create(lua_State *s) @@ -740,7 +740,7 @@ static int get_beings_in_circle(lua_State *s) lua_newtable(s); int tableStackPosition = lua_gettop(s); int tableIndex = 1; - for (MovingObjectIterator i(m->getAroundPointIterator(Point(x, y), r)); i; ++i) + for (BeingIterator i(m->getAroundPointIterator(Point(x, y), r)); i; ++i) { char t = (*i)->getType(); if (t == OBJECT_NPC || t == OBJECT_CHARACTER || t == OBJECT_MONSTER) diff --git a/src/utils/functors.h b/src/utils/functors.h index 4c7bee55..fefbeb1a 100644 --- a/src/utils/functors.h +++ b/src/utils/functors.h @@ -36,7 +36,7 @@ namespace * * Note: * - this functor assumes that the object defines as public the following - * method: std::string getName(void). + * method: std::string getName() const. * - this functor assumes that the list is a list of pointers. */ template <typename T> |