From 7aee56f062989c8901322a09b2da40bb028eb222 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Sun, 18 Mar 2012 22:24:38 +0100 Subject: Changed Item to a component of Actor Items also have positions, so the ItemComponent only makes sense as part of an Actor. Later on it will probably be part of an entity that also has an ActorComponent. Since it was annoying to update all the places where items were created, I've introduced a function for this. The component types are now prefixed with "CT_" because I wanted to introduce an 'Item' namespace which would otherwise be conflicting. The component types enum isn't used much in the code so it can look a bit ugly. Reviewed-by: Yohann Ferreira --- src/game-server/commandhandler.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/game-server/commandhandler.cpp') diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index 6de22242..ad6a1bc2 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -568,11 +568,11 @@ static void handleItem(Character *player, std::string &args) static void handleDrop(Character *player, std::string &args) { ItemClass *ic; - int value = 0; + int amount = 0; // get arguments std::string itemclass = getArgument(args); - std::string valuestr = getArgument(args); + std::string amountstr = getArgument(args); // check all arguments are there if (itemclass.empty()) @@ -598,26 +598,26 @@ static void handleDrop(Character *player, std::string &args) return; } - //identify the amount - if (valuestr.empty()) + // identify the amount + if (amountstr.empty()) { - value = 1; + amount = 1; } - else if (utils::isNumeric(valuestr)) + else if (utils::isNumeric(amountstr)) { - value = utils::stringToInt(valuestr); + amount = utils::stringToInt(amountstr); } // check for valid amount - if (value <= 0) + if (amount <= 0) { say("Invalid number of items", player); return; } - // create the integer and put it on the map - Item *item = new Item(ic, value); - item->setMap(player->getMap()); - item->setPosition(player->getPosition()); + Entity *item = Item::create(player->getMap(), + player->getPosition(), + ic, amount); + GameState::insertOrDelete(item); // log transaction -- cgit v1.2.3-70-g09d2 From 7aeb3b4a6c34a8f679719c207e51394d7e48828b Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Mon, 19 Mar 2012 22:09:25 +0100 Subject: Changed Effect to a component of Actor Reviewed-by: Yohann Ferreira --- src/game-server/commandhandler.cpp | 6 ++--- src/game-server/component.h | 1 + src/game-server/effect.cpp | 30 +++++++++++++++++-------- src/game-server/effect.h | 41 +++++++++++++++------------------- src/game-server/item.cpp | 7 +++--- src/game-server/item.h | 2 +- src/game-server/state.cpp | 23 ++++++++++--------- src/game-server/triggerareacomponent.h | 2 +- src/scripting/lua.cpp | 2 +- 9 files changed, 61 insertions(+), 53 deletions(-) (limited to 'src/game-server/commandhandler.cpp') diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index ad6a1bc2..001f65f6 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -171,7 +171,7 @@ static CmdRef const cmdRef[] = }; -static void say(const std::string message, Character *player) +static void say(const std::string &message, Character *player) { GameState::sayTo(player, NULL, message); } @@ -1500,7 +1500,7 @@ static void handleEffect(Character *player, std::string &args) if (arguments.size() == 1) { int id = utils::stringToInt(arguments[0]); - Effects::show(id, player->getMap(), player); + Effects::show(id, player); } else if (arguments.size() == 2) { @@ -1511,7 +1511,7 @@ static void handleEffect(Character *player, std::string &args) say("Invalid target player.", player); return; } - Effects::show(id, p->getMap(), 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 fd477b90..90dda5a5 100644 --- a/src/game-server/component.h +++ b/src/game-server/component.h @@ -25,6 +25,7 @@ class Entity; enum ComponentType { + CT_Effect, CT_TriggerArea, CT_SpawnArea, CT_Item, diff --git a/src/game-server/effect.cpp b/src/game-server/effect.cpp index b7c6c643..f994ec77 100644 --- a/src/game-server/effect.cpp +++ b/src/game-server/effect.cpp @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2004-2010 The Mana World Development Team + * Copyright (C) 2012 The Mana Developers * * This file is part of The Mana Server. * @@ -20,29 +21,40 @@ #include "game-server/effect.h" -#include "game-server/mapcomposite.h" +#include "game-server/being.h" +#include "game-server/entity.h" #include "game-server/state.h" -void Effect::update() +const ComponentType EffectComponent::type; + +void EffectComponent::update(Entity &entity) { if (mHasBeenShown) - GameState::enqueueRemove(this); + GameState::enqueueRemove(static_cast(&entity)); } namespace Effects { void show(int id, MapComposite *map, const Point &pos) { - Effect *effect = new Effect(id); + Actor *effect = new Actor(OBJECT_EFFECT); + effect->addComponent(new EffectComponent(id)); effect->setMap(map); effect->setPosition(pos); + GameState::enqueueInsert(effect); } - void show(int id, MapComposite *map, Being *b) + + void show(int id, Being *b) { - Effect *effect = new Effect(id); - effect->setMap(map); - if (effect->setBeing(b)) - GameState::enqueueInsert(effect); + EffectComponent *effectComponent = new EffectComponent(id); + effectComponent->setBeing(b); + + Actor *effect = new Actor(OBJECT_EFFECT); + effect->addComponent(effectComponent); + effect->setMap(b->getMap()); + effect->setPosition(b->getPosition()); + + GameState::enqueueInsert(effect); } } diff --git a/src/game-server/effect.h b/src/game-server/effect.h index 2e22d46e..4ac63611 100644 --- a/src/game-server/effect.h +++ b/src/game-server/effect.h @@ -1,6 +1,7 @@ /* * The Mana Server * Copyright (C) 2004-2010 The Mana World Development Team + * Copyright (C) 2012 The Mana Developers * * This file is part of The Mana Server. * @@ -21,17 +22,21 @@ #ifndef EFFECT_H #define EFFECT_H -#include "game-server/actor.h" -#include "game-server/being.h" +#include "game-server/component.h" -class Effect : public Actor +class Being; +class MapComposite; +class Point; + +class EffectComponent : public Component { public: - Effect(int id) - : Actor(OBJECT_EFFECT) - , mEffectId(id) + static const ComponentType type = CT_Effect; + + EffectComponent(int id) + : mEffectId(id) , mHasBeenShown(false) - , mBeing(NULL) + , mBeing(0) {} int getEffectId() const @@ -43,26 +48,16 @@ class Effect : public Actor /** * Removes effect after it has been shown. */ - virtual void update(); + void update(Entity &entity); /** * Called when the object has been shown to a player in the state loop. */ - void show() + void setShown() { mHasBeenShown = true; } - - bool setBeing(Being *b) - { - if (b) - { - setPosition(b->getPosition()); - mBeing = b; - return true; - } else { - return false; - } - } + void setBeing(Being *b) + { mBeing = b; } private: int mEffectId; @@ -77,7 +72,7 @@ namespace Effects * Convenience methods to show an effect. */ void show(int id, MapComposite *map, const Point &pos); - void show(int id, MapComposite *map, Being *b); + void show(int id, Being *b); // TODO: get this in sync with effects.xml enum { @@ -85,4 +80,4 @@ namespace Effects }; } -#endif +#endif // EFFECT_H diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp index 44029303..b7b0d785 100644 --- a/src/game-server/item.cpp +++ b/src/game-server/item.cpp @@ -19,10 +19,6 @@ * along with The Mana Server. If not, see . */ - -#include -#include - #include "game-server/item.h" #include "common/configuration.h" @@ -33,6 +29,9 @@ #include "scripting/script.h" #include "scripting/scriptmanager.h" +#include +#include + bool ItemEffectAttrMod::apply(Being *itemUser) { LOG_DEBUG("Applying modifier."); diff --git a/src/game-server/item.h b/src/game-server/item.h index 2ce858c7..e88c1f98 100644 --- a/src/game-server/item.h +++ b/src/game-server/item.h @@ -311,7 +311,7 @@ class ItemComponent : public Component int getAmount() const { return mAmount; } - virtual void update(Entity &entity); + void update(Entity &entity); private: ItemClass *mType; diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index d84f35b2..ab0dcd79 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -355,10 +355,11 @@ static void informPlayer(MapComposite *map, Character *p) for (FixedActorIterator it(map->getAroundBeingIterator(p, visualRange)); it; ++it) { - assert((*it)->getType() == OBJECT_ITEM || - (*it)->getType() == OBJECT_EFFECT); - Actor *o = *it; + + assert(o->getType() == OBJECT_ITEM || + o->getType() == OBJECT_EFFECT); + Point opos = o->getPosition(); int oflags = o->getUpdateFlags(); bool willBeInRange = ppos.inRangeOf(opos, visualRange); @@ -394,21 +395,21 @@ static void informPlayer(MapComposite *map, Character *p) break; case OBJECT_EFFECT: { - Effect *o = static_cast< Effect * >(*it); - o->show(); + EffectComponent *e = o->getComponent(); + e->setShown(); // Don't show old effects if (!(oflags & UPDATEFLAG_NEW_ON_MAP)) break; - Being *b = o->getBeing(); - if (b) + + if (Being *b = e->getBeing()) { MessageOut effectMsg(GPMSG_CREATE_EFFECT_BEING); - effectMsg.writeInt16(o->getEffectId()); + effectMsg.writeInt16(e->getEffectId()); effectMsg.writeInt16(b->getPublicID()); gameHandler->sendTo(p, effectMsg); } else { MessageOut effectMsg(GPMSG_CREATE_EFFECT_POS); - effectMsg.writeInt16(o->getEffectId()); + effectMsg.writeInt16(e->getEffectId()); effectMsg.writeInt16(opos.x); effectMsg.writeInt16(opos.y); gameHandler->sendTo(p, effectMsg); @@ -559,7 +560,7 @@ bool GameState::insert(Entity *ptr) case OBJECT_EFFECT: LOG_DEBUG("Effect inserted: " - << static_cast(obj)->getEffectId()); + << obj->getComponent()->getEffectId()); break; case OBJECT_MONSTER: @@ -633,7 +634,7 @@ void GameState::remove(Entity *ptr) case OBJECT_EFFECT: LOG_DEBUG("Effect removed: " - << static_cast(ptr)->getEffectId()); + << ptr->getComponent()->getEffectId()); break; case OBJECT_MONSTER: diff --git a/src/game-server/triggerareacomponent.h b/src/game-server/triggerareacomponent.h index 2185d8cf..f766c815 100644 --- a/src/game-server/triggerareacomponent.h +++ b/src/game-server/triggerareacomponent.h @@ -79,7 +79,7 @@ class TriggerAreaComponent : public Component mOnce(once) {} - virtual void update(Entity &entity); + void update(Entity &entity); private: Rectangle mZone; diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 0dd6582d..705ee4c9 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -443,7 +443,7 @@ static int effect_create(lua_State *s) { // being mode Being *b = checkBeing(s, 2); - Effects::show(id, b->getMap(), b); + Effects::show(id, b); } else { -- cgit v1.2.3-70-g09d2 From 585a33e221a7ee392791f4fd5a5ec9214b8fe868 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Sat, 30 Mar 2013 09:29:08 +0100 Subject: Moved fighting code into a component All damage dealing is now handeled via CombatComponent. Monsters use a derived MonsterCombatComponent since they can have a damage mutation and have a seperate script callback. The wirering with Being is still not optional since most of the stuff does not exist as components. Things done: - Seperated the fighting code from Being and only let Characters and Monsters add the Component (less overhead for npcs) - Added a getter for Attribute values to prevent searching it all the time in non Being members - Fixed the type if the damage mutation to double (no idea why it was int) I did not want to copy it over incorrectly - Removed the addAttack/removeAttack overrides in Character and made the knuckleAttack being added based on newly added signals Future TODOS: - Remove depedency on Being as soon all needed dependencies are available as components of Entity - Move the monster script callback into the general combatcomponent and make it usuable for characters too --- gameserver.cbp | 4 + src/CMakeLists.txt | 4 + src/game-server/attack.cpp | 2 + src/game-server/attack.h | 8 +- src/game-server/being.cpp | 171 ++--------------------- src/game-server/being.h | 86 +----------- src/game-server/buysell.cpp | 6 +- src/game-server/character.cpp | 55 +++++--- src/game-server/character.h | 4 +- src/game-server/combatcomponent.cpp | 213 +++++++++++++++++++++++++++++ src/game-server/combatcomponent.h | 144 +++++++++++++++++++ src/game-server/commandhandler.cpp | 2 +- src/game-server/component.h | 1 + src/game-server/gamehandler.cpp | 3 +- src/game-server/item.cpp | 5 +- src/game-server/mapcomposite.cpp | 5 +- src/game-server/monster.cpp | 117 +++++----------- src/game-server/monster.h | 15 +- src/game-server/monstercombatcomponent.cpp | 99 ++++++++++++++ src/game-server/monstercombatcomponent.h | 54 ++++++++ src/game-server/state.cpp | 14 +- src/game-server/trade.cpp | 8 +- src/scripting/lua.cpp | 5 +- 23 files changed, 651 insertions(+), 374 deletions(-) create mode 100644 src/game-server/combatcomponent.cpp create mode 100644 src/game-server/combatcomponent.h create mode 100644 src/game-server/monstercombatcomponent.cpp create mode 100644 src/game-server/monstercombatcomponent.h (limited to 'src/game-server/commandhandler.cpp') diff --git a/gameserver.cbp b/gameserver.cbp index acb8f3c8..599b3510 100644 --- a/gameserver.cbp +++ b/gameserver.cbp @@ -132,6 +132,8 @@ + + @@ -160,6 +162,8 @@ + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 17a27892..f72726de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -212,6 +212,8 @@ SET(SRCS_MANASERVGAME game-server/character.cpp game-server/collisiondetection.h game-server/collisiondetection.cpp + game-server/combatcomponent.h + game-server/combatcomponent.cpp game-server/command.cpp game-server/commandhandler.cpp game-server/commandhandler.h @@ -240,6 +242,8 @@ SET(SRCS_MANASERVGAME game-server/mapreader.cpp game-server/monster.h game-server/monster.cpp + game-server/monstercombatcomponent.h + game-server/monstercombatcomponent.cpp game-server/monstermanager.h game-server/monstermanager.cpp game-server/npc.h diff --git a/src/game-server/attack.cpp b/src/game-server/attack.cpp index 1825b86a..a1300e4d 100644 --- a/src/game-server/attack.cpp +++ b/src/game-server/attack.cpp @@ -75,6 +75,7 @@ AttackInfo *AttackInfo::readAttackNode(xmlNodePtr node) void Attacks::add(AttackInfo *attackInfo) { mAttacks.push_back(Attack(attackInfo)); + attack_added.emit(*mAttacks.rbegin()); } void Attacks::remove(AttackInfo *attackInfo) @@ -86,6 +87,7 @@ void Attacks::remove(AttackInfo *attackInfo) { if (mCurrentAttack && mCurrentAttack->getAttackInfo() == attackInfo) mCurrentAttack = 0; + attack_removed.emit(*it); mAttacks.erase(it); return; } diff --git a/src/game-server/attack.h b/src/game-server/attack.h index 0bcc361c..cecb4fd5 100644 --- a/src/game-server/attack.h +++ b/src/game-server/attack.h @@ -24,6 +24,9 @@ #include #include +#include +#include + #include "common/defines.h" #include "scripting/script.h" @@ -168,7 +171,7 @@ class Attack /** * Helper class for storing multiple auto-attacks. */ -class Attacks +class Attacks : public sigc::trackable { public: Attacks(): @@ -188,6 +191,9 @@ class Attacks unsigned getNumber() { return mAttacks.size(); } + sigc::signal attack_added; + sigc::signal attack_removed; + private: std::vector mAttacks; diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 9112a1b8..42d34046 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -27,6 +27,7 @@ #include "game-server/attributemanager.h" #include "game-server/character.h" #include "game-server/collisiondetection.h" +#include "game-server/combatcomponent.h" #include "game-server/mapcomposite.h" #include "game-server/effect.h" #include "game-server/skillmanager.h" @@ -43,9 +44,7 @@ Script::Ref Being::mRecalculateBaseAttributeCallback; Being::Being(EntityType type): Actor(type), mAction(STAND), - mTarget(NULL), mGender(GENDER_UNSPECIFIED), - mCurrentAttack(0), mDirection(DOWN), mEmoteId(0) { @@ -87,74 +86,7 @@ void Being::triggerEmote(int id) raiseUpdateFlags(UPDATEFLAG_EMOTE); } -int Being::damage(Actor * /* source */, const Damage &damage) -{ - if (mAction == DEAD) - return 0; - - int HPloss = damage.base; - if (damage.delta) - HPloss += rand() * (damage.delta + 1) / RAND_MAX; - - // TODO magical attacks and associated elemental modifiers - switch (damage.type) - { - case DAMAGE_PHYSICAL: - if (!damage.trueStrike && - rand()%((int) getModifiedAttribute(ATTR_DODGE) + 1) > - rand()%(damage.cth + 1)) - { - HPloss = 0; - // TODO Process triggers for a dodged physical attack here. - // If there is an attacker included, also process triggers for the attacker (failed physical strike) - } - else - { - HPloss = HPloss * (1.0 - (0.0159375f * - getModifiedAttribute(ATTR_DEFENSE)) / - (1.0 + 0.017 * - getModifiedAttribute(ATTR_DEFENSE))) + - (rand()%((HPloss >> 4) + 1)); - // TODO Process triggers for receiving damage here. - // If there is an attacker included, also process triggers for the attacker (successful physical strike) - } - break; - case DAMAGE_MAGICAL: -#if 0 - getModifiedAttribute(BASE_ELEM_BEGIN + damage.element); -#else - LOG_WARN("Attempt to use magical type damage! This has not been" - "implemented yet and should not be used!"); - HPloss = 0; -#endif - break; - case DAMAGE_DIRECT: - break; - default: - LOG_WARN("Unknown damage type '" << damage.type << "'!"); - break; - } - - if (HPloss > 0) - { - mHitsTaken.push_back(HPloss); - Attribute &HP = mAttributes.at(ATTR_HP); - LOG_DEBUG("Being " << getPublicID() << " suffered " << HPloss - << " damage. HP: " - << HP.getModifiedAttribute() << "/" - << mAttributes.at(ATTR_MAX_HP).getModifiedAttribute()); - setAttribute(ATTR_HP, HP.getBase() - HPloss); - // No HP regen after being hit if this is set. - mHealthRegenerationTimeout.setSoft( - Configuration::getValue("game_hpRegenBreakAfterHit", 0)); - } - else - { - HPloss = 0; - } - return HPloss; -} void Being::heal() { @@ -191,71 +123,9 @@ void Being::died() // dead beings stay where they are clearDestination(); - // reset target - mTarget = NULL; - signal_died.emit(this); } -void Being::processAttacks() -{ - if (mAction != ATTACK || !mTarget) - return; - - // Ticks attacks even when not attacking to permit cooldowns and warmups. - std::vector attacksReady; - mAttacks.getUsuableAttacks(&attacksReady); - - if (Attack *triggerableAttack = mAttacks.getTriggerableAttack()) - { - processAttack(*triggerableAttack); - mAttacks.markAttackAsTriggered(); - } - - // Deal with the ATTACK action. - if (attacksReady.empty()) - return; - - Attack *highestPriorityAttack = 0; - // Performs all ready attacks. - for (std::vector::const_iterator it = attacksReady.begin(), - it_end = attacksReady.end(); it != it_end; ++it) - { - // check if target is in range using the pythagorean theorem - int distx = this->getPosition().x - mTarget->getPosition().x; - int disty = this->getPosition().y - mTarget->getPosition().y; - int distSquare = (distx * distx + disty * disty); - AttackInfo *info = (*it)->getAttackInfo(); - int maxDist = info->getDamage().range + getSize(); - - if (distSquare <= maxDist * maxDist && - (!highestPriorityAttack || - highestPriorityAttack->getAttackInfo()->getPriority() - < info->getPriority())) - { - highestPriorityAttack = *it; - } - } - if (highestPriorityAttack) - { - mAttacks.startAttack(highestPriorityAttack); - mCurrentAttack = highestPriorityAttack; - setDestination(getPosition()); - // TODO: Turn into direction of enemy - raiseUpdateFlags(UPDATEFLAG_ATTACK); - } -} - -void Being::addAttack(AttackInfo *attackInfo) -{ - mAttacks.add(attackInfo); -} - -void Being::removeAttack(AttackInfo *attackInfo) -{ - mAttacks.remove(attackInfo); -} - void Being::setDestination(const Point &dst) { mDst = dst; @@ -480,23 +350,6 @@ int Being::directionToAngle(int direction) } } -int Being::performAttack(Being *target, const Damage &dmg) -{ - // check target legality - if (!target - || target == this - || target->getAction() == DEAD - || !target->canFight()) - return -1; - - if (getMap()->getPvP() == PVP_NONE - && target->getType() == OBJECT_CHARACTER - && getType() == OBJECT_CHARACTER) - return -1; - - return target->damage(this, dmg); -} - void Being::setAction(BeingAction action) { mAction = action; @@ -547,7 +400,7 @@ void Being::setAttribute(unsigned id, double value) } } -double Being::getAttribute(unsigned id) const +const Attribute *Being::getAttribute(unsigned id) const { AttributeMap::const_iterator ret = mAttributes.find(id); if (ret == mAttributes.end()) @@ -556,6 +409,18 @@ double Being::getAttribute(unsigned id) const << id << " not found! Returning 0."); return 0; } + return &ret->second; +} + +double Being::getAttributeBase(unsigned id) const +{ + AttributeMap::const_iterator ret = mAttributes.find(id); + if (ret == mAttributes.end()) + { + LOG_DEBUG("Being::getAttributeBase: Attribute " + << id << " not found! Returning 0."); + return 0; + } return ret->second.getBase(); } @@ -594,7 +459,7 @@ void Being::recalculateBaseAttribute(unsigned attr) { double newBase = utils::tpsToRawSpeed( getModifiedAttribute(ATTR_MOVE_SPEED_TPS)); - if (newBase != getAttribute(attr)) + if (newBase != getAttributeBase(attr)) setAttribute(attr, newBase); return; } @@ -742,8 +607,6 @@ void Being::update() if (getModifiedAttribute(ATTR_HP) <= 0 && mAction != DEAD) died(); - processAttacks(); - Actor::update(); } @@ -754,7 +617,3 @@ void Being::inserted(Entity *) mOld = getPosition(); } -void Being::processAttack(Attack &attack) -{ - performAttack(mTarget, attack.getAttackInfo()->getDamage()); -} diff --git a/src/game-server/being.h b/src/game-server/being.h index 1d1f4204..ce45d59c 100644 --- a/src/game-server/being.h +++ b/src/game-server/being.h @@ -46,11 +46,6 @@ struct Status typedef std::map< int, Status > StatusEffects; -/** - * Type definition for a list of hits - */ -typedef std::vector Hits; - /** * Generic being (living actor). Keeps direction, destination and a few other * relevant properties. Used for characters & monsters (all animated objects). @@ -68,13 +63,6 @@ class Being : public Actor */ virtual void update(); - /** - * Takes a damage structure, computes the real damage based on the - * stats, deducts the result from the hitpoints and adds the result to - * the HitsTaken list. - */ - virtual int damage(Actor *source, const Damage &damage); - /** Restores all hit points of the being */ void heal(); @@ -86,21 +74,6 @@ class Being : public Actor */ virtual void died(); - /** - * Process all available attacks - */ - void processAttacks(); - - /** - * Adds an attack to the available attacks - */ - void addAttack(AttackInfo *attack); - - /** - * Removes an attack from the available attacks - */ - void removeAttack(AttackInfo *attackInfo); - /** * Gets the destination coordinates of the being. */ @@ -133,25 +106,6 @@ class Being : public Actor BeingDirection getDirection() const { return mDirection; } - - /** - * Gets the damage list. - */ - const Hits &getHitsTaken() const - { return mHitsTaken; } - - /** - * Clears the damage list. - */ - void clearHitsTaken() - { mHitsTaken.clear(); } - - /** - * Performs an attack. - * Return Value: damage inflicted or -1 when illegal target - */ - int performAttack(Being *target, const Damage &dmg); - /** * Sets the current action. */ @@ -163,15 +117,6 @@ class Being : public Actor BeingAction getAction() const { return mAction; } - /** - * Gets the attack id the being is currently performing. - * For being, this is defaulted to the first one (1). - */ - virtual int getAttackId() const - { return mCurrentAttack ? - mCurrentAttack->getAttackInfo()->getDamage().id : 0; - } - /** * Moves the being toward its destination. */ @@ -195,9 +140,14 @@ class Being : public Actor void setAttribute(unsigned id, double value); /** - * Gets an attribute. + * Gets an attribute or 0 if not existing. + */ + const Attribute *getAttribute(unsigned id) const; + + /** + * Gets an attribute base. */ - double getAttribute(unsigned id) const; + double getAttributeBase(unsigned id) const; /** * Gets an attribute after applying modifiers. @@ -285,18 +235,6 @@ class Being : public Actor */ static int directionToAngle(int direction); - /** - * Get Target - */ - Being *getTarget() const - { return mTarget; } - - /** - * Set Target - */ - void setTarget(Being *target) - { mTarget = target; } - static void setUpdateDerivedAttributesCallback(Script *script) { script->assignCallback(mRecalculateDerivedAttributesCallback); } @@ -317,11 +255,6 @@ class Being : public Actor { return mEmoteId; } protected: - /** - * Performs an attack - */ - virtual void processAttack(Attack &attack); - /** * Update the being direction when moving so avoid directions desyncs * with other clients. @@ -333,14 +266,10 @@ class Being : public Actor BeingAction mAction; AttributeMap mAttributes; - Attacks mAttacks; StatusEffects mStatus; - Being *mTarget; Point mOld; /**< Old coordinates. */ Point mDst; /**< Target coordinates. */ BeingGender mGender; /**< Gender of the being. */ - Attack *mCurrentAttack; /**< Last used attack. */ - private: Being(const Being &rhs); @@ -355,7 +284,6 @@ class Being : public Actor BeingDirection mDirection; /**< Facing direction. */ std::string mName; - Hits mHitsTaken; /**< List of punches taken since last update. */ /** Time until hp is regenerated again */ Timeout mHealthRegenerationTimeout; diff --git a/src/game-server/buysell.cpp b/src/game-server/buysell.cpp index 1a0d8d91..ed6d92e4 100644 --- a/src/game-server/buysell.cpp +++ b/src/game-server/buysell.cpp @@ -154,15 +154,15 @@ void BuySell::perform(int id, int amount) { amount -= inv.remove(id, amount); mChar->setAttribute(mCurrencyId, - mChar->getAttribute(mCurrencyId) + + mChar->getAttributeBase(mCurrencyId) + amount * i->cost); } else { - amount = std::min(amount, ((int) mChar->getAttribute(mCurrencyId)) / i->cost); + amount = std::min(amount, ((int) mChar->getAttributeBase(mCurrencyId)) / i->cost); amount -= inv.insert(id, amount); mChar->setAttribute(mCurrencyId, - mChar->getAttribute(mCurrencyId) - + mChar->getAttributeBase(mCurrencyId) - amount * i->cost); } if (i->amount) diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 8cc0e65a..994e3311 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -22,8 +22,10 @@ #include "common/configuration.h" #include "game-server/accountconnection.h" +#include "game-server/attack.h" #include "game-server/attributemanager.h" #include "game-server/buysell.h" +#include "game-server/combatcomponent.h" #include "game-server/inventory.h" #include "game-server/item.h" #include "game-server/itemmanager.h" @@ -99,14 +101,13 @@ Character::Character(MessageIn &msg): setWalkMask(Map::BLOCKMASK_WALL); setBlockType(BLOCKTYPE_CHARACTER); - // Get character data. - mDatabaseID = msg.readInt32(); - setName(msg.readString()); - deserializeCharacterData(*this, msg); - mOld = getPosition(); - Inventory(this).initialize(); - modifiedAllAttribute(); - setSize(16); + + CombatComponent *combatcomponent = new CombatComponent(*this); + addComponent(combatcomponent); + combatcomponent->getAttacks().attack_added.connect( + sigc::mem_fun(this, &Character::attackAdded)); + combatcomponent->getAttacks().attack_removed.connect( + sigc::mem_fun(this, &Character::attackRemoved)); // Default knuckle attack int damageBase = this->getModifiedAttribute(ATTR_STR); @@ -121,7 +122,16 @@ Character::Character(MessageIn &msg): knuckleDamage.range = DEFAULT_TILE_LENGTH; mKnuckleAttackInfo = new AttackInfo(0, knuckleDamage, 7, 3, 0); - addAttack(mKnuckleAttackInfo); + combatcomponent->addAttack(mKnuckleAttackInfo); + + // Get character data. + mDatabaseID = msg.readInt32(); + setName(msg.readString()); + deserializeCharacterData(*this, msg); + mOld = getPosition(); + Inventory(this).initialize(); + modifiedAllAttribute(); + setSize(16); } Character::~Character() @@ -199,7 +209,7 @@ void Character::respawn() // Make it alive again setAction(STAND); // Reset target - mTarget = NULL; + getComponent()->clearTarget(); // Execute respawn callback when set if (executeCallback(mDeathAcceptedCallback, this)) @@ -422,7 +432,7 @@ void Character::sendStatus() { int attr = *i; attribMsg.writeInt16(attr); - attribMsg.writeInt32(getAttribute(attr) * 256); + attribMsg.writeInt32(getAttributeBase(attr) * 256); attribMsg.writeInt32(getModifiedAttribute(attr) * 256); } if (attribMsg.getLength() > 2) gameHandler->sendTo(this, attribMsg); @@ -497,7 +507,7 @@ void Character::flagAttribute(int attr) { // Inform the client of this attribute modification. accountHandler->updateAttributes(getDatabaseID(), attr, - getAttribute(attr), + getAttributeBase(attr), getModifiedAttribute(attr)); mModifiedAttributes.insert(attr); } @@ -655,7 +665,7 @@ AttribmodResponseCode Character::useCharacterPoint(size_t attribute) return ATTRIBMOD_NO_POINTS_LEFT; --mCharacterPoints; - setAttribute(attribute, getAttribute(attribute) + 1); + setAttribute(attribute, getAttributeBase(attribute) + 1); updateDerivedAttributes(attribute); return ATTRIBMOD_OK; } @@ -666,12 +676,12 @@ AttribmodResponseCode Character::useCorrectionPoint(size_t attribute) return ATTRIBMOD_INVALID_ATTRIBUTE; if (!mCorrectionPoints) return ATTRIBMOD_NO_POINTS_LEFT; - if (getAttribute(attribute) <= 1) + if (getAttributeBase(attribute) <= 1) return ATTRIBMOD_DENIED; --mCorrectionPoints; ++mCharacterPoints; - setAttribute(attribute, getAttribute(attribute) - 1); + setAttribute(attribute, getAttributeBase(attribute) - 1); updateDerivedAttributes(attribute); return ATTRIBMOD_OK; } @@ -704,19 +714,20 @@ void Character::resumeNpcThread() } } -void Character::addAttack(AttackInfo *attackInfo) +void Character::attackAdded(Attack &attack) { // Remove knuckle attack - Being::addAttack(attackInfo); - Being::removeAttack(mKnuckleAttackInfo); + if (attack.getAttackInfo() != mKnuckleAttackInfo) + getComponent()->removeAttack(mKnuckleAttackInfo); } -void Character::removeAttack(AttackInfo *attackInfo) +void Character::attackRemoved(Attack &attack) { - Being::removeAttack(attackInfo); // Add knuckle attack - if (mAttacks.getNumber() == 0) - Being::addAttack(mKnuckleAttackInfo); + CombatComponent *combatComponent = getComponent(); + // 1 since the attack is not really removed yet. + if (combatComponent->getAttacks().getNumber() == 1) + combatComponent->addAttack(mKnuckleAttackInfo); } void Character::disconnected() diff --git a/src/game-server/character.h b/src/game-server/character.h index dc703c8f..8b015f98 100644 --- a/src/game-server/character.h +++ b/src/game-server/character.h @@ -425,9 +425,9 @@ class Character : public Being void triggerLoginCallback(); - virtual void addAttack(AttackInfo *attackInfo); + void attackAdded(Attack &attackInfo); - virtual void removeAttack(AttackInfo *attackInfo); + void attackRemoved(Attack &attackInfo); sigc::signal signal_disconnected; diff --git a/src/game-server/combatcomponent.cpp b/src/game-server/combatcomponent.cpp new file mode 100644 index 00000000..199126f6 --- /dev/null +++ b/src/game-server/combatcomponent.cpp @@ -0,0 +1,213 @@ +/* + * The Mana Server + * Copyright (C) 2013 The Mana Developers + * + * This file is part of The Mana Server. + * + * The Mana Server is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana Server. If not, see . + */ + +#include "combatcomponent.h" + +#include "game-server/being.h" +#include "game-server/mapcomposite.h" + +#include "utils/logger.h" + +CombatComponent::CombatComponent(Being &being): + mTarget(0), + mCurrentAttack(0) +{ + being.signal_died.connect(sigc::mem_fun(this, + &CombatComponent::diedOrRemoved)); + being.signal_removed.connect(sigc::mem_fun(this, + &CombatComponent::diedOrRemoved)); +} + +CombatComponent::~CombatComponent() +{ +} + +void CombatComponent::update(Entity &entity) +{ + // Temponary for as long as Being is not split into Components + // Prevents to implement all at once + // TODO: remove this as soon as possible + Being &being = static_cast(entity); + + + if (being.getAction() != ATTACK || !mTarget) + return; + + std::vector attacksReady; + mAttacks.getUsuableAttacks(&attacksReady); + + if (Attack *triggerableAttack = mAttacks.getTriggerableAttack()) + { + processAttack(being, *triggerableAttack); + mAttacks.markAttackAsTriggered(); + } + + // Deal with the ATTACK action. + if (attacksReady.empty()) + return; + + Attack *highestPriorityAttack = 0; + // Performs all ready attacks. + for (std::vector::const_iterator it = attacksReady.begin(), + it_end = attacksReady.end(); it != it_end; ++it) + { + // check if target is in range using the pythagorean theorem + int distx = being.getPosition().x - mTarget->getPosition().x; + int disty = being.getPosition().y - mTarget->getPosition().y; + int distSquare = (distx * distx + disty * disty); + AttackInfo *info = (*it)->getAttackInfo(); + int maxDist = info->getDamage().range + being.getSize(); + + if (distSquare <= maxDist * maxDist && + (!highestPriorityAttack || + highestPriorityAttack->getAttackInfo()->getPriority() + < info->getPriority())) + { + highestPriorityAttack = *it; + } + } + if (highestPriorityAttack) + { + mAttacks.startAttack(highestPriorityAttack); + mCurrentAttack = highestPriorityAttack; + being.setDestination(being.getPosition()); + // TODO: Turn into direction of enemy + being.raiseUpdateFlags(UPDATEFLAG_ATTACK); + } +} + +/** + * Takes a damage structure, computes the real damage based on the + * stats, deducts the result from the hitpoints and adds the result to + * the HitsTaken list. + */ +int CombatComponent::damage(Being &target, Being *source, const Damage &damage) +{ + int HPloss = damage.base; + if (damage.delta) + HPloss += rand() * (damage.delta + 1) / RAND_MAX; + + // TODO magical attacks and associated elemental modifiers + switch (damage.type) + { + case DAMAGE_PHYSICAL: + if (!damage.trueStrike && + rand()%((int) target.getModifiedAttribute(ATTR_DODGE) + 1) > + rand()%(damage.cth + 1)) + { + HPloss = 0; + // TODO Process triggers for a dodged physical attack here. + // If there is an attacker included, also process triggers for the attacker (failed physical strike) + } + else + { + HPloss = HPloss * (1.0 - (0.0159375f * + target.getModifiedAttribute(ATTR_DEFENSE)) / + (1.0 + 0.017 * + target.getModifiedAttribute(ATTR_DEFENSE))) + + (rand()%((HPloss >> 4) + 1)); + // TODO Process triggers for receiving damage here. + // If there is an attacker included, also process triggers for the attacker (successful physical strike) + } + break; + case DAMAGE_MAGICAL: +#if 0 + target.getModifiedAttribute(BASE_ELEM_BEGIN + damage.element); +#else + LOG_WARN("Attempt to use magical type damage! This has not been" + "implemented yet and should not be used!"); + HPloss = 0; +#endif + break; + case DAMAGE_DIRECT: + break; + default: + LOG_WARN("Unknown damage type '" << damage.type << "'!"); + break; + } + + if (HPloss > 0) + { + mHitsTaken.push_back(HPloss); + const Attribute *HP = target.getAttribute(ATTR_HP); + LOG_DEBUG("Being " << target.getPublicID() << " suffered " << HPloss + << " damage. HP: " + << HP->getModifiedAttribute() << "/" + << target.getModifiedAttribute(ATTR_MAX_HP)); + target.setAttribute(ATTR_HP, HP->getBase() - HPloss); + // No HP regen after being hit if this is set. + // TODO: Reenable this once the attributes are available as a component + // A bit too fuzzy to implement at the moment + //mHealthRegenerationTimeout.setSoft( + // Configuration::getValue("game_hpRegenBreakAfterHit", 0)); + } + else + { + HPloss = 0; + } + + signal_damaged.emit(source, damage, HPloss); + return HPloss; +} + +/** + * Performs an attack + */ +void CombatComponent::processAttack(Being &source, Attack &attack) +{ + performAttack(source, attack.getAttackInfo()->getDamage()); +} + +/** + * Adds an attack to the available attacks + */ +void CombatComponent::addAttack(AttackInfo *attackInfo) +{ + mAttacks.add(attackInfo); +} + +/** + * Removes an attack from the available attacks + */ +void CombatComponent::removeAttack(AttackInfo *attackInfo) +{ + mAttacks.remove(attackInfo); +} + +/** + * Performs an attack. + */ +int CombatComponent::performAttack(Being &source, const Damage &dmg) +{ + // check target legality + if (!mTarget + || mTarget == &source + || mTarget->getAction() == DEAD + || !mTarget->canFight()) + return -1; + + if (source.getMap()->getPvP() == PVP_NONE + && mTarget->getType() == OBJECT_CHARACTER + && source.getType() == OBJECT_CHARACTER) + return -1; + + return mTarget->getComponent()->damage(*mTarget, + &source, dmg); +} diff --git a/src/game-server/combatcomponent.h b/src/game-server/combatcomponent.h new file mode 100644 index 00000000..033b543d --- /dev/null +++ b/src/game-server/combatcomponent.h @@ -0,0 +1,144 @@ +/* + * The Mana Server + * Copyright (C) 2013 The Mana Developers + * + * This file is part of The Mana Server. + * + * The Mana Server is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana Server. If not, see . + */ + +#ifndef COMBATCOMPONENT_H +#define COMBATCOMPONENT_H + +#include "component.h" + +#include + +#include + +#include "game-server/attack.h" + +class Actor; +class Being; + +/** + * Type definition for a list of hits + */ +typedef std::vector Hits; + +class CombatComponent: public Component, public sigc::trackable +{ +public: + static const ComponentType type = CT_Fighting; + + CombatComponent(Being &being); + virtual ~CombatComponent(); + + void update(Entity &entity); + + void addAttack(AttackInfo *attack); + void removeAttack(AttackInfo *attackInfo); + Attacks &getAttacks(); + + const Hits &getHitsTaken() const; + void clearHitsTaken(); + + int performAttack(Being &source, const Damage &dmg); + virtual int damage(Being &target, Being *source, const Damage &damage); + + int getAttackId() const; + + Being *getTarget() const; + void setTarget(Being *target); + void clearTarget(); + + void diedOrRemoved(Entity *entity); + + sigc::signal signal_damaged; + +protected: + virtual void processAttack(Being &source, Attack &attack); + + Being *mTarget; + Attacks mAttacks; + Attack *mCurrentAttack; // Last used attack + Hits mHitsTaken; //List of punches taken since last update. + +}; + +inline Attacks &CombatComponent::getAttacks() +{ + return mAttacks; +} + +/** + * Gets the damage list. + */ +inline const Hits &CombatComponent::getHitsTaken() const +{ + return mHitsTaken; +} + +/** + * Clears the damage list. + */ +inline void CombatComponent::clearHitsTaken() +{ + mHitsTaken.clear(); +} + +/** + * Gets the attack id the being is currently performing. + * For being, this is defaulted to the first one (1). + */ +inline int CombatComponent::getAttackId() const +{ + return mCurrentAttack ? + mCurrentAttack->getAttackInfo()->getDamage().id : 0; +} + +/** + * Get Target + */ +inline Being *CombatComponent::getTarget() const +{ + return mTarget; +} + +/** + * Set Target + */ +inline void CombatComponent::setTarget(Being *target) +{ + mTarget = target; +} + +/** + * Clears the target + */ +inline void CombatComponent::clearTarget() +{ + mTarget = 0; +} + +/** + * Handler for the died and removed event of the targeting being + * @param entity The removed/died being (not used here) + */ +inline void CombatComponent::diedOrRemoved(Entity *entity) +{ + clearTarget(); +} + +#endif // COMBATCOMPONENT_H diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index 001f65f6..353c3ef0 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -670,7 +670,7 @@ static void handleMoney(Character *player, std::string &args) value = utils::stringToInt(valuestr); // change how much money the player has - other->setAttribute(ATTR_GP , other->getAttribute(ATTR_GP) + value); + other->setAttribute(ATTR_GP , other->getAttributeBase(ATTR_GP) + value); // log transaction std::string msg = "User created " + valuestr + " money"; diff --git a/src/game-server/component.h b/src/game-server/component.h index 740668a8..47e9dd0f 100644 --- a/src/game-server/component.h +++ b/src/game-server/component.h @@ -26,6 +26,7 @@ class Entity; enum ComponentType { CT_Effect, + CT_Fighting, CT_Item, CT_Npc, CT_SpawnArea, diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index 51b64a26..9cec7728 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -27,6 +27,7 @@ #include "common/transaction.h" #include "game-server/accountconnection.h" #include "game-server/buysell.h" +#include "game-server/combatcomponent.h" #include "game-server/commandhandler.h" #include "game-server/emotemanager.h" #include "game-server/inventory.h" @@ -649,7 +650,7 @@ void GameHandler::handleAttack(GameClient &client, MessageIn &message) Being *being = findBeingNear(client.character, id); if (being && being->getType() != OBJECT_NPC) { - client.character->setTarget(being); + client.character->getComponent()->setTarget(being); client.character->setAction(ATTACK); } } diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp index b7b0d785..7295b95a 100644 --- a/src/game-server/item.cpp +++ b/src/game-server/item.cpp @@ -25,6 +25,7 @@ #include "game-server/attack.h" #include "game-server/attributemanager.h" #include "game-server/being.h" +#include "game-server/combatcomponent.h" #include "game-server/state.h" #include "scripting/script.h" #include "scripting/scriptmanager.h" @@ -49,13 +50,13 @@ void ItemEffectAttrMod::dispell(Being *itemUser) bool ItemEffectAttack::apply(Being *itemUser) { - itemUser->addAttack(mAttackInfo); + itemUser->getComponent()->addAttack(mAttackInfo); return false; } void ItemEffectAttack::dispell(Being *itemUser) { - itemUser->removeAttack(mAttackInfo); + itemUser->getComponent()->removeAttack(mAttackInfo); } ItemEffectScript::~ItemEffectScript() diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index a1a3f989..f1b545ec 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -26,6 +26,7 @@ #include "common/configuration.h" #include "common/resourcemanager.h" #include "game-server/character.h" +#include "game-server/combatcomponent.h" #include "game-server/mapcomposite.h" #include "game-server/map.h" #include "game-server/mapmanager.h" @@ -591,9 +592,9 @@ void MapComposite::remove(Entity *ptr) if ((*i)->canFight()) { Being *being = static_cast(*i); - if (being->getTarget() == ptr) + if (being->getComponent()->getTarget() == ptr) { - being->setTarget(NULL); + being->getComponent()->clearTarget(); } } if (*i == ptr) diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index ceae82ca..25abb68a 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -28,6 +28,7 @@ #include "game-server/item.h" #include "game-server/map.h" #include "game-server/mapcomposite.h" +#include "game-server/monstercombatcomponent.h" #include "game-server/state.h" #include "scripting/scriptmanager.h" #include "utils/logger.h" @@ -98,9 +99,6 @@ Monster::Monster(MonsterClass *specy): } } - mDamageMutation = mutation ? - (100 + (rand() % (mutation * 2)) - mutation) / 100.0 : 1; - setSize(specy->getSize()); setGender(specy->getGender()); @@ -111,13 +109,16 @@ Monster::Monster(MonsterClass *specy): mAttackPositions.push_back(AttackPosition(0, -dist, DOWN)); mAttackPositions.push_back(AttackPosition(0, dist, UP)); - // Take attacks from specy - std::vector &attacks = specy->getAttackInfos(); - for (std::vector::iterator it = attacks.begin(), - it_end = attacks.end(); it != it_end; ++it) - { - addAttack(*it); - } + MonsterCombatComponent *combatComponent = + new MonsterCombatComponent(*this); + addComponent(combatComponent); + + double damageMutation = mutation ? + (100.0 + (rand() % (mutation * 2)) - mutation) / 100.0 : 1.0; + combatComponent->setDamageMutation(damageMutation); + + combatComponent->signal_damaged.connect( + sigc::mem_fun(this, &Monster::receivedDamage)); } Monster::~Monster() @@ -151,7 +152,7 @@ void Monster::update() refreshTarget(); // Cancel the rest when we have a target - if (mTarget) + if (getComponent()->getTarget()) return; // We have no target - let's wander around @@ -188,7 +189,7 @@ void Monster::refreshTarget() Point bestAttackPosition; // reset Target. We will find a new one if possible - mTarget = 0; + getComponent()->clearTarget(); // Iterate through objects nearby int aroundArea = Configuration::getValue("game_visualRange", 448); @@ -242,11 +243,11 @@ void Monster::refreshTarget() } if (bestTarget) { - mTarget = bestTarget; + getComponent()->setTarget(bestTarget); if (bestAttackPosition == getPosition()) { mAction = ATTACK; - updateDirection(getPosition(), mTarget->getPosition()); + updateDirection(getPosition(), bestTarget->getPosition()); } else { @@ -255,35 +256,6 @@ void Monster::refreshTarget() } } -void Monster::processAttack(Attack &attack) -{ - if (!mTarget) - { - setAction(STAND); - return; - } - - Damage dmg = attack.getAttackInfo()->getDamage(); - dmg.skill = 0; - dmg.base *= mDamageMutation; - dmg.delta *= mDamageMutation; - - int hit = performAttack(mTarget, attack.getAttackInfo()->getDamage()); - - const Script::Ref &scriptCallback = - attack.getAttackInfo()->getScriptCallback(); - - if (scriptCallback.isValid() && hit > -1) - { - Script *script = ScriptManager::currentState(); - script->prepare(scriptCallback); - script->push(this); - script->push(mTarget); - script->push(hit); - script->execute(getMap()); - } -} - int Monster::calculatePositionPriority(Point position, int targetPriority) { Point thisPos = getPosition(); @@ -375,44 +347,6 @@ std::map Monster::getAngerList() const return result; } -int Monster::damage(Actor *source, const Damage &damage) -{ - Damage newDamage = damage; - float factor = mSpecy->getVulnerability(newDamage.element); - newDamage.base = newDamage.base * factor; - newDamage.delta = newDamage.delta * factor; - int HPLoss = Being::damage(source, newDamage); - if (source) - changeAnger(source, HPLoss); - - if (HPLoss && source && source->getType() == OBJECT_CHARACTER) - { - Character *s = static_cast< Character * >(source); - - mExpReceivers[s].insert(damage.skill); - if (mKillStealProtectedTimeout.expired() || mOwner == s - || mOwner->getParty() == s->getParty()) - { - mOwner = s; - mLegalExpReceivers.insert(s); - mKillStealProtectedTimeout.set(KILLSTEAL_PROTECTION_TIME); - } - } - - if (mSpecy->getDamageCallback().isValid()) - { - Script *script = ScriptManager::currentState(); - script->prepare(mSpecy->getDamageCallback()); - script->push(this); - script->push(source); - script->push(HPLoss); - // TODO: add exact damage parameters as well - script->execute(getMap()); - } - - return HPLoss; -} - void Monster::died() { if (mAction == DEAD) @@ -467,3 +401,24 @@ void Monster::died() } } } + + +void Monster::receivedDamage(Being *source, const Damage &damage, int hpLoss) +{ + if (source) + changeAnger(source, hpLoss); + + if (hpLoss && source && source->getType() == OBJECT_CHARACTER) + { + Character *s = static_cast< Character * >(source); + + mExpReceivers[s].insert(damage.skill); + if (mKillStealProtectedTimeout.expired() || mOwner == s + || mOwner->getParty() == s->getParty()) + { + mOwner = s; + mLegalExpReceivers.insert(s); + mKillStealProtectedTimeout.set(KILLSTEAL_PROTECTION_TIME); + } + } +} diff --git a/src/game-server/monster.h b/src/game-server/monster.h index e87180dd..3bd34a95 100644 --- a/src/game-server/monster.h +++ b/src/game-server/monster.h @@ -291,16 +291,13 @@ class Monster : public Being void refreshTarget(); - /** - * Performs an attack - */ - virtual void processAttack(Attack &attack); - /** * Kills the being. */ void died(); + void receivedDamage(Being *attacker, const Damage &damage, int hpLoss); + /** * Alters hate for the monster */ @@ -308,11 +305,6 @@ class Monster : public Being std::map getAngerList() const; - /** - * Calls the damage function in Being and updates the aggro list - */ - virtual int damage(Actor *source, const Damage &damage); - /** * Removes a being from the anger list. */ @@ -342,9 +334,6 @@ class Monster : public Being */ Character *mOwner; - /** Factor for damage mutation */ - unsigned mDamageMutation; - /** List of characters and their skills that attacked this monster. */ std::map > mExpReceivers; diff --git a/src/game-server/monstercombatcomponent.cpp b/src/game-server/monstercombatcomponent.cpp new file mode 100644 index 00000000..dc669556 --- /dev/null +++ b/src/game-server/monstercombatcomponent.cpp @@ -0,0 +1,99 @@ +/* + * The Mana Server + * Copyright (C) 2013 The Mana Developers + * + * This file is part of The Mana Server. + * + * The Mana Server is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana Server. If not, see . + */ + +#include "game-server/monstercombatcomponent.h" + +#include "game-server/monster.h" +#include "scripting/scriptmanager.h" + +MonsterCombatComponent::MonsterCombatComponent(Monster &monster): + CombatComponent(monster), + mDamageMutation(0) +{ + // Take attacks from specy + std::vector &attacks = monster.getSpecy()->getAttackInfos(); + for (std::vector::iterator it = attacks.begin(), + it_end = attacks.end(); it != it_end; ++it) + { + addAttack(*it); + } +} + +/** + * Performs an attack + */ +void MonsterCombatComponent::processAttack(Being *source, Attack &attack) +{ + if (!mTarget) + { + source->setAction(STAND); + return; + } + + Damage dmg = attack.getAttackInfo()->getDamage(); + dmg.skill = 0; + dmg.base *= mDamageMutation; + dmg.delta *= mDamageMutation; + + int hit = performAttack(*mTarget, attack.getAttackInfo()->getDamage()); + + const Script::Ref &scriptCallback = + attack.getAttackInfo()->getScriptCallback(); + + if (scriptCallback.isValid() && hit > -1) + { + Script *script = ScriptManager::currentState(); + script->prepare(scriptCallback); + script->push(source); + script->push(mTarget); + script->push(hit); + script->execute(source->getMap()); + } +} + +/** + * Calls the damage function in Being and updates the aggro list + */ +int MonsterCombatComponent::damage(Being &target, + Being *source, + const Damage &damage) +{ + // Temporarily depend on monster as long as it does not exist as a component + Monster &monster = static_cast(target); + Damage newDamage = damage; + MonsterClass *specy = monster.getSpecy(); + float factor = specy->getVulnerability(newDamage.element); + newDamage.base = newDamage.base * factor; + newDamage.delta = newDamage.delta * factor; + int hpLoss = CombatComponent::damage(target, source, newDamage); + + + if (specy->getDamageCallback().isValid()) + { + Script *script = ScriptManager::currentState(); + script->prepare(specy->getDamageCallback()); + script->push(&target); + script->push(source); + script->push(hpLoss); + // TODO: add exact damage parameters as well + script->execute(monster.getMap()); + } + return hpLoss; +} diff --git a/src/game-server/monstercombatcomponent.h b/src/game-server/monstercombatcomponent.h new file mode 100644 index 00000000..766c7734 --- /dev/null +++ b/src/game-server/monstercombatcomponent.h @@ -0,0 +1,54 @@ +/* + * The Mana Server + * Copyright (C) 2013 The Mana Developers + * + * This file is part of The Mana Server. + * + * The Mana Server is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana Server. If not, see . + */ + +#ifndef MONSTERCOMBATCOMPONENT_H +#define MONSTERCOMBATCOMPONENT_H + +#include "game-server/combatcomponent.h" + +#include "game-server/attack.h" +#include "game-server/being.h" + +class Monster; + +class MonsterCombatComponent: public CombatComponent +{ +public: + MonsterCombatComponent(Monster &monster); + + void processAttack(Being *source, Attack &attack); + int damage(Being &target, Being *source, const Damage &damage); + + void setDamageMutation(double mutation); + +private: + double mDamageMutation; +}; + +/** + * Sets the mutation of the damage compared to the default damage of the specy + * @param mutation + */ +inline void MonsterCombatComponent::setDamageMutation(double mutation) +{ + mDamageMutation = mutation; +} + +#endif /* MONSTERCOMBATCOMPONENT_H */ diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 673d48fa..eaffe772 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -22,11 +22,12 @@ #include "common/configuration.h" #include "game-server/accountconnection.h" +#include "game-server/effect.h" +#include "game-server/combatcomponent.h" #include "game-server/gamehandler.h" #include "game-server/inventory.h" #include "game-server/item.h" #include "game-server/itemmanager.h" -#include "game-server/effect.h" #include "game-server/map.h" #include "game-server/mapcomposite.h" #include "game-server/mapmanager.h" @@ -166,7 +167,9 @@ static void informPlayer(MapComposite *map, Character *p) MessageOut AttackMsg(GPMSG_BEING_ATTACK); AttackMsg.writeInt16(oid); AttackMsg.writeInt8(o->getDirection()); - AttackMsg.writeInt8(static_cast< Being * >(o)->getAttackId()); + CombatComponent *combatComponent = + o->getComponent(); + AttackMsg.writeInt8(combatComponent->getAttackId()); gameHandler->sendTo(p, AttackMsg); } @@ -217,8 +220,9 @@ static void informPlayer(MapComposite *map, Character *p) // Send damage messages. if (o->canFight()) { - Being *victim = static_cast< Being * >(o); - const Hits &hits = victim->getHitsTaken(); + CombatComponent *combatComponent = + o->getComponent(); + const Hits &hits = combatComponent->getHitsTaken(); for (Hits::const_iterator j = hits.begin(), j_end = hits.end(); j != j_end; ++j) { @@ -462,7 +466,7 @@ void GameState::update(int tick) a->clearUpdateFlags(); if (a->canFight()) { - static_cast< Being * >(a)->clearHitsTaken(); + a->getComponent()->clearHitsTaken(); } } } diff --git a/src/game-server/trade.cpp b/src/game-server/trade.cpp index e1779d2f..0b906b1f 100644 --- a/src/game-server/trade.cpp +++ b/src/game-server/trade.cpp @@ -131,14 +131,14 @@ void Trade::agree(Character *c) // Check if both player has the objects in their inventories // and enouth money, then swap them. Inventory v1(mChar1), v2(mChar2); - if (mChar1->getAttribute(mCurrencyId) >= mMoney1 - mMoney2 && - mChar2->getAttribute(mCurrencyId) >= mMoney2 - mMoney1 && + if (mChar1->getAttributeBase(mCurrencyId) >= mMoney1 - mMoney2 && + mChar2->getAttributeBase(mCurrencyId) >= mMoney2 - mMoney1 && perform(mItems1, v1, v2) && perform(mItems2, v2, v1)) { - mChar1->setAttribute(mCurrencyId, mChar1->getAttribute(mCurrencyId) + mChar1->setAttribute(mCurrencyId, mChar1->getAttributeBase(mCurrencyId) - mMoney1 + mMoney2); - mChar2->setAttribute(mCurrencyId, mChar2->getAttribute(mCurrencyId) + mChar2->setAttribute(mCurrencyId, mChar2->getAttributeBase(mCurrencyId) - mMoney2 + mMoney1); } else diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index d4438990..cbdb088c 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -33,6 +33,7 @@ extern "C" { #include "game-server/buysell.h" #include "game-server/character.h" #include "game-server/collisiondetection.h" +#include "game-server/combatcomponent.h" #include "game-server/effect.h" #include "game-server/gamehandler.h" #include "game-server/inventory.h" @@ -1417,7 +1418,7 @@ static int being_damage(lua_State *s) { dmg.skill = checkSkill(s, 8); } - being->damage(source, dmg); + being->getComponent()->damage(*being, source, dmg); return 0; } @@ -1692,7 +1693,7 @@ static int being_get_base_attribute(lua_State *s) int attr = luaL_checkint(s, 2); luaL_argcheck(s, attr > 0, 2, "invalid attribute id"); - lua_pushinteger(s, being->getAttribute(attr)); + lua_pushinteger(s, being->getAttributeBase(attr)); return 1; } -- cgit v1.2.3-70-g09d2 From 4a8080dcf73dab2b6e62b8500fec3bb996bcbf17 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Tue, 2 Apr 2013 22:25:24 +0200 Subject: Fixed multiple warnings and errors that blocked c++0x This allows the server to compile with c++0x (and enables it). This also includes some coding style / readabillity fixes. --- src/CMakeLists.txt | 2 ++ src/chat-server/chathandler.cpp | 2 +- src/common/permissionmanager.cpp | 2 +- src/game-server/buysell.cpp | 26 +++++++++++++--------- src/game-server/buysell.h | 8 ++++--- src/game-server/character.cpp | 3 ++- src/game-server/commandhandler.cpp | 8 +++---- src/game-server/inventory.cpp | 3 +-- src/game-server/itemmanager.cpp | 3 +-- src/game-server/mapcomposite.cpp | 3 ++- src/game-server/skillmanager.cpp | 3 +-- src/game-server/state.cpp | 38 +++++++++++++++++++------------- src/game-server/state.h | 4 ++-- src/game-server/trade.cpp | 7 ++++-- src/game-server/trade.h | 5 +++-- src/game-server/triggerareacomponent.cpp | 2 +- src/game-server/triggerareacomponent.h | 6 ++--- src/scripting/lua.cpp | 2 +- 18 files changed, 74 insertions(+), 53 deletions(-) (limited to 'src/game-server/commandhandler.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c88d716..85d6b6d2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,6 +41,8 @@ SET(FLAGS "${FLAGS} -DPACKAGE_VERSION=\\\"${VERSION}\\\"") SET(FLAGS "${FLAGS} -DPKG_DATADIR=\\\"${PKG_DATADIR}/\\\"") SET(FLAGS "${FLAGS} -DLOCALEDIR=\\\"${LOCALEDIR}/\\\"") +SET(FLAGS "${FLAGS} -std=c++0x") + # If the Sqlite option is enabled... IF (WITH_SQLITE) FIND_PACKAGE(Sqlite3 REQUIRED) diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp index 63aaa43a..93b1af43 100644 --- a/src/chat-server/chathandler.cpp +++ b/src/chat-server/chathandler.cpp @@ -443,7 +443,7 @@ void ChatHandler::handleModeChangeMessage(ChatClient &client, MessageIn &msg) trans.mCharacterId = client.characterId; trans.mAction = TRANS_CHANNEL_MODE; trans.mMessage = "User mode "; - trans.mMessage.append(mode + " set on " + user); + trans.mMessage.append(utils::toString(mode) + " set on " + user); storage->addTransaction(trans); } diff --git a/src/common/permissionmanager.cpp b/src/common/permissionmanager.cpp index 573e1d26..5510fd7c 100644 --- a/src/common/permissionmanager.cpp +++ b/src/common/permissionmanager.cpp @@ -37,7 +37,7 @@ void addPermission(std::string permission, char mask) std::map::iterator i = permissions.find(permission); if (i == permissions.end()) { - permissions.insert(std::make_pair(permission, mask)); + permissions.insert(std::make_pair(permission, mask)); } else { i->second |= mask; } diff --git a/src/game-server/buysell.cpp b/src/game-server/buysell.cpp index ed6d92e4..1e63d523 100644 --- a/src/game-server/buysell.cpp +++ b/src/game-server/buysell.cpp @@ -46,7 +46,7 @@ void BuySell::cancel() delete this; } -bool BuySell::registerItem(int id, int amount, int cost) +bool BuySell::registerItem(unsigned id, int amount, int cost) { if (mSell) { @@ -57,8 +57,11 @@ bool BuySell::registerItem(int id, int amount, int cost) amount = nb; } - TradedItem it = { id, amount, cost }; - mItems.push_back(it); + TradedItem item; + item.itemId = id; + item.amount = amount; + item.cost = cost; + mItems.push_back(item); return true; } @@ -76,11 +79,11 @@ int BuySell::registerPlayerItems() for (InventoryData::const_iterator it = inventoryData.begin(), it_end = inventoryData.end(); it != it_end; ++it) { - unsigned nb = it->second.amount; - if (!nb) + unsigned amount = it->second.amount; + if (!amount) continue; - int id = it->second.itemId; + unsigned id = it->second.itemId; int cost = -1; if (itemManager->getItem(id)) { @@ -106,15 +109,18 @@ int BuySell::registerPlayerItems() if (i->itemId == id) { itemAlreadyAdded = true; - i->amount += nb; + i->amount += amount; break; } } if (!itemAlreadyAdded) { - TradedItem itTrade = { id, nb, cost }; - mItems.push_back(itTrade); + TradedItem tradeItem; + tradeItem.itemId = id; + tradeItem.amount = amount; + tradeItem.cost = cost; + mItems.push_back(tradeItem); nbItemsToSell++; } } @@ -142,7 +148,7 @@ bool BuySell::start(Actor *actor) return true; } -void BuySell::perform(int id, int amount) +void BuySell::perform(unsigned id, int amount) { Inventory inv(mChar); for (TradedItems::iterator i = mItems.begin(), diff --git a/src/game-server/buysell.h b/src/game-server/buysell.h index 38566005..72da2ce6 100644 --- a/src/game-server/buysell.h +++ b/src/game-server/buysell.h @@ -45,7 +45,7 @@ class BuySell * and how much it will cost. * @return true if at least one item was registered. */ - bool registerItem(int id, int amount, int cost); + bool registerItem(unsigned id, int amount, int cost); /** * Registers every player's item at an average cost given by the ItemDB. @@ -62,7 +62,7 @@ class BuySell /** * Performs the trade. */ - void perform(int id, int amount); + void perform(unsigned id, int amount); private: @@ -70,7 +70,9 @@ class BuySell struct TradedItem { - unsigned short itemId, amount, cost; + unsigned itemId; + int amount; + int cost; }; typedef std::vector< TradedItem > TradedItems; diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 994e3311..e52747fd 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -223,7 +223,8 @@ void Character::respawn() int spawnX = Configuration::getValue("char_respawnX", 1024); int spawnY = Configuration::getValue("char_respawnY", 1024); - GameState::enqueueWarp(this, MapManager::getMap(spawnMap), spawnX, spawnY); + GameState::enqueueWarp(this, MapManager::getMap(spawnMap), + Point(spawnX, spawnY)); } bool Character::specialUseCheck(SpecialMap::iterator it) diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index 353c3ef0..68899e3c 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -377,7 +377,7 @@ static void handleWarp(Character *player, std::string &args) y = utils::stringToInt(ystr); // now warp the player - GameState::warp(player, map, x, y); + GameState::warp(player, map, Point(x, y)); // log transaction std::stringstream ss; @@ -479,7 +479,7 @@ static void handleCharWarp(Character *player, std::string &args) y = utils::stringToInt(ystr); // now warp the player - GameState::warp(other, map, x, y); + GameState::warp(other, map, Point(x, y)); // log transaction std::stringstream ss; @@ -774,7 +774,7 @@ static void handleGoto(Character *player, std::string &args) // move the player to where the other player is MapComposite *map = other->getMap(); const Point &pos = other->getPosition(); - GameState::warp(player, map, pos.x, pos.y); + GameState::warp(player, map, pos); // log transaction std::stringstream msg; @@ -808,7 +808,7 @@ static void handleRecall(Character *player, std::string &args) // move the other player to where the player is MapComposite *map = player->getMap(); const Point &pos = player->getPosition(); - GameState::warp(other, map, pos.x, pos.y); + GameState::warp(other, map, pos); } static void handleReload(Character *, std::string &) diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index 1fe09001..e14a36af 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -715,8 +715,7 @@ bool Inventory::equip(int inventorySlot) { EquipmentItem equipItem(it->second.itemId, itemInstance); mPoss->equipSlots.insert( - std::make_pair - (equipReq.equipSlotId, equipItem)); + std::make_pair(equipReq.equipSlotId, equipItem)); --capacityLeft; } } diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index 4837ce98..504ba127 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -159,8 +159,7 @@ void ItemManager::readEquipSlotsFile() << ", capacity: " << capacity << ", visible? " << visible); EquipSlotInfo *equipSlotInfo = new EquipSlotInfo(slotId, name, capacity, visible); - mEquipSlotsInfo.insert( - std::make_pair(slotId, equipSlotInfo)); + mEquipSlotsInfo.insert(std::make_pair(slotId, equipSlotInfo)); mNamedEquipSlotsInfo.insert(name, equipSlotInfo); totalCapacity += capacity; diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index f1b545ec..bb7093b2 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -802,7 +802,8 @@ void MapComposite::initializeContent() if (destMap && destX && destY) { Entity *entity = new Entity(OBJECT_OTHER, this); - WarpAction *action = new WarpAction(destMap, destX, destY); + const Point warpTarget(destX, destY); + WarpAction *action = new WarpAction(destMap, warpTarget); entity->addComponent( new TriggerAreaComponent(object->getBounds(), action, false)); diff --git a/src/game-server/skillmanager.cpp b/src/game-server/skillmanager.cpp index 2e78194c..69a875e6 100644 --- a/src/game-server/skillmanager.cpp +++ b/src/game-server/skillmanager.cpp @@ -130,8 +130,7 @@ void SkillManager::readSkillNode(xmlNodePtr skillNode, mDefaultSkillId = skillInfo->id; } - mSkillsInfo.insert( - std::make_pair(skillInfo->id, skillInfo)); + mSkillsInfo.insert(std::make_pair(skillInfo->id, skillInfo)); std::string keyName = setName + "_" + skillInfo->skillName; mNamedSkillsInfo.insert(keyName, skillInfo); diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index eaffe772..d3a29860 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -54,7 +54,8 @@ enum */ struct DelayedEvent { - unsigned short type, x, y; + unsigned short type; + Point point; MapComposite *map; }; @@ -104,9 +105,7 @@ static void serializeLooks(Character *ch, MessageOut &msg) // When the insertion succeeds, its the first time // we encounter the item, so we can send the look change. // We also send empty slots for unequipment handling. - lookChanges.insert( - std::make_pair(it->first, - it->second.itemId)); + lookChanges.insert(std::make_pair(it->first, it->second.itemId)); } } @@ -500,7 +499,7 @@ void GameState::update(int tick) case EVENT_WARP: assert(o->getType() == OBJECT_CHARACTER); - warp(static_cast< Character * >(o), e.map, e.x, e.y); + warp(static_cast< Character * >(o), e.map, e.point); break; } } @@ -700,11 +699,11 @@ void GameState::remove(Entity *ptr) map->remove(ptr); } -void GameState::warp(Character *ptr, MapComposite *map, int x, int y) +void GameState::warp(Character *ptr, MapComposite *map, const Point &point) { remove(ptr); ptr->setMap(map); - ptr->setPosition(Point(x, y)); + ptr->setPosition(point); ptr->clearDestination(); /* Force update of persistent data on map change, so that characters can respawn at the start of the map after a death or @@ -750,28 +749,37 @@ static void enqueueEvent(Actor *ptr, const DelayedEvent &e) void GameState::enqueueInsert(Actor *ptr) { - DelayedEvent e = { EVENT_INSERT, 0, 0, 0 }; - enqueueEvent(ptr, e); + DelayedEvent event; + event.type = EVENT_INSERT; + event.map = 0; + enqueueEvent(ptr, event); } void GameState::enqueueRemove(Actor *ptr) { - DelayedEvent e = { EVENT_REMOVE, 0, 0, 0 }; - enqueueEvent(ptr, e); + DelayedEvent event; + event.type = EVENT_REMOVE; + event.map = 0; + enqueueEvent(ptr, event); } -void GameState::enqueueWarp(Character *ptr, MapComposite *m, int x, int y) +void GameState::enqueueWarp(Character *ptr, + MapComposite *map, + const Point &point) { // When the player has just disconnected, better not wait for the pointer // to become invalid. if (!ptr->isConnected()) { - warp(ptr, m, x, y); + warp(ptr, map, point); return; } - DelayedEvent e = { EVENT_WARP, x, y, m }; - enqueueEvent(ptr, e); + DelayedEvent event; + event.type = EVENT_WARP; + event.point = point; + event.map = map; + enqueueEvent(ptr, event); } void GameState::sayAround(Actor *obj, const std::string &text) diff --git a/src/game-server/state.h b/src/game-server/state.h index c518972f..e8ed30a8 100644 --- a/src/game-server/state.h +++ b/src/game-server/state.h @@ -71,7 +71,7 @@ namespace GameState * @note No update may be in progress. * @note The character is destroyed, if needed. */ - void warp(Character *, MapComposite *, int x, int y); + void warp(Character *, MapComposite *, const Point &point); /** * Enqueues an insert event. @@ -90,7 +90,7 @@ namespace GameState * Enqueues a warp event. * @note The event will be executed at end of update. */ - void enqueueWarp(Character *, MapComposite *, int x, int y); + void enqueueWarp(Character *, MapComposite *, const Point &point); /** * Says something to an actor. diff --git a/src/game-server/trade.cpp b/src/game-server/trade.cpp index 0b906b1f..042719b2 100644 --- a/src/game-server/trade.cpp +++ b/src/game-server/trade.cpp @@ -249,8 +249,11 @@ void Trade::addItem(Character *c, int slot, int amount) later on. At worst, the transaction will be canceled at the end if the client lied. */ - TradedItem ti = { id, slot, amount }; - items->push_back(ti); + TradedItem tradedItem; + tradedItem.id = id; + tradedItem.slot = slot; + tradedItem.amount = amount; + items->push_back(tradedItem); MessageOut msg(GPMSG_TRADE_ADD_ITEM); msg.writeInt16(id); diff --git a/src/game-server/trade.h b/src/game-server/trade.h index 43b674fb..3e5fb3a3 100644 --- a/src/game-server/trade.h +++ b/src/game-server/trade.h @@ -77,8 +77,9 @@ class Trade struct TradedItem { - unsigned short id; - unsigned char slot, amount; + unsigned id; + unsigned slot; + int amount; }; typedef std::vector< TradedItem > TradedItems; diff --git a/src/game-server/triggerareacomponent.cpp b/src/game-server/triggerareacomponent.cpp index ebfe8580..7c32f097 100644 --- a/src/game-server/triggerareacomponent.cpp +++ b/src/game-server/triggerareacomponent.cpp @@ -34,7 +34,7 @@ void WarpAction::process(Actor *obj) { if (obj->getType() == OBJECT_CHARACTER) { - GameState::enqueueWarp(static_cast< Character * >(obj), mMap, mX, mY); + GameState::enqueueWarp(static_cast< Character * >(obj), mMap, mTargetPoint); } } diff --git a/src/game-server/triggerareacomponent.h b/src/game-server/triggerareacomponent.h index f766c815..6c2df7d1 100644 --- a/src/game-server/triggerareacomponent.h +++ b/src/game-server/triggerareacomponent.h @@ -40,14 +40,14 @@ class TriggerAction class WarpAction : public TriggerAction { public: - WarpAction(MapComposite *m, int x, int y) - : mMap(m), mX(x), mY(y) {} + WarpAction(MapComposite *m, const Point &point) + : mMap(m), mTargetPoint(point) {} virtual void process(Actor *obj); private: MapComposite *mMap; - unsigned short mX, mY; + Point mTargetPoint; }; class ScriptAction : public TriggerAction diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index cbdb088c..a02f84e4 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1650,7 +1650,7 @@ static int chr_warp(lua_State *s) x *= map->getTileWidth(); y *= map->getTileHeight(); } - GameState::enqueueWarp(q, m, x, y); + GameState::enqueueWarp(q, m, Point(x, y)); return 0; } -- cgit v1.2.3-70-g09d2 From 4b57962ee4c10e48956c2888199605bebdb17b8f Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Wed, 3 Apr 2013 14:32:57 +0200 Subject: Moved the Monster class to a Component Things done: - Allowed to create new Attributes outside of the protected scope of Being - Moved Monster to MonsterComponent - Some minor cleanup in the Attribute setting code of monsters --- src/game-server/being.cpp | 7 ++ src/game-server/being.h | 13 ++- src/game-server/combatcomponent.cpp | 2 +- src/game-server/commandhandler.cpp | 3 +- src/game-server/component.h | 1 + src/game-server/monster.cpp | 136 +++++++++++++++-------------- src/game-server/monster.h | 27 +++--- src/game-server/monstercombatcomponent.cpp | 20 ++--- src/game-server/monstercombatcomponent.h | 4 +- src/game-server/spawnareacomponent.cpp | 3 +- src/game-server/state.cpp | 21 +++-- src/scripting/lua.cpp | 33 ++++--- src/scripting/luautil.cpp | 8 +- src/scripting/luautil.h | 5 +- 14 files changed, 160 insertions(+), 123 deletions(-) (limited to 'src/game-server/commandhandler.cpp') diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 42d34046..2237f6a6 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -400,6 +400,13 @@ void Being::setAttribute(unsigned id, double value) } } +void Being::createAttribute(unsigned id, const AttributeManager::AttributeInfo + &attributeInfo) +{ + mAttributes.insert(std::pair + (id,Attribute(attributeInfo))); +} + const Attribute *Being::getAttribute(unsigned id) const { AttributeMap::const_iterator ret = mAttributes.find(id); diff --git a/src/game-server/being.h b/src/game-server/being.h index ce45d59c..41be5fff 100644 --- a/src/game-server/being.h +++ b/src/game-server/being.h @@ -139,6 +139,15 @@ class Being : public Actor */ void setAttribute(unsigned id, double value); + /** + * Creates an Attribute that did not exist before + * + * @param id The id of the attribute + * @param attributeInfo The info that describes the attribute + */ + void createAttribute(unsigned id, const AttributeManager::AttributeInfo + &attributeInfo); + /** * Gets an attribute or 0 if not existing. */ @@ -254,7 +263,6 @@ class Being : public Actor int getLastEmote() const { return mEmoteId; } - protected: /** * Update the being direction when moving so avoid directions desyncs * with other clients. @@ -262,8 +270,11 @@ class Being : public Actor void updateDirection(const Point ¤tPos, const Point &destPos); + protected: static const int TICKS_PER_HP_REGENERATION = 100; + /** Delay until move to next tile in miliseconds. */ + unsigned short mMoveTime; BeingAction mAction; AttributeMap mAttributes; StatusEffects mStatus; diff --git a/src/game-server/combatcomponent.cpp b/src/game-server/combatcomponent.cpp index 199126f6..469569b6 100644 --- a/src/game-server/combatcomponent.cpp +++ b/src/game-server/combatcomponent.cpp @@ -41,7 +41,7 @@ CombatComponent::~CombatComponent() void CombatComponent::update(Entity &entity) { - // Temponary for as long as Being is not split into Components + // Temporary for as long as Being is not split into Components // Prevents to implement all at once // TODO: remove this as soon as possible Being &being = static_cast(entity); diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index 68899e3c..35968286 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -732,7 +732,8 @@ static void handleSpawn(Character *player, std::string &args) // create the monsters and put them on the map for (int i = 0; i < value; ++i) { - Being *monster = new Monster(mc); + Being *monster = new Being(OBJECT_MONSTER); + monster->addComponent(new MonsterComponent(*monster, mc)); monster->setMap(map); monster->setPosition(pos); monster->clearDestination(); diff --git a/src/game-server/component.h b/src/game-server/component.h index 47e9dd0f..974cad0c 100644 --- a/src/game-server/component.h +++ b/src/game-server/component.h @@ -28,6 +28,7 @@ enum ComponentType CT_Effect, CT_Fighting, CT_Item, + CT_Monster, CT_Npc, CT_SpawnArea, CT_TriggerArea, diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index 25abb68a..9e45bb1d 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -53,27 +53,22 @@ double MonsterClass::getVulnerability(Element element) const return it->second; } -Monster::Monster(MonsterClass *specy): - Being(OBJECT_MONSTER), +MonsterComponent::MonsterComponent(Being &being, MonsterClass *specy): mSpecy(specy), mOwner(NULL) { LOG_DEBUG("Monster spawned! (id: " << mSpecy->getId() << ")."); - setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER); - setBlockType(BLOCKTYPE_MONSTER); + being.setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER); + being.setBlockType(BLOCKTYPE_MONSTER); /* * Initialise the attribute structures. */ - const AttributeManager::AttributeScope &mobAttr = - attributeManager->getAttributeScope(MonsterScope); - for (AttributeManager::AttributeScope::const_iterator it = mobAttr.begin(), - it_end = mobAttr.end(); it != it_end; ++it) + for (auto attrInfo : attributeManager->getAttributeScope(MonsterScope)) { - mAttributes.insert(std::pair< unsigned, Attribute > - (it->first, Attribute(*it->second))); + being.createAttribute(attrInfo.first, *attrInfo.second); } /* @@ -83,24 +78,22 @@ Monster::Monster(MonsterClass *specy): int mutation = specy->getMutation(); - for (AttributeMap::iterator it2 = mAttributes.begin(), - it2_end = mAttributes.end(); it2 != it2_end; ++it2) + for (auto &attribute : specy->getAttributes()) { - double attr = 0.0f; - - if (specy->hasAttribute(it2->first)) + double attributeValue = attribute.second; + if (mutation != 0) { - attr = specy->getAttribute(it2->first); - - setAttribute(it2->first, - mutation ? - attr * (100 + (rand() % (mutation * 2)) - mutation) / 100.0 : - attr); + double factor = 100 + (rand() % (mutation * 2)) - mutation; + attributeValue = attributeValue * factor / 100.0; } + being.setAttribute(attribute.first, attributeValue); } - setSize(specy->getSize()); - setGender(specy->getGender()); + being.setSize(specy->getSize()); + being.setGender(specy->getGender()); + + being.signal_died.connect(sigc::mem_fun(this, + &MonsterComponent::monsterDied)); // Set positions relative to target from which the monster can attack int dist = specy->getAttackDistance(); @@ -110,33 +103,34 @@ Monster::Monster(MonsterClass *specy): mAttackPositions.push_back(AttackPosition(0, dist, UP)); MonsterCombatComponent *combatComponent = - new MonsterCombatComponent(*this); - addComponent(combatComponent); + new MonsterCombatComponent(being, specy); + being.addComponent(combatComponent); double damageMutation = mutation ? (100.0 + (rand() % (mutation * 2)) - mutation) / 100.0 : 1.0; combatComponent->setDamageMutation(damageMutation); combatComponent->signal_damaged.connect( - sigc::mem_fun(this, &Monster::receivedDamage)); + sigc::mem_fun(this, &MonsterComponent::receivedDamage)); } -Monster::~Monster() +MonsterComponent::~MonsterComponent() { } -void Monster::update() +void MonsterComponent::update(Entity &entity) { - Being::update(); - if (mKillStealProtectedTimeout.justFinished()) mOwner = NULL; + // Temporary until all depedencies are available as component + Being &being = static_cast(entity); + // If dead, remove it - if (mAction == DEAD) + if (being.getAction() == DEAD) { if (mDecayTimeout.expired()) - GameState::enqueueRemove(this); + GameState::enqueueRemove(&being); return; } @@ -145,18 +139,19 @@ void Monster::update() { Script *script = ScriptManager::currentState(); script->prepare(mSpecy->getUpdateCallback()); - script->push(this); - script->execute(getMap()); + script->push(&entity); + script->execute(entity.getMap()); } - refreshTarget(); + refreshTarget(entity); // Cancel the rest when we have a target - if (getComponent()->getTarget()) + if (entity.getComponent()->getTarget()) return; // We have no target - let's wander around - if (mStrollTimeout.expired() && getPosition() == getDestination()) + if (mStrollTimeout.expired() && + being.getPosition() == being.getDestination()) { if (mKillStealProtectedTimeout.expired()) { @@ -164,23 +159,26 @@ void Monster::update() if (range) { Point randomPos(rand() % (range * 2 + 1) - - range + getPosition().x, + - range + being.getPosition().x, rand() % (range * 2 + 1) - - range + getPosition().y); + - range + being.getPosition().y); // Don't allow negative destinations, to avoid rounding // problems when divided by tile size if (randomPos.x >= 0 && randomPos.y >= 0) - setDestination(randomPos); + being.setDestination(randomPos); } mStrollTimeout.set(10 + rand() % 10); } } } -void Monster::refreshTarget() +void MonsterComponent::refreshTarget(Entity &entity) { + // Temporary until all depedencies are available as component + Being &being = static_cast(entity); + // We are dead and sadly not possible to keep attacking :( - if (mAction == DEAD) + if (being.getAction() == DEAD) return; // Check potential attack positions @@ -189,11 +187,12 @@ void Monster::refreshTarget() Point bestAttackPosition; // reset Target. We will find a new one if possible - getComponent()->clearTarget(); + entity.getComponent()->clearTarget(); // Iterate through objects nearby int aroundArea = Configuration::getValue("game_visualRange", 448); - for (BeingIterator i(getMap()->getAroundBeingIterator(this, aroundArea)); + for (BeingIterator i(entity.getMap()->getAroundBeingIterator(&being, + aroundArea)); i; ++i) { // We only want to attack player characters @@ -231,7 +230,8 @@ void Monster::refreshTarget() attackPosition.x += j->x; attackPosition.y += j->y; - int posPriority = calculatePositionPriority(attackPosition, + int posPriority = calculatePositionPriority(entity, + attackPosition, targetPriority); if (posPriority > bestTargetPriority) { @@ -243,26 +243,32 @@ void Monster::refreshTarget() } if (bestTarget) { - getComponent()->setTarget(bestTarget); - if (bestAttackPosition == getPosition()) + entity.getComponent()->setTarget(bestTarget); + if (bestAttackPosition == being.getPosition()) { - mAction = ATTACK; - updateDirection(getPosition(), bestTarget->getPosition()); + being.setAction(ATTACK); + being.updateDirection(being.getPosition(), + bestTarget->getPosition()); } else { - setDestination(bestAttackPosition); + being.setDestination(bestAttackPosition); } } } -int Monster::calculatePositionPriority(Point position, int targetPriority) +int MonsterComponent::calculatePositionPriority(Entity &entity, + Point position, + int targetPriority) { - Point thisPos = getPosition(); + // Temporary until all depedencies are available as component + Actor &actor = static_cast(entity); + + Point thisPos = actor.getPosition(); unsigned range = mSpecy->getTrackRange(); - Map *map = getMap()->getMap(); + Map *map = entity.getMap()->getMap(); int tileWidth = map->getTileWidth(); int tileHeight = map->getTileHeight(); @@ -276,7 +282,7 @@ int Monster::calculatePositionPriority(Point position, int targetPriority) Path path; path = map->findPath(thisPos.x / tileWidth, thisPos.y / tileHeight, position.x / tileWidth, position.y / tileHeight, - getWalkMask(), + actor.getWalkMask(), range); if (path.empty() || path.size() >= range) @@ -289,7 +295,7 @@ int Monster::calculatePositionPriority(Point position, int targetPriority) } } -void Monster::forgetTarget(Entity *entity) +void MonsterComponent::forgetTarget(Entity *entity) { Being *b = static_cast< Being * >(entity); { @@ -307,7 +313,7 @@ void Monster::forgetTarget(Entity *entity) } } -void Monster::changeAnger(Actor *target, int amount) +void MonsterComponent::changeAnger(Actor *target, int amount) { const EntityType type = target->getType(); if (type != OBJECT_MONSTER && type != OBJECT_CHARACTER) @@ -327,13 +333,13 @@ void Monster::changeAnger(Actor *target, int amount) // Forget target either when it's removed or died, whichever // happens first. aggressionInfo.removedConnection = - being->signal_removed.connect(sigc::mem_fun(this, &Monster::forgetTarget)); + being->signal_removed.connect(sigc::mem_fun(this, &MonsterComponent::forgetTarget)); aggressionInfo.diedConnection = - being->signal_died.connect(sigc::mem_fun(this, &Monster::forgetTarget)); + being->signal_died.connect(sigc::mem_fun(this, &MonsterComponent::forgetTarget)); } } -std::map Monster::getAngerList() const +std::map MonsterComponent::getAngerList() const { std::map result; std::map::const_iterator i, i_end; @@ -347,12 +353,8 @@ std::map Monster::getAngerList() const return result; } -void Monster::died() +void MonsterComponent::monsterDied(Being *monster) { - if (mAction == DEAD) - return; - - Being::died(); mDecayTimeout.set(DECAY_TIME); if (mExpReceivers.size() > 0) @@ -366,8 +368,8 @@ void Monster::died() if (p <= drop.probability) { - Actor *item = Item::create(getMap(), - getPosition(), + Actor *item = Item::create(monster->getMap(), + monster->getPosition(), drop.item, 1); GameState::enqueueInsert(item); } @@ -403,7 +405,7 @@ void Monster::died() } -void Monster::receivedDamage(Being *source, const Damage &damage, int hpLoss) +void MonsterComponent::receivedDamage(Being *source, const Damage &damage, int hpLoss) { if (source) changeAnger(source, hpLoss); diff --git a/src/game-server/monster.h b/src/game-server/monster.h index 3bd34a95..d1c8e900 100644 --- a/src/game-server/monster.h +++ b/src/game-server/monster.h @@ -139,6 +139,9 @@ class MonsterClass bool hasAttribute(int attribute) const { return (mAttributes.find(attribute) != mAttributes.end()); } + const std::map &getAttributes() const + { return mAttributes; } + /** Sets collision circle radius. */ void setSize(int size) { mSize = size; } @@ -246,7 +249,7 @@ class MonsterClass Script::Ref mDamageCallback; friend class MonsterManager; - friend class Monster; + friend class MonsterComponent; }; /** @@ -267,16 +270,18 @@ struct AttackPosition }; /** - * The class for a fightable monster with its own AI + * The component for a fightable monster with its own AI */ -class Monster : public Being +class MonsterComponent : public Component { public: + static const ComponentType type = CT_Monster; + /** Time in game ticks until ownership of a monster can change. */ static const int KILLSTEAL_PROTECTION_TIME = 100; - Monster(MonsterClass *); - ~Monster(); + MonsterComponent(Being &being, MonsterClass *); + ~MonsterComponent(); /** * Returns monster specy. @@ -287,14 +292,14 @@ class Monster : public Being /** * Performs one step of controller logic. */ - void update(); + void update(Entity &entity); - void refreshTarget(); + void refreshTarget(Entity &entity); /** - * Kills the being. + * Signal handler */ - void died(); + void monsterDied(Being *monster); void receivedDamage(Being *attacker, const Damage &damage, int hpLoss); @@ -313,7 +318,9 @@ class Monster : public Being private: static const int DECAY_TIME = 50; - int calculatePositionPriority(Point position, int targetPriority); + int calculatePositionPriority(Entity &entity, + Point position, + int targetPriority); MonsterClass *mSpecy; diff --git a/src/game-server/monstercombatcomponent.cpp b/src/game-server/monstercombatcomponent.cpp index dc669556..0fc0b483 100644 --- a/src/game-server/monstercombatcomponent.cpp +++ b/src/game-server/monstercombatcomponent.cpp @@ -23,16 +23,14 @@ #include "game-server/monster.h" #include "scripting/scriptmanager.h" -MonsterCombatComponent::MonsterCombatComponent(Monster &monster): +MonsterCombatComponent::MonsterCombatComponent(Being &monster, + MonsterClass *specy): CombatComponent(monster), mDamageMutation(0) { - // Take attacks from specy - std::vector &attacks = monster.getSpecy()->getAttackInfos(); - for (std::vector::iterator it = attacks.begin(), - it_end = attacks.end(); it != it_end; ++it) + for (auto &attack : specy->getAttackInfos()) { - addAttack(*it); + addAttack(attack); } } @@ -72,13 +70,11 @@ void MonsterCombatComponent::processAttack(Being *source, Attack &attack) * Calls the damage function in Being and updates the aggro list */ int MonsterCombatComponent::damage(Being &target, - Being *source, - const Damage &damage) + Being *source, + const Damage &damage) { - // Temporarily depend on monster as long as it does not exist as a component - Monster &monster = static_cast(target); Damage newDamage = damage; - MonsterClass *specy = monster.getSpecy(); + MonsterClass *specy = target.getComponent()->getSpecy(); float factor = specy->getVulnerability(newDamage.element); newDamage.base = newDamage.base * factor; newDamage.delta = newDamage.delta * factor; @@ -93,7 +89,7 @@ int MonsterCombatComponent::damage(Being &target, script->push(source); script->push(hpLoss); // TODO: add exact damage parameters as well - script->execute(monster.getMap()); + script->execute(target.getMap()); } return hpLoss; } diff --git a/src/game-server/monstercombatcomponent.h b/src/game-server/monstercombatcomponent.h index 766c7734..b65c48f4 100644 --- a/src/game-server/monstercombatcomponent.h +++ b/src/game-server/monstercombatcomponent.h @@ -26,12 +26,12 @@ #include "game-server/attack.h" #include "game-server/being.h" -class Monster; +class MonsterClass; class MonsterCombatComponent: public CombatComponent { public: - MonsterCombatComponent(Monster &monster); + MonsterCombatComponent(Being &monster, MonsterClass *specy); void processAttack(Being *source, Attack &attack); int damage(Being &target, Being *source, const Damage &damage); diff --git a/src/game-server/spawnareacomponent.cpp b/src/game-server/spawnareacomponent.cpp index d71c2502..557a2da5 100644 --- a/src/game-server/spawnareacomponent.cpp +++ b/src/game-server/spawnareacomponent.cpp @@ -67,7 +67,8 @@ void SpawnAreaComponent::update(Entity &entity) const int width = mZone.w; const int height = mZone.h; - Being *being = new Monster(mSpecy); + Being *being = new Being(OBJECT_MONSTER); + being->addComponent(new MonsterComponent(*being, mSpecy)); if (being->getModifiedAttribute(ATTR_MAX_HP) <= 0) { diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index d3a29860..74bd87e4 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -270,9 +270,10 @@ static void informPlayer(MapComposite *map, Character *p) case OBJECT_MONSTER: { - Monster *q = static_cast< Monster * >(o); - enterMsg.writeInt16(q->getSpecy()->getId()); - enterMsg.writeString(q->getName()); + MonsterComponent *monsterComponent = + o->getComponent(); + enterMsg.writeInt16(monsterComponent->getSpecy()->getId()); + enterMsg.writeString(o->getName()); } break; case OBJECT_NPC: @@ -567,10 +568,13 @@ bool GameState::insert(Entity *ptr) break; case OBJECT_MONSTER: + { + MonsterComponent *monsterComponent = + obj->getComponent(); LOG_DEBUG("Monster inserted: " - << static_cast(obj)->getSpecy()->getId()); + << monsterComponent->getSpecy()->getId()); break; - + } case OBJECT_ACTOR: case OBJECT_OTHER: default: @@ -641,10 +645,13 @@ void GameState::remove(Entity *ptr) break; case OBJECT_MONSTER: + { + MonsterComponent *monsterComponent = + ptr->getComponent(); LOG_DEBUG("Monster removed: " - << static_cast(ptr)->getSpecy()->getId()); + << monsterComponent->getSpecy()->getId()); break; - + } case OBJECT_ACTOR: case OBJECT_OTHER: default: diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index a02f84e4..993508a2 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -355,12 +355,13 @@ static int monster_create(lua_State *s) const int y = luaL_checkint(s, 3); MapComposite *m = checkCurrentMap(s); - Monster *q = new Monster(monsterClass); - q->setMap(m); - q->setPosition(Point(x, y)); - GameState::enqueueInsert(q); + Being *monster = new Being(OBJECT_MONSTER); + monster->addComponent(new MonsterComponent(*monster, monsterClass)); + monster->setMap(m); + monster->setPosition(Point(x, y)); + GameState::enqueueInsert(monster); - lua_pushlightuserdata(s, q); + lua_pushlightuserdata(s, monster); return 1; } @@ -374,7 +375,7 @@ static int monster_create(lua_State *s) static int monster_remove(lua_State *s) { bool monsterRemoved = false; - if (Monster *m = getMonster(s, 1)) + if (Being *m = getMonster(s, 1)) { GameState::remove(m); monsterRemoved = true; @@ -2245,8 +2246,10 @@ static int chr_take_special(lua_State *s) */ static int monster_get_id(lua_State *s) { - Monster *monster = checkMonster(s, 1); - lua_pushinteger(s, monster->getSpecy()->getId()); + Being *monster = checkMonster(s, 1); + MonsterComponent *monsterComponent = + monster->getComponent(); + lua_pushinteger(s, monsterComponent->getSpecy()->getId()); return 1; } @@ -2258,10 +2261,10 @@ static int monster_get_id(lua_State *s) */ static int monster_change_anger(lua_State *s) { - Monster *monster = checkMonster(s, 1); + Being *monster = checkMonster(s, 1); Being *being = checkBeing(s, 2); const int anger = luaL_checkint(s, 3); - monster->changeAnger(being, anger); + monster->getComponent()->changeAnger(being, anger); return 0; } @@ -2272,9 +2275,9 @@ static int monster_change_anger(lua_State *s) */ static int monster_drop_anger(lua_State *s) { - Monster *monster = checkMonster(s, 1); + Being *monster = checkMonster(s, 1); Being *being = checkBeing(s, 2); - monster->forgetTarget(being); + monster->getComponent()->forgetTarget(being); return 0; } @@ -2286,8 +2289,10 @@ static int monster_drop_anger(lua_State *s) */ static int monster_get_angerlist(lua_State *s) { - Monster *monster = checkMonster(s, 1); - pushSTLContainer(s, monster->getAngerList()); + Being *monster = checkMonster(s, 1); + MonsterComponent *monsterComponent = + monster->getComponent(); + pushSTLContainer(s, monsterComponent->getAngerList()); return 1; } diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp index 24e9edf7..d082cbe7 100644 --- a/src/scripting/luautil.cpp +++ b/src/scripting/luautil.cpp @@ -158,14 +158,14 @@ ItemClass *getItemClass(lua_State *s, int p) return itemClass; } -Monster *getMonster(lua_State *s, int p) +Being *getMonster(lua_State *s, int p) { if (!lua_islightuserdata(s, p)) return 0; Entity *t = static_cast(lua_touserdata(s, p)); if (t->getType() != OBJECT_MONSTER) return 0; - return static_cast(t); + return static_cast(t); } MonsterClass *getMonsterClass(lua_State *s, int p) @@ -220,9 +220,9 @@ ItemClass *checkItemClass(lua_State *s, int p) return itemClass; } -Monster *checkMonster(lua_State *s, int p) +Being *checkMonster(lua_State *s, int p) { - Monster *monster = getMonster(s, p); + Being *monster = getMonster(s, p); luaL_argcheck(s, monster, p, "monster expected"); return monster; } diff --git a/src/scripting/luautil.h b/src/scripting/luautil.h index dd63c0f7..e76a15a1 100644 --- a/src/scripting/luautil.h +++ b/src/scripting/luautil.h @@ -43,7 +43,6 @@ class Entity; class ItemClass; class MapComposite; class MapObject; -class Monster; class MonsterClass; class StatusEffect; @@ -169,14 +168,14 @@ Script * getScript(lua_State *s); Being * getBeing(lua_State *s, int p); Character * getCharacter(lua_State *s, int p); ItemClass * getItemClass(lua_State *s, int p); -Monster * getMonster(lua_State *s, int p); +Being * getMonster(lua_State *s, int p); MonsterClass * getMonsterClass(lua_State *s, int p); Being * getNpc(lua_State *s, int p); Being * checkBeing(lua_State *s, int p); Character * checkCharacter(lua_State *s, int p); ItemClass * checkItemClass(lua_State *s, int p); -Monster * checkMonster(lua_State *s, int p); +Being * checkMonster(lua_State *s, int p); MonsterClass * checkMonsterClass(lua_State *s, int p); Being * checkNpc(lua_State *s, int p); int checkSkill(lua_State *s, int p); -- cgit v1.2.3-70-g09d2 From c1ba76b936c04dbdcdcc3ed86f919a949c8aa63f Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Wed, 10 Apr 2013 17:48:20 +0200 Subject: Fixed @kill killing yourself --- src/game-server/commandhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/game-server/commandhandler.cpp') diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index 35968286..d38828fe 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -1239,7 +1239,7 @@ static void handleKill(Character *player, std::string &args) } // kill the player - player->setAttribute(ATTR_HP, 0); + other->setAttribute(ATTR_HP, 0); // feedback std::stringstream targetMsg; -- cgit v1.2.3-70-g09d2 From aa04597c5f8bb806996d604699fc8ebff6d53bdd Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Sat, 6 Apr 2013 21:36:50 +0200 Subject: Converted the Character class into a component A CharacterData was created as a proxy class in order to allow using the old serialization method. --- src/account-server/character.h | 31 ++- src/account-server/storage.cpp | 4 +- src/common/permissionmanager.cpp | 15 +- src/common/permissionmanager.h | 8 +- src/game-server/accountconnection.cpp | 47 ++-- src/game-server/accountconnection.h | 20 +- src/game-server/attack.cpp | 8 +- src/game-server/attack.h | 12 +- src/game-server/being.cpp | 2 + src/game-server/being.h | 11 +- src/game-server/buysell.cpp | 12 +- src/game-server/buysell.h | 6 +- src/game-server/character.cpp | 318 +++++++++++++------------- src/game-server/character.h | 379 +++++++++++++++++++++++++------ src/game-server/combatcomponent.cpp | 4 +- src/game-server/commandhandler.cpp | 318 +++++++++++++++----------- src/game-server/commandhandler.h | 4 +- src/game-server/component.h | 1 + src/game-server/gamehandler.cpp | 181 ++++++++++----- src/game-server/gamehandler.h | 19 +- src/game-server/inventory.cpp | 11 +- src/game-server/inventory.h | 5 +- src/game-server/mapcomposite.cpp | 4 +- src/game-server/mapcomposite.h | 6 +- src/game-server/monster.cpp | 28 +-- src/game-server/monster.h | 10 +- src/game-server/npc.cpp | 22 +- src/game-server/npc.h | 10 +- src/game-server/postman.h | 29 +-- src/game-server/quest.cpp | 46 ++-- src/game-server/quest.h | 17 +- src/game-server/state.cpp | 72 +++--- src/game-server/state.h | 6 +- src/game-server/trade.cpp | 50 ++-- src/game-server/trade.h | 16 +- src/game-server/triggerareacomponent.cpp | 2 +- src/scripting/lua.cpp | 150 ++++++------ src/scripting/luascript.cpp | 14 +- src/scripting/luascript.h | 6 +- src/scripting/luautil.cpp | 8 +- src/scripting/luautil.h | 6 +- src/serialize/characterdata.h | 20 +- 42 files changed, 1178 insertions(+), 760 deletions(-) (limited to 'src/game-server/commandhandler.cpp') diff --git a/src/account-server/character.h b/src/account-server/character.h index a6ac43ed..a9aa810b 100644 --- a/src/account-server/character.h +++ b/src/account-server/character.h @@ -47,6 +47,12 @@ struct AttributeValue double base; /**< Base value of the attribute. */ double modified; /**< Value after various modifiers have been applied. */ + + double getBase() const + { return base; } + + double getModifiedAttribute() const + { return modified; } }; struct SpecialValue @@ -62,6 +68,15 @@ struct SpecialValue unsigned currentMana; }; +struct Status +{ + Status() + : time(0) + {} + + unsigned time; +}; + /** * Stores attributes by their id. */ @@ -76,7 +91,7 @@ class CharacterData { public: - CharacterData(const std::string &name, int id = -1); + CharacterData(const std::string &name, int id = -1); /** * Gets the database id of the character. @@ -154,6 +169,9 @@ class CharacterData void setModAttribute(unsigned id, double value) { mAttributes[id].modified = value; } + const AttributeMap &getAttributes() const + { return mAttributes; } + int getSkillSize() const { return mExperience.size(); } @@ -176,15 +194,15 @@ class CharacterData * Get / Set a status effects */ void applyStatusEffect(int id, int time) - { mStatusEffects[id] = time; } + { mStatusEffects[id].time = time; } int getStatusEffectSize() const { return mStatusEffects.size(); } - const std::map::const_iterator getStatusEffectBegin() const + const std::map::const_iterator getStatusEffectBegin() const { return mStatusEffects.begin(); } - const std::map::const_iterator getStatusEffectEnd() const + const std::map::const_iterator getStatusEffectEnd() const { return mStatusEffects.end(); } /** @@ -283,7 +301,7 @@ class CharacterData Point mPos; //!< Position the being is at. AttributeMap mAttributes; //!< Attributes. std::map mExperience; //!< Skill Experience. - std::map mStatusEffects; //!< Status Effects + std::map mStatusEffects; //!< Status Effects std::map mKillCount; //!< Kill Count SpecialMap mSpecials; unsigned short mMapId; //!< Map the being is on. @@ -299,9 +317,6 @@ class CharacterData //!< belongs to. friend class AccountHandler; friend class Storage; - // Set as a friend, but still a lot of redundant accessors. FIXME. - template< class T > - friend void serializeCharacterData(const T &data, MessageOut &msg); }; /** diff --git a/src/account-server/storage.cpp b/src/account-server/storage.cpp index 5275f0b0..dd8cf9ac 100644 --- a/src/account-server/storage.cpp +++ b/src/account-server/storage.cpp @@ -910,12 +910,12 @@ bool Storage::updateCharacter(CharacterData *character) } try { - std::map::const_iterator status_it; + std::map::const_iterator status_it; for (status_it = character->getStatusEffectBegin(); status_it != character->getStatusEffectEnd(); status_it++) { insertStatusEffect(character->getDatabaseID(), - status_it->first, status_it->second); + status_it->first, status_it->second.time); } } catch (const dal::DbSqlQueryExecFailure& e) diff --git a/src/common/permissionmanager.cpp b/src/common/permissionmanager.cpp index 5510fd7c..ee970bd9 100644 --- a/src/common/permissionmanager.cpp +++ b/src/common/permissionmanager.cpp @@ -105,9 +105,10 @@ void PermissionManager::reload() } -PermissionManager::Result PermissionManager::checkPermission(const Character* character, std::string permission) +PermissionManager::Result PermissionManager::checkPermission(const Being* character, std::string permission) { - return checkPermission(character->getAccountLevel(), permission); + return checkPermission(character->getComponent() + ->getAccountLevel(), permission); } PermissionManager::Result PermissionManager::checkPermission(unsigned char level, std::string permission) @@ -139,12 +140,13 @@ unsigned char PermissionManager::getMaskFromAlias(const std::string &alias) } } -std::list PermissionManager::getPermissionList(const Character* character) +std::list PermissionManager::getPermissionList(const Being* character) { std::list result; std::map::iterator i; - unsigned char mask = character->getAccountLevel(); + unsigned char mask = character->getComponent() + ->getAccountLevel(); for (i = permissions.begin(); i != permissions.end(); i++) { @@ -157,12 +159,13 @@ std::list PermissionManager::getPermissionList(const Character* cha return result; } -std::list PermissionManager::getClassList(const Character* character) +std::list PermissionManager::getClassList(const Being* character) { std::list result; std::map::iterator i; - unsigned char mask = character->getAccountLevel(); + unsigned char mask = character->getComponent() + ->getAccountLevel(); for (i = aliases.begin(); i != aliases.end(); i++) { diff --git a/src/common/permissionmanager.h b/src/common/permissionmanager.h index bf36f658..a78f581d 100644 --- a/src/common/permissionmanager.h +++ b/src/common/permissionmanager.h @@ -25,7 +25,7 @@ #include #include -class Character; +class Being; namespace PermissionManager { @@ -48,7 +48,7 @@ namespace PermissionManager /** * Returns if the characters account has the given permission */ - Result checkPermission(const Character* character, std::string permission); + Result checkPermission(const Being* character, std::string permission); Result checkPermission(unsigned char level, std::string permission); /** @@ -59,12 +59,12 @@ namespace PermissionManager /** * Gets a list of all permissions the character is having */ - std::list getPermissionList(const Character* character); + std::list getPermissionList(const Being* character); /** * Gets a list of all permissions classes the character is having */ - std::list getClassList(const Character* character); + std::list getClassList(const Being* character); } // namespace PermissionManager diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp index 44858fcd..bdf44b4e 100644 --- a/src/game-server/accountconnection.cpp +++ b/src/game-server/accountconnection.cpp @@ -102,11 +102,12 @@ bool AccountConnection::start(int gameServerPort) return true; } -void AccountConnection::sendCharacterData(Character *p) +void AccountConnection::sendCharacterData(Entity *p) { MessageOut msg(GAMSG_PLAYER_DATA); - msg.writeInt32(p->getDatabaseID()); - serializeCharacterData(*p, msg); + auto *characterComponent = p->getComponent(); + msg.writeInt32(characterComponent->getDatabaseID()); + serializeCharacterData(*characterComponent->getCharacterData(), msg); send(msg); } @@ -154,8 +155,9 @@ void AccountConnection::processMessage(MessageIn &msg) case AGMSG_PLAYER_ENTER: { std::string token = msg.readString(MAGIC_TOKEN_LENGTH); - Character *ptr = new Character(msg); - gameHandler->addPendingCharacter(token, ptr); + Being *character = new Being(OBJECT_CHARACTER); + character->addComponent(new CharacterComponent(*character, msg)); + gameHandler->addPendingCharacter(token, character); } break; case AGMSG_ACTIVE_MAP: @@ -241,7 +243,7 @@ void AccountConnection::processMessage(MessageIn &msg) case CGMSG_POST_RESPONSE: { // get the character - Character *character = postMan->getCharacter(msg.readInt32()); + Being *character = postMan->getCharacter(msg.readInt32()); // check character is still valid if (!character) @@ -259,7 +261,7 @@ void AccountConnection::processMessage(MessageIn &msg) case CGMSG_STORE_POST_RESPONSE: { // get character - Character *character = postMan->getCharacter(msg.readInt32()); + Being *character = postMan->getCharacter(msg.readInt32()); // check character is valid if (!character) @@ -288,21 +290,21 @@ void AccountConnection::playerReconnectAccount(int id, send(msg); } -void AccountConnection::requestCharacterVar(Character *ch, +void AccountConnection::requestCharacterVar(Entity *ch, const std::string &name) { MessageOut msg(GAMSG_GET_VAR_CHR); - msg.writeInt32(ch->getDatabaseID()); + msg.writeInt32(ch->getComponent()->getDatabaseID()); msg.writeString(name); send(msg); } -void AccountConnection::updateCharacterVar(Character *ch, +void AccountConnection::updateCharacterVar(Entity *ch, const std::string &name, const std::string &value) { MessageOut msg(GAMSG_SET_VAR_CHR); - msg.writeInt32(ch->getDatabaseID()); + msg.writeInt32(ch->getComponent()->getDatabaseID()); msg.writeString(name); msg.writeString(value); send(msg); @@ -328,10 +330,10 @@ void AccountConnection::updateWorldVar(const std::string &name, send(msg); } -void AccountConnection::banCharacter(Character *ch, int duration) +void AccountConnection::banCharacter(Entity *ch, int duration) { MessageOut msg(GAMSG_BAN_PLAYER); - msg.writeInt32(ch->getDatabaseID()); + msg.writeInt32(ch->getComponent()->getDatabaseID()); msg.writeInt32(duration); send(msg); } @@ -357,9 +359,12 @@ void AccountConnection::sendStatistics() switch (t->getType()) { case OBJECT_CHARACTER: - players.push_back - (static_cast< Character * >(t)->getDatabaseID()); + { + auto *characterComponent = + t->getComponent(); + players.push_back(characterComponent->getDatabaseID()); break; + } case OBJECT_MONSTER: ++nbMonsters; break; @@ -379,13 +384,13 @@ void AccountConnection::sendStatistics() send(msg); } -void AccountConnection::sendPost(Character *c, MessageIn &msg) +void AccountConnection::sendPost(Entity *c, MessageIn &msg) { // send message to account server with id of sending player, // the id of receiving player, the letter receiver and contents, and attachments LOG_DEBUG("Sending GCMSG_STORE_POST."); MessageOut out(GCMSG_STORE_POST); - out.writeInt32(c->getDatabaseID()); + out.writeInt32(c->getComponent()->getDatabaseID()); out.writeString(msg.readString()); // name of receiver out.writeString(msg.readString()); // content of letter while (msg.getUnreadLength()) // attachments @@ -397,7 +402,7 @@ void AccountConnection::sendPost(Character *c, MessageIn &msg) send(out); } -void AccountConnection::getPost(Character *c) +void AccountConnection::getPost(Entity *c) { // let the postman know to expect some post for this character postMan->addCharacter(c); @@ -405,14 +410,14 @@ void AccountConnection::getPost(Character *c) // send message to account server with id of retrieving player LOG_DEBUG("Sending GCMSG_REQUEST_POST"); MessageOut out(GCMSG_REQUEST_POST); - out.writeInt32(c->getDatabaseID()); + out.writeInt32(c->getComponent()->getDatabaseID()); send(out); } -void AccountConnection::changeAccountLevel(Character *c, int level) +void AccountConnection::changeAccountLevel(Entity *c, int level) { MessageOut msg(GAMSG_CHANGE_ACCOUNT_LEVEL); - msg.writeInt32(c->getDatabaseID()); + msg.writeInt32(c->getComponent()->getDatabaseID()); msg.writeInt16(level); send(msg); } diff --git a/src/game-server/accountconnection.h b/src/game-server/accountconnection.h index a144a1d1..2ad79dd2 100644 --- a/src/game-server/accountconnection.h +++ b/src/game-server/accountconnection.h @@ -24,7 +24,7 @@ #include "net/messageout.h" #include "net/connection.h" -class Character; +class Entity; class MapComposite; /** @@ -45,7 +45,7 @@ class AccountConnection : public Connection /** * Sends data of a given character. */ - void sendCharacterData(Character *); + void sendCharacterData(Entity *); /** * Prepares the account server for a reconnecting player @@ -55,19 +55,19 @@ class AccountConnection : public Connection /** * Requests the value of a character-bound variable from the database. */ - void requestCharacterVar(Character *, const std::string &); + void requestCharacterVar(Entity *, const std::string &); /** * Pushes a new character-bound value to the database. */ - void updateCharacterVar(Character *, const std::string &name, - const std::string &value); + void updateCharacterVar(Entity *, const std::string &name, + const std::string &value); /** * Pushes a new value of a map variable to the account server. */ void updateMapVar(MapComposite *, const std::string &name, - const std::string &value); + const std::string &value); /** * Pushes a new value of a world variable to the account server. @@ -78,7 +78,7 @@ class AccountConnection : public Connection /** * Sends ban message. */ - void banCharacter(Character *, int); + void banCharacter(Entity *, int); /** * Gathers statistics and sends them. @@ -88,17 +88,17 @@ class AccountConnection : public Connection /** * Send letter */ - void sendPost(Character *, MessageIn &); + void sendPost(Entity *, MessageIn &); /** * Get post */ - void getPost(Character *); + void getPost(Entity *); /** * Change Account Level */ - void changeAccountLevel(Character *, int); + void changeAccountLevel(Entity *, int); /** * Sends all changed player data to the account server to minimize diff --git a/src/game-server/attack.cpp b/src/game-server/attack.cpp index a1300e4d..6ca85fb8 100644 --- a/src/game-server/attack.cpp +++ b/src/game-server/attack.cpp @@ -72,13 +72,13 @@ AttackInfo *AttackInfo::readAttackNode(xmlNodePtr node) return attack; } -void Attacks::add(AttackInfo *attackInfo) +void Attacks::add(CombatComponent *combatComponent, AttackInfo *attackInfo) { mAttacks.push_back(Attack(attackInfo)); - attack_added.emit(*mAttacks.rbegin()); + attack_added.emit(combatComponent, *mAttacks.rbegin()); } -void Attacks::remove(AttackInfo *attackInfo) +void Attacks::remove(CombatComponent *combatComponent, AttackInfo *attackInfo) { for (std::vector::iterator it = mAttacks.begin(), it_end = mAttacks.end(); it != it_end; ++it) @@ -87,7 +87,7 @@ void Attacks::remove(AttackInfo *attackInfo) { if (mCurrentAttack && mCurrentAttack->getAttackInfo() == attackInfo) mCurrentAttack = 0; - attack_removed.emit(*it); + attack_removed.emit(combatComponent, *it); mAttacks.erase(it); return; } diff --git a/src/game-server/attack.h b/src/game-server/attack.h index cecb4fd5..348a94bb 100644 --- a/src/game-server/attack.h +++ b/src/game-server/attack.h @@ -35,6 +35,8 @@ #include "game-server/timeout.h" +class CombatComponent; + /** * Structure that describes the severity and nature of an attack a being can * be hit by. @@ -68,7 +70,7 @@ struct Damage * Class that stores information about an auto-attack */ -class Character; +class CharacterComponent; struct AttackInfo { @@ -178,8 +180,8 @@ class Attacks : public sigc::trackable mCurrentAttack(0) {} - void add(AttackInfo *); - void remove(AttackInfo *); + void add(CombatComponent *combatComponent, AttackInfo *); + void remove(CombatComponent *combatComponent, AttackInfo *); void markAttackAsTriggered(); Attack *getTriggerableAttack(); void startAttack(Attack *attack); @@ -191,8 +193,8 @@ class Attacks : public sigc::trackable unsigned getNumber() { return mAttacks.size(); } - sigc::signal attack_added; - sigc::signal attack_removed; + sigc::signal attack_added; + sigc::signal attack_removed; private: std::vector mAttacks; diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 2237f6a6..b50a5fac 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -483,6 +483,8 @@ void Being::recalculateBaseAttribute(unsigned attr) void Being::updateDerivedAttributes(unsigned attr) { + signal_attribute_changed.emit(this, attr); + LOG_DEBUG("Being: Updating derived attribute(s) of: " << attr); // Handle default actions before handing over to the script engine diff --git a/src/game-server/being.h b/src/game-server/being.h index 41be5fff..de30ad60 100644 --- a/src/game-server/being.h +++ b/src/game-server/being.h @@ -153,6 +153,9 @@ class Being : public Actor */ const Attribute *getAttribute(unsigned id) const; + const AttributeMap &getAttributes() const + { return mAttributes; } + /** * Gets an attribute base. */ @@ -197,14 +200,14 @@ class Being : public Actor * attributes if it has changed. * @returns Whether it was changed. */ - virtual void recalculateBaseAttribute(unsigned); + void recalculateBaseAttribute(unsigned); /** * Attribute has changed, recalculate base value of dependant * attributes (and handle other actions for the modified * attribute) */ - virtual void updateDerivedAttributes(unsigned); + void updateDerivedAttributes(unsigned); /** * Sets a statuseffect on this being @@ -221,6 +224,9 @@ class Being : public Actor */ bool hasStatusEffect(int id) const; + const StatusEffects &getStatusEffects() const + { return mStatus; } + /** * Returns the time of the status effect if in effect, or 0 if not */ @@ -251,6 +257,7 @@ class Being : public Actor { script->assignCallback(mRecalculateBaseAttributeCallback); } sigc::signal signal_died; + sigc::signal signal_attribute_changed; /** * Activate an emote flag on the being. diff --git a/src/game-server/buysell.cpp b/src/game-server/buysell.cpp index 1e63d523..e73e13c5 100644 --- a/src/game-server/buysell.cpp +++ b/src/game-server/buysell.cpp @@ -30,15 +30,15 @@ #include -BuySell::BuySell(Character *c, bool sell): +BuySell::BuySell(Being *c, bool sell): mCurrencyId(ATTR_GP), mChar(c), mSell(sell) { - c->setBuySell(this); + c->getComponent()->setBuySell(this); } BuySell::~BuySell() { - mChar->setBuySell(NULL); + mChar->getComponent()->setBuySell(nullptr); } void BuySell::cancel() @@ -75,7 +75,9 @@ int BuySell::registerPlayerItems() // We parse the player inventory and add all item // in a sell list. - const InventoryData &inventoryData = mChar->getPossessions().getInventory(); + auto *component = mChar->getComponent(); + const InventoryData &inventoryData = + component->getPossessions().getInventory(); for (InventoryData::const_iterator it = inventoryData.begin(), it_end = inventoryData.end(); it != it_end; ++it) { @@ -144,7 +146,7 @@ bool BuySell::start(Actor *actor) msg.writeInt16(i->amount); msg.writeInt16(i->cost); } - mChar->getClient()->send(msg); + mChar->getComponent()->getClient()->send(msg); return true; } diff --git a/src/game-server/buysell.h b/src/game-server/buysell.h index 72da2ce6..8450aff1 100644 --- a/src/game-server/buysell.h +++ b/src/game-server/buysell.h @@ -23,7 +23,7 @@ #include -class Character; +class Being; class Actor; class BuySell @@ -33,7 +33,7 @@ class BuySell /** * Sets up a trade between a character and an NPC. */ - BuySell(Character *, bool sell); + BuySell(Being *, bool sell); /** * Cancels the trade. @@ -80,7 +80,7 @@ class BuySell /** The attribute ID of the currency to use. Hardcoded for now (FIXME) */ unsigned mCurrencyId; - Character *mChar; /**< Character involved. */ + Being *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 e52747fd..63621491 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -49,30 +49,29 @@ #include // Experience curve related values -const float Character::EXPCURVE_EXPONENT = 3.0f; -const float Character::EXPCURVE_FACTOR = 10.0f; -const float Character::LEVEL_SKILL_PRECEDENCE_FACTOR = 0.75f; -const float Character::EXP_LEVEL_FLEXIBILITY = 1.0f; +const float CharacterComponent::EXPCURVE_EXPONENT = 3.0f; +const float CharacterComponent::EXPCURVE_FACTOR = 10.0f; +const float CharacterComponent::LEVEL_SKILL_PRECEDENCE_FACTOR = 0.75f; +const float CharacterComponent::EXP_LEVEL_FLEXIBILITY = 1.0f; -Script::Ref Character::mDeathCallback; -Script::Ref Character::mDeathAcceptedCallback; -Script::Ref Character::mLoginCallback; +Script::Ref CharacterComponent::mDeathCallback; +Script::Ref CharacterComponent::mDeathAcceptedCallback; +Script::Ref CharacterComponent::mLoginCallback; -static bool executeCallback(Script::Ref function, Character *character) +static bool executeCallback(Script::Ref function, Entity &entity) { if (!function.isValid()) return false; Script *script = ScriptManager::currentState(); script->prepare(function); - script->push(character); - script->execute(character->getMap()); + script->push(&entity); + script->execute(entity.getMap()); return true; } -Character::Character(MessageIn &msg): - Being(OBJECT_CHARACTER), +CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): mClient(NULL), mConnected(true), mTransactionHandler(NULL), @@ -88,29 +87,35 @@ Character::Character(MessageIn &msg): mTransaction(TRANS_NONE), mTalkNpcId(0), mNpcThread(0), - mKnuckleAttackInfo(0) + mKnuckleAttackInfo(0), + mBaseEntity(&entity) { - const AttributeManager::AttributeScope &attr = + // Temporary until all dependencies are in a component + Being &being = static_cast(entity); + + mCharacterData = new CharacterData(&being, this); + + const AttributeManager::AttributeScope &attributes = attributeManager->getAttributeScope(CharacterScope); LOG_DEBUG("Character creation: initialisation of " - << attr.size() << " attributes."); - for (AttributeManager::AttributeScope::const_iterator it1 = attr.begin(), - it1_end = attr.end(); it1 != it1_end; ++it1) - mAttributes.insert(std::make_pair(it1->first, Attribute(*it1->second))); + << attributes.size() << " attributes."); + for (auto attributeScope : attributes) + being.createAttribute(attributeScope.first, *attributeScope.second); + - setWalkMask(Map::BLOCKMASK_WALL); - setBlockType(BLOCKTYPE_CHARACTER); + being.setWalkMask(Map::BLOCKMASK_WALL); + being.setBlockType(BLOCKTYPE_CHARACTER); - CombatComponent *combatcomponent = new CombatComponent(*this); - addComponent(combatcomponent); + CombatComponent *combatcomponent = new CombatComponent(being); + entity.addComponent(combatcomponent); combatcomponent->getAttacks().attack_added.connect( - sigc::mem_fun(this, &Character::attackAdded)); + sigc::mem_fun(this, &CharacterComponent::attackAdded)); combatcomponent->getAttacks().attack_removed.connect( - sigc::mem_fun(this, &Character::attackRemoved)); + sigc::mem_fun(this, &CharacterComponent::attackRemoved)); // Default knuckle attack - int damageBase = this->getModifiedAttribute(ATTR_STR); + int damageBase = being.getModifiedAttribute(ATTR_STR); int damageDelta = damageBase / 2; Damage knuckleDamage; knuckleDamage.skill = skillManager->getDefaultSkillId(); @@ -126,34 +131,38 @@ Character::Character(MessageIn &msg): // Get character data. mDatabaseID = msg.readInt32(); - setName(msg.readString()); - deserializeCharacterData(*this, msg); - mOld = getPosition(); - Inventory(this).initialize(); - modifiedAllAttribute(); - setSize(16); + being.setName(msg.readString()); + + deserializeCharacterData(*mCharacterData, msg); + + Inventory(&being, mPossessions).initialize(); + modifiedAllAttributes(entity); + being.setSize(16); + + being.signal_attribute_changed.connect(sigc::mem_fun( + this, &CharacterComponent::attributeChanged)); } -Character::~Character() +CharacterComponent::~CharacterComponent() { delete mNpcThread; delete mKnuckleAttackInfo; } -void Character::update() +void CharacterComponent::update(Entity &entity) { - // First, deal with being generic updates - Being::update(); + // Temporary until all dependencies are available as component + Being &being = static_cast(entity); // Update character level if needed. if (mRecalculateLevel) { mRecalculateLevel = false; - recalculateLevel(); + recalculateLevel(entity); } // Dead character: don't regenerate anything else - if (getAction() == DEAD) + if (being.getAction() == DEAD) return; // Update special recharge @@ -169,9 +178,9 @@ void Character::update() { Script *script = ScriptManager::currentState(); script->prepare(s.specialInfo->rechargedCallback); - script->push(this); + script->push(&entity); script->push(s.specialInfo->id); - script->execute(getMap()); + script->execute(entity.getMap()); } } } @@ -181,53 +190,46 @@ void Character::update() sendSpecialUpdate(); mSpecialUpdateNeeded = false; } - - mStatusEffects.clear(); - StatusEffects::iterator it = mStatus.begin(); - while (it != mStatus.end()) - { - mStatusEffects[it->first] = it->second.time; - it++; - } } -void Character::died() +void CharacterComponent::characterDied(Being *being) { - Being::died(); - executeCallback(mDeathCallback, this); + executeCallback(mDeathCallback, *being); } -void Character::respawn() +void CharacterComponent::respawn(Entity &entity) { - if (mAction != DEAD) + // Temporary until all dependencies are available as component + Being &being = static_cast(entity); + + if (being.getAction() != DEAD) { - LOG_WARN("Character \"" << getName() + LOG_WARN("Character \"" << being.getName() << "\" tried to respawn without being dead"); return; } // Make it alive again - setAction(STAND); + being.setAction(STAND); // Reset target - getComponent()->clearTarget(); + entity.getComponent()->clearTarget(); // Execute respawn callback when set - if (executeCallback(mDeathAcceptedCallback, this)) + if (executeCallback(mDeathAcceptedCallback, entity)) return; // No script respawn callback set - fall back to hardcoded logic - mAttributes[ATTR_HP].setBase(mAttributes[ATTR_MAX_HP].getModifiedAttribute()); - updateDerivedAttributes(ATTR_HP); + being.setAttribute(ATTR_HP, being.getModifiedAttribute(ATTR_MAX_HP)); // Warp back to spawn point. int spawnMap = Configuration::getValue("char_respawnMap", 1); int spawnX = Configuration::getValue("char_respawnX", 1024); int spawnY = Configuration::getValue("char_respawnY", 1024); - GameState::enqueueWarp(this, MapManager::getMap(spawnMap), + GameState::enqueueWarp(&being, MapManager::getMap(spawnMap), Point(spawnX, spawnY)); } -bool Character::specialUseCheck(SpecialMap::iterator it) +bool CharacterComponent::specialUseCheck(SpecialMap::iterator it) { if (it == mSpecials.end()) { @@ -257,7 +259,7 @@ bool Character::specialUseCheck(SpecialMap::iterator it) return true; } -void Character::useSpecialOnBeing(int id, Being *b) +void CharacterComponent::useSpecialOnBeing(Entity &user, int id, Being *b) { SpecialMap::iterator it = mSpecials.find(id); if (!specialUseCheck(it)) @@ -270,13 +272,13 @@ void Character::useSpecialOnBeing(int id, Being *b) //tell script engine to cast the spell Script *script = ScriptManager::currentState(); script->prepare(special.specialInfo->useCallback); - script->push(this); + script->push(&user); script->push(b); script->push(special.specialInfo->id); - script->execute(getMap()); + script->execute(user.getMap()); } -void Character::useSpecialOnPoint(int id, int x, int y) +void CharacterComponent::useSpecialOnPoint(Entity &user, int id, int x, int y) { SpecialMap::iterator it = mSpecials.find(id); if (!specialUseCheck(it)) @@ -289,14 +291,14 @@ void Character::useSpecialOnPoint(int id, int x, int y) //tell script engine to cast the spell Script *script = ScriptManager::currentState(); script->prepare(special.specialInfo->useCallback); - script->push(this); + script->push(&user); script->push(x); script->push(y); script->push(special.specialInfo->id); - script->execute(getMap()); + script->execute(user.getMap()); } -bool Character::giveSpecial(int id, int currentMana) +bool CharacterComponent::giveSpecial(int id, int currentMana) { if (mSpecials.find(id) == mSpecials.end()) { @@ -315,7 +317,7 @@ bool Character::giveSpecial(int id, int currentMana) return false; } -bool Character::setSpecialMana(int id, int mana) +bool CharacterComponent::setSpecialMana(int id, int mana) { SpecialMap::iterator it = mSpecials.find(id); if (it != mSpecials.end()) @@ -327,7 +329,7 @@ bool Character::setSpecialMana(int id, int mana) return false; } -bool Character::setSpecialRechargeSpeed(int id, int speed) +bool CharacterComponent::setSpecialRechargeSpeed(int id, int speed) { SpecialMap::iterator it = mSpecials.find(id); if (it != mSpecials.end()) @@ -339,7 +341,7 @@ bool Character::setSpecialRechargeSpeed(int id, int speed) return false; } -void Character::sendSpecialUpdate() +void CharacterComponent::sendSpecialUpdate() { //GPMSG_SPECIAL_STATUS = 0x0293, // { B specialID, L current, L max, L recharge } @@ -353,20 +355,10 @@ void Character::sendSpecialUpdate() msg.writeInt32(it->second.specialInfo->neededMana); msg.writeInt32(it->second.rechargeSpeed); } - gameHandler->sendTo(this, msg); + gameHandler->sendTo(mClient, msg); } -int Character::getMapId() const -{ - return getMap()->getID(); -} - -void Character::setMapId(int id) -{ - setMap(MapManager::getMap(id)); -} - -void Character::cancelTransaction() +void CharacterComponent::cancelTransaction() { TransactionType t = mTransaction; mTransaction = TRANS_NONE; @@ -383,19 +375,19 @@ void Character::cancelTransaction() } } -Trade *Character::getTrading() const +Trade *CharacterComponent::getTrading() const { return mTransaction == TRANS_TRADE ? static_cast< Trade * >(mTransactionHandler) : NULL; } -BuySell *Character::getBuySell() const +BuySell *CharacterComponent::getBuySell() const { return mTransaction == TRANS_BUYSELL ? static_cast< BuySell * >(mTransactionHandler) : NULL; } -void Character::setTrading(Trade *t) +void CharacterComponent::setTrading(Trade *t) { if (t) { @@ -410,7 +402,7 @@ void Character::setTrading(Trade *t) } } -void Character::setBuySell(BuySell *t) +void CharacterComponent::setBuySell(BuySell *t) { if (t) { @@ -425,18 +417,21 @@ void Character::setBuySell(BuySell *t) } } -void Character::sendStatus() +void CharacterComponent::sendStatus(Entity &entity) { + // Temporary until all dependencies are available as components + Being &being = static_cast(entity); + MessageOut attribMsg(GPMSG_PLAYER_ATTRIBUTE_CHANGE); for (std::set::const_iterator i = mModifiedAttributes.begin(), i_end = mModifiedAttributes.end(); i != i_end; ++i) { int attr = *i; attribMsg.writeInt16(attr); - attribMsg.writeInt32(getAttributeBase(attr) * 256); - attribMsg.writeInt32(getModifiedAttribute(attr) * 256); + attribMsg.writeInt32(being.getAttributeBase(attr) * 256); + attribMsg.writeInt32(being.getModifiedAttribute(attr) * 256); } - if (attribMsg.getLength() > 2) gameHandler->sendTo(this, attribMsg); + if (attribMsg.getLength() > 2) gameHandler->sendTo(mClient, attribMsg); mModifiedAttributes.clear(); MessageOut expMsg(GPMSG_PLAYER_EXP_CHANGE); @@ -449,7 +444,7 @@ void Character::sendStatus() expMsg.writeInt32(getExpNeeded(skill)); expMsg.writeInt16(levelForExp(getExperience(skill))); } - if (expMsg.getLength() > 2) gameHandler->sendTo(this, expMsg); + if (expMsg.getLength() > 2) gameHandler->sendTo(mClient, expMsg); mModifiedExperience.clear(); if (mUpdateLevelProgress) @@ -457,73 +452,52 @@ void Character::sendStatus() mUpdateLevelProgress = false; MessageOut progressMessage(GPMSG_LEVEL_PROGRESS); progressMessage.writeInt8(mLevelProgress); - gameHandler->sendTo(this, progressMessage); + gameHandler->sendTo(mClient, progressMessage); } } -void Character::modifiedAllAttribute() +void CharacterComponent::modifiedAllAttributes(Entity &entity) { + // Temporary until all dependencies are available as components + Being &being = static_cast(entity); + LOG_DEBUG("Marking all attributes as changed, requiring recalculation."); - for (AttributeMap::iterator it = mAttributes.begin(), - it_end = mAttributes.end(); - it != it_end; ++it) + for (auto attribute : being.getAttributes()) { - recalculateBaseAttribute(it->first); - updateDerivedAttributes(it->first); + being.recalculateBaseAttribute(attribute.first); + mModifiedAttributes.insert(attribute.first); } } -void Character::recalculateBaseAttribute(unsigned attr) +void CharacterComponent::attributeChanged(Being *being, unsigned attr) { - // `attr' may or may not have changed. Recalculate the base value. - LOG_DEBUG("Received update attribute recalculation request at Character " - "for " << attr << "."); - if (!mAttributes.count(attr)) - return; + // Inform the client of this attribute modification. + accountHandler->updateAttributes(getDatabaseID(), attr, + being->getAttributeBase(attr), + being->getModifiedAttribute(attr)); + mModifiedAttributes.insert(attr); + // Update the knuckle Attack if required if (attr == ATTR_STR && mKnuckleAttackInfo) { // TODO: dehardcode this Damage &knuckleDamage = mKnuckleAttackInfo->getDamage(); - knuckleDamage.base = getModifiedAttribute(ATTR_STR); + knuckleDamage.base = being->getModifiedAttribute(ATTR_STR); knuckleDamage.delta = knuckleDamage.base / 2; } - Being::recalculateBaseAttribute(attr); - -} - - -void Character::updateDerivedAttributes(unsigned attr) -{ - /* - * `attr' has changed, perform updates accordingly. - */ - flagAttribute(attr); - - - Being::updateDerivedAttributes(attr); } -void Character::flagAttribute(int attr) -{ - // Inform the client of this attribute modification. - accountHandler->updateAttributes(getDatabaseID(), attr, - getAttributeBase(attr), - getModifiedAttribute(attr)); - mModifiedAttributes.insert(attr); -} - -int Character::expForLevel(int level) +int CharacterComponent::expForLevel(int level) { return int(pow(level, EXPCURVE_EXPONENT) * EXPCURVE_FACTOR); } -int Character::levelForExp(int exp) +int CharacterComponent::levelForExp(int exp) { return int(pow(float(exp) / EXPCURVE_FACTOR, 1.0f / EXPCURVE_EXPONENT)); } -void Character::receiveExperience(int skill, int experience, int optimalLevel) +void CharacterComponent::receiveExperience(int skill, int experience, int optimalLevel) { // reduce experience when skill is over optimal level int levelOverOptimum = levelForExp(getExperience(skill)) - optimalLevel; @@ -562,7 +536,7 @@ void Character::receiveExperience(int skill, int experience, int optimalLevel) mRecalculateLevel = true; } -void Character::incrementKillCount(int monsterType) +void CharacterComponent::incrementKillCount(int monsterType) { std::map::iterator i = mKillCount.find(monsterType); if (i == mKillCount.end()) @@ -577,7 +551,7 @@ void Character::incrementKillCount(int monsterType) } } -int Character::getKillCount(int monsterType) const +int CharacterComponent::getKillCount(int monsterType) const { std::map::const_iterator i = mKillCount.find(monsterType); if (i != mKillCount.end()) @@ -586,7 +560,7 @@ int Character::getKillCount(int monsterType) const } -void Character::recalculateLevel() +void CharacterComponent::recalculateLevel(Entity &entity) { std::list levels; std::map::const_iterator a; @@ -618,7 +592,7 @@ void Character::recalculateLevel() while (mLevel < level) { - levelup(); + levelup(entity); } int levelProgress = int((level - floor(level)) * 100); @@ -629,20 +603,23 @@ void Character::recalculateLevel() } } -int Character::getExpNeeded(size_t skill) const +int CharacterComponent::getExpNeeded(size_t skill) const { int level = levelForExp(getExperience(skill)); - return Character::expForLevel(level + 1) - expForLevel(level); + return CharacterComponent::expForLevel(level + 1) - expForLevel(level); } -int Character::getExpGot(size_t skill) const +int CharacterComponent::getExpGot(size_t skill) const { int level = levelForExp(getExperience(skill)); - return mExperience.at(skill) - Character::expForLevel(level); + return mExperience.at(skill) - CharacterComponent::expForLevel(level); } -void Character::levelup() +void CharacterComponent::levelup(Entity &entity) { + // Temporary until all dependencies are available as Component + Being &being = static_cast(entity); + mLevel++; mCharacterPoints += CHARPOINTS_PER_LEVELUP; @@ -654,40 +631,47 @@ void Character::levelup() levelupMsg.writeInt16(mLevel); levelupMsg.writeInt16(mCharacterPoints); levelupMsg.writeInt16(mCorrectionPoints); - gameHandler->sendTo(this, levelupMsg); - LOG_INFO(getName()<<" reached level "<sendTo(mClient, levelupMsg); + LOG_INFO(being.getName() << " reached level " << mLevel); } -AttribmodResponseCode Character::useCharacterPoint(size_t attribute) +AttribmodResponseCode CharacterComponent::useCharacterPoint(Entity &entity, + size_t attribute) { + // Temporary until all dependencies are available as Component + Being &being = static_cast(entity); + if (!attributeManager->isAttributeDirectlyModifiable(attribute)) return ATTRIBMOD_INVALID_ATTRIBUTE; if (!mCharacterPoints) return ATTRIBMOD_NO_POINTS_LEFT; --mCharacterPoints; - setAttribute(attribute, getAttributeBase(attribute) + 1); - updateDerivedAttributes(attribute); + being.setAttribute(attribute, being.getAttributeBase(attribute) + 1); + being.updateDerivedAttributes(attribute); return ATTRIBMOD_OK; } -AttribmodResponseCode Character::useCorrectionPoint(size_t attribute) +AttribmodResponseCode CharacterComponent::useCorrectionPoint(Entity &entity, + size_t attribute) { + // Temporary until all dependencies are available as Component + Being &being = static_cast(entity); + if (!attributeManager->isAttributeDirectlyModifiable(attribute)) return ATTRIBMOD_INVALID_ATTRIBUTE; if (!mCorrectionPoints) return ATTRIBMOD_NO_POINTS_LEFT; - if (getAttributeBase(attribute) <= 1) + if (being.getAttributeBase(attribute) <= 1) return ATTRIBMOD_DENIED; --mCorrectionPoints; ++mCharacterPoints; - setAttribute(attribute, getAttributeBase(attribute) - 1); - updateDerivedAttributes(attribute); + being.setAttribute(attribute, being.getAttributeBase(attribute) - 1); return ATTRIBMOD_OK; } -void Character::startNpcThread(Script::Thread *thread, int npcId) +void CharacterComponent::startNpcThread(Script::Thread *thread, int npcId) { if (mNpcThread) delete mNpcThread; @@ -698,7 +682,7 @@ void Character::startNpcThread(Script::Thread *thread, int npcId) resumeNpcThread(); } -void Character::resumeNpcThread() +void CharacterComponent::resumeNpcThread() { Script *script = ScriptManager::currentState(); @@ -708,43 +692,47 @@ void Character::resumeNpcThread() { MessageOut msg(GPMSG_NPC_CLOSE); msg.writeInt16(mTalkNpcId); - gameHandler->sendTo(this, msg); + gameHandler->sendTo(mClient, msg); mTalkNpcId = 0; mNpcThread = 0; } } -void Character::attackAdded(Attack &attack) +void CharacterComponent::attackAdded(CombatComponent *combatComponent, + Attack &attack) { // Remove knuckle attack if (attack.getAttackInfo() != mKnuckleAttackInfo) - getComponent()->removeAttack(mKnuckleAttackInfo); + combatComponent->removeAttack(mKnuckleAttackInfo); } -void Character::attackRemoved(Attack &attack) +void CharacterComponent::attackRemoved(CombatComponent *combatComponent, + Attack &attack) { // Add knuckle attack - CombatComponent *combatComponent = getComponent(); // 1 since the attack is not really removed yet. if (combatComponent->getAttacks().getNumber() == 1) combatComponent->addAttack(mKnuckleAttackInfo); } -void Character::disconnected() +void CharacterComponent::disconnected(Entity &entity) { + // Temporary until all dependencies are available as a Component + Being &being = static_cast(entity); + mConnected = false; // Make the dead characters respawn, even in case of disconnection. - if (getAction() == DEAD) - respawn(); + if (being.getAction() == DEAD) + respawn(entity); else - GameState::remove(this); + GameState::remove(&entity); - signal_disconnected.emit(this); + signal_disconnected.emit(entity); } -bool Character::takeSpecial(int id) +bool CharacterComponent::takeSpecial(int id) { SpecialMap::iterator i = mSpecials.find(id); if (i != mSpecials.end()) @@ -756,12 +744,12 @@ bool Character::takeSpecial(int id) return false; } -void Character::clearSpecials() +void CharacterComponent::clearSpecials() { mSpecials.clear(); } -void Character::triggerLoginCallback() +void CharacterComponent::triggerLoginCallback(Entity &entity) { - executeCallback(mLoginCallback, this); + executeCallback(mLoginCallback, entity); } diff --git a/src/game-server/character.h b/src/game-server/character.h index 8b015f98..4b5089d6 100644 --- a/src/game-server/character.h +++ b/src/game-server/character.h @@ -26,6 +26,8 @@ #include "common/manaserv_protocol.h" #include "game-server/being.h" +#include "game-server/mapcomposite.h" +#include "game-server/mapmanager.h" #include "game-server/specialmanager.h" #include "scripting/script.h" @@ -63,48 +65,113 @@ struct SpecialValue */ typedef std::map SpecialMap; + +class CharacterData +{ +public: + CharacterData(Being *being, CharacterComponent *characterComponent); + + void setGender(BeingGender); + BeingGender getGender() const; + + void setMapId(int id); + int getMapId() const; + void setPosition(Point &point); + const Point &getPosition() const; + + void setAttribute(int id, int base); + void setModAttribute(int id, int mod); + const AttributeMap &getAttributes() const; + void setCharacterPoints(int characterPoints); + int getCharacterPoints() const; + void setCorrectionPoints(int correctionPoints); + int getCorrectionPoints() const; + + void setExperience(int skill, int level); + void setLevel(int level) const; + int getLevel() const; + + int getAccountLevel() const; + + void setHairStyle(int style); + int getHairStyle() const; + void setHairColor(int color); + int getHairColor() const; + + void setAccountLevel(int level); + + int getSkillSize() const; + const std::map::const_iterator getSkillBegin() const; + const std::map::const_iterator getSkillEnd() const; + + void applyStatusEffect(int status, int time); + int getStatusEffectSize() const; + const std::map::const_iterator getStatusEffectBegin() const; + const std::map::const_iterator getStatusEffectEnd() const; + + int getKillCountSize() const; + const std::map::const_iterator getKillCountBegin() const; + const std::map::const_iterator getKillCountEnd() const; + void setKillCount(int monsterId, int kills); + + void clearSpecials(); + void giveSpecial(int id, int mana); + int getSpecialSize() const; + SpecialMap::const_iterator getSpecialBegin() const; + SpecialMap::const_iterator getSpecialEnd() const; + + Possessions &getPossessions() const; + +private: + Being *mBeing; + CharacterComponent *mCharacterComponent; +}; + + /** * The representation of a player's character in the game world. */ -class Character : public Being +class CharacterComponent : public Component { public: + static const ComponentType type = CT_Character; + /** * Utility constructor for creating a Character from a received * characterdata message. */ - Character(MessageIn &msg); + CharacterComponent(Entity &entity, MessageIn &msg); - ~Character(); + ~CharacterComponent(); /** * recalculates the level when necessary and calls Being::update */ - void update(); + void update(Entity &entity); void processAttacks(); /** - * Executes the global die script and calls the base class function + * Executes the global die script */ - virtual void died(); + virtual void characterDied(Being *); /** * makes the character respawn */ - void respawn(); + void respawn(Entity &entity); /** * makes the character perform a special action on a being * when it is allowed to do so */ - void useSpecialOnBeing(int id, Being *b); + void useSpecialOnBeing(Entity &user, int id, Being *b); /** * makes the character perform a special action on a map point * when it is allowed to do so */ - void useSpecialOnPoint(int id, int x, int y); + void useSpecialOnPoint(Entity &user, int id, int x, int y); /** * Allows a character to perform a special action @@ -232,43 +299,25 @@ class Character : public Being * Sends a message that informs the client about attribute * modified since last call. */ - void sendStatus(); - - /** - * Gets the ID of the map that the character is on. - * For serialization purpose only. - */ - int getMapId() const; - - /** - * Sets the ID of the map that the character is on. - * For serialization purpose only. - */ - void setMapId(int); + void sendStatus(Entity &entity); /** * Marks all attributes as being modified. */ - void modifiedAllAttribute(); + void modifiedAllAttributes(Entity &entity); /** - * Recalculate the base value of an attribute and update derived - * attributes if it has changed. - */ - void recalculateBaseAttribute(unsigned); - - - /** - * Attribute has changed, recalculate base value of dependant - * attributes (and handle other actions for the modified - * attribute) + * Signal handler for attribute changed event + * Flags the attribute as modified. + * @param being th being of which the attribute was changed + * @param attributeId the changed id */ - void updateDerivedAttributes(unsigned); + void attributeChanged(Being *being, unsigned attributeId); /** * Calls all the "disconnected" listener. */ - void disconnected(); + void disconnected(Entity &entity); /** * Associative array containing all the quest variables known by the @@ -291,18 +340,6 @@ class Character : public Being const std::map::const_iterator getSkillEnd() const { return mExperience.end(); } - /** - * Used to serialize status effects. - */ - int getStatusEffectSize() const - { return mStatusEffects.size(); } - - const std::map::const_iterator getStatusEffectBegin() const - { return mStatusEffects.begin(); } - - const std::map::const_iterator getStatusEffectEnd() const - { return mStatusEffects.end(); } - /** * Used to serialize kill count. */ @@ -366,13 +403,15 @@ class Character : public Being * Tries to use a character point to increase a * basic attribute */ - AttribmodResponseCode useCharacterPoint(size_t attribute); + AttribmodResponseCode useCharacterPoint(Entity &entity, + size_t attribute); /** * Tries to use a correction point to reduce a * basic attribute and regain a character point */ - AttribmodResponseCode useCorrectionPoint(size_t attribute); + AttribmodResponseCode useCorrectionPoint(Entity &entity, + size_t attribute); void setCharacterPoints(int points) { mCharacterPoints = points; } int getCharacterPoints() const { return mCharacterPoints; } @@ -423,13 +462,15 @@ class Character : public Being static void setLoginCallback(Script *script) { script->assignCallback(mLoginCallback); } - void triggerLoginCallback(); + void triggerLoginCallback(Entity &entity); - void attackAdded(Attack &attackInfo); + void attackAdded(CombatComponent *combatComponent, Attack &attackInfo); + void attackRemoved(CombatComponent *combatComponent, Attack &attackInfo); - void attackRemoved(Attack &attackInfo); + CharacterData *getCharacterData() + { return mCharacterData; } - sigc::signal signal_disconnected; + sigc::signal signal_disconnected; private: bool specialUseCheck(SpecialMap::iterator it); @@ -439,8 +480,8 @@ class Character : public Being double getAttrMod(AttributeMap::const_iterator it) const { return it->second.getModifiedAttribute(); } - Character(const Character &); - Character &operator=(const Character &); + CharacterComponent(const CharacterComponent &); + CharacterComponent &operator=(const CharacterComponent &); static const float EXPCURVE_EXPONENT; static const float EXPCURVE_FACTOR; @@ -453,12 +494,7 @@ class Character : public Being /** * Advances the character by one level; */ - void levelup(); - - /** - * Marks attribute as recently modified. - */ - void flagAttribute(int); + void levelup(Entity &entity); /** * Returns the exp needed for next skill levelup @@ -473,7 +509,7 @@ class Character : public Being /** * Recalculates the character level */ - void recalculateLevel(); + void recalculateLevel(Entity &entity); /** * Informs the client about his characters special charge status @@ -503,9 +539,6 @@ class Character : public Being std::map mExperience; /**< experience collected for each skill.*/ SpecialMap mSpecials; - std::map mStatusEffects; /**< only used by select functions - to make it easier to make the accountserver - do not modify or use anywhere else*/ bool mSpecialUpdateNeeded; int mDatabaseID; /**< Character's database ID. */ @@ -529,13 +562,221 @@ class Character : public Being AttackInfo *mKnuckleAttackInfo; + Entity *mBaseEntity; /**< The entity this component is part of + this is ONLY required to allow using + the serialization routine without many + changes (we cannot pass the entity as + argument there). DO NOT USE THIS IF IT + IS AVOIDABLE in order to allow + refactoring this easier later! */ + + CharacterData *mCharacterData; + static Script::Ref mDeathCallback; static Script::Ref mDeathAcceptedCallback; static Script::Ref mLoginCallback; - - // Set as a friend, but still a lot of redundant accessors. FIXME. - template< class T > - friend void serializeCharacterData(const T &data, MessageOut &msg); }; + +inline CharacterData::CharacterData(Being *being, + CharacterComponent *characterComponent): + mBeing(being), + mCharacterComponent(characterComponent) +{} + +inline void CharacterData::setGender(BeingGender gender) +{ + mBeing->setGender(gender); +} + +inline BeingGender CharacterData::getGender() const +{ + return mBeing->getGender(); +} + +inline void CharacterData::setMapId(int id) +{ + mBeing->setMap(MapManager::getMap(id)); +} + +inline int CharacterData::getMapId() const +{ + return mBeing->getMap()->getID(); +} + +inline void CharacterData::setPosition(Point &point) +{ + mBeing->setPosition(point); +} + +inline const Point &CharacterData::getPosition() const +{ + return mBeing->getPosition(); +} + +inline void CharacterData::setAttribute(int id, int base) +{ + mBeing->setAttribute(id, base); +} + +inline void CharacterData::setModAttribute(int id, int mod) +{ + mBeing->setModAttribute(id, mod); +} + +inline const AttributeMap &CharacterData::getAttributes() const +{ + return mBeing->getAttributes(); +} + +inline void CharacterData::setCharacterPoints(int characterPoints) +{ + mCharacterComponent->setCharacterPoints(characterPoints); +} + +inline int CharacterData::getCharacterPoints() const +{ + return mCharacterComponent->getCharacterPoints(); +} + +inline void CharacterData::setCorrectionPoints(int correctionPoints) +{ + mCharacterComponent->setCorrectionPoints(correctionPoints); +} + +inline int CharacterData::getCorrectionPoints() const +{ + return mCharacterComponent->getCorrectionPoints(); +} + +inline void CharacterData::setExperience(int skill, int level) +{ + mCharacterComponent->setExperience(skill, level); +} + +inline void CharacterData::setLevel(int level) const +{ + mCharacterComponent->setLevel(level); +} + +inline int CharacterData::getLevel() const +{ + return mCharacterComponent->getLevel(); +} + +inline int CharacterData::getAccountLevel() const +{ + return mCharacterComponent->getAccountLevel(); +} + +inline void CharacterData::setHairStyle(int style) +{ + mCharacterComponent->setHairStyle(style); +} + +inline int CharacterData::getHairStyle() const +{ + return mCharacterComponent->getHairStyle(); +} + +inline void CharacterData::setHairColor(int color) +{ + mCharacterComponent->setHairColor(color); +} + +inline int CharacterData::getHairColor() const +{ + return mCharacterComponent->getHairColor(); +} + +inline void CharacterData::setAccountLevel(int level) +{ + mCharacterComponent->setAccountLevel(level); +} + +inline int CharacterData::getSkillSize() const +{ + return mCharacterComponent->getSkillSize(); +} + +inline const std::map::const_iterator CharacterData::getSkillBegin() const +{ + return mCharacterComponent->getSkillBegin(); +} + +inline const std::map::const_iterator CharacterData::getSkillEnd() const +{ + return mCharacterComponent->getSkillEnd(); +} + +inline void CharacterData::applyStatusEffect(int status, int time) +{ + mBeing->applyStatusEffect(status, time); +} + +inline int CharacterData::getStatusEffectSize() const +{ + return mBeing->getStatusEffects().size(); +} + +inline const std::map::const_iterator CharacterData::getStatusEffectBegin() const +{ + return mBeing->getStatusEffects().begin(); +} + +inline const std::map::const_iterator CharacterData::getStatusEffectEnd() const +{ + return mBeing->getStatusEffects().end(); +} + +inline int CharacterData::getKillCountSize() const +{ + return mCharacterComponent->getKillCountSize(); +} + +inline const std::map::const_iterator CharacterData::getKillCountBegin() const +{ + return mCharacterComponent->getKillCountBegin(); +} + +inline const std::map::const_iterator CharacterData::getKillCountEnd() const +{ + return mCharacterComponent->getKillCountEnd(); +} + +inline void CharacterData::setKillCount(int monsterId, int kills) +{ + mCharacterComponent->setKillCount(monsterId, kills); +} + +inline void CharacterData::clearSpecials() +{ + mCharacterComponent->clearSpecials(); +} + +inline void CharacterData::giveSpecial(int id, int mana) +{ + mCharacterComponent->giveSpecial(id, mana); +} + +inline int CharacterData::getSpecialSize() const +{ + return mCharacterComponent->getSpecialSize(); +} + +inline SpecialMap::const_iterator CharacterData::getSpecialBegin() const +{ + return mCharacterComponent->getSpecialBegin(); +} + +inline SpecialMap::const_iterator CharacterData::getSpecialEnd() const +{ + return mCharacterComponent->getSpecialEnd(); +} + +inline Possessions &CharacterData::getPossessions() const +{ + return mCharacterComponent->getPossessions(); +} + #endif // CHARACTER_H diff --git a/src/game-server/combatcomponent.cpp b/src/game-server/combatcomponent.cpp index 469569b6..d71f86a3 100644 --- a/src/game-server/combatcomponent.cpp +++ b/src/game-server/combatcomponent.cpp @@ -180,7 +180,7 @@ void CombatComponent::processAttack(Being &source, Attack &attack) */ void CombatComponent::addAttack(AttackInfo *attackInfo) { - mAttacks.add(attackInfo); + mAttacks.add(this, attackInfo); } /** @@ -188,7 +188,7 @@ void CombatComponent::addAttack(AttackInfo *attackInfo) */ void CombatComponent::removeAttack(AttackInfo *attackInfo) { - mAttacks.remove(attackInfo); + mAttacks.remove(this, attackInfo); } /** diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index d38828fe..63b960d3 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -48,44 +48,44 @@ struct CmdRef const char *cmd; const char *usage; const char *help; - void (*func)(Character*, std::string&) ; + void (*func)(Being*, std::string&) ; }; -static void handleHelp(Character*, std::string&); -static void handleReport(Character*, std::string&); -static void handleWhere(Character*, std::string&); -static void handleRights(Character*, std::string&); -static void handleWarp(Character*, std::string&); -static void handleCharWarp(Character*, std::string&); -static void handleGoto(Character*, std::string&); -static void handleRecall(Character*, std::string&); -static void handleBan(Character*, std::string&); -static void handleItem(Character*, std::string&); -static void handleDrop(Character*, std::string&); -static void handleMoney(Character*, std::string&); -static void handleSpawn(Character*, std::string&); -static void handleAttribute(Character*, std::string&); -static void handleReload(Character*, std::string&); -static void handlePermissions(Character*, std::string&); -static void handleGivePermission(Character*, std::string&); -static void handleTakePermission(Character*, std::string&); -static void handleAnnounce(Character*, std::string&); -static void handleHistory(Character*, std::string&); -static void handleMute(Character*, std::string&); -static void handleDie(Character*, std::string&); -static void handleKill(Character*, std::string&); -static void handleKick(Character*, std::string&); -static void handleLog(Character*, std::string&); -static void handleLogsay(Character*, std::string&); -static void handleKillMonsters(Character*, std::string&); -static void handleCraft(Character*, std::string&); -static void handleGetPos(Character*, std::string&); -static void handleSkills(Character*, std::string&); -static void handleEffect(Character*, std::string&); -static void handleGiveSpecial(Character*, std::string&); -static void handleTakeSpecial(Character*, std::string&); -static void handleRechargeSpecial(Character*, std::string&); -static void handleListSpecials(Character*, std::string&); +static void handleHelp(Being*, std::string&); +static void handleReport(Being*, std::string&); +static void handleWhere(Being*, std::string&); +static void handleRights(Being*, std::string&); +static void handleWarp(Being*, std::string&); +static void handleCharWarp(Being*, std::string&); +static void handleGoto(Being*, std::string&); +static void handleRecall(Being*, std::string&); +static void handleBan(Being*, std::string&); +static void handleItem(Being*, std::string&); +static void handleDrop(Being*, std::string&); +static void handleMoney(Being*, std::string&); +static void handleSpawn(Being*, std::string&); +static void handleAttribute(Being*, std::string&); +static void handleReload(Being*, std::string&); +static void handlePermissions(Being*, std::string&); +static void handleGivePermission(Being*, std::string&); +static void handleTakePermission(Being*, std::string&); +static void handleAnnounce(Being*, std::string&); +static void handleHistory(Being*, std::string&); +static void handleMute(Being*, std::string&); +static void handleDie(Being*, std::string&); +static void handleKill(Being*, std::string&); +static void handleKick(Being*, std::string&); +static void handleLog(Being*, std::string&); +static void handleLogsay(Being*, std::string&); +static void handleKillMonsters(Being*, std::string&); +static void handleCraft(Being*, std::string&); +static void handleGetPos(Being*, std::string&); +static void handleSkills(Being*, std::string&); +static void handleEffect(Being*, std::string&); +static void handleGiveSpecial(Being*, std::string&); +static void handleTakeSpecial(Being*, std::string&); +static void handleRechargeSpecial(Being*, std::string&); +static void handleListSpecials(Being*, std::string&); static CmdRef const cmdRef[] = { @@ -171,7 +171,7 @@ static CmdRef const cmdRef[] = }; -static void say(const std::string &message, Character *player) +static void say(const std::string &message, Being *player) { GameState::sayTo(player, NULL, message); } @@ -193,10 +193,10 @@ static bool checkPermission(Character *player, unsigned permissions) * Returns the next argument, and remove it from the given string. */ -static std::string playerRights(Character *ch) +static std::string playerRights(Being *ch) { std::stringstream str; - str << (unsigned)ch->getAccountLevel(); + str << (unsigned)ch->getComponent()->getAccountLevel(); str << " ( "; std::list classes = PermissionManager::getClassList(ch); @@ -263,7 +263,7 @@ static std::string getArgument(std::string &args) return argument; } -static void handleHelp(Character *player, std::string &args) +static void handleHelp(Being *player, std::string &args) { if (args.empty()) { @@ -302,7 +302,7 @@ static void handleHelp(Character *player, std::string &args) } } -static void handleWarp(Character *player, std::string &args) +static void handleWarp(Being *player, std::string &args) { int x, y; MapComposite *map; @@ -382,15 +382,17 @@ static void handleWarp(Character *player, std::string &args) // log transaction std::stringstream ss; ss << "User warped to " << map->getName() << " (" << x << ", " << y << ")"; - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_WARP, + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_WARP, ss.str()); } -static void handleCharWarp(Character *player, std::string &args) +static void handleCharWarp(Being *player, std::string &args) { int x, y; MapComposite *map; - Character *other; + Being *other; // get the arguments std::string character = getArgument(args); @@ -485,13 +487,14 @@ static void handleCharWarp(Character *player, std::string &args) std::stringstream ss; ss << "User warped " << other->getName() << " to " << map->getName() << " (" << x << ", " << y << ")"; - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_WARP, - ss.str()); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_WARP, ss.str()); } -static void handleItem(Character *player, std::string &args) +static void handleItem(Being *player, std::string &args) { - Character *other; + Being *other; ItemClass *ic; int value = 0; @@ -562,10 +565,12 @@ static void handleItem(Character *player, std::string &args) // log transaction std::stringstream str; str << "User created item " << ic->getDatabaseID(); - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_ITEM, str.str()); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_ITEM, str.str()); } -static void handleDrop(Character *player, std::string &args) +static void handleDrop(Being *player, std::string &args) { ItemClass *ic; int amount = 0; @@ -623,12 +628,14 @@ static void handleDrop(Character *player, std::string &args) // log transaction std::stringstream str; str << "User created item " << ic->getDatabaseID(); - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_DROP, str.str()); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_DROP, str.str()); } -static void handleMoney(Character *player, std::string &args) +static void handleMoney(Being *player, std::string &args) { - Character *other; + Being *other; int value; // get arguments @@ -674,10 +681,12 @@ static void handleMoney(Character *player, std::string &args) // log transaction std::string msg = "User created " + valuestr + " money"; - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_MONEY, msg); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_MONEY, msg); } -static void handleSpawn(Character *player, std::string &args) +static void handleSpawn(Being *player, std::string &args) { MonsterClass *mc; MapComposite *map = player->getMap(); @@ -745,13 +754,15 @@ static void handleSpawn(Character *player, std::string &args) // log transaction std::string msg = "User created monster " + monster->getName(); - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_SPAWN, msg); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_SPAWN, msg); } } -static void handleGoto(Character *player, std::string &args) +static void handleGoto(Being *player, std::string &args) { - Character *other; + Being *other; // get the arguments std::string character = getArgument(args); @@ -780,12 +791,14 @@ static void handleGoto(Character *player, std::string &args) // log transaction std::stringstream msg; msg << "User warped own character to " << other->getName(); - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_GOTO, msg.str()); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_GOTO, msg.str()); } -static void handleRecall(Character *player, std::string &args) +static void handleRecall(Being *player, std::string &args) { - Character *other; + Being *other; // get the arguments std::string character = getArgument(args); @@ -812,16 +825,16 @@ static void handleRecall(Character *player, std::string &args) GameState::warp(other, map, pos); } -static void handleReload(Character *, std::string &) +static void handleReload(Being *, std::string &) { // reload the items and monsters itemManager->reload(); monsterManager->reload(); } -static void handleBan(Character *player, std::string &args) +static void handleBan(Being *player, std::string &args) { - Character *other; + Being *other; int length; int lengthMutiplier = 0; @@ -877,22 +890,25 @@ static void handleBan(Character *player, std::string &args) return; } + auto *characterComponent = player->getComponent(); + // ban the player accountHandler->banCharacter(other, length); // disconnect the player MessageOut kickmsg(GPMSG_CONNECT_RESPONSE); kickmsg.writeInt8(ERRMSG_ADMINISTRATIVE_LOGOFF); - other->getClient()->disconnect(kickmsg); + characterComponent->getClient()->disconnect(kickmsg); // feedback for command user std::string msg = "You've banned " + other->getName() + " for " + utils::toString(length) + " minutes"; say(msg.c_str(), player); // log transaction msg = "User banned " + other->getName() + " for " + utils::toString(length) + " minutes"; - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_BAN, msg); + accountHandler->sendTransaction(characterComponent->getDatabaseID(), + TRANS_CMD_BAN, msg); } -static void handlePermissions(Character *player, std::string &args) +static void handlePermissions(Being *player, std::string &args) { std::string character = getArgument(args); if (character.empty()) @@ -902,7 +918,7 @@ static void handlePermissions(Character *player, std::string &args) return; } - Character *other = gameHandler->getCharacterByNameSlow(character); + Being *other = gameHandler->getCharacterByNameSlow(character); if (!other) { say("Invalid character", player); @@ -913,9 +929,9 @@ static void handlePermissions(Character *player, std::string &args) playerRights(other), player); } -static void handleGivePermission(Character *player, std::string &args) +static void handleGivePermission(Being *player, std::string &args) { - Character *other; + Being *other; // get the arguments std::string character = getArgument(args); @@ -953,20 +969,24 @@ static void handleGivePermission(Character *player, std::string &args) return; } - if (permission & other->getAccountLevel()) + auto *characterComponent = + player->getComponent(); + + if (permission & characterComponent->getAccountLevel()) { say(player->getName()+" already has the permission "+strPermission, player); } else { - permission += other->getAccountLevel(); + permission += characterComponent->getAccountLevel(); // change the player's account level - other->setAccountLevel(permission); + characterComponent->setAccountLevel(permission); accountHandler->changeAccountLevel(other, permission); // log transaction std::string msg = "User gave right " + strPermission + " to " + other->getName(); - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_SETGROUP, msg); + accountHandler->sendTransaction(characterComponent->getDatabaseID(), + TRANS_CMD_SETGROUP, msg); say("You gave " + other->getName() + " the rights of a " + strPermission, player); say("Congratulations, " + player->getName() + @@ -974,9 +994,9 @@ static void handleGivePermission(Character *player, std::string &args) } } -static void handleTakePermission(Character *player, std::string &args) +static void handleTakePermission(Being *player, std::string &args) { - Character *other; + Being *other; // get the arguments std::string character = getArgument(args); @@ -1014,27 +1034,30 @@ static void handleTakePermission(Character *player, std::string &args) return; } + auto *characterComponent = + player->getComponent(); - if (!(permission & other->getAccountLevel())) + if (!(permission & characterComponent->getAccountLevel())) { say(player->getName()+" hasn't got the permission "+strPermission, player); } else { - permission = other->getAccountLevel() - permission; + permission = characterComponent->getAccountLevel() - permission; // change the player's account level - other->setAccountLevel(permission); + characterComponent->setAccountLevel(permission); accountHandler->changeAccountLevel(other, permission); // log transaction std::string msg = "User took right " + strPermission + " from " + other->getName(); - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_SETGROUP, msg); + accountHandler->sendTransaction(characterComponent->getDatabaseID(), + TRANS_CMD_SETGROUP, msg); say("Sorry, "+player->getName()+" revoked your rights of a "+strPermission, other); } } -static void handleAttribute(Character *player, std::string &args) +static void handleAttribute(Being *player, std::string &args) { - Character *other; + Being *other; int attr, value; // get arguments @@ -1098,10 +1121,12 @@ static void handleAttribute(Character *player, std::string &args) std::stringstream msg; msg << "User changed attribute " << attr << " of player " << other->getName() << " to " << value; - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_ATTRIBUTE, msg.str()); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_ATTRIBUTE, msg.str()); } -static void handleReport(Character *player, std::string &args) +static void handleReport(Being *player, std::string &args) { std::string bugReport = getArgument(args); @@ -1115,7 +1140,7 @@ static void handleReport(Character *player, std::string &args) // TODO: Send the report to a developer or something } -static void handleAnnounce(Character *player, std::string &args) +static void handleAnnounce(Being *player, std::string &args) { if (args.empty()) { @@ -1126,16 +1151,17 @@ static void handleAnnounce(Character *player, std::string &args) MessageOut msg(GAMSG_ANNOUNCE); msg.writeString(args); - msg.writeInt16(player->getDatabaseID()); + msg.writeInt16(player->getComponent() + ->getDatabaseID()); msg.writeString(player->getName()); accountHandler->send(msg); } -static void handleWhere(Character *player, std::string &) +static void handleWhere(Being *player, std::string &) { std::stringstream str; str << "Your current location is map " - << player->getMapId() + << player->getMap()->getID() << " [" << player->getPosition().x << ":" @@ -1144,19 +1170,19 @@ static void handleWhere(Character *player, std::string &) say (str.str(), player); } -static void handleRights(Character *player, std::string &) +static void handleRights(Being *player, std::string &) { say("Your rights level is: " + playerRights(player), player); } -static void handleHistory(Character *, std::string &) +static void handleHistory(Being *, std::string &) { // TODO: Get args number of transactions and show them to the player } -static void handleMute(Character *player, std::string &args) +static void handleMute(Being *player, std::string &args) { - Character *other; + Being *other; int length; // Get arguments. @@ -1185,7 +1211,7 @@ static void handleMute(Character *player, std::string &args) } // Mute the player. - other->mute(length); + other->getComponent()->mute(length); // Feedback. std::stringstream targetMsg; @@ -1214,18 +1240,20 @@ static void handleMute(Character *player, std::string &args) } else { msg << "User unmuted " << other->getName(); } - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_MUTE, msg.str()); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_MUTE, msg.str()); } -static void handleDie(Character *player, std::string &) +static void handleDie(Being *player, std::string &) { player->setAttribute(ATTR_HP, 0); say("You've killed yourself.", player); } -static void handleKill(Character *player, std::string &args) +static void handleKill(Being *player, std::string &args) { - Character *other; + Being *other; // get arguments std::string character = getArgument(args); @@ -1252,12 +1280,14 @@ static void handleKill(Character *player, std::string &args) // log transaction std::stringstream logMsg; logMsg << "User killed " << other->getName(); - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_KILL, logMsg.str()); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_KILL, logMsg.str()); } -static void handleKick(Character *player, std::string &args) +static void handleKick(Being *player, std::string &args) { - Character *other; + Being *other; // get arguments std::string character = getArgument(args); @@ -1275,19 +1305,25 @@ static void handleKick(Character *player, std::string &args) userMsg << "You kicked " << other->getName() << "."; say(userMsg.str(), player); + + auto *characterComponent = + player->getComponent(); + // disconnect the client MessageOut msg(GPMSG_CONNECT_RESPONSE); msg.writeInt8(ERRMSG_ADMINISTRATIVE_LOGOFF); - other->getClient()->disconnect(msg); + characterComponent->getClient()->disconnect(msg); // log transaction std::stringstream logMsg; logMsg << "User kicked " << other->getName(); - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_KICK, logMsg.str()); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_KICK, logMsg.str()); } -static void handleLog(Character *player, std::string &msg) +static void handleLog(Being *player, std::string &msg) { if (msg.empty()) { @@ -1298,13 +1334,15 @@ static void handleLog(Character *player, std::string &msg) // log transaction std::string logmsg = "[silent] " + msg; - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_LOG, logmsg); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_LOG, logmsg); // send feedback say("Message logged", player); } -static void handleLogsay(Character *player, std::string &msg) +static void handleLogsay(Being *player, std::string &msg) { if (msg.empty()) { @@ -1317,13 +1355,15 @@ static void handleLogsay(Character *player, std::string &msg) // log transaction std::string logmsg = "[public] " + msg; - accountHandler->sendTransaction(player->getDatabaseID(), TRANS_CMD_LOG, logmsg); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_LOG, logmsg); // send feedback say("Message logged", player); } -static void handleKillMonsters(Character *player, std::string &) +static void handleKillMonsters(Being *player, std::string &) { const MapComposite *map = player->getMap(); int count = 0; @@ -1343,11 +1383,12 @@ static void handleKillMonsters(Character *player, std::string &) // log transaction std::string msg = "User killed all monsters on map " + map->getName(); - accountHandler->sendTransaction(player->getDatabaseID(), - TRANS_CMD_KILLMONSTERS, msg); + int databaseId = + player->getComponent()->getDatabaseID(); + accountHandler->sendTransaction(databaseId, TRANS_CMD_KILLMONSTERS, msg); } -static void handleCraft(Character *player, std::string &args) +static void handleCraft(Being *player, std::string &args) { std::stringstream errMsg; std::list recipe; @@ -1420,7 +1461,7 @@ static void handleCraft(Character *player, std::string &args) } } -static void handleGetPos(Character *player, std::string &args) +static void handleGetPos(Being *player, std::string &args) { std::string character = getArgument(args); if (character.empty()) @@ -1429,7 +1470,7 @@ static void handleGetPos(Character *player, std::string &args) say("Usage: @getpos ", player); return; } - Character *other; + Being *other; other = gameHandler->getCharacterByNameSlow(character); if (!other) { @@ -1441,7 +1482,7 @@ static void handleGetPos(Character *player, std::string &args) str << "The current location of " << character << " is map " - << other->getMapId() + << other->getMap()->getID() << " [" << pos.x << ":" @@ -1450,7 +1491,7 @@ static void handleGetPos(Character *player, std::string &args) say(str.str(), player); } -static void handleSkills(Character *player, std::string &args) +static void handleSkills(Being *player, std::string &args) { std::string character = getArgument(args); if (character.empty()) @@ -1459,7 +1500,7 @@ static void handleSkills(Character *player, std::string &args) say("Usage: @skills ", player); return; } - Character *other; + Being *other; if (character == "#") other = player; else @@ -1470,9 +1511,15 @@ static void handleSkills(Character *player, std::string &args) return; } + + auto *characterComponent = + player->getComponent(); + say("List of skills of player '" + other->getName() + "':", player); - std::map::const_iterator it = other->getSkillBegin(); - std::map::const_iterator it_end = other->getSkillEnd(); + std::map::const_iterator it = + characterComponent->getSkillBegin(); + std::map::const_iterator it_end = + characterComponent->getSkillEnd(); if (it == it_end) { @@ -1489,7 +1536,7 @@ static void handleSkills(Character *player, std::string &args) } } -static void handleEffect(Character *player, std::string &args) +static void handleEffect(Being *player, std::string &args) { std::vector arguments; for (std::string arg = getArgument(args); !arg.empty(); @@ -1506,7 +1553,7 @@ static void handleEffect(Character *player, std::string &args) else if (arguments.size() == 2) { int id = utils::stringToInt(arguments[0]); - Character *p = gameHandler->getCharacterByNameSlow(arguments[1]); + Being *p = gameHandler->getCharacterByNameSlow(arguments[1]); if (!p) { say("Invalid target player.", player); @@ -1529,7 +1576,7 @@ static void handleEffect(Character *player, std::string &args) } } -static void handleGiveSpecial(Character *player, std::string &args) +static void handleGiveSpecial(Being *player, std::string &args) { std::string character = getArgument(args); std::string special = getArgument(args); @@ -1540,7 +1587,7 @@ static void handleGiveSpecial(Character *player, std::string &args) return; } - Character *other; + Being *other; if (character == "#") other = player; else @@ -1558,14 +1605,15 @@ static void handleGiveSpecial(Character *player, std::string &args) else specialId = specialManager->getId(special); - if (specialId <= 0 || !other->giveSpecial(specialId)) + if (specialId <= 0 || + !other->getComponent()->giveSpecial(specialId)) { say("Invalid special.", player); return; } } -static void handleTakeSpecial(Character *player, std::string &args) +static void handleTakeSpecial(Being *player, std::string &args) { std::string character = getArgument(args); std::string special = getArgument(args); @@ -1576,7 +1624,7 @@ static void handleTakeSpecial(Character *player, std::string &args) return; } - Character *other; + Being *other; if (character == "#") other = player; else @@ -1599,14 +1647,14 @@ static void handleTakeSpecial(Character *player, std::string &args) say("Invalid special.", player); return; } - if (!other->takeSpecial(specialId)) + if (!other->getComponent()->takeSpecial(specialId)) { say("Character does not have special.", player); return; } } -static void handleRechargeSpecial(Character *player, std::string &args) +static void handleRechargeSpecial(Being *player, std::string &args) { std::string character = getArgument(args); std::string special = getArgument(args); @@ -1618,7 +1666,7 @@ static void handleRechargeSpecial(Character *player, std::string &args) return; } - Character *other; + Being *other; if (character == "#") other = player; else @@ -1658,14 +1706,15 @@ static void handleRechargeSpecial(Character *player, std::string &args) } mana = utils::stringToInt(newMana); } - if (!other->setSpecialMana(specialId, mana)) + if (!other->getComponent() + ->setSpecialMana(specialId, mana)) { say("Character does not have special.", player); return; } } -static void handleListSpecials(Character *player, std::string &args) +static void handleListSpecials(Being *player, std::string &args) { std::string character = getArgument(args); if (character.empty()) @@ -1675,7 +1724,7 @@ static void handleListSpecials(Character *player, std::string &args) return; } - Character *other; + Being *other; if (character == "#") other = player; else @@ -1687,9 +1736,12 @@ static void handleListSpecials(Character *player, std::string &args) return; } + auto *characterComponent = + other->getComponent(); + say("Specials of character " + other->getName() + ":", player); - for (SpecialMap::const_iterator it = other->getSpecialBegin(), - it_end = other->getSpecialEnd(); it != it_end; ++it) + for (SpecialMap::const_iterator it = characterComponent->getSpecialBegin(), + it_end = characterComponent->getSpecialEnd(); it != it_end; ++it) { const SpecialValue &info = it->second; std::stringstream str; @@ -1699,7 +1751,7 @@ static void handleListSpecials(Character *player, std::string &args) } } -void CommandHandler::handleCommand(Character *player, +void CommandHandler::handleCommand(Being *player, const std::string &command) { // get command type, and arguments diff --git a/src/game-server/commandhandler.h b/src/game-server/commandhandler.h index 5327dda7..b5a268f5 100644 --- a/src/game-server/commandhandler.h +++ b/src/game-server/commandhandler.h @@ -23,14 +23,14 @@ #include -class Character; +class Being; namespace CommandHandler { /** * Parse and handle the given command. */ - void handleCommand(Character *player, const std::string &command); + void handleCommand(Being *player, const std::string &command); } #endif //SERVER_COMMANDHANDLER_H diff --git a/src/game-server/component.h b/src/game-server/component.h index 974cad0c..45fe742e 100644 --- a/src/game-server/component.h +++ b/src/game-server/component.h @@ -25,6 +25,7 @@ class Entity; enum ComponentType { + CT_Character, CT_Effect, CT_Fighting, CT_Item, diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index 9cec7728..55588b61 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -71,27 +71,28 @@ void GameHandler::computerDisconnected(NetComputer *comp) { mTokenCollector.deletePendingClient(&computer); } - else if (Character *ch = computer.character) + else if (Entity *ch = computer.character) { accountHandler->sendCharacterData(ch); - ch->disconnected(); + ch->getComponent()->disconnected(*ch); delete ch; } delete &computer; } -void GameHandler::kill(Character *ch) +void GameHandler::kill(Entity *ch) { - GameClient *client = ch->getClient(); + auto *component = ch->getComponent(); + GameClient *client = component->getClient(); assert(client); - client->character = NULL; + client->character = nullptr; client->status = CLIENT_LOGIN; - ch->setClient(0); + component->setClient(0); } -void GameHandler::prepareServerChange(Character *ch) +void GameHandler::prepareServerChange(Entity *ch) { - GameClient *client = ch->getClient(); + GameClient *client = ch->getComponent()->getClient(); assert(client); client->status = CLIENT_CHANGE_SERVER; } @@ -104,14 +105,16 @@ void GameHandler::completeServerChange(int id, const std::string &token, { GameClient *c = static_cast< GameClient * >(*i); if (c->status == CLIENT_CHANGE_SERVER && - c->character->getDatabaseID() == id) + c->character->getComponent() + ->getDatabaseID() == id) { MessageOut msg(GPMSG_PLAYER_SERVER_CHANGE); msg.writeString(token, MAGIC_TOKEN_LENGTH); msg.writeString(address); msg.writeInt16(port); c->send(msg); - c->character->disconnected(); + c->character->getComponent()->disconnected( + *c->character); delete c->character; c->character = NULL; c->status = CLIENT_LOGIN; @@ -126,10 +129,11 @@ void GameHandler::updateCharacter(int charid, int partyid) i_end = clients.end(); i != i_end; ++i) { GameClient *c = static_cast< GameClient * >(*i); - if (c->character->getDatabaseID() == charid) - { - c->character->setParty(partyid); - } + auto *characterComponent = + c->character->getComponent(); + + if (characterComponent->getDatabaseID() == charid) + characterComponent->setParty(partyid); } } @@ -165,7 +169,7 @@ static Being *findBeingNear(Actor *p, int id) return 0; } -static Character *findCharacterNear(Actor *p, int id) +static Being *findCharacterNear(Actor *p, int id) { MapComposite *map = p->getMap(); const Point &ppos = p->getPosition(); @@ -174,10 +178,14 @@ static Character *findCharacterNear(Actor *p, int id) for (CharacterIterator i(map->getAroundPointIterator(ppos, pixelDist)); i; ++i) { - Character *c = *i; + Being *c = *i; if (c->getPublicID() != id) continue; - return ppos.inRangeOf(c->getPosition(), pixelDist) ? c : 0; + + if (ppos.inRangeOf(c->getPosition(), pixelDist)) + return c; + + return 0; } return 0; } @@ -293,7 +301,8 @@ void GameHandler::processMessage(NetComputer *computer, MessageIn &message) case PGMSG_RESPAWN: // plausibility check is done by character class - client.character->respawn(); + client.character->getComponent()->respawn( + *client.character); break; case PGMSG_NPC_POST_SEND: @@ -315,26 +324,34 @@ void GameHandler::processMessage(NetComputer *computer, MessageIn &message) } } -void GameHandler::sendTo(Character *beingPtr, MessageOut &msg) +void GameHandler::sendTo(Entity *beingPtr, MessageOut &msg) +{ + GameClient *client = beingPtr->getComponent() + ->getClient(); + sendTo(client, msg); +} + +void GameHandler::sendTo(GameClient *client, MessageOut &msg) { - GameClient *client = beingPtr->getClient(); assert(client && client->status == CLIENT_CONNECTED); client->send(msg); } -void GameHandler::addPendingCharacter(const std::string &token, Character *ch) +void GameHandler::addPendingCharacter(const std::string &token, Being *ch) { /* First, check if the character is already on the map. This may happen if a client just lost its connection, and logged to the account server again, yet the game server has not yet detected the lost connection. */ - int id = ch->getDatabaseID(); + int id = ch->getComponent()->getDatabaseID(); for (NetComputers::const_iterator i = clients.begin(), i_end = clients.end(); i != i_end; ++i) { GameClient *c = static_cast< GameClient * >(*i); - Character *old_ch = c->character; - if (old_ch && old_ch->getDatabaseID() == id) + Being *old_ch = c->character; + const int oldId = old_ch->getComponent() + ->getDatabaseID(); + if (old_ch && oldId == id) { if (c->status != CLIENT_CONNECTED) { @@ -350,7 +367,7 @@ void GameHandler::addPendingCharacter(const std::string &token, Character *ch) it available for a new connection. */ delete ch; GameState::remove(old_ch); - kill(old_ch); + kill(ch); ch = old_ch; break; } @@ -360,12 +377,15 @@ void GameHandler::addPendingCharacter(const std::string &token, Character *ch) mTokenCollector.addPendingConnect(token, ch); } -void GameHandler::tokenMatched(GameClient *computer, Character *character) +void GameHandler::tokenMatched(GameClient *computer, Being *character) { computer->character = character; computer->status = CLIENT_CONNECTED; - character->setClient(computer); + auto *characterComponent = + character->getComponent(); + + characterComponent->setClient(computer); MessageOut result(GPMSG_CONNECT_RESPONSE); @@ -378,14 +398,14 @@ void GameHandler::tokenMatched(GameClient *computer, Character *character) return; } // Trigger login script bind - character->triggerLoginCallback(); + characterComponent->triggerLoginCallback(*character); result.writeInt8(ERRMSG_OK); computer->send(result); // Force sending the whole character to the client. Inventory(character).sendFull(); - character->modifiedAllAttribute(); + characterComponent->modifiedAllAttributes(*character); } void GameHandler::deletePendingClient(GameClient *computer) @@ -401,18 +421,18 @@ void GameHandler::deletePendingClient(GameClient *computer) computer->disconnect(msg); } -void GameHandler::deletePendingConnect(Character *character) +void GameHandler::deletePendingConnect(Being *character) { delete character; } -Character *GameHandler::getCharacterByNameSlow(const std::string &name) const +Being *GameHandler::getCharacterByNameSlow(const std::string &name) const { for (NetComputers::const_iterator i = clients.begin(), i_end = clients.end(); i != i_end; ++i) { GameClient *c = static_cast< GameClient * >(*i); - Character *ch = c->character; + Being *ch = c->character; if (ch && ch->getName() == name && c->status == CLIENT_CONNECTED) { @@ -433,7 +453,7 @@ void GameHandler::handleSay(GameClient &client, MessageIn &message) CommandHandler::handleCommand(client.character, say); return; } - if (!client.character->isMuted()) + if (!client.character->getComponent()->isMuted()) { GameState::sayAround(client.character, say); } @@ -518,9 +538,11 @@ void GameHandler::handlePickup(GameClient &client, MessageIn &message) std::stringstream str; str << "User picked up item " << ic->getDatabaseID() << " at " << opos.x << "x" << opos.y; + auto *characterComponent = client.character + ->getComponent(); accountHandler->sendTransaction( - client.character->getDatabaseID(), - TRANS_ITEM_PICKUP, str.str() + characterComponent->getDatabaseID(), + TRANS_ITEM_PICKUP, str.str() ); } break; @@ -545,7 +567,9 @@ void GameHandler::handleUseItem(GameClient &client, MessageIn &message) std::stringstream str; str << "User activated item " << ic->getDatabaseID() << " from slot " << slot; - accountHandler->sendTransaction(client.character->getDatabaseID(), + auto *characterComponent = client.character + ->getComponent(); + accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_ITEM_USED, str.str()); if (ic->useTrigger(client.character, ITT_ACTIVATE)) inv.removeFromSlot(slot, 1); @@ -588,7 +612,9 @@ void GameHandler::handleDrop(GameClient &client, MessageIn &message) std::stringstream str; str << "User dropped item " << ic->getDatabaseID() << " at " << pos.x << "x" << pos.y; - accountHandler->sendTransaction(client.character->getDatabaseID(), + auto *characterComponent = client.character + ->getComponent(); + accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_ITEM_DROP, str.str()); } } @@ -637,7 +663,9 @@ void GameHandler::handleMoveItem(GameClient &client, MessageIn &message) std::stringstream str; str << "User moved item " << " from slot " << slot1 << " to slot " << slot2; - accountHandler->sendTransaction(client.character->getDatabaseID(), + auto *characterComponent = + client.character->getComponent(); + accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_ITEM_MOVE, str.str()); } @@ -667,7 +695,9 @@ void GameHandler::handleUseSpecialOnBeing(GameClient &client, MessageIn &message being = findBeingNear(client.character, targetID); LOG_DEBUG("Character " << client.character->getPublicID() << " tries to use his special attack " << specialID); - client.character->useSpecialOnBeing(specialID, being); + auto *characterComponent = client.character + ->getComponent(); + characterComponent->useSpecialOnBeing(*client.character, specialID, being); } void GameHandler::handleUseSpecialOnPoint(GameClient &client, MessageIn &message) @@ -681,7 +711,9 @@ void GameHandler::handleUseSpecialOnPoint(GameClient &client, MessageIn &message LOG_DEBUG("Character " << client.character->getPublicID() << " tries to use his special attack " << specialID); - client.character->useSpecialOnPoint(specialID, x, y); + auto *characterComponent = client.character + ->getComponent(); + characterComponent->useSpecialOnPoint(*client.character, specialID, x, y); } void GameHandler::handleActionChange(GameClient &client, MessageIn &message) @@ -716,7 +748,11 @@ void GameHandler::handleActionChange(GameClient &client, MessageIn &message) // log transaction std::stringstream str; str << "User changed action from " << current << " to " << action; - accountHandler->sendTransaction(client.character->getDatabaseID(), + + auto *characterComponent = + client.character->getComponent(); + + accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_ACTION_CHANGE, str.str()); } @@ -735,19 +771,21 @@ void GameHandler::handleDisconnect(GameClient &client, MessageIn &message) MessageOut result(GPMSG_DISCONNECT_RESPONSE); result.writeInt8(ERRMSG_OK); // It is, when control reaches here + auto *characterComponent = + client.character->getComponent(); + if (reconnectAccount) { std::string magic_token(utils::getMagicToken()); result.writeString(magic_token, MAGIC_TOKEN_LENGTH); // No accountserver data, the client should remember that accountHandler->playerReconnectAccount( - client.character->getDatabaseID(), + characterComponent->getDatabaseID(), magic_token); } accountHandler->sendCharacterData(client.character); - // Done with the character, also handle possible respawn case - client.character->disconnected(); + characterComponent->disconnected(*client.character); delete client.character; client.character = 0; client.status = CLIENT_LOGIN; @@ -759,12 +797,15 @@ void GameHandler::handleTradeRequest(GameClient &client, MessageIn &message) { const int id = message.readInt16(); - if (Trade *t = client.character->getTrading()) + auto *characterComponent = + client.character->getComponent(); + + if (Trade *t = characterComponent->getTrading()) if (t->request(client.character, id)) return; - Character *q = findCharacterNear(client.character, id); - if (!q || q->isBusy()) + Being *q = findCharacterNear(client.character, id); + if (!q || characterComponent->isBusy()) { client.send(MessageOut(GPMSG_TRADE_CANCEL)); return; @@ -775,14 +816,19 @@ void GameHandler::handleTradeRequest(GameClient &client, MessageIn &message) // log transaction std::string str; str = "User requested trade with " + q->getName(); - accountHandler->sendTransaction(client.character->getDatabaseID(), + accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_TRADE_REQUEST, str); } void GameHandler::handleTrade(GameClient &client, MessageIn &message) { + auto *characterComponent = + client.character->getComponent(); + + int databaseId = characterComponent->getDatabaseID(); + std::stringstream str; - Trade *t = client.character->getTrading(); + Trade *t = characterComponent->getTrading(); if (!t) return; @@ -797,7 +843,7 @@ void GameHandler::handleTrade(GameClient &client, MessageIn &message) case PGMSG_TRADE_AGREED: t->agree(client.character); // log transaction - accountHandler->sendTransaction(client.character->getDatabaseID(), + accountHandler->sendTransaction(databaseId, TRANS_TRADE_END, "User finished trading"); break; @@ -807,7 +853,7 @@ void GameHandler::handleTrade(GameClient &client, MessageIn &message) t->setMoney(client.character, money); // log transaction str << "User added " << money << " money to trade."; - accountHandler->sendTransaction(client.character->getDatabaseID(), + accountHandler->sendTransaction(databaseId, TRANS_TRADE_MONEY, str.str()); } break; case PGMSG_TRADE_ADD_ITEM: @@ -816,7 +862,7 @@ void GameHandler::handleTrade(GameClient &client, MessageIn &message) t->addItem(client.character, slot, message.readInt8()); // log transaction str << "User add item from slot " << slot; - accountHandler->sendTransaction(client.character->getDatabaseID(), + accountHandler->sendTransaction(databaseId, TRANS_TRADE_ITEM, str.str()); } break; } @@ -824,7 +870,8 @@ void GameHandler::handleTrade(GameClient &client, MessageIn &message) void GameHandler::handleNpcBuySell(GameClient &client, MessageIn &message) { - BuySell *t = client.character->getBuySell(); + BuySell *t = client.character->getComponent() + ->getBuySell(); if (!t) return; const int id = message.readInt16(); @@ -834,9 +881,13 @@ void GameHandler::handleNpcBuySell(GameClient &client, MessageIn &message) void GameHandler::handleRaiseAttribute(GameClient &client, MessageIn &message) { + auto *characterComponent = + client.character->getComponent(); + const int attribute = message.readInt16(); AttribmodResponseCode retCode; - retCode = client.character->useCharacterPoint(attribute); + retCode = characterComponent->useCharacterPoint(*client.character, + attribute); MessageOut result(GPMSG_RAISE_ATTRIBUTE_RESPONSE); result.writeInt8(retCode); @@ -846,23 +897,27 @@ void GameHandler::handleRaiseAttribute(GameClient &client, MessageIn &message) if (retCode == ATTRIBMOD_OK) { accountHandler->updateCharacterPoints( - client.character->getDatabaseID(), - client.character->getCharacterPoints(), - client.character->getCorrectionPoints()); + characterComponent->getDatabaseID(), + characterComponent->getCharacterPoints(), + characterComponent->getCorrectionPoints()); // log transaction std::stringstream str; str << "User increased attribute " << attribute; - accountHandler->sendTransaction(client.character->getDatabaseID(), + accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_ATTR_INCREASE, str.str()); } } void GameHandler::handleLowerAttribute(GameClient &client, MessageIn &message) { + auto *characterComponent = + client.character->getComponent(); + const int attribute = message.readInt32(); AttribmodResponseCode retCode; - retCode = client.character->useCorrectionPoint(attribute); + retCode = characterComponent->useCorrectionPoint(*client.character, + attribute); MessageOut result(GPMSG_LOWER_ATTRIBUTE_RESPONSE); result.writeInt8(retCode); @@ -872,14 +927,14 @@ void GameHandler::handleLowerAttribute(GameClient &client, MessageIn &message) if (retCode == ATTRIBMOD_OK) { accountHandler->updateCharacterPoints( - client.character->getDatabaseID(), - client.character->getCharacterPoints(), - client.character->getCorrectionPoints()); + characterComponent->getDatabaseID(), + characterComponent->getCharacterPoints(), + characterComponent->getCorrectionPoints()); // log transaction std::stringstream str; str << "User decreased attribute " << attribute; - accountHandler->sendTransaction(client.character->getDatabaseID(), + accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_ATTR_DECREASE, str.str()); } } diff --git a/src/game-server/gamehandler.h b/src/game-server/gamehandler.h index c05e0087..70facb4c 100644 --- a/src/game-server/gamehandler.h +++ b/src/game-server/gamehandler.h @@ -38,7 +38,7 @@ struct GameClient: NetComputer { GameClient(ENetPeer *peer) : NetComputer(peer), character(NULL), status(CLIENT_LOGIN) {} - Character *character; + Being *character; int status; }; @@ -58,17 +58,18 @@ class GameHandler: public ConnectionHandler /** * Sends message to the given character. */ - void sendTo(Character *, MessageOut &msg); + void sendTo(Entity *, MessageOut &msg); + void sendTo(GameClient *, MessageOut &msg); /** * Kills connection with given character. */ - void kill(Character *); + void kill(Entity *); /** * Prepares a server change for given character. */ - void prepareServerChange(Character *); + void prepareServerChange(Entity *); /** * Completes a server change for given character ID. @@ -85,13 +86,13 @@ class GameHandler: public ConnectionHandler * Registers a character that should soon be claimed by a client. * @param token token used by the client when connecting. */ - void addPendingCharacter(const std::string &token, Character *); + void addPendingCharacter(const std::string &token, Being *); /** * Combines a client with its character. * (Needed for TokenCollector) */ - void tokenMatched(GameClient *computer, Character *character); + void tokenMatched(GameClient *computer, Being *character); /** * Deletes a pending client's data. @@ -103,13 +104,13 @@ class GameHandler: public ConnectionHandler * Deletes a pending connection's data. * (Needed for TokenCollector) */ - void deletePendingConnect(Character *character); + void deletePendingConnect(Being *character); /** * Gets the character associated to a character name. This method is * slow, so it should never be called for regular operations. */ - Character *getCharacterByNameSlow(const std::string &) const; + Being *getCharacterByNameSlow(const std::string &) const; protected: NetComputer *computerConnected(ENetPeer *); @@ -160,7 +161,7 @@ class GameHandler: public ConnectionHandler /** * Container for pending clients and pending connections. */ - TokenCollector mTokenCollector; + TokenCollector mTokenCollector; }; extern GameHandler *gameHandler; diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index e14a36af..2219ada1 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -29,8 +29,15 @@ #include "net/messageout.h" #include "utils/logger.h" -Inventory::Inventory(Character *p): - mPoss(&p->getPossessions()), mCharacter(p) +Inventory::Inventory(Being *p): + mPoss(&p->getComponent()->getPossessions()), + mCharacter(p) +{ +} + +Inventory::Inventory(Being *p, Possessions &possessions): + mPoss(&possessions), + mCharacter(p) { } diff --git a/src/game-server/inventory.h b/src/game-server/inventory.h index 42856bff..75336ace 100644 --- a/src/game-server/inventory.h +++ b/src/game-server/inventory.h @@ -36,7 +36,8 @@ class Inventory /** * Creates a view on the possessions of a character. */ - Inventory(Character *); + explicit Inventory(Being *); + Inventory(Being *, Possessions &possessions); /** * Commits delayed changes if applicable. @@ -189,7 +190,7 @@ class Inventory Possessions *mPoss; /**< Pointer to the modified possessions. */ - Character *mCharacter; /**< Character to notify. */ + Being *mCharacter; /**< Character to notify. */ }; #endif diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index bb7093b2..e35c68fb 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -182,7 +182,7 @@ CharacterIterator::CharacterIterator(const ZoneIterator &it) while (iterator && (*iterator)->nbCharacters == 0) ++iterator; if (iterator) { - current = static_cast< Character * >((*iterator)->objects[pos]); + current = static_cast< Being * >((*iterator)->objects[pos]); } } @@ -195,7 +195,7 @@ void CharacterIterator::operator++() } if (iterator) { - current = static_cast< Character * >((*iterator)->objects[pos]); + current = static_cast< Being * >((*iterator)->objects[pos]); } } diff --git a/src/game-server/mapcomposite.h b/src/game-server/mapcomposite.h index ba76ddc8..c8eb2e88 100644 --- a/src/game-server/mapcomposite.h +++ b/src/game-server/mapcomposite.h @@ -31,7 +31,7 @@ class Actor; class Being; -class Character; +class CharacterComponent; class Map; class MapComposite; class Point; @@ -76,11 +76,11 @@ struct CharacterIterator { ZoneIterator iterator; unsigned short pos; - Character *current; + Being *current; CharacterIterator(const ZoneIterator &); void operator++(); - Character *operator*() const { return current; } + Being *operator*() const { return current; } operator bool() const { return iterator; } }; diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index 9e45bb1d..39b62593 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -307,7 +307,7 @@ void MonsterComponent::forgetTarget(Entity *entity) if (b->getType() == OBJECT_CHARACTER) { - Character *c = static_cast< Character * >(b); + Being *c = static_cast< Being * >(b); mExpReceivers.erase(c); mLegalExpReceivers.erase(c); } @@ -376,7 +376,7 @@ void MonsterComponent::monsterDied(Being *monster) } // Distribute exp reward. - std::map > ::iterator iChar; + std::map > ::iterator iChar; std::set::iterator iSkill; @@ -385,21 +385,24 @@ void MonsterComponent::monsterDied(Being *monster) for (iChar = mExpReceivers.begin(); iChar != mExpReceivers.end(); iChar++) { - Character *character = (*iChar).first; + auto *character = (*iChar).first; const std::set &skillSet = (*iChar).second; if (mLegalExpReceivers.find(character) == mLegalExpReceivers.end() || skillSet.empty()) continue; + auto characterComponent = + character->getComponent(); + int expPerSkill = int(expPerChar / skillSet.size()); for (iSkill = skillSet.begin(); iSkill != skillSet.end(); iSkill++) { - character->receiveExperience(*iSkill, expPerSkill, - mSpecy->getOptimalLevel()); + characterComponent->receiveExperience(*iSkill, expPerSkill, + mSpecy->getOptimalLevel()); } - character->incrementKillCount(mSpecy->getId()); + characterComponent->incrementKillCount(mSpecy->getId()); } } } @@ -412,14 +415,13 @@ void MonsterComponent::receivedDamage(Being *source, const Damage &damage, int h if (hpLoss && source && source->getType() == OBJECT_CHARACTER) { - Character *s = static_cast< Character * >(source); - - mExpReceivers[s].insert(damage.skill); - if (mKillStealProtectedTimeout.expired() || mOwner == s - || mOwner->getParty() == s->getParty()) + mExpReceivers[source].insert(damage.skill); + if (mKillStealProtectedTimeout.expired() || mOwner == source + || mOwner->getComponent()->getParty() == + source->getComponent()->getParty()) { - mOwner = s; - mLegalExpReceivers.insert(s); + mOwner = source; + mLegalExpReceivers.insert(source); mKillStealProtectedTimeout.set(KILLSTEAL_PROTECTION_TIME); } } diff --git a/src/game-server/monster.h b/src/game-server/monster.h index d1c8e900..e4d986b3 100644 --- a/src/game-server/monster.h +++ b/src/game-server/monster.h @@ -33,7 +33,7 @@ #include -class Character; +class CharacterComponent; class ItemClass; class Script; @@ -275,7 +275,7 @@ struct AttackPosition class MonsterComponent : public Component { public: - static const ComponentType type = CT_Monster; + static const ComponentType type = CT_Monster; /** Time in game ticks until ownership of a monster can change. */ static const int KILLSTEAL_PROTECTION_TIME = 100; @@ -339,16 +339,16 @@ class MonsterComponent : public Component /** * Character who currently owns this monster (killsteal protection). */ - Character *mOwner; + Being *mOwner; /** List of characters and their skills that attacked this monster. */ - std::map > mExpReceivers; + std::map > mExpReceivers; /** * List of characters who are entitled to receive exp (killsteal * protection). */ - std::set mLegalExpReceivers; + std::set mLegalExpReceivers; /** * Set positions relative to target from which the monster can attack. diff --git a/src/game-server/npc.cpp b/src/game-server/npc.cpp index 788f0c95..e7a2988b 100644 --- a/src/game-server/npc.cpp +++ b/src/game-server/npc.cpp @@ -73,9 +73,10 @@ void NpcComponent::setUpdateCallback(Script::Ref function) -static Script *prepareResume(Character *ch, Script::ThreadState expectedState) +static Script *prepareResume(Being *ch, Script::ThreadState expectedState) { - Script::Thread *thread = ch->getNpcThread(); + Script::Thread *thread = + ch->getComponent()->getNpcThread(); if (!thread || thread->mState != expectedState) return 0; @@ -84,7 +85,7 @@ static Script *prepareResume(Character *ch, Script::ThreadState expectedState) return script; } -void Npc::start(Being *npc, Character *ch) +void Npc::start(Being *npc, Being *ch) { NpcComponent *npcComponent = npc->getComponent(); @@ -98,30 +99,31 @@ void Npc::start(Being *npc, Character *ch) script->prepare(talkCallback); script->push(npc); script->push(ch); - ch->startNpcThread(thread, npc->getPublicID()); + ch->getComponent() + ->startNpcThread(thread, npc->getPublicID()); } } -void Npc::resume(Character *ch) +void Npc::resume(Being *ch) { if (prepareResume(ch, Script::ThreadPaused)) - ch->resumeNpcThread(); + ch->getComponent()->resumeNpcThread(); } -void Npc::integerReceived(Character *ch, int value) +void Npc::integerReceived(Being *ch, int value) { if (Script *script = prepareResume(ch, Script::ThreadExpectingNumber)) { script->push(value); - ch->resumeNpcThread(); + ch->getComponent()->resumeNpcThread(); } } -void Npc::stringReceived(Character *ch, const std::string &value) +void Npc::stringReceived(Being *ch, const std::string &value) { if (Script *script = prepareResume(ch, Script::ThreadExpectingString)) { script->push(value); - ch->resumeNpcThread(); + ch->getComponent()->resumeNpcThread(); } } diff --git a/src/game-server/npc.h b/src/game-server/npc.h index 1a0b4e8e..63d4ee8b 100644 --- a/src/game-server/npc.h +++ b/src/game-server/npc.h @@ -25,7 +25,7 @@ #include "game-server/component.h" #include "scripting/script.h" -class Character; +class CharacterComponent; /** * Component describing a non-player character. @@ -88,22 +88,22 @@ namespace Npc { /** * Starts a conversation with the NPC. */ -void start(Being *npc, Character *ch); +void start(Being *npc, Being *ch); /** * Resumes an NPC conversation. */ -void resume(Character *ch); +void resume(Being *ch); /** * The player has made a choice or entered an integer. */ -void integerReceived(Character *ch, int value); +void integerReceived(Being *ch, int value); /** * The player has entered an string. */ -void stringReceived(Character *ch, const std::string &value); +void stringReceived(Being *ch, const std::string &value); } // namespace Npc diff --git a/src/game-server/postman.h b/src/game-server/postman.h index b9cf7bb2..8862ccf6 100644 --- a/src/game-server/postman.h +++ b/src/game-server/postman.h @@ -24,12 +24,12 @@ #include #include -class Character; +class Being; class Script; struct PostCallback { - void (*handler)(Character *, + void (*handler)(Being *, const std::string &sender, const std::string &letter, Script *); @@ -40,32 +40,35 @@ struct PostCallback class PostMan { public: - Character *getCharacter(int id) const + Being *getCharacter(int id) const { - std::map::const_iterator itr = mCharacters.find(id); + std::map::const_iterator itr = mCharacters.find(id); if (itr != mCharacters.end()) return itr->second; return 0; } - void addCharacter(Character *player) + void addCharacter(Entity *player) { - std::map::iterator itr = mCharacters.find(player->getDatabaseID()); + int dataBaseId = player->getComponent() + ->getDatabaseID(); + std::map::iterator itr = mCharacters.find(dataBaseId); if (itr == mCharacters.end()) { - mCharacters.insert(std::pair(player->getDatabaseID(), player)); + Being *being = static_cast(player); + mCharacters.insert(std::pair(dataBaseId, being)); } } - void getPost(Character *player, PostCallback &f) + void getPost(Being *player, PostCallback &f) { - mCallbacks.insert(std::pair(player, f)); + mCallbacks.insert(std::pair(player, f)); accountHandler->getPost(player); } - void gotPost(Character *player, std::string sender, std::string letter) + void gotPost(Being *player, std::string sender, std::string letter) { - std::map::iterator itr = mCallbacks.find(player); + std::map::iterator itr = mCallbacks.find(player); if (itr != mCallbacks.end()) { itr->second.handler(player, sender, letter, itr->second.script); @@ -73,8 +76,8 @@ public: } private: - std::map mCharacters; - std::map mCallbacks; + std::map mCharacters; + std::map mCallbacks; }; extern PostMan *postMan; diff --git a/src/game-server/quest.cpp b/src/game-server/quest.cpp index d6d7d92d..803ec60b 100644 --- a/src/game-server/quest.cpp +++ b/src/game-server/quest.cpp @@ -36,7 +36,7 @@ typedef std::map< std::string, QuestCallbacks > PendingVariables; struct PendingQuest { - Character *character; + Being *character; sigc::connection removedConnection; sigc::connection disconnectedConnection; PendingVariables variables; @@ -46,23 +46,27 @@ typedef std::map< int, PendingQuest > PendingQuests; static PendingQuests pendingQuests; -bool getQuestVar(Character *ch, const std::string &name, std::string &value) +bool getQuestVar(Being *ch, const std::string &name, std::string &value) { std::map< std::string, std::string >::iterator - i = ch->questCache.find(name); - if (i == ch->questCache.end()) return false; + i = ch->getComponent()->questCache.find(name); + if (i == ch->getComponent()->questCache.end()) + return false; value = i->second; return true; } -void setQuestVar(Character *ch, const std::string &name, +void setQuestVar(Being *ch, const std::string &name, const std::string &value) { + auto *characterComponent = + ch->getComponent(); + std::map< std::string, std::string >::iterator - i = ch->questCache.lower_bound(name); - if (i == ch->questCache.end() || i->first != name) + i = characterComponent->questCache.lower_bound(name); + if (i == characterComponent->questCache.end() || i->first != name) { - ch->questCache.insert(i, std::make_pair(name, value)); + characterComponent->questCache.insert(i, std::make_pair(name, value)); } else if (i->second == value) { @@ -75,7 +79,7 @@ void setQuestVar(Character *ch, const std::string &name, accountHandler->updateCharacterVar(ch, name, value); } -void QuestRefCallback::triggerCallback(Character *ch, +void QuestRefCallback::triggerCallback(Being *ch, const std::string &value) const { if (!mRef.isValid()) @@ -91,7 +95,7 @@ void QuestRefCallback::triggerCallback(Character *ch, static void partialRemove(Entity *t) { - int id = static_cast< Character * >(t)->getDatabaseID(); + int id = t->getComponent()->getDatabaseID(); PendingVariables &variables = pendingQuests[id].variables; // Remove all the callbacks, but do not remove the variable names. for (PendingVariables::iterator i = variables.begin(), @@ -102,9 +106,9 @@ static void partialRemove(Entity *t) // The listener is kept in case a fullRemove is needed later. } -static void fullRemove(Character *ch) +static void fullRemove(Entity &ch) { - int id = ch->getDatabaseID(); + int id = ch.getComponent()->getDatabaseID(); { PendingQuest &pendingQuest = pendingQuests[id]; @@ -116,11 +120,15 @@ static void fullRemove(Character *ch) pendingQuests.erase(id); } -void recoverQuestVar(Character *ch, const std::string &name, +void recoverQuestVar(Being *ch, const std::string &name, QuestCallback *f) { - assert(ch->questCache.find(name) == ch->questCache.end()); - int id = ch->getDatabaseID(); + auto *characterComponent = + ch->getComponent(); + + assert(characterComponent->questCache.find(name) == + characterComponent->questCache.end()); + int id = ch->getComponent()->getDatabaseID(); PendingQuests::iterator i = pendingQuests.lower_bound(id); if (i == pendingQuests.end() || i->first != id) { @@ -134,7 +142,8 @@ void recoverQuestVar(Character *ch, const std::string &name, pendingQuest.removedConnection = ch->signal_removed.connect(sigc::ptr_fun(partialRemove)); pendingQuest.disconnectedConnection = - ch->signal_disconnected.connect(sigc::ptr_fun(fullRemove)); + characterComponent->signal_disconnected.connect( + sigc::ptr_fun(fullRemove)); i = pendingQuests.insert(i, std::make_pair(id, pendingQuest)); } @@ -162,8 +171,9 @@ void recoveredQuestVar(int id, return; } - Character *ch = pendingQuest.character; - ch->questCache[name] = value; + Being *ch = pendingQuest.character; + auto *characterComponent = ch->getComponent(); + characterComponent->questCache[name] = value; // Call the registered callbacks. for (QuestCallbacks::const_iterator k = j->second.begin(), diff --git a/src/game-server/quest.h b/src/game-server/quest.h index 0d130789..13f91cc2 100644 --- a/src/game-server/quest.h +++ b/src/game-server/quest.h @@ -25,7 +25,7 @@ #include "scripting/scriptmanager.h" -class Character; +class Being; class Script; @@ -35,14 +35,14 @@ class QuestCallback virtual ~QuestCallback() { } - virtual void triggerCallback(Character *ch, + virtual void triggerCallback(Being *ch, const std::string &value) const = 0; }; class QuestThreadCallback : public QuestCallback { public: - typedef void (*Handler)(Character *, + typedef void (*Handler)(Being *, const std::string &value, Script *mScript); @@ -52,7 +52,7 @@ class QuestThreadCallback : public QuestCallback mScript(script) { } - void triggerCallback(Character *ch, const std::string &value) const + void triggerCallback(Being *ch, const std::string &value) const { mHandler(ch, value, mScript); } private: @@ -67,7 +67,7 @@ class QuestRefCallback : public QuestCallback mQuestName(questName) { script->assignCallback(mRef); } - void triggerCallback(Character *ch, const std::string &value) const; + void triggerCallback(Being *ch, const std::string &value) const; private: Script::Ref mRef; @@ -78,19 +78,18 @@ class QuestRefCallback : public QuestCallback * Gets the value associated to a quest variable. * @return false if no value was in cache. */ -bool getQuestVar(Character *, const std::string &name, std::string &value); +bool getQuestVar(Being *, const std::string &name, std::string &value); /** * Sets the value associated to a quest variable. */ -void setQuestVar(Character *, const std::string &name, - const std::string &value); +void setQuestVar(Being *, const std::string &name, const std::string &value); /** * Starts the recovery of a variable and returns immediatly. The callback will * be called once the value has been recovered. */ -void recoverQuestVar(Character *, const std::string &name, QuestCallback *); +void recoverQuestVar(Being *, const std::string &name, QuestCallback *); /** * Called by the handler of the account server when a value is received. diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 74bd87e4..f1ed99a0 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -79,9 +79,10 @@ static std::map< std::string, std::string > mScriptVariables; /** * Sets message fields describing character look. */ -static void serializeLooks(Character *ch, MessageOut &msg) +static void serializeLooks(Being *ch, MessageOut &msg) { - const EquipData &equipData = ch->getPossessions().getEquipment(); + const EquipData &equipData = ch->getComponent() + ->getPossessions().getEquipment(); // We'll use a set to check whether we already sent the update for the given // item instance. @@ -127,7 +128,7 @@ static void serializeLooks(Character *ch, MessageOut &msg) /** * Informs a player of what happened around the character. */ -static void informPlayer(MapComposite *map, Character *p) +static void informPlayer(MapComposite *map, Being *p) { MessageOut moveMsg(GPMSG_BEINGS_MOVE); MessageOut damageMsg(GPMSG_BEINGS_DAMAGE); @@ -186,11 +187,12 @@ static void informPlayer(MapComposite *map, Character *p) { MessageOut LooksMsg(GPMSG_BEING_LOOKS_CHANGE); LooksMsg.writeInt16(oid); - Character * c = static_cast(o); - serializeLooks(c, LooksMsg); - LooksMsg.writeInt16(c->getHairStyle()); - LooksMsg.writeInt16(c->getHairColor()); - LooksMsg.writeInt16(c->getGender()); + serializeLooks(o, LooksMsg); + auto *characterComponent = + o->getComponent(); + LooksMsg.writeInt16(characterComponent->getHairStyle()); + LooksMsg.writeInt16(characterComponent->getHairColor()); + LooksMsg.writeInt16(o->getGender()); gameHandler->sendTo(p, LooksMsg); } @@ -261,11 +263,12 @@ static void informPlayer(MapComposite *map, Character *p) { case OBJECT_CHARACTER: { - Character *q = static_cast< Character * >(o); - enterMsg.writeString(q->getName()); - enterMsg.writeInt8(q->getHairStyle()); - enterMsg.writeInt8(q->getHairColor()); - serializeLooks(q, enterMsg); + auto *characterComponent = + o->getComponent(); + enterMsg.writeString(o->getName()); + enterMsg.writeInt8(characterComponent->getHairStyle()); + enterMsg.writeInt8(characterComponent->getHairColor()); + serializeLooks(o, enterMsg); } break; case OBJECT_MONSTER: @@ -328,19 +331,20 @@ static void informPlayer(MapComposite *map, Character *p) gameHandler->sendTo(p, damageMsg); // Inform client about status change. - p->sendStatus(); + p->getComponent()->sendStatus(*p); // Inform client about health change of party members for (CharacterIterator i(map->getWholeMapIterator()); i; ++i) { - Character *c = *i; + Being *c = *i; // Make sure its not the same character if (c == p) continue; // make sure they are in the same party - if (c->getParty() == p->getParty()) + if (c->getComponent()->getParty() == + p->getComponent()->getParty()) { int cflags = c->getUpdateFlags(); if (cflags & UPDATEFLAG_HEALTHCHANGE) @@ -487,9 +491,8 @@ void GameState::update(int tick) remove(o); if (o->getType() == OBJECT_CHARACTER) { - Character *ch = static_cast< Character * >(o); - ch->disconnected(); - gameHandler->kill(ch); + o->getComponent()->disconnected(*o); + gameHandler->kill(o); } delete o; break; @@ -500,7 +503,7 @@ void GameState::update(int tick) case EVENT_WARP: assert(o->getType() == OBJECT_CHARACTER); - warp(static_cast< Character * >(o), e.map, e.point); + warp(static_cast(o), e.map, e.point); break; } } @@ -593,11 +596,11 @@ bool GameState::insert(Entity *ptr) mapChangeMessage.writeString(map->getName()); mapChangeMessage.writeInt16(pos.x); mapChangeMessage.writeInt16(pos.y); - gameHandler->sendTo(static_cast< Character * >(obj), mapChangeMessage); + gameHandler->sendTo(ptr, mapChangeMessage); // update the online state of the character - accountHandler->updateOnlineStatus( - static_cast< Character * >(obj)->getDatabaseID(), true); + accountHandler->updateOnlineStatus(ptr->getComponent() + ->getDatabaseID(), true); return true; } @@ -663,11 +666,13 @@ void GameState::remove(Entity *ptr) { if (ptr->getType() == OBJECT_CHARACTER) { - static_cast< Character * >(ptr)->cancelTransaction(); + auto *characterComponent = + ptr->getComponent(); + characterComponent->cancelTransaction(); // remove characters online status accountHandler->updateOnlineStatus( - static_cast< Character * >(ptr)->getDatabaseID(), false); + characterComponent->getDatabaseID(), false); } Actor *obj = static_cast< Actor * >(ptr); @@ -706,7 +711,7 @@ void GameState::remove(Entity *ptr) map->remove(ptr); } -void GameState::warp(Character *ptr, MapComposite *map, const Point &point) +void GameState::warp(Being *ptr, MapComposite *map, const Point &point) { remove(ptr); ptr->setMap(map); @@ -717,16 +722,19 @@ void GameState::warp(Character *ptr, MapComposite *map, const Point &point) a disconnection. */ accountHandler->sendCharacterData(ptr); + auto *characterComponent = + ptr->getComponent(); + // If the player has just left, The character pointer is also about // to be deleted. So we don't have to do anything else. - if (!ptr->isConnected()) + if (!characterComponent->isConnected()) return; if (map->isActive()) { if (!insert(ptr)) { - ptr->disconnected(); + characterComponent->disconnected(*ptr); gameHandler->kill(ptr); delete ptr; } @@ -734,7 +742,7 @@ void GameState::warp(Character *ptr, MapComposite *map, const Point &point) else { MessageOut msg(GAMSG_REDIRECT); - msg.writeInt32(ptr->getDatabaseID()); + msg.writeInt32(characterComponent->getDatabaseID()); accountHandler->send(msg); gameHandler->prepareServerChange(ptr); } @@ -770,13 +778,13 @@ void GameState::enqueueRemove(Actor *ptr) enqueueEvent(ptr, event); } -void GameState::enqueueWarp(Character *ptr, +void GameState::enqueueWarp(Being *ptr, MapComposite *map, const Point &point) { // When the player has just disconnected, better not wait for the pointer // to become invalid. - if (!ptr->isConnected()) + if (!ptr->getComponent()->isConnected()) { warp(ptr, map, point); return; @@ -823,7 +831,7 @@ void GameState::sayTo(Actor *destination, Actor *source, const std::string &text } msg.writeString(text); - gameHandler->sendTo(static_cast< Character * >(destination), msg); + gameHandler->sendTo(destination, msg); } void GameState::sayToAll(const std::string &text) diff --git a/src/game-server/state.h b/src/game-server/state.h index e8ed30a8..512e9afd 100644 --- a/src/game-server/state.h +++ b/src/game-server/state.h @@ -26,7 +26,7 @@ #include class Actor; -class Character; +class Being; class Entity; class ItemClass; class MapComposite; @@ -71,7 +71,7 @@ namespace GameState * @note No update may be in progress. * @note The character is destroyed, if needed. */ - void warp(Character *, MapComposite *, const Point &point); + void warp(Being *, MapComposite *, const Point &point); /** * Enqueues an insert event. @@ -90,7 +90,7 @@ namespace GameState * Enqueues a warp event. * @note The event will be executed at end of update. */ - void enqueueWarp(Character *, MapComposite *, const Point &point); + void enqueueWarp(Being *, MapComposite *, const Point &point); /** * Says something to an actor. diff --git a/src/game-server/trade.cpp b/src/game-server/trade.cpp index 042719b2..9e9e05fb 100644 --- a/src/game-server/trade.cpp +++ b/src/game-server/trade.cpp @@ -37,31 +37,31 @@ * TRADE_AGREE_WAIT : One player has agreed, waiting for the other one */ -Trade::Trade(Character *c1, Character *c2): +Trade::Trade(Being *c1, Being *c2): mChar1(c1), mChar2(c2), mMoney1(0), mMoney2(0), mState(TRADE_INIT), mCurrencyId(ATTR_GP) { MessageOut msg(GPMSG_TRADE_REQUEST); msg.writeInt16(c1->getPublicID()); - c2->getClient()->send(msg); - c1->setTrading(this); - c2->setTrading(this); + c2->getComponent()->getClient()->send(msg); + c1->getComponent()->setTrading(this); + c2->getComponent()->setTrading(this); } Trade::~Trade() { - mChar1->setTrading(NULL); - mChar2->setTrading(NULL); + mChar1->getComponent()->setTrading(nullptr); + mChar2->getComponent()->setTrading(nullptr); } void Trade::cancel() { MessageOut msg(GPMSG_TRADE_CANCEL); - mChar1->getClient()->send(msg); - mChar2->getClient()->send(msg); + mChar1->getComponent()->getClient()->send(msg); + mChar2->getComponent()->getClient()->send(msg); delete this; } -bool Trade::request(Character *c, int id) +bool Trade::request(Being *c, int id) { //The trade isn't confirmed, the player which is request is the same. if (mState != TRADE_INIT || c != mChar2 || mChar1->getPublicID() != id) @@ -79,8 +79,8 @@ bool Trade::request(Character *c, int id) //Telling both player that the trade has started MessageOut msg(GPMSG_TRADE_START); - mChar1->getClient()->send(msg); - mChar2->getClient()->send(msg); + mChar1->getComponent()->getClient()->send(msg); + mChar2->getComponent()->getClient()->send(msg); return true; } @@ -99,7 +99,7 @@ bool Trade::perform(TradedItems items, Inventory &inv1, Inventory &inv2) return true; } -void Trade::agree(Character *c) +void Trade::agree(Being *c) { // No player agreed if (mState == TRADE_CONFIRMED) @@ -116,7 +116,7 @@ void Trade::agree(Character *c) // Send the other player that the first player has confirmed MessageOut msg(GPMSG_TRADE_AGREED); - mChar2->getClient()->send(msg); + mChar2->getComponent()->getClient()->send(msg); return; } @@ -148,12 +148,12 @@ void Trade::agree(Character *c) } MessageOut msg(GPMSG_TRADE_COMPLETE); - mChar1->getClient()->send(msg); - mChar2->getClient()->send(msg); + mChar1->getComponent()->getClient()->send(msg); + mChar2->getComponent()->getClient()->send(msg); delete this; } -void Trade::confirm(Character *c) +void Trade::confirm(Being *c) { if (mState == TRADE_CONFIRMED || mState == TRADE_AGREE_WAIT) return; @@ -173,7 +173,7 @@ void Trade::confirm(Character *c) //Send the other player that the first player has confirmed MessageOut msg(GPMSG_TRADE_CONFIRM); - mChar2->getClient()->send(msg); + mChar2->getComponent()->getClient()->send(msg); return; } @@ -185,11 +185,11 @@ void Trade::confirm(Character *c) mState = TRADE_CONFIRMED; MessageOut msg(GPMSG_TRADE_BOTH_CONFIRM); - mChar1->getClient()->send(msg); - mChar2->getClient()->send(msg); + mChar1->getComponent()->getClient()->send(msg); + mChar2->getComponent()->getClient()->send(msg); } -void Trade::setMoney(Character *c, int amount) +void Trade::setMoney(Being *c, int amount) { //If the player has already confirmed, exit. if ((mState != TRADE_RUN && (mState != TRADE_CONFIRM_WAIT || c != mChar1)) @@ -205,26 +205,26 @@ void Trade::setMoney(Character *c, int amount) if (c == mChar1) { mMoney1 = amount; - mChar2->getClient()->send(msg); + mChar2->getComponent()->getClient()->send(msg); } else { assert(c == mChar2); mMoney2 = amount; - mChar1->getClient()->send(msg); + mChar1->getComponent()->getClient()->send(msg); } // Go back to normal run. mState = TRADE_RUN; } -void Trade::addItem(Character *c, int slot, int amount) +void Trade::addItem(Being *c, int slot, int amount) { //If the player has already confirmed, exit. if ((mState != TRADE_RUN && (mState != TRADE_CONFIRM_WAIT || c != mChar1)) || amount < 0) return; - Character *other; + Being *other; TradedItems *items; if (c == mChar1) { @@ -258,5 +258,5 @@ void Trade::addItem(Character *c, int slot, int amount) MessageOut msg(GPMSG_TRADE_ADD_ITEM); msg.writeInt16(id); msg.writeInt8(amount); - other->getClient()->send(msg); + other->getComponent()->getClient()->send(msg); } diff --git a/src/game-server/trade.h b/src/game-server/trade.h index 3e5fb3a3..be527e86 100644 --- a/src/game-server/trade.h +++ b/src/game-server/trade.h @@ -23,7 +23,7 @@ #include -class Character; +class Being; class Inventory; class Trade @@ -34,7 +34,7 @@ class Trade * Sets up a trade between two characters. * Asks for an acknowledgment from the second one. */ - Trade(Character *, Character *); + Trade(Being *, Being *); /** * Cancels a trade by a given character (optional). @@ -49,27 +49,27 @@ class Trade * otherwise. * @return true if the current trade keeps going. */ - bool request(Character *, int); + bool request(Being *, int); /** * Confirm the trade. */ - void confirm(Character *); + void confirm(Being *); /* * Agree to complete the trade */ - void agree(Character *c); + void agree(Being *c); /** * Adds some items to the trade. */ - void addItem(Character *, int slot, int amount); + void addItem(Being *, int slot, int amount); /** * Adds some money to the trade. */ - void setMoney(Character *, int amount); + void setMoney(Being *, int amount); private: @@ -98,7 +98,7 @@ class Trade static bool perform(TradedItems items, Inventory &inv1, Inventory &inv2); - Character *mChar1, *mChar2; /**< Characters involved. */ + Being *mChar1, *mChar2; /**< Characters involved. */ TradedItems mItems1, mItems2; /**< Traded items. */ int mMoney1, mMoney2; /**< Traded money. */ TradeState mState; /**< State of transaction. */ diff --git a/src/game-server/triggerareacomponent.cpp b/src/game-server/triggerareacomponent.cpp index 7c32f097..d4736e4e 100644 --- a/src/game-server/triggerareacomponent.cpp +++ b/src/game-server/triggerareacomponent.cpp @@ -34,7 +34,7 @@ void WarpAction::process(Actor *obj) { if (obj->getType() == OBJECT_CHARACTER) { - GameState::enqueueWarp(static_cast< Character * >(obj), mMap, mTargetPoint); + GameState::enqueueWarp(static_cast(obj), mMap, mTargetPoint); } } diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 993508a2..622d1867 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -120,7 +120,7 @@ static int on_recalculate_base_attribute(lua_State *s) static int on_character_death(lua_State *s) { luaL_checktype(s, 1, LUA_TFUNCTION); - Character::setDeathCallback(getScript(s)); + CharacterComponent::setDeathCallback(getScript(s)); return 0; } @@ -134,7 +134,7 @@ static int on_character_death(lua_State *s) static int on_character_death_accept(lua_State *s) { luaL_checktype(s, 1, LUA_TFUNCTION); - Character::setDeathAcceptedCallback(getScript(s)); + CharacterComponent::setDeathAcceptedCallback(getScript(s)); return 0; } @@ -147,7 +147,7 @@ static int on_character_death_accept(lua_State *s) static int on_character_login(lua_State *s) { luaL_checktype(s, 1, LUA_TFUNCTION); - Character::setLoginCallback(getScript(s)); + CharacterComponent::setLoginCallback(getScript(s)); return 0; } @@ -502,7 +502,7 @@ static int item_drop(lua_State *s) static int npc_message(lua_State *s) { Being *npc = checkNpc(s, 1); - Character *q = checkCharacter(s, 2); + Being *q = checkCharacter(s, 2); const char *m = luaL_checkstring(s, 3); Script::Thread *thread = checkCurrentThread(s); @@ -535,7 +535,7 @@ static int npc_message(lua_State *s) static int npc_choice(lua_State *s) { Being *npc = checkNpc(s, 1); - Character *q = checkCharacter(s, 2); + Being *q = checkCharacter(s, 2); Script::Thread *thread = checkCurrentThread(s); @@ -591,7 +591,7 @@ static int npc_choice(lua_State *s) static int npc_ask_integer(lua_State *s) { Being *npc = checkNpc(s, 1); - Character *q = checkCharacter(s, 2); + Being *q = checkCharacter(s, 2); int min = luaL_checkint(s, 3); int max = luaL_checkint(s, 4); int defaultValue = luaL_optint(s, 5, min); @@ -621,7 +621,7 @@ static int npc_ask_integer(lua_State *s) static int npc_ask_string(lua_State *s) { Being *npc = checkNpc(s, 1); - Character *q = checkCharacter(s, 2); + Being *q = checkCharacter(s, 2); Script::Thread *thread = checkCurrentThread(s); @@ -641,7 +641,7 @@ static int npc_ask_string(lua_State *s) static int npc_post(lua_State *s) { Being *npc = checkNpc(s, 1); - Character *q = checkCharacter(s, 2); + Being *q = checkCharacter(s, 2); MessageOut msg(GPMSG_NPC_POST); msg.writeInt16(npc->getPublicID()); @@ -768,7 +768,7 @@ static int announce(lua_State *s) static int npc_trade(lua_State *s) { Being *npc = checkNpc(s, 1); - Character *q = checkCharacter(s, 2); + Being *q = checkCharacter(s, 2); if (!lua_isboolean(s, 3)) { luaL_error(s, "npc_trade called with incorrect parameters."); @@ -892,7 +892,7 @@ static int npc_trade(lua_State *s) */ static int chr_inv_count(lua_State *s) { - Character *q = checkCharacter(s, 1); + Being *q = checkCharacter(s, 1); if (!lua_isboolean(s, 2) || !lua_isboolean(s, 3)) { luaL_error(s, "chr_inv_count called with incorrect parameters."); @@ -933,7 +933,7 @@ static int chr_inv_count(lua_State *s) */ static int chr_inv_change(lua_State *s) { - Character *q = checkCharacter(s, 1); + Being *q = checkCharacter(s, 1); int nb_items = (lua_gettop(s) - 1) / 2; Inventory inv(q); for (int i = 0; i < nb_items; ++i) @@ -997,10 +997,11 @@ static int chr_inv_change(lua_State *s) */ static int chr_get_inventory(lua_State *s) { - Character *q = checkCharacter(s, 1); + Being *q = checkCharacter(s, 1); // Create a lua table with the inventory ids. - const InventoryData invData = q->getPossessions().getInventory(); + const InventoryData invData = q->getComponent() + ->getPossessions().getInventory(); lua_newtable(s); int firstTableStackPosition = lua_gettop(s); @@ -1061,10 +1062,11 @@ static int chr_get_inventory(lua_State *s) */ static int chr_get_equipment(lua_State *s) { - Character *q = checkCharacter(s, 1); + Being *q = checkCharacter(s, 1); // Create a lua table with the inventory ids. - const EquipData equipData = q->getPossessions().getEquipment(); + const EquipData equipData = q->getComponent() + ->getPossessions().getEquipment(); lua_newtable(s); int firstTableStackPosition = lua_gettop(s); @@ -1113,7 +1115,7 @@ static int chr_get_equipment(lua_State *s) */ static int chr_equip_slot(lua_State *s) { - Character *ch = checkCharacter(s, 1); + Being *ch = checkCharacter(s, 1); int inventorySlot = luaL_checkint(s, 2); Inventory inv(ch); @@ -1132,7 +1134,7 @@ static int chr_equip_slot(lua_State *s) */ static int chr_equip_item(lua_State *s) { - Character *ch = checkCharacter(s, 1); + Being *ch = checkCharacter(s, 1); ItemClass *it = checkItemClass(s, 2); Inventory inv(ch); @@ -1156,7 +1158,7 @@ static int chr_equip_item(lua_State *s) */ static int chr_unequip_slot(lua_State *s) { - Character *ch = checkCharacter(s, 1); + Being *ch = checkCharacter(s, 1); int equipmentSlot = luaL_checkint(s, 2); Inventory inv(ch); @@ -1176,7 +1178,7 @@ static int chr_unequip_slot(lua_State *s) */ static int chr_unequip_item(lua_State *s) { - Character *ch = checkCharacter(s, 1); + Being *ch = checkCharacter(s, 1); ItemClass *it = checkItemClass(s, 2); Inventory inv(ch); @@ -1197,7 +1199,7 @@ static int chr_unequip_item(lua_State *s) */ static int chr_get_quest(lua_State *s) { - Character *q = checkCharacter(s, 1); + Being *q = checkCharacter(s, 1); const char *name = luaL_checkstring(s, 2); luaL_argcheck(s, name[0] != 0, 2, "empty variable name"); @@ -1226,7 +1228,7 @@ static int chr_get_quest(lua_State *s) */ static int chr_set_quest(lua_State *s) { - Character *q = checkCharacter(s, 1); + Being *q = checkCharacter(s, 1); const char *name = luaL_checkstring(s, 2); const char *value = luaL_checkstring(s, 3); luaL_argcheck(s, name[0] != 0, 2, "empty variable name"); @@ -1246,11 +1248,12 @@ static int chr_set_quest(lua_State *s) */ static int chr_set_special_recharge_speed(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const int special = checkSpecial(s, 2); const int speed = luaL_checkint(s, 3); - if (!c->setSpecialRechargeSpeed(special, speed)) + if (!c->getComponent() + ->setSpecialRechargeSpeed(special, speed)) { luaL_error(s, "chr_set_special_recharge_speed called with special " @@ -1271,12 +1274,14 @@ static int chr_set_special_recharge_speed(lua_State *s) */ static int chr_get_special_recharge_speed(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const int special = checkSpecial(s, 2); - SpecialMap::iterator it = c->findSpecial(special); + auto *characterComponent = c->getComponent(); - luaL_argcheck(s, it != c->getSpecialEnd(), 2, + SpecialMap::iterator it = characterComponent->findSpecial(special); + + luaL_argcheck(s, it != characterComponent->getSpecialEnd(), 2, "character does not have special"); lua_pushinteger(s, it->second.rechargeSpeed); @@ -1295,10 +1300,10 @@ static int chr_get_special_recharge_speed(lua_State *s) */ static int chr_set_special_mana(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const int special = checkSpecial(s, 2); const int mana = luaL_checkint(s, 3); - if (!c->setSpecialMana(special, mana)) + if (!c->getComponent()->setSpecialMana(special, mana)) { luaL_error(s, "chr_set_special_mana called with special " @@ -1319,10 +1324,11 @@ static int chr_set_special_mana(lua_State *s) */ static int chr_get_special_mana(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); + auto *characterComponent = c->getComponent(); const int special = checkSpecial(s, 2); - SpecialMap::iterator it = c->findSpecial(special); - luaL_argcheck(s, it != c->getSpecialEnd(), 2, + SpecialMap::iterator it = characterComponent->findSpecial(special); + luaL_argcheck(s, it != characterComponent->getSpecialEnd(), 2, "character does not have special"); lua_pushinteger(s, it->second.currentMana); return 1; @@ -1610,7 +1616,7 @@ static int being_get_walkmask(lua_State *s) */ static int chr_warp(lua_State *s) { - Character *q = checkCharacter(s, 1); + Being *q = checkCharacter(s, 1); int x = luaL_checkint(s, 3); int y = luaL_checkint(s, 4); @@ -1838,15 +1844,17 @@ static int being_set_gender(lua_State *s) */ static int chr_get_level(lua_State *s) { - Character *ch = checkCharacter(s, 1); + Being *ch = checkCharacter(s, 1); + auto *characterComponent = ch->getComponent(); if (lua_gettop(s) > 1) { int skillId = checkSkill(s, 2); - lua_pushinteger(s, ch->levelForExp(ch->getExperience(skillId))); + lua_pushinteger(s, characterComponent->levelForExp( + characterComponent->getExperience(skillId))); } else { - lua_pushinteger(s, ch->getLevel()); + lua_pushinteger(s, characterComponent->getLevel()); } return 1; } @@ -1862,9 +1870,9 @@ static int chr_get_level(lua_State *s) */ static int chr_get_exp(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); int skill = checkSkill(s, 2); - const int exp = c->getExperience(skill); + const int exp = c->getComponent()->getExperience(skill); lua_pushinteger(s, exp); return 1; @@ -1882,12 +1890,13 @@ static int chr_get_exp(lua_State *s) */ static int chr_give_exp(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); int skill = checkSkill(s, 2); const int exp = luaL_checkint(s, 3); const int optimalLevel = luaL_optint(s, 4, 0); - c->receiveExperience(skill, exp, optimalLevel); + c->getComponent()->receiveExperience(skill, exp, + optimalLevel); return 0; } @@ -1900,7 +1909,7 @@ static int chr_give_exp(lua_State *s) static int exp_for_level(lua_State *s) { const int level = luaL_checkint(s, 1); - lua_pushinteger(s, Character::expForLevel(level)); + lua_pushinteger(s, CharacterComponent::expForLevel(level)); return 1; } @@ -1911,9 +1920,9 @@ static int exp_for_level(lua_State *s) */ static int chr_get_hair_color(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); - lua_pushinteger(s, c->getHairColor()); + lua_pushinteger(s, c->getComponent()->getHairColor()); return 1; } @@ -1924,11 +1933,11 @@ static int chr_get_hair_color(lua_State *s) */ static int chr_set_hair_color(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const int color = luaL_checkint(s, 2); luaL_argcheck(s, color >= 0, 2, "invalid color id"); - c->setHairColor(color); + c->getComponent()->setHairColor(color); c->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); return 0; @@ -1941,9 +1950,9 @@ static int chr_set_hair_color(lua_State *s) */ static int chr_get_hair_style(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); - lua_pushinteger(s, c->getHairStyle()); + lua_pushinteger(s, c->getComponent()->getHairStyle()); return 1; } @@ -1954,11 +1963,11 @@ static int chr_get_hair_style(lua_State *s) */ static int chr_set_hair_style(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const int style = luaL_checkint(s, 2); luaL_argcheck(s, style >= 0, 2, "invalid style id"); - c->setHairStyle(style); + c->getComponent()->setHairStyle(style); c->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); return 0; } @@ -1974,10 +1983,10 @@ static int chr_set_hair_style(lua_State *s) */ static int chr_get_kill_count(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); MonsterClass *monster = checkMonsterClass(s, 2); - lua_pushinteger(s, c->getKillCount(monster->getId())); + lua_pushinteger(s, c->getComponent()->getKillCount(monster->getId())); return 1; } @@ -1988,8 +1997,9 @@ static int chr_get_kill_count(lua_State *s) */ static int chr_get_rights(lua_State *s) { - Character *c = checkCharacter(s, 1); - lua_pushinteger(s, c->getAccountLevel()); + Being *c = checkCharacter(s, 1); + lua_pushinteger(s, + c->getComponent()->getAccountLevel()); return 1; } @@ -2000,10 +2010,10 @@ static int chr_get_rights(lua_State *s) */ static int chr_kick(lua_State *s) { - Character *ch = checkCharacter(s, 1); + Being *ch = checkCharacter(s, 1); MessageOut kickmsg(GPMSG_CONNECT_RESPONSE); kickmsg.writeInt8(ERRMSG_ADMINISTRATIVE_LOGOFF); - ch->getClient()->disconnect(kickmsg); + ch->getComponent()->getClient()->disconnect(kickmsg); return 0; } @@ -2033,7 +2043,7 @@ static int being_get_mapid(lua_State *s) */ static int chr_request_quest(lua_State *s) { - Character *ch = checkCharacter(s, 1); + Being *ch = checkCharacter(s, 1); const char *name = luaL_checkstring(s, 2); luaL_argcheck(s, name[0] != 0, 2, "empty variable name"); luaL_checktype(s, 3, LUA_TFUNCTION); @@ -2072,7 +2082,7 @@ static int chr_request_quest(lua_State *s) */ static int chr_try_get_quest(lua_State *s) { - Character *q = checkCharacter(s, 1); + Being *q = checkCharacter(s, 1); const char *name = luaL_checkstring(s, 2); luaL_argcheck(s, name[0] != 0, 2, "empty variable name"); @@ -2096,7 +2106,7 @@ static int get_character_by_name(lua_State *s) { const char *name = luaL_checkstring(s, 1); - Character *ch = gameHandler->getCharacterByNameSlow(name); + Being *ch = gameHandler->getCharacterByNameSlow(name); if (!ch) lua_pushnil(s); else @@ -2112,7 +2122,7 @@ static int get_character_by_name(lua_State *s) */ static int chr_get_post(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); Script *script = getScript(s); Script::Thread *thread = checkCurrentThread(s, script); @@ -2151,7 +2161,7 @@ static int being_register(lua_State *s) */ static int chr_shake_screen(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const int x = luaL_checkint(s, 2); const int y = luaL_checkint(s, 3); @@ -2164,7 +2174,7 @@ static int chr_shake_screen(lua_State *s) if (lua_isnumber(s, 5)) msg.writeInt16(lua_tointeger(s, 5)); - c->getClient()->send(msg); + c->getComponent()->getClient()->send(msg); return 0; } @@ -2177,12 +2187,12 @@ static int chr_shake_screen(lua_State *s) */ static int chr_create_text_particle(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const char *text = luaL_checkstring(s, 2); MessageOut msg(GPMSG_CREATE_TEXT_PARTICLE); msg.writeString(text); - c->getClient()->send(msg); + c->getComponent()->getClient()->send(msg); return 0; } @@ -2195,11 +2205,11 @@ static int chr_create_text_particle(lua_State *s) static int chr_give_special(lua_State *s) { // cost_type is ignored until we have more than one cost type - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const int special = checkSpecial(s, 2); const int currentMana = luaL_optint(s, 3, 0); - c->giveSpecial(special, currentMana); + c->getComponent()->giveSpecial(special, currentMana); return 0; } @@ -2210,10 +2220,11 @@ static int chr_give_special(lua_State *s) */ static int chr_has_special(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const int special = luaL_checkint(s, 2); - lua_pushboolean(s, c->hasSpecial(special)); + lua_pushboolean(s, c->getComponent()->hasSpecial( + special)); return 1; } @@ -2227,11 +2238,12 @@ static int chr_has_special(lua_State *s) */ static int chr_take_special(lua_State *s) { - Character *c = checkCharacter(s, 1); + Being *c = checkCharacter(s, 1); const int special = luaL_checkint(s, 2); - lua_pushboolean(s, c->hasSpecial(special)); - c->takeSpecial(special); + lua_pushboolean(s, c->getComponent()->hasSpecial( + special)); + c->getComponent()->takeSpecial(special); return 1; } diff --git a/src/scripting/luascript.cpp b/src/scripting/luascript.cpp index e9f4492d..328ae8ce 100644 --- a/src/scripting/luascript.cpp +++ b/src/scripting/luascript.cpp @@ -275,35 +275,37 @@ void LuaScript::processRemoveEvent(Entity *entity) /** * Called when the server has recovered the value of a quest variable. */ -void LuaScript::getQuestCallback(Character *q, +void LuaScript::getQuestCallback(Being *q, const std::string &value, Script *script) { - Script::Thread *thread = q->getNpcThread(); + auto *characterComponent = q->getComponent(); + Script::Thread *thread = characterComponent->getNpcThread(); if (!thread || thread->mState != Script::ThreadExpectingString) return; script->prepareResume(thread); script->push(value); - q->resumeNpcThread(); + characterComponent->resumeNpcThread(); } /** * Called when the server has recovered the post for a user. */ -void LuaScript::getPostCallback(Character *q, +void LuaScript::getPostCallback(Being *q, const std::string &sender, const std::string &letter, Script *script) { - Script::Thread *thread = q->getNpcThread(); + auto *characterComponent = q->getComponent(); + Script::Thread *thread = characterComponent->getNpcThread(); if (!thread || thread->mState != Script::ThreadExpectingTwoStrings) return; script->prepareResume(thread); script->push(sender); script->push(letter); - q->resumeNpcThread(); + characterComponent->resumeNpcThread(); } diff --git a/src/scripting/luascript.h b/src/scripting/luascript.h index 3bedbc28..b7bdde1e 100644 --- a/src/scripting/luascript.h +++ b/src/scripting/luascript.h @@ -28,7 +28,7 @@ extern "C" { #include "scripting/script.h" -class Character; +class CharacterComponent; /** * Implementation of the Script class for Lua. @@ -69,11 +69,11 @@ class LuaScript : public Script void unref(Ref &ref); - static void getQuestCallback(Character *, + static void getQuestCallback(Being *, const std::string &value, Script *); - static void getPostCallback(Character *, + static void getPostCallback(Being *, const std::string &sender, const std::string &letter, Script *); diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp index d082cbe7..f835be81 100644 --- a/src/scripting/luautil.cpp +++ b/src/scripting/luautil.cpp @@ -128,14 +128,14 @@ Being *getBeing(lua_State *s, int p) return static_cast(lua_touserdata(s, p)); } -Character *getCharacter(lua_State *s, int p) +Being *getCharacter(lua_State *s, int p) { if (!lua_islightuserdata(s, p)) return 0; Entity *t = static_cast(lua_touserdata(s, p)); if (t->getType() != OBJECT_CHARACTER) return 0; - return static_cast(t); + return static_cast(t); } ItemClass *getItemClass(lua_State *s, int p) @@ -206,9 +206,9 @@ Being *checkBeing(lua_State *s, int p) return being; } -Character *checkCharacter(lua_State *s, int p) +Being *checkCharacter(lua_State *s, int p) { - Character *character = getCharacter(s, p); + Being *character = getCharacter(s, p); luaL_argcheck(s, character, p, "character expected"); return character; } diff --git a/src/scripting/luautil.h b/src/scripting/luautil.h index e76a15a1..bf335d20 100644 --- a/src/scripting/luautil.h +++ b/src/scripting/luautil.h @@ -38,7 +38,7 @@ extern "C" { #include "game-server/specialmanager.h" class Being; -class Character; +class CharacterComponent; class Entity; class ItemClass; class MapComposite; @@ -166,14 +166,14 @@ typedef LuaUserData LuaSpecialInfo; Script * getScript(lua_State *s); Being * getBeing(lua_State *s, int p); -Character * getCharacter(lua_State *s, int p); +Being * getCharacter(lua_State *s, int p); ItemClass * getItemClass(lua_State *s, int p); Being * getMonster(lua_State *s, int p); MonsterClass * getMonsterClass(lua_State *s, int p); Being * getNpc(lua_State *s, int p); Being * checkBeing(lua_State *s, int p); -Character * checkCharacter(lua_State *s, int p); +Being * checkCharacter(lua_State *s, int p); ItemClass * checkItemClass(lua_State *s, int p); Being * checkMonster(lua_State *s, int p); MonsterClass * checkMonsterClass(lua_State *s, int p); diff --git a/src/serialize/characterdata.h b/src/serialize/characterdata.h index abcc6114..c25fb096 100644 --- a/src/serialize/characterdata.h +++ b/src/serialize/characterdata.h @@ -42,16 +42,14 @@ void serializeCharacterData(const T &data, MessageOut &msg) msg.writeInt16(data.getCharacterPoints()); msg.writeInt16(data.getCorrectionPoints()); - msg.writeInt16(data.mAttributes.size()); - AttributeMap::const_iterator attr_it, attr_it_end; - for (attr_it = data.mAttributes.begin(), - attr_it_end = data.mAttributes.end(); - attr_it != attr_it_end; - ++attr_it) + + const AttributeMap &attributes = data.getAttributes(); + msg.writeInt16(attributes.size()); + for (auto attributeIt : attributes) { - msg.writeInt16(attr_it->first); - msg.writeDouble(data.getAttrBase(attr_it)); - msg.writeDouble(data.getAttrMod(attr_it)); + msg.writeInt16(attributeIt.first); + msg.writeDouble(attributeIt.second.getBase()); + msg.writeDouble(attributeIt.second.getModifiedAttribute()); } // character skills @@ -66,11 +64,11 @@ void serializeCharacterData(const T &data, MessageOut &msg) // status effects currently affecting the character msg.writeInt16(data.getStatusEffectSize()); - std::map::const_iterator status_it; + std::map::const_iterator status_it; for (status_it = data.getStatusEffectBegin(); status_it != data.getStatusEffectEnd(); status_it++) { msg.writeInt16(status_it->first); - msg.writeInt16(status_it->second); + msg.writeInt16(status_it->second.time); } // location -- cgit v1.2.3-70-g09d2 From d7fa7ea64f6bb0bc0b097e4bf1ceb4bd9620d0da Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Wed, 10 Apr 2013 23:04:42 +0200 Subject: Converted Being into a Component I did not really care too much about staying consistent with the use of static_casts to Actors since they are only temporary anyway until Actor is a component too. --- src/common/permissionmanager.cpp | 6 +- src/common/permissionmanager.h | 8 +- src/game-server/accountconnection.cpp | 7 +- src/game-server/being.cpp | 245 +++++++++++++--------- src/game-server/being.h | 59 +++--- src/game-server/buysell.cpp | 26 ++- src/game-server/buysell.h | 6 +- src/game-server/character.cpp | 90 ++++---- src/game-server/character.h | 40 ++-- src/game-server/combatcomponent.cpp | 67 +++--- src/game-server/combatcomponent.h | 24 +-- src/game-server/commandhandler.cpp | 315 +++++++++++++++------------- src/game-server/commandhandler.h | 4 +- src/game-server/component.h | 1 + src/game-server/effect.cpp | 2 +- src/game-server/effect.h | 11 +- src/game-server/gamehandler.cpp | 101 +++++---- src/game-server/gamehandler.h | 17 +- src/game-server/inventory.cpp | 26 ++- src/game-server/inventory.h | 6 +- src/game-server/item.cpp | 27 ++- src/game-server/item.h | 24 +-- src/game-server/mapcomposite.cpp | 36 ++-- src/game-server/mapcomposite.h | 15 +- src/game-server/monster.cpp | 100 ++++----- src/game-server/monster.h | 18 +- src/game-server/monstercombatcomponent.cpp | 10 +- src/game-server/monstercombatcomponent.h | 6 +- src/game-server/npc.cpp | 12 +- src/game-server/npc.h | 8 +- src/game-server/postman.h | 27 +-- src/game-server/quest.cpp | 12 +- src/game-server/quest.h | 16 +- src/game-server/spawnareacomponent.cpp | 8 +- src/game-server/state.cpp | 86 +++++--- src/game-server/state.h | 5 +- src/game-server/statuseffect.cpp | 6 +- src/game-server/statuseffect.h | 4 +- src/game-server/trade.cpp | 39 ++-- src/game-server/trade.h | 16 +- src/game-server/triggerareacomponent.cpp | 2 +- src/scripting/lua.cpp | 317 ++++++++++++++++------------- src/scripting/luascript.cpp | 6 +- src/scripting/luascript.h | 6 +- src/scripting/luautil.cpp | 32 +-- src/scripting/luautil.h | 17 +- src/scripting/script.h | 3 +- src/scripting/scriptmanager.cpp | 2 +- src/scripting/scriptmanager.h | 2 +- 49 files changed, 1051 insertions(+), 872 deletions(-) (limited to 'src/game-server/commandhandler.cpp') diff --git a/src/common/permissionmanager.cpp b/src/common/permissionmanager.cpp index ee970bd9..c5c87f66 100644 --- a/src/common/permissionmanager.cpp +++ b/src/common/permissionmanager.cpp @@ -105,7 +105,7 @@ void PermissionManager::reload() } -PermissionManager::Result PermissionManager::checkPermission(const Being* character, std::string permission) +PermissionManager::Result PermissionManager::checkPermission(const Entity* character, std::string permission) { return checkPermission(character->getComponent() ->getAccountLevel(), permission); @@ -140,7 +140,7 @@ unsigned char PermissionManager::getMaskFromAlias(const std::string &alias) } } -std::list PermissionManager::getPermissionList(const Being* character) +std::list PermissionManager::getPermissionList(const Entity* character) { std::list result; std::map::iterator i; @@ -159,7 +159,7 @@ std::list PermissionManager::getPermissionList(const Being* charact return result; } -std::list PermissionManager::getClassList(const Being* character) +std::list PermissionManager::getClassList(const Entity* character) { std::list result; std::map::iterator i; diff --git a/src/common/permissionmanager.h b/src/common/permissionmanager.h index a78f581d..2189f89f 100644 --- a/src/common/permissionmanager.h +++ b/src/common/permissionmanager.h @@ -25,7 +25,7 @@ #include #include -class Being; +class Entity; namespace PermissionManager { @@ -48,7 +48,7 @@ namespace PermissionManager /** * Returns if the characters account has the given permission */ - Result checkPermission(const Being* character, std::string permission); + Result checkPermission(const Entity *character, std::string permission); Result checkPermission(unsigned char level, std::string permission); /** @@ -59,12 +59,12 @@ namespace PermissionManager /** * Gets a list of all permissions the character is having */ - std::list getPermissionList(const Being* character); + std::list getPermissionList(const Entity* character); /** * Gets a list of all permissions classes the character is having */ - std::list getClassList(const Being* character); + std::list getClassList(const Entity* character); } // namespace PermissionManager diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp index bdf44b4e..622fc1d6 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); - Being *character = new Being(OBJECT_CHARACTER); + Entity *character = new Actor(OBJECT_CHARACTER); + character->addComponent(new BeingComponent(*character)); character->addComponent(new CharacterComponent(*character, msg)); gameHandler->addPendingCharacter(token, character); } break; @@ -243,7 +244,7 @@ void AccountConnection::processMessage(MessageIn &msg) case CGMSG_POST_RESPONSE: { // get the character - Being *character = postMan->getCharacter(msg.readInt32()); + Entity *character = postMan->getCharacter(msg.readInt32()); // check character is still valid if (!character) @@ -261,7 +262,7 @@ void AccountConnection::processMessage(MessageIn &msg) case CGMSG_STORE_POST_RESPONSE: { // get character - Being *character = postMan->getCharacter(msg.readInt32()); + Entity *character = postMan->getCharacter(msg.readInt32()); // check character is valid if (!character) diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index b50a5fac..ad3fcfc7 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -38,11 +38,10 @@ #include "scripting/scriptmanager.h" -Script::Ref Being::mRecalculateDerivedAttributesCallback; -Script::Ref Being::mRecalculateBaseAttributeCallback; +Script::Ref BeingComponent::mRecalculateDerivedAttributesCallback; +Script::Ref BeingComponent::mRecalculateBaseAttributeCallback; -Being::Being(EntityType type): - Actor(type), +BeingComponent::BeingComponent(Entity &entity): mAction(STAND), mGender(GENDER_UNSPECIFIED), mDirection(DOWN), @@ -60,10 +59,12 @@ Being::Being(EntityType type): LOG_DEBUG("Attempting to create attribute '" << it1->first << "'."); mAttributes.insert(std::make_pair(it1->first, Attribute(*it1->second))); - } - signal_inserted.connect(sigc::mem_fun(this, &Being::inserted)); + clearDestination(entity); + + entity.signal_inserted.connect(sigc::mem_fun(this, + &BeingComponent::inserted)); // TODO: Way to define default base values? // Should this be handled by the virtual modifiedAttribute? @@ -78,17 +79,20 @@ Being::Being(EntityType type): #endif } -void Being::triggerEmote(int id) +void BeingComponent::triggerEmote(Entity &entity, int id) { + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + mEmoteId = id; if (id > -1) - raiseUpdateFlags(UPDATEFLAG_EMOTE); + actor.raiseUpdateFlags(UPDATEFLAG_EMOTE); } -void Being::heal() +void BeingComponent::heal(Entity &entity) { Attribute &hp = mAttributes.at(ATTR_HP); Attribute &maxHp = mAttributes.at(ATTR_MAX_HP); @@ -97,10 +101,10 @@ void Being::heal() // Reset all modifications present in hp. hp.clearMods(); - setAttribute(ATTR_HP, maxHp.getModifiedAttribute()); + setAttribute(entity, ATTR_HP, maxHp.getModifiedAttribute()); } -void Being::heal(int gain) +void BeingComponent::heal(Entity &entity, int gain) { Attribute &hp = mAttributes.at(ATTR_HP); Attribute &maxHp = mAttributes.at(ATTR_MAX_HP); @@ -108,44 +112,71 @@ void Being::heal(int gain) return; // Full hp, do nothing. // Cannot go over maximum hitpoints. - setAttribute(ATTR_HP, hp.getBase() + gain); + setAttribute(entity, ATTR_HP, hp.getBase() + gain); if (hp.getModifiedAttribute() > maxHp.getModifiedAttribute()) - setAttribute(ATTR_HP, maxHp.getModifiedAttribute()); + setAttribute(entity, ATTR_HP, maxHp.getModifiedAttribute()); } -void Being::died() +void BeingComponent::died(Entity &entity) { + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + if (mAction == DEAD) return; - LOG_DEBUG("Being " << getPublicID() << " died."); - setAction(DEAD); + LOG_DEBUG("Being " << actor.getPublicID() << " died."); + setAction(entity, DEAD); // dead beings stay where they are - clearDestination(); + clearDestination(entity); - signal_died.emit(this); + signal_died.emit(&entity); } -void Being::setDestination(const Point &dst) +void BeingComponent::setDestination(Entity &entity, const Point &dst) { + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + mDst = dst; - raiseUpdateFlags(UPDATEFLAG_NEW_DESTINATION); + actor.raiseUpdateFlags(UPDATEFLAG_NEW_DESTINATION); mPath.clear(); } -Path Being::findPath() +void BeingComponent::clearDestination(Entity &entity) { - Map *map = getMap()->getMap(); + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + + setDestination(entity, actor.getPosition()); +} + +void BeingComponent::setDirection(Entity &entity, BeingDirection direction) +{ + // Temponary until all dependencies are available as components + Actor &actor = static_cast(entity); + mDirection = direction; + actor.raiseUpdateFlags(UPDATEFLAG_DIRCHANGE); +} + +Path BeingComponent::findPath(Entity &entity) +{ + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + + Map *map = entity.getMap()->getMap(); int tileWidth = map->getTileWidth(); int tileHeight = map->getTileHeight(); - int startX = getPosition().x / tileWidth; - int startY = getPosition().y / tileHeight; + int startX = actor.getPosition().x / tileWidth; + int startY = actor.getPosition().y / tileHeight; int destX = mDst.x / tileWidth, destY = mDst.y / tileHeight; - return map->findPath(startX, startY, destX, destY, getWalkMask()); + return map->findPath(startX, startY, destX, destY, actor.getWalkMask()); } -void Being::updateDirection(const Point ¤tPos, const Point &destPos) +void BeingComponent::updateDirection(Entity &entity, + const Point ¤tPos, + const Point &destPos) { // We update the being direction on each tile to permit other beings // entering in range to always see the being with a direction value. @@ -161,18 +192,18 @@ void Being::updateDirection(const Point ¤tPos, const Point &destPos) if (currentPos.x == destPos.x) { if (currentPos.y > destPos.y) - setDirection(UP); + setDirection(entity, UP); else - setDirection(DOWN); + setDirection(entity, DOWN); return; } if (currentPos.y == destPos.y) { if (currentPos.x > destPos.x) - setDirection(LEFT); + setDirection(entity, LEFT); else - setDirection(RIGHT); + setDirection(entity, RIGHT); return; } @@ -186,9 +217,9 @@ void Being::updateDirection(const Point ¤tPos, const Point &destPos) // Compute tan of the angle if ((currentPos.y - destPos.y) / (destPos.x - currentPos.x) < 1) // The angle is less than 45°, we look to the right - setDirection(RIGHT); + setDirection(entity, RIGHT); else - setDirection(UP); + setDirection(entity, UP); return; } else // Down-right @@ -196,9 +227,9 @@ void Being::updateDirection(const Point ¤tPos, const Point &destPos) // Compute tan of the angle if ((destPos.y - currentPos.y) / (destPos.x - currentPos.x) < 1) // The angle is less than 45°, we look to the right - setDirection(RIGHT); + setDirection(entity, RIGHT); else - setDirection(DOWN); + setDirection(entity, DOWN); return; } } @@ -210,9 +241,9 @@ void Being::updateDirection(const Point ¤tPos, const Point &destPos) // Compute tan of the angle if ((currentPos.y - destPos.y) / (currentPos.x - destPos.x) < 1) // The angle is less than 45°, we look to the left - setDirection(LEFT); + setDirection(entity, LEFT); else - setDirection(UP); + setDirection(entity, UP); return; } else // Down-left @@ -220,16 +251,19 @@ void Being::updateDirection(const Point ¤tPos, const Point &destPos) // Compute tan of the angle if ((destPos.y - currentPos.y) / (currentPos.x - destPos.x) < 1) // The angle is less than 45°, we look to the left - setDirection(LEFT); + setDirection(entity, LEFT); else - setDirection(DOWN); + setDirection(entity, DOWN); return; } } } -void Being::move() +void BeingComponent::move(Entity &entity) { + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + // Immobile beings cannot move. if (!checkAttributeExists(ATTR_MOVE_SPEED_RAW) || !getModifiedAttribute(ATTR_MOVE_SPEED_RAW)) @@ -238,10 +272,10 @@ void Being::move() // 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 = getPosition(); + mOld = actor.getPosition(); // Ignore not moving beings - if (mAction == STAND && mDst == getPosition()) + if (mAction == STAND && mDst == actor.getPosition()) return; if (mMoveTime > WORLD_TICK_MS) @@ -251,22 +285,22 @@ void Being::move() return; } - Map *map = getMap()->getMap(); + Map *map = entity.getMap()->getMap(); int tileWidth = map->getTileWidth(); int tileHeight = map->getTileHeight(); - int tileSX = getPosition().x / tileWidth; - int tileSY = getPosition().y / tileHeight; + int tileSX = actor.getPosition().x / tileWidth; + int tileSY = actor.getPosition().y / tileHeight; int tileDX = mDst.x / tileWidth; int tileDY = mDst.y / tileHeight; if (tileSX == tileDX && tileSY == tileDY) { if (mAction == WALK) - setAction(STAND); + setAction(entity, STAND); // Moving while staying on the same tile is free // We only update the direction in that case. - updateDirection(getPosition(), mDst); - setPosition(mDst); + updateDirection(entity, actor.getPosition(), mDst); + actor.setPosition(mDst); mMoveTime = 0; return; } @@ -281,7 +315,8 @@ void Being::move() for (PathIterator pathIterator = mPath.begin(); pathIterator != mPath.end(); pathIterator++) { - if (!map->getWalk(pathIterator->x, pathIterator->y, getWalkMask())) + if (!map->getWalk(pathIterator->x, pathIterator->y, + actor.getWalkMask())) { mPath.clear(); break; @@ -292,20 +327,20 @@ void Being::move() { // No path exists: the walkability of cached path has changed, the // destination has changed, or a path was never set. - mPath = findPath(); + mPath = findPath(entity); } if (mPath.empty()) { if (mAction == WALK) - setAction(STAND); + setAction(entity, STAND); // no path was found mDst = mOld; mMoveTime = 0; return; } - setAction(WALK); + setAction(entity, WALK); Point prev(tileSX, tileSY); Point pos; @@ -330,15 +365,15 @@ void Being::move() pos.y = next.y * tileHeight + (tileHeight / 2); } while (mMoveTime < WORLD_TICK_MS); - setPosition(pos); + actor.setPosition(pos); mMoveTime = mMoveTime > WORLD_TICK_MS ? mMoveTime - WORLD_TICK_MS : 0; // Update the being direction also - updateDirection(mOld, pos); + updateDirection(entity, mOld, pos); } -int Being::directionToAngle(int direction) +int BeingComponent::directionToAngle(int direction) { switch (direction) { @@ -350,37 +385,42 @@ int Being::directionToAngle(int direction) } } -void Being::setAction(BeingAction action) +void BeingComponent::setAction(Entity &entity, BeingAction action) { + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + mAction = action; if (action != ATTACK && // The players are informed about these actions action != WALK) // by other messages { - raiseUpdateFlags(UPDATEFLAG_ACTIONCHANGE); + actor.raiseUpdateFlags(UPDATEFLAG_ACTIONCHANGE); } } -void Being::applyModifier(unsigned attr, double value, unsigned layer, - unsigned duration, unsigned id) +void BeingComponent::applyModifier(Entity &entity, unsigned attr, double value, + unsigned layer, unsigned duration, + unsigned id) { mAttributes.at(attr).add(duration, value, layer, id); - updateDerivedAttributes(attr); + updateDerivedAttributes(entity, attr); } -bool Being::removeModifier(unsigned attr, double value, unsigned layer, - unsigned id, bool fullcheck) +bool BeingComponent::removeModifier(Entity &entity, unsigned attr, + double value, unsigned layer, + unsigned id, bool fullcheck) { bool ret = mAttributes.at(attr).remove(value, layer, id, fullcheck); - updateDerivedAttributes(attr); + updateDerivedAttributes(entity, attr); return ret; } -void Being::setGender(BeingGender gender) +void BeingComponent::setGender(BeingGender gender) { mGender = gender; } -void Being::setAttribute(unsigned id, double value) +void BeingComponent::setAttribute(Entity &entity, unsigned id, double value) { AttributeMap::iterator ret = mAttributes.find(id); if (ret == mAttributes.end()) @@ -396,35 +436,35 @@ void Being::setAttribute(unsigned id, double value) else { ret->second.setBase(value); - updateDerivedAttributes(id); + updateDerivedAttributes(entity, id); } } -void Being::createAttribute(unsigned id, const AttributeManager::AttributeInfo +void BeingComponent::createAttribute(unsigned id, const AttributeManager::AttributeInfo &attributeInfo) { mAttributes.insert(std::pair (id,Attribute(attributeInfo))); } -const Attribute *Being::getAttribute(unsigned id) const +const Attribute *BeingComponent::getAttribute(unsigned id) const { AttributeMap::const_iterator ret = mAttributes.find(id); if (ret == mAttributes.end()) { - LOG_DEBUG("Being::getAttribute: Attribute " + LOG_DEBUG("BeingComponent::getAttribute: Attribute " << id << " not found! Returning 0."); return 0; } return &ret->second; } -double Being::getAttributeBase(unsigned id) const +double BeingComponent::getAttributeBase(unsigned id) const { AttributeMap::const_iterator ret = mAttributes.find(id); if (ret == mAttributes.end()) { - LOG_DEBUG("Being::getAttributeBase: Attribute " + LOG_DEBUG("BeingComponent::getAttributeBase: Attribute " << id << " not found! Returning 0."); return 0; } @@ -432,32 +472,32 @@ double Being::getAttributeBase(unsigned id) const } -double Being::getModifiedAttribute(unsigned id) const +double BeingComponent::getModifiedAttribute(unsigned id) const { AttributeMap::const_iterator ret = mAttributes.find(id); if (ret == mAttributes.end()) { - LOG_DEBUG("Being::getModifiedAttribute: Attribute " + LOG_DEBUG("BeingComponent::getModifiedAttribute: Attribute " << id << " not found! Returning 0."); return 0; } return ret->second.getModifiedAttribute(); } -void Being::setModAttribute(unsigned, double) +void BeingComponent::setModAttribute(unsigned, double) { // No-op to satisfy shared structure. // The game-server calculates this manually. return; } -void Being::recalculateBaseAttribute(unsigned attr) +void BeingComponent::recalculateBaseAttribute(Entity &entity, unsigned attr) { LOG_DEBUG("Being: Received update attribute recalculation request for " << attr << "."); if (!mAttributes.count(attr)) { - LOG_DEBUG("Being::recalculateBaseAttribute: " << attr << " not found!"); + LOG_DEBUG("BeingComponent::recalculateBaseAttribute: " << attr << " not found!"); return; } @@ -467,7 +507,7 @@ void Being::recalculateBaseAttribute(unsigned attr) double newBase = utils::tpsToRawSpeed( getModifiedAttribute(ATTR_MOVE_SPEED_TPS)); if (newBase != getAttributeBase(attr)) - setAttribute(attr, newBase); + setAttribute(entity, attr, newBase); return; } @@ -476,14 +516,17 @@ void Being::recalculateBaseAttribute(unsigned attr) Script *script = ScriptManager::currentState(); script->prepare(mRecalculateBaseAttributeCallback); - script->push(this); + script->push(&entity); script->push(attr); - script->execute(getMap()); + script->execute(entity.getMap()); } -void Being::updateDerivedAttributes(unsigned attr) +void BeingComponent::updateDerivedAttributes(Entity &entity, unsigned attr) { - signal_attribute_changed.emit(this, attr); + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + + signal_attribute_changed.emit(&entity, attr); LOG_DEBUG("Being: Updating derived attribute(s) of: " << attr); @@ -492,12 +535,12 @@ void Being::updateDerivedAttributes(unsigned attr) { case ATTR_MAX_HP: case ATTR_HP: - raiseUpdateFlags(UPDATEFLAG_HEALTHCHANGE); + actor.raiseUpdateFlags(UPDATEFLAG_HEALTHCHANGE); break; case ATTR_MOVE_SPEED_TPS: // Does not make a lot of sense to have in the scripts. // So handle it here: - recalculateBaseAttribute(ATTR_MOVE_SPEED_RAW); + recalculateBaseAttribute(entity, ATTR_MOVE_SPEED_RAW); break; } @@ -506,12 +549,12 @@ void Being::updateDerivedAttributes(unsigned attr) Script *script = ScriptManager::currentState(); script->prepare(mRecalculateDerivedAttributesCallback); - script->push(this); + script->push(&entity); script->push(attr); - script->execute(getMap()); + script->execute(entity.getMap()); } -void Being::applyStatusEffect(int id, int timer) +void BeingComponent::applyStatusEffect(int id, int timer) { if (mAction == DEAD) return; @@ -529,12 +572,12 @@ void Being::applyStatusEffect(int id, int timer) } } -void Being::removeStatusEffect(int id) +void BeingComponent::removeStatusEffect(int id) { setStatusEffectTime(id, 0); } -bool Being::hasStatusEffect(int id) const +bool BeingComponent::hasStatusEffect(int id) const { StatusEffects::const_iterator it = mStatus.begin(); while (it != mStatus.end()) @@ -546,21 +589,24 @@ bool Being::hasStatusEffect(int id) const return false; } -unsigned Being::getStatusEffectTime(int id) const +unsigned BeingComponent::getStatusEffectTime(int id) const { StatusEffects::const_iterator it = mStatus.find(id); if (it != mStatus.end()) return it->second.time; else return 0; } -void Being::setStatusEffectTime(int id, int time) +void BeingComponent::setStatusEffectTime(int id, int time) { StatusEffects::iterator it = mStatus.find(id); if (it != mStatus.end()) it->second.time = time; } -void Being::update() +void BeingComponent::update(Entity &entity) { + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + int oldHP = getModifiedAttribute(ATTR_HP); int newHP = oldHP; int maxHP = getModifiedAttribute(ATTR_MAX_HP); @@ -579,8 +625,8 @@ void Being::update() // Only update HP when it actually changed to avoid network noise if (newHP != oldHP) { - setAttribute(ATTR_HP, newHP); - raiseUpdateFlags(UPDATEFLAG_HEALTHCHANGE); + setAttribute(entity, ATTR_HP, newHP); + actor.raiseUpdateFlags(UPDATEFLAG_HEALTHCHANGE); } // Update lifetime of effects. @@ -589,7 +635,7 @@ void Being::update() ++it) { if (it->second.tick()) - updateDerivedAttributes(it->first); + updateDerivedAttributes(entity, it->first); } // Update and run status effects @@ -598,7 +644,7 @@ void Being::update() { it->second.time--; if (it->second.time > 0 && mAction != DEAD) - it->second.status->tick(this, it->second.time); + it->second.status->tick(entity, it->second.time); if (it->second.time <= 0 || mAction == DEAD) { @@ -614,15 +660,16 @@ void Being::update() // Check if being died if (getModifiedAttribute(ATTR_HP) <= 0 && mAction != DEAD) - died(); - - Actor::update(); + died(entity); } -void Being::inserted(Entity *) +void BeingComponent::inserted(Entity *entity) { + // Temporary until all depdencies are available as component + Actor *actor = static_cast(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 = getPosition(); + mOld = actor->getPosition(); } diff --git a/src/game-server/being.h b/src/game-server/being.h index de30ad60..dd9790db 100644 --- a/src/game-server/being.h +++ b/src/game-server/being.h @@ -32,7 +32,7 @@ #include "game-server/attack.h" #include "game-server/timeout.h" -class Being; +class BeingComponent; class MapComposite; class StatusEffect; @@ -50,29 +50,31 @@ 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 Being : public Actor +class BeingComponent : public Component, public sigc::trackable { public: + static const ComponentType type = CT_Being; + /** * Proxy constructor. */ - Being(EntityType type); + BeingComponent(Entity &entity); /** * Update being state. */ - virtual void update(); + virtual void update(Entity &entity); /** Restores all hit points of the being */ - void heal(); + void heal(Entity &entity); /** Restores a specific number of hit points of the being */ - void heal(int hp); + void heal(Entity &entity, int hp); /** * Changes status and calls all the "died" listeners. */ - virtual void died(); + virtual void died(Entity &entity); /** * Gets the destination coordinates of the being. @@ -83,14 +85,13 @@ class Being : public Actor /** * Sets the destination coordinates of the being. */ - void setDestination(const Point &dst); + void setDestination(Entity &entity, const Point &dst); /** * Sets the destination coordinates of the being to the current * position. */ - void clearDestination() - { setDestination(getPosition()); } + void clearDestination(Entity &entity); /** * Gets the old coordinates of the being. @@ -101,15 +102,14 @@ class Being : public Actor /** * Sets the facing direction of the being. */ - void setDirection(BeingDirection direction) - { mDirection = direction; raiseUpdateFlags(UPDATEFLAG_DIRCHANGE); } + void setDirection(Entity &entity, BeingDirection direction); BeingDirection getDirection() const { return mDirection; } /** * Sets the current action. */ - void setAction(BeingAction action); + void setAction(Entity &entity, BeingAction action); /** * Sets the current action. @@ -120,12 +120,12 @@ class Being : public Actor /** * Moves the being toward its destination. */ - void move(); + void move(Entity &entity); /** * Returns the path to the being's current destination. */ - virtual Path findPath(); + virtual Path findPath(Entity &); /** Gets the gender of the being (male or female). */ BeingGender getGender() const @@ -137,7 +137,7 @@ class Being : public Actor /** * Sets an attribute. */ - void setAttribute(unsigned id, double value); + void setAttribute(Entity &entity, unsigned id, double value); /** * Creates an Attribute that did not exist before @@ -188,11 +188,13 @@ class Being : public Actor * @param lvl If non-zero, indicates that a temporary modifier can be * dispelled prematuraly by a spell of given level. */ - void applyModifier(unsigned attr, double value, unsigned layer, - unsigned duration = 0, unsigned id = 0); + void applyModifier(Entity &entity, unsigned attr, double value, + unsigned layer, unsigned duration = 0, + unsigned id = 0); - bool removeModifier(unsigned attr, double value, unsigned layer, - unsigned id = 0, bool fullcheck = false); + bool removeModifier(Entity &entity, unsigned attr, double value, + unsigned layer, unsigned id = 0, + bool fullcheck = false); /** * Called when an attribute modifier is changed. @@ -200,14 +202,14 @@ class Being : public Actor * attributes if it has changed. * @returns Whether it was changed. */ - void recalculateBaseAttribute(unsigned); + void recalculateBaseAttribute(Entity &, unsigned); /** * Attribute has changed, recalculate base value of dependant * attributes (and handle other actions for the modified * attribute) */ - void updateDerivedAttributes(unsigned); + void updateDerivedAttributes(Entity &entity, unsigned); /** * Sets a statuseffect on this being @@ -256,13 +258,13 @@ class Being : public Actor static void setRecalculateBaseAttributeCallback(Script *script) { script->assignCallback(mRecalculateBaseAttributeCallback); } - sigc::signal signal_died; - sigc::signal signal_attribute_changed; + sigc::signal signal_died; + sigc::signal signal_attribute_changed; /** * Activate an emote flag on the being. */ - void triggerEmote(int id); + void triggerEmote(Entity &entity, int id); /** * Tells the last emote used. @@ -274,7 +276,8 @@ class Being : public Actor * Update the being direction when moving so avoid directions desyncs * with other clients. */ - void updateDirection(const Point ¤tPos, + void updateDirection(Entity &entity, + const Point ¤tPos, const Point &destPos); protected: @@ -290,8 +293,8 @@ class Being : public Actor BeingGender mGender; /**< Gender of the being. */ private: - Being(const Being &rhs); - Being &operator=(const Being &rhs); + BeingComponent(const BeingComponent &rhs); + BeingComponent &operator=(const BeingComponent &rhs); /** * Connected to signal_inserted to reset the old position. diff --git a/src/game-server/buysell.cpp b/src/game-server/buysell.cpp index e73e13c5..3ba29ef6 100644 --- a/src/game-server/buysell.cpp +++ b/src/game-server/buysell.cpp @@ -30,7 +30,7 @@ #include -BuySell::BuySell(Being *c, bool sell): +BuySell::BuySell(Actor *c, bool sell): mCurrencyId(ATTR_GP), mChar(c), mSell(sell) { c->getComponent()->setBuySell(this); @@ -156,22 +156,28 @@ void BuySell::perform(unsigned id, int amount) for (TradedItems::iterator i = mItems.begin(), i_end = mItems.end(); i != i_end; ++i) { - if (i->itemId != id) continue; - if (i->amount && i->amount <= amount) amount = i->amount; + auto *beingComponent = mChar->getComponent(); + + if (i->itemId != id) + continue; + if (i->amount && i->amount <= amount) + amount = i->amount; if (mSell) { amount -= inv.remove(id, amount); - mChar->setAttribute(mCurrencyId, - mChar->getAttributeBase(mCurrencyId) + - amount * i->cost); + const double currentMoney = + beingComponent->getAttributeBase(mCurrencyId); + beingComponent->setAttribute(*mChar, mCurrencyId, + currentMoney + amount * i->cost); } else { - amount = std::min(amount, ((int) mChar->getAttributeBase(mCurrencyId)) / i->cost); + const double currentMoney = + beingComponent->getAttributeBase(mCurrencyId); + amount = std::min(amount, ((int)currentMoney) / i->cost); amount -= inv.insert(id, amount); - mChar->setAttribute(mCurrencyId, - mChar->getAttributeBase(mCurrencyId) - - amount * i->cost); + beingComponent->setAttribute(*mChar, mCurrencyId, + currentMoney - amount * i->cost); } if (i->amount) { diff --git a/src/game-server/buysell.h b/src/game-server/buysell.h index 8450aff1..88904f4d 100644 --- a/src/game-server/buysell.h +++ b/src/game-server/buysell.h @@ -23,8 +23,8 @@ #include -class Being; class Actor; +class Entity; class BuySell { @@ -33,7 +33,7 @@ class BuySell /** * Sets up a trade between a character and an NPC. */ - BuySell(Being *, bool sell); + BuySell(Actor *, bool sell); /** * Cancels the trade. @@ -80,7 +80,7 @@ class BuySell /** The attribute ID of the currency to use. Hardcoded for now (FIXME) */ unsigned mCurrencyId; - Being *mChar; /**< Character involved. */ + Actor *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 63621491..8f35fef4 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -91,16 +91,19 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): mBaseEntity(&entity) { // Temporary until all dependencies are in a component - Being &being = static_cast(entity); + Actor &being = static_cast(entity); mCharacterData = new CharacterData(&being, this); + auto *beingComponent = entity.getComponent(); + const AttributeManager::AttributeScope &attributes = attributeManager->getAttributeScope(CharacterScope); LOG_DEBUG("Character creation: initialisation of " << attributes.size() << " attributes."); for (auto attributeScope : attributes) - being.createAttribute(attributeScope.first, *attributeScope.second); + beingComponent->createAttribute(attributeScope.first, + *attributeScope.second); being.setWalkMask(Map::BLOCKMASK_WALL); @@ -115,7 +118,7 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): sigc::mem_fun(this, &CharacterComponent::attackRemoved)); // Default knuckle attack - int damageBase = being.getModifiedAttribute(ATTR_STR); + int damageBase = beingComponent->getModifiedAttribute(ATTR_STR); int damageDelta = damageBase / 2; Damage knuckleDamage; knuckleDamage.skill = skillManager->getDefaultSkillId(); @@ -131,7 +134,7 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): // Get character data. mDatabaseID = msg.readInt32(); - being.setName(msg.readString()); + beingComponent->setName(msg.readString()); deserializeCharacterData(*mCharacterData, msg); @@ -139,7 +142,7 @@ CharacterComponent::CharacterComponent(Entity &entity, MessageIn &msg): modifiedAllAttributes(entity); being.setSize(16); - being.signal_attribute_changed.connect(sigc::mem_fun( + beingComponent->signal_attribute_changed.connect(sigc::mem_fun( this, &CharacterComponent::attributeChanged)); } @@ -151,9 +154,6 @@ CharacterComponent::~CharacterComponent() void CharacterComponent::update(Entity &entity) { - // Temporary until all dependencies are available as component - Being &being = static_cast(entity); - // Update character level if needed. if (mRecalculateLevel) { @@ -162,7 +162,7 @@ void CharacterComponent::update(Entity &entity) } // Dead character: don't regenerate anything else - if (being.getAction() == DEAD) + if (entity.getComponent()->getAction() == DEAD) return; // Update special recharge @@ -192,25 +192,24 @@ void CharacterComponent::update(Entity &entity) } } -void CharacterComponent::characterDied(Being *being) +void CharacterComponent::characterDied(Entity *being) { executeCallback(mDeathCallback, *being); } void CharacterComponent::respawn(Entity &entity) { - // Temporary until all dependencies are available as component - Being &being = static_cast(entity); + auto *beingComponent = entity.getComponent(); - if (being.getAction() != DEAD) + if (beingComponent->getAction() != DEAD) { - LOG_WARN("Character \"" << being.getName() + LOG_WARN("Character \"" << beingComponent->getName() << "\" tried to respawn without being dead"); return; } // Make it alive again - being.setAction(STAND); + beingComponent->setAction(entity, STAND); // Reset target entity.getComponent()->clearTarget(); @@ -219,13 +218,14 @@ void CharacterComponent::respawn(Entity &entity) return; // No script respawn callback set - fall back to hardcoded logic - being.setAttribute(ATTR_HP, being.getModifiedAttribute(ATTR_MAX_HP)); + const double maxHp = beingComponent->getModifiedAttribute(ATTR_MAX_HP); + beingComponent->setAttribute(entity, ATTR_HP, maxHp); // Warp back to spawn point. int spawnMap = Configuration::getValue("char_respawnMap", 1); int spawnX = Configuration::getValue("char_respawnX", 1024); int spawnY = Configuration::getValue("char_respawnY", 1024); - GameState::enqueueWarp(&being, MapManager::getMap(spawnMap), + GameState::enqueueWarp(&entity, MapManager::getMap(spawnMap), Point(spawnX, spawnY)); } @@ -259,7 +259,7 @@ bool CharacterComponent::specialUseCheck(SpecialMap::iterator it) return true; } -void CharacterComponent::useSpecialOnBeing(Entity &user, int id, Being *b) +void CharacterComponent::useSpecialOnBeing(Entity &user, int id, Entity *b) { SpecialMap::iterator it = mSpecials.find(id); if (!specialUseCheck(it)) @@ -419,17 +419,15 @@ void CharacterComponent::setBuySell(BuySell *t) void CharacterComponent::sendStatus(Entity &entity) { - // Temporary until all dependencies are available as components - Being &being = static_cast(entity); - + auto *beingComponent = entity.getComponent(); MessageOut attribMsg(GPMSG_PLAYER_ATTRIBUTE_CHANGE); for (std::set::const_iterator i = mModifiedAttributes.begin(), i_end = mModifiedAttributes.end(); i != i_end; ++i) { int attr = *i; attribMsg.writeInt16(attr); - attribMsg.writeInt32(being.getAttributeBase(attr) * 256); - attribMsg.writeInt32(being.getModifiedAttribute(attr) * 256); + attribMsg.writeInt32(beingComponent->getAttributeBase(attr) * 256); + attribMsg.writeInt32(beingComponent->getModifiedAttribute(attr) * 256); } if (attribMsg.getLength() > 2) gameHandler->sendTo(mClient, attribMsg); mModifiedAttributes.clear(); @@ -458,23 +456,24 @@ void CharacterComponent::sendStatus(Entity &entity) void CharacterComponent::modifiedAllAttributes(Entity &entity) { - // Temporary until all dependencies are available as components - Being &being = static_cast(entity); + auto *beingComponent = entity.getComponent(); LOG_DEBUG("Marking all attributes as changed, requiring recalculation."); - for (auto attribute : being.getAttributes()) + for (auto attribute : beingComponent->getAttributes()) { - being.recalculateBaseAttribute(attribute.first); + beingComponent->recalculateBaseAttribute(entity, attribute.first); mModifiedAttributes.insert(attribute.first); } } -void CharacterComponent::attributeChanged(Being *being, unsigned attr) +void CharacterComponent::attributeChanged(Entity *entity, unsigned attr) { + auto *beingComponent = entity->getComponent(); + // Inform the client of this attribute modification. accountHandler->updateAttributes(getDatabaseID(), attr, - being->getAttributeBase(attr), - being->getModifiedAttribute(attr)); + beingComponent->getAttributeBase(attr), + beingComponent->getModifiedAttribute(attr)); mModifiedAttributes.insert(attr); // Update the knuckle Attack if required @@ -482,7 +481,7 @@ void CharacterComponent::attributeChanged(Being *being, unsigned attr) { // TODO: dehardcode this Damage &knuckleDamage = mKnuckleAttackInfo->getDamage(); - knuckleDamage.base = being->getModifiedAttribute(ATTR_STR); + knuckleDamage.base = beingComponent->getModifiedAttribute(ATTR_STR); knuckleDamage.delta = knuckleDamage.base / 2; } } @@ -617,9 +616,6 @@ int CharacterComponent::getExpGot(size_t skill) const void CharacterComponent::levelup(Entity &entity) { - // Temporary until all dependencies are available as Component - Being &being = static_cast(entity); - mLevel++; mCharacterPoints += CHARPOINTS_PER_LEVELUP; @@ -632,14 +628,14 @@ void CharacterComponent::levelup(Entity &entity) levelupMsg.writeInt16(mCharacterPoints); levelupMsg.writeInt16(mCorrectionPoints); gameHandler->sendTo(mClient, levelupMsg); - LOG_INFO(being.getName() << " reached level " << mLevel); + LOG_INFO(entity.getComponent()->getName() + << " reached level " << mLevel); } AttribmodResponseCode CharacterComponent::useCharacterPoint(Entity &entity, size_t attribute) { - // Temporary until all dependencies are available as Component - Being &being = static_cast(entity); + auto *beingComponent = entity.getComponent(); if (!attributeManager->isAttributeDirectlyModifiable(attribute)) return ATTRIBMOD_INVALID_ATTRIBUTE; @@ -647,27 +643,30 @@ AttribmodResponseCode CharacterComponent::useCharacterPoint(Entity &entity, return ATTRIBMOD_NO_POINTS_LEFT; --mCharacterPoints; - being.setAttribute(attribute, being.getAttributeBase(attribute) + 1); - being.updateDerivedAttributes(attribute); + + const double base = beingComponent->getAttributeBase(attribute); + beingComponent->setAttribute(entity, attribute, base + 1); + beingComponent->updateDerivedAttributes(entity, attribute); return ATTRIBMOD_OK; } AttribmodResponseCode CharacterComponent::useCorrectionPoint(Entity &entity, size_t attribute) { - // Temporary until all dependencies are available as Component - Being &being = static_cast(entity); + auto *beingComponent = entity.getComponent(); if (!attributeManager->isAttributeDirectlyModifiable(attribute)) return ATTRIBMOD_INVALID_ATTRIBUTE; if (!mCorrectionPoints) return ATTRIBMOD_NO_POINTS_LEFT; - if (being.getAttributeBase(attribute) <= 1) + if (beingComponent->getAttributeBase(attribute) <= 1) return ATTRIBMOD_DENIED; --mCorrectionPoints; ++mCharacterPoints; - being.setAttribute(attribute, being.getAttributeBase(attribute) - 1); + + const double base = beingComponent->getAttributeBase(attribute); + beingComponent->setAttribute(entity, attribute, base - 1); return ATTRIBMOD_OK; } @@ -718,13 +717,10 @@ void CharacterComponent::attackRemoved(CombatComponent *combatComponent, void CharacterComponent::disconnected(Entity &entity) { - // Temporary until all dependencies are available as a Component - Being &being = static_cast(entity); - mConnected = false; // Make the dead characters respawn, even in case of disconnection. - if (being.getAction() == DEAD) + if (entity.getComponent()->getAction() == DEAD) respawn(entity); else GameState::remove(&entity); diff --git a/src/game-server/character.h b/src/game-server/character.h index 4b5089d6..74d08d30 100644 --- a/src/game-server/character.h +++ b/src/game-server/character.h @@ -69,7 +69,7 @@ typedef std::map SpecialMap; class CharacterData { public: - CharacterData(Being *being, CharacterComponent *characterComponent); + CharacterData(Actor *actor, CharacterComponent *characterComponent); void setGender(BeingGender); BeingGender getGender() const; @@ -123,7 +123,7 @@ public: Possessions &getPossessions() const; private: - Being *mBeing; + Actor *mActor; CharacterComponent *mCharacterComponent; }; @@ -154,7 +154,7 @@ class CharacterComponent : public Component /** * Executes the global die script */ - virtual void characterDied(Being *); + virtual void characterDied(Entity *); /** * makes the character respawn @@ -165,7 +165,7 @@ class CharacterComponent : public Component * makes the character perform a special action on a being * when it is allowed to do so */ - void useSpecialOnBeing(Entity &user, int id, Being *b); + void useSpecialOnBeing(Entity &user, int id, Entity *b); /** * makes the character perform a special action on a map point @@ -312,7 +312,7 @@ class CharacterComponent : public Component * @param being th being of which the attribute was changed * @param attributeId the changed id */ - void attributeChanged(Being *being, unsigned attributeId); + void attributeChanged(Entity *being, unsigned attributeId); /** * Calls all the "disconnected" listener. @@ -578,55 +578,55 @@ class CharacterComponent : public Component }; -inline CharacterData::CharacterData(Being *being, +inline CharacterData::CharacterData(Actor *actor, CharacterComponent *characterComponent): - mBeing(being), + mActor(actor), mCharacterComponent(characterComponent) {} inline void CharacterData::setGender(BeingGender gender) { - mBeing->setGender(gender); + mActor->getComponent()->setGender(gender); } inline BeingGender CharacterData::getGender() const { - return mBeing->getGender(); + return mActor->getComponent()->getGender(); } inline void CharacterData::setMapId(int id) { - mBeing->setMap(MapManager::getMap(id)); + mActor->setMap(MapManager::getMap(id)); } inline int CharacterData::getMapId() const { - return mBeing->getMap()->getID(); + return mActor->getMap()->getID(); } inline void CharacterData::setPosition(Point &point) { - mBeing->setPosition(point); + mActor->setPosition(point); } inline const Point &CharacterData::getPosition() const { - return mBeing->getPosition(); + return mActor->getPosition(); } inline void CharacterData::setAttribute(int id, int base) { - mBeing->setAttribute(id, base); + mActor->getComponent()->setAttribute(*mActor, id, base); } inline void CharacterData::setModAttribute(int id, int mod) { - mBeing->setModAttribute(id, mod); + mActor->getComponent()->setModAttribute(id, mod); } inline const AttributeMap &CharacterData::getAttributes() const { - return mBeing->getAttributes(); + return mActor->getComponent()->getAttributes(); } inline void CharacterData::setCharacterPoints(int characterPoints) @@ -711,22 +711,22 @@ inline const std::map::const_iterator CharacterData::getSkillEnd() con inline void CharacterData::applyStatusEffect(int status, int time) { - mBeing->applyStatusEffect(status, time); + mActor->getComponent()->applyStatusEffect(status, time); } inline int CharacterData::getStatusEffectSize() const { - return mBeing->getStatusEffects().size(); + return mActor->getComponent()->getStatusEffects().size(); } inline const std::map::const_iterator CharacterData::getStatusEffectBegin() const { - return mBeing->getStatusEffects().begin(); + return mActor->getComponent()->getStatusEffects().begin(); } inline const std::map::const_iterator CharacterData::getStatusEffectEnd() const { - return mBeing->getStatusEffects().end(); + return mActor->getComponent()->getStatusEffects().end(); } inline int CharacterData::getKillCountSize() const diff --git a/src/game-server/combatcomponent.cpp b/src/game-server/combatcomponent.cpp index d71f86a3..df2d034d 100644 --- a/src/game-server/combatcomponent.cpp +++ b/src/game-server/combatcomponent.cpp @@ -25,12 +25,12 @@ #include "utils/logger.h" -CombatComponent::CombatComponent(Being &being): - mTarget(0), - mCurrentAttack(0) +CombatComponent::CombatComponent(Entity &being): + mTarget(nullptr), + mCurrentAttack(nullptr) { - being.signal_died.connect(sigc::mem_fun(this, - &CombatComponent::diedOrRemoved)); + being.getComponent()->signal_died.connect(sigc::mem_fun( + this, &CombatComponent::diedOrRemoved)); being.signal_removed.connect(sigc::mem_fun(this, &CombatComponent::diedOrRemoved)); } @@ -44,10 +44,11 @@ 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 - Being &being = static_cast(entity); + Actor &actor = static_cast(entity); + auto *beingComponent = entity.getComponent(); - if (being.getAction() != ATTACK || !mTarget) + if (beingComponent->getAction() != ATTACK || !mTarget) return; std::vector attacksReady; @@ -55,7 +56,7 @@ void CombatComponent::update(Entity &entity) if (Attack *triggerableAttack = mAttacks.getTriggerableAttack()) { - processAttack(being, *triggerableAttack); + processAttack(entity, *triggerableAttack); mAttacks.markAttackAsTriggered(); } @@ -69,11 +70,11 @@ void CombatComponent::update(Entity &entity) it_end = attacksReady.end(); it != it_end; ++it) { // check if target is in range using the pythagorean theorem - int distx = being.getPosition().x - mTarget->getPosition().x; - int disty = being.getPosition().y - mTarget->getPosition().y; + int distx = actor.getPosition().x - mTarget->getPosition().x; + int disty = actor.getPosition().y - mTarget->getPosition().y; int distSquare = (distx * distx + disty * disty); AttackInfo *info = (*it)->getAttackInfo(); - int maxDist = info->getDamage().range + being.getSize(); + int maxDist = info->getDamage().range + actor.getSize(); if (distSquare <= maxDist * maxDist && (!highestPriorityAttack || @@ -87,9 +88,9 @@ void CombatComponent::update(Entity &entity) { mAttacks.startAttack(highestPriorityAttack); mCurrentAttack = highestPriorityAttack; - being.setDestination(being.getPosition()); + beingComponent->setDestination(entity, actor.getPosition()); // TODO: Turn into direction of enemy - being.raiseUpdateFlags(UPDATEFLAG_ATTACK); + actor.raiseUpdateFlags(UPDATEFLAG_ATTACK); } } @@ -98,8 +99,12 @@ void CombatComponent::update(Entity &entity) * stats, deducts the result from the hitpoints and adds the result to * the HitsTaken list. */ -int CombatComponent::damage(Being &target, Being *source, const Damage &damage) +int CombatComponent::damage(Entity &target, + Entity *source, + const Damage &damage) { + auto *beingComponent = target.getComponent(); + int HPloss = damage.base; if (damage.delta) HPloss += rand() * (damage.delta + 1) / RAND_MAX; @@ -108,8 +113,10 @@ int CombatComponent::damage(Being &target, Being *source, const Damage &damage) switch (damage.type) { case DAMAGE_PHYSICAL: - if (!damage.trueStrike && - rand()%((int) target.getModifiedAttribute(ATTR_DODGE) + 1) > + { + const double dodge = + beingComponent->getModifiedAttribute(ATTR_DODGE); + if (!damage.trueStrike && rand()%((int)dodge + 1) > rand()%(damage.cth + 1)) { HPloss = 0; @@ -118,18 +125,19 @@ int CombatComponent::damage(Being &target, Being *source, const Damage &damage) } else { - HPloss = HPloss * (1.0 - (0.0159375f * - target.getModifiedAttribute(ATTR_DEFENSE)) / - (1.0 + 0.017 * - target.getModifiedAttribute(ATTR_DEFENSE))) + - (rand()%((HPloss >> 4) + 1)); + const double defense = + beingComponent->getModifiedAttribute(ATTR_DEFENSE); + HPloss = HPloss * (1.0 - (0.0159375f * defense) / + (1.0 + 0.017 * defense)) + + (rand()%((HPloss / 16) + 1)); // TODO Process triggers for receiving damage here. // If there is an attacker included, also process triggers for the attacker (successful physical strike) } break; + } case DAMAGE_MAGICAL: #if 0 - target.getModifiedAttribute(BASE_ELEM_BEGIN + damage.element); + beingComponent.getModifiedAttribute(BASE_ELEM_BEGIN + damage.element); #else LOG_WARN("Attempt to use magical type damage! This has not been" "implemented yet and should not be used!"); @@ -146,12 +154,13 @@ int CombatComponent::damage(Being &target, Being *source, const Damage &damage) if (HPloss > 0) { mHitsTaken.push_back(HPloss); - const Attribute *HP = target.getAttribute(ATTR_HP); - LOG_DEBUG("Being " << target.getPublicID() << " suffered " << HPloss + const Attribute *HP = beingComponent->getAttribute(ATTR_HP); + LOG_DEBUG("Being " << static_cast(target).getPublicID() + << " suffered " << HPloss << " damage. HP: " << HP->getModifiedAttribute() << "/" - << target.getModifiedAttribute(ATTR_MAX_HP)); - target.setAttribute(ATTR_HP, HP->getBase() - HPloss); + << beingComponent->getModifiedAttribute(ATTR_MAX_HP)); + beingComponent->setAttribute(target, ATTR_HP, HP->getBase() - HPloss); // No HP regen after being hit if this is set. // TODO: Reenable this once the attributes are available as a component // A bit too fuzzy to implement at the moment @@ -170,7 +179,7 @@ int CombatComponent::damage(Being &target, Being *source, const Damage &damage) /** * Performs an attack */ -void CombatComponent::processAttack(Being &source, Attack &attack) +void CombatComponent::processAttack(Entity &source, Attack &attack) { performAttack(source, attack.getAttackInfo()->getDamage()); } @@ -194,12 +203,12 @@ void CombatComponent::removeAttack(AttackInfo *attackInfo) /** * Performs an attack. */ -int CombatComponent::performAttack(Being &source, const Damage &dmg) +int CombatComponent::performAttack(Entity &source, const Damage &dmg) { // check target legality if (!mTarget || mTarget == &source - || mTarget->getAction() == DEAD + || mTarget->getComponent()->getAction() == DEAD || !mTarget->canFight()) return -1; diff --git a/src/game-server/combatcomponent.h b/src/game-server/combatcomponent.h index 033b543d..393eb612 100644 --- a/src/game-server/combatcomponent.h +++ b/src/game-server/combatcomponent.h @@ -29,8 +29,8 @@ #include "game-server/attack.h" +class Entity; class Actor; -class Being; /** * Type definition for a list of hits @@ -42,7 +42,7 @@ class CombatComponent: public Component, public sigc::trackable public: static const ComponentType type = CT_Fighting; - CombatComponent(Being &being); + CombatComponent(Entity &being); virtual ~CombatComponent(); void update(Entity &entity); @@ -54,23 +54,23 @@ public: const Hits &getHitsTaken() const; void clearHitsTaken(); - int performAttack(Being &source, const Damage &dmg); - virtual int damage(Being &target, Being *source, const Damage &damage); + int performAttack(Entity &source, const Damage &dmg); + virtual int damage(Entity &target, Entity *source, const Damage &damage); int getAttackId() const; - Being *getTarget() const; - void setTarget(Being *target); + Actor *getTarget() const; + void setTarget(Actor *target); void clearTarget(); void diedOrRemoved(Entity *entity); - sigc::signal signal_damaged; + sigc::signal signal_damaged; protected: - virtual void processAttack(Being &source, Attack &attack); + virtual void processAttack(Entity &source, Attack &attack); - Being *mTarget; + Actor *mTarget; Attacks mAttacks; Attack *mCurrentAttack; // Last used attack Hits mHitsTaken; //List of punches taken since last update. @@ -111,7 +111,7 @@ inline int CombatComponent::getAttackId() const /** * Get Target */ -inline Being *CombatComponent::getTarget() const +inline Actor *CombatComponent::getTarget() const { return mTarget; } @@ -119,7 +119,7 @@ inline Being *CombatComponent::getTarget() const /** * Set Target */ -inline void CombatComponent::setTarget(Being *target) +inline void CombatComponent::setTarget(Actor *target) { mTarget = target; } @@ -129,7 +129,7 @@ inline void CombatComponent::setTarget(Being *target) */ inline void CombatComponent::clearTarget() { - mTarget = 0; + mTarget = nullptr; } /** diff --git a/src/game-server/commandhandler.cpp b/src/game-server/commandhandler.cpp index 63b960d3..8a8e1380 100644 --- a/src/game-server/commandhandler.cpp +++ b/src/game-server/commandhandler.cpp @@ -48,44 +48,44 @@ struct CmdRef const char *cmd; const char *usage; const char *help; - void (*func)(Being*, std::string&) ; + void (*func)(Entity*, std::string&) ; }; -static void handleHelp(Being*, std::string&); -static void handleReport(Being*, std::string&); -static void handleWhere(Being*, std::string&); -static void handleRights(Being*, std::string&); -static void handleWarp(Being*, std::string&); -static void handleCharWarp(Being*, std::string&); -static void handleGoto(Being*, std::string&); -static void handleRecall(Being*, std::string&); -static void handleBan(Being*, std::string&); -static void handleItem(Being*, std::string&); -static void handleDrop(Being*, std::string&); -static void handleMoney(Being*, std::string&); -static void handleSpawn(Being*, std::string&); -static void handleAttribute(Being*, std::string&); -static void handleReload(Being*, std::string&); -static void handlePermissions(Being*, std::string&); -static void handleGivePermission(Being*, std::string&); -static void handleTakePermission(Being*, std::string&); -static void handleAnnounce(Being*, std::string&); -static void handleHistory(Being*, std::string&); -static void handleMute(Being*, std::string&); -static void handleDie(Being*, std::string&); -static void handleKill(Being*, std::string&); -static void handleKick(Being*, std::string&); -static void handleLog(Being*, std::string&); -static void handleLogsay(Being*, std::string&); -static void handleKillMonsters(Being*, std::string&); -static void handleCraft(Being*, std::string&); -static void handleGetPos(Being*, std::string&); -static void handleSkills(Being*, std::string&); -static void handleEffect(Being*, std::string&); -static void handleGiveSpecial(Being*, std::string&); -static void handleTakeSpecial(Being*, std::string&); -static void handleRechargeSpecial(Being*, std::string&); -static void handleListSpecials(Being*, std::string&); +static void handleHelp(Entity*, std::string&); +static void handleReport(Entity*, std::string&); +static void handleWhere(Entity*, std::string&); +static void handleRights(Entity*, std::string&); +static void handleWarp(Entity*, std::string&); +static void handleCharWarp(Entity*, std::string&); +static void handleGoto(Entity*, std::string&); +static void handleRecall(Entity*, std::string&); +static void handleBan(Entity*, std::string&); +static void handleItem(Entity*, std::string&); +static void handleDrop(Entity*, std::string&); +static void handleMoney(Entity*, std::string&); +static void handleSpawn(Entity*, std::string&); +static void handleAttribute(Entity*, std::string&); +static void handleReload(Entity*, std::string&); +static void handlePermissions(Entity*, std::string&); +static void handleGivePermission(Entity*, std::string&); +static void handleTakePermission(Entity*, std::string&); +static void handleAnnounce(Entity*, std::string&); +static void handleHistory(Entity*, std::string&); +static void handleMute(Entity*, std::string&); +static void handleDie(Entity*, std::string&); +static void handleKill(Entity*, std::string&); +static void handleKick(Entity*, std::string&); +static void handleLog(Entity*, std::string&); +static void handleLogsay(Entity*, std::string&); +static void handleKillMonsters(Entity*, std::string&); +static void handleCraft(Entity*, std::string&); +static void handleGetPos(Entity*, std::string&); +static void handleSkills(Entity*, std::string&); +static void handleEffect(Entity*, std::string&); +static void handleGiveSpecial(Entity*, std::string&); +static void handleTakeSpecial(Entity*, std::string&); +static void handleRechargeSpecial(Entity*, std::string&); +static void handleListSpecials(Entity*, std::string&); static CmdRef const cmdRef[] = { @@ -171,9 +171,9 @@ static CmdRef const cmdRef[] = }; -static void say(const std::string &message, Being *player) +static void say(const std::string &message, Entity *player) { - GameState::sayTo(player, NULL, message); + GameState::sayTo(static_cast(player), nullptr, message); } /* @@ -193,7 +193,7 @@ static bool checkPermission(Character *player, unsigned permissions) * Returns the next argument, and remove it from the given string. */ -static std::string playerRights(Being *ch) +static std::string playerRights(Entity *ch) { std::stringstream str; str << (unsigned)ch->getComponent()->getAccountLevel(); @@ -263,7 +263,7 @@ static std::string getArgument(std::string &args) return argument; } -static void handleHelp(Being *player, std::string &args) +static void handleHelp(Entity *player, std::string &args) { if (args.empty()) { @@ -302,7 +302,7 @@ static void handleHelp(Being *player, std::string &args) } } -static void handleWarp(Being *player, std::string &args) +static void handleWarp(Entity *player, std::string &args) { int x, y; MapComposite *map; @@ -388,11 +388,11 @@ static void handleWarp(Being *player, std::string &args) ss.str()); } -static void handleCharWarp(Being *player, std::string &args) +static void handleCharWarp(Entity *player, std::string &args) { int x, y; MapComposite *map; - Being *other; + Entity *other; // get the arguments std::string character = getArgument(args); @@ -485,16 +485,16 @@ static void handleCharWarp(Being *player, std::string &args) // log transaction std::stringstream ss; - ss << "User warped " << other->getName() << " to " << map->getName() << - " (" << x << ", " << y << ")"; + ss << "User warped " << other->getComponent()->getName() + << " to " << map->getName() << " (" << x << ", " << y << ")"; int databaseId = player->getComponent()->getDatabaseID(); accountHandler->sendTransaction(databaseId, TRANS_CMD_WARP, ss.str()); } -static void handleItem(Being *player, std::string &args) +static void handleItem(Entity *player, std::string &args) { - Being *other; + Entity *other; ItemClass *ic; int value = 0; @@ -570,7 +570,7 @@ static void handleItem(Being *player, std::string &args) accountHandler->sendTransaction(databaseId, TRANS_CMD_ITEM, str.str()); } -static void handleDrop(Being *player, std::string &args) +static void handleDrop(Entity *player, std::string &args) { ItemClass *ic; int amount = 0; @@ -620,7 +620,7 @@ static void handleDrop(Being *player, std::string &args) } Entity *item = Item::create(player->getMap(), - player->getPosition(), + static_cast(player)->getPosition(), ic, amount); GameState::insertOrDelete(item); @@ -633,9 +633,9 @@ static void handleDrop(Being *player, std::string &args) accountHandler->sendTransaction(databaseId, TRANS_CMD_DROP, str.str()); } -static void handleMoney(Being *player, std::string &args) +static void handleMoney(Entity *player, std::string &args) { - Being *other; + Entity *other; int value; // get arguments @@ -676,8 +676,11 @@ static void handleMoney(Being *player, std::string &args) // change value into an integer value = utils::stringToInt(valuestr); + auto *beingComponent = other->getComponent(); + // change how much money the player has - other->setAttribute(ATTR_GP , other->getAttributeBase(ATTR_GP) + value); + const double previousMoney = beingComponent->getAttributeBase(ATTR_GP); + beingComponent->setAttribute(*player, ATTR_GP , previousMoney + value); // log transaction std::string msg = "User created " + valuestr + " money"; @@ -686,11 +689,11 @@ static void handleMoney(Being *player, std::string &args) accountHandler->sendTransaction(databaseId, TRANS_CMD_MONEY, msg); } -static void handleSpawn(Being *player, std::string &args) +static void handleSpawn(Entity *player, std::string &args) { MonsterClass *mc; MapComposite *map = player->getMap(); - const Point &pos = player->getPosition(); + const Point &pos = static_cast(player)->getPosition(); int value = 0; // get the arguments @@ -741,11 +744,11 @@ static void handleSpawn(Being *player, std::string &args) // create the monsters and put them on the map for (int i = 0; i < value; ++i) { - Being *monster = new Being(OBJECT_MONSTER); + Actor *monster = new Actor(OBJECT_MONSTER); + monster->setPosition(pos); + monster->addComponent(new BeingComponent(*monster)); monster->addComponent(new MonsterComponent(*monster, mc)); monster->setMap(map); - monster->setPosition(pos); - monster->clearDestination(); if (!GameState::insertOrDelete(monster)) { // The map is full. Break out. @@ -753,16 +756,17 @@ static void handleSpawn(Being *player, std::string &args) } // log transaction - std::string msg = "User created monster " + monster->getName(); + std::string msg = "User created monster " + + monster->getComponent()->getName(); int databaseId = player->getComponent()->getDatabaseID(); accountHandler->sendTransaction(databaseId, TRANS_CMD_SPAWN, msg); } } -static void handleGoto(Being *player, std::string &args) +static void handleGoto(Entity *player, std::string &args) { - Being *other; + Entity *other; // get the arguments std::string character = getArgument(args); @@ -785,20 +789,21 @@ static void handleGoto(Being *player, std::string &args) // move the player to where the other player is MapComposite *map = other->getMap(); - const Point &pos = other->getPosition(); + const Point &pos = static_cast(other)->getPosition(); GameState::warp(player, map, pos); // log transaction std::stringstream msg; - msg << "User warped own character to " << other->getName(); + msg << "User warped own character to " + << other->getComponent()->getName(); int databaseId = player->getComponent()->getDatabaseID(); accountHandler->sendTransaction(databaseId, TRANS_CMD_GOTO, msg.str()); } -static void handleRecall(Being *player, std::string &args) +static void handleRecall(Entity *player, std::string &args) { - Being *other; + Entity *other; // get the arguments std::string character = getArgument(args); @@ -821,20 +826,20 @@ static void handleRecall(Being *player, std::string &args) // move the other player to where the player is MapComposite *map = player->getMap(); - const Point &pos = player->getPosition(); + const Point &pos = static_cast(player)->getPosition(); GameState::warp(other, map, pos); } -static void handleReload(Being *, std::string &) +static void handleReload(Entity *, std::string &) { // reload the items and monsters itemManager->reload(); monsterManager->reload(); } -static void handleBan(Being *player, std::string &args) +static void handleBan(Entity *player, std::string &args) { - Being *other; + Entity *other; int length; int lengthMutiplier = 0; @@ -900,15 +905,16 @@ static void handleBan(Being *player, std::string &args) characterComponent->getClient()->disconnect(kickmsg); // feedback for command user - std::string msg = "You've banned " + other->getName() + " for " + utils::toString(length) + " minutes"; + std::string otherName = other->getComponent()->getName(); + std::string msg = "You've banned " + otherName + " for " + utils::toString(length) + " minutes"; say(msg.c_str(), player); // log transaction - msg = "User banned " + other->getName() + " for " + utils::toString(length) + " minutes"; + msg = "User banned " + otherName + " for " + utils::toString(length) + " minutes"; accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_CMD_BAN, msg); } -static void handlePermissions(Being *player, std::string &args) +static void handlePermissions(Entity *player, std::string &args) { std::string character = getArgument(args); if (character.empty()) @@ -918,20 +924,20 @@ static void handlePermissions(Being *player, std::string &args) return; } - Being *other = gameHandler->getCharacterByNameSlow(character); + Entity *other = gameHandler->getCharacterByNameSlow(character); if (!other) { say("Invalid character", player); return; } - say(other->getName() + " has the permissions: " + + say(other->getComponent()->getName() + " has the permissions: " + playerRights(other), player); } -static void handleGivePermission(Being *player, std::string &args) +static void handleGivePermission(Entity *player, std::string &args) { - Being *other; + Entity *other; // get the arguments std::string character = getArgument(args); @@ -974,7 +980,8 @@ static void handleGivePermission(Being *player, std::string &args) if (permission & characterComponent->getAccountLevel()) { - say(player->getName()+" already has the permission "+strPermission, player); + say(player->getComponent()->getName() + +" already has the permission "+strPermission, player); } else { @@ -984,19 +991,21 @@ static void handleGivePermission(Being *player, std::string &args) accountHandler->changeAccountLevel(other, permission); // log transaction - std::string msg = "User gave right " + strPermission + " to " + other->getName(); + std::string msg = "User gave right " + strPermission + " to " + + other->getComponent()->getName(); accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_CMD_SETGROUP, msg); - say("You gave " + other->getName() + + say("You gave " + other->getComponent()->getName() + " the rights of a " + strPermission, player); - say("Congratulations, " + player->getName() + + say("Congratulations, " + + player->getComponent()->getName() + " gave you the rights of a " + strPermission, other); } } -static void handleTakePermission(Being *player, std::string &args) +static void handleTakePermission(Entity *player, std::string &args) { - Being *other; + Entity *other; // get the arguments std::string character = getArgument(args); @@ -1039,7 +1048,8 @@ static void handleTakePermission(Being *player, std::string &args) if (!(permission & characterComponent->getAccountLevel())) { - say(player->getName()+" hasn't got the permission "+strPermission, player); + say(player->getComponent()->getName() + +" hasn't got the permission "+strPermission, player); } else { permission = characterComponent->getAccountLevel() - permission; // change the player's account level @@ -1047,17 +1057,19 @@ static void handleTakePermission(Being *player, std::string &args) accountHandler->changeAccountLevel(other, permission); // log transaction - std::string msg = "User took right " + strPermission + " from " + other->getName(); + std::string msg = "User took right " + strPermission + " from " + + other->getComponent()->getName(); accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_CMD_SETGROUP, msg); - say("Sorry, "+player->getName()+" revoked your rights of a "+strPermission, other); + say("Sorry, "+player->getComponent()->getName() + +" revoked your rights of a "+strPermission, other); } } -static void handleAttribute(Being *player, std::string &args) +static void handleAttribute(Entity *player, std::string &args) { - Being *other; + Entity *other; int attr, value; // get arguments @@ -1114,19 +1126,22 @@ static void handleAttribute(Being *player, std::string &args) return; } + auto *beingComponent = other->getComponent(); + // change the player's attribute - other->setAttribute(attr, value); + beingComponent->setAttribute(*other, attr, value); // log transaction std::stringstream msg; - msg << "User changed attribute " << attr << " of player " << other->getName() + msg << "User changed attribute " << attr << " of player " + << beingComponent->getName() << " to " << value; int databaseId = player->getComponent()->getDatabaseID(); accountHandler->sendTransaction(databaseId, TRANS_CMD_ATTRIBUTE, msg.str()); } -static void handleReport(Being *player, std::string &args) +static void handleReport(Entity *player, std::string &args) { std::string bugReport = getArgument(args); @@ -1140,7 +1155,7 @@ static void handleReport(Being *player, std::string &args) // TODO: Send the report to a developer or something } -static void handleAnnounce(Being *player, std::string &args) +static void handleAnnounce(Entity *player, std::string &args) { if (args.empty()) { @@ -1153,36 +1168,37 @@ static void handleAnnounce(Being *player, std::string &args) msg.writeString(args); msg.writeInt16(player->getComponent() ->getDatabaseID()); - msg.writeString(player->getName()); + msg.writeString(player->getComponent()->getName()); accountHandler->send(msg); } -static void handleWhere(Being *player, std::string &) +static void handleWhere(Entity *player, std::string &) { + Actor *actor = static_cast(player); std::stringstream str; str << "Your current location is map " << player->getMap()->getID() << " [" - << player->getPosition().x + << actor->getPosition().x << ":" - << player->getPosition().y + << actor->getPosition().y << "]"; say (str.str(), player); } -static void handleRights(Being *player, std::string &) +static void handleRights(Entity *player, std::string &) { say("Your rights level is: " + playerRights(player), player); } -static void handleHistory(Being *, std::string &) +static void handleHistory(Entity *, std::string &) { // TODO: Get args number of transactions and show them to the player } -static void handleMute(Being *player, std::string &args) +static void handleMute(Entity *player, std::string &args) { - Being *other; + Entity *other; int length; // Get arguments. @@ -1213,21 +1229,26 @@ static void handleMute(Being *player, std::string &args) // Mute the player. other->getComponent()->mute(length); + const std::string &playerName = + player->getComponent()->getName(); + const std::string &otherName = + other->getComponent()->getName(); + // Feedback. std::stringstream targetMsg; std::stringstream userMsg; if (length > 0) { - targetMsg << player->getName() << " muted you for " + targetMsg << playerName << " muted you for " << length << " seconds."; - userMsg << "You muted " << other->getName() + userMsg << "You muted " << otherName << " for " << length << " seconds."; } else { - targetMsg << player->getName() << " unmuted you."; - userMsg << "You unmuted " << other->getName() << "."; + targetMsg << playerName << " unmuted you."; + userMsg << "You unmuted " << otherName << "."; } say(targetMsg.str(), other); say(userMsg.str(), player); @@ -1236,24 +1257,24 @@ static void handleMute(Being *player, std::string &args) std::stringstream msg; if (length > 0) { - msg << "User muted " << other->getName() << " for " << length << " seconds."; + msg << "User muted " << otherName << " for " << length << " seconds."; } else { - msg << "User unmuted " << other->getName(); + msg << "User unmuted " << otherName; } int databaseId = player->getComponent()->getDatabaseID(); accountHandler->sendTransaction(databaseId, TRANS_CMD_MUTE, msg.str()); } -static void handleDie(Being *player, std::string &) +static void handleDie(Entity *player, std::string &) { - player->setAttribute(ATTR_HP, 0); + player->getComponent()->setAttribute(*player, ATTR_HP, 0); say("You've killed yourself.", player); } -static void handleKill(Being *player, std::string &args) +static void handleKill(Entity *player, std::string &args) { - Being *other; + Entity *other; // get arguments std::string character = getArgument(args); @@ -1267,27 +1288,30 @@ static void handleKill(Being *player, std::string &args) } // kill the player - other->setAttribute(ATTR_HP, 0); + other->getComponent()->setAttribute(*player, ATTR_HP, 0); // feedback std::stringstream targetMsg; std::stringstream userMsg; - targetMsg << "You were killed by server command from "<< player->getName() << "."; - userMsg << "You killed " << other->getName() << "."; + targetMsg << "You were killed by server command from " + << player->getComponent()->getName() << "."; + userMsg << "You killed " + << other->getComponent()->getName() << "."; say(targetMsg.str(), other); say(userMsg.str(), player); // log transaction std::stringstream logMsg; - logMsg << "User killed " << other->getName(); + logMsg << "User killed " + << other->getComponent()->getName(); int databaseId = player->getComponent()->getDatabaseID(); accountHandler->sendTransaction(databaseId, TRANS_CMD_KILL, logMsg.str()); } -static void handleKick(Being *player, std::string &args) +static void handleKick(Entity *player, std::string &args) { - Being *other; + Entity *other; // get arguments std::string character = getArgument(args); @@ -1302,7 +1326,8 @@ static void handleKick(Being *player, std::string &args) // send feedback std::stringstream userMsg; - userMsg << "You kicked " << other->getName() << "."; + userMsg << "You kicked " + << other->getComponent()->getName() << "."; say(userMsg.str(), player); @@ -1316,14 +1341,15 @@ static void handleKick(Being *player, std::string &args) // log transaction std::stringstream logMsg; - logMsg << "User kicked " << other->getName(); + logMsg << "User kicked " + << other->getComponent()->getName(); int databaseId = player->getComponent()->getDatabaseID(); accountHandler->sendTransaction(databaseId, TRANS_CMD_KICK, logMsg.str()); } -static void handleLog(Being *player, std::string &msg) +static void handleLog(Entity *player, std::string &msg) { if (msg.empty()) { @@ -1342,7 +1368,7 @@ static void handleLog(Being *player, std::string &msg) say("Message logged", player); } -static void handleLogsay(Being *player, std::string &msg) +static void handleLogsay(Entity *player, std::string &msg) { if (msg.empty()) { @@ -1351,7 +1377,7 @@ static void handleLogsay(Being *player, std::string &msg) return; } - GameState::sayAround(player, msg); + GameState::sayAround(static_cast(player), msg); // log transaction std::string logmsg = "[public] " + msg; @@ -1363,16 +1389,17 @@ static void handleLogsay(Being *player, std::string &msg) say("Message logged", player); } -static void handleKillMonsters(Being *player, std::string &) +static void handleKillMonsters(Entity *player, std::string &) { const MapComposite *map = player->getMap(); int count = 0; for (BeingIterator it(map->getWholeMapIterator()); it; ++it) { - if ((*it)->getType() == OBJECT_MONSTER && (*it)->getAction() != DEAD) + if ((*it)->getType() == OBJECT_MONSTER && + (*it)->getComponent()->getAction() != DEAD) { - (*it)->died(); + (*it)->getComponent()->died(**it); count++; } } @@ -1388,7 +1415,7 @@ static void handleKillMonsters(Being *player, std::string &) accountHandler->sendTransaction(databaseId, TRANS_CMD_KILLMONSTERS, msg); } -static void handleCraft(Being *player, std::string &args) +static void handleCraft(Entity *player, std::string &args) { std::stringstream errMsg; std::list recipe; @@ -1461,7 +1488,7 @@ static void handleCraft(Being *player, std::string &args) } } -static void handleGetPos(Being *player, std::string &args) +static void handleGetPos(Entity *player, std::string &args) { std::string character = getArgument(args); if (character.empty()) @@ -1470,14 +1497,14 @@ static void handleGetPos(Being *player, std::string &args) say("Usage: @getpos ", player); return; } - Being *other; + Entity *other; other = gameHandler->getCharacterByNameSlow(character); if (!other) { say("Invalid character, or player is offline.", player); return; } - const Point &pos = other->getPosition(); + const Point &pos = static_cast(other)->getPosition(); std::stringstream str; str << "The current location of " << character @@ -1491,7 +1518,7 @@ static void handleGetPos(Being *player, std::string &args) say(str.str(), player); } -static void handleSkills(Being *player, std::string &args) +static void handleSkills(Entity *player, std::string &args) { std::string character = getArgument(args); if (character.empty()) @@ -1500,7 +1527,7 @@ static void handleSkills(Being *player, std::string &args) say("Usage: @skills ", player); return; } - Being *other; + Entity *other; if (character == "#") other = player; else @@ -1515,7 +1542,8 @@ static void handleSkills(Being *player, std::string &args) auto *characterComponent = player->getComponent(); - say("List of skills of player '" + other->getName() + "':", player); + say("List of skills of player '" + + other->getComponent()->getName() + "':", player); std::map::const_iterator it = characterComponent->getSkillBegin(); std::map::const_iterator it_end = @@ -1536,7 +1564,7 @@ static void handleSkills(Being *player, std::string &args) } } -static void handleEffect(Being *player, std::string &args) +static void handleEffect(Entity *player, std::string &args) { std::vector arguments; for (std::string arg = getArgument(args); !arg.empty(); @@ -1548,18 +1576,18 @@ static void handleEffect(Being *player, std::string &args) if (arguments.size() == 1) { int id = utils::stringToInt(arguments[0]); - Effects::show(id, player); + Effects::show(id, static_cast(player)); } else if (arguments.size() == 2) { int id = utils::stringToInt(arguments[0]); - Being *p = gameHandler->getCharacterByNameSlow(arguments[1]); + Entity *p = gameHandler->getCharacterByNameSlow(arguments[1]); if (!p) { say("Invalid target player.", player); return; } - Effects::show(id, p); + Effects::show(id, static_cast(p)); } else if (arguments.size() == 3) { @@ -1576,7 +1604,7 @@ static void handleEffect(Being *player, std::string &args) } } -static void handleGiveSpecial(Being *player, std::string &args) +static void handleGiveSpecial(Entity *player, std::string &args) { std::string character = getArgument(args); std::string special = getArgument(args); @@ -1587,7 +1615,7 @@ static void handleGiveSpecial(Being *player, std::string &args) return; } - Being *other; + Entity *other; if (character == "#") other = player; else @@ -1613,7 +1641,7 @@ static void handleGiveSpecial(Being *player, std::string &args) } } -static void handleTakeSpecial(Being *player, std::string &args) +static void handleTakeSpecial(Entity *player, std::string &args) { std::string character = getArgument(args); std::string special = getArgument(args); @@ -1624,7 +1652,7 @@ static void handleTakeSpecial(Being *player, std::string &args) return; } - Being *other; + Entity *other; if (character == "#") other = player; else @@ -1654,7 +1682,7 @@ static void handleTakeSpecial(Being *player, std::string &args) } } -static void handleRechargeSpecial(Being *player, std::string &args) +static void handleRechargeSpecial(Entity *player, std::string &args) { std::string character = getArgument(args); std::string special = getArgument(args); @@ -1666,7 +1694,7 @@ static void handleRechargeSpecial(Being *player, std::string &args) return; } - Being *other; + Entity *other; if (character == "#") other = player; else @@ -1714,7 +1742,7 @@ static void handleRechargeSpecial(Being *player, std::string &args) } } -static void handleListSpecials(Being *player, std::string &args) +static void handleListSpecials(Entity *player, std::string &args) { std::string character = getArgument(args); if (character.empty()) @@ -1724,7 +1752,7 @@ static void handleListSpecials(Being *player, std::string &args) return; } - Being *other; + Entity *other; if (character == "#") other = player; else @@ -1739,7 +1767,8 @@ static void handleListSpecials(Being *player, std::string &args) auto *characterComponent = other->getComponent(); - say("Specials of character " + other->getName() + ":", player); + say("Specials of character " + + other->getComponent()->getName() + ":", player); for (SpecialMap::const_iterator it = characterComponent->getSpecialBegin(), it_end = characterComponent->getSpecialEnd(); it != it_end; ++it) { @@ -1751,7 +1780,7 @@ static void handleListSpecials(Being *player, std::string &args) } } -void CommandHandler::handleCommand(Being *player, +void CommandHandler::handleCommand(Entity *player, const std::string &command) { // get command type, and arguments diff --git a/src/game-server/commandhandler.h b/src/game-server/commandhandler.h index b5a268f5..c947a4dc 100644 --- a/src/game-server/commandhandler.h +++ b/src/game-server/commandhandler.h @@ -23,14 +23,14 @@ #include -class Being; +class Entity; namespace CommandHandler { /** * Parse and handle the given command. */ - void handleCommand(Being *player, const std::string &command); + void handleCommand(Entity *player, const std::string &command); } #endif //SERVER_COMMANDHANDLER_H diff --git a/src/game-server/component.h b/src/game-server/component.h index 45fe742e..c3f54839 100644 --- a/src/game-server/component.h +++ b/src/game-server/component.h @@ -26,6 +26,7 @@ class Entity; enum ComponentType { CT_Character, + CT_Being, CT_Effect, CT_Fighting, CT_Item, diff --git a/src/game-server/effect.cpp b/src/game-server/effect.cpp index f994ec77..b8e03dab 100644 --- a/src/game-server/effect.cpp +++ b/src/game-server/effect.cpp @@ -45,7 +45,7 @@ namespace Effects GameState::enqueueInsert(effect); } - void show(int id, Being *b) + void show(int id, Actor *b) { EffectComponent *effectComponent = new EffectComponent(id); effectComponent->setBeing(b); diff --git a/src/game-server/effect.h b/src/game-server/effect.h index 4ac63611..4c355d67 100644 --- a/src/game-server/effect.h +++ b/src/game-server/effect.h @@ -24,7 +24,8 @@ #include "game-server/component.h" -class Being; +class Actor; +class Entity; class MapComposite; class Point; @@ -42,7 +43,7 @@ class EffectComponent : public Component int getEffectId() const { return mEffectId; } - Being *getBeing() const + Entity *getBeing() const { return mBeing; } /** @@ -56,13 +57,13 @@ class EffectComponent : public Component void setShown() { mHasBeenShown = true; } - void setBeing(Being *b) + void setBeing(Entity *b) { mBeing = b; } private: int mEffectId; bool mHasBeenShown; - Being *mBeing; + Entity *mBeing; }; @@ -72,7 +73,7 @@ namespace Effects * Convenience methods to show an effect. */ void show(int id, MapComposite *map, const Point &pos); - void show(int id, Being *b); + void show(int id, Actor *b); // TODO: get this in sync with effects.xml enum { diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index 55588b61..b01c5002 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -153,7 +153,7 @@ static Actor *findActorNear(Actor *p, int id) return 0; } -static Being *findBeingNear(Actor *p, int id) +static Entity *findBeingNear(Actor *p, int id) { MapComposite *map = p->getMap(); const Point &ppos = p->getPosition(); @@ -161,7 +161,7 @@ static Being *findBeingNear(Actor *p, int id) const int pixelDist = DEFAULT_TILE_LENGTH * TILES_TO_BE_NEAR; for (BeingIterator i(map->getAroundPointIterator(ppos, pixelDist)); i; ++i) { - Being *b = *i; + Actor *b = static_cast(*i); if (b->getPublicID() != id) continue; return ppos.inRangeOf(b->getPosition(), pixelDist) ? b : 0; @@ -169,7 +169,7 @@ static Being *findBeingNear(Actor *p, int id) return 0; } -static Being *findCharacterNear(Actor *p, int id) +static Entity *findCharacterNear(Actor *p, int id) { MapComposite *map = p->getMap(); const Point &ppos = p->getPosition(); @@ -178,7 +178,7 @@ static Being *findCharacterNear(Actor *p, int id) for (CharacterIterator i(map->getAroundPointIterator(ppos, pixelDist)); i; ++i) { - Being *c = *i; + Actor *c = static_cast(*i); if (c->getPublicID() != id) continue; @@ -337,7 +337,7 @@ void GameHandler::sendTo(GameClient *client, MessageOut &msg) client->send(msg); } -void GameHandler::addPendingCharacter(const std::string &token, Being *ch) +void GameHandler::addPendingCharacter(const std::string &token, Entity *ch) { /* First, check if the character is already on the map. This may happen if a client just lost its connection, and logged to the account server @@ -348,7 +348,7 @@ void GameHandler::addPendingCharacter(const std::string &token, Being *ch) i_end = clients.end(); i != i_end; ++i) { GameClient *c = static_cast< GameClient * >(*i); - Being *old_ch = c->character; + Entity *old_ch = c->character; const int oldId = old_ch->getComponent() ->getDatabaseID(); if (old_ch && oldId == id) @@ -377,7 +377,7 @@ void GameHandler::addPendingCharacter(const std::string &token, Being *ch) mTokenCollector.addPendingConnect(token, ch); } -void GameHandler::tokenMatched(GameClient *computer, Being *character) +void GameHandler::tokenMatched(GameClient *computer, Entity *character) { computer->character = character; computer->status = CLIENT_CONNECTED; @@ -421,19 +421,19 @@ void GameHandler::deletePendingClient(GameClient *computer) computer->disconnect(msg); } -void GameHandler::deletePendingConnect(Being *character) +void GameHandler::deletePendingConnect(Entity *character) { delete character; } -Being *GameHandler::getCharacterByNameSlow(const std::string &name) const +Entity *GameHandler::getCharacterByNameSlow(const std::string &name) const { for (NetComputers::const_iterator i = clients.begin(), i_end = clients.end(); i != i_end; ++i) { GameClient *c = static_cast< GameClient * >(*i); - Being *ch = c->character; - if (ch && ch->getName() == name && + Entity *ch = c->character; + if (ch && ch->getComponent()->getName() == name && c->status == CLIENT_CONNECTED) { return ch; @@ -455,11 +455,11 @@ void GameHandler::handleSay(GameClient &client, MessageIn &message) } if (!client.character->getComponent()->isMuted()) { - GameState::sayAround(client.character, say); + GameState::sayAround(static_cast(client.character), say); } else { - GameState::sayTo(client.character, NULL, + GameState::sayTo(static_cast(client.character), nullptr, "You are not allowed to talk right now."); } } @@ -467,15 +467,12 @@ void GameHandler::handleSay(GameClient &client, MessageIn &message) void GameHandler::handleNpc(GameClient &client, MessageIn &message) { int id = message.readInt16(); - Actor *actor = findActorNear(client.character, id); + Actor *actor = findActorNear(static_cast(client.character), id); if (!actor || actor->getType() != OBJECT_NPC) { sendNpcError(client, id, "Not close enough to NPC\n"); return; } - - Being *npc = static_cast(actor); - switch (message.getId()) { case PGMSG_NPC_SELECT: @@ -488,7 +485,7 @@ void GameHandler::handleNpc(GameClient &client, MessageIn &message) Npc::stringReceived(client.character, message.readString()); break; case PGMSG_NPC_TALK: - Npc::start(npc, client.character); + Npc::start(actor, client.character); break; case PGMSG_NPC_TALK_NEXT: default: @@ -501,7 +498,7 @@ void GameHandler::handlePickup(GameClient &client, MessageIn &message) { const int x = message.readInt16(); const int y = message.readInt16(); - const Point ppos = client.character->getPosition(); + const Point ppos = static_cast(client.character)->getPosition(); // TODO: use a less arbitrary value. if (std::abs(x - ppos.x) + std::abs(y - ppos.y) < 48) @@ -510,8 +507,8 @@ void GameHandler::handlePickup(GameClient &client, MessageIn &message) Point ipos(x, y); for (FixedActorIterator i(map->getAroundPointIterator(ipos, 0)); i; ++i) { - Actor *o = *i; - Point opos = o->getPosition(); + Entity *o = *i; + Point opos = static_cast(o)->getPosition(); if (o->getType() == OBJECT_ITEM && opos.x == x && opos.y == y) { @@ -553,7 +550,7 @@ void GameHandler::handlePickup(GameClient &client, MessageIn &message) void GameHandler::handleUseItem(GameClient &client, MessageIn &message) { - if (client.character->getAction() == DEAD) + if (client.character->getComponent()->getAction() == DEAD) return; const int slot = message.readInt16(); @@ -587,7 +584,7 @@ void GameHandler::handleDrop(GameClient &client, MessageIn &message) { int nb = inv.removeFromSlot(slot, amount); MapComposite *map = client.character->getMap(); - Point pos = client.character->getPosition(); + Point pos = static_cast(client.character)->getPosition(); Entity *item = Item::create(map, pos, ic, amount - nb); @@ -625,7 +622,8 @@ void GameHandler::handleWalk(GameClient &client, MessageIn &message) const int y = message.readInt16(); Point dst(x, y); - client.character->setDestination(dst); + client.character->getComponent()->setDestination( + *client.character, dst); } void GameHandler::handleEquip(GameClient &client, MessageIn &message) @@ -672,28 +670,32 @@ void GameHandler::handleMoveItem(GameClient &client, MessageIn &message) void GameHandler::handleAttack(GameClient &client, MessageIn &message) { int id = message.readInt16(); - LOG_DEBUG("Character " << client.character->getPublicID() + Actor *actor = static_cast(client.character); + LOG_DEBUG("Character " << actor->getPublicID() << " attacked being " << id); - Being *being = findBeingNear(client.character, id); + Actor *being = static_cast(findBeingNear(actor, id)); if (being && being->getType() != OBJECT_NPC) { client.character->getComponent()->setTarget(being); - client.character->setAction(ATTACK); + client.character->getComponent()->setAction(*actor, + ATTACK); } } void GameHandler::handleUseSpecialOnBeing(GameClient &client, MessageIn &message) { - if (client.character->getAction() == DEAD) + if (client.character->getComponent()->getAction() == DEAD) return; + Actor *actor = static_cast(client.character); + const int specialID = message.readInt8(); const int targetID = message.readInt16(); // 0 when no target is selected - Being *being = 0; + Entity *being = 0; if (targetID != 0) - being = findBeingNear(client.character, targetID); - LOG_DEBUG("Character " << client.character->getPublicID() + being = findBeingNear(actor, targetID); + LOG_DEBUG("Character " << actor->getPublicID() << " tries to use his special attack " << specialID); auto *characterComponent = client.character ->getComponent(); @@ -702,14 +704,15 @@ void GameHandler::handleUseSpecialOnBeing(GameClient &client, MessageIn &message void GameHandler::handleUseSpecialOnPoint(GameClient &client, MessageIn &message) { - if (client.character->getAction() == DEAD) + if (client.character->getComponent()->getAction() == DEAD) return; const int specialID = message.readInt8(); const int x = message.readInt16(); const int y = message.readInt16(); - LOG_DEBUG("Character " << client.character->getPublicID() + LOG_DEBUG("Character " + << static_cast(client.character)->getPublicID() << " tries to use his special attack " << specialID); auto *characterComponent = client.character ->getComponent(); @@ -718,8 +721,10 @@ void GameHandler::handleUseSpecialOnPoint(GameClient &client, MessageIn &message void GameHandler::handleActionChange(GameClient &client, MessageIn &message) { + auto *beingComponent = client.character->getComponent(); + const BeingAction action = (BeingAction) message.readInt8(); - const BeingAction current = (BeingAction) client.character->getAction(); + const BeingAction current = (BeingAction) beingComponent->getAction(); bool logActionChange = true; switch (action) @@ -727,14 +732,14 @@ void GameHandler::handleActionChange(GameClient &client, MessageIn &message) case STAND: if (current == SIT) { - client.character->setAction(STAND); + beingComponent->setAction(*client.character, STAND); logActionChange = false; } break; case SIT: if (current == STAND) { - client.character->setAction(SIT); + beingComponent->setAction(*client.character, SIT); logActionChange = false; } break; @@ -761,7 +766,8 @@ void GameHandler::handleActionChange(GameClient &client, MessageIn &message) void GameHandler::handleDirectionChange(GameClient &client, MessageIn &message) { const BeingDirection direction = (BeingDirection) message.readInt8(); - client.character->setDirection(direction); + client.character->getComponent() + ->setDirection(*client.character, direction); } void GameHandler::handleDisconnect(GameClient &client, MessageIn &message) @@ -804,7 +810,7 @@ void GameHandler::handleTradeRequest(GameClient &client, MessageIn &message) if (t->request(client.character, id)) return; - Being *q = findCharacterNear(client.character, id); + Entity *q = findCharacterNear(static_cast(client.character), id); if (!q || characterComponent->isBusy()) { client.send(MessageOut(GPMSG_TRADE_CANCEL)); @@ -815,7 +821,8 @@ void GameHandler::handleTradeRequest(GameClient &client, MessageIn &message) // log transaction std::string str; - str = "User requested trade with " + q->getName(); + str = "User requested trade with " + q->getComponent() + ->getName(); accountHandler->sendTransaction(characterComponent->getDatabaseID(), TRANS_TRADE_REQUEST, str); } @@ -952,16 +959,18 @@ void GameHandler::handlePartyInvite(GameClient &client, MessageIn &message) const int visualRange = Configuration::getValue("game_visualRange", 448); std::string invitee = message.readString(); - if (invitee == client.character->getName()) + if (invitee == client.character->getComponent()->getName()) return; for (CharacterIterator it(map->getWholeMapIterator()); it; ++it) { - if ((*it)->getName() == invitee) + if ((*it)->getComponent()->getName() == invitee) { // calculate if the invitee is within the visual range - const int xInviter = client.character->getPosition().x; - const int yInviter = client.character->getPosition().y; + const int xInviter = + static_cast(client.character)->getPosition().x; + const int yInviter = + static_cast(client.character)->getPosition().y; const int xInvitee = (*it)->getPosition().x; const int yInvitee = (*it)->getPosition().y; const int dx = std::abs(xInviter - xInvitee); @@ -969,7 +978,8 @@ void GameHandler::handlePartyInvite(GameClient &client, MessageIn &message) if (visualRange > std::max(dx, dy)) { MessageOut out(GCMSG_PARTY_INVITE); - out.writeString(client.character->getName()); + out.writeString(client.character + ->getComponent()->getName()); out.writeString(invitee); accountHandler->send(out); return; @@ -988,7 +998,8 @@ void GameHandler::handleTriggerEmoticon(GameClient &client, MessageIn &message) { const int id = message.readInt16(); if (emoteManager->isIdAvailable(id)) - client.character->triggerEmote(id); + client.character->getComponent()->triggerEmote( + *client.character, id); } void GameHandler::sendNpcError(GameClient &client, int id, diff --git a/src/game-server/gamehandler.h b/src/game-server/gamehandler.h index 70facb4c..d66caf52 100644 --- a/src/game-server/gamehandler.h +++ b/src/game-server/gamehandler.h @@ -21,11 +21,12 @@ #ifndef SERVER_GAMEHANDLER_H #define SERVER_GAMEHANDLER_H -#include "game-server/character.h" #include "net/connectionhandler.h" #include "net/netcomputer.h" #include "utils/tokencollector.h" +class Entity; + enum { CLIENT_LOGIN = 0, @@ -37,8 +38,8 @@ enum struct GameClient: NetComputer { GameClient(ENetPeer *peer) - : NetComputer(peer), character(NULL), status(CLIENT_LOGIN) {} - Being *character; + : NetComputer(peer), character(nullptr), status(CLIENT_LOGIN) {} + Entity *character; int status; }; @@ -86,13 +87,13 @@ class GameHandler: public ConnectionHandler * Registers a character that should soon be claimed by a client. * @param token token used by the client when connecting. */ - void addPendingCharacter(const std::string &token, Being *); + void addPendingCharacter(const std::string &token, Entity *); /** * Combines a client with its character. * (Needed for TokenCollector) */ - void tokenMatched(GameClient *computer, Being *character); + void tokenMatched(GameClient *computer, Entity *character); /** * Deletes a pending client's data. @@ -104,13 +105,13 @@ class GameHandler: public ConnectionHandler * Deletes a pending connection's data. * (Needed for TokenCollector) */ - void deletePendingConnect(Being *character); + void deletePendingConnect(Entity *character); /** * Gets the character associated to a character name. This method is * slow, so it should never be called for regular operations. */ - Being *getCharacterByNameSlow(const std::string &) const; + Entity *getCharacterByNameSlow(const std::string &) const; protected: NetComputer *computerConnected(ENetPeer *); @@ -161,7 +162,7 @@ class GameHandler: public ConnectionHandler /** * Container for pending clients and pending connections. */ - TokenCollector mTokenCollector; + TokenCollector mTokenCollector; }; extern GameHandler *gameHandler; diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index 2219ada1..465cf8fa 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -29,13 +29,13 @@ #include "net/messageout.h" #include "utils/logger.h" -Inventory::Inventory(Being *p): +Inventory::Inventory(Entity *p): mPoss(&p->getComponent()->getPossessions()), mCharacter(p) { } -Inventory::Inventory(Being *p, Possessions &possessions): +Inventory::Inventory(Entity *p, Possessions &possessions): mPoss(&possessions), mCharacter(p) { @@ -97,7 +97,7 @@ void Inventory::initialize() { LOG_WARN("Inventory: deleting unknown item type " << it1->second.itemId << " from the inventory of '" - << mCharacter->getName() + << mCharacter->getComponent()->getName() << "'!"); mPoss->inventory.erase(it1++); } @@ -124,7 +124,7 @@ void Inventory::initialize() { LOG_WARN("Equipment: deleting unknown item id " << it2->second.itemId << " from the equipment of '" - << mCharacter->getName() + << mCharacter->getComponent()->getName() << "'!"); mPoss->equipSlots.erase(it2++); continue; @@ -164,7 +164,8 @@ unsigned Inventory::insert(unsigned itemId, unsigned amount) unsigned maxPerSlot = item->getMaxPerSlot(); LOG_DEBUG("Inventory: Inserting " << amount << " item(s) Id: " << itemId - << " for character '" << mCharacter->getName() << "'."); + << " for character '" + << mCharacter->getComponent()->getName() << "'."); InventoryData::iterator it, it_end = mPoss->inventory.end(); // Add to slots with existing items of this type first. @@ -278,7 +279,8 @@ unsigned Inventory::remove(unsigned itemId, unsigned amount) return amount; LOG_DEBUG("Inventory: Request remove of " << amount << " item(s) id: " - << itemId << " for character: '" << mCharacter->getName() + << itemId << " for character: '" + << mCharacter->getComponent()->getName() << "'."); MessageOut invMsg(GPMSG_INVENTORY); @@ -338,7 +340,8 @@ unsigned Inventory::move(unsigned slot1, unsigned slot2, unsigned amount) { LOG_DEBUG(amount << " item(s) requested to move from: " << slot1 << " to " - << slot2 << " for character: '" << mCharacter->getName() << "'."); + << slot2 << " for character: '" + << mCharacter->getComponent()->getName() << "'."); if (!amount || slot1 == slot2 || slot2 >= INVENTORY_SLOTS) return amount; @@ -467,7 +470,8 @@ unsigned Inventory::removeFromSlot(unsigned slot, unsigned amount) return amount; LOG_DEBUG("Inventory: Request Removal of " << amount << " item(s) in slot: " - << slot << " for character: '" << mCharacter->getName() << "'."); + << slot << " for character: '" + << mCharacter->getComponent()->getName() << "'."); MessageOut invMsg(GPMSG_INVENTORY); // Check if an item of the same id exists elsewhere in the inventory @@ -666,7 +670,8 @@ bool Inventory::equip(int inventorySlot) { // Something went wrong even when we tested the unequipment process. LOG_WARN("Unable to unequip even when unequip was tested. " - "Character : " << mCharacter->getName() + "Character : " + << mCharacter->getComponent()->getName() << ", unequip slot: " << *it3); return false; } @@ -837,6 +842,7 @@ bool Inventory::unequip(unsigned itemInstance) void Inventory::checkLookchanges(unsigned slotTypeId) { + Actor *actor = static_cast(mCharacter); if (itemManager->isEquipSlotVisible(slotTypeId)) - mCharacter->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); + actor->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); } diff --git a/src/game-server/inventory.h b/src/game-server/inventory.h index 75336ace..1740a8d9 100644 --- a/src/game-server/inventory.h +++ b/src/game-server/inventory.h @@ -36,8 +36,8 @@ class Inventory /** * Creates a view on the possessions of a character. */ - explicit Inventory(Being *); - Inventory(Being *, Possessions &possessions); + explicit Inventory(Entity *); + Inventory(Entity *, Possessions &possessions); /** * Commits delayed changes if applicable. @@ -190,7 +190,7 @@ class Inventory Possessions *mPoss; /**< Pointer to the modified possessions. */ - Being *mCharacter; /**< Character to notify. */ + Entity *mCharacter; /**< Character to notify. */ }; #endif diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp index 7295b95a..2b2d4620 100644 --- a/src/game-server/item.cpp +++ b/src/game-server/item.cpp @@ -33,28 +33,33 @@ #include #include -bool ItemEffectAttrMod::apply(Being *itemUser) +bool ItemEffectAttrMod::apply(Entity *itemUser) { LOG_DEBUG("Applying modifier."); - itemUser->applyModifier(mAttributeId, mMod, mAttributeLayer, - mDuration, mId); + itemUser->getComponent()->applyModifier(*itemUser, + mAttributeId, mMod, + mAttributeLayer, + mDuration, mId); return false; } -void ItemEffectAttrMod::dispell(Being *itemUser) +void ItemEffectAttrMod::dispell(Entity *itemUser) { LOG_DEBUG("Dispelling modifier."); - itemUser->removeModifier(mAttributeId, mMod, mAttributeLayer, - mId, !mDuration); + itemUser->getComponent()->removeModifier(*itemUser, + mAttributeId, + mMod, + mAttributeLayer, + mId, !mDuration); } -bool ItemEffectAttack::apply(Being *itemUser) +bool ItemEffectAttack::apply(Entity *itemUser) { itemUser->getComponent()->addAttack(mAttackInfo); return false; } -void ItemEffectAttack::dispell(Being *itemUser) +void ItemEffectAttack::dispell(Entity *itemUser) { itemUser->getComponent()->removeAttack(mAttackInfo); } @@ -63,7 +68,7 @@ ItemEffectScript::~ItemEffectScript() { } -bool ItemEffectScript::apply(Being *itemUser) +bool ItemEffectScript::apply(Entity *itemUser) { if (mActivateEventName.empty()) return false; @@ -82,7 +87,7 @@ bool ItemEffectScript::apply(Being *itemUser) return false; } -void ItemEffectScript::dispell(Being *itemUser) +void ItemEffectScript::dispell(Entity *itemUser) { if (mDispellEventName.empty()) return; @@ -123,7 +128,7 @@ void ItemClass::addEffect(ItemEffectInfo *effect, mDispells.insert(std::make_pair(dispell, effect)); } -bool ItemClass::useTrigger(Being *itemUser, ItemTriggerType trigger) +bool ItemClass::useTrigger(Entity *itemUser, ItemTriggerType trigger) { if (!trigger) return false; diff --git a/src/game-server/item.h b/src/game-server/item.h index e88c1f98..e436afdc 100644 --- a/src/game-server/item.h +++ b/src/game-server/item.h @@ -28,7 +28,7 @@ #include "game-server/attack.h" #include "scripting/script.h" -class Being; +class Entity; class ItemClass; class MapComposite; @@ -105,8 +105,8 @@ class ItemEffectInfo public: virtual ~ItemEffectInfo() {} - virtual bool apply(Being *itemUser) = 0; - virtual void dispell(Being *itemUser) = 0; + virtual bool apply(Entity *itemUser) = 0; + virtual void dispell(Entity *itemUser) = 0; }; class ItemEffectAttrMod : public ItemEffectInfo @@ -118,8 +118,8 @@ class ItemEffectAttrMod : public ItemEffectInfo mMod(value), mDuration(duration), mId(id) {} - bool apply(Being *itemUser); - void dispell(Being *itemUser); + bool apply(Entity *itemUser); + void dispell(Entity *itemUser); private: unsigned mAttributeId; @@ -136,8 +136,8 @@ class ItemEffectAttack : public ItemEffectInfo mAttackInfo(attackInfo) {} - bool apply(Being *itemUser); - void dispell(Being *itemUser); + bool apply(Entity *itemUser); + void dispell(Entity *itemUser); private: AttackInfo *mAttackInfo; }; @@ -145,9 +145,9 @@ class ItemEffectAttack : public ItemEffectInfo class ItemEffectConsumes : public ItemEffectInfo { public: - bool apply(Being *) + bool apply(Entity *) { return true; } - void dispell(Being *) + void dispell(Entity *) {} }; @@ -164,8 +164,8 @@ class ItemEffectScript : public ItemEffectInfo ~ItemEffectScript(); - bool apply(Being *itemUser); - void dispell(Being *itemUser); + bool apply(Entity *itemUser); + void dispell(Entity *itemUser); private: ItemClass *mItemClass; @@ -206,7 +206,7 @@ class ItemClass * Applies the modifiers of an item to a given user. * @return true if item should be removed. */ - bool useTrigger(Being *itemUser, ItemTriggerType trigger); + bool useTrigger(Entity *itemUser, ItemTriggerType trigger); /** * Gets unit cost of these items. diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index e35c68fb..61e0a8b9 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -182,7 +182,7 @@ CharacterIterator::CharacterIterator(const ZoneIterator &it) while (iterator && (*iterator)->nbCharacters == 0) ++iterator; if (iterator) { - current = static_cast< Being * >((*iterator)->objects[pos]); + current = (*iterator)->objects[pos]; } } @@ -195,7 +195,7 @@ void CharacterIterator::operator++() } if (iterator) { - current = static_cast< Being * >((*iterator)->objects[pos]); + current = static_cast< Actor * >((*iterator)->objects[pos]); } } @@ -205,7 +205,7 @@ BeingIterator::BeingIterator(const ZoneIterator &it) while (iterator && (*iterator)->nbMovingObjects == 0) ++iterator; if (iterator) { - current = static_cast< Being * >((*iterator)->objects[pos]); + current = static_cast< Actor * >((*iterator)->objects[pos]); } } @@ -218,7 +218,7 @@ void BeingIterator::operator++() } if (iterator) { - current = static_cast< Being * >((*iterator)->objects[pos]); + current = static_cast< Actor * >((*iterator)->objects[pos]); } } @@ -541,10 +541,12 @@ ZoneIterator MapComposite::getInsideRectangleIterator(const Rectangle &p) const return ZoneIterator(r, mContent); } -ZoneIterator MapComposite::getAroundBeingIterator(Being *obj, int radius) const +ZoneIterator MapComposite::getAroundBeingIterator(Actor *obj, int radius) const { MapRegion r1; - mContent->fillRegion(r1, obj->getOldPosition(), radius); + mContent->fillRegion(r1, + obj->getComponent()->getOldPosition(), + radius); MapRegion r2 = r1; for (MapRegion::iterator i = r1.begin(), i_end = r1.end(); i != i_end; ++i) { @@ -570,7 +572,7 @@ bool MapComposite::insert(Entity *ptr) { if (ptr->isVisible()) { - if (ptr->canMove() && !mContent->allocate(static_cast< Being * >(ptr))) + if (ptr->canMove() && !mContent->allocate(static_cast< Actor * >(ptr))) { return false; } @@ -591,10 +593,9 @@ void MapComposite::remove(Entity *ptr) { if ((*i)->canFight()) { - Being *being = static_cast(*i); - if (being->getComponent()->getTarget() == ptr) + if ((*i)->getComponent()->getTarget() == ptr) { - being->getComponent()->clearTarget(); + (*i)->getComponent()->clearTarget(); } } if (*i == ptr) @@ -610,7 +611,7 @@ void MapComposite::remove(Entity *ptr) if (ptr->canMove()) { - mContent->deallocate(static_cast< Being * >(ptr)); + mContent->deallocate(obj); } } } @@ -636,7 +637,7 @@ void MapComposite::update() // Move objects around and update zones. for (BeingIterator it(getWholeMapIterator()); it; ++it) { - (*it)->move(); + (*it)->getComponent()->move(**it); } for (int i = 0; i < mContent->mapHeight * mContent->mapWidth; ++i) @@ -651,18 +652,19 @@ void MapComposite::update() if (!(*i)->canMove()) continue; - Being *obj = static_cast< Being * >(*i); + Actor *actor = static_cast(*i); - const Point &pos1 = obj->getOldPosition(), - &pos2 = obj->getPosition(); + const Point &pos1 = + actor->getComponent()->getOldPosition(); + const Point &pos2 = actor->getPosition(); MapZone &src = mContent->getZone(pos1), &dst = mContent->getZone(pos2); if (&src != &dst) { addZone(src.destinations, &dst - mContent->zones); - src.remove(obj); - dst.insert(obj); + src.remove(actor); + dst.insert(actor); } } } diff --git a/src/game-server/mapcomposite.h b/src/game-server/mapcomposite.h index c8eb2e88..9a6bde07 100644 --- a/src/game-server/mapcomposite.h +++ b/src/game-server/mapcomposite.h @@ -30,7 +30,6 @@ #include "game-server/map.h" class Actor; -class Being; class CharacterComponent; class Map; class MapComposite; @@ -76,11 +75,11 @@ struct CharacterIterator { ZoneIterator iterator; unsigned short pos; - Being *current; + Actor *current; CharacterIterator(const ZoneIterator &); void operator++(); - Being *operator*() const { return current; } + Actor *operator*() const { return current; } operator bool() const { return iterator; } }; @@ -91,11 +90,11 @@ struct BeingIterator { ZoneIterator iterator; unsigned short pos; - Being *current; + Actor *current; BeingIterator(const ZoneIterator &); void operator++(); - Being *operator*() const { return current; } + Actor *operator*() const { return current; } operator bool() const { return iterator; } }; @@ -106,11 +105,11 @@ struct FixedActorIterator { ZoneIterator iterator; unsigned short pos; - Actor *current; + Entity *current; FixedActorIterator(const ZoneIterator &); void operator++(); - Actor *operator*() const { return current; } + Entity *operator*() const { return current; } operator bool() const { return iterator; } }; @@ -315,7 +314,7 @@ class MapComposite * 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(Being *, int radius) const; + ZoneIterator getAroundBeingIterator(Actor *, int radius) const; /** * Gets everything related to the map. diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index 39b62593..e3acf323 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -53,14 +53,16 @@ double MonsterClass::getVulnerability(Element element) const return it->second; } -MonsterComponent::MonsterComponent(Being &being, MonsterClass *specy): +MonsterComponent::MonsterComponent(Actor &actor, MonsterClass *specy): mSpecy(specy), mOwner(NULL) { LOG_DEBUG("Monster spawned! (id: " << mSpecy->getId() << ")."); - being.setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER); - being.setBlockType(BLOCKTYPE_MONSTER); + auto *beingComponent = actor.getComponent(); + + actor.setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER); + actor.setBlockType(BLOCKTYPE_MONSTER); /* * Initialise the attribute structures. @@ -68,7 +70,7 @@ MonsterComponent::MonsterComponent(Being &being, MonsterClass *specy): for (auto attrInfo : attributeManager->getAttributeScope(MonsterScope)) { - being.createAttribute(attrInfo.first, *attrInfo.second); + beingComponent->createAttribute(attrInfo.first, *attrInfo.second); } /* @@ -86,13 +88,13 @@ MonsterComponent::MonsterComponent(Being &being, MonsterClass *specy): double factor = 100 + (rand() % (mutation * 2)) - mutation; attributeValue = attributeValue * factor / 100.0; } - being.setAttribute(attribute.first, attributeValue); + beingComponent->setAttribute(actor, attribute.first, attributeValue); } - being.setSize(specy->getSize()); - being.setGender(specy->getGender()); + actor.setSize(specy->getSize()); + beingComponent->setGender(specy->getGender()); - being.signal_died.connect(sigc::mem_fun(this, + beingComponent->signal_died.connect(sigc::mem_fun(this, &MonsterComponent::monsterDied)); // Set positions relative to target from which the monster can attack @@ -103,8 +105,8 @@ MonsterComponent::MonsterComponent(Being &being, MonsterClass *specy): mAttackPositions.push_back(AttackPosition(0, dist, UP)); MonsterCombatComponent *combatComponent = - new MonsterCombatComponent(being, specy); - being.addComponent(combatComponent); + new MonsterCombatComponent(actor, specy); + actor.addComponent(combatComponent); double damageMutation = mutation ? (100.0 + (rand() % (mutation * 2)) - mutation) / 100.0 : 1.0; @@ -124,13 +126,15 @@ void MonsterComponent::update(Entity &entity) mOwner = NULL; // Temporary until all depedencies are available as component - Being &being = static_cast(entity); + Actor &being = static_cast(entity); + + auto *beingComponent = entity.getComponent(); // If dead, remove it - if (being.getAction() == DEAD) + if (beingComponent->getAction() == DEAD) { if (mDecayTimeout.expired()) - GameState::enqueueRemove(&being); + GameState::enqueueRemove(static_cast(&entity)); return; } @@ -151,7 +155,7 @@ void MonsterComponent::update(Entity &entity) // We have no target - let's wander around if (mStrollTimeout.expired() && - being.getPosition() == being.getDestination()) + being.getPosition() == beingComponent->getDestination()) { if (mKillStealProtectedTimeout.expired()) { @@ -165,7 +169,7 @@ void MonsterComponent::update(Entity &entity) // Don't allow negative destinations, to avoid rounding // problems when divided by tile size if (randomPos.x >= 0 && randomPos.y >= 0) - being.setDestination(randomPos); + beingComponent->setDestination(entity, randomPos); } mStrollTimeout.set(10 + rand() % 10); } @@ -174,16 +178,17 @@ void MonsterComponent::update(Entity &entity) void MonsterComponent::refreshTarget(Entity &entity) { - // Temporary until all depedencies are available as component - Being &being = static_cast(entity); + // Temporary until all depdencies are available as component + Actor &actor = static_cast(entity); + auto *beingComponent = entity.getComponent(); // We are dead and sadly not possible to keep attacking :( - if (being.getAction() == DEAD) + if (beingComponent->getAction() == DEAD) return; // Check potential attack positions int bestTargetPriority = 0; - Being *bestTarget = 0; + Actor *bestTarget = 0; Point bestAttackPosition; // reset Target. We will find a new one if possible @@ -191,7 +196,7 @@ void MonsterComponent::refreshTarget(Entity &entity) // Iterate through objects nearby int aroundArea = Configuration::getValue("game_visualRange", 448); - for (BeingIterator i(entity.getMap()->getAroundBeingIterator(&being, + for (BeingIterator i(entity.getMap()->getAroundBeingIterator(&actor, aroundArea)); i; ++i) { @@ -199,15 +204,16 @@ void MonsterComponent::refreshTarget(Entity &entity) if ((*i)->getType() != OBJECT_CHARACTER) continue; - Being *target = static_cast(*i); + Actor *target = *i; // Dead characters are ignored - if (target->getAction() == DEAD) + if (beingComponent->getAction() == DEAD) continue; // Determine how much we hate the target int targetPriority = 0; - std::map::iterator angerIterator = mAnger.find(target); + std::map::iterator angerIterator = + mAnger.find(target); if (angerIterator != mAnger.end()) { const AggressionInfo &aggressionInfo = angerIterator->second; @@ -244,15 +250,15 @@ void MonsterComponent::refreshTarget(Entity &entity) if (bestTarget) { entity.getComponent()->setTarget(bestTarget); - if (bestAttackPosition == being.getPosition()) + if (bestAttackPosition == actor.getPosition()) { - being.setAction(ATTACK); - being.updateDirection(being.getPosition(), - bestTarget->getPosition()); + beingComponent->setAction(entity, ATTACK); + beingComponent->updateDirection(actor, actor.getPosition(), + bestTarget->getPosition()); } else { - being.setDestination(bestAttackPosition); + beingComponent->setDestination(entity, bestAttackPosition); } } } @@ -297,7 +303,7 @@ int MonsterComponent::calculatePositionPriority(Entity &entity, void MonsterComponent::forgetTarget(Entity *entity) { - Being *b = static_cast< Being * >(entity); + Entity *b = static_cast< Entity * >(entity); { AggressionInfo &aggressionInfo = mAnger[b]; aggressionInfo.removedConnection.disconnect(); @@ -307,42 +313,41 @@ void MonsterComponent::forgetTarget(Entity *entity) if (b->getType() == OBJECT_CHARACTER) { - Being *c = static_cast< Being * >(b); + Entity *c = static_cast< Entity * >(b); mExpReceivers.erase(c); mLegalExpReceivers.erase(c); } } -void MonsterComponent::changeAnger(Actor *target, int amount) +void MonsterComponent::changeAnger(Entity *target, int amount) { const EntityType type = target->getType(); if (type != OBJECT_MONSTER && type != OBJECT_CHARACTER) return; - Being *being = static_cast< Being * >(target); - - if (mAnger.find(being) != mAnger.end()) + if (mAnger.find(target) != mAnger.end()) { - mAnger[being].anger += amount; + mAnger[target].anger += amount; } else { - AggressionInfo &aggressionInfo = mAnger[being]; + AggressionInfo &aggressionInfo = mAnger[target]; aggressionInfo.anger = amount; // Forget target either when it's removed or died, whichever // happens first. aggressionInfo.removedConnection = - being->signal_removed.connect(sigc::mem_fun(this, &MonsterComponent::forgetTarget)); - aggressionInfo.diedConnection = - being->signal_died.connect(sigc::mem_fun(this, &MonsterComponent::forgetTarget)); + target->signal_removed.connect(sigc::mem_fun(this, &MonsterComponent::forgetTarget)); + aggressionInfo.diedConnection = target->getComponent() + ->signal_died.connect( + sigc::mem_fun(this, &MonsterComponent::forgetTarget)); } } -std::map MonsterComponent::getAngerList() const +std::map MonsterComponent::getAngerList() const { - std::map result; - std::map::const_iterator i, i_end; + std::map result; + std::map::const_iterator i, i_end; for (i = mAnger.begin(), i_end = mAnger.end(); i != i_end; ++i) { @@ -353,8 +358,11 @@ std::map MonsterComponent::getAngerList() const return result; } -void MonsterComponent::monsterDied(Being *monster) +void MonsterComponent::monsterDied(Entity *monster) { + // Temporary until all depdencies are available as component + Actor *actor = static_cast(monster); + mDecayTimeout.set(DECAY_TIME); if (mExpReceivers.size() > 0) @@ -369,14 +377,14 @@ void MonsterComponent::monsterDied(Being *monster) if (p <= drop.probability) { Actor *item = Item::create(monster->getMap(), - monster->getPosition(), + actor->getPosition(), drop.item, 1); GameState::enqueueInsert(item); } } // Distribute exp reward. - std::map > ::iterator iChar; + std::map > ::iterator iChar; std::set::iterator iSkill; @@ -408,7 +416,7 @@ void MonsterComponent::monsterDied(Being *monster) } -void MonsterComponent::receivedDamage(Being *source, const Damage &damage, int hpLoss) +void MonsterComponent::receivedDamage(Entity *source, const Damage &damage, int hpLoss) { if (source) changeAnger(source, hpLoss); diff --git a/src/game-server/monster.h b/src/game-server/monster.h index e4d986b3..1b17bfd6 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(Being &being, MonsterClass *); + MonsterComponent(Actor &actor, MonsterClass *); ~MonsterComponent(); /** @@ -299,16 +299,16 @@ class MonsterComponent : public Component /** * Signal handler */ - void monsterDied(Being *monster); + void monsterDied(Entity *monster); - void receivedDamage(Being *attacker, const Damage &damage, int hpLoss); + void receivedDamage(Entity *attacker, const Damage &damage, int hpLoss); /** * Alters hate for the monster */ - void changeAnger(Actor *target, int amount); + void changeAnger(Entity *target, int amount); - std::map getAngerList() const; + std::map getAngerList() const; /** * Removes a being from the anger list. @@ -334,21 +334,21 @@ class MonsterComponent : public Component sigc::connection removedConnection; sigc::connection diedConnection; }; - std::map mAnger; + std::map mAnger; /** * Character who currently owns this monster (killsteal protection). */ - Being *mOwner; + Entity *mOwner; /** List of characters and their skills that attacked this monster. */ - std::map > mExpReceivers; + std::map > mExpReceivers; /** * List of characters who are entitled to receive exp (killsteal * protection). */ - std::set mLegalExpReceivers; + std::set mLegalExpReceivers; /** * Set positions relative to target from which the monster can attack. diff --git a/src/game-server/monstercombatcomponent.cpp b/src/game-server/monstercombatcomponent.cpp index 0fc0b483..35e2f249 100644 --- a/src/game-server/monstercombatcomponent.cpp +++ b/src/game-server/monstercombatcomponent.cpp @@ -23,7 +23,7 @@ #include "game-server/monster.h" #include "scripting/scriptmanager.h" -MonsterCombatComponent::MonsterCombatComponent(Being &monster, +MonsterCombatComponent::MonsterCombatComponent(Entity &monster, MonsterClass *specy): CombatComponent(monster), mDamageMutation(0) @@ -37,11 +37,11 @@ MonsterCombatComponent::MonsterCombatComponent(Being &monster, /** * Performs an attack */ -void MonsterCombatComponent::processAttack(Being *source, Attack &attack) +void MonsterCombatComponent::processAttack(Entity *source, Attack &attack) { if (!mTarget) { - source->setAction(STAND); + source->getComponent()->setAction(*source, STAND); return; } @@ -69,8 +69,8 @@ void MonsterCombatComponent::processAttack(Being *source, Attack &attack) /** * Calls the damage function in Being and updates the aggro list */ -int MonsterCombatComponent::damage(Being &target, - Being *source, +int MonsterCombatComponent::damage(Entity &target, + Entity *source, const Damage &damage) { Damage newDamage = damage; diff --git a/src/game-server/monstercombatcomponent.h b/src/game-server/monstercombatcomponent.h index b65c48f4..36afa26e 100644 --- a/src/game-server/monstercombatcomponent.h +++ b/src/game-server/monstercombatcomponent.h @@ -31,10 +31,10 @@ class MonsterClass; class MonsterCombatComponent: public CombatComponent { public: - MonsterCombatComponent(Being &monster, MonsterClass *specy); + MonsterCombatComponent(Entity &monster, MonsterClass *specy); - void processAttack(Being *source, Attack &attack); - int damage(Being &target, Being *source, const Damage &damage); + void processAttack(Entity *source, Attack &attack); + int damage(Entity &target, Entity *source, const Damage &damage); void setDamageMutation(double mutation); diff --git a/src/game-server/npc.cpp b/src/game-server/npc.cpp index e7a2988b..f9e714b9 100644 --- a/src/game-server/npc.cpp +++ b/src/game-server/npc.cpp @@ -73,7 +73,7 @@ void NpcComponent::setUpdateCallback(Script::Ref function) -static Script *prepareResume(Being *ch, Script::ThreadState expectedState) +static Script *prepareResume(Entity *ch, Script::ThreadState expectedState) { Script::Thread *thread = ch->getComponent()->getNpcThread(); @@ -85,7 +85,7 @@ static Script *prepareResume(Being *ch, Script::ThreadState expectedState) return script; } -void Npc::start(Being *npc, Being *ch) +void Npc::start(Entity *npc, Entity *ch) { NpcComponent *npcComponent = npc->getComponent(); @@ -100,17 +100,17 @@ void Npc::start(Being *npc, Being *ch) script->push(npc); script->push(ch); ch->getComponent() - ->startNpcThread(thread, npc->getPublicID()); + ->startNpcThread(thread, static_cast(npc)->getPublicID()); } } -void Npc::resume(Being *ch) +void Npc::resume(Entity *ch) { if (prepareResume(ch, Script::ThreadPaused)) ch->getComponent()->resumeNpcThread(); } -void Npc::integerReceived(Being *ch, int value) +void Npc::integerReceived(Entity *ch, int value) { if (Script *script = prepareResume(ch, Script::ThreadExpectingNumber)) { @@ -119,7 +119,7 @@ void Npc::integerReceived(Being *ch, int value) } } -void Npc::stringReceived(Being *ch, const std::string &value) +void Npc::stringReceived(Entity *ch, const std::string &value) { if (Script *script = prepareResume(ch, Script::ThreadExpectingString)) { diff --git a/src/game-server/npc.h b/src/game-server/npc.h index 63d4ee8b..98fbd64d 100644 --- a/src/game-server/npc.h +++ b/src/game-server/npc.h @@ -88,22 +88,22 @@ namespace Npc { /** * Starts a conversation with the NPC. */ -void start(Being *npc, Being *ch); +void start(Entity *npc, Entity *ch); /** * Resumes an NPC conversation. */ -void resume(Being *ch); +void resume(Entity *ch); /** * The player has made a choice or entered an integer. */ -void integerReceived(Being *ch, int value); +void integerReceived(Entity *ch, int value); /** * The player has entered an string. */ -void stringReceived(Being *ch, const std::string &value); +void stringReceived(Entity *ch, const std::string &value); } // namespace Npc diff --git a/src/game-server/postman.h b/src/game-server/postman.h index 8862ccf6..145db9e7 100644 --- a/src/game-server/postman.h +++ b/src/game-server/postman.h @@ -24,12 +24,14 @@ #include #include -class Being; +#include "game-server/character.h" +#include "game-server/entity.h" + class Script; struct PostCallback { - void (*handler)(Being *, + void (*handler)(Entity *, const std::string &sender, const std::string &letter, Script *); @@ -40,9 +42,9 @@ struct PostCallback class PostMan { public: - Being *getCharacter(int id) const + Entity *getCharacter(int id) const { - std::map::const_iterator itr = mCharacters.find(id); + std::map::const_iterator itr = mCharacters.find(id); if (itr != mCharacters.end()) return itr->second; return 0; @@ -52,23 +54,22 @@ public: { int dataBaseId = player->getComponent() ->getDatabaseID(); - std::map::iterator itr = mCharacters.find(dataBaseId); + std::map::iterator itr = mCharacters.find(dataBaseId); if (itr == mCharacters.end()) { - Being *being = static_cast(player); - mCharacters.insert(std::pair(dataBaseId, being)); + mCharacters.insert(std::pair(dataBaseId, player)); } } - void getPost(Being *player, PostCallback &f) + void getPost(Entity *player, PostCallback &f) { - mCallbacks.insert(std::pair(player, f)); + mCallbacks.insert(std::pair(player, f)); accountHandler->getPost(player); } - void gotPost(Being *player, std::string sender, std::string letter) + void gotPost(Entity *player, std::string sender, std::string letter) { - std::map::iterator itr = mCallbacks.find(player); + std::map::iterator itr = mCallbacks.find(player); if (itr != mCallbacks.end()) { itr->second.handler(player, sender, letter, itr->second.script); @@ -76,8 +77,8 @@ public: } private: - std::map mCharacters; - std::map mCallbacks; + std::map mCharacters; + std::map mCallbacks; }; extern PostMan *postMan; diff --git a/src/game-server/quest.cpp b/src/game-server/quest.cpp index 803ec60b..515e6200 100644 --- a/src/game-server/quest.cpp +++ b/src/game-server/quest.cpp @@ -36,7 +36,7 @@ typedef std::map< std::string, QuestCallbacks > PendingVariables; struct PendingQuest { - Being *character; + Entity *character; sigc::connection removedConnection; sigc::connection disconnectedConnection; PendingVariables variables; @@ -46,7 +46,7 @@ typedef std::map< int, PendingQuest > PendingQuests; static PendingQuests pendingQuests; -bool getQuestVar(Being *ch, const std::string &name, std::string &value) +bool getQuestVar(Entity *ch, const std::string &name, std::string &value) { std::map< std::string, std::string >::iterator i = ch->getComponent()->questCache.find(name); @@ -56,7 +56,7 @@ bool getQuestVar(Being *ch, const std::string &name, std::string &value) return true; } -void setQuestVar(Being *ch, const std::string &name, +void setQuestVar(Entity *ch, const std::string &name, const std::string &value) { auto *characterComponent = @@ -79,7 +79,7 @@ void setQuestVar(Being *ch, const std::string &name, accountHandler->updateCharacterVar(ch, name, value); } -void QuestRefCallback::triggerCallback(Being *ch, +void QuestRefCallback::triggerCallback(Entity *ch, const std::string &value) const { if (!mRef.isValid()) @@ -120,7 +120,7 @@ static void fullRemove(Entity &ch) pendingQuests.erase(id); } -void recoverQuestVar(Being *ch, const std::string &name, +void recoverQuestVar(Entity *ch, const std::string &name, QuestCallback *f) { auto *characterComponent = @@ -171,7 +171,7 @@ void recoveredQuestVar(int id, return; } - Being *ch = pendingQuest.character; + Entity *ch = pendingQuest.character; auto *characterComponent = ch->getComponent(); characterComponent->questCache[name] = value; diff --git a/src/game-server/quest.h b/src/game-server/quest.h index 13f91cc2..bfc1f874 100644 --- a/src/game-server/quest.h +++ b/src/game-server/quest.h @@ -25,7 +25,7 @@ #include "scripting/scriptmanager.h" -class Being; +class Entity; class Script; @@ -35,14 +35,14 @@ class QuestCallback virtual ~QuestCallback() { } - virtual void triggerCallback(Being *ch, + virtual void triggerCallback(Entity *ch, const std::string &value) const = 0; }; class QuestThreadCallback : public QuestCallback { public: - typedef void (*Handler)(Being *, + typedef void (*Handler)(Entity *, const std::string &value, Script *mScript); @@ -52,7 +52,7 @@ class QuestThreadCallback : public QuestCallback mScript(script) { } - void triggerCallback(Being *ch, const std::string &value) const + void triggerCallback(Entity *ch, const std::string &value) const { mHandler(ch, value, mScript); } private: @@ -67,7 +67,7 @@ class QuestRefCallback : public QuestCallback mQuestName(questName) { script->assignCallback(mRef); } - void triggerCallback(Being *ch, const std::string &value) const; + void triggerCallback(Entity *ch, const std::string &value) const; private: Script::Ref mRef; @@ -78,18 +78,18 @@ class QuestRefCallback : public QuestCallback * Gets the value associated to a quest variable. * @return false if no value was in cache. */ -bool getQuestVar(Being *, const std::string &name, std::string &value); +bool getQuestVar(Entity *, const std::string &name, std::string &value); /** * Sets the value associated to a quest variable. */ -void setQuestVar(Being *, const std::string &name, const std::string &value); +void setQuestVar(Entity *, const std::string &name, const std::string &value); /** * Starts the recovery of a variable and returns immediatly. The callback will * be called once the value has been recovered. */ -void recoverQuestVar(Being *, const std::string &name, QuestCallback *); +void recoverQuestVar(Entity *, const std::string &name, QuestCallback *); /** * Called by the handler of the account server when a value is received. diff --git a/src/game-server/spawnareacomponent.cpp b/src/game-server/spawnareacomponent.cpp index 557a2da5..843371a7 100644 --- a/src/game-server/spawnareacomponent.cpp +++ b/src/game-server/spawnareacomponent.cpp @@ -67,10 +67,12 @@ void SpawnAreaComponent::update(Entity &entity) const int width = mZone.w; const int height = mZone.h; - Being *being = new Being(OBJECT_MONSTER); + Actor *being = new Actor(OBJECT_MONSTER); + auto *beingComponent = new BeingComponent(*being); + being->addComponent(beingComponent); being->addComponent(new MonsterComponent(*being, mSpecy)); - if (being->getModifiedAttribute(ATTR_MAX_HP) <= 0) + if (beingComponent->getModifiedAttribute(ATTR_MAX_HP) <= 0) { LOG_WARN("Refusing to spawn dead monster " << mSpecy->getId()); delete being; @@ -96,7 +98,7 @@ void SpawnAreaComponent::update(Entity &entity) being->setMap(map); being->setPosition(position); - being->clearDestination(); + beingComponent->clearDestination(*being); GameState::enqueueInsert(being); mNumBeings++; diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index f1ed99a0..87213f61 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -79,7 +79,7 @@ static std::map< std::string, std::string > mScriptVariables; /** * Sets message fields describing character look. */ -static void serializeLooks(Being *ch, MessageOut &msg) +static void serializeLooks(Entity *ch, MessageOut &msg) { const EquipData &equipData = ch->getComponent() ->getPossessions().getEquipment(); @@ -128,11 +128,12 @@ static void serializeLooks(Being *ch, MessageOut &msg) /** * Informs a player of what happened around the character. */ -static void informPlayer(MapComposite *map, Being *p) +static void informPlayer(MapComposite *map, Actor *p) { MessageOut moveMsg(GPMSG_BEINGS_MOVE); MessageOut damageMsg(GPMSG_BEINGS_DAMAGE); - const Point &pold = p->getOldPosition(), ppos = p->getPosition(); + const Point &pold = p->getComponent()->getOldPosition(); + const Point &ppos = p->getPosition(); int pid = p->getPublicID(), pflags = p->getUpdateFlags(); int visualRange = Configuration::getValue("game_visualRange", 448); @@ -140,9 +141,11 @@ static void informPlayer(MapComposite *map, Being *p) for (BeingIterator it(map->getAroundBeingIterator(p, visualRange)); it; ++it) { - Being *o = *it; + Actor *o = *it; - const Point &oold = o->getOldPosition(), opos = o->getPosition(); + const Point &oold = + o->getComponent()->getOldPosition(); + const Point &opos = o->getPosition(); int otype = o->getType(); int oid = o->getPublicID(), oflags = o->getUpdateFlags(); int flags = 0; @@ -166,7 +169,8 @@ static void informPlayer(MapComposite *map, Being *p) { MessageOut AttackMsg(GPMSG_BEING_ATTACK); AttackMsg.writeInt16(oid); - AttackMsg.writeInt8(o->getDirection()); + AttackMsg.writeInt8( + o->getComponent()->getDirection()); CombatComponent *combatComponent = o->getComponent(); AttackMsg.writeInt8(combatComponent->getAttackId()); @@ -178,7 +182,8 @@ static void informPlayer(MapComposite *map, Being *p) { MessageOut ActionMsg(GPMSG_BEING_ACTION_CHANGE); ActionMsg.writeInt16(oid); - ActionMsg.writeInt8(static_cast< Being * >(o)->getAction()); + ActionMsg.writeInt8( + o->getComponent()->getAction()); gameHandler->sendTo(p, ActionMsg); } @@ -192,14 +197,16 @@ static void informPlayer(MapComposite *map, Being *p) o->getComponent(); LooksMsg.writeInt16(characterComponent->getHairStyle()); LooksMsg.writeInt16(characterComponent->getHairColor()); - LooksMsg.writeInt16(o->getGender()); + LooksMsg.writeInt16( + o->getComponent()->getGender()); gameHandler->sendTo(p, LooksMsg); } // Send emote messages. if (oflags & UPDATEFLAG_EMOTE) { - int emoteId = o->getLastEmote(); + int emoteId = + o->getComponent()->getLastEmote(); if (emoteId > -1) { MessageOut EmoteMsg(GPMSG_BEING_EMOTE); @@ -214,7 +221,8 @@ static void informPlayer(MapComposite *map, Being *p) { MessageOut DirMsg(GPMSG_BEING_DIR_CHANGE); DirMsg.writeInt16(oid); - DirMsg.writeInt8(o->getDirection()); + DirMsg.writeInt8( + o->getComponent()->getDirection()); gameHandler->sendTo(p, DirMsg); } @@ -254,18 +262,20 @@ static void informPlayer(MapComposite *map, Being *p) MessageOut enterMsg(GPMSG_BEING_ENTER); enterMsg.writeInt8(otype); enterMsg.writeInt16(oid); - enterMsg.writeInt8(static_cast< Being *>(o)->getAction()); + enterMsg.writeInt8(o->getComponent()->getAction()); enterMsg.writeInt16(opos.x); enterMsg.writeInt16(opos.y); - enterMsg.writeInt8(o->getDirection()); - enterMsg.writeInt8(o->getGender()); + enterMsg.writeInt8( + o->getComponent()->getDirection()); + enterMsg.writeInt8(o->getComponent()->getGender()); switch (otype) { case OBJECT_CHARACTER: { auto *characterComponent = o->getComponent(); - enterMsg.writeString(o->getName()); + enterMsg.writeString( + o->getComponent()->getName()); enterMsg.writeInt8(characterComponent->getHairStyle()); enterMsg.writeInt8(characterComponent->getHairColor()); serializeLooks(o, enterMsg); @@ -276,14 +286,17 @@ static void informPlayer(MapComposite *map, Being *p) MonsterComponent *monsterComponent = o->getComponent(); enterMsg.writeInt16(monsterComponent->getSpecy()->getId()); - enterMsg.writeString(o->getName()); + enterMsg.writeString( + o->getComponent()->getName()); } break; case OBJECT_NPC: { - NpcComponent *npcComponent = o->getComponent(); + NpcComponent *npcComponent = + o->getComponent(); enterMsg.writeInt16(npcComponent->getNpcId()); - enterMsg.writeString(o->getName()); + enterMsg.writeString( + o->getComponent()->getName()); } break; default: @@ -319,7 +332,8 @@ static void informPlayer(MapComposite *map, Being *p) // to get it within a byte with decimal precision. // For instance, a value of 4.5 will be sent as 45. moveMsg.writeInt8((unsigned short) - (o->getModifiedAttribute(ATTR_MOVE_SPEED_TPS) * 10)); + (o->getComponent() + ->getModifiedAttribute(ATTR_MOVE_SPEED_TPS) * 10)); } } @@ -336,7 +350,7 @@ static void informPlayer(MapComposite *map, Being *p) // Inform client about health change of party members for (CharacterIterator i(map->getWholeMapIterator()); i; ++i) { - Being *c = *i; + Actor *c = *i; // Make sure its not the same character if (c == p) @@ -349,10 +363,14 @@ static void informPlayer(MapComposite *map, Being *p) int cflags = c->getUpdateFlags(); if (cflags & UPDATEFLAG_HEALTHCHANGE) { + auto *beingComponent = c->getComponent(); + MessageOut healthMsg(GPMSG_BEING_HEALTH_CHANGE); healthMsg.writeInt16(c->getPublicID()); - healthMsg.writeInt16(c->getModifiedAttribute(ATTR_HP)); - healthMsg.writeInt16(c->getModifiedAttribute(ATTR_MAX_HP)); + healthMsg.writeInt16( + beingComponent->getModifiedAttribute(ATTR_HP)); + healthMsg.writeInt16( + beingComponent->getModifiedAttribute(ATTR_MAX_HP)); gameHandler->sendTo(p, healthMsg); } } @@ -363,7 +381,7 @@ static void informPlayer(MapComposite *map, Being *p) for (FixedActorIterator it(map->getAroundBeingIterator(p, visualRange)); it; ++it) { - Actor *o = *it; + Actor *o = static_cast(*it); assert(o->getType() == OBJECT_ITEM || o->getType() == OBJECT_EFFECT); @@ -409,11 +427,12 @@ static void informPlayer(MapComposite *map, Being *p) if (!(oflags & UPDATEFLAG_NEW_ON_MAP)) break; - if (Being *b = e->getBeing()) + if (Entity *b = e->getBeing()) { MessageOut effectMsg(GPMSG_CREATE_EFFECT_BEING); effectMsg.writeInt16(e->getEffectId()); - effectMsg.writeInt16(b->getPublicID()); + effectMsg.writeInt16(static_cast(b) + ->getPublicID()); gameHandler->sendTo(p, effectMsg); } else { MessageOut effectMsg(GPMSG_CREATE_EFFECT_POS); @@ -503,7 +522,7 @@ void GameState::update(int tick) case EVENT_WARP: assert(o->getType() == OBJECT_CHARACTER); - warp(static_cast(o), e.map, e.point); + warp(o, e.map, e.point); break; } } @@ -562,7 +581,7 @@ bool GameState::insert(Entity *ptr) case OBJECT_CHARACTER: LOG_DEBUG("Player inserted: " - << static_cast(obj)->getName()); + << obj->getComponent()->getName()); break; case OBJECT_EFFECT: @@ -639,7 +658,7 @@ void GameState::remove(Entity *ptr) case OBJECT_CHARACTER: LOG_DEBUG("Player removed: " - << static_cast(ptr)->getName()); + << ptr->getComponent()->getName()); break; case OBJECT_EFFECT: @@ -711,12 +730,15 @@ void GameState::remove(Entity *ptr) map->remove(ptr); } -void GameState::warp(Being *ptr, MapComposite *map, const Point &point) +void GameState::warp(Entity *ptr, MapComposite *map, const Point &point) { remove(ptr); + + Actor *actor = static_cast(ptr); + ptr->setMap(map); - ptr->setPosition(point); - ptr->clearDestination(); + actor->setPosition(point); + ptr->getComponent()->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 a disconnection. */ @@ -778,7 +800,7 @@ void GameState::enqueueRemove(Actor *ptr) enqueueEvent(ptr, event); } -void GameState::enqueueWarp(Being *ptr, +void GameState::enqueueWarp(Entity *ptr, MapComposite *map, const Point &point) { @@ -794,7 +816,7 @@ void GameState::enqueueWarp(Being *ptr, event.type = EVENT_WARP; event.point = point; event.map = map; - enqueueEvent(ptr, event); + enqueueEvent(static_cast(ptr), event); } void GameState::sayAround(Actor *obj, const std::string &text) diff --git a/src/game-server/state.h b/src/game-server/state.h index 512e9afd..becfd597 100644 --- a/src/game-server/state.h +++ b/src/game-server/state.h @@ -26,7 +26,6 @@ #include class Actor; -class Being; class Entity; class ItemClass; class MapComposite; @@ -71,7 +70,7 @@ namespace GameState * @note No update may be in progress. * @note The character is destroyed, if needed. */ - void warp(Being *, MapComposite *, const Point &point); + void warp(Entity *, MapComposite *, const Point &point); /** * Enqueues an insert event. @@ -90,7 +89,7 @@ namespace GameState * Enqueues a warp event. * @note The event will be executed at end of update. */ - void enqueueWarp(Being *, MapComposite *, const Point &point); + void enqueueWarp(Entity *, MapComposite *, const Point &point); /** * Says something to an actor. diff --git a/src/game-server/statuseffect.cpp b/src/game-server/statuseffect.cpp index b5b988f4..75fae986 100644 --- a/src/game-server/statuseffect.cpp +++ b/src/game-server/statuseffect.cpp @@ -32,14 +32,14 @@ StatusEffect::~StatusEffect() { } -void StatusEffect::tick(Being *target, int count) +void StatusEffect::tick(Entity &target, int count) { if (mTickCallback.isValid()) { Script *s = ScriptManager::currentState(); s->prepare(mTickCallback); - s->push(target); + s->push(&target); s->push(count); - s->execute(target->getMap()); + s->execute(target.getMap()); } } diff --git a/src/game-server/statuseffect.h b/src/game-server/statuseffect.h index 7da5fdf9..3c38944b 100644 --- a/src/game-server/statuseffect.h +++ b/src/game-server/statuseffect.h @@ -23,7 +23,7 @@ #include "scripting/script.h" -class Being; +class Entity; class StatusEffect { @@ -31,7 +31,7 @@ class StatusEffect StatusEffect(int id); ~StatusEffect(); - void tick(Being *target, int count); + void tick(Entity &target, int count); int getId() const { return mId; } diff --git a/src/game-server/trade.cpp b/src/game-server/trade.cpp index 9e9e05fb..1d863137 100644 --- a/src/game-server/trade.cpp +++ b/src/game-server/trade.cpp @@ -37,11 +37,11 @@ * TRADE_AGREE_WAIT : One player has agreed, waiting for the other one */ -Trade::Trade(Being *c1, Being *c2): +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(c1->getPublicID()); + msg.writeInt16(static_cast(c1)->getPublicID()); c2->getComponent()->getClient()->send(msg); c1->getComponent()->setTrading(this); c2->getComponent()->setTrading(this); @@ -61,10 +61,11 @@ void Trade::cancel() delete this; } -bool Trade::request(Being *c, int id) +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 || mChar1->getPublicID() != id) + if (mState != TRADE_INIT || c != mChar2 || + static_cast(mChar1)->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. */ @@ -99,7 +100,7 @@ bool Trade::perform(TradedItems items, Inventory &inv1, Inventory &inv2) return true; } -void Trade::agree(Being *c) +void Trade::agree(Entity *c) { // No player agreed if (mState == TRADE_CONFIRMED) @@ -131,15 +132,23 @@ void Trade::agree(Being *c) // Check if both player has the objects in their inventories // and enouth money, then swap them. Inventory v1(mChar1), v2(mChar2); - if (mChar1->getAttributeBase(mCurrencyId) >= mMoney1 - mMoney2 && - mChar2->getAttributeBase(mCurrencyId) >= mMoney2 - mMoney1 && + + const double moneyChar1 = mChar1->getComponent() + ->getAttributeBase(mCurrencyId); + const double moneyChar2 = mChar2->getComponent() + ->getAttributeBase(mCurrencyId); + + if (moneyChar1 >= mMoney1 - mMoney2 && + moneyChar2 >= mMoney2 - mMoney1 && perform(mItems1, v1, v2) && perform(mItems2, v2, v1)) { - mChar1->setAttribute(mCurrencyId, mChar1->getAttributeBase(mCurrencyId) - - mMoney1 + mMoney2); - mChar2->setAttribute(mCurrencyId, mChar2->getAttributeBase(mCurrencyId) - - mMoney2 + mMoney1); + mChar1->getComponent() + ->setAttribute(*mChar1, mCurrencyId, + moneyChar1 - mMoney1 + mMoney2); + mChar2->getComponent() + ->setAttribute(*mChar2, mCurrencyId, + moneyChar2 - mMoney2 + mMoney1); } else { @@ -153,7 +162,7 @@ void Trade::agree(Being *c) delete this; } -void Trade::confirm(Being *c) +void Trade::confirm(Entity *c) { if (mState == TRADE_CONFIRMED || mState == TRADE_AGREE_WAIT) return; @@ -189,7 +198,7 @@ void Trade::confirm(Being *c) mChar2->getComponent()->getClient()->send(msg); } -void Trade::setMoney(Being *c, int amount) +void Trade::setMoney(Entity *c, int amount) { //If the player has already confirmed, exit. if ((mState != TRADE_RUN && (mState != TRADE_CONFIRM_WAIT || c != mChar1)) @@ -218,13 +227,13 @@ void Trade::setMoney(Being *c, int amount) mState = TRADE_RUN; } -void Trade::addItem(Being *c, int slot, int amount) +void Trade::addItem(Entity *c, int slot, int amount) { //If the player has already confirmed, exit. if ((mState != TRADE_RUN && (mState != TRADE_CONFIRM_WAIT || c != mChar1)) || amount < 0) return; - Being *other; + Entity *other; TradedItems *items; if (c == mChar1) { diff --git a/src/game-server/trade.h b/src/game-server/trade.h index be527e86..72ec0b3d 100644 --- a/src/game-server/trade.h +++ b/src/game-server/trade.h @@ -23,7 +23,7 @@ #include -class Being; +class Entity; class Inventory; class Trade @@ -34,7 +34,7 @@ class Trade * Sets up a trade between two characters. * Asks for an acknowledgment from the second one. */ - Trade(Being *, Being *); + Trade(Entity *, Entity *); /** * Cancels a trade by a given character (optional). @@ -49,27 +49,27 @@ class Trade * otherwise. * @return true if the current trade keeps going. */ - bool request(Being *, int); + bool request(Entity *, int); /** * Confirm the trade. */ - void confirm(Being *); + void confirm(Entity *); /* * Agree to complete the trade */ - void agree(Being *c); + void agree(Entity *c); /** * Adds some items to the trade. */ - void addItem(Being *, int slot, int amount); + void addItem(Entity *, int slot, int amount); /** * Adds some money to the trade. */ - void setMoney(Being *, int amount); + void setMoney(Entity *, int amount); private: @@ -98,7 +98,7 @@ class Trade static bool perform(TradedItems items, Inventory &inv1, Inventory &inv2); - Being *mChar1, *mChar2; /**< Characters involved. */ + Entity *mChar1, *mChar2; /**< Characters involved. */ TradedItems mItems1, mItems2; /**< Traded items. */ int mMoney1, mMoney2; /**< Traded money. */ TradeState mState; /**< State of transaction. */ diff --git a/src/game-server/triggerareacomponent.cpp b/src/game-server/triggerareacomponent.cpp index d4736e4e..224b17f9 100644 --- a/src/game-server/triggerareacomponent.cpp +++ b/src/game-server/triggerareacomponent.cpp @@ -34,7 +34,7 @@ void WarpAction::process(Actor *obj) { if (obj->getType() == OBJECT_CHARACTER) { - GameState::enqueueWarp(static_cast(obj), mMap, mTargetPoint); + GameState::enqueueWarp(obj, mMap, mTargetPoint); } } diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 622d1867..39fc3e8b 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -88,7 +88,7 @@ extern "C" { static int on_update_derived_attribute(lua_State *s) { luaL_checktype(s, 1, LUA_TFUNCTION); - Being::setUpdateDerivedAttributesCallback(getScript(s)); + BeingComponent::setUpdateDerivedAttributesCallback(getScript(s)); return 0; } @@ -107,7 +107,7 @@ static int on_update_derived_attribute(lua_State *s) static int on_recalculate_base_attribute(lua_State *s) { luaL_checktype(s, 1, LUA_TFUNCTION); - Being::setRecalculateBaseAttributeCallback(getScript(s)); + BeingComponent::setRecalculateBaseAttributeCallback(getScript(s)); return 0; } @@ -283,13 +283,15 @@ static int npc_create(lua_State *s) NpcComponent *npcComponent = new NpcComponent(id); - Being *npc = new Being(OBJECT_NPC); + Actor *npc = new Actor(OBJECT_NPC); + auto *beingComponent = new BeingComponent(*npc); + npc->addComponent(beingComponent); npc->addComponent(npcComponent); // some health so it doesn't spawn dead - npc->setAttribute(ATTR_MAX_HP, 100); - npc->setAttribute(ATTR_HP, 100); - npc->setName(name); - npc->setGender(getGender(gender)); + beingComponent->setAttribute(*npc, ATTR_MAX_HP, 100); + beingComponent->setAttribute(*npc, ATTR_HP, 100); + beingComponent->setName(name); + beingComponent->setGender(getGender(gender)); npc->setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_MONSTER | Map::BLOCKMASK_CHARACTER); @@ -320,9 +322,9 @@ static int npc_create(lua_State *s) */ static int npc_enable(lua_State *s) { - Being *npc = checkNpc(s, 1); + Entity *npc = checkNpc(s, 1); npc->getComponent()->setEnabled(true); - GameState::enqueueInsert(npc); + GameState::enqueueInsert(static_cast(npc)); return 0; } @@ -333,7 +335,7 @@ static int npc_enable(lua_State *s) */ static int npc_disable(lua_State *s) { - Being *npc = checkNpc(s, 1); + Entity *npc = checkNpc(s, 1); npc->getComponent()->setEnabled(false); GameState::remove(npc); return 0; @@ -355,7 +357,8 @@ static int monster_create(lua_State *s) const int y = luaL_checkint(s, 3); MapComposite *m = checkCurrentMap(s); - Being *monster = new Being(OBJECT_MONSTER); + Actor *monster = new Actor(OBJECT_MONSTER); + monster->addComponent(new BeingComponent(*monster)); monster->addComponent(new MonsterComponent(*monster, monsterClass)); monster->setMap(m); monster->setPosition(Point(x, y)); @@ -375,7 +378,7 @@ static int monster_create(lua_State *s) static int monster_remove(lua_State *s) { bool monsterRemoved = false; - if (Being *m = getMonster(s, 1)) + if (Entity *m = getMonster(s, 1)) { GameState::remove(m); monsterRemoved = true; @@ -454,8 +457,8 @@ static int effect_create(lua_State *s) if (lua_isuserdata(s, 2)) { // being mode - Being *b = checkBeing(s, 2); - Effects::show(id, b); + Entity *b = checkBeing(s, 2); + Effects::show(id, static_cast(b)); } else { @@ -501,14 +504,14 @@ static int item_drop(lua_State *s) */ static int npc_message(lua_State *s) { - Being *npc = checkNpc(s, 1); - Being *q = checkCharacter(s, 2); + Entity *npc = checkNpc(s, 1); + Entity *q = checkCharacter(s, 2); const char *m = luaL_checkstring(s, 3); Script::Thread *thread = checkCurrentThread(s); MessageOut msg(GPMSG_NPC_MESSAGE); - msg.writeInt16(npc->getPublicID()); + msg.writeInt16(static_cast(npc)->getPublicID()); msg.writeString(m); gameHandler->sendTo(q, msg); @@ -534,13 +537,13 @@ static int npc_message(lua_State *s) */ static int npc_choice(lua_State *s) { - Being *npc = checkNpc(s, 1); - Being *q = checkCharacter(s, 2); + Entity *npc = checkNpc(s, 1); + Entity *q = checkCharacter(s, 2); Script::Thread *thread = checkCurrentThread(s); MessageOut msg(GPMSG_NPC_CHOICE); - msg.writeInt16(npc->getPublicID()); + msg.writeInt16(static_cast(npc)->getPublicID()); for (int i = 3, i_end = lua_gettop(s); i <= i_end; ++i) { if (lua_isstring(s, i)) @@ -590,8 +593,8 @@ static int npc_choice(lua_State *s) */ static int npc_ask_integer(lua_State *s) { - Being *npc = checkNpc(s, 1); - Being *q = checkCharacter(s, 2); + Entity *npc = checkNpc(s, 1); + Entity *q = checkCharacter(s, 2); int min = luaL_checkint(s, 3); int max = luaL_checkint(s, 4); int defaultValue = luaL_optint(s, 5, min); @@ -599,7 +602,7 @@ static int npc_ask_integer(lua_State *s) Script::Thread *thread = checkCurrentThread(s); MessageOut msg(GPMSG_NPC_NUMBER); - msg.writeInt16(npc->getPublicID()); + msg.writeInt16(static_cast(npc)->getPublicID()); msg.writeInt32(min); msg.writeInt32(max); msg.writeInt32(defaultValue); @@ -620,13 +623,13 @@ static int npc_ask_integer(lua_State *s) */ static int npc_ask_string(lua_State *s) { - Being *npc = checkNpc(s, 1); - Being *q = checkCharacter(s, 2); + Entity *npc = checkNpc(s, 1); + Entity *q = checkCharacter(s, 2); Script::Thread *thread = checkCurrentThread(s); MessageOut msg(GPMSG_NPC_STRING); - msg.writeInt16(npc->getPublicID()); + msg.writeInt16(static_cast(npc)->getPublicID()); gameHandler->sendTo(q, msg); thread->mState = Script::ThreadExpectingString; @@ -640,11 +643,11 @@ static int npc_ask_string(lua_State *s) */ static int npc_post(lua_State *s) { - Being *npc = checkNpc(s, 1); - Being *q = checkCharacter(s, 2); + Entity *npc = checkNpc(s, 1); + Entity *q = checkCharacter(s, 2); MessageOut msg(GPMSG_NPC_POST); - msg.writeInt16(npc->getPublicID()); + msg.writeInt16(static_cast(npc)->getPublicID()); gameHandler->sendTo(q, msg); return 0; @@ -658,9 +661,9 @@ static int npc_post(lua_State *s) */ static int being_say(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); const char *message = luaL_checkstring(s, 2); - GameState::sayAround(being, message); + GameState::sayAround(static_cast(being), message); return 0; } @@ -672,10 +675,10 @@ static int being_say(lua_State *s) */ static int chat_message(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); const char *message = luaL_checkstring(s, 2); - GameState::sayTo(being, NULL, message); + GameState::sayTo(static_cast(being), nullptr, message); return 0; } @@ -767,8 +770,8 @@ static int announce(lua_State *s) */ static int npc_trade(lua_State *s) { - Being *npc = checkNpc(s, 1); - Being *q = checkCharacter(s, 2); + Entity *npc = checkNpc(s, 1); + Entity *q = checkCharacter(s, 2); if (!lua_isboolean(s, 3)) { luaL_error(s, "npc_trade called with incorrect parameters."); @@ -776,7 +779,7 @@ static int npc_trade(lua_State *s) } bool sellMode = lua_toboolean(s, 3); - BuySell *t = new BuySell(q, sellMode); + BuySell *t = new BuySell(static_cast(q), sellMode); if (!lua_istable(s, 4)) { if (sellMode) @@ -790,7 +793,7 @@ static int npc_trade(lua_State *s) return 1; } - if (t->start(npc)) + if (t->start(static_cast(npc))) { lua_pushinteger(s, 0); return 1; @@ -868,7 +871,7 @@ static int npc_trade(lua_State *s) lua_pushinteger(s, 1); return 1; } - if (t->start(npc)) + if (t->start(static_cast(npc))) { lua_pushinteger(s, 0); return 1; @@ -892,7 +895,7 @@ static int npc_trade(lua_State *s) */ static int chr_inv_count(lua_State *s) { - Being *q = checkCharacter(s, 1); + Entity *q = checkCharacter(s, 1); if (!lua_isboolean(s, 2) || !lua_isboolean(s, 3)) { luaL_error(s, "chr_inv_count called with incorrect parameters."); @@ -933,7 +936,7 @@ static int chr_inv_count(lua_State *s) */ static int chr_inv_change(lua_State *s) { - Being *q = checkCharacter(s, 1); + Entity *q = checkCharacter(s, 1); int nb_items = (lua_gettop(s) - 1) / 2; Inventory inv(q); for (int i = 0; i < nb_items; ++i) @@ -956,7 +959,9 @@ static int chr_inv_change(lua_State *s) if (nb) { LOG_WARN("chr_inv_change() removed more items than owned: " - << "character: " << q->getName() << " item id: " << id); + << "character: " + << q->getComponent()->getName() + << " item id: " << id); } } else @@ -964,8 +969,8 @@ static int chr_inv_change(lua_State *s) nb = inv.insert(id, nb); if (nb) { - Actor *item = Item::create(q->getMap(), - q->getPosition(), + Actor *item = Item::create(q->getMap(), static_cast(q) + ->getPosition(), ic, nb); GameState::enqueueInsert(item); } @@ -997,7 +1002,7 @@ static int chr_inv_change(lua_State *s) */ static int chr_get_inventory(lua_State *s) { - Being *q = checkCharacter(s, 1); + Entity *q = checkCharacter(s, 1); // Create a lua table with the inventory ids. const InventoryData invData = q->getComponent() @@ -1062,7 +1067,7 @@ static int chr_get_inventory(lua_State *s) */ static int chr_get_equipment(lua_State *s) { - Being *q = checkCharacter(s, 1); + Entity *q = checkCharacter(s, 1); // Create a lua table with the inventory ids. const EquipData equipData = q->getComponent() @@ -1115,7 +1120,7 @@ static int chr_get_equipment(lua_State *s) */ static int chr_equip_slot(lua_State *s) { - Being *ch = checkCharacter(s, 1); + Entity *ch = checkCharacter(s, 1); int inventorySlot = luaL_checkint(s, 2); Inventory inv(ch); @@ -1134,7 +1139,7 @@ static int chr_equip_slot(lua_State *s) */ static int chr_equip_item(lua_State *s) { - Being *ch = checkCharacter(s, 1); + Entity *ch = checkCharacter(s, 1); ItemClass *it = checkItemClass(s, 2); Inventory inv(ch); @@ -1158,7 +1163,7 @@ static int chr_equip_item(lua_State *s) */ static int chr_unequip_slot(lua_State *s) { - Being *ch = checkCharacter(s, 1); + Entity *ch = checkCharacter(s, 1); int equipmentSlot = luaL_checkint(s, 2); Inventory inv(ch); @@ -1178,7 +1183,7 @@ static int chr_unequip_slot(lua_State *s) */ static int chr_unequip_item(lua_State *s) { - Being *ch = checkCharacter(s, 1); + Entity *ch = checkCharacter(s, 1); ItemClass *it = checkItemClass(s, 2); Inventory inv(ch); @@ -1199,7 +1204,7 @@ static int chr_unequip_item(lua_State *s) */ static int chr_get_quest(lua_State *s) { - Being *q = checkCharacter(s, 1); + Entity *q = checkCharacter(s, 1); const char *name = luaL_checkstring(s, 2); luaL_argcheck(s, name[0] != 0, 2, "empty variable name"); @@ -1228,7 +1233,7 @@ static int chr_get_quest(lua_State *s) */ static int chr_set_quest(lua_State *s) { - Being *q = checkCharacter(s, 1); + Entity *q = checkCharacter(s, 1); const char *name = luaL_checkstring(s, 2); const char *value = luaL_checkstring(s, 3); luaL_argcheck(s, name[0] != 0, 2, "empty variable name"); @@ -1248,7 +1253,7 @@ static int chr_set_quest(lua_State *s) */ static int chr_set_special_recharge_speed(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const int special = checkSpecial(s, 2); const int speed = luaL_checkint(s, 3); @@ -1274,7 +1279,7 @@ static int chr_set_special_recharge_speed(lua_State *s) */ static int chr_get_special_recharge_speed(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const int special = checkSpecial(s, 2); auto *characterComponent = c->getComponent(); @@ -1300,7 +1305,7 @@ static int chr_get_special_recharge_speed(lua_State *s) */ static int chr_set_special_mana(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const int special = checkSpecial(s, 2); const int mana = luaL_checkint(s, 3); if (!c->getComponent()->setSpecialMana(special, mana)) @@ -1324,7 +1329,7 @@ static int chr_set_special_mana(lua_State *s) */ static int chr_get_special_mana(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); auto *characterComponent = c->getComponent(); const int special = checkSpecial(s, 2); SpecialMap::iterator it = characterComponent->findSpecial(special); @@ -1345,17 +1350,22 @@ static int chr_get_special_mana(lua_State *s) */ static int being_walk(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); const int x = luaL_checkint(s, 2); const int y = luaL_checkint(s, 3); - being->setDestination(Point(x, y)); + auto *beingComponent = being->getComponent(); + + beingComponent->setDestination(*being, Point(x, y)); if (lua_gettop(s) >= 4) { - being->setAttribute(ATTR_MOVE_SPEED_TPS, luaL_checknumber(s, 4)); - being->setAttribute(ATTR_MOVE_SPEED_RAW, utils::tpsToRawSpeed( - being->getModifiedAttribute(ATTR_MOVE_SPEED_TPS))); + const double speedTps = luaL_checknumber(s, 4); + beingComponent->setAttribute(*being, ATTR_MOVE_SPEED_TPS, speedTps); + const double modifiedSpeedTps = + beingComponent->getModifiedAttribute(ATTR_MOVE_SPEED_TPS); + beingComponent->setAttribute(*being, ATTR_MOVE_SPEED_RAW, + utils::tpsToRawSpeed(modifiedSpeedTps)); } return 0; @@ -1396,7 +1406,7 @@ static int being_walk(lua_State *s) */ static int being_damage(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); if (!being->canFight()) { @@ -1410,7 +1420,7 @@ static int being_damage(lua_State *s) dmg.cth = luaL_checkint(s, 4); dmg.type = (DamageType)luaL_checkint(s, 5); dmg.element = (Element)luaL_checkint(s, 6); - Being *source = 0; + Entity *source = 0; if (lua_gettop(s) >= 7) { source = checkBeing(s, 7); @@ -1441,15 +1451,16 @@ static int being_damage(lua_State *s) */ static int being_heal(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); if (lua_gettop(s) == 1) // when there is only one argument { - being->heal(); + being->getComponent()->heal(*being); } else { - being->heal(luaL_checkint(s, 2)); + being->getComponent()->heal(*being, + luaL_checkint(s, 2)); } return 0; @@ -1462,8 +1473,8 @@ static int being_heal(lua_State *s) */ static int being_get_name(lua_State *s) { - Being *being = checkBeing(s, 1); - push(s, being->getName()); + Entity *being = checkBeing(s, 1); + push(s, being->getComponent()->getName()); return 1; } @@ -1483,7 +1494,7 @@ static int being_get_name(lua_State *s) */ static int being_type(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); lua_pushinteger(s, being->getType()); return 1; } @@ -1503,8 +1514,8 @@ static int being_type(lua_State *s) */ static int being_get_action(lua_State *s) { - Being *being = checkBeing(s, 1); - lua_pushinteger(s, being->getAction()); + Entity *being = checkBeing(s, 1); + lua_pushinteger(s, being->getComponent()->getAction()); return 1; } @@ -1515,9 +1526,10 @@ static int being_get_action(lua_State *s) */ static int being_set_action(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); int act = luaL_checkint(s, 2); - being->setAction((BeingAction) act); + being->getComponent()->setAction(*being, + (BeingAction) act); return 0; } @@ -1536,8 +1548,8 @@ static int being_set_action(lua_State *s) */ static int being_get_direction(lua_State *s) { - Being *being = checkBeing(s, 1); - lua_pushinteger(s, being->getDirection()); + Entity *being = checkBeing(s, 1); + lua_pushinteger(s, being->getComponent()->getDirection()); return 1; } @@ -1549,9 +1561,9 @@ static int being_get_direction(lua_State *s) */ static int being_set_direction(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); BeingDirection dir = (BeingDirection) luaL_checkint(s, 2); - being->setDirection(dir); + being->getComponent()->setDirection(*being, dir); return 0; } @@ -1570,7 +1582,7 @@ static int being_set_direction(lua_State *s) */ static int being_set_walkmask(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); const char *stringMask = luaL_checkstring(s, 2); unsigned char mask = 0x00; if (strchr(stringMask, 'w')) @@ -1579,7 +1591,7 @@ static int being_set_walkmask(lua_State *s) mask |= Map::BLOCKMASK_CHARACTER; else if (strchr(stringMask, 'm')) mask |= Map::BLOCKMASK_MONSTER; - being->setWalkMask(mask); + static_cast(being)->setWalkMask(mask); return 0; } @@ -1591,8 +1603,8 @@ static int being_set_walkmask(lua_State *s) */ static int being_get_walkmask(lua_State *s) { - Being *being = checkBeing(s, 1); - const unsigned char mask = being->getWalkMask(); + Entity *being = checkBeing(s, 1); + const unsigned char mask = static_cast(being)->getWalkMask(); luaL_Buffer buffer; luaL_buffinit(s, &buffer); if (mask & Map::BLOCKMASK_WALL) @@ -1616,7 +1628,7 @@ static int being_get_walkmask(lua_State *s) */ static int chr_warp(lua_State *s) { - Being *q = checkCharacter(s, 1); + Entity *q = checkCharacter(s, 1); int x = luaL_checkint(s, 3); int y = luaL_checkint(s, 4); @@ -1670,8 +1682,8 @@ static int chr_warp(lua_State *s) */ static int posX(lua_State *s) { - Being *being = checkBeing(s, 1); - lua_pushinteger(s, being->getPosition().x); + Entity *being = checkBeing(s, 1); + lua_pushinteger(s, static_cast(being)->getPosition().x); return 1; } @@ -1683,8 +1695,8 @@ static int posX(lua_State *s) */ static int posY(lua_State *s) { - Being *being = checkBeing(s, 1); - lua_pushinteger(s, being->getPosition().y); + Entity *being = checkBeing(s, 1); + lua_pushinteger(s, static_cast(being)->getPosition().y); return 1; } @@ -1696,11 +1708,12 @@ static int posY(lua_State *s) */ static int being_get_base_attribute(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); int attr = luaL_checkint(s, 2); luaL_argcheck(s, attr > 0, 2, "invalid attribute id"); - lua_pushinteger(s, being->getAttributeBase(attr)); + lua_pushinteger(s, being->getComponent() + ->getAttributeBase(attr)); return 1; } @@ -1711,11 +1724,11 @@ static int being_get_base_attribute(lua_State *s) */ static int being_set_base_attribute(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); int attr = luaL_checkint(s, 2); double value = luaL_checknumber(s, 3); - being->setAttribute(attr, value); + being->getComponent()->setAttribute(*being, attr, value); return 0; } @@ -1740,11 +1753,13 @@ static int being_set_base_attribute(lua_State *s) */ static int being_get_modified_attribute(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); int attr = luaL_checkint(s, 2); luaL_argcheck(s, attr > 0, 2, "invalid attribute id"); - lua_pushinteger(s, being->getModifiedAttribute(attr)); + const double value = + being->getComponent()->getModifiedAttribute(attr); + lua_pushinteger(s, value); return 1; } @@ -1766,14 +1781,16 @@ static int being_get_modified_attribute(lua_State *s) */ static int being_apply_attribute_modifier(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); int attr = luaL_checkint(s,2); double value = luaL_checknumber(s, 3); int layer = luaL_checkint(s, 4); int duration = luaL_optint(s, 5, 0); int effectId = luaL_optint(s, 6, 0); - being->applyModifier(attr, value, layer, duration, effectId); + being->getComponent()->applyModifier(*being, attr, value, + layer, duration, + effectId); return 0; } @@ -1785,13 +1802,14 @@ static int being_apply_attribute_modifier(lua_State *s) */ static int being_remove_attribute_modifier(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); int attr = luaL_checkint(s, 2); double value = luaL_checknumber(s, 3); int layer = luaL_checkint(s, 4); int effectId = luaL_optint(s, 5, 0); - being->removeModifier(attr, value, layer, effectId); + being->getComponent()->removeModifier(*being, attr, value, + layer, effectId); return 0; } @@ -1807,8 +1825,8 @@ static int being_remove_attribute_modifier(lua_State *s) */ static int being_get_gender(lua_State *s) { - Being *b = checkBeing(s, 1); - lua_pushinteger(s, b->getGender()); + Entity *b = checkBeing(s, 1); + lua_pushinteger(s, b->getComponent()->getGender()); return 1; } @@ -1825,9 +1843,9 @@ static int being_get_gender(lua_State *s) */ static int being_set_gender(lua_State *s) { - Being *b = checkBeing(s, 1); + Entity *b = checkBeing(s, 1); const int gender = luaL_checkinteger(s, 2); - b->setGender(getGender(gender)); + b->getComponent()->setGender(getGender(gender)); return 0; } @@ -1844,7 +1862,7 @@ static int being_set_gender(lua_State *s) */ static int chr_get_level(lua_State *s) { - Being *ch = checkCharacter(s, 1); + Entity *ch = checkCharacter(s, 1); auto *characterComponent = ch->getComponent(); if (lua_gettop(s) > 1) { @@ -1870,7 +1888,7 @@ static int chr_get_level(lua_State *s) */ static int chr_get_exp(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); int skill = checkSkill(s, 2); const int exp = c->getComponent()->getExperience(skill); @@ -1890,7 +1908,7 @@ static int chr_get_exp(lua_State *s) */ static int chr_give_exp(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); int skill = checkSkill(s, 2); const int exp = luaL_checkint(s, 3); const int optimalLevel = luaL_optint(s, 4, 0); @@ -1920,7 +1938,7 @@ static int exp_for_level(lua_State *s) */ static int chr_get_hair_color(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); lua_pushinteger(s, c->getComponent()->getHairColor()); return 1; @@ -1933,12 +1951,12 @@ static int chr_get_hair_color(lua_State *s) */ static int chr_set_hair_color(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const int color = luaL_checkint(s, 2); luaL_argcheck(s, color >= 0, 2, "invalid color id"); c->getComponent()->setHairColor(color); - c->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); + static_cast(c)->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); return 0; } @@ -1950,7 +1968,7 @@ static int chr_set_hair_color(lua_State *s) */ static int chr_get_hair_style(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); lua_pushinteger(s, c->getComponent()->getHairStyle()); return 1; @@ -1963,12 +1981,12 @@ static int chr_get_hair_style(lua_State *s) */ static int chr_set_hair_style(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const int style = luaL_checkint(s, 2); luaL_argcheck(s, style >= 0, 2, "invalid style id"); c->getComponent()->setHairStyle(style); - c->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); + static_cast(c)->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); return 0; } @@ -1983,7 +2001,7 @@ static int chr_set_hair_style(lua_State *s) */ static int chr_get_kill_count(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); MonsterClass *monster = checkMonsterClass(s, 2); lua_pushinteger(s, c->getComponent()->getKillCount(monster->getId())); @@ -1997,7 +2015,7 @@ static int chr_get_kill_count(lua_State *s) */ static int chr_get_rights(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); lua_pushinteger(s, c->getComponent()->getAccountLevel()); return 1; @@ -2010,7 +2028,7 @@ static int chr_get_rights(lua_State *s) */ static int chr_kick(lua_State *s) { - Being *ch = checkCharacter(s, 1); + Entity *ch = checkCharacter(s, 1); MessageOut kickmsg(GPMSG_CONNECT_RESPONSE); kickmsg.writeInt8(ERRMSG_ADMINISTRATIVE_LOGOFF); ch->getComponent()->getClient()->disconnect(kickmsg); @@ -2025,7 +2043,7 @@ static int chr_kick(lua_State *s) */ static int being_get_mapid(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); if (MapComposite *map = being->getMap()) lua_pushinteger(s, map->getID()); else @@ -2043,7 +2061,7 @@ static int being_get_mapid(lua_State *s) */ static int chr_request_quest(lua_State *s) { - Being *ch = checkCharacter(s, 1); + Entity *ch = checkCharacter(s, 1); const char *name = luaL_checkstring(s, 2); luaL_argcheck(s, name[0] != 0, 2, "empty variable name"); luaL_checktype(s, 3, LUA_TFUNCTION); @@ -2082,7 +2100,7 @@ static int chr_request_quest(lua_State *s) */ static int chr_try_get_quest(lua_State *s) { - Being *q = checkCharacter(s, 1); + Entity *q = checkCharacter(s, 1); const char *name = luaL_checkstring(s, 2); luaL_argcheck(s, name[0] != 0, 2, "empty variable name"); @@ -2106,7 +2124,7 @@ static int get_character_by_name(lua_State *s) { const char *name = luaL_checkstring(s, 1); - Being *ch = gameHandler->getCharacterByNameSlow(name); + Entity *ch = gameHandler->getCharacterByNameSlow(name); if (!ch) lua_pushnil(s); else @@ -2122,7 +2140,7 @@ static int get_character_by_name(lua_State *s) */ static int chr_get_post(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); Script *script = getScript(s); Script::Thread *thread = checkCurrentThread(s, script); @@ -2145,10 +2163,11 @@ static int chr_get_post(lua_State *s) */ static int being_register(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); Script *script = getScript(s); - being->signal_died.connect(sigc::mem_fun(script, &Script::processDeathEvent)); + being->getComponent()->signal_died.connect( + sigc::mem_fun(script, &Script::processDeathEvent)); being->signal_removed.connect(sigc::mem_fun(script, &Script::processRemoveEvent)); return 0; @@ -2161,7 +2180,7 @@ static int being_register(lua_State *s) */ static int chr_shake_screen(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const int x = luaL_checkint(s, 2); const int y = luaL_checkint(s, 3); @@ -2187,7 +2206,7 @@ static int chr_shake_screen(lua_State *s) */ static int chr_create_text_particle(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const char *text = luaL_checkstring(s, 2); MessageOut msg(GPMSG_CREATE_TEXT_PARTICLE); @@ -2205,7 +2224,7 @@ static int chr_create_text_particle(lua_State *s) static int chr_give_special(lua_State *s) { // cost_type is ignored until we have more than one cost type - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const int special = checkSpecial(s, 2); const int currentMana = luaL_optint(s, 3, 0); @@ -2220,7 +2239,7 @@ static int chr_give_special(lua_State *s) */ static int chr_has_special(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const int special = luaL_checkint(s, 2); lua_pushboolean(s, c->getComponent()->hasSpecial( @@ -2238,7 +2257,7 @@ static int chr_has_special(lua_State *s) */ static int chr_take_special(lua_State *s) { - Being *c = checkCharacter(s, 1); + Entity *c = checkCharacter(s, 1); const int special = luaL_checkint(s, 2); lua_pushboolean(s, c->getComponent()->hasSpecial( @@ -2258,7 +2277,7 @@ static int chr_take_special(lua_State *s) */ static int monster_get_id(lua_State *s) { - Being *monster = checkMonster(s, 1); + Entity *monster = checkMonster(s, 1); MonsterComponent *monsterComponent = monster->getComponent(); lua_pushinteger(s, monsterComponent->getSpecy()->getId()); @@ -2273,8 +2292,8 @@ static int monster_get_id(lua_State *s) */ static int monster_change_anger(lua_State *s) { - Being *monster = checkMonster(s, 1); - Being *being = checkBeing(s, 2); + Entity *monster = checkMonster(s, 1); + Entity *being = checkBeing(s, 2); const int anger = luaL_checkint(s, 3); monster->getComponent()->changeAnger(being, anger); return 0; @@ -2287,8 +2306,8 @@ static int monster_change_anger(lua_State *s) */ static int monster_drop_anger(lua_State *s) { - Being *monster = checkMonster(s, 1); - Being *being = checkBeing(s, 2); + Entity *monster = checkMonster(s, 1); + Entity *being = checkBeing(s, 2); monster->getComponent()->forgetTarget(being); return 0; } @@ -2301,7 +2320,7 @@ static int monster_drop_anger(lua_State *s) */ static int monster_get_angerlist(lua_State *s) { - Being *monster = checkMonster(s, 1); + Entity *monster = checkMonster(s, 1); MonsterComponent *monsterComponent = monster->getComponent(); pushSTLContainer(s, monsterComponent->getAngerList()); @@ -2320,11 +2339,11 @@ static int monster_get_angerlist(lua_State *s) */ static int being_apply_status(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); const int id = luaL_checkint(s, 2); const int time = luaL_checkint(s, 3); - being->applyStatusEffect(id, time); + being->getComponent()->applyStatusEffect(id, time); return 0; } @@ -2335,10 +2354,10 @@ static int being_apply_status(lua_State *s) */ static int being_remove_status(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); const int id = luaL_checkint(s, 2); - being->removeStatusEffect(id); + being->getComponent()->removeStatusEffect(id); return 0; } @@ -2349,10 +2368,11 @@ static int being_remove_status(lua_State *s) */ static int being_has_status(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); const int id = luaL_checkint(s, 2); - lua_pushboolean(s, being->hasStatusEffect(id)); + lua_pushboolean(s, being->getComponent() + ->hasStatusEffect(id)); return 1; } @@ -2363,10 +2383,11 @@ static int being_has_status(lua_State *s) */ static int being_get_status_time(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); const int id = luaL_checkint(s, 2); - lua_pushinteger(s, being->getStatusEffectTime(id)); + lua_pushinteger(s, being->getComponent() + ->getStatusEffectTime(id)); return 1; } @@ -2377,11 +2398,11 @@ static int being_get_status_time(lua_State *s) */ static int being_set_status_time(lua_State *s) { - Being *being = checkBeing(s, 1); + Entity *being = checkBeing(s, 1); const int id = luaL_checkint(s, 2); const int time = luaL_checkint(s, 3); - being->setStatusEffectTime(id, time); + being->getComponent()->setStatusEffectTime(id, time); return 0; } @@ -2664,8 +2685,8 @@ static int get_beings_in_circle(lua_State *s) int x, y, r; if (lua_islightuserdata(s, 1)) { - Being *b = checkBeing(s, 1); - const Point &pos = b->getPosition(); + Entity *b = checkBeing(s, 1); + const Point &pos = static_cast(b)->getPosition(); x = pos.x; y = pos.y; r = luaL_checkint(s, 2); @@ -2685,11 +2706,13 @@ static int get_beings_in_circle(lua_State *s) int tableIndex = 1; for (BeingIterator i(m->getAroundPointIterator(Point(x, y), r)); i; ++i) { - Being *b = *i; + Entity *b = *i; char t = b->getType(); if (t == OBJECT_NPC || t == OBJECT_CHARACTER || t == OBJECT_MONSTER) { - if (Collision::circleWithCircle(b->getPosition(), b->getSize(), + Actor *actor = static_cast(b); + if (Collision::circleWithCircle(actor->getPosition(), + actor->getSize(), Point(x, y), r)) { lua_pushlightuserdata(s, b); @@ -2724,10 +2747,10 @@ static int get_beings_in_rectangle(lua_State *s) Rectangle rect = {x, y ,w, h}; for (BeingIterator i(m->getInsideRectangleIterator(rect)); i; ++i) { - Being *b = *i; + Entity *b = *i; char t = b->getType(); if ((t == OBJECT_NPC || t == OBJECT_CHARACTER || t == OBJECT_MONSTER) && - rect.contains(b->getPosition())) + rect.contains(static_cast(b)->getPosition())) { lua_pushlightuserdata(s, b); lua_rawseti(s, tableStackPosition, tableIndex); @@ -2749,8 +2772,8 @@ static int get_distance(lua_State *s) int x1, y1, x2, y2; if (lua_gettop(s) == 2) { - Being *being1 = checkBeing(s, 1); - Being *being2 = checkBeing(s, 2); + Actor *being1 = static_cast(checkBeing(s, 1)); + Actor *being2 = static_cast(checkBeing(s, 2)); x1 = being1->getPosition().x; y1 = being1->getPosition().y; diff --git a/src/scripting/luascript.cpp b/src/scripting/luascript.cpp index 328ae8ce..83ac36bc 100644 --- a/src/scripting/luascript.cpp +++ b/src/scripting/luascript.cpp @@ -248,7 +248,7 @@ void LuaScript::load(const char *prog, const char *name, mContext = previousContext; } -void LuaScript::processDeathEvent(Being *entity) +void LuaScript::processDeathEvent(Entity *entity) { if (mDeathNotificationCallback.isValid()) { @@ -275,7 +275,7 @@ void LuaScript::processRemoveEvent(Entity *entity) /** * Called when the server has recovered the value of a quest variable. */ -void LuaScript::getQuestCallback(Being *q, +void LuaScript::getQuestCallback(Entity *q, const std::string &value, Script *script) { @@ -292,7 +292,7 @@ void LuaScript::getQuestCallback(Being *q, /** * Called when the server has recovered the post for a user. */ -void LuaScript::getPostCallback(Being *q, +void LuaScript::getPostCallback(Entity *q, const std::string &sender, const std::string &letter, Script *script) diff --git a/src/scripting/luascript.h b/src/scripting/luascript.h index b7bdde1e..b874976a 100644 --- a/src/scripting/luascript.h +++ b/src/scripting/luascript.h @@ -69,16 +69,16 @@ class LuaScript : public Script void unref(Ref &ref); - static void getQuestCallback(Being *, + static void getQuestCallback(Entity *, const std::string &value, Script *); - static void getPostCallback(Being *, + static void getPostCallback(Entity *, const std::string &sender, const std::string &letter, Script *); - void processDeathEvent(Being *entity); + void processDeathEvent(Entity *entity); void processRemoveEvent(Entity *entity); diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp index f835be81..261acd16 100644 --- a/src/scripting/luautil.cpp +++ b/src/scripting/luautil.cpp @@ -121,21 +121,21 @@ Script *getScript(lua_State *s) valid in the map. TODO: do it. */ -Being *getBeing(lua_State *s, int p) +Entity *getBeing(lua_State *s, int p) { if (!lua_islightuserdata(s, p)) return 0; - return static_cast(lua_touserdata(s, p)); + return static_cast(lua_touserdata(s, p)); } -Being *getCharacter(lua_State *s, int p) +Entity *getCharacter(lua_State *s, int p) { if (!lua_islightuserdata(s, p)) return 0; Entity *t = static_cast(lua_touserdata(s, p)); if (t->getType() != OBJECT_CHARACTER) return 0; - return static_cast(t); + return static_cast(t); } ItemClass *getItemClass(lua_State *s, int p) @@ -158,14 +158,14 @@ ItemClass *getItemClass(lua_State *s, int p) return itemClass; } -Being *getMonster(lua_State *s, int p) +Entity *getMonster(lua_State *s, int p) { if (!lua_islightuserdata(s, p)) return 0; Entity *t = static_cast(lua_touserdata(s, p)); if (t->getType() != OBJECT_MONSTER) return 0; - return static_cast(t); + return t; } MonsterClass *getMonsterClass(lua_State *s, int p) @@ -188,27 +188,27 @@ MonsterClass *getMonsterClass(lua_State *s, int p) return monsterClass; } -Being *getNpc(lua_State *s, int p) +Entity *getNpc(lua_State *s, int p) { if (!lua_islightuserdata(s, p)) return 0; Entity *t = static_cast(lua_touserdata(s, p)); if (t->getType() != OBJECT_NPC) return 0; - return static_cast(t); + return t; } -Being *checkBeing(lua_State *s, int p) +Entity *checkBeing(lua_State *s, int p) { - Being *being = getBeing(s, p); + Entity *being = getBeing(s, p); luaL_argcheck(s, being, p, "being expected"); return being; } -Being *checkCharacter(lua_State *s, int p) +Entity *checkCharacter(lua_State *s, int p) { - Being *character = getCharacter(s, p); + Entity *character = getCharacter(s, p); luaL_argcheck(s, character, p, "character expected"); return character; } @@ -220,9 +220,9 @@ ItemClass *checkItemClass(lua_State *s, int p) return itemClass; } -Being *checkMonster(lua_State *s, int p) +Entity *checkMonster(lua_State *s, int p) { - Being *monster = getMonster(s, p); + Entity *monster = getMonster(s, p); luaL_argcheck(s, monster, p, "monster expected"); return monster; } @@ -234,9 +234,9 @@ MonsterClass *checkMonsterClass(lua_State *s, int p) return monsterClass; } -Being *checkNpc(lua_State *s, int p) +Entity *checkNpc(lua_State *s, int p) { - Being *npc = getNpc(s, p); + Entity *npc = getNpc(s, p); luaL_argcheck(s, npc, p, "npc expected"); return npc; } diff --git a/src/scripting/luautil.h b/src/scripting/luautil.h index bf335d20..1bc02935 100644 --- a/src/scripting/luautil.h +++ b/src/scripting/luautil.h @@ -37,7 +37,6 @@ extern "C" { #include "game-server/attack.h" #include "game-server/specialmanager.h" -class Being; class CharacterComponent; class Entity; class ItemClass; @@ -165,19 +164,19 @@ typedef LuaUserData LuaSpecialInfo; Script * getScript(lua_State *s); -Being * getBeing(lua_State *s, int p); -Being * getCharacter(lua_State *s, int p); +Entity * getBeing(lua_State *s, int p); +Entity * getCharacter(lua_State *s, int p); ItemClass * getItemClass(lua_State *s, int p); -Being * getMonster(lua_State *s, int p); +Entity * getMonster(lua_State *s, int p); MonsterClass * getMonsterClass(lua_State *s, int p); -Being * getNpc(lua_State *s, int p); +Entity * getNpc(lua_State *s, int p); -Being * checkBeing(lua_State *s, int p); -Being * checkCharacter(lua_State *s, int p); +Entity * checkBeing(lua_State *s, int p); +Entity * checkCharacter(lua_State *s, int p); ItemClass * checkItemClass(lua_State *s, int p); -Being * checkMonster(lua_State *s, int p); +Entity * checkMonster(lua_State *s, int p); MonsterClass * checkMonsterClass(lua_State *s, int p); -Being * checkNpc(lua_State *s, int p); +Entity * checkNpc(lua_State *s, int p); int checkSkill(lua_State *s, int p); int checkSpecial(lua_State *s, int p); diff --git a/src/scripting/script.h b/src/scripting/script.h index 574d1b9b..694deed6 100644 --- a/src/scripting/script.h +++ b/src/scripting/script.h @@ -31,7 +31,6 @@ #include -class Being; class MapComposite; class Entity; @@ -238,7 +237,7 @@ class Script : public sigc::trackable const Context *getContext() const { return mContext; } - virtual void processDeathEvent(Being *entity) = 0; + virtual void processDeathEvent(Entity *entity) = 0; virtual void processRemoveEvent(Entity *entity) = 0; diff --git a/src/scripting/scriptmanager.cpp b/src/scripting/scriptmanager.cpp index 39a1a6a5..ee231611 100644 --- a/src/scripting/scriptmanager.cpp +++ b/src/scripting/scriptmanager.cpp @@ -49,7 +49,7 @@ Script *ScriptManager::currentState() return _currentState; } -bool ScriptManager::performCraft(Being *crafter, +bool ScriptManager::performCraft(Entity *crafter, const std::list &recipe) { if (!_craftCallback.isValid()) diff --git a/src/scripting/scriptmanager.h b/src/scripting/scriptmanager.h index 03b6e64b..14b01b62 100644 --- a/src/scripting/scriptmanager.h +++ b/src/scripting/scriptmanager.h @@ -55,7 +55,7 @@ bool loadMainScript(const std::string &file); */ Script *currentState(); -bool performCraft(Being *crafter, const std::list &recipe); +bool performCraft(Entity *crafter, const std::list &recipe); void setCraftCallback(Script *script); void setSpecialCallback(Script *script); -- cgit v1.2.3-70-g09d2 From 9e6a0f98ecb52e04ab5afce817cb1d7fe2076450 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Thu, 11 Apr 2013 11:10:47 +0200 Subject: Moved Actor into an Component This was the final step to remove the hierachy with Entity on the top. --- src/game-server/accountconnection.cpp | 3 +- src/game-server/actor.cpp | 36 +++++++------ src/game-server/actor.h | 21 ++++---- src/game-server/attack.h | 3 +- src/game-server/being.cpp | 83 +++++++++++----------------- src/game-server/being.h | 2 +- src/game-server/buysell.cpp | 9 ++-- src/game-server/buysell.h | 7 ++- src/game-server/character.cpp | 19 +++---- src/game-server/character.h | 34 ++++++------ src/game-server/combatcomponent.cpp | 27 ++++++---- src/game-server/combatcomponent.h | 13 +++-- src/game-server/commandhandler.cpp | 35 ++++++------ src/game-server/component.h | 5 +- src/game-server/effect.cpp | 17 +++--- src/game-server/effect.h | 3 +- src/game-server/entity.h | 6 ++- src/game-server/gamehandler.cpp | 90 ++++++++++++++++--------------- src/game-server/inventory.cpp | 4 +- src/game-server/item.cpp | 10 ++-- src/game-server/item.h | 2 +- src/game-server/mapcomposite.cpp | 63 ++++++++++++---------- src/game-server/mapcomposite.h | 31 ++++++----- src/game-server/monster.cpp | 87 +++++++++++++++--------------- src/game-server/monster.h | 2 +- src/game-server/npc.cpp | 5 +- src/game-server/spawnareacomponent.cpp | 8 +-- src/game-server/state.cpp | 92 +++++++++++++++++--------------- src/game-server/state.h | 9 ++-- src/game-server/trade.cpp | 4 +- src/game-server/triggerareacomponent.cpp | 12 +++-- src/game-server/triggerareacomponent.h | 10 ++-- src/scripting/lua.cpp | 85 +++++++++++++++-------------- 33 files changed, 429 insertions(+), 408 deletions(-) (limited to 'src/game-server/commandhandler.cpp') 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 -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 #include #include @@ -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(entity); - mEmoteId = id; if (id > -1) - actor.raiseUpdateFlags(UPDATEFLAG_EMOTE); + entity.getComponent()->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(entity); - if (mAction == DEAD) return; - LOG_DEBUG("Being " << actor.getPublicID() << " died."); + LOG_DEBUG("Being " << entity.getComponent()->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(entity); - mDst = dst; - actor.raiseUpdateFlags(UPDATEFLAG_NEW_DESTINATION); + entity.getComponent()->raiseUpdateFlags( + UPDATEFLAG_NEW_DESTINATION); mPath.clear(); } void BeingComponent::clearDestination(Entity &entity) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast(entity); - - setDestination(entity, actor.getPosition()); + setDestination(entity, + entity.getComponent()->getPosition()); } void BeingComponent::setDirection(Entity &entity, BeingDirection direction) { - // Temponary until all dependencies are available as components - Actor &actor = static_cast(entity); mDirection = direction; - actor.raiseUpdateFlags(UPDATEFLAG_DIRCHANGE); + entity.getComponent()->raiseUpdateFlags( + UPDATEFLAG_DIRCHANGE); } Path BeingComponent::findPath(Entity &entity) { - // Temporary until all depdencies are available as component - Actor &actor = static_cast(entity); + auto *actorComponent = entity.getComponent(); 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(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()->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()->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()->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()->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(entity); - mAction = action; if (action != ATTACK && // The players are informed about these actions action != WALK) // by other messages { - actor.raiseUpdateFlags(UPDATEFLAG_ACTIONCHANGE); + entity.getComponent()->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(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()->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(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()->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(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()->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 -BuySell::BuySell(Actor *c, bool sell): +BuySell::BuySell(Entity *c, bool sell): mCurrencyId(ATTR_GP), mChar(c), mSell(sell) { c->getComponent()->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()->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()->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 -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(entity); - - mCharacterData = new CharacterData(&being, this); + mCharacterData = new CharacterData(&entity, this); auto *beingComponent = entity.getComponent(); @@ -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->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 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()->setGender(gender); + mEntity->getComponent()->setGender(gender); } inline BeingGender CharacterData::getGender() const { - return mActor->getComponent()->getGender(); + return mEntity->getComponent()->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()->setPosition(*mEntity, point); } inline const Point &CharacterData::getPosition() const { - return mActor->getPosition(); + return mEntity->getComponent()->getPosition(); } inline void CharacterData::setAttribute(int id, int base) { - mActor->getComponent()->setAttribute(*mActor, id, base); + mEntity->getComponent()->setAttribute(*mEntity, id, base); } inline void CharacterData::setModAttribute(int id, int mod) { - mActor->getComponent()->setModAttribute(id, mod); + mEntity->getComponent()->setModAttribute(id, mod); } inline const AttributeMap &CharacterData::getAttributes() const { - return mActor->getComponent()->getAttributes(); + return mEntity->getComponent()->getAttributes(); } inline void CharacterData::setCharacterPoints(int characterPoints) @@ -711,22 +711,22 @@ inline const std::map::const_iterator CharacterData::getSkillEnd() con inline void CharacterData::applyStatusEffect(int status, int time) { - mActor->getComponent()->applyStatusEffect(status, time); + mEntity->getComponent()->applyStatusEffect(status, time); } inline int CharacterData::getStatusEffectSize() const { - return mActor->getComponent()->getStatusEffects().size(); + return mEntity->getComponent()->getStatusEffects().size(); } inline const std::map::const_iterator CharacterData::getStatusEffectBegin() const { - return mActor->getComponent()->getStatusEffects().begin(); + return mEntity->getComponent()->getStatusEffects().begin(); } inline const std::map::const_iterator CharacterData::getStatusEffectEnd() const { - return mActor->getComponent()->getStatusEffects().end(); + return mEntity->getComponent()->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(entity); - auto *beingComponent = entity.getComponent(); if (beingComponent->getAction() != ATTACK || !mTarget) @@ -69,12 +64,18 @@ void CombatComponent::update(Entity &entity) for (std::vector::const_iterator it = attacksReady.begin(), it_end = attacksReady.end(); it != it_end; ++it) { + const Point &attackerPosition = + entity.getComponent()->getPosition(); + const Point &targetPosition = + mTarget->getComponent()->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()->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()->getPosition(); + beingComponent->setDestination(entity, point); // TODO: Turn into direction of enemy - actor.raiseUpdateFlags(UPDATEFLAG_ATTACK); + entity.getComponent()->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(target).getPublicID() + LOG_DEBUG("Being " + << target.getComponent()->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 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(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(player)->getPosition(), - ic, amount); + const Point &position = + player->getComponent()->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(player)->getPosition(); + const Point &pos = player->getComponent()->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(other)->getPosition(); + const Point &pos = other->getComponent()->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(player)->getPosition(); + const Point &pos = player->getComponent()->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(player); + const Point &position = + player->getComponent()->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(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(other)->getPosition(); + const Point &pos = other->getComponent()->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(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(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 + 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(&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()->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 signal_inserted; sigc::signal signal_removed; + sigc::signal signal_map_changed; private: MapComposite *mMap; /**< Map the entity is on */ @@ -91,7 +92,6 @@ inline EntityType Entity::getType() const template 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()->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()->getPublicID() != id) continue; - return ppos.inRangeOf(a->getPosition(), pixelDist) ? a : 0; + return ppos.inRangeOf(a->getComponent()->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()->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(*i); - if (b->getPublicID() != id) + Entity *b = *i; + if (b->getComponent()->getPublicID() != id) continue; - return ppos.inRangeOf(b->getPosition(), pixelDist) ? b : 0; + return ppos.inRangeOf(b->getComponent()->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()->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(*i); - if (c->getPublicID() != id) + Entity *c = *i; + if (c->getComponent()->getPublicID() != id) continue; - if (ppos.inRangeOf(c->getPosition(), pixelDist)) + if (ppos.inRangeOf(c->getComponent()->getPosition(), + pixelDist)) return c; return 0; @@ -455,11 +458,11 @@ void GameHandler::handleSay(GameClient &client, MessageIn &message) } if (!client.character->getComponent()->isMuted()) { - GameState::sayAround(static_cast(client.character), say); + GameState::sayAround(client.character, say); } else { - GameState::sayTo(static_cast(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(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(client.character)->getPosition(); + const Point ppos = + client.character->getComponent()->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(o)->getPosition(); + Point opos = o->getComponent()->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(client.character)->getPosition(); + const Point &pos = client.character->getComponent() + ->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(client.character); - LOG_DEBUG("Character " << actor->getPublicID() - << " attacked being " << id); + const int publicId = + client.character->getComponent()->getPublicID(); + LOG_DEBUG("Character " << publicId << " attacked being " << id); - Actor *being = static_cast(findBeingNear(actor, id)); + Entity *being = findBeingNear(client.character, id); if (being && being->getType() != OBJECT_NPC) { client.character->getComponent()->setTarget(being); - client.character->getComponent()->setAction(*actor, - ATTACK); + client.character->getComponent()->setAction( + *client.character, ATTACK); } } @@ -688,14 +693,15 @@ void GameHandler::handleUseSpecialOnBeing(GameClient &client, MessageIn &message if (client.character->getComponent()->getAction() == DEAD) return; - Actor *actor = static_cast(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()->getPublicID(); + LOG_DEBUG("Character " << publicId << " tries to use his special attack " << specialID); auto *characterComponent = client.character ->getComponent(); @@ -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(client.character)->getPublicID() + const int publicId = + client.character->getComponent()->getPublicID(); + LOG_DEBUG("Character " << publicId << " tries to use his special attack " << specialID); auto *characterComponent = client.character ->getComponent(); @@ -810,7 +817,7 @@ void GameHandler::handleTradeRequest(GameClient &client, MessageIn &message) if (t->request(client.character, id)) return; - Entity *q = findCharacterNear(static_cast(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()->getName() == invitee) { // calculate if the invitee is within the visual range - const int xInviter = - static_cast(client.character)->getPosition().x; - const int yInviter = - static_cast(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(); + auto *inviteeComponent = (*it)->getComponent(); + 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(mCharacter); if (itemManager->isEquipSlotVisible(slotTypeId)) - actor->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); + mCharacter->getComponent()->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(&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(); + 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()->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()->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()->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()->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()->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(*i); - const Point &pos1 = - actor->getComponent()->getOldPosition(); - const Point &pos2 = actor->getPosition(); + (*i)->getComponent()->getOldPosition(); + const Point &pos2 = + (*i)->getComponent()->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(); + auto *beingComponent = entity.getComponent(); - actor.setWalkMask(Map::BLOCKMASK_WALL | Map::BLOCKMASK_CHARACTER); - actor.setBlockType(BLOCKTYPE_MONSTER); + auto *actorComponent = entity.getComponent(); + 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(entity); - auto *beingComponent = entity.getComponent(); // If dead, remove it if (beingComponent->getAction() == DEAD) { if (mDecayTimeout.expired()) - GameState::enqueueRemove(static_cast(&entity)); + GameState::enqueueRemove(&entity); return; } @@ -153,19 +152,20 @@ void MonsterComponent::update(Entity &entity) if (entity.getComponent()->getTarget()) return; + const Point &position = + entity.getComponent()->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(entity); auto *beingComponent = entity.getComponent(); // 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::iterator j = mAttackPositions.begin(); j != mAttackPositions.end(); j++) { - Point attackPosition = target->getPosition(); + Point attackPosition = + target->getComponent()->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()->getPosition(); + const Point &targetPosition = + bestTarget->getComponent()->getPosition(); + entity.getComponent()->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(entity); - - Point thisPos = actor.getPosition(); + Point thisPos = entity.getComponent()->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()->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 MonsterComponent::getAngerList() const void MonsterComponent::monsterDied(Entity *monster) { - // Temporary until all depdencies are available as component - Actor *actor = static_cast(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()->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() - ->startNpcThread(thread, static_cast(npc)->getPublicID()); + auto *actorComponent = npc->getComponent(); + ch->getComponent()->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()->getOldPosition(); - const Point &ppos = p->getPosition(); - int pid = p->getPublicID(), pflags = p->getUpdateFlags(); + const Point &ppos = p->getComponent()->getPosition(); + int pid = p->getComponent()->getPublicID(); + int pflags = p->getComponent()->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()->getOldPosition(); - const Point &opos = o->getPosition(); + const Point &opos = o->getComponent()->getPosition(); int otype = o->getType(); - int oid = o->getPublicID(), oflags = o->getUpdateFlags(); + int oid = o->getComponent()->getPublicID(); + int oflags = o->getComponent()->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()->getParty() == p->getComponent()->getParty()) { - int cflags = c->getUpdateFlags(); + int cflags = c->getComponent()->getUpdateFlags(); if (cflags & UPDATEFLAG_HEALTHCHANGE) { auto *beingComponent = c->getComponent(); MessageOut healthMsg(GPMSG_BEING_HEALTH_CHANGE); - healthMsg.writeInt16(c->getPublicID()); + healthMsg.writeInt16( + c->getComponent()->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(*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()->getPosition(); + int oflags = o->getComponent()->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(); MessageOut effectMsg(GPMSG_CREATE_EFFECT_BEING); effectMsg.writeInt16(e->getEffectId()); - effectMsg.writeInt16(static_cast(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()->clearUpdateFlags(); if (a->canFight()) { a->getComponent()->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()->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()->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()->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()->getPublicID()); + Point objectPos = ptr->getComponent()->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()->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(ptr); - Point pos = actor->getPosition(); + Point pos = ptr->getComponent()->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()->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(ptr); - ptr->setMap(map); - actor->setPosition(point); + ptr->getComponent()->setPosition(*ptr, point); ptr->getComponent()->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(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()->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()->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()->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 -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(c1)->getPublicID()); + msg.writeInt16(c1->getComponent()->getPublicID()); c2->getComponent()->getClient()->send(msg); c1->getComponent()->setTrading(this); c2->getComponent()->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(mChar1)->getPublicID() != id) + mChar1->getComponent()->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 -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 insideNow; + std::set insideNow; for (BeingIterator i(map->getInsideRectangleIterator(mZone)); i; ++i) { // Don't deal with uninitialized actors - if (!(*i) || !(*i)->isPublicIdValid()) + if (!(*i) || !(*i)->getComponent()->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()->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 -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 mInside; + std::set 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()->setEnabled(true); - GameState::enqueueInsert(static_cast(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(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(npc)->getPublicID()); + msg.writeInt16(npc->getComponent()->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(npc)->getPublicID()); + msg.writeInt16(npc->getComponent()->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(npc)->getPublicID()); + msg.writeInt16(npc->getComponent()->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(npc)->getPublicID()); + msg.writeInt16(npc->getComponent()->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(npc)->getPublicID()); + msg.writeInt16(npc->getComponent()->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(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(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(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(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(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(q) - ->getPosition(), - ic, nb); + const Point &position = + q->getComponent()->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(being)->setWalkMask(mask); + being->getComponent()->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(being)->getWalkMask(); + const unsigned char mask = + being->getComponent()->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(being)->getPosition().x); + lua_pushinteger(s, being->getComponent()->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(being)->getPosition().y); + lua_pushinteger(s, being->getComponent()->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()->setHairColor(color); - static_cast(c)->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); + c->getComponent()->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()->setHairStyle(style); - static_cast(c)->raiseUpdateFlags(UPDATEFLAG_LOOKSCHANGE); + c->getComponent()->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(b)->getPosition(); + const Point &pos = b->getComponent()->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(b); - if (Collision::circleWithCircle(actor->getPosition(), - actor->getSize(), + auto *actorComponent = b->getComponent(); + 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(b)->getPosition())) + rect.contains(b->getComponent()->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(checkBeing(s, 1)); - Actor *being2 = static_cast(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()->getPosition().x; + y1 = being1->getComponent()->getPosition().y; + x2 = being2->getComponent()->getPosition().x; + y2 = being2->getComponent()->getPosition().y; } else { -- cgit v1.2.3-70-g09d2