diff options
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 { |