summaryrefslogtreecommitdiffstats
path: root/src/game-server
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2013-04-06 21:36:50 +0200
committerErik Schilling <ablu.erikschilling@googlemail.com>2013-04-11 13:43:00 +0200
commitaa04597c5f8bb806996d604699fc8ebff6d53bdd (patch)
tree20e6a79a873605b62c80011fd5c80351f60df6fb /src/game-server
parentd95fccfca8575d8fb06988e558a338e37776961a (diff)
downloadmanaserv-aa04597c5f8bb806996d604699fc8ebff6d53bdd.tar.gz
manaserv-aa04597c5f8bb806996d604699fc8ebff6d53bdd.tar.xz
manaserv-aa04597c5f8bb806996d604699fc8ebff6d53bdd.zip
Converted the Character class into a component
A CharacterData was created as a proxy class in order to allow using the old serialization method.
Diffstat (limited to 'src/game-server')
-rw-r--r--src/game-server/accountconnection.cpp47
-rw-r--r--src/game-server/accountconnection.h20
-rw-r--r--src/game-server/attack.cpp8
-rw-r--r--src/game-server/attack.h12
-rw-r--r--src/game-server/being.cpp2
-rw-r--r--src/game-server/being.h11
-rw-r--r--src/game-server/buysell.cpp12
-rw-r--r--src/game-server/buysell.h6
-rw-r--r--src/game-server/character.cpp318
-rw-r--r--src/game-server/character.h379
-rw-r--r--src/game-server/combatcomponent.cpp4
-rw-r--r--src/game-server/commandhandler.cpp318
-rw-r--r--src/game-server/commandhandler.h4
-rw-r--r--src/game-server/component.h1
-rw-r--r--src/game-server/gamehandler.cpp181
-rw-r--r--src/game-server/gamehandler.h19
-rw-r--r--src/game-server/inventory.cpp11
-rw-r--r--src/game-server/inventory.h5
-rw-r--r--src/game-server/mapcomposite.cpp4
-rw-r--r--src/game-server/mapcomposite.h6
-rw-r--r--src/game-server/monster.cpp28
-rw-r--r--src/game-server/monster.h10
-rw-r--r--src/game-server/npc.cpp22
-rw-r--r--src/game-server/npc.h10
-rw-r--r--src/game-server/postman.h29
-rw-r--r--src/game-server/quest.cpp46
-rw-r--r--src/game-server/quest.h17
-rw-r--r--src/game-server/state.cpp72
-rw-r--r--src/game-server/state.h6
-rw-r--r--src/game-server/trade.cpp50
-rw-r--r--src/game-server/trade.h16
-rw-r--r--src/game-server/triggerareacomponent.cpp2
32 files changed, 1032 insertions, 644 deletions
diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp
index 44858fc..bdf44b4 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<CharacterComponent>();
+ 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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>();
+ 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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->getDatabaseID());
msg.writeInt16(level);
send(msg);
}
diff --git a/src/game-server/accountconnection.h b/src/game-server/accountconnection.h
index a144a1d..2ad79dd 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 a1300e4..6ca85fb 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<Attack>::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 cecb4fd..348a94b 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<void, Attack &> attack_added;
- sigc::signal<void, Attack &> attack_removed;
+ sigc::signal<void, CombatComponent *, Attack &> attack_added;
+ sigc::signal<void, CombatComponent *, Attack &> attack_removed;
private:
std::vector<Attack> mAttacks;
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp
index 2237f6a..b50a5fa 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 41be5ff..de30ad6 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<void, Being *> signal_died;
+ sigc::signal<void, Being *, unsigned> 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 1e63d52..e73e13c 100644
--- a/src/game-server/buysell.cpp
+++ b/src/game-server/buysell.cpp
@@ -30,15 +30,15 @@
#include <algorithm>
-BuySell::BuySell(Character *c, bool sell):
+BuySell::BuySell(Being *c, bool sell):
mCurrencyId(ATTR_GP), mChar(c), mSell(sell)
{
- c->setBuySell(this);
+ c->getComponent<CharacterComponent>()->setBuySell(this);
}
BuySell::~BuySell()
{
- mChar->setBuySell(NULL);
+ mChar->getComponent<CharacterComponent>()->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<CharacterComponent>();
+ 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<CharacterComponent>()->getClient()->send(msg);
return true;
}
diff --git a/src/game-server/buysell.h b/src/game-server/buysell.h
index 72da2ce..8450aff 100644
--- a/src/game-server/buysell.h
+++ b/src/game-server/buysell.h
@@ -23,7 +23,7 @@
#include <vector>
-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 e52747f..6362149 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -49,30 +49,29 @@
#include <limits.h>
// 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<Being &>(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<Being &>(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<Being &>(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<CombatComponent>()->clearTarget();
+ entity.getComponent<CombatComponent>()->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<Being &>(entity);
+
MessageOut attribMsg(GPMSG_PLAYER_ATTRIBUTE_CHANGE);
for (std::set<size_t>::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<Being &>(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<int, int>::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<int, int>::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<float> levels;
std::map<int, int>::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<Being &>(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 "<<mLevel);
+ gameHandler->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<Being &>(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<Being &>(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<CombatComponent>()->removeAttack(mKnuckleAttackInfo);
+ combatComponent->removeAttack(mKnuckleAttackInfo);
}
-void Character::attackRemoved(Attack &attack)
+void CharacterComponent::attackRemoved(CombatComponent *combatComponent,
+ Attack &attack)
{
// Add knuckle attack
- CombatComponent *combatComponent = getComponent<CombatComponent>();
// 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<Being &>(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 8b015f9..4b5089d 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<unsigned, SpecialValue> 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<int, int>::const_iterator getSkillBegin() const;
+ const std::map<int, int>::const_iterator getSkillEnd() const;
+
+ void applyStatusEffect(int status, int time);
+ int getStatusEffectSize() const;
+ const std::map<int, Status>::const_iterator getStatusEffectBegin() const;
+ const std::map<int, Status>::const_iterator getStatusEffectEnd() const;
+
+ int getKillCountSize() const;
+ const std::map<int, int>::const_iterator getKillCountBegin() const;
+ const std::map<int, int>::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
@@ -292,18 +341,6 @@ class Character : public Being
{ return mExperience.end(); }
/**
- * Used to serialize status effects.
- */
- int getStatusEffectSize() const
- { return mStatusEffects.size(); }
-
- const std::map<int, int>::const_iterator getStatusEffectBegin() const
- { return mStatusEffects.begin(); }
-
- const std::map<int, int>::const_iterator getStatusEffectEnd() const
- { return mStatusEffects.end(); }
-
- /**
* Used to serialize kill count.
*/
int getKillCountSize() const
@@ -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<void, Character *> signal_disconnected;
+ sigc::signal<void, Entity &> 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<int, int> mExperience; /**< experience collected for each skill.*/
SpecialMap mSpecials;
- std::map<int, int> 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<int, int>::const_iterator CharacterData::getSkillBegin() const
+{
+ return mCharacterComponent->getSkillBegin();
+}
+
+inline const std::map<int, int>::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<int, Status>::const_iterator CharacterData::getStatusEffectBegin() const
+{
+ return mBeing->getStatusEffects().begin();
+}
+
+inline const std::map<int, Status>::const_iterator CharacterData::getStatusEffectEnd() const
+{
+ return mBeing->getStatusEffects().end();
+}
+
+inline int CharacterData::getKillCountSize() const
+{
+ return mCharacterComponent->getKillCountSize();
+}
+
+inline const std::map<int, int>::const_iterator CharacterData::getKillCountBegin() const
+{
+ return mCharacterComponent->getKillCountBegin();
+}
+
+inline const std::map<int, int>::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 469569b..d71f86a 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 d38828f..63b960d 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<CharacterComponent>()->getAccountLevel();
str << " ( ";
std::list<std::string> 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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>();
+
// 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<CharacterComponent>();
+
+ 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<CharacterComponent>();
- 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<CharacterComponent>()->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<CharacterComponent>()
+ ->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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>();
+
// 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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->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<InventoryItem> 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 <character>", 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 <character>", 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<CharacterComponent>();
+
say("List of skills of player '" + other->getName() + "':", player);
- std::map<int, int>::const_iterator it = other->getSkillBegin();
- std::map<int, int>::const_iterator it_end = other->getSkillEnd();
+ std::map<int, int>::const_iterator it =
+ characterComponent->getSkillBegin();
+ std::map<int, int>::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<std::string> 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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()
+ ->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<CharacterComponent>();
+
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 5327dda..b5a268f 100644
--- a/src/game-server/commandhandler.h
+++ b/src/game-server/commandhandler.h
@@ -23,14 +23,14 @@
#include <string>
-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 974cad0..45fe742 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 9cec772..55588b6 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<CharacterComponent>()->disconnected(*ch);
delete ch;
}
delete &computer;
}
-void GameHandler::kill(Character *ch)
+void GameHandler::kill(Entity *ch)
{
- GameClient *client = ch->getClient();
+ auto *component = ch->getComponent<CharacterComponent>();
+ 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<CharacterComponent>()->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<CharacterComponent>()
+ ->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<CharacterComponent>()->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<CharacterComponent>();
+
+ 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<CharacterComponent>()->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<CharacterComponent>()
+ ->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<CharacterComponent>()->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<CharacterComponent>()
+ ->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>();
+
+ 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<CharacterComponent>()->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<CharacterComponent>();
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<CharacterComponent>();
+ 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<CharacterComponent>();
+ 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<CharacterComponent>();
+ 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>();
+ 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>();
+ 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<CharacterComponent>();
+
+ 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<CharacterComponent>();
+
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<CharacterComponent>();
+
+ 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<CharacterComponent>();
+
+ 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<CharacterComponent>()
+ ->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<CharacterComponent>();
+
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<CharacterComponent>();
+
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 c05e008..70facb4 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<GameHandler, GameClient *, Character *> mTokenCollector;
+ TokenCollector<GameHandler, GameClient *, Being *> mTokenCollector;
};
extern GameHandler *gameHandler;
diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp
index e14a36a..2219ada 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<CharacterComponent>()->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 42856bf..75336ac 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 bb7093b..e35c68f 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 ba76ddc..c8eb2e8 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 9e45bb1..39b6259 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<Character *, std::set <size_t> > ::iterator iChar;
+ std::map<Being *, std::set <size_t> > ::iterator iChar;
std::set<size_t>::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<size_t> &skillSet = (*iChar).second;
if (mLegalExpReceivers.find(character) == mLegalExpReceivers.end()
|| skillSet.empty())
continue;
+ auto characterComponent =
+ character->getComponent<CharacterComponent>();
+
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<CharacterComponent>()->getParty() ==
+ source->getComponent<CharacterComponent>()->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 d1c8e90..e4d986b 100644
--- a/src/game-server/monster.h
+++ b/src/game-server/monster.h
@@ -33,7 +33,7 @@
#include <sigc++/connection.h>
-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<Character *, std::set <size_t> > mExpReceivers;
+ std::map<Being *, std::set <size_t> > mExpReceivers;
/**
* List of characters who are entitled to receive exp (killsteal
* protection).
*/
- std::set<Character *> mLegalExpReceivers;
+ std::set<Being *> 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 788f0c9..e7a2988 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<CharacterComponent>()->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<NpcComponent>();
@@ -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<CharacterComponent>()
+ ->startNpcThread(thread, npc->getPublicID());
}
}
-void Npc::resume(Character *ch)
+void Npc::resume(Being *ch)
{
if (prepareResume(ch, Script::ThreadPaused))
- ch->resumeNpcThread();
+ ch->getComponent<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->resumeNpcThread();
}
}
diff --git a/src/game-server/npc.h b/src/game-server/npc.h
index 1a0b4e8..63d4ee8 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 b9cf7bb..8862ccf 100644
--- a/src/game-server/postman.h
+++ b/src/game-server/postman.h
@@ -24,12 +24,12 @@
#include <map>
#include <string>
-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<int, Character*>::const_iterator itr = mCharacters.find(id);
+ std::map<int, Being*>::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<int, Character*>::iterator itr = mCharacters.find(player->getDatabaseID());
+ int dataBaseId = player->getComponent<CharacterComponent>()
+ ->getDatabaseID();
+ std::map<int, Being*>::iterator itr = mCharacters.find(dataBaseId);
if (itr == mCharacters.end())
{
- mCharacters.insert(std::pair<int, Character*>(player->getDatabaseID(), player));
+ Being *being = static_cast<Being *>(player);
+ mCharacters.insert(std::pair<int, Being*>(dataBaseId, being));
}
}
- void getPost(Character *player, PostCallback &f)
+ void getPost(Being *player, PostCallback &f)
{
- mCallbacks.insert(std::pair<Character*, PostCallback>(player, f));
+ mCallbacks.insert(std::pair<Being*, PostCallback>(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<Character*, PostCallback>::iterator itr = mCallbacks.find(player);
+ std::map<Being*, PostCallback>::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<int, Character*> mCharacters;
- std::map<Character*, PostCallback> mCallbacks;
+ std::map<int, Being*> mCharacters;
+ std::map<Being*, PostCallback> mCallbacks;
};
extern PostMan *postMan;
diff --git a/src/game-server/quest.cpp b/src/game-server/quest.cpp
index d6d7d92..803ec60 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<CharacterComponent>()->questCache.find(name);
+ if (i == ch->getComponent<CharacterComponent>()->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<CharacterComponent>();
+
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<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>();
+
+ assert(characterComponent->questCache.find(name) ==
+ characterComponent->questCache.end());
+ int id = ch->getComponent<CharacterComponent>()->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>();
+ 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 0d13078..13f91cc 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 74bd87e..f1ed99a 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<CharacterComponent>()
+ ->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<Character * >(o);
- serializeLooks(c, LooksMsg);
- LooksMsg.writeInt16(c->getHairStyle());
- LooksMsg.writeInt16(c->getHairColor());
- LooksMsg.writeInt16(c->getGender());
+ serializeLooks(o, LooksMsg);
+ auto *characterComponent =
+ o->getComponent<CharacterComponent>();
+ 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<CharacterComponent>();
+ 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<CharacterComponent>()->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<CharacterComponent>()->getParty() ==
+ p->getComponent<CharacterComponent>()->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<CharacterComponent>()->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<Being *>(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<CharacterComponent>()
+ ->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>();
+ 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<CharacterComponent>();
+
// 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<CharacterComponent>()->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 e8ed30a..512e9af 100644
--- a/src/game-server/state.h
+++ b/src/game-server/state.h
@@ -26,7 +26,7 @@
#include <string>
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 042719b..9e9e05f 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<CharacterComponent>()->getClient()->send(msg);
+ c1->getComponent<CharacterComponent>()->setTrading(this);
+ c2->getComponent<CharacterComponent>()->setTrading(this);
}
Trade::~Trade()
{
- mChar1->setTrading(NULL);
- mChar2->setTrading(NULL);
+ mChar1->getComponent<CharacterComponent>()->setTrading(nullptr);
+ mChar2->getComponent<CharacterComponent>()->setTrading(nullptr);
}
void Trade::cancel()
{
MessageOut msg(GPMSG_TRADE_CANCEL);
- mChar1->getClient()->send(msg);
- mChar2->getClient()->send(msg);
+ mChar1->getComponent<CharacterComponent>()->getClient()->send(msg);
+ mChar2->getComponent<CharacterComponent>()->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<CharacterComponent>()->getClient()->send(msg);
+ mChar2->getComponent<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->getClient()->send(msg);
+ mChar2->getComponent<CharacterComponent>()->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<CharacterComponent>()->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<CharacterComponent>()->getClient()->send(msg);
+ mChar2->getComponent<CharacterComponent>()->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<CharacterComponent>()->getClient()->send(msg);
}
else
{
assert(c == mChar2);
mMoney2 = amount;
- mChar1->getClient()->send(msg);
+ mChar1->getComponent<CharacterComponent>()->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<CharacterComponent>()->getClient()->send(msg);
}
diff --git a/src/game-server/trade.h b/src/game-server/trade.h
index 3e5fb3a..be527e8 100644
--- a/src/game-server/trade.h
+++ b/src/game-server/trade.h
@@ -23,7 +23,7 @@
#include <vector>
-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 7c32f09..d4736e4 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<Being *>(obj), mMap, mTargetPoint);
}
}