diff options
author | Erik Schilling <ablu.erikschilling@googlemail.com> | 2013-04-11 11:10:47 +0200 |
---|---|---|
committer | Erik Schilling <ablu.erikschilling@googlemail.com> | 2013-04-12 14:56:28 +0200 |
commit | 9e6a0f98ecb52e04ab5afce817cb1d7fe2076450 (patch) | |
tree | 97b6ffedbfbaf09389fe05c1d183471a97740ebb /src | |
parent | d7fa7ea64f6bb0bc0b097e4bf1ceb4bd9620d0da (diff) | |
download | manaserv-9e6a0f98ecb52e04ab5afce817cb1d7fe2076450.tar.gz manaserv-9e6a0f98ecb52e04ab5afce817cb1d7fe2076450.tar.bz2 manaserv-9e6a0f98ecb52e04ab5afce817cb1d7fe2076450.tar.xz manaserv-9e6a0f98ecb52e04ab5afce817cb1d7fe2076450.zip |
Moved Actor into an Component
This was the final step to remove the hierachy with Entity on the top.
Diffstat (limited to 'src')
33 files changed, 429 insertions, 408 deletions
diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp index 622fc1d6..72f87763 100644 --- a/src/game-server/accountconnection.cpp +++ b/src/game-server/accountconnection.cpp @@ -155,7 +155,8 @@ void AccountConnection::processMessage(MessageIn &msg) case AGMSG_PLAYER_ENTER: { std::string token = msg.readString(MAGIC_TOKEN_LENGTH); - Entity *character = new Actor(OBJECT_CHARACTER); + Entity *character = new Entity(OBJECT_CHARACTER); + character->addComponent(new ActorComponent(*character)); character->addComponent(new BeingComponent(*character)); character->addComponent(new CharacterComponent(*character, msg)); gameHandler->addPendingCharacter(token, character); diff --git a/src/game-server/actor.cpp b/src/game-server/actor.cpp index 60379124..9c839172 100644 --- a/src/game-server/actor.cpp +++ b/src/game-server/actor.cpp @@ -25,10 +25,24 @@ #include <cassert> -Actor::~Actor() +ActorComponent::ActorComponent(Entity &entity): + mMoveTime(0), + mUpdateFlags(0), + mPublicID(65535), + mSize(0), + mWalkMask(0), + mBlockType(BLOCKTYPE_NONE) +{ + entity.signal_removed.connect( + sigc::mem_fun(this, &ActorComponent::removed)); + entity.signal_map_changed.connect( + sigc::mem_fun(this, &ActorComponent::mapChanged)); +} + +void ActorComponent::removed(Entity *entity) { // Free the map position - if (MapComposite *mapComposite = getMap()) + if (MapComposite *mapComposite = entity->getMap()) { Map *map = mapComposite->getMap(); int tileWidth = map->getTileWidth(); @@ -38,10 +52,10 @@ Actor::~Actor() } } -void Actor::setPosition(const Point &p) +void ActorComponent::setPosition(Entity &entity, const Point &p) { // Update blockmap - if (MapComposite *mapComposite = getMap()) + if (MapComposite *mapComposite = entity.getMap()) { Map *map = mapComposite->getMap(); int tileWidth = map->getTileWidth(); @@ -58,21 +72,11 @@ void Actor::setPosition(const Point &p) mPos = p; } -void Actor::setMap(MapComposite *mapComposite) +void ActorComponent::mapChanged(Entity *entity) { - assert(mapComposite); const Point p = getPosition(); - if (MapComposite *oldMapComposite = getMap()) - { - Map *oldMap = oldMapComposite->getMap(); - int oldTileWidth = oldMap->getTileWidth(); - int oldTileHeight = oldMap->getTileHeight(); - oldMap->freeTile(p.x / oldTileWidth, p.y / oldTileHeight, - getBlockType()); - } - Entity::setMap(mapComposite); - Map *map = mapComposite->getMap(); + Map *map = entity->getMap()->getMap(); int tileWidth = map->getTileWidth(); int tileHeight = map->getTileHeight(); map->blockTile(p.x / tileWidth, p.y / tileHeight, getBlockType()); diff --git a/src/game-server/actor.h b/src/game-server/actor.h index 83b2c0fe..2950d512 100644 --- a/src/game-server/actor.h +++ b/src/game-server/actor.h @@ -45,20 +45,17 @@ enum * Generic client-visible object. Keeps track of position, size and what to * update clients about. */ -class Actor : public Entity +class ActorComponent : public Component { public: - Actor(EntityType type) - : Entity(type), - mMoveTime(0), - mUpdateFlags(0), - mPublicID(65535), - mSize(0), - mWalkMask(0), - mBlockType(BLOCKTYPE_NONE) + static const ComponentType type = CT_Actor; + + ActorComponent(Entity &entity); + + void update(Entity &entity) {} - ~Actor(); + void removed(Entity *entity); /** * Sets the coordinates. Also updates the walkmap of the map the actor @@ -66,7 +63,7 @@ class Actor : public Entity * * @param p the coordinates. */ - void setPosition(const Point &p); + void setPosition(Entity &entity, const Point &p); /** * Gets the coordinates. @@ -138,7 +135,7 @@ class Actor : public Entity /** * Overridden in order to update the walkmap. */ - virtual void setMap(MapComposite *map); + virtual void mapChanged(Entity *entity); protected: diff --git a/src/game-server/attack.h b/src/game-server/attack.h index 348a94bb..8dc62629 100644 --- a/src/game-server/attack.h +++ b/src/game-server/attack.h @@ -21,6 +21,7 @@ #ifndef ATTACK_H #define ATTACK_H +#include <cassert> #include <cstddef> #include <list> @@ -146,7 +147,7 @@ class Attack public: Attack(AttackInfo *info): mInfo(info) - {} + {assert(info);} AttackInfo *getAttackInfo() { return mInfo; } diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index ad3fcfc7..41ab7757 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -81,13 +81,10 @@ BeingComponent::BeingComponent(Entity &entity): void BeingComponent::triggerEmote(Entity &entity, int id) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); - mEmoteId = id; if (id > -1) - actor.raiseUpdateFlags(UPDATEFLAG_EMOTE); + entity.getComponent<ActorComponent>()->raiseUpdateFlags(UPDATEFLAG_EMOTE); } @@ -119,13 +116,11 @@ void BeingComponent::heal(Entity &entity, int gain) void BeingComponent::died(Entity &entity) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); - if (mAction == DEAD) return; - LOG_DEBUG("Being " << actor.getPublicID() << " died."); + LOG_DEBUG("Being " << entity.getComponent<ActorComponent>()->getPublicID() + << " died."); setAction(entity, DEAD); // dead beings stay where they are clearDestination(entity); @@ -135,43 +130,38 @@ void BeingComponent::died(Entity &entity) void BeingComponent::setDestination(Entity &entity, const Point &dst) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); - mDst = dst; - actor.raiseUpdateFlags(UPDATEFLAG_NEW_DESTINATION); + entity.getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_NEW_DESTINATION); mPath.clear(); } void BeingComponent::clearDestination(Entity &entity) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); - - setDestination(entity, actor.getPosition()); + setDestination(entity, + entity.getComponent<ActorComponent>()->getPosition()); } void BeingComponent::setDirection(Entity &entity, BeingDirection direction) { - // Temponary until all dependencies are available as components - Actor &actor = static_cast<Actor &>(entity); mDirection = direction; - actor.raiseUpdateFlags(UPDATEFLAG_DIRCHANGE); + entity.getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_DIRCHANGE); } Path BeingComponent::findPath(Entity &entity) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); + auto *actorComponent = entity.getComponent<ActorComponent>(); Map *map = entity.getMap()->getMap(); int tileWidth = map->getTileWidth(); int tileHeight = map->getTileHeight(); - int startX = actor.getPosition().x / tileWidth; - int startY = actor.getPosition().y / tileHeight; + int startX = actorComponent->getPosition().x / tileWidth; + int startY = actorComponent->getPosition().y / tileHeight; int destX = mDst.x / tileWidth, destY = mDst.y / tileHeight; - return map->findPath(startX, startY, destX, destY, actor.getWalkMask()); + return map->findPath(startX, startY, destX, destY, + actorComponent->getWalkMask()); } void BeingComponent::updateDirection(Entity &entity, @@ -261,9 +251,6 @@ void BeingComponent::updateDirection(Entity &entity, void BeingComponent::move(Entity &entity) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); - // Immobile beings cannot move. if (!checkAttributeExists(ATTR_MOVE_SPEED_RAW) || !getModifiedAttribute(ATTR_MOVE_SPEED_RAW)) @@ -272,10 +259,10 @@ void BeingComponent::move(Entity &entity) // Remember the current position before moving. This is used by // MapComposite::update() to determine whether a being has moved from one // zone to another. - mOld = actor.getPosition(); + mOld = entity.getComponent<ActorComponent>()->getPosition(); // Ignore not moving beings - if (mAction == STAND && mDst == actor.getPosition()) + if (mAction == STAND && mDst == mOld) return; if (mMoveTime > WORLD_TICK_MS) @@ -288,8 +275,8 @@ void BeingComponent::move(Entity &entity) Map *map = entity.getMap()->getMap(); int tileWidth = map->getTileWidth(); int tileHeight = map->getTileHeight(); - int tileSX = actor.getPosition().x / tileWidth; - int tileSY = actor.getPosition().y / tileHeight; + int tileSX = mOld.x / tileWidth; + int tileSY = mOld.y / tileHeight; int tileDX = mDst.x / tileWidth; int tileDY = mDst.y / tileHeight; @@ -299,8 +286,8 @@ void BeingComponent::move(Entity &entity) setAction(entity, STAND); // Moving while staying on the same tile is free // We only update the direction in that case. - updateDirection(entity, actor.getPosition(), mDst); - actor.setPosition(mDst); + updateDirection(entity, mOld, mDst); + entity.getComponent<ActorComponent>()->setPosition(entity, mDst); mMoveTime = 0; return; } @@ -315,8 +302,9 @@ void BeingComponent::move(Entity &entity) for (PathIterator pathIterator = mPath.begin(); pathIterator != mPath.end(); pathIterator++) { - if (!map->getWalk(pathIterator->x, pathIterator->y, - actor.getWalkMask())) + const unsigned char walkmask = + entity.getComponent<ActorComponent>()->getWalkMask(); + if (!map->getWalk(pathIterator->x, pathIterator->y, walkmask)) { mPath.clear(); break; @@ -365,7 +353,7 @@ void BeingComponent::move(Entity &entity) pos.y = next.y * tileHeight + (tileHeight / 2); } while (mMoveTime < WORLD_TICK_MS); - actor.setPosition(pos); + entity.getComponent<ActorComponent>()->setPosition(entity, pos); mMoveTime = mMoveTime > WORLD_TICK_MS ? mMoveTime - WORLD_TICK_MS : 0; @@ -387,14 +375,12 @@ int BeingComponent::directionToAngle(int direction) void BeingComponent::setAction(Entity &entity, BeingAction action) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); - mAction = action; if (action != ATTACK && // The players are informed about these actions action != WALK) // by other messages { - actor.raiseUpdateFlags(UPDATEFLAG_ACTIONCHANGE); + entity.getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_ACTIONCHANGE); } } @@ -523,9 +509,6 @@ void BeingComponent::recalculateBaseAttribute(Entity &entity, unsigned attr) void BeingComponent::updateDerivedAttributes(Entity &entity, unsigned attr) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); - signal_attribute_changed.emit(&entity, attr); LOG_DEBUG("Being: Updating derived attribute(s) of: " << attr); @@ -535,7 +518,8 @@ void BeingComponent::updateDerivedAttributes(Entity &entity, unsigned attr) { case ATTR_MAX_HP: case ATTR_HP: - actor.raiseUpdateFlags(UPDATEFLAG_HEALTHCHANGE); + entity.getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_HEALTHCHANGE); break; case ATTR_MOVE_SPEED_TPS: // Does not make a lot of sense to have in the scripts. @@ -604,9 +588,6 @@ void BeingComponent::setStatusEffectTime(int id, int time) void BeingComponent::update(Entity &entity) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); - int oldHP = getModifiedAttribute(ATTR_HP); int newHP = oldHP; int maxHP = getModifiedAttribute(ATTR_MAX_HP); @@ -626,7 +607,8 @@ void BeingComponent::update(Entity &entity) if (newHP != oldHP) { setAttribute(entity, ATTR_HP, newHP); - actor.raiseUpdateFlags(UPDATEFLAG_HEALTHCHANGE); + entity.getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_HEALTHCHANGE); } // Update lifetime of effects. @@ -665,11 +647,8 @@ void BeingComponent::update(Entity &entity) void BeingComponent::inserted(Entity *entity) { - // Temporary until all depdencies are available as component - Actor *actor = static_cast<Actor *>(entity); - // Reset the old position, since after insertion it is important that it is // in sync with the zone that we're currently present in. - mOld = actor->getPosition(); + mOld = entity->getComponent<ActorComponent>()->getPosition(); } diff --git a/src/game-server/being.h b/src/game-server/being.h index dd9790db..5ccc8e89 100644 --- a/src/game-server/being.h +++ b/src/game-server/being.h @@ -50,7 +50,7 @@ typedef std::map< int, Status > StatusEffects; * Generic being (living actor). Keeps direction, destination and a few other * relevant properties. Used for characters & monsters (all animated objects). */ -class BeingComponent : public Component, public sigc::trackable +class BeingComponent : public Component { public: static const ComponentType type = CT_Being; diff --git a/src/game-server/buysell.cpp b/src/game-server/buysell.cpp index 3ba29ef6..cc209ccf 100644 --- a/src/game-server/buysell.cpp +++ b/src/game-server/buysell.cpp @@ -30,7 +30,7 @@ #include <algorithm> -BuySell::BuySell(Actor *c, bool sell): +BuySell::BuySell(Entity *c, bool sell): mCurrencyId(ATTR_GP), mChar(c), mSell(sell) { c->getComponent<CharacterComponent>()->setBuySell(this); @@ -94,7 +94,8 @@ int BuySell::registerPlayerItems() else { LOG_WARN("registerPlayersItems(): The character Id: " - << mChar->getPublicID() << " has unknown items (Id: " << id + << mChar->getComponent<ActorComponent>()->getPublicID() + << " has unknown items (Id: " << id << "). They have been ignored."); continue; } @@ -129,7 +130,7 @@ int BuySell::registerPlayerItems() return nbItemsToSell; } -bool BuySell::start(Actor *actor) +bool BuySell::start(Entity *actor) { if (mItems.empty()) { @@ -138,7 +139,7 @@ bool BuySell::start(Actor *actor) } MessageOut msg(mSell ? GPMSG_NPC_SELL : GPMSG_NPC_BUY); - msg.writeInt16(actor->getPublicID()); + msg.writeInt16(actor->getComponent<ActorComponent>()->getPublicID()); for (TradedItems::const_iterator i = mItems.begin(), i_end = mItems.end(); i != i_end; ++i) { diff --git a/src/game-server/buysell.h b/src/game-server/buysell.h index 88904f4d..0906aaf4 100644 --- a/src/game-server/buysell.h +++ b/src/game-server/buysell.h @@ -23,7 +23,6 @@ #include <vector> -class Actor; class Entity; class BuySell @@ -33,7 +32,7 @@ class BuySell /** * Sets up a trade between a character and an NPC. */ - BuySell(Actor *, bool sell); + BuySell(Entity *, bool sell); /** * Cancels the trade. @@ -57,7 +56,7 @@ class BuySell * Sends the item list to player. * @return true if at least one item was registered before start. */ - bool start(Actor *actor); + bool start(Entity *actor); /** * Performs the trade. @@ -80,7 +79,7 @@ class BuySell /** The attribute ID of the currency to use. Hardcoded for now (FIXME) */ unsigned mCurrencyId; - Actor *mChar; /**< Character involved. */ + Entity *mChar; /**< Character involved. */ TradedItems mItems; /**< Traded items. */ bool mSell; /**< Are items sold? */ }; diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 8f35fef4..ab13e008 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -90,10 +90,7 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): mKnuckleAttackInfo(0), mBaseEntity(&entity) { - // Temporary until all dependencies are in a component - Actor &being = static_cast<Actor &>(entity); - - mCharacterData = new CharacterData(&being, this); + mCharacterData = new CharacterData(&entity, this); auto *beingComponent = entity.getComponent<BeingComponent>(); @@ -105,12 +102,13 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): beingComponent->createAttribute(attributeScope.first, *attributeScope.second); - - being.setWalkMask(Map::BLOCKMASK_WALL); - being.setBlockType(BLOCKTYPE_CHARACTER); + auto *actorComponent = entity.getComponent<ActorComponent>(); + actorComponent->setWalkMask(Map::BLOCKMASK_WALL); + actorComponent->setBlockType(BLOCKTYPE_CHARACTER); + actorComponent->setSize(16); - CombatComponent *combatcomponent = new CombatComponent(being); + CombatComponent *combatcomponent = new CombatComponent(entity); entity.addComponent(combatcomponent); combatcomponent->getAttacks().attack_added.connect( sigc::mem_fun(this, &CharacterComponent::attackAdded)); @@ -138,9 +136,8 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): deserializeCharacterData(*mCharacterData, msg); - Inventory(&being, mPossessions).initialize(); - modifiedAllAttributes(entity); - being.setSize(16); + Inventory(&entity, mPossessions).initialize(); + modifiedAllAttributes(entity);; beingComponent->signal_attribute_changed.connect(sigc::mem_fun( this, &CharacterComponent::attributeChanged)); diff --git a/src/game-server/character.h b/src/game-server/character.h index 74d08d30..195ea8d9 100644 --- a/src/game-server/character.h +++ b/src/game-server/character.h @@ -69,7 +69,7 @@ typedef std::map<unsigned, SpecialValue> SpecialMap; class CharacterData { public: - CharacterData(Actor *actor, CharacterComponent *characterComponent); + CharacterData(Entity *entity, CharacterComponent *characterComponent); void setGender(BeingGender); BeingGender getGender() const; @@ -123,7 +123,7 @@ public: Possessions &getPossessions() const; private: - Actor *mActor; + Entity *mEntity; CharacterComponent *mCharacterComponent; }; @@ -578,55 +578,55 @@ class CharacterComponent : public Component }; -inline CharacterData::CharacterData(Actor *actor, +inline CharacterData::CharacterData(Entity *entity, CharacterComponent *characterComponent): - mActor(actor), + mEntity(entity), mCharacterComponent(characterComponent) {} inline void CharacterData::setGender(BeingGender gender) { - mActor->getComponent<BeingComponent>()->setGender(gender); + mEntity->getComponent<BeingComponent>()->setGender(gender); } inline BeingGender CharacterData::getGender() const { - return mActor->getComponent<BeingComponent>()->getGender(); + return mEntity->getComponent<BeingComponent>()->getGender(); } inline void CharacterData::setMapId(int id) { - mActor->setMap(MapManager::getMap(id)); + mEntity->setMap(MapManager::getMap(id)); } inline int CharacterData::getMapId() const { - return mActor->getMap()->getID(); + return mEntity->getMap()->getID(); } inline void CharacterData::setPosition(Point &point) { - mActor->setPosition(point); + mEntity->getComponent<ActorComponent>()->setPosition(*mEntity, point); } inline const Point &CharacterData::getPosition() const { - return mActor->getPosition(); + return mEntity->getComponent<ActorComponent>()->getPosition(); } inline void CharacterData::setAttribute(int id, int base) { - mActor->getComponent<BeingComponent>()->setAttribute(*mActor, id, base); + mEntity->getComponent<BeingComponent>()->setAttribute(*mEntity, id, base); } inline void CharacterData::setModAttribute(int id, int mod) { - mActor->getComponent<BeingComponent>()->setModAttribute(id, mod); + mEntity->getComponent<BeingComponent>()->setModAttribute(id, mod); } inline const AttributeMap &CharacterData::getAttributes() const { - return mActor->getComponent<BeingComponent>()->getAttributes(); + return mEntity->getComponent<BeingComponent>()->getAttributes(); } inline void CharacterData::setCharacterPoints(int characterPoints) @@ -711,22 +711,22 @@ inline const std::map<int, int>::const_iterator CharacterData::getSkillEnd() con inline void CharacterData::applyStatusEffect(int status, int time) { - mActor->getComponent<BeingComponent>()->applyStatusEffect(status, time); + mEntity->getComponent<BeingComponent>()->applyStatusEffect(status, time); } inline int CharacterData::getStatusEffectSize() const { - return mActor->getComponent<BeingComponent>()->getStatusEffects().size(); + return mEntity->getComponent<BeingComponent>()->getStatusEffects().size(); } inline const std::map<int, Status>::const_iterator CharacterData::getStatusEffectBegin() const { - return mActor->getComponent<BeingComponent>()->getStatusEffects().begin(); + return mEntity->getComponent<BeingComponent>()->getStatusEffects().begin(); } inline const std::map<int, Status>::const_iterator CharacterData::getStatusEffectEnd() const { - return mActor->getComponent<BeingComponent>()->getStatusEffects().end(); + return mEntity->getComponent<BeingComponent>()->getStatusEffects().end(); } inline int CharacterData::getKillCountSize() const diff --git a/src/game-server/combatcomponent.cpp b/src/game-server/combatcomponent.cpp index df2d034d..38c7716e 100644 --- a/src/game-server/combatcomponent.cpp +++ b/src/game-server/combatcomponent.cpp @@ -41,11 +41,6 @@ CombatComponent::~CombatComponent() void CombatComponent::update(Entity &entity) { - // Temporary for as long as Being is not split into Components - // Prevents to implement all at once - // TODO: remove this as soon as possible - Actor &actor = static_cast<Actor&>(entity); - auto *beingComponent = entity.getComponent<BeingComponent>(); if (beingComponent->getAction() != ATTACK || !mTarget) @@ -69,12 +64,18 @@ void CombatComponent::update(Entity &entity) for (std::vector<Attack *>::const_iterator it = attacksReady.begin(), it_end = attacksReady.end(); it != it_end; ++it) { + const Point &attackerPosition = + entity.getComponent<ActorComponent>()->getPosition(); + const Point &targetPosition = + mTarget->getComponent<ActorComponent>()->getPosition(); + // check if target is in range using the pythagorean theorem - int distx = actor.getPosition().x - mTarget->getPosition().x; - int disty = actor.getPosition().y - mTarget->getPosition().y; + int distx = attackerPosition.x - targetPosition.x; + int disty = attackerPosition.y - targetPosition.y; int distSquare = (distx * distx + disty * disty); AttackInfo *info = (*it)->getAttackInfo(); - int maxDist = info->getDamage().range + actor.getSize(); + int maxDist = info->getDamage().range + + entity.getComponent<ActorComponent>()->getSize(); if (distSquare <= maxDist * maxDist && (!highestPriorityAttack || @@ -88,9 +89,12 @@ void CombatComponent::update(Entity &entity) { mAttacks.startAttack(highestPriorityAttack); mCurrentAttack = highestPriorityAttack; - beingComponent->setDestination(entity, actor.getPosition()); + const Point &point = + entity.getComponent<ActorComponent>()->getPosition(); + beingComponent->setDestination(entity, point); // TODO: Turn into direction of enemy - actor.raiseUpdateFlags(UPDATEFLAG_ATTACK); + entity.getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_ATTACK); } } @@ -155,7 +159,8 @@ int CombatComponent::damage(Entity &target, { mHitsTaken.push_back(HPloss); const Attribute *HP = beingComponent->getAttribute(ATTR_HP); - LOG_DEBUG("Being " << static_cast<Actor &>(target).getPublicID() + LOG_DEBUG("Being " + << target.getComponent<ActorComponent>()->getPublicID() << " suffered " << HPloss << " damage. HP: " << HP->getModifiedAttribute() << "/" diff --git a/src/game-server/combatcomponent.h b/src/game-server/combatcomponent.h index 393eb612..168c08d7 100644 --- a/src/game-server/combatcomponent.h +++ b/src/game-server/combatcomponent.h @@ -30,14 +30,13 @@ #include "game-server/attack.h" class Entity; -class Actor; /** * Type definition for a list of hits */ typedef std::vector<unsigned> Hits; -class CombatComponent: public Component, public sigc::trackable +class CombatComponent: public Component { public: static const ComponentType type = CT_Fighting; @@ -59,8 +58,8 @@ public: int getAttackId() const; - Actor *getTarget() const; - void setTarget(Actor *target); + Entity *getTarget() const; + void setTarget(Entity *target); void clearTarget(); void diedOrRemoved(Entity *entity); @@ -70,7 +69,7 @@ public: protected: virtual void processAttack(Entity &source, Attack &attack); - Actor *mTarget; + Entity *mTarget; Attacks mAttacks; Attack *mCurrentAttack; // Last used attack Hits mHitsTaken; //List of punches taken since last update. @@ -111,7 +110,7 @@ inline int CombatComponent::getAttackId() const /** * Get Target */ -inline Actor *CombatComponent::getTarget() const +inline Entity *CombatComponent::getTarget() const { return mTarget; } @@ -119,7 +118,7 @@ inline Actor *CombatComponent::getTarget() const /** * Set Target */ -inline void CombatComponent::setTarget(Actor *target) +inline void CombatComponent::setTarget(Entity *target) { mTarget = target; } diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index 8a8e1380..9c413ed8 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -173,7 +173,7 @@ static CmdRef const cmdRef[] = static void say(const std::string &message, Entity *player) { - GameState::sayTo(static_cast<Actor*>(player), nullptr, message); + GameState::sayTo(player, nullptr, message); } /* @@ -619,9 +619,9 @@ static void handleDrop(Entity *player, std::string &args) return; } - Entity *item = Item::create(player->getMap(), - static_cast<Actor*>(player)->getPosition(), - ic, amount); + const Point &position = + player->getComponent<ActorComponent>()->getPosition(); + Entity *item = Item::create(player->getMap(), position, ic, amount); GameState::insertOrDelete(item); @@ -693,7 +693,7 @@ static void handleSpawn(Entity *player, std::string &args) { MonsterClass *mc; MapComposite *map = player->getMap(); - const Point &pos = static_cast<Actor*>(player)->getPosition(); + const Point &pos = player->getComponent<ActorComponent>()->getPosition(); int value = 0; // get the arguments @@ -744,8 +744,10 @@ static void handleSpawn(Entity *player, std::string &args) // create the monsters and put them on the map for (int i = 0; i < value; ++i) { - Actor *monster = new Actor(OBJECT_MONSTER); - monster->setPosition(pos); + Entity *monster = new Entity(OBJECT_MONSTER); + auto *actorComponent = new ActorComponent(*monster); + monster->addComponent(actorComponent); + actorComponent->setPosition(*monster, pos); monster->addComponent(new BeingComponent(*monster)); monster->addComponent(new MonsterComponent(*monster, mc)); monster->setMap(map); @@ -789,7 +791,7 @@ static void handleGoto(Entity *player, std::string &args) // move the player to where the other player is MapComposite *map = other->getMap(); - const Point &pos = static_cast<Actor*>(other)->getPosition(); + const Point &pos = other->getComponent<ActorComponent>()->getPosition(); GameState::warp(player, map, pos); // log transaction @@ -826,7 +828,7 @@ static void handleRecall(Entity *player, std::string &args) // move the other player to where the player is MapComposite *map = player->getMap(); - const Point &pos = static_cast<Actor*>(player)->getPosition(); + const Point &pos = player->getComponent<ActorComponent>()->getPosition(); GameState::warp(other, map, pos); } @@ -1174,14 +1176,15 @@ static void handleAnnounce(Entity *player, std::string &args) static void handleWhere(Entity *player, std::string &) { - Actor *actor = static_cast<Actor*>(player); + const Point &position = + player->getComponent<ActorComponent>()->getPosition(); std::stringstream str; str << "Your current location is map " << player->getMap()->getID() << " [" - << actor->getPosition().x + << position.x << ":" - << actor->getPosition().y + << position.y << "]"; say (str.str(), player); } @@ -1377,7 +1380,7 @@ static void handleLogsay(Entity *player, std::string &msg) return; } - GameState::sayAround(static_cast<Actor*>(player), msg); + GameState::sayAround(player, msg); // log transaction std::string logmsg = "[public] " + msg; @@ -1504,7 +1507,7 @@ static void handleGetPos(Entity *player, std::string &args) say("Invalid character, or player is offline.", player); return; } - const Point &pos = static_cast<Actor*>(other)->getPosition(); + const Point &pos = other->getComponent<ActorComponent>()->getPosition(); std::stringstream str; str << "The current location of " << character @@ -1576,7 +1579,7 @@ static void handleEffect(Entity *player, std::string &args) if (arguments.size() == 1) { int id = utils::stringToInt(arguments[0]); - Effects::show(id, static_cast<Actor*>(player)); + Effects::show(id, player); } else if (arguments.size() == 2) { @@ -1587,7 +1590,7 @@ static void handleEffect(Entity *player, std::string &args) say("Invalid target player.", player); return; } - Effects::show(id, static_cast<Actor*>(p)); + Effects::show(id, p); } else if (arguments.size() == 3) { diff --git a/src/game-server/component.h b/src/game-server/component.h index c3f54839..824de2c8 100644 --- a/src/game-server/component.h +++ b/src/game-server/component.h @@ -21,10 +21,13 @@ #ifndef COMPONENT_H #define COMPONENT_H +#include <sigc++/trackable.h> + class Entity; enum ComponentType { + CT_Actor, CT_Character, CT_Being, CT_Effect, @@ -41,7 +44,7 @@ enum ComponentType /** * A component of an entity. */ -class Component +class Component : public sigc::trackable { public: virtual ~Component() {} diff --git a/src/game-server/effect.cpp b/src/game-server/effect.cpp index b8e03dab..94f4613c 100644 --- a/src/game-server/effect.cpp +++ b/src/game-server/effect.cpp @@ -30,30 +30,35 @@ const ComponentType EffectComponent::type; void EffectComponent::update(Entity &entity) { if (mHasBeenShown) - GameState::enqueueRemove(static_cast<Actor*>(&entity)); + GameState::enqueueRemove(&entity); } namespace Effects { void show(int id, MapComposite *map, const Point &pos) { - Actor *effect = new Actor(OBJECT_EFFECT); + Entity *effect = new Entity(OBJECT_EFFECT); + auto *actorComponent = new ActorComponent(*effect); + effect->addComponent(actorComponent); effect->addComponent(new EffectComponent(id)); effect->setMap(map); - effect->setPosition(pos); + actorComponent->setPosition(*effect, pos); GameState::enqueueInsert(effect); } - void show(int id, Actor *b) + void show(int id, Entity *b) { EffectComponent *effectComponent = new EffectComponent(id); effectComponent->setBeing(b); - Actor *effect = new Actor(OBJECT_EFFECT); + Entity *effect = new Entity(OBJECT_EFFECT); + auto *actorComponent = new ActorComponent(*effect); + effect->addComponent(actorComponent); effect->addComponent(effectComponent); effect->setMap(b->getMap()); - effect->setPosition(b->getPosition()); + const Point &point = b->getComponent<ActorComponent>()->getPosition(); + actorComponent->setPosition(*effect, point); GameState::enqueueInsert(effect); } diff --git a/src/game-server/effect.h b/src/game-server/effect.h index 4c355d67..556d6acb 100644 --- a/src/game-server/effect.h +++ b/src/game-server/effect.h @@ -24,7 +24,6 @@ #include "game-server/component.h" -class Actor; class Entity; class MapComposite; class Point; @@ -73,7 +72,7 @@ namespace Effects * Convenience methods to show an effect. */ void show(int id, MapComposite *map, const Point &pos); - void show(int id, Actor *b); + void show(int id, Entity *b); // TODO: get this in sync with effects.xml enum { diff --git a/src/game-server/entity.h b/src/game-server/entity.h index 9d418df3..81faa941 100644 --- a/src/game-server/entity.h +++ b/src/game-server/entity.h @@ -62,10 +62,11 @@ class Entity : public sigc::trackable virtual void update(); MapComposite *getMap() const; - virtual void setMap(MapComposite *map); + void setMap(MapComposite *map); sigc::signal<void, Entity *> signal_inserted; sigc::signal<void, Entity *> signal_removed; + sigc::signal<void, Entity *> signal_map_changed; private: MapComposite *mMap; /**< Map the entity is on */ @@ -91,7 +92,6 @@ inline EntityType Entity::getType() const template <class T> inline void Entity::addComponent(T *component) { - assert(!mComponents[T::type]); mComponents[T::type] = component; } @@ -101,6 +101,7 @@ inline void Entity::addComponent(T *component) */ inline Component *Entity::getComponent(ComponentType type) const { + assert(mComponents[type]); return mComponents[type]; } @@ -153,6 +154,7 @@ inline MapComposite *Entity::getMap() const inline void Entity::setMap(MapComposite *map) { mMap = map; + signal_map_changed.emit(this); } #endif // ENTITY_H diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index b01c5002..603bb1e8 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -137,52 +137,55 @@ void GameHandler::updateCharacter(int charid, int partyid) } } -static Actor *findActorNear(Actor *p, int id) +static Entity *findActorNear(Entity *p, int id) { MapComposite *map = p->getMap(); - const Point &ppos = p->getPosition(); + const Point &ppos = p->getComponent<ActorComponent>()->getPosition(); // See map.h for tiles constants const int pixelDist = DEFAULT_TILE_LENGTH * TILES_TO_BE_NEAR; for (ActorIterator i(map->getAroundPointIterator(ppos, pixelDist)); i; ++i) { - Actor *a = *i; - if (a->getPublicID() != id) + Entity *a = *i; + if (a->getComponent<ActorComponent>()->getPublicID() != id) continue; - return ppos.inRangeOf(a->getPosition(), pixelDist) ? a : 0; + return ppos.inRangeOf(a->getComponent<ActorComponent>()->getPosition(), + pixelDist) ? a : 0; } return 0; } -static Entity *findBeingNear(Actor *p, int id) +static Entity *findBeingNear(Entity *p, int id) { MapComposite *map = p->getMap(); - const Point &ppos = p->getPosition(); + const Point &ppos = p->getComponent<ActorComponent>()->getPosition(); // See map.h for tiles constants const int pixelDist = DEFAULT_TILE_LENGTH * TILES_TO_BE_NEAR; for (BeingIterator i(map->getAroundPointIterator(ppos, pixelDist)); i; ++i) { - Actor *b = static_cast<Actor *>(*i); - if (b->getPublicID() != id) + Entity *b = *i; + if (b->getComponent<ActorComponent>()->getPublicID() != id) continue; - return ppos.inRangeOf(b->getPosition(), pixelDist) ? b : 0; + return ppos.inRangeOf(b->getComponent<ActorComponent>()->getPosition(), + pixelDist) ? b : 0; } return 0; } -static Entity *findCharacterNear(Actor *p, int id) +static Entity *findCharacterNear(Entity *p, int id) { MapComposite *map = p->getMap(); - const Point &ppos = p->getPosition(); + const Point &ppos = p->getComponent<ActorComponent>()->getPosition(); // See map.h for tiles constants const int pixelDist = DEFAULT_TILE_LENGTH * TILES_TO_BE_NEAR; for (CharacterIterator i(map->getAroundPointIterator(ppos, pixelDist)); i; ++i) { - Actor *c = static_cast<Actor *>(*i); - if (c->getPublicID() != id) + Entity *c = *i; + if (c->getComponent<ActorComponent>()->getPublicID() != id) continue; - if (ppos.inRangeOf(c->getPosition(), pixelDist)) + if (ppos.inRangeOf(c->getComponent<ActorComponent>()->getPosition(), + pixelDist)) return c; return 0; @@ -455,11 +458,11 @@ void GameHandler::handleSay(GameClient &client, MessageIn &message) } if (!client.character->getComponent<CharacterComponent>()->isMuted()) { - GameState::sayAround(static_cast<Actor *>(client.character), say); + GameState::sayAround(client.character, say); } else { - GameState::sayTo(static_cast<Actor *>(client.character), nullptr, + GameState::sayTo(client.character, nullptr, "You are not allowed to talk right now."); } } @@ -467,7 +470,7 @@ void GameHandler::handleSay(GameClient &client, MessageIn &message) void GameHandler::handleNpc(GameClient &client, MessageIn &message) { int id = message.readInt16(); - Actor *actor = findActorNear(static_cast<Actor *>(client.character), id); + Entity *actor = findActorNear(client.character, id); if (!actor || actor->getType() != OBJECT_NPC) { sendNpcError(client, id, "Not close enough to NPC\n"); @@ -498,7 +501,8 @@ void GameHandler::handlePickup(GameClient &client, MessageIn &message) { const int x = message.readInt16(); const int y = message.readInt16(); - const Point ppos = static_cast<Actor *>(client.character)->getPosition(); + const Point ppos = + client.character->getComponent<ActorComponent>()->getPosition(); // TODO: use a less arbitrary value. if (std::abs(x - ppos.x) + std::abs(y - ppos.y) < 48) @@ -508,7 +512,7 @@ void GameHandler::handlePickup(GameClient &client, MessageIn &message) for (FixedActorIterator i(map->getAroundPointIterator(ipos, 0)); i; ++i) { Entity *o = *i; - Point opos = static_cast<Actor *>(o)->getPosition(); + Point opos = o->getComponent<ActorComponent>()->getPosition(); if (o->getType() == OBJECT_ITEM && opos.x == x && opos.y == y) { @@ -584,7 +588,8 @@ void GameHandler::handleDrop(GameClient &client, MessageIn &message) { int nb = inv.removeFromSlot(slot, amount); MapComposite *map = client.character->getMap(); - Point pos = static_cast<Actor *>(client.character)->getPosition(); + const Point &pos = client.character->getComponent<ActorComponent>() + ->getPosition(); Entity *item = Item::create(map, pos, ic, amount - nb); @@ -670,16 +675,16 @@ void GameHandler::handleMoveItem(GameClient &client, MessageIn &message) void GameHandler::handleAttack(GameClient &client, MessageIn &message) { int id = message.readInt16(); - Actor *actor = static_cast<Actor *>(client.character); - LOG_DEBUG("Character " << actor->getPublicID() - << " attacked being " << id); + const int publicId = + client.character->getComponent<ActorComponent>()->getPublicID(); + LOG_DEBUG("Character " << publicId << " attacked being " << id); - Actor *being = static_cast<Actor *>(findBeingNear(actor, id)); + Entity *being = findBeingNear(client.character, id); if (being && being->getType() != OBJECT_NPC) { client.character->getComponent<CombatComponent>()->setTarget(being); - client.character->getComponent<BeingComponent>()->setAction(*actor, - ATTACK); + client.character->getComponent<BeingComponent>()->setAction( + *client.character, ATTACK); } } @@ -688,14 +693,15 @@ void GameHandler::handleUseSpecialOnBeing(GameClient &client, MessageIn &message if (client.character->getComponent<BeingComponent>()->getAction() == DEAD) return; - Actor *actor = static_cast<Actor *>(client.character); - const int specialID = message.readInt8(); const int targetID = message.readInt16(); // 0 when no target is selected Entity *being = 0; if (targetID != 0) - being = findBeingNear(actor, targetID); - LOG_DEBUG("Character " << actor->getPublicID() + being = findBeingNear(client.character, targetID); + + const int publicId = + client.character->getComponent<ActorComponent>()->getPublicID(); + LOG_DEBUG("Character " << publicId << " tries to use his special attack " << specialID); auto *characterComponent = client.character ->getComponent<CharacterComponent>(); @@ -711,8 +717,9 @@ void GameHandler::handleUseSpecialOnPoint(GameClient &client, MessageIn &message const int x = message.readInt16(); const int y = message.readInt16(); - LOG_DEBUG("Character " - << static_cast<Actor *>(client.character)->getPublicID() + const int publicId = + client.character->getComponent<ActorComponent>()->getPublicID(); + LOG_DEBUG("Character " << publicId << " tries to use his special attack " << specialID); auto *characterComponent = client.character ->getComponent<CharacterComponent>(); @@ -810,7 +817,7 @@ void GameHandler::handleTradeRequest(GameClient &client, MessageIn &message) if (t->request(client.character, id)) return; - Entity *q = findCharacterNear(static_cast<Actor *>(client.character), id); + Entity *q = findCharacterNear(client.character, id); if (!q || characterComponent->isBusy()) { client.send(MessageOut(GPMSG_TRADE_CANCEL)); @@ -967,14 +974,13 @@ void GameHandler::handlePartyInvite(GameClient &client, MessageIn &message) if ((*it)->getComponent<BeingComponent>()->getName() == invitee) { // calculate if the invitee is within the visual range - const int xInviter = - static_cast<Actor *>(client.character)->getPosition().x; - const int yInviter = - static_cast<Actor *>(client.character)->getPosition().y; - const int xInvitee = (*it)->getPosition().x; - const int yInvitee = (*it)->getPosition().y; - const int dx = std::abs(xInviter - xInvitee); - const int dy = std::abs(yInviter - yInvitee); + auto *inviterComponent = + client.character->getComponent<ActorComponent>(); + auto *inviteeComponent = (*it)->getComponent<ActorComponent>(); + const Point &inviterPosition = inviterComponent->getPosition(); + const Point &inviteePosition = inviteeComponent->getPosition(); + const int dx = std::abs(inviterPosition.x - inviteePosition.x); + const int dy = std::abs(inviterPosition.y - inviteePosition.y); if (visualRange > std::max(dx, dy)) { MessageOut out(GCMSG_PARTY_INVITE); diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index 465cf8fa..bec5961b 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -842,7 +842,7 @@ bool Inventory::unequip(unsigned itemInstance) void Inventory::checkLookchanges(unsigned slotTypeId) { - Actor *actor = static_cast<Actor*>(mCharacter); if (itemManager->isEquipSlotVisible(slotTypeId)) - actor->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); + mCharacter->getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_LOOKSCHANGE); } diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp index 2b2d4620..ed74e925 100644 --- a/src/game-server/item.cpp +++ b/src/game-server/item.cpp @@ -171,21 +171,23 @@ void ItemComponent::update(Entity &entity) { mLifetime--; if (!mLifetime) - GameState::enqueueRemove(static_cast<Actor*>(&entity)); + GameState::enqueueRemove(&entity); } } namespace Item { -Actor *create(MapComposite *map, +Entity *create(MapComposite *map, Point pos, ItemClass *itemClass, int amount) { - Actor *itemActor = new Actor(OBJECT_ITEM); + Entity *itemActor = new Entity(OBJECT_ITEM); + ActorComponent *actorComponent = new ActorComponent(*itemActor); + itemActor->addComponent(actorComponent); itemActor->addComponent(new ItemComponent(itemClass, amount)); itemActor->setMap(map); - itemActor->setPosition(pos); + actorComponent->setPosition(*itemActor, pos); return itemActor; } diff --git a/src/game-server/item.h b/src/game-server/item.h index e436afdc..76242094 100644 --- a/src/game-server/item.h +++ b/src/game-server/item.h @@ -334,7 +334,7 @@ namespace Item { * * @return the created item */ -Actor *create(MapComposite *map, Point pos, ItemClass *itemClass, int amount); +Entity *create(MapComposite *map, Point pos, ItemClass *itemClass, int amount); } // namespace Item diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index 61e0a8b9..ec881cfa 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -53,7 +53,7 @@ in dealing with zone changes. */ static int const zoneDiam = 256; -void MapZone::insert(Actor *obj) +void MapZone::insert(Entity *obj) { int type = obj->getType(); switch (type) @@ -98,9 +98,9 @@ void MapZone::insert(Actor *obj) } } -void MapZone::remove(Actor *obj) +void MapZone::remove(Entity *obj) { - std::vector< Actor * >::iterator i_beg = objects.begin(), i, i_end; + std::vector< Entity * >::iterator i_beg = objects.begin(), i, i_end; int type = obj->getType(); switch (type) { @@ -195,7 +195,7 @@ void CharacterIterator::operator++() } if (iterator) { - current = static_cast< Actor * >((*iterator)->objects[pos]); + current = (*iterator)->objects[pos]; } } @@ -205,7 +205,7 @@ BeingIterator::BeingIterator(const ZoneIterator &it) while (iterator && (*iterator)->nbMovingObjects == 0) ++iterator; if (iterator) { - current = static_cast< Actor * >((*iterator)->objects[pos]); + current = (*iterator)->objects[pos]; } } @@ -218,7 +218,7 @@ void BeingIterator::operator++() } if (iterator) { - current = static_cast< Actor * >((*iterator)->objects[pos]); + current = (*iterator)->objects[pos]; } } @@ -372,15 +372,18 @@ MapContent::~MapContent() delete[] zones; } -bool MapContent::allocate(Actor *obj) +bool MapContent::allocate(Entity *obj) { // First, try allocating from the last used bucket. ObjectBucket *b = buckets[last_bucket]; + + auto *actorComponent = obj->getComponent<ActorComponent>(); + int i = b->allocate(); if (i >= 0) { b->objects[i] = obj; - obj->setPublicID(last_bucket * 256 + i); + actorComponent->setPublicID(last_bucket * 256 + i); return true; } @@ -403,7 +406,7 @@ bool MapContent::allocate(Actor *obj) { last_bucket = i; b->objects[j] = obj; - obj->setPublicID(last_bucket * 256 + j); + actorComponent->setPublicID(last_bucket * 256 + j); return true; } } @@ -413,9 +416,9 @@ bool MapContent::allocate(Actor *obj) return false; } -void MapContent::deallocate(Actor *obj) +void MapContent::deallocate(Entity *obj) { - unsigned short id = obj->getPublicID(); + unsigned short id = obj->getComponent<ActorComponent>()->getPublicID(); buckets[id / 256]->deallocate(id % 256); } @@ -527,10 +530,11 @@ ZoneIterator MapComposite::getAroundPointIterator(const Point &p, int radius) co return ZoneIterator(r, mContent); } -ZoneIterator MapComposite::getAroundActorIterator(Actor *obj, int radius) const +ZoneIterator MapComposite::getAroundActorIterator(Entity *obj, int radius) const { MapRegion r; - mContent->fillRegion(r, obj->getPosition(), radius); + mContent->fillRegion(r, obj->getComponent<ActorComponent>()->getPosition(), + radius); return ZoneIterator(r, mContent); } @@ -541,7 +545,7 @@ ZoneIterator MapComposite::getInsideRectangleIterator(const Rectangle &p) const return ZoneIterator(r, mContent); } -ZoneIterator MapComposite::getAroundBeingIterator(Actor *obj, int radius) const +ZoneIterator MapComposite::getAroundBeingIterator(Entity *obj, int radius) const { MapRegion r1; mContent->fillRegion(r1, @@ -564,7 +568,9 @@ ZoneIterator MapComposite::getAroundBeingIterator(Actor *obj, int radius) const r2.swap(r3); } } - mContent->fillRegion(r2, obj->getPosition(), radius); + mContent->fillRegion(r2, + obj->getComponent<ActorComponent>()->getPosition(), + radius); return ZoneIterator(r2, mContent); } @@ -572,13 +578,12 @@ bool MapComposite::insert(Entity *ptr) { if (ptr->isVisible()) { - if (ptr->canMove() && !mContent->allocate(static_cast< Actor * >(ptr))) - { + if (ptr->canMove() && !mContent->allocate(ptr)) return false; - } - Actor *obj = static_cast< Actor * >(ptr); - mContent->getZone(obj->getPosition()).insert(obj); + const Point &point = + ptr->getComponent<ActorComponent>()->getPosition(); + mContent->getZone(point).insert(ptr); } ptr->setMap(this); @@ -606,12 +611,13 @@ void MapComposite::remove(Entity *ptr) if (ptr->isVisible()) { - Actor *obj = static_cast< Actor * >(ptr); - mContent->getZone(obj->getPosition()).remove(obj); + const Point &point = + ptr->getComponent<ActorComponent>()->getPosition(); + mContent->getZone(point).remove(ptr); if (ptr->canMove()) { - mContent->deallocate(obj); + mContent->deallocate(ptr); } } } @@ -652,19 +658,18 @@ void MapComposite::update() if (!(*i)->canMove()) continue; - Actor *actor = static_cast<Actor *>(*i); - const Point &pos1 = - actor->getComponent<BeingComponent>()->getOldPosition(); - const Point &pos2 = actor->getPosition(); + (*i)->getComponent<BeingComponent>()->getOldPosition(); + const Point &pos2 = + (*i)->getComponent<ActorComponent>()->getPosition(); MapZone &src = mContent->getZone(pos1), &dst = mContent->getZone(pos2); if (&src != &dst) { addZone(src.destinations, &dst - mContent->zones); - src.remove(actor); - dst.insert(actor); + src.remove(*i); + dst.insert(*i); } } } diff --git a/src/game-server/mapcomposite.h b/src/game-server/mapcomposite.h index 9a6bde07..219f2d9f 100644 --- a/src/game-server/mapcomposite.h +++ b/src/game-server/mapcomposite.h @@ -29,13 +29,12 @@ #include "scripting/script.h" #include "game-server/map.h" -class Actor; class CharacterComponent; +class Entity; class Map; class MapComposite; class Point; class Rectangle; -class Entity; struct MapContent; struct MapZone; @@ -75,11 +74,11 @@ struct CharacterIterator { ZoneIterator iterator; unsigned short pos; - Actor *current; + Entity *current; CharacterIterator(const ZoneIterator &); void operator++(); - Actor *operator*() const { return current; } + Entity *operator*() const { return current; } operator bool() const { return iterator; } }; @@ -90,11 +89,11 @@ struct BeingIterator { ZoneIterator iterator; unsigned short pos; - Actor *current; + Entity *current; BeingIterator(const ZoneIterator &); void operator++(); - Actor *operator*() const { return current; } + Entity *operator*() const { return current; } operator bool() const { return iterator; } }; @@ -120,11 +119,11 @@ struct ActorIterator { ZoneIterator iterator; unsigned short pos; - Actor *current; + Entity *current; ActorIterator(const ZoneIterator &); void operator++(); - Actor *operator*() const { return current; } + Entity *operator*() const { return current; } operator bool() const { return iterator; } }; @@ -139,7 +138,7 @@ struct MapZone * Characters are stored first, then the remaining MovingObjects, then the * remaining Objects. */ - std::vector< Actor * > objects; + std::vector< Entity * > objects; /** * Destinations of the objects that left this zone. @@ -149,8 +148,8 @@ struct MapZone MapRegion destinations; MapZone(): nbCharacters(0), nbMovingObjects(0) {} - void insert(Actor *); - void remove(Actor *); + void insert(Entity *); + void remove(Entity *); }; /** @@ -164,7 +163,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. */ - Actor *objects[256]; + Entity *objects[256]; ObjectBucket(); int allocate(); @@ -182,12 +181,12 @@ struct MapContent /** * Allocates a unique ID for an actor on this map. */ - bool allocate(Actor *); + bool allocate(Entity *); /** * Deallocates an ID. */ - void deallocate(Actor *); + void deallocate(Entity *); /** * Fills a region of zones within the range of a point. @@ -308,13 +307,13 @@ class MapComposite /** * Gets an iterator on the objects around a given actor. */ - ZoneIterator getAroundActorIterator(Actor *, int radius) const; + ZoneIterator getAroundActorIterator(Entity *, 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 getAroundBeingIterator(Actor *, int radius) const; + ZoneIterator getAroundBeingIterator(Entity *, int radius) const; /** * Gets everything related to the map. diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index e3acf323..be0e1618 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -53,16 +53,19 @@ double MonsterClass::getVulnerability(Element element) const return it->second; } -MonsterComponent::MonsterComponent(Actor &actor, MonsterClass *specy): +MonsterComponent::MonsterComponent(Entity &entity, MonsterClass *specy): mSpecy(specy), - mOwner(NULL) + mOwner(nullptr) { LOG_DEBUG("Monster spawned! (id: " << mSpecy->getId() << ")."); - auto *beingComponent = actor.getComponent<BeingComponent>(); + auto *beingComponent = entity.getComponent<BeingComponent>(); - actor.setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER); - actor.setBlockType(BLOCKTYPE_MONSTER); + auto *actorComponent = entity.getComponent<ActorComponent>(); + actorComponent->setWalkMask(Map::BLOCKMASK_WALL | + Map::BLOCKMASK_CHARACTER); + actorComponent->setBlockType(BLOCKTYPE_MONSTER); + actorComponent->setSize(specy->getSize()); /* * Initialise the attribute structures. @@ -88,10 +91,9 @@ MonsterComponent::MonsterComponent(Actor &actor, MonsterClass *specy): double factor = 100 + (rand() % (mutation * 2)) - mutation; attributeValue = attributeValue * factor / 100.0; } - beingComponent->setAttribute(actor, attribute.first, attributeValue); + beingComponent->setAttribute(entity, attribute.first, attributeValue); } - actor.setSize(specy->getSize()); beingComponent->setGender(specy->getGender()); beingComponent->signal_died.connect(sigc::mem_fun(this, @@ -105,8 +107,8 @@ MonsterComponent::MonsterComponent(Actor &actor, MonsterClass *specy): mAttackPositions.push_back(AttackPosition(0, dist, UP)); MonsterCombatComponent *combatComponent = - new MonsterCombatComponent(actor, specy); - actor.addComponent(combatComponent); + new MonsterCombatComponent(entity, specy); + entity.addComponent(combatComponent); double damageMutation = mutation ? (100.0 + (rand() % (mutation * 2)) - mutation) / 100.0 : 1.0; @@ -125,16 +127,13 @@ void MonsterComponent::update(Entity &entity) if (mKillStealProtectedTimeout.justFinished()) mOwner = NULL; - // Temporary until all depedencies are available as component - Actor &being = static_cast<Actor &>(entity); - auto *beingComponent = entity.getComponent<BeingComponent>(); // If dead, remove it if (beingComponent->getAction() == DEAD) { if (mDecayTimeout.expired()) - GameState::enqueueRemove(static_cast<Actor*>(&entity)); + GameState::enqueueRemove(&entity); return; } @@ -153,19 +152,20 @@ void MonsterComponent::update(Entity &entity) if (entity.getComponent<CombatComponent>()->getTarget()) return; + const Point &position = + entity.getComponent<ActorComponent>()->getPosition(); + // We have no target - let's wander around if (mStrollTimeout.expired() && - being.getPosition() == beingComponent->getDestination()) + position == beingComponent->getDestination()) { if (mKillStealProtectedTimeout.expired()) { unsigned range = mSpecy->getStrollRange(); if (range) { - Point randomPos(rand() % (range * 2 + 1) - - range + being.getPosition().x, - rand() % (range * 2 + 1) - - range + being.getPosition().y); + Point randomPos(rand() % (range * 2 + 1) - range + position.x, + rand() % (range * 2 + 1) - range + position.y); // Don't allow negative destinations, to avoid rounding // problems when divided by tile size if (randomPos.x >= 0 && randomPos.y >= 0) @@ -178,8 +178,6 @@ void MonsterComponent::update(Entity &entity) void MonsterComponent::refreshTarget(Entity &entity) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast<Actor &>(entity); auto *beingComponent = entity.getComponent<BeingComponent>(); // We are dead and sadly not possible to keep attacking :( @@ -188,7 +186,7 @@ void MonsterComponent::refreshTarget(Entity &entity) // Check potential attack positions int bestTargetPriority = 0; - Actor *bestTarget = 0; + Entity *bestTarget = 0; Point bestAttackPosition; // reset Target. We will find a new one if possible @@ -196,7 +194,7 @@ void MonsterComponent::refreshTarget(Entity &entity) // Iterate through objects nearby int aroundArea = Configuration::getValue("game_visualRange", 448); - for (BeingIterator i(entity.getMap()->getAroundBeingIterator(&actor, + for (BeingIterator i(entity.getMap()->getAroundBeingIterator(&entity, aroundArea)); i; ++i) { @@ -204,7 +202,7 @@ void MonsterComponent::refreshTarget(Entity &entity) if ((*i)->getType() != OBJECT_CHARACTER) continue; - Actor *target = *i; + Entity *target = *i; // Dead characters are ignored if (beingComponent->getAction() == DEAD) @@ -232,7 +230,8 @@ void MonsterComponent::refreshTarget(Entity &entity) for (std::list<AttackPosition>::iterator j = mAttackPositions.begin(); j != mAttackPositions.end(); j++) { - Point attackPosition = target->getPosition(); + Point attackPosition = + target->getComponent<ActorComponent>()->getPosition(); attackPosition.x += j->x; attackPosition.y += j->y; @@ -249,12 +248,17 @@ void MonsterComponent::refreshTarget(Entity &entity) } if (bestTarget) { + const Point &ownPosition = + entity.getComponent<ActorComponent>()->getPosition(); + const Point &targetPosition = + bestTarget->getComponent<ActorComponent>()->getPosition(); + entity.getComponent<CombatComponent>()->setTarget(bestTarget); - if (bestAttackPosition == actor.getPosition()) + if (bestAttackPosition == ownPosition) { beingComponent->setAction(entity, ATTACK); - beingComponent->updateDirection(actor, actor.getPosition(), - bestTarget->getPosition()); + beingComponent->updateDirection(entity, ownPosition, + targetPosition); } else { @@ -267,10 +271,7 @@ int MonsterComponent::calculatePositionPriority(Entity &entity, Point position, int targetPriority) { - // Temporary until all depedencies are available as component - Actor &actor = static_cast<Actor &>(entity); - - Point thisPos = actor.getPosition(); + Point thisPos = entity.getComponent<ActorComponent>()->getPosition(); unsigned range = mSpecy->getTrackRange(); @@ -288,7 +289,7 @@ int MonsterComponent::calculatePositionPriority(Entity &entity, Path path; path = map->findPath(thisPos.x / tileWidth, thisPos.y / tileHeight, position.x / tileWidth, position.y / tileHeight, - actor.getWalkMask(), + entity.getComponent<ActorComponent>()->getWalkMask(), range); if (path.empty() || path.size() >= range) @@ -303,19 +304,17 @@ int MonsterComponent::calculatePositionPriority(Entity &entity, void MonsterComponent::forgetTarget(Entity *entity) { - Entity *b = static_cast< Entity * >(entity); { - AggressionInfo &aggressionInfo = mAnger[b]; + AggressionInfo &aggressionInfo = mAnger[entity]; aggressionInfo.removedConnection.disconnect(); aggressionInfo.diedConnection.disconnect(); } - mAnger.erase(b); + mAnger.erase(entity); - if (b->getType() == OBJECT_CHARACTER) + if (entity->getType() == OBJECT_CHARACTER) { - Entity *c = static_cast< Entity * >(b); - mExpReceivers.erase(c); - mLegalExpReceivers.erase(c); + mExpReceivers.erase(entity); + mLegalExpReceivers.erase(entity); } } @@ -360,9 +359,6 @@ std::map<Entity *, int> MonsterComponent::getAngerList() const void MonsterComponent::monsterDied(Entity *monster) { - // Temporary until all depdencies are available as component - Actor *actor = static_cast<Actor *>(monster); - mDecayTimeout.set(DECAY_TIME); if (mExpReceivers.size() > 0) @@ -376,9 +372,10 @@ void MonsterComponent::monsterDied(Entity *monster) if (p <= drop.probability) { - Actor *item = Item::create(monster->getMap(), - actor->getPosition(), - drop.item, 1); + const Point &position = + monster->getComponent<ActorComponent>()->getPosition(); + Entity *item = Item::create(monster->getMap(), position, + drop.item, 1); GameState::enqueueInsert(item); } } diff --git a/src/game-server/monster.h b/src/game-server/monster.h index 1b17bfd6..d28ec577 100644 --- a/src/game-server/monster.h +++ b/src/game-server/monster.h @@ -280,7 +280,7 @@ class MonsterComponent : public Component /** Time in game ticks until ownership of a monster can change. */ static const int KILLSTEAL_PROTECTION_TIME = 100; - MonsterComponent(Actor &actor, MonsterClass *); + MonsterComponent(Entity &entity, MonsterClass *); ~MonsterComponent(); /** diff --git a/src/game-server/npc.cpp b/src/game-server/npc.cpp index f9e714b9..7806e510 100644 --- a/src/game-server/npc.cpp +++ b/src/game-server/npc.cpp @@ -99,8 +99,9 @@ void Npc::start(Entity *npc, Entity *ch) script->prepare(talkCallback); script->push(npc); script->push(ch); - ch->getComponent<CharacterComponent>() - ->startNpcThread(thread, static_cast<Actor*>(npc)->getPublicID()); + auto *actorComponent = npc->getComponent<ActorComponent>(); + ch->getComponent<CharacterComponent>()->startNpcThread( + thread, actorComponent->getPublicID()); } } diff --git a/src/game-server/spawnareacomponent.cpp b/src/game-server/spawnareacomponent.cpp index 843371a7..afc86666 100644 --- a/src/game-server/spawnareacomponent.cpp +++ b/src/game-server/spawnareacomponent.cpp @@ -67,7 +67,9 @@ void SpawnAreaComponent::update(Entity &entity) const int width = mZone.w; const int height = mZone.h; - Actor *being = new Actor(OBJECT_MONSTER); + Entity *being = new Entity(OBJECT_MONSTER); + auto *actorComponent = new ActorComponent(*being); + being->addComponent(actorComponent); auto *beingComponent = new BeingComponent(*being); being->addComponent(beingComponent); being->addComponent(new MonsterComponent(*being, mSpecy)); @@ -88,7 +90,7 @@ void SpawnAreaComponent::update(Entity &entity) } while (!realMap->getWalk(position.x / realMap->getTileWidth(), position.y / realMap->getTileHeight(), - being->getWalkMask()) + actorComponent->getWalkMask()) && triesLeft); if (triesLeft) @@ -97,7 +99,7 @@ void SpawnAreaComponent::update(Entity &entity) sigc::mem_fun(this, &SpawnAreaComponent::decrease)); being->setMap(map); - being->setPosition(position); + actorComponent->setPosition(*being, position); beingComponent->clearDestination(*being); GameState::enqueueInsert(being); diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 87213f61..10869669 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -59,7 +59,7 @@ struct DelayedEvent MapComposite *map; }; -typedef std::map< Actor *, DelayedEvent > DelayedEvents; +typedef std::map< Entity *, DelayedEvent > DelayedEvents; /** * The current world time in ticks since server start. @@ -128,26 +128,28 @@ static void serializeLooks(Entity *ch, MessageOut &msg) /** * Informs a player of what happened around the character. */ -static void informPlayer(MapComposite *map, Actor *p) +static void informPlayer(MapComposite *map, Entity *p) { MessageOut moveMsg(GPMSG_BEINGS_MOVE); MessageOut damageMsg(GPMSG_BEINGS_DAMAGE); const Point &pold = p->getComponent<BeingComponent>()->getOldPosition(); - const Point &ppos = p->getPosition(); - int pid = p->getPublicID(), pflags = p->getUpdateFlags(); + const Point &ppos = p->getComponent<ActorComponent>()->getPosition(); + int pid = p->getComponent<ActorComponent>()->getPublicID(); + int pflags = p->getComponent<ActorComponent>()->getUpdateFlags(); int visualRange = Configuration::getValue("game_visualRange", 448); // Inform client about activities of other beings near its character for (BeingIterator it(map->getAroundBeingIterator(p, visualRange)); it; ++it) { - Actor *o = *it; + Entity *o = *it; const Point &oold = o->getComponent<BeingComponent>()->getOldPosition(); - const Point &opos = o->getPosition(); + const Point &opos = o->getComponent<ActorComponent>()->getPosition(); int otype = o->getType(); - int oid = o->getPublicID(), oflags = o->getUpdateFlags(); + int oid = o->getComponent<ActorComponent>()->getPublicID(); + int oflags = o->getComponent<ActorComponent>()->getUpdateFlags(); int flags = 0; // Check if the character p and the moving object o are around. @@ -350,7 +352,7 @@ static void informPlayer(MapComposite *map, Actor *p) // Inform client about health change of party members for (CharacterIterator i(map->getWholeMapIterator()); i; ++i) { - Actor *c = *i; + Entity *c = *i; // Make sure its not the same character if (c == p) @@ -360,13 +362,14 @@ static void informPlayer(MapComposite *map, Actor *p) if (c->getComponent<CharacterComponent>()->getParty() == p->getComponent<CharacterComponent>()->getParty()) { - int cflags = c->getUpdateFlags(); + int cflags = c->getComponent<ActorComponent>()->getUpdateFlags(); if (cflags & UPDATEFLAG_HEALTHCHANGE) { auto *beingComponent = c->getComponent<BeingComponent>(); MessageOut healthMsg(GPMSG_BEING_HEALTH_CHANGE); - healthMsg.writeInt16(c->getPublicID()); + healthMsg.writeInt16( + c->getComponent<ActorComponent>()->getPublicID()); healthMsg.writeInt16( beingComponent->getModifiedAttribute(ATTR_HP)); healthMsg.writeInt16( @@ -381,13 +384,13 @@ static void informPlayer(MapComposite *map, Actor *p) for (FixedActorIterator it(map->getAroundBeingIterator(p, visualRange)); it; ++it) { - Actor *o = static_cast<Actor *>(*it); + Entity *o = *it; assert(o->getType() == OBJECT_ITEM || o->getType() == OBJECT_EFFECT); - Point opos = o->getPosition(); - int oflags = o->getUpdateFlags(); + Point opos = o->getComponent<ActorComponent>()->getPosition(); + int oflags = o->getComponent<ActorComponent>()->getUpdateFlags(); bool willBeInRange = ppos.inRangeOf(opos, visualRange); bool wereInRange = pold.inRangeOf(opos, visualRange) && !((pflags | oflags) & UPDATEFLAG_NEW_ON_MAP); @@ -429,10 +432,11 @@ static void informPlayer(MapComposite *map, Actor *p) if (Entity *b = e->getBeing()) { + auto *actorComponent = + b->getComponent<ActorComponent>(); MessageOut effectMsg(GPMSG_CREATE_EFFECT_BEING); effectMsg.writeInt16(e->getEffectId()); - effectMsg.writeInt16(static_cast<Actor*>(b) - ->getPublicID()); + effectMsg.writeInt16(actorComponent->getPublicID()); gameHandler->sendTo(p, effectMsg); } else { MessageOut effectMsg(GPMSG_CREATE_EFFECT_POS); @@ -485,8 +489,8 @@ void GameState::update(int tick) for (ActorIterator it(map->getWholeMapIterator()); it; ++it) { - Actor *a = *it; - a->clearUpdateFlags(); + Entity *a = *it; + a->getComponent<ActorComponent>()->clearUpdateFlags(); if (a->canFight()) { a->getComponent<CombatComponent>()->clearHitsTaken(); @@ -503,7 +507,7 @@ void GameState::update(int tick) it_end = delayedEvents.end(); it != it_end; ++it) { const DelayedEvent &e = it->second; - Actor *o = it->first; + Entity *o = it->first; switch (e.type) { case EVENT_REMOVE: @@ -545,9 +549,9 @@ bool GameState::insert(Entity *ptr) } // Check that coordinates are actually valid. - Actor *obj = static_cast< Actor * >(ptr); + Entity *obj = static_cast< Entity * >(ptr); Map *mp = map->getMap(); - Point pos = obj->getPosition(); + Point pos = obj->getComponent<ActorComponent>()->getPosition(); if ((int)pos.x / mp->getTileWidth() >= mp->getWidth() || (int)pos.y / mp->getTileHeight() >= mp->getHeight()) { @@ -555,7 +559,7 @@ bool GameState::insert(Entity *ptr) << pos.y << " outside map " << map->getID() << '.'); // Set an arbitrary small position. pos = Point(100, 100); - obj->setPosition(pos); + obj->getComponent<ActorComponent>()->setPosition(*ptr, pos); } if (!map->insert(obj)) @@ -604,7 +608,8 @@ bool GameState::insert(Entity *ptr) break; } - obj->raiseUpdateFlags(UPDATEFLAG_NEW_ON_MAP); + obj->getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_NEW_ON_MAP); if (obj->getType() != OBJECT_CHARACTER) return true; @@ -694,15 +699,15 @@ void GameState::remove(Entity *ptr) characterComponent->getDatabaseID(), false); } - Actor *obj = static_cast< Actor * >(ptr); MessageOut msg(GPMSG_BEING_LEAVE); - msg.writeInt16(obj->getPublicID()); - Point objectPos = obj->getPosition(); + msg.writeInt16(ptr->getComponent<ActorComponent>()->getPublicID()); + Point objectPos = ptr->getComponent<ActorComponent>()->getPosition(); - for (CharacterIterator p(map->getAroundActorIterator(obj, visualRange)); + for (CharacterIterator p(map->getAroundActorIterator(ptr, visualRange)); p; ++p) { - if (*p != obj && objectPos.inRangeOf((*p)->getPosition(), + if (*p != ptr && objectPos.inRangeOf( + (*p)->getComponent<ActorComponent>()->getPosition(), visualRange)) { gameHandler->sendTo(*p, msg); @@ -711,16 +716,17 @@ void GameState::remove(Entity *ptr) } else if (ptr->getType() == OBJECT_ITEM) { - Actor *actor = static_cast<Actor*>(ptr); - Point pos = actor->getPosition(); + Point pos = ptr->getComponent<ActorComponent>()->getPosition(); MessageOut msg(GPMSG_ITEMS); msg.writeInt16(0); msg.writeInt16(pos.x); msg.writeInt16(pos.y); - for (CharacterIterator p(map->getAroundActorIterator(actor, visualRange)); p; ++p) + for (CharacterIterator p(map->getAroundActorIterator(ptr, visualRange)); p; ++p) { - if (pos.inRangeOf((*p)->getPosition(), visualRange)) + const Point &point = + (*p)->getComponent<ActorComponent>()->getPosition(); + if (pos.inRangeOf(point, visualRange)) { gameHandler->sendTo(*p, msg); } @@ -734,10 +740,8 @@ void GameState::warp(Entity *ptr, MapComposite *map, const Point &point) { remove(ptr); - Actor *actor = static_cast<Actor *>(ptr); - ptr->setMap(map); - actor->setPosition(point); + ptr->getComponent<ActorComponent>()->setPosition(*ptr, point); ptr->getComponent<BeingComponent>()->clearDestination(*ptr); /* Force update of persistent data on map change, so that characters can respawn at the start of the map after a death or @@ -773,7 +777,7 @@ void GameState::warp(Entity *ptr, MapComposite *map, const Point &point) /** * Enqueues an event. It will be executed at end of update. */ -static void enqueueEvent(Actor *ptr, const DelayedEvent &e) +static void enqueueEvent(Entity *ptr, const DelayedEvent &e) { std::pair< DelayedEvents::iterator, bool > p = delayedEvents.insert(std::make_pair(ptr, e)); @@ -784,7 +788,7 @@ static void enqueueEvent(Actor *ptr, const DelayedEvent &e) } } -void GameState::enqueueInsert(Actor *ptr) +void GameState::enqueueInsert(Entity *ptr) { DelayedEvent event; event.type = EVENT_INSERT; @@ -792,7 +796,7 @@ void GameState::enqueueInsert(Actor *ptr) enqueueEvent(ptr, event); } -void GameState::enqueueRemove(Actor *ptr) +void GameState::enqueueRemove(Entity *ptr) { DelayedEvent event; event.type = EVENT_REMOVE; @@ -816,24 +820,26 @@ void GameState::enqueueWarp(Entity *ptr, event.type = EVENT_WARP; event.point = point; event.map = map; - enqueueEvent(static_cast<Actor *>(ptr), event); + enqueueEvent(ptr, event); } -void GameState::sayAround(Actor *obj, const std::string &text) +void GameState::sayAround(Entity *obj, const std::string &text) { - Point speakerPosition = obj->getPosition(); + Point speakerPosition = obj->getComponent<ActorComponent>()->getPosition(); int visualRange = Configuration::getValue("game_visualRange", 448); for (CharacterIterator i(obj->getMap()->getAroundActorIterator(obj, visualRange)); i; ++i) { - if (speakerPosition.inRangeOf((*i)->getPosition(), visualRange)) + const Point &point = + (*i)->getComponent<ActorComponent>()->getPosition(); + if (speakerPosition.inRangeOf(point, visualRange)) { sayTo(*i, obj, text); } } } -void GameState::sayTo(Actor *destination, Actor *source, const std::string &text) +void GameState::sayTo(Entity *destination, Entity *source, const std::string &text) { if (destination->getType() != OBJECT_CHARACTER) return; //only characters will read it anyway @@ -849,7 +855,7 @@ void GameState::sayTo(Actor *destination, Actor *source, const std::string &text } else { - msg.writeInt16(static_cast< Actor * >(source)->getPublicID()); + msg.writeInt16(source->getComponent<ActorComponent>()->getPublicID()); } msg.writeString(text); diff --git a/src/game-server/state.h b/src/game-server/state.h index becfd597..4f690ad0 100644 --- a/src/game-server/state.h +++ b/src/game-server/state.h @@ -25,7 +25,6 @@ #include <string> -class Actor; class Entity; class ItemClass; class MapComposite; @@ -76,14 +75,14 @@ namespace GameState * Enqueues an insert event. * @note The event will be executed at end of update. */ - void enqueueInsert(Actor *); + void enqueueInsert(Entity *); /** * Enqueues a remove event. * @note The event will be executed at end of update. * @note The entity will be destroyed at that time. */ - void enqueueRemove(Actor *); + void enqueueRemove(Entity *); /** * Enqueues a warp event. @@ -95,12 +94,12 @@ namespace GameState * Says something to an actor. * @note passing NULL as source generates a message from "Server:" */ - void sayTo(Actor *destination, Actor *source, const std::string &text); + void sayTo(Entity *destination, Entity *source, const std::string &text); /** * Says something to everything around an actor. */ - void sayAround(Actor *, const std::string &text); + void sayAround(Entity *, const std::string &text); /** * Says something to every player on the server. diff --git a/src/game-server/trade.cpp b/src/game-server/trade.cpp index 1d863137..3fbcd0e6 100644 --- a/src/game-server/trade.cpp +++ b/src/game-server/trade.cpp @@ -41,7 +41,7 @@ Trade::Trade(Entity *c1, Entity *c2): mChar1(c1), mChar2(c2), mMoney1(0), mMoney2(0), mState(TRADE_INIT), mCurrencyId(ATTR_GP) { MessageOut msg(GPMSG_TRADE_REQUEST); - msg.writeInt16(static_cast<Actor *>(c1)->getPublicID()); + msg.writeInt16(c1->getComponent<ActorComponent>()->getPublicID()); c2->getComponent<CharacterComponent>()->getClient()->send(msg); c1->getComponent<CharacterComponent>()->setTrading(this); c2->getComponent<CharacterComponent>()->setTrading(this); @@ -65,7 +65,7 @@ bool Trade::request(Entity *c, int id) { //The trade isn't confirmed, the player which is request is the same. if (mState != TRADE_INIT || c != mChar2 || - static_cast<Actor *>(mChar1)->getPublicID() != id) + mChar1->getComponent<ActorComponent>()->getPublicID() != id) { /* This is not an ack for the current transaction. So assume a new one is about to start and cancel the current one. */ diff --git a/src/game-server/triggerareacomponent.cpp b/src/game-server/triggerareacomponent.cpp index 224b17f9..e9354901 100644 --- a/src/game-server/triggerareacomponent.cpp +++ b/src/game-server/triggerareacomponent.cpp @@ -30,7 +30,7 @@ #include <cassert> -void WarpAction::process(Actor *obj) +void WarpAction::process(Entity *obj) { if (obj->getType() == OBJECT_CHARACTER) { @@ -46,7 +46,7 @@ ScriptAction::ScriptAction(Script *script, Script::Ref callback, int arg) : assert(mCallback.isValid()); } -void ScriptAction::process(Actor *obj) +void ScriptAction::process(Entity *obj) { LOG_DEBUG("Script trigger area activated: " << "(" << obj << ", " << mArg << ")"); @@ -62,19 +62,21 @@ const ComponentType TriggerAreaComponent::type; void TriggerAreaComponent::update(Entity &entity) { MapComposite *map = entity.getMap(); - std::set<Actor*> insideNow; + std::set<Entity *> insideNow; for (BeingIterator i(map->getInsideRectangleIterator(mZone)); i; ++i) { // Don't deal with uninitialized actors - if (!(*i) || !(*i)->isPublicIdValid()) + if (!(*i) || !(*i)->getComponent<ActorComponent>()->isPublicIdValid()) continue; // The BeingIterator returns the mapZones in touch with the rectangle // area. On the other hand, the beings contained in the map zones // may not be within the rectangle area. Hence, this additional // contains() condition. - if (mZone.contains((*i)->getPosition())) + const Point &point = + (*i)->getComponent<ActorComponent>()->getPosition(); + if (mZone.contains(point)) { insideNow.insert(*i); diff --git a/src/game-server/triggerareacomponent.h b/src/game-server/triggerareacomponent.h index 6c2df7d1..3d2a8412 100644 --- a/src/game-server/triggerareacomponent.h +++ b/src/game-server/triggerareacomponent.h @@ -28,13 +28,13 @@ #include <set> -class Actor; +class Entity; class TriggerAction { public: virtual ~TriggerAction() {} - virtual void process(Actor *obj) = 0; + virtual void process(Entity *obj) = 0; }; class WarpAction : public TriggerAction @@ -43,7 +43,7 @@ class WarpAction : public TriggerAction WarpAction(MapComposite *m, const Point &point) : mMap(m), mTargetPoint(point) {} - virtual void process(Actor *obj); + virtual void process(Entity *obj); private: MapComposite *mMap; @@ -55,7 +55,7 @@ class ScriptAction : public TriggerAction public: ScriptAction(Script *script, Script::Ref callback, int arg); - virtual void process(Actor *obj); + virtual void process(Entity *obj); private: Script *mScript; // Script object to be called @@ -85,7 +85,7 @@ class TriggerAreaComponent : public Component Rectangle mZone; TriggerAction *mAction; bool mOnce; - std::set<Actor *> mInside; + std::set<Entity *> mInside; }; #endif // TRIGGERAREACOMPONENT_H diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 39fc3e8b..66496f8e 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -283,7 +283,9 @@ static int npc_create(lua_State *s) NpcComponent *npcComponent = new NpcComponent(id); - Actor *npc = new Actor(OBJECT_NPC); + Entity *npc = new Entity(OBJECT_NPC); + auto *actorComponent = new ActorComponent(*npc); + npc->addComponent(actorComponent); auto *beingComponent = new BeingComponent(*npc); npc->addComponent(beingComponent); npc->addComponent(npcComponent); @@ -293,10 +295,10 @@ static int npc_create(lua_State *s) beingComponent->setName(name); beingComponent->setGender(getGender(gender)); - npc->setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_MONSTER | - Map::BLOCKMASK_CHARACTER); + actorComponent->setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_MONSTER | + Map::BLOCKMASK_CHARACTER); npc->setMap(m); - npc->setPosition(Point(x, y)); + actorComponent->setPosition(*npc, Point(x, y)); if (lua_isfunction(s, 6)) { @@ -324,7 +326,7 @@ static int npc_enable(lua_State *s) { Entity *npc = checkNpc(s, 1); npc->getComponent<NpcComponent>()->setEnabled(true); - GameState::enqueueInsert(static_cast<Actor *>(npc)); + GameState::enqueueInsert(npc); return 0; } @@ -357,11 +359,13 @@ static int monster_create(lua_State *s) const int y = luaL_checkint(s, 3); MapComposite *m = checkCurrentMap(s); - Actor *monster = new Actor(OBJECT_MONSTER); + Entity *monster = new Entity(OBJECT_MONSTER); + auto *actorComponent = new ActorComponent(*monster); + monster->addComponent(actorComponent); monster->addComponent(new BeingComponent(*monster)); monster->addComponent(new MonsterComponent(*monster, monsterClass)); monster->setMap(m); - monster->setPosition(Point(x, y)); + actorComponent->setPosition(*monster, Point(x, y)); GameState::enqueueInsert(monster); lua_pushlightuserdata(s, monster); @@ -458,7 +462,7 @@ static int effect_create(lua_State *s) { // being mode Entity *b = checkBeing(s, 2); - Effects::show(id, static_cast<Actor *>(b)); + Effects::show(id, b); } else { @@ -486,7 +490,7 @@ static int item_drop(lua_State *s) const int number = luaL_optint(s, 4, 1); MapComposite *map = checkCurrentMap(s); - Actor *item = Item::create(map, Point(x, y), ic, number); + Entity *item = Item::create(map, Point(x, y), ic, number); GameState::enqueueInsert(item); return 0; } @@ -511,7 +515,7 @@ static int npc_message(lua_State *s) Script::Thread *thread = checkCurrentThread(s); MessageOut msg(GPMSG_NPC_MESSAGE); - msg.writeInt16(static_cast<Actor *>(npc)->getPublicID()); + msg.writeInt16(npc->getComponent<ActorComponent>()->getPublicID()); msg.writeString(m); gameHandler->sendTo(q, msg); @@ -543,7 +547,7 @@ static int npc_choice(lua_State *s) Script::Thread *thread = checkCurrentThread(s); MessageOut msg(GPMSG_NPC_CHOICE); - msg.writeInt16(static_cast<Actor *>(npc)->getPublicID()); + msg.writeInt16(npc->getComponent<ActorComponent>()->getPublicID()); for (int i = 3, i_end = lua_gettop(s); i <= i_end; ++i) { if (lua_isstring(s, i)) @@ -602,7 +606,7 @@ static int npc_ask_integer(lua_State *s) Script::Thread *thread = checkCurrentThread(s); MessageOut msg(GPMSG_NPC_NUMBER); - msg.writeInt16(static_cast<Actor *>(npc)->getPublicID()); + msg.writeInt16(npc->getComponent<ActorComponent>()->getPublicID()); msg.writeInt32(min); msg.writeInt32(max); msg.writeInt32(defaultValue); @@ -629,7 +633,7 @@ static int npc_ask_string(lua_State *s) Script::Thread *thread = checkCurrentThread(s); MessageOut msg(GPMSG_NPC_STRING); - msg.writeInt16(static_cast<Actor *>(npc)->getPublicID()); + msg.writeInt16(npc->getComponent<ActorComponent>()->getPublicID()); gameHandler->sendTo(q, msg); thread->mState = Script::ThreadExpectingString; @@ -647,7 +651,7 @@ static int npc_post(lua_State *s) Entity *q = checkCharacter(s, 2); MessageOut msg(GPMSG_NPC_POST); - msg.writeInt16(static_cast<Actor *>(npc)->getPublicID()); + msg.writeInt16(npc->getComponent<ActorComponent>()->getPublicID()); gameHandler->sendTo(q, msg); return 0; @@ -663,7 +667,7 @@ static int being_say(lua_State *s) { Entity *being = checkBeing(s, 1); const char *message = luaL_checkstring(s, 2); - GameState::sayAround(static_cast<Actor *>(being), message); + GameState::sayAround(being, message); return 0; } @@ -678,7 +682,7 @@ static int chat_message(lua_State *s) Entity *being = checkBeing(s, 1); const char *message = luaL_checkstring(s, 2); - GameState::sayTo(static_cast<Actor *>(being), nullptr, message); + GameState::sayTo(being, nullptr, message); return 0; } @@ -779,7 +783,7 @@ static int npc_trade(lua_State *s) } bool sellMode = lua_toboolean(s, 3); - BuySell *t = new BuySell(static_cast<Actor *>(q), sellMode); + BuySell *t = new BuySell(q, sellMode); if (!lua_istable(s, 4)) { if (sellMode) @@ -793,7 +797,7 @@ static int npc_trade(lua_State *s) return 1; } - if (t->start(static_cast<Actor *>(npc))) + if (t->start(npc)) { lua_pushinteger(s, 0); return 1; @@ -871,7 +875,7 @@ static int npc_trade(lua_State *s) lua_pushinteger(s, 1); return 1; } - if (t->start(static_cast<Actor *>(npc))) + if (t->start(npc)) { lua_pushinteger(s, 0); return 1; @@ -969,9 +973,9 @@ static int chr_inv_change(lua_State *s) nb = inv.insert(id, nb); if (nb) { - Actor *item = Item::create(q->getMap(), static_cast<Actor *>(q) - ->getPosition(), - ic, nb); + const Point &position = + q->getComponent<ActorComponent>()->getPosition(); + Entity *item = Item::create(q->getMap(), position, ic, nb); GameState::enqueueInsert(item); } } @@ -1591,7 +1595,7 @@ static int being_set_walkmask(lua_State *s) mask |= Map::BLOCKMASK_CHARACTER; else if (strchr(stringMask, 'm')) mask |= Map::BLOCKMASK_MONSTER; - static_cast<Actor *>(being)->setWalkMask(mask); + being->getComponent<ActorComponent>()->setWalkMask(mask); return 0; } @@ -1604,7 +1608,8 @@ static int being_set_walkmask(lua_State *s) static int being_get_walkmask(lua_State *s) { Entity *being = checkBeing(s, 1); - const unsigned char mask = static_cast<Actor *>(being)->getWalkMask(); + const unsigned char mask = + being->getComponent<ActorComponent>()->getWalkMask(); luaL_Buffer buffer; luaL_buffinit(s, &buffer); if (mask & Map::BLOCKMASK_WALL) @@ -1683,7 +1688,7 @@ static int chr_warp(lua_State *s) static int posX(lua_State *s) { Entity *being = checkBeing(s, 1); - lua_pushinteger(s, static_cast<Actor *>(being)->getPosition().x); + lua_pushinteger(s, being->getComponent<ActorComponent>()->getPosition().x); return 1; } @@ -1696,7 +1701,7 @@ static int posX(lua_State *s) static int posY(lua_State *s) { Entity *being = checkBeing(s, 1); - lua_pushinteger(s, static_cast<Actor *>(being)->getPosition().y); + lua_pushinteger(s, being->getComponent<ActorComponent>()->getPosition().y); return 1; } @@ -1956,7 +1961,8 @@ static int chr_set_hair_color(lua_State *s) luaL_argcheck(s, color >= 0, 2, "invalid color id"); c->getComponent<CharacterComponent>()->setHairColor(color); - static_cast<Actor *>(c)->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); + c->getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_LOOKSCHANGE); return 0; } @@ -1986,7 +1992,8 @@ static int chr_set_hair_style(lua_State *s) luaL_argcheck(s, style >= 0, 2, "invalid style id"); c->getComponent<CharacterComponent>()->setHairStyle(style); - static_cast<Actor *>(c)->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); + c->getComponent<ActorComponent>()->raiseUpdateFlags( + UPDATEFLAG_LOOKSCHANGE); return 0; } @@ -2686,7 +2693,7 @@ static int get_beings_in_circle(lua_State *s) if (lua_islightuserdata(s, 1)) { Entity *b = checkBeing(s, 1); - const Point &pos = static_cast<Actor *>(b)->getPosition(); + const Point &pos = b->getComponent<ActorComponent>()->getPosition(); x = pos.x; y = pos.y; r = luaL_checkint(s, 2); @@ -2710,9 +2717,9 @@ static int get_beings_in_circle(lua_State *s) char t = b->getType(); if (t == OBJECT_NPC || t == OBJECT_CHARACTER || t == OBJECT_MONSTER) { - Actor *actor = static_cast<Actor *>(b); - if (Collision::circleWithCircle(actor->getPosition(), - actor->getSize(), + auto *actorComponent = b->getComponent<ActorComponent>(); + if (Collision::circleWithCircle(actorComponent->getPosition(), + actorComponent->getSize(), Point(x, y), r)) { lua_pushlightuserdata(s, b); @@ -2750,7 +2757,7 @@ static int get_beings_in_rectangle(lua_State *s) Entity *b = *i; char t = b->getType(); if ((t == OBJECT_NPC || t == OBJECT_CHARACTER || t == OBJECT_MONSTER) && - rect.contains(static_cast<Actor *>(b)->getPosition())) + rect.contains(b->getComponent<ActorComponent>()->getPosition())) { lua_pushlightuserdata(s, b); lua_rawseti(s, tableStackPosition, tableIndex); @@ -2772,13 +2779,13 @@ static int get_distance(lua_State *s) int x1, y1, x2, y2; if (lua_gettop(s) == 2) { - Actor *being1 = static_cast<Actor *>(checkBeing(s, 1)); - Actor *being2 = static_cast<Actor *>(checkBeing(s, 2)); + Entity *being1 = checkBeing(s, 1); + Entity *being2 = checkBeing(s, 2); - x1 = being1->getPosition().x; - y1 = being1->getPosition().y; - x2 = being2->getPosition().x; - y2 = being2->getPosition().y; + x1 = being1->getComponent<ActorComponent>()->getPosition().x; + y1 = being1->getComponent<ActorComponent>()->getPosition().y; + x2 = being2->getComponent<ActorComponent>()->getPosition().x; + y2 = being2->getComponent<ActorComponent>()->getPosition().y; } else { |