diff options
author | Rogier Polak <rogier.l.a.polak@gmail.com> | 2007-03-14 17:47:44 +0000 |
---|---|---|
committer | Rogier Polak <rogier.l.a.polak@gmail.com> | 2007-03-14 17:47:44 +0000 |
commit | 7ee29dd31113ea6419801e42de0e4b4a122b7aca (patch) | |
tree | d72ab243f5f378d7254d4765b3df0b46b63f5aa3 /src | |
parent | d69f5bc43d0d08f9b47465598d6b53552a252dfc (diff) | |
download | manaserv-7ee29dd31113ea6419801e42de0e4b4a122b7aca.tar.gz manaserv-7ee29dd31113ea6419801e42de0e4b4a122b7aca.tar.bz2 manaserv-7ee29dd31113ea6419801e42de0e4b4a122b7aca.tar.xz manaserv-7ee29dd31113ea6419801e42de0e4b4a122b7aca.zip |
Modified the game-server to use AbstractCharacterData, some renaming
Diffstat (limited to 'src')
35 files changed, 974 insertions, 1076 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 544d2eba..6deadc84 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -65,13 +65,13 @@ tmwserv_account_SOURCES = \ tmwserv_game_SOURCES = \ game-server/main-game.cpp \ + abstractcharacterdata.hpp \ + abstractcharacterdata.cpp \ configuration.h \ configuration.cpp \ controller.h \ controller.cpp \ defines.h \ - playerdata.hpp \ - playerdata.cpp \ point.h \ resourcemanager.h \ resourcemanager.cpp \ @@ -81,6 +81,8 @@ tmwserv_game_SOURCES = \ game-server/accountconnection.cpp \ game-server/being.hpp \ game-server/being.cpp \ + game-server/character.hpp \ + game-server/character.cpp \ game-server/collisiondetection.hpp \ game-server/collisiondetection.cpp \ game-server/gamehandler.hpp \ @@ -101,8 +103,6 @@ tmwserv_game_SOURCES = \ game-server/mapreader.cpp \ game-server/object.hpp \ game-server/object.cpp \ - game-server/player.hpp \ - game-server/player.cpp \ game-server/state.hpp \ game-server/state.cpp \ game-server/testing.cpp \ diff --git a/src/abstractcharacterdata.cpp b/src/abstractcharacterdata.cpp index ac6fd440..57685273 100644 --- a/src/abstractcharacterdata.cpp +++ b/src/abstractcharacterdata.cpp @@ -22,6 +22,7 @@ #include "abstractcharacterdata.hpp" +#include "defines.h" #include "net/messagein.hpp" #include "net/messageout.hpp" #include "point.h" @@ -36,21 +37,26 @@ void AbstractCharacterData::serialize(MessageOut &msg) const msg.writeByte(getLevel()); msg.writeShort(getMoney()); - for (int i = 0; i < NB_ATTRIBUTES; ++i) + for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i) { - msg.writeByte(getAttribute(i)); + msg.writeByte(getBaseAttribute(i)); } msg.writeShort(getMapId()); - msg.writeShort(getPos().x); - msg.writeShort(getPos().y); + msg.writeShort(getPosition().x); + msg.writeShort(getPosition().y); + /** + * TODO: uncomment/redesign after Inventory is redesigned/improved + * TODO: Test and debug. + * for (int j = 0; j < getNumberOfInventoryItems(); ++j) { msg.writeShort(getInventoryItem(j).itemClassId); - msg.writeByte(getInventoryItem(j).numberOfItemsInSlot); - msg.writeByte((unsigned short)getInventoryItem(j).isEquiped); + msg.writeShort(getInventoryItem(j).numberOfItemsInSlot); + msg.writeByte((char)getInventoryItem(j).isEquiped); } + */ } void AbstractCharacterData::deserialize(MessageIn &msg) @@ -63,9 +69,9 @@ void AbstractCharacterData::deserialize(MessageIn &msg) setLevel(msg.readByte()); setMoney(msg.readShort()); - for (int i = 0; i < NB_ATTRIBUTES; ++i) + for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i) { - setAttribute(i, msg.readByte()); + setBaseAttribute(i, msg.readByte()); } setMapId(msg.readShort()); @@ -73,15 +79,23 @@ void AbstractCharacterData::deserialize(MessageIn &msg) Point temporaryPoint; temporaryPoint.x = msg.readShort(); temporaryPoint.y = msg.readShort(); - setPos(temporaryPoint); + setPosition(temporaryPoint); + + /** + * TODO: uncomment/redesign after Inventory is redesigned/improved + * TODO: Test and debug. + * clearInventory(); - while (msg.getUnreadLength()) + + // byte = 1, short = 2 + while (msg.getUnreadLength() >= 5) { InventoryItem tempItem; tempItem.itemClassId = msg.readShort(); - tempItem.numberOfItemsInSlot = msg.readByte(); + tempItem.numberOfItemsInSlot = msg.readShort(); tempItem.isEquiped = (bool) msg.readByte(); addItemToInventory(tempItem); } + */ } diff --git a/src/abstractcharacterdata.hpp b/src/abstractcharacterdata.hpp index 3a15ed57..fd98c7e8 100644 --- a/src/abstractcharacterdata.hpp +++ b/src/abstractcharacterdata.hpp @@ -17,7 +17,7 @@ * with The Mana World; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ + * $Id$ */ #ifndef _TMWSERV_ABSTRACTCHARACTERDATA @@ -39,20 +39,6 @@ enum }; /** - * Attributes of a Character. - */ -enum -{ - ATT_STRENGTH = 0, - ATT_AGILITY, - ATT_VITALITY, - ATT_INTELLIGENCE, - ATT_DEXTERITY, - ATT_LUCK, - NB_ATTRIBUTES -}; - -/** * Numbers of inventory slots */ enum @@ -63,11 +49,12 @@ enum /** * Structure representing an item stored in the inventory. + * Primarily for the communication between account- and gameserver. */ struct InventoryItem { unsigned short itemClassId; - unsigned char numberOfItemsInSlot; + unsigned short numberOfItemsInSlot; bool isEquiped; }; @@ -103,7 +90,7 @@ class AbstractCharacterData /** Sets the name of the character. */ virtual void - setName(const std::string&) = 0; + setName(const std::string& name) = 0; /** Gets the gender of the character (male or female). */ virtual int @@ -145,13 +132,13 @@ class AbstractCharacterData virtual void setMoney(int amount) = 0; - /** Gets the value of an attribute of the character. */ + /** Gets the value of a base attribute of the character. */ virtual unsigned short - getAttribute(int attributeNumber) const = 0; + getBaseAttribute(int attributeNumber) const = 0; - /** Sets the value of an attribute of the character. */ + /** Sets the value of a base attribute of the character. */ virtual void - setAttribute(int attributeNumber, int value) = 0; + setBaseAttribute(int attributeNumber, int value) = 0; /** Gets the Id of the map that the character is on. */ virtual int @@ -163,11 +150,11 @@ class AbstractCharacterData /** Gets the position of the character on the map. */ virtual Point const & - getPos() const = 0; + getPosition() const = 0; /** Sets the position of the character on the map. */ virtual void - setPos(const Point &p) = 0; + setPosition(const Point &p) = 0; /** * The access functions for inventory diff --git a/src/account-server/accounthandler.cpp b/src/account-server/accounthandler.cpp index 2b1f2ff0..fe3c64d8 100644 --- a/src/account-server/accounthandler.cpp +++ b/src/account-server/accounthandler.cpp @@ -351,8 +351,8 @@ AccountHandler::handleLoginMessage(AccountClient &computer, MessageIn &msg) charInfo.writeByte(chars[i]->getHairColor()); charInfo.writeByte(chars[i]->getLevel()); charInfo.writeShort(chars[i]->getMoney()); - for (int j = 0; j < NB_ATTRIBUTES; ++j) - charInfo.writeShort(chars[i]->getAttribute(j)); + for (int j = 0; j < NB_BASE_ATTRIBUTES; ++j) + charInfo.writeShort(chars[i]->getBaseAttribute(j)); computer.send(charInfo); } return; @@ -620,8 +620,8 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, // LATER_ON: Add race, face and maybe special attributes. // Customization of character's attributes... - unsigned short attributes[NB_ATTRIBUTES]; - for (int i = 0; i < NB_ATTRIBUTES; ++i) + unsigned short attributes[NB_BASE_ATTRIBUTES]; + for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i) attributes[i] = msg.readShort(); // We see if the difference between the lowest stat and the highest @@ -630,7 +630,7 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, unsigned short highestAttribute = 0; // start value unsigned int totalAttributes = 0; bool validNonZeroAttributes = true; - for (int i = 0; i < NB_ATTRIBUTES; ++i) + for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i) { // For good total attributes check. totalAttributes += attributes[i]; @@ -663,8 +663,8 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, else { CharacterPtr newCharacter(new CharacterData(name)); - for (int i = 0; i < NB_ATTRIBUTES; ++i) - newCharacter->setAttribute(i, attributes[i]); + for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i) + newCharacter->setBaseAttribute(i, attributes[i]); newCharacter->setMoney(0); newCharacter->setLevel(1); newCharacter->setGender(gender); @@ -673,7 +673,7 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, newCharacter->setMapId((int) config.getValue("defaultMap", 1)); Point startingPos((int) config.getValue("startX", 0), (int) config.getValue("startY", 0)); - newCharacter->setPos(startingPos); + newCharacter->setPosition(startingPos); computer.getAccount()->addCharacter(newCharacter); LOG_INFO("Character " << name << " was created for " @@ -693,8 +693,8 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, charInfo.writeByte(chars[slot]->getHairColor()); charInfo.writeByte(chars[slot]->getLevel()); charInfo.writeShort(chars[slot]->getMoney()); - for (int j = 0; j < NB_ATTRIBUTES; ++j) - charInfo.writeShort(chars[slot]->getAttribute(j)); + for (int j = 0; j < NB_BASE_ATTRIBUTES; ++j) + charInfo.writeShort(chars[slot]->getBaseAttribute(j)); computer.send(charInfo); return; } @@ -749,9 +749,9 @@ handleReconnectedAccount(AccountClient &computer, int accountID) charInfo.writeByte(chars[i]->getLevel()); charInfo.writeShort(chars[i]->getMoney()); - for (int j = 0; j < NB_ATTRIBUTES; ++j) + for (int j = 0; j < NB_BASE_ATTRIBUTES; ++j) { - charInfo.writeShort(chars[i]->getAttribute(j)); + charInfo.writeShort(chars[i]->getBaseAttribute(j)); } computer.send(charInfo); } diff --git a/src/account-server/characterdata.cpp b/src/account-server/characterdata.cpp index 50d1562e..95b5e75a 100644 --- a/src/account-server/characterdata.cpp +++ b/src/account-server/characterdata.cpp @@ -28,9 +28,9 @@ CharacterData::CharacterData(std::string const &name, int id): mDatabaseID(id), mAccountID(-1), mName(name), mGender(0), mHairStyle(0), mHairColor(0), mLevel(0), mMoney(0), mMapId(0), mPos(0,0) { - for (int i = 0; i < NB_ATTRIBUTES; ++i) + for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i) { - mAttributes[i] = 0; + mBaseAttributes[i] = 0; } } @@ -38,9 +38,9 @@ CharacterData::CharacterData(MessageIn & msg): mDatabaseID(-1), mAccountID(-1), mName(""), mGender(0), mHairStyle(0), mHairColor(0), mLevel(0), mMoney(0), mMapId(0), mPos(0,0) { - for (int i = 0; i < NB_ATTRIBUTES; ++i) + for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i) { - mAttributes[i] = 0; + mBaseAttributes[i] = 0; } deserialize(msg); } diff --git a/src/account-server/characterdata.hpp b/src/account-server/characterdata.hpp index 8911cb21..4122bdbe 100644 --- a/src/account-server/characterdata.hpp +++ b/src/account-server/characterdata.hpp @@ -17,14 +17,14 @@ * with The Mana World; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id$ + * $Id$ */ #ifndef _TMWSERV_CHARACTERDATA #define _TMWSERV_CHARACTERDATA #include "abstractcharacterdata.hpp" - +#include "defines.h" #include <string> #include <vector> @@ -43,7 +43,7 @@ class CharacterData: public AbstractCharacterData /** * Constructor used for creating a character from a serialised message. */ - CharacterData(MessageIn &); + CharacterData(MessageIn & msg); /** * Get and set methods @@ -113,15 +113,15 @@ class CharacterData: public AbstractCharacterData void setMoney(int amount) { mMoney = amount; } - /** Gets the value of an attribute of the character. */ + /** Gets the value of a base attribute of the character. */ unsigned short - getAttribute(int attributeNumber) const - { return mAttributes[attributeNumber]; } + getBaseAttribute(int attributeNumber) const + { return mBaseAttributes[attributeNumber]; } - /** Sets the value of an attribute of the character. */ + /** Sets the value of a base attribute of the character. */ void - setAttribute(int attributeNumber, int value) - { mAttributes[attributeNumber] = value; } + setBaseAttribute(int attributeNumber, int value) + { mBaseAttributes[attributeNumber] = value; } /** Gets the Id of the map that the character is on. */ int @@ -133,11 +133,11 @@ class CharacterData: public AbstractCharacterData /** Gets the position of the character on the map. */ Point const & - getPos() const { return mPos; } + getPosition() const { return mPos; } /** Sets the position of the character on the map. */ void - setPos(const Point &p) { mPos = p; } + setPosition(const Point &p) { mPos = p; } /** Returns the number of inventory items. */ int @@ -169,7 +169,7 @@ class CharacterData: public AbstractCharacterData unsigned char mHairColor; //!< Hair Color of the being. unsigned char mLevel; //!< Level of the being. unsigned int mMoney; //!< Wealth of the being. - unsigned short mAttributes[NB_ATTRIBUTES]; //!< The attributes of the + unsigned short mBaseAttributes[NB_BASE_ATTRIBUTES]; //!< The attributes of the //!< character. unsigned short mMapId; //!< Map the being is on. Point mPos; //!< Position the being is at. diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp index cd63473c..0df47d86 100644 --- a/src/account-server/dalstorage.cpp +++ b/src/account-server/dalstorage.cpp @@ -170,10 +170,11 @@ DALStorage::open(void) createTable(CHANNELS_TBL_NAME, SQL_CHANNELS_TABLE); } catch (const DbConnectionFailure& e) { - LOG_ERROR("Unable to connect to the database: " << e.what()); + LOG_ERROR("(DALStorage::open #1) Unable to connect to the database: " + << e.what()); } catch (const DbSqlQueryExecFailure& e) { - LOG_ERROR("SQL query failure: " << e.what()); + LOG_ERROR("(DALStorage::open #2) SQL query failure: " << e.what()); } mIsOpen = mDb->isConnected(); @@ -391,7 +392,8 @@ CharacterPtr DALStorage::getCharacter(int id) // a string to an unsigned short. string_to< unsigned short > toUshort; - CharacterData *character = new CharacterData(charInfo(0, 2), toUint(charInfo(0, 0))); + CharacterData *character = new CharacterData(charInfo(0, 2), + toUint(charInfo(0, 0))); character->setAccountID(toUint(charInfo(0, 1))); character->setGender(toUshort(charInfo(0, 3))); character->setHairStyle(toUshort(charInfo(0, 4))); @@ -399,10 +401,10 @@ CharacterPtr DALStorage::getCharacter(int id) character->setLevel(toUshort(charInfo(0, 6))); character->setMoney(toUint(charInfo(0, 7))); Point pos(toUshort(charInfo(0, 8)), toUshort(charInfo(0, 9))); - character->setPos(pos); - for (int i = 0; i < NB_ATTRIBUTES; ++i) + character->setPosition(pos); + for (int i = 0; i < NB_BASE_ATTRIBUTES; ++i) { - character->setAttribute(i, toUshort(charInfo(0, 11 + i))); + character->setBaseAttribute(i, toUshort(charInfo(0, 11 + i))); } int mapId = toUint(charInfo(0, 10)); @@ -458,7 +460,7 @@ DALStorage::getEmailList() } catch (const dal::DbSqlQueryExecFailure& e) { // TODO: throw an exception. - LOG_ERROR("SQL query failure: " << e.what()); + LOG_ERROR("(DALStorage::getEmailList) SQL query failure: " << e.what()); } return emailList; @@ -485,7 +487,7 @@ bool DALStorage::doesEmailAddressExist(std::string const &email) return iReturn != 0; } catch (std::exception const &e) { // TODO: throw an exception. - LOG_ERROR("SQL query failure: " << e.what()); + LOG_ERROR("(DALStorage::doesEmailAddressExist) SQL query failure: " << e.what()); } return true; @@ -512,7 +514,8 @@ bool DALStorage::doesCharacterNameExist(const std::string& name) return iReturn != 0; } catch (std::exception const &e) { // TODO: throw an exception. - LOG_ERROR("SQL query failure: " << e.what()); + LOG_ERROR("(DALStorage::doesCharacterNameExist) SQL query failure: " + << e.what()); } return true; @@ -524,54 +527,55 @@ DALStorage::updateCharacter(CharacterPtr character) // If not opened already open(); - //Character data (see CharacterData for details) + // Update the database Character data (see CharacterData for details) try { std::ostringstream sqlUpdateCharacterInfo; sqlUpdateCharacterInfo << "update " << CHARACTERS_TBL_NAME << " " - << "set" - << "gender = " << character->getGender() - << ", " - << "hair_style = " << (int)character->getHairStyle() - << ", " - << "hair_color = " << (int)character->getHairColor() - << ", " - << "level = " << (int)character->getLevel() - << ", " - << "money = " << character->getMoney() - << ", " - << "x = " << character->getPos().x - << ", " - << "y = " << character->getPos().y - << ", " - << "map_id = " << character->getMapId() - << ", " - << "str = " << character->getAttribute(ATT_STRENGTH) - << ", " - << "agi = " << character->getAttribute(ATT_AGILITY) - << ", " - << "vit = " << character->getAttribute(ATT_VITALITY) - << ", " + << "set " + << "gender = '" << character->getGender() + << "', " + << "hair_style = '" << (int)character->getHairStyle() + << "', " + << "hair_color = '" << (int)character->getHairColor() + << "', " + << "level = '" << (int)character->getLevel() + << "', " + << "money = '" << character->getMoney() + << "', " + << "x = '" << character->getPosition().x + << "', " + << "y = '" << character->getPosition().y + << "', " + << "map_id = '" << character->getMapId() + << "', " + << "str = '" << character->getBaseAttribute(ATT_STRENGTH) + << "', " + << "agi = '" << character->getBaseAttribute(ATT_AGILITY) + << "', " + << "vit = '" << character->getBaseAttribute(ATT_VITALITY) + << "', " #if defined(MYSQL_SUPPORT) || defined(POSTGRESQL_SUPPORT) - << "`int` = " + << "`int` = '" #else - << "int = " + << "int = '" #endif - << character->getAttribute(ATT_INTELLIGENCE) - << ", " - << "dex = " << character->getAttribute(ATT_DEXTERITY) - << ", " - << "luck = " << character->getAttribute(ATT_LUCK) - << "where id = " << character->getDatabaseID() - << ";"; + << character->getBaseAttribute(ATT_INTELLIGENCE) + << "', " + << "dex = '" << character->getBaseAttribute(ATT_DEXTERITY) + << "', " + << "luck = '" << character->getBaseAttribute(ATT_LUCK) + << "' " + << "where id = '" << character->getDatabaseID() + << "';"; mDb->execSql(sqlUpdateCharacterInfo.str()); } catch (const dal::DbSqlQueryExecFailure& e) { // TODO: throw an exception. - LOG_ERROR("SQL query failure: " << e.what()); + LOG_ERROR("(DALStorage::updateCharacter #1) SQL query failure: " << e.what()); return false; } @@ -584,30 +588,30 @@ DALStorage::updateCharacter(CharacterPtr character) { std::ostringstream sqlDeleteCharacterInventory; sqlDeleteCharacterInventory - << "delete * from " << INVENTORIES_TBL_NAME - << "where owner_id = " << character->getDatabaseID() << ";"; - + << "delete from " << INVENTORIES_TBL_NAME + << " where owner_id = '" << character->getDatabaseID() << "';"; mDb->execSql(sqlDeleteCharacterInventory.str()); } catch (const dal::DbSqlQueryExecFailure& e) { // TODO: throw an exception. - LOG_ERROR("SQL query failure: " << e.what()); + LOG_ERROR("(DALStorage::updateCharacter #2) SQL query failure: " << e.what()); return false; } // Insert the new inventory data - try + if (character->getNumberOfInventoryItems()) { - if (character->getNumberOfInventoryItems()) + try { std::ostringstream sqlInsertCharacterInventory; + sqlInsertCharacterInventory << "insert into " << INVENTORIES_TBL_NAME - << "(owner_id, class_id, amount, equipped) " + << " (owner_id, class_id, amount, equipped) " << "values "; - for (int j = 0; ; ) + for (int j = 0; j < character->getNumberOfInventoryItems(); j++) { sqlInsertCharacterInventory << "(" << character->getDatabaseID() << ", " @@ -615,21 +619,23 @@ DALStorage::updateCharacter(CharacterPtr character) << character->getInventoryItem(j).numberOfItemsInSlot << ", " << (unsigned short) - character->getInventoryItem(j).isEquiped + character->getInventoryItem(j).isEquiped << ")"; + // Adding the comma only if it's needed - if (++j < character->getNumberOfInventoryItems()) - sqlInsertCharacterInventory << ", "; + if (j < (character->getNumberOfInventoryItems() - 1)) + sqlInsertCharacterInventory << ", "; } + sqlInsertCharacterInventory << ";"; mDb->execSql(sqlInsertCharacterInventory.str()); } - } - catch (const dal::DbSqlQueryExecFailure& e) - { - // TODO: throw an exception. - LOG_ERROR("SQL query failure: " << e.what()); - return false; + catch (const dal::DbSqlQueryExecFailure& e) + { + // TODO: throw an exception. + LOG_ERROR("(DALStorage::updateCharacter #3) SQL query failure: " << e.what()); + return false; + } } return true; } @@ -677,7 +683,7 @@ DALStorage::getChannelList() } catch (const dal::DbSqlQueryExecFailure& e) { // TODO: throw an exception. - LOG_ERROR("SQL query failure: " << e.what()); + LOG_ERROR("(DALStorage::getChannelList) SQL query failure: " << e.what()); } return channels; @@ -734,7 +740,7 @@ DALStorage::updateChannels(std::map<short, ChatChannel>& channelList) } catch (const dal::DbSqlQueryExecFailure& e) { // TODO: throw an exception. - LOG_ERROR("SQL query failure: " << e.what()); + LOG_ERROR("(DALStorage::updateChannels) SQL query failure: " << e.what()); } } @@ -865,15 +871,15 @@ void DALStorage::flush(AccountPtr const &account) << (int)(*it)->getHairColor() << ", " << (int)(*it)->getLevel() << ", " << (*it)->getMoney() << ", " - << (*it)->getPos().x << ", " - << (*it)->getPos().y << ", " + << (*it)->getPosition().x << ", " + << (*it)->getPosition().y << ", " << (*it)->getMapId() << ", " - << (*it)->getAttribute(ATT_STRENGTH) << ", " - << (*it)->getAttribute(ATT_AGILITY) << ", " - << (*it)->getAttribute(ATT_VITALITY) << ", " - << (*it)->getAttribute(ATT_INTELLIGENCE) << ", " - << (*it)->getAttribute(ATT_DEXTERITY) << ", " - << (*it)->getAttribute(ATT_LUCK) << ");"; + << (*it)->getBaseAttribute(ATT_STRENGTH) << ", " + << (*it)->getBaseAttribute(ATT_AGILITY) << ", " + << (*it)->getBaseAttribute(ATT_VITALITY) << ", " + << (*it)->getBaseAttribute(ATT_INTELLIGENCE) << ", " + << (*it)->getBaseAttribute(ATT_DEXTERITY) << ", " + << (*it)->getBaseAttribute(ATT_LUCK) << ");"; mDb->execSql(sqlInsertCharactersTable.str()); } else { @@ -886,19 +892,20 @@ void DALStorage::flush(AccountPtr const &account) << " hair_color = " << (int)(*it)->getHairColor() << ", " << " level = " << (int)(*it)->getLevel() << ", " << " money = " << (*it)->getMoney() << ", " - << " x = " << (*it)->getPos().x << ", " - << " y = " << (*it)->getPos().y << ", " + << " x = " << (*it)->getPosition().x << ", " + << " y = " << (*it)->getPosition().y << ", " << " map_id = " << (*it)->getMapId() << ", " - << " str = " << (*it)->getAttribute(ATT_STRENGTH) << ", " - << " agi = " << (*it)->getAttribute(ATT_AGILITY) << ", " - << " vit = " << (*it)->getAttribute(ATT_VITALITY) << ", " + << " str = " << (*it)->getBaseAttribute(ATT_STRENGTH) << ", " + << " agi = " << (*it)->getBaseAttribute(ATT_AGILITY) << ", " + << " vit = " << (*it)->getBaseAttribute(ATT_VITALITY) << ", " #if defined(MYSQL_SUPPORT) || defined(POSTGRESQL_SUPPORT) - << " `int` = " << (*it)->getAttribute(ATT_INTELLIGENCE) << ", " + << " `int` = " #else - << " int = " << (*it)->getAttribute(ATT_INTELLIGENCE) << ", " + << " int = " #endif - << " dex = " << (*it)->getAttribute(ATT_DEXTERITY) << ", " - << " luck = " << (*it)->getAttribute(ATT_LUCK) + << (*it)->getBaseAttribute(ATT_INTELLIGENCE) << ", " + << " dex = " << (*it)->getBaseAttribute(ATT_DEXTERITY) << ", " + << " luck = " << (*it)->getBaseAttribute(ATT_LUCK) << " where id = " << (*it)->getDatabaseID() << ";"; mDb->execSql(sqlUpdateCharactersTable.str()); diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp index d2159d44..53cc53f5 100644 --- a/src/account-server/serverhandler.cpp +++ b/src/account-server/serverhandler.cpp @@ -125,7 +125,9 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) case GAMSG_PLAYER_DATA: { LOG_DEBUG("GAMSG_PLAYER_DATA"); - + // TODO: Store it in memory, only update the database when needed. + // That should get rid of the + // no_update_on_switch_character_bug as well. Storage &store = Storage::instance("tmw"); CharacterPtr ptr(new CharacterData(msg)); diff --git a/src/controller.cpp b/src/controller.cpp index 737a01b9..23ae9bc8 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -28,9 +28,6 @@ Controlled::Controlled(int type): Being(type, 65535), mCountDown(0) { - mStats.base.resize(NB_STATS_BEING, 1); //TODO: fill with the real values - mStats.absoluteModificator.resize(NB_STATS_BEING, 0); - mStats.percentModificators.resize(NB_STATS_BEING); } void Controlled::update() @@ -67,9 +64,3 @@ void Controlled::die() Being::die(); } -void Controlled::calculateStats() -{ - /* All base stats of a monster should be set directly by the monster - * database, so there is nothing we should have to calculate here. - */ -} diff --git a/src/controller.h b/src/controller.h index f99a2b74..7bd1d334 100644 --- a/src/controller.h +++ b/src/controller.h @@ -46,13 +46,6 @@ class Controlled: public Being */ virtual void die(); - /** - * Recalculates all stats of the being that are derived from others. - * Call whenever you change something that affects a derived stat. - * Called automatically when you manipulate a stat using setBaseStat() - */ - virtual void calculateStats(); - private: /** Count down till next random movement (temporary). */ unsigned int mCountDown; diff --git a/src/defines.h b/src/defines.h index bd188347..7635ca5c 100644 --- a/src/defines.h +++ b/src/defines.h @@ -75,10 +75,11 @@ enum MAX_HAIRSTYLE_VALUE = 7, MAX_HAIRCOLOR_VALUE = 9, MAX_GENDER_VALUE = 2, -/** Tells the max difference between the - * less big stat and the biggest one. - * So that players haven't disproportionned - * Raw statistics. + +/** + * Determines the maximum difference between the largest attribute and the + * smallest one. To ensure that characters do not have disproportionned + * attributes. */ MAX_DIFF_BETWEEN_ATTRIBUTES = 5, /** @@ -150,7 +151,7 @@ enum { GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }* GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }* GPMSG_BEING_ENTER = 0x0200, // B type, W being id, B action, W*2 position - // player: S name, B hair style, B hair color, B gender + // character: S name, B hair style, B hair color, B gender // monster: W type id GPMSG_BEING_LEAVE = 0x0201, // W being id GPMSG_ITEM_APPEAR = 0x0202, // W item id, W*2 position @@ -191,8 +192,8 @@ enum { // Inter-server GAMSG_REGISTER = 0x500, // S address, W port, { W map id }* AGMSG_ACTIVE_MAP = 0x501, // W map id - AGMSG_PLAYER_ENTER = 0x510, // B*32 token, serialised player data - GAMSG_PLAYER_DATA = 0x520, // serialised player data + AGMSG_PLAYER_ENTER = 0x510, // B*32 token, serialised character data + GAMSG_PLAYER_DATA = 0x520, // serialised character data GAMSG_REDIRECT = 0x530, // L id AGMSG_REDIRECT_RESPONSE = 0x531, // L id, B*32 token, S game address, W game port GAMSG_PLAYER_RECONNECT = 0x532, // L id, B*32 token @@ -262,4 +263,80 @@ enum { MOVING_DESTINATION = 2 }; +/** + * Enumerations for the handling of attributes and their modifiers. + */ + +/** + * Possible states of beings. + * States can be multiple for the same being. + * To be used as bitmask values. + */ +enum BeingState +{ + STATE_POISONED = 1, + STATE_STONED = 2, + STATE_STUNNED = 4, + STATE_SLOWED = 8, + STATE_TIRED = 16, + STATE_MAD = 32, + STATE_BERSERK = 64, + STATE_HASTED = 128, + STATE_FLOATING = 256 +}; + +/** + * Base attributes of a Being. + */ +enum +{ + ATT_STRENGTH = 0, + ATT_AGILITY, + ATT_VITALITY, + ATT_INTELLIGENCE, + ATT_DEXTERITY, + ATT_LUCK, +/** ATT_WILLPOWER, + ATT_CHARISMA,*/ + NB_BASE_ATTRIBUTES +}; +/** + * Character skills + */ +enum WeaponSkills +{ + SKILL_WEAPON_UNARMED = 0, + SKILL_WEAPON_SWORD, + SKILL_WEAPON_AXE, + SKILL_WEAPON_POLEARM, + SKILL_WEAPON_JAVELIN, + SKILL_WEAPON_WHIP, + SKILL_WEAPON_DAGGER, + SKILL_WEAPON_STAFF, + SKILL_WEAPON_BOW, + SKILL_WEAPON_CROSSBOW, + SKILL_WEAPON_THROWN, + NB_WEAPONSKILLS +}; + +enum MagicSkills +{ + SKILL_MAGIC_IAMJUSTAPLACEHOLDER = NB_WEAPONSKILLS, + NB_MAGICSKILLS +}; + +enum CraftSkills +{ + SKILL_CRAFT_IAMJUSTAPLACEHOLDER = NB_MAGICSKILLS, + NB_CRAFTSKILLS +}; + +enum OtherSkills +{ + SKILL_IAMJUSTAPLACEHOLDER = NB_CRAFTSKILLS, + NB_OTHERSKILLS +} + +static const NB_CHARACTER_SKILLS = NB_OTHERSKILLS; + #endif // _TMWSERV_DEFINES_H_ diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp index 1178838c..dea2e82c 100644 --- a/src/game-server/accountconnection.cpp +++ b/src/game-server/accountconnection.cpp @@ -26,13 +26,13 @@ #include "game-server/accountconnection.hpp" #include "game-server/gamehandler.hpp" #include "game-server/mapmanager.hpp" -#include "game-server/player.hpp" +#include "game-server/character.hpp" #include "net/messagein.hpp" #include "net/messageout.hpp" #include "utils/logger.h" #include "utils/tokendispenser.hpp" -extern void registerGameClient(std::string const &, Player *); +extern void registerGameClient(std::string const &, Character *); bool AccountConnection::start() { @@ -54,10 +54,9 @@ bool AccountConnection::start() return true; } -void AccountConnection::sendPlayerData(PlayerData *p) +void AccountConnection::sendCharacterData(Character *p) { MessageOut msg(GAMSG_PLAYER_DATA); - msg.writeLong(p->getDatabaseID()); p->serialize(msg); send(msg); } @@ -69,12 +68,7 @@ void AccountConnection::processMessage(MessageIn &msg) case AGMSG_PLAYER_ENTER: { std::string token = msg.readString(MAGIC_TOKEN_LENGTH); - int id = msg.readLong(); - std::string name = msg.readString(); - Player *ptr = new Player(name, id); - ptr->deserialize(msg); - ptr->setMapId(ptr->getMap()); - ptr->setPosition(ptr->getPos()); + Character *ptr = new Character(msg); ptr->setSpeed(150); // TODO registerGameClient(token, ptr); } break; @@ -107,5 +101,4 @@ void AccountConnection::playerReconnectAccount(int id, const std::string magic_t msg.writeLong(id); msg.writeString(magic_token, MAGIC_TOKEN_LENGTH); send(msg); - } diff --git a/src/game-server/accountconnection.hpp b/src/game-server/accountconnection.hpp index 5f8ae0e9..24ee1598 100644 --- a/src/game-server/accountconnection.hpp +++ b/src/game-server/accountconnection.hpp @@ -26,7 +26,7 @@ #include "net/connection.hpp" -class PlayerData; +class Character; /** * A connection to the account server. @@ -41,9 +41,9 @@ class AccountConnection: public Connection bool start(); /** - * Sends data of given player. + * Sends data of a given character. */ - void sendPlayerData(PlayerData *); + void sendCharacterData(Character *); /** * Prepares the account server for a reconnecting player diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 3364d23f..8703fc2b 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -26,6 +26,25 @@ #include "game-server/mapcomposite.hpp" #include "utils/logger.h" +Being::Being(int type, int id): + MovingObject(type, id), + mAction(STAND) +{ + for (int i = 0; i < NB_BASE_ATTRIBUTES; i++) + { + mBaseAttributes[i] = 0; + } + for (int j = 0; j < NB_COMPOUND_ATTRIBUTES; j++) + { + mCompoundAttributes[j] = 0; + } + mBeingModificators.absoluteModificator.resize(NB_COMPOUND_ATTRIBUTES, 0); + mBeingModificators.percentModificators.resize(NB_COMPOUND_ATTRIBUTES); + //TODO: set the base attributes, calculate the compound attributes +} + +Being::~Being() +{} void Being::damage(Damage damage) { @@ -40,7 +59,8 @@ void Being::damage(Damage damage) switch (damage.type) { case DAMAGETYPE_PHYSICAL: - HPloss -= getRealStat(STAT_PHYSICAL_DEFENCE) / damage.penetration; + HPloss -= getCompoundAttribute(ATT_PHYSICAL_DEFENCE) + / damage.penetration; break; case DAMAGETYPE_MAGICAL: // NIY @@ -121,7 +141,7 @@ void Being::performAttack(MapComposite *map) int type = o->getType(); - if (type != OBJECT_PLAYER && type != OBJECT_MONSTER) continue; + if (type != OBJECT_CHARACTER && type != OBJECT_MONSTER) continue; Point opos = o->getPosition(); @@ -145,17 +165,19 @@ void Being::setAction(Action action) } } -void Being::addAbsoluteStatModifier(unsigned numStat, short value) +void Being::addAbsoluteStatModifier(int attributeNumber, short value) { - mStats.absoluteModificator.at(numStat) = mStats.absoluteModificator.at(numStat) + value; + mBeingModificators.absoluteModificator.at(attributeNumber) += value; + calculateCompoundAttribute(attributeNumber); } -void Being::removeAbsoluteStatModifier(unsigned numStat, short value) +void Being::removeAbsoluteStatModifier(int attributeNumber, short value) { - mStats.absoluteModificator.at(numStat) = mStats.absoluteModificator.at(numStat) - value; + mBeingModificators.absoluteModificator.at(attributeNumber) -= value; + calculateCompoundAttribute(attributeNumber); } -void Being::addPercentStatModifier(unsigned numStat, short value) +void Being::addPercentStatModifier(int attributeNumber, short value) { if (value < -100) { @@ -163,39 +185,76 @@ void Being::addPercentStatModifier(unsigned numStat, short value) getPublicID()<< "that would make the stat negative!" ); + return; } - else - { - mStats.percentModificators.at(numStat).push_back(value); - } + + mBeingModificators.percentModificators.at(attributeNumber).push_back(value); + calculateCompoundAttribute(attributeNumber); } -void Being::removePercentStatModifier(unsigned numStat, short value) +void Being::removePercentStatModifier(int attributeNumber, short value) { - std::list<short>::iterator i = mStats.percentModificators.at(numStat).begin(); - - while (i != mStats.percentModificators.at(numStat).end()) + std::list<short>::iterator + i = mBeingModificators.percentModificators.at(attributeNumber).begin(), + i_end = mBeingModificators.percentModificators.at(attributeNumber).end(); + for (; i != i_end; i++) { if ((*i) = value) { - mStats.percentModificators.at(numStat).erase(i); - return; + mBeingModificators.percentModificators.at(attributeNumber).erase(i); + break; } } - LOG_WARN( "Attempt to remove a stat modificator for Being"<< - getPublicID()<< - "that hasn't been added before!" - ); + if (i == i_end) + LOG_WARN("Attempt to remove a stat modificator for Being" << + getPublicID() << + "that hasn't been added before!"); + + calculateCompoundAttribute(attributeNumber); + + return; } -unsigned short Being::getRealStat(unsigned numStat) +void Being::calculateCompoundAttribute(int attributeNumber) { - int value = mStats.base.at(numStat) + mStats.absoluteModificator.at(numStat); + int value; + + if (attributeNumber < NB_BASE_ATTRIBUTES) + value = getBaseAttribute(attributeNumber); + + switch (attributeNumber) + { + case ATT_HP_MAXIMUM: + value = 20 + (20 * getBaseAttribute(ATT_VITALITY)); + break; + case ATT_PHYSICAL_ATTACK_MINIMUM: + value = 10 + getBaseAttribute(ATT_STRENGTH); + break; + case ATT_PHYSICAL_ATTACK_FLUCTUATION: + value = 10; + break; + case ATT_PHYSICAL_DEFENCE: + value = 10 + getBaseAttribute(ATT_STRENGTH); + break; + case ATT_MAGIC: + value = 0; + break; + case ATT_ACCURACY: + value = 50 + getBaseAttribute(ATT_DEXTERITY); + break; + case ATT_SPEED: + value = getBaseAttribute(ATT_AGILITY); + break; + } + + value += mBeingModificators.absoluteModificator.at(attributeNumber); + std::list<short>::iterator i; float multiplier = 1.0f; - for ( i = mStats.percentModificators.at(numStat).begin(); - i != mStats.percentModificators.at(numStat).end(); + + for ( i = mBeingModificators.percentModificators.at(attributeNumber).begin(); + i != mBeingModificators.percentModificators.at(attributeNumber).end(); i++ ) { @@ -206,13 +265,15 @@ unsigned short Being::getRealStat(unsigned numStat) * would result in a stat near 2^16. To make sure that this doesn't happen * we return a value of 0 in that case */ - if (multiplier < 0.0f) - { - return 0; - } - else + mCompoundAttributes[attributeNumber] = + (multiplier < 0.0f) ? 0 : (unsigned short)(value * multiplier); +} + +void Being::recalculateAllCompoundAttributes() +{ + for (int i = 0; i < (NB_COMPOUND_ATTRIBUTES); i++) { - return (unsigned short)(value * multiplier); + calculateCompoundAttribute(i); } } @@ -220,7 +281,8 @@ Damage Being::getPhysicalAttackDamage() { Damage damage; damage.type = DAMAGETYPE_PHYSICAL; - damage.value = getRealStat(STAT_PHYSICAL_ATTACK_MINIMUM) + (rand()%getRealStat(STAT_PHYSICAL_ATTACK_FLUCTUATION)); + damage.value = getCompoundAttribute(ATT_PHYSICAL_ATTACK_MINIMUM) + + (rand()%getCompoundAttribute(ATT_PHYSICAL_ATTACK_FLUCTUATION)); damage.penetration = 1; // TODO: get from equipped weapon damage.element = ELEMENT_NEUTRAL; // TODO: get from equipped weapon damage.source = this; diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp index 77b7bfc8..a245f617 100644 --- a/src/game-server/being.hpp +++ b/src/game-server/being.hpp @@ -34,6 +34,21 @@ class Being; class MapComposite; /** + * Derived attributes of a Being. + */ +enum +{ + ATT_HP_MAXIMUM = NB_BASE_ATTRIBUTES, + ATT_PHYSICAL_ATTACK_MINIMUM, + ATT_PHYSICAL_ATTACK_FLUCTUATION, + ATT_PHYSICAL_DEFENCE, + ATT_MAGIC, + ATT_ACCURACY, + ATT_SPEED, + NB_COMPOUND_ATTRIBUTES +}; + +/** * Element attribute for beings, actors and items. * Subject to change until pauan and dabe are finished with the element system. */ @@ -49,24 +64,6 @@ enum Element }; /** - * States attribute for beings, and actors. - * States can be multiple for the same being. - */ -struct BeingState -{ - bool STATE_NORMAL; - bool STATE_POISONED; - bool STATE_STONED; - bool STATE_STUNNED; - bool STATE_SLOWED; - bool STATE_TIRED; - bool STATE_MAD; - bool STATE_BERSERK; - bool STATE_HASTED; - bool STATE_FLOATING; -}; - -/** * Beings and actors directions */ enum @@ -89,7 +86,8 @@ enum Damagetype }; /** - * Structure describing severity and nature of an attack a being can suffer of + * Structure that describes the severity and nature of an attack a being can + * be hit by. */ struct Damage { @@ -106,37 +104,24 @@ struct Damage typedef std::list<unsigned int> Hits; /** - * Structure type for the stats of a Being. + * Structures for storing the attribute modifiers of a Being. */ -struct Stats +struct BeingModificators { - std::vector<unsigned short> base; std::vector<short> absoluteModificator; std::vector< std::list<short> > percentModificators; }; + /** * Generic Being (living object). - * Used for players & monsters (all animated objects). + * Used for characters & monsters (all animated objects). */ class Being : public MovingObject { public: /** - * Computed statistics of a Being. - */ - enum Stat - { - STAT_HP_MAXIMUM, - STAT_PHYSICAL_ATTACK_MINIMUM, - STAT_PHYSICAL_ATTACK_FLUCTUATION, - STAT_PHYSICAL_DEFENCE, - // add new computed statistics on demand - NB_STATS_BEING - }; - - /** * Moves enum for beings and actors for others players vision. * WARNING: Has to be in sync with the same enum in the Being class * of the client! @@ -153,65 +138,37 @@ class Being : public MovingObject /** * Proxy constructor. */ - Being(int type, int id) - : MovingObject(type, id), - mAction(STAND) - {} + Being(int type, int id); - /** - * Sets a being statistic. - * - * @param numStat the statistic number. - * @param value the new value. - */ - void setBaseStat(unsigned numStat, unsigned short value) - { mStats.base[numStat] = value; - calculateBaseStats(); - } + ~Being(); /** * Adds a fixed value stat modifier */ - void addAbsoluteStatModifier(unsigned numStat, short value); + void addAbsoluteStatModifier(int attributeNumber, short value); /** * Removes a fixed value stat modifier */ - void removeAbsoluteStatModifier(unsigned numStat, short value); + void removeAbsoluteStatModifier(int attributeNumber, short value); /** * Adds a multiplier stat modificator in percent */ - void addPercentStatModifier(unsigned numStat, short value); + void addPercentStatModifier(int attributeNumber, short value); /** * Removes a previously added percent stat modifier. * Does nothing and logs a warning when no modifier with the same * value has been added before. */ - void removePercentStatModifier(unsigned numStat, short value); + void removePercentStatModifier(int attributeNumber, short value); /** - * Returns a being statistic without temporary modifiers - * - * @param numStat the statistic number. - * @return the statistic value. + * Returns a specific compound attribute of a being. */ - unsigned short getBaseStat(unsigned stat) - { return mStats.base.at(stat); } - - /** - * Returns a being statistic with added temporary modifiers - */ - unsigned short getRealStat(unsigned stat); - - /** - * Recalculates all stats of the being that are derived from others. - * Call whenever you change something that affects a derived stat. - * Called automatically when you manipulate a stat using setBaseStat() - */ - virtual void calculateBaseStats() - { /*NOOP*/ }; + unsigned short getCompoundAttribute(int attributeNumber) + { return mCompoundAttributes[attributeNumber]; } /** * Creates a damage structure for a normal melee attack based on the @@ -259,6 +216,9 @@ class Being : public MovingObject */ virtual void setAction(Action action); + /** + * Sets the current action. + */ virtual Action getAction() const { return mAction; } @@ -267,16 +227,46 @@ class Being : public MovingObject */ virtual void move(); + /** + * FOR TESTING PURPOSES ONLY + * Sets a compound attribute. + * Remember, they're modified after a modifier is added. + */ + void setCompoundAttribute(int attributeNumber, unsigned short value) + { mCompoundAttributes[attributeNumber] = value; } + protected: + + /** + * Sets a base attribute. + */ + void setBaseAttribute(int attributeNumber, unsigned short value) + { mBaseAttributes[attributeNumber] = value; } + + /** + * Gets a derived attribute. + */ + unsigned short getBaseAttribute(int attributeNumber) const + { return mBaseAttributes[attributeNumber]; } + + /** + * Recalculates the compound attributes of a being. + */ + void recalculateAllCompoundAttributes(); + + void calculateCompoundAttribute(int attributeNumber); + int mHitpoints; /**< Hitpoints of the being */ Action mAction; - - Stats mStats; + BeingModificators mBeingModificators; private: Being(Being const &rhs); Being &operator=(Being const &rhs); + unsigned short mBaseAttributes[NB_BASE_ATTRIBUTES]; + unsigned short mCompoundAttributes[NB_COMPOUND_ATTRIBUTES]; + Hits mHitsTaken; /**< List of punches taken since last update */ }; diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp new file mode 100644 index 00000000..4aa0576d --- /dev/null +++ b/src/game-server/character.cpp @@ -0,0 +1,108 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "game-server/character.hpp" + +#include <cassert> + +#include "defines.h" +#include "net/messagein.hpp" + +InventoryItem tempItem; + +Character::Character(): + Being(OBJECT_CHARACTER, 65535), + mClient(NULL), + mDatabaseID(-1), mName(""), mGender(0), mHairStyle(0), mHairColor(0), + mLevel(0), mMoney(0) +{ + for (int i = 0; i < EQUIPMENT_SLOTS; ++i) + { + mPossessions.equipment[i] = 0; + } +} + +Character::Character(MessageIn & msg): + Being(OBJECT_CHARACTER, 65535), + mClient(NULL), + mDatabaseID(-1), mName(""), mGender(0), mHairStyle(0), mHairColor(0), + mLevel(0), mMoney(0) +{ + for (int i = 0; i < EQUIPMENT_SLOTS; ++i) + { + mPossessions.equipment[i] = 0; + } + deserialize(msg); + recalculateAllCompoundAttributes(); +} +/** + * Update the internal status. + */ +void +Character::update() +{ + // attacking + if (mAction == ATTACK) + { + // plausibility check of attack command + if (mActionTime <= 0) + { + // request perform attack + mActionTime = 1000; + mAction = STAND; + raiseUpdateFlags(UPDATEFLAG_ATTACK); + } + } +} + +int +Character::getNumberOfInventoryItems() const +{ + // TODO: implement after redesign/improvement of Inventory + return 0; +} + +InventoryItem const & +Character::getInventoryItem(unsigned short slot) const +{ + // TODO: implement after redesign/improvement of Inventory + //InventoryItem tempItem; + + tempItem.itemClassId = 0; + tempItem.numberOfItemsInSlot = 0; + tempItem.isEquiped = false; + + return tempItem; +} + +void +Character::clearInventory() +{ + // TODO: implement after redesign/improvement of Inventory +} + +void +Character::addItemToInventory(const InventoryItem& item) +{ + // TODO: implement after redesign/improvement of Inventory +} + diff --git a/src/game-server/character.hpp b/src/game-server/character.hpp new file mode 100644 index 00000000..42736a79 --- /dev/null +++ b/src/game-server/character.hpp @@ -0,0 +1,263 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMWSERV_CHARACTER_HPP_ +#define _TMWSERV_CHARACTER_HPP_ + +#include "abstractcharacterdata.hpp" +#include "game-server/being.hpp" + +#include <string> +#include <vector> + +class GameClient; +class MessageIn; +class Point; + + +struct Possessions +{ + unsigned short equipment[EQUIPMENT_SLOTS]; + std::vector< InventoryItem > inventory; +}; + +/** + * The representation of a player's character in the game world. + */ +class Character : public Being, public AbstractCharacterData +{ + public: + + /** + * Basic constructor + */ + Character(); + + /** + * Utility constructor for creating a Character from a received + * characterdata message. + */ + Character(MessageIn & msg); + + /** + * Updates the internal status. + */ + void update(); + + /** + * Gets client computer. + */ + GameClient *getClient() const + { return mClient; } + + /** + * Sets client computer. + */ + void setClient(GameClient *c) + { mClient = c; } + + /** + * Gets a reference on the possession. + * Used in the current Inventory class + */ + Possessions &getPossessions() + { return mPossessions; } + + + /** + * Character data: + * Get and set methods + */ + + /** Gets the database id of the character. */ + int + getDatabaseID() const + { return mDatabaseID; } + + /** Sets the database id of the character. */ + void + setDatabaseID(int id) + { mDatabaseID = id; } + + /** Gets the name of the character. */ + std::string const & + getName() const + { return mName; } + + /** Sets the name of the character. */ + void + setName(const std::string& name) + { mName = name; } + + /** Gets the gender of the character (male or female). */ + int + getGender() const + { return mGender;} + + /** Sets the gender of the character (male or female). */ + void + setGender(int gender) + { mGender = gender; } + + /** Gets the hairstyle of the character. */ + int + getHairStyle() const + { return mHairStyle; } + + /** Sets the hairstyle of the character. */ + void + setHairStyle(int style) + { mHairStyle = style; } + + /** Gets the haircolor of the character. */ + int + getHairColor() const + { return mHairColor; } + + /** Sets the haircolor of the character. */ + void + setHairColor(int color) + { mHairColor = color; } + + /** Gets the level of the character. */ + int + getLevel() const + { return mLevel; } + + /** Sets the level of the character. */ + void + setLevel(int level) + { mLevel = level; } + + /** Gets the amount of money the character has. */ + int + getMoney() const + { return mMoney; } + + /** Sets the amount of money the character has. */ + void + setMoney(int amount) + { mMoney = amount; } + + /** + * Gets the value of an attribute of the character. + * Inherited from Being, explicitly defined because + * of double inheritance. + */ + unsigned short + getBaseAttribute(int attributeNumber) const + { return Being::getBaseAttribute(attributeNumber); } + + /** + * Sets the value of an attribute of the character. + * Inherited from Being, explicitly defined because + * of double inheritance. + */ + void + setBaseAttribute(int attributeNumber, int value) + { Being::setBaseAttribute(attributeNumber, value); } + + /** + * Gets the Id of the map that the character is on. + * Inherited from Thing through Being, explicitly defined because + * of double inheritance. + */ + int + getMapId() const + { return Being::getMapId(); } + + /** + * Sets the Id of the map that the character is on. + * Inherited from Thing through Being, explicitly defined because + * of double inheritance. + */ + void + setMapId(int mapId) + { Being::setMapId(mapId); } + + /** + * Gets the position of the character on the map. + * Inherited from Object through Being, explicitly defined because + * of double inheritance. + */ + Point const & + getPosition() const + { return Being::getPosition(); } + + /** + * Sets the position of the character on the map. + * Inherited from Object through Being, explicitly defined because + * of double inheritance. + */ + void + setPosition(const Point &p) + { Being::setPosition(p); } + + /** + * The access functions for inventory + * + * Currently not implemented + */ + + /** + * Returns the number of inventory items. + * (items don't have to be unique) + * TODO: maybe renaming to NumberOfFilledSlots would be better. + */ + int + getNumberOfInventoryItems() const; + + /** + * Returns a reference to the item in inventory at slot. + * TODO: Keep this consistent with whatever is chosen for + * getNumberOfInventoryItems. + */ + InventoryItem const & + getInventoryItem(unsigned short slot) const; + + /** Clears the inventory, in preperation for an update. */ + void + clearInventory(); + + /** Adds an inventory item to the inventory. */ + void + addItemToInventory(const InventoryItem& item); + + + private: + Character(Character const &); + Character &operator=(Character const &); + + GameClient *mClient; /**< Client computer. */ + + int mDatabaseID; /**< Character's database ID. */ + std::string mName; /**< Name of the character. */ + unsigned char mGender; /**< Gender of the character. */ + unsigned char mHairStyle; /**< Hair Style of the character. */ + unsigned char mHairColor; /**< Hair Color of the character. */ + unsigned char mLevel; /**< Level of the character. */ + unsigned int mMoney; /**< Wealth of the being. */ + + Possessions mPossessions; /**< Possesssions of the character. */ +}; + +#endif // _TMWSERV_CHARACTER_HPP_ diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index d3da0526..7fd42f80 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -21,11 +21,12 @@ * $Id$ */ +#include "game-server/gamehandler.hpp" + #include <cassert> #include <map> #include "game-server/accountconnection.hpp" -#include "game-server/gamehandler.hpp" #include "game-server/inventory.hpp" #include "game-server/item.hpp" #include "game-server/itemmanager.hpp" @@ -49,13 +50,13 @@ struct GameClient: NetComputer { GameClient(ENetPeer *peer) : NetComputer(peer), character(NULL), status(CLIENT_LOGIN) {} - Player *character; + Character *character; int status; }; struct GamePendingLogin { - Player *character; + Character *character; int timeout; }; @@ -79,7 +80,7 @@ static GamePendingClients pendingClients; /** * Links a client to a character. */ -static void linkCharacter(GameClient *computer, Player *ch) +static void linkCharacter(GameClient *computer, Character *ch) { computer->character = ch; computer->status = CLIENT_CONNECTED; @@ -93,9 +94,9 @@ static void linkCharacter(GameClient *computer, Player *ch) /** * Notification that a particular token has been given to allow a certain - * player to enter the game. + * character to enter the game. */ -void registerGameClient(std::string const &token, Player *ch) +void registerGameClient(std::string const &token, Character *ch) { GamePendingClients::iterator i = pendingClients.find(token); if (i != pendingClients.end()) @@ -134,7 +135,7 @@ void GameHandler::computerDisconnected(NetComputer *computer) break; } } - if (Player *ch = static_cast< GameClient * >(computer)->character) + if (Character *ch = static_cast< GameClient * >(computer)->character) { gameState->remove(ch); delete ch; @@ -142,7 +143,7 @@ void GameHandler::computerDisconnected(NetComputer *computer) delete computer; } -void GameHandler::kill(Player *ch) +void GameHandler::kill(Character *ch) { GameClient *client = ch->getClient(); assert(client != NULL); @@ -150,7 +151,7 @@ void GameHandler::kill(Player *ch) client->status = CLIENT_LOGIN; } -void GameHandler::prepareServerChange(Player *ch) +void GameHandler::prepareServerChange(Character *ch) { GameClient *client = ch->getClient(); assert(client != NULL); @@ -299,7 +300,7 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) case PGMSG_ATTACK: { - LOG_DEBUG("Player " << computer.character->getPublicID() + LOG_DEBUG("Character " << computer.character->getPublicID() << " attacks"); computer.character->setDirection(message.readByte()); computer.character->setAction(Being::ATTACK); @@ -344,8 +345,12 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) computer.character->getDatabaseID(), magic_token); } - // TODO: check if the character's updated info is send to the database + // TODO: implement a delayed remove gameState->remove(computer.character); + + accountHandler->sendCharacterData(computer.character); + + // Done with the character delete computer.character; computer.character = NULL; computer.status = CLIENT_LOGIN; @@ -360,7 +365,7 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) computer.send(result); } -void GameHandler::sendTo(Player *beingPtr, MessageOut &msg) +void GameHandler::sendTo(Character *beingPtr, MessageOut &msg) { GameClient *client = beingPtr->getClient(); assert(client && client->status == CLIENT_CONNECTED); diff --git a/src/game-server/gamehandler.hpp b/src/game-server/gamehandler.hpp index faeff656..9f76e865 100644 --- a/src/game-server/gamehandler.hpp +++ b/src/game-server/gamehandler.hpp @@ -24,7 +24,7 @@ #ifndef _TMW_SERVER_GAMEHANDLER_ #define _TMW_SERVER_GAMEHANDLER_ -#include "game-server/player.hpp" +#include "game-server/character.hpp" #include "net/connectionhandler.hpp" /** @@ -44,22 +44,22 @@ class GameHandler: public ConnectionHandler bool startListen(enet_uint16 port); /** - * Sends message to the given player. + * Sends message to the given character. */ - void sendTo(Player *, MessageOut &msg); + void sendTo(Character *, MessageOut &msg); /** - * Kills connection with given player. + * Kills connection with given character. */ - void kill(Player *); + void kill(Character *); /** - * Prepares a server change for given player. + * Prepares a server change for given character. */ - void prepareServerChange(Player *); + void prepareServerChange(Character *); /** - * Completes a server change for given player ID. + * Completes a server change for given character ID. */ void completeServerChange(int id, std::string const &token, std::string const &address, int port); diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index 4b64728e..0d2a82f5 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -30,7 +30,10 @@ #include "game-server/itemmanager.hpp" #include "net/messageout.hpp" -Inventory::Inventory(Player *p) +// For the InventoryItem structure +#include "abstractcharacterdata.hpp" + +Inventory::Inventory(Character *p) : poss(p->getPossessions()), msg(GPMSG_INVENTORY), client(p) {} @@ -59,16 +62,16 @@ void Inventory::sendFull() const for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), i_end = poss.inventory.end(); i != i_end; ++i) { - if (i->itemId) + if (i->itemClassId) { m.writeByte(slot); - m.writeShort(i->itemId); - m.writeByte(i->amount); + m.writeShort(i->itemClassId); + m.writeByte(i->numberOfItemsInSlot); ++slot; } else { - slot += i->amount; + slot += i->numberOfItemsInSlot; } } @@ -82,10 +85,10 @@ int Inventory::getItem(int slot) const { if (slot == 0) { - return i->itemId; + return i->itemClassId; } - slot -= i->itemId ? 1 : i->amount; + slot -= i->itemClassId ? 1 : i->numberOfItemsInSlot; if (slot < 0) { @@ -106,7 +109,7 @@ int Inventory::getIndex(int slot) const return index; } - slot -= i->itemId ? 1 : i->amount; + slot -= i->itemClassId ? 1 : i->numberOfItemsInSlot; if (slot < 0) { @@ -122,7 +125,7 @@ int Inventory::getSlot(int index) const for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), i_end = poss.inventory.begin() + index; i != i_end; ++i) { - slot += i->itemId ? 1 : i->amount; + slot += i->itemClassId ? 1 : i->numberOfItemsInSlot; } return slot; } @@ -133,18 +136,18 @@ int Inventory::fillFreeSlot(int itemId, int amount, int maxPerSlot) for (int i = 0, i_end = poss.inventory.size(); i < i_end; ++i) { InventoryItem &it = poss.inventory[i]; - if (it.itemId == 0) + if (it.itemClassId == 0) { int nb = std::min(amount, maxPerSlot); - if (it.amount <= 1) + if (it.numberOfItemsInSlot <= 1) { - it.itemId = itemId; - it.amount = nb; + it.itemClassId = itemId; + it.numberOfItemsInSlot = nb; } else { - --it.amount; - InventoryItem iu = { itemId, nb }; + --it.numberOfItemsInSlot; + InventoryItem iu = { itemId, nb, false }; poss.inventory.insert(poss.inventory.begin() + i, iu); ++i_end; } @@ -166,7 +169,7 @@ int Inventory::fillFreeSlot(int itemId, int amount, int maxPerSlot) { int nb = std::min(amount, maxPerSlot); amount -= nb; - InventoryItem it = { itemId, nb }; + InventoryItem it = { itemId, nb, false }; poss.inventory.push_back(it); msg.writeByte(slot + EQUIP_CLIENT_INVENTORY); @@ -186,15 +189,15 @@ int Inventory::insert(int itemId, int amount) for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), i_end = poss.inventory.end(); i != i_end; ++i) { - if (i->itemId == itemId) + if (i->itemClassId == itemId) { - int nb = std::min(maxPerSlot - i->amount, amount); - i->amount += nb; + int nb = std::min(maxPerSlot - i->numberOfItemsInSlot, amount); + i->numberOfItemsInSlot += nb; amount -= nb; msg.writeByte(slot + EQUIP_CLIENT_INVENTORY); msg.writeShort(itemId); - msg.writeByte(i->amount); + msg.writeByte(i->numberOfItemsInSlot); if (amount == 0) { @@ -204,7 +207,7 @@ int Inventory::insert(int itemId, int amount) } else { - slot += i->itemId ? 1 : i->amount; + slot += i->itemClassId ? 1 : i->numberOfItemsInSlot; } } @@ -218,9 +221,9 @@ int Inventory::count(int itemId) const for (std::vector< InventoryItem >::iterator i = poss.inventory.begin(), i_end = poss.inventory.end(); i != i_end; ++i) { - if (i->itemId == itemId) + if (i->itemClassId == itemId) { - nb += i->amount; + nb += i->numberOfItemsInSlot; } } @@ -235,22 +238,23 @@ void Inventory::freeIndex(int i) { poss.inventory.pop_back(); } - else if (poss.inventory[i + 1].itemId == 0) + else if (poss.inventory[i + 1].itemClassId == 0) { - it.itemId = 0; - it.amount = poss.inventory[i + 1].amount + 1; + it.itemClassId = 0; + it.numberOfItemsInSlot = poss.inventory[i + 1].numberOfItemsInSlot + 1; poss.inventory.erase(poss.inventory.begin() + i + 1); } else { - it.itemId = 0; - it.amount = 1; + it.itemClassId = 0; + it.numberOfItemsInSlot = 1; } - if (i > 0 && poss.inventory[i - 1].itemId == 0) + if (i > 0 && poss.inventory[i - 1].itemClassId == 0) { // Note: "it" is no longer a valid iterator. - poss.inventory[i - 1].amount += poss.inventory[i].amount; + poss.inventory[i - 1].numberOfItemsInSlot + += poss.inventory[i].numberOfItemsInSlot; poss.inventory.erase(poss.inventory.begin() + i); } } @@ -260,18 +264,18 @@ int Inventory::remove(int itemId, int amount) for (int i = poss.inventory.size() - 1; i >= 0; --i) { InventoryItem &it = poss.inventory[i]; - if (it.itemId == itemId) + if (it.itemClassId == itemId) { - int nb = std::min((int)it.amount, amount); - it.amount -= nb; + int nb = std::min((int)it.numberOfItemsInSlot, amount); + it.numberOfItemsInSlot -= nb; amount -= nb; msg.writeByte(getSlot(i) + EQUIP_CLIENT_INVENTORY); msg.writeShort(itemId); - msg.writeByte(it.amount); + msg.writeByte(it.numberOfItemsInSlot); // If the slot is empty, compress the inventory. - if (it.amount == 0) + if (it.numberOfItemsInSlot == 0) { freeIndex(i); } @@ -296,16 +300,16 @@ int Inventory::removeFromSlot(int slot, int amount) } InventoryItem &it = poss.inventory[i]; - int nb = std::min((int)it.amount, amount); - it.amount -= nb; + int nb = std::min((int)it.numberOfItemsInSlot, amount); + it.numberOfItemsInSlot -= nb; amount -= nb; msg.writeByte(slot + EQUIP_CLIENT_INVENTORY); - msg.writeShort(it.itemId); - msg.writeByte(it.amount); + msg.writeShort(it.itemClassId); + msg.writeByte(it.numberOfItemsInSlot); // If the slot is empty, compress the inventory. - if (it.amount == 0) + if (it.numberOfItemsInSlot == 0) { freeIndex(i); } @@ -430,5 +434,5 @@ bool Inventory::equip(int slot) default: return false; - } + } } diff --git a/src/game-server/inventory.hpp b/src/game-server/inventory.hpp index 06a4ad03..65d010d7 100644 --- a/src/game-server/inventory.hpp +++ b/src/game-server/inventory.hpp @@ -24,8 +24,7 @@ #ifndef INVENTORY_H #define INVENTORY_H -#include "playerdata.hpp" -#include "game-server/player.hpp" +#include "game-server/character.hpp" #include "net/messageout.hpp" enum @@ -62,16 +61,16 @@ enum class GameClient; /** - * Class used to handle Player possessions and prepare outgoing messages. + * Class used to handle Character possessions and prepare outgoing messages. */ class Inventory { Possessions &poss; MessageOut msg; - Player *client; + Character *client; public: - Inventory(Player *); + Inventory(Character *); /** * Sends the update message to the client. diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp index 9345e33e..e3934202 100644 --- a/src/game-server/item.cpp +++ b/src/game-server/item.cpp @@ -31,11 +31,9 @@ bool ItemClass::use(Being *itemUser) // Calling a script if scriptName != "" if (!mScriptName.empty()) - { - return (runScript(itemUser) && usedSuccessfully); - } - else - return usedSuccessfully; + return (runScript(itemUser) && usedSuccessfully); + + return usedSuccessfully; } bool ItemClass::runScript(Being *itemUser) diff --git a/src/game-server/item.hpp b/src/game-server/item.hpp index 40a687ab..08965076 100644 --- a/src/game-server/item.hpp +++ b/src/game-server/item.hpp @@ -24,7 +24,10 @@ #ifndef _TMWSERV_ITEM #define _TMWSERV_ITEM -#include "game-server/player.hpp" +// For NB_BASE_ATTRIBUTES and NB_DERIVED_ATTRIBUTES +#include "defines.h" + +#include "game-server/character.hpp" /** * Enumeration of available Item types. @@ -71,31 +74,31 @@ enum }; /** - * States attribute effects to beings, and actors. + * State effects to beings, and actors. * States can be multiple for the same being. */ enum { - STATE_NORMAL = 0, - STATE_POISONED, - STATE_STONED, - STATE_STUNNED, - STATE_SLOWED, - STATE_TIRED, - STATE_MAD, - STATE_BERSERK, - STATE_HASTED, - STATE_FLOATING, - - STATE_NOT_POISONED, - STATE_NOT_STONED, - STATE_NOT_STUNNED, - STATE_NOT_SLOWED, - STATE_NOT_TIRED, - STATE_NOT_MAD, - STATE_NOT_BERSERK, - STATE_NOT_HASTED, - STATE_NOT_FLOATING + SET_STATE_NORMAL = 0, + SET_STATE_POISONED, + SET_STATE_STONED, + SET_STATE_STUNNED, + SET_STATE_SLOWED, + SET_STATE_TIRED, + SET_STATE_MAD, + SET_STATE_BERSERK, + SET_STATE_HASTED, + SET_STATE_FLOATING, + + SET_STATE_NOT_POISONED, + SET_STATE_NOT_STONED, + SET_STATE_NOT_STUNNED, + SET_STATE_NOT_SLOWED, + SET_STATE_NOT_TIRED, + SET_STATE_NOT_MAD, + SET_STATE_NOT_BERSERK, + SET_STATE_NOT_HASTED, + SET_STATE_NOT_FLOATING }; /** @@ -110,8 +113,9 @@ struct Modifiers unsigned char beingStateEffect; /**< Being State (dis)alteration */ unsigned short lifetime; /**< Modifiers lifetime in seconds. */ - // Caracteristics Modifiers - short stat[Player::NB_STATS_PLAYER]; /**< Stat modifiers */ + // Characteristics Modifiers + short baseAttributes[NB_BASE_ATTRIBUTES]; /**< Raw Stats modifiers */ + short derivedAttributes[NB_COMPOUND_ATTRIBUTES - NB_BASE_ATTRIBUTES]; /**< Computed Stats modifiers */ // Weapon unsigned short range; /**< Weapon Item Range */ @@ -223,7 +227,7 @@ class ItemClass // Item reference information unsigned short mDatabaseID; - unsigned short mSpriteID; /**< The sprite that should be shown to the player */ + unsigned short mSpriteID; /**< The sprite that should be shown to the character */ unsigned char mType; /**< Type: usable, equipment. */ unsigned short mWeight; /**< Weight of the item. */ unsigned short mCost; /**< Unit cost the item. */ diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index ea060d06..a372906c 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -21,8 +21,10 @@ * $Id$ */ -#include "resourcemanager.h" #include "game-server/itemmanager.hpp" + +#include "defines.h" +#include "resourcemanager.h" #include "utils/logger.h" #include "utils/xml.hpp" @@ -81,25 +83,29 @@ ItemManager::ItemManager(std::string const &itemReferenceFile) int maxPerSlot = XML::getProperty(node, "max_per_slot", 0); std::string scriptName = XML::getProperty(node, "script_name", std::string()); + //TODO: add child nodes for these modifiers (additive and factor) Modifiers modifiers; modifiers.element = XML::getProperty(node, "element", 0); modifiers.lifetime = XML::getProperty(node, "lifetime", 0); - modifiers.stat[Player::STRENGTH] = XML::getProperty(node, "strength", 0); - modifiers.stat[Player::AGILITY] = XML::getProperty(node, "agility", 0); - modifiers.stat[Player::VITALITY] = XML::getProperty(node, "vitality", 0); - modifiers.stat[Player::INTELLIGENCE] = XML::getProperty(node, "intelligence", 0); - modifiers.stat[Player::DEXTERITY] = XML::getProperty(node, "dexterity", 0); - modifiers.stat[Player::WILLPOWER] = XML::getProperty(node, "willpower", 0); - modifiers.stat[Player::CHARISMA] = XML::getProperty(node, "charisma", 0); - - modifiers.stat[Being::STAT_HP_MAXIMUM] = XML::getProperty(node, "hp", 0); - modifiers.stat[Being::STAT_PHYSICAL_ATTACK_MINIMUM] = XML::getProperty(node, "attack", 0); - modifiers.stat[Being::STAT_PHYSICAL_DEFENCE] = XML::getProperty(node, "defence", 0); - - + modifiers.baseAttributes[ATT_STRENGTH] = XML::getProperty(node, "strength", 0); + modifiers.baseAttributes[ATT_AGILITY] = XML::getProperty(node, "agility", 0); + modifiers.baseAttributes[ATT_VITALITY] = XML::getProperty(node, "vitality", 0); + modifiers.baseAttributes[ATT_INTELLIGENCE] = XML::getProperty(node, "intelligence", 0); + modifiers.baseAttributes[ATT_DEXTERITY] = XML::getProperty(node, "dexterity", 0); + modifiers.baseAttributes[ATT_LUCK] = XML::getProperty(node, "luck", 0); +/** modifiers.baseAttributes[ATT_WILLPOWER] = XML::getProperty(node, "willpower", 0); + modifiers.baseAttributes[ATT_CHARISMA] = XML::getProperty(node, "charisma", 0);*/ + modifiers.derivedAttributes[ATT_HP_MAXIMUM] = XML::getProperty(node, "hp", 0); + modifiers.derivedAttributes[ATT_PHYSICAL_ATTACK_MINIMUM] = XML::getProperty(node, "attack", 0); + modifiers.derivedAttributes[ATT_PHYSICAL_DEFENCE] = XML::getProperty(node, "defence", 0); + modifiers.derivedAttributes[ATT_MAGIC] = XML::getProperty(node, "magic", 0); + modifiers.derivedAttributes[ATT_ACCURACY] = XML::getProperty(node, "accuracy", 0); + modifiers.derivedAttributes[ATT_SPEED] = XML::getProperty(node, "speed", 0); +/** modifiers.hp = XML::getProperty(node, "hp", 0); + modifiers.mp = XML::getProperty(node, "mp", 0);*/ modifiers.range = XML::getProperty(node, "range", 0); modifiers.weaponType = XML::getProperty(node, "weapon_type", 0); - modifiers.beingStateEffect = XML::getProperty(node, "status_effect", 0); +/** modifiers.beingStateEffect = XML::getProperty(node, "status_effect", 0);*/ ItemClass *item = new ItemClass(id, itemType); item->setWeight(weight); diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index 0250d14a..5ca2330b 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -27,7 +27,7 @@ #include "point.h" #include "game-server/map.hpp" #include "game-server/mapcomposite.hpp" -#include "game-server/player.hpp" +#include "game-server/character.hpp" /* TODO: Implement overlapping map zones instead of strict partitioning. Purpose: to decrease the number of zone changes, as overlapping allows for @@ -48,25 +48,25 @@ void MapZone::insert(Object *obj) int type = obj->getType(); switch (type) { - case OBJECT_PLAYER: + case OBJECT_CHARACTER: { - if (nbPlayers != nbMovingObjects) + if (nbCharacters != nbMovingObjects) { if (nbMovingObjects != objects.size()) { objects.push_back(objects[nbMovingObjects]); - objects[nbMovingObjects] = objects[nbPlayers]; + objects[nbMovingObjects] = objects[nbCharacters]; } else { - objects.push_back(objects[nbPlayers]); + objects.push_back(objects[nbCharacters]); } - objects[nbPlayers] = obj; - ++nbPlayers; + objects[nbCharacters] = obj; + ++nbCharacters; ++nbMovingObjects; break; } - ++nbPlayers; + ++nbCharacters; } // no break! case OBJECT_MONSTER: case OBJECT_NPC: @@ -93,15 +93,15 @@ void MapZone::remove(Object *obj) int type = obj->getType(); switch (type) { - case OBJECT_PLAYER: + case OBJECT_CHARACTER: { i = i_beg; - i_end = objects.begin() + nbPlayers; + i_end = objects.begin() + nbCharacters; } break; case OBJECT_MONSTER: case OBJECT_NPC: { - i = objects.begin() + nbPlayers; + i = objects.begin() + nbCharacters; i_end = objects.begin() + nbMovingObjects; } break; default: @@ -113,11 +113,11 @@ void MapZone::remove(Object *obj) i = std::find(i, i_end, obj); assert(i != i_end); unsigned pos = i - i_beg; - if (pos < nbPlayers) + if (pos < nbCharacters) { - objects[pos] = objects[nbPlayers - 1]; - pos = nbPlayers - 1; - --nbPlayers; + objects[pos] = objects[nbCharacters - 1]; + pos = nbCharacters - 1; + --nbCharacters; } if (pos < nbMovingObjects) { @@ -164,26 +164,26 @@ void ZoneIterator::operator++() } } -PlayerIterator::PlayerIterator(ZoneIterator const &it) +CharacterIterator::CharacterIterator(ZoneIterator const &it) : iterator(it), pos(0) { - while (iterator && (*iterator)->nbPlayers == 0) ++iterator; + while (iterator && (*iterator)->nbCharacters == 0) ++iterator; if (iterator) { - current = static_cast< Player * >((*iterator)->objects[pos]); + current = static_cast< Character * >((*iterator)->objects[pos]); } } -void PlayerIterator::operator++() +void CharacterIterator::operator++() { - if (++pos == (*iterator)->nbPlayers) + if (++pos == (*iterator)->nbCharacters) { - do ++iterator; while (iterator && (*iterator)->nbPlayers == 0); + do ++iterator; while (iterator && (*iterator)->nbCharacters == 0); pos = 0; } if (iterator) { - current = static_cast< Player * >((*iterator)->objects[pos]); + current = static_cast< Character * >((*iterator)->objects[pos]); } } @@ -442,7 +442,7 @@ ZoneIterator MapComposite::getInsideRectangleIterator(Rectangle const &p) const return ZoneIterator(r, this); } -ZoneIterator MapComposite::getAroundPlayerIterator(MovingObject *obj, int radius) const +ZoneIterator MapComposite::getAroundCharacterIterator(MovingObject *obj, int radius) const { MapRegion r1; fillRegion(r1, obj->getOldPosition(), radius); diff --git a/src/game-server/mapcomposite.hpp b/src/game-server/mapcomposite.hpp index 8de50962..0fd9dbde 100644 --- a/src/game-server/mapcomposite.hpp +++ b/src/game-server/mapcomposite.hpp @@ -30,7 +30,7 @@ class Map; class MapComposite; class MovingObject; class Object; -class Player; +class Character; class Point; class Rectangle; class Thing; @@ -45,10 +45,10 @@ typedef std::vector< unsigned > MapRegion; */ struct MapZone { - unsigned short nbPlayers, nbMovingObjects; + unsigned short nbCharacters, nbMovingObjects; /** * Objects present in this zone. - * Players are stored first, then the remaining MovingObjects, then the + * Characters are stored first, then the remaining MovingObjects, then the * remaining Objects. */ std::vector< Object * > objects; @@ -60,7 +60,7 @@ struct MapZone */ MapRegion destinations; - MapZone(): nbPlayers(0), nbMovingObjects(0) {} + MapZone(): nbCharacters(0), nbMovingObjects(0) {} void insert(Object *); void remove(Object *); }; @@ -82,17 +82,17 @@ struct ZoneIterator }; /** - * Iterates through the Players of a region. + * Iterates through the Characters of a region. */ -struct PlayerIterator +struct CharacterIterator { ZoneIterator iterator; unsigned short pos; - Player *current; + Character *current; - PlayerIterator(ZoneIterator const &); + CharacterIterator(ZoneIterator const &); void operator++(); - Player *operator*() const { return current; } + Character *operator*() const { return current; } operator bool() const { return iterator; } }; @@ -221,9 +221,9 @@ class MapComposite /** * Gets an iterator on the objects around the old and new positions of - * a player (including the ones that were but are now elsewhere). + * a character (including the ones that were but are now elsewhere). */ - ZoneIterator getAroundPlayerIterator(MovingObject *, int radius) const; + ZoneIterator getAroundCharacterIterator(MovingObject *, int radius) const; /** * Gets everything related to the map. @@ -257,7 +257,7 @@ class MapComposite Map *map; /**< Actual map. */ /** - * Things (items, players, monsters, etc) located on the map. + * Things (items, characters, monsters, etc) located on the map. */ std::vector< Thing * > things; diff --git a/src/game-server/object.hpp b/src/game-server/object.hpp index b067b34b..3071f710 100644 --- a/src/game-server/object.hpp +++ b/src/game-server/object.hpp @@ -36,7 +36,7 @@ enum OBJECT_ACTOR, // An item that toggle map/quest actions (doors, switchs, ...) and can speak (map panels). OBJECT_NPC, // Non-Playable-Character is an actor capable of movement and maybe actions OBJECT_MONSTER, // A monster (moving actor with AI. Should be able to toggle map/quest actions, too) - OBJECT_PLAYER, // A normal being + OBJECT_CHARACTER,// A normal being OBJECT_OTHER // Server-only object }; @@ -87,14 +87,14 @@ class Thing * Returns whether this thing can move on the map or not. (MovingObject) */ bool canMove() const - { return mType == OBJECT_PLAYER || mType == OBJECT_MONSTER || + { return mType == OBJECT_CHARACTER || mType == OBJECT_MONSTER || mType == OBJECT_NPC; } /** * Returns whether this thing can fight or not. (Being) */ bool canFight() const - { return mType == OBJECT_PLAYER || mType == OBJECT_MONSTER; } + { return mType == OBJECT_CHARACTER || mType == OBJECT_MONSTER; } /** * Updates the internal status. diff --git a/src/game-server/player.cpp b/src/game-server/player.cpp deleted file mode 100644 index 923d2513..00000000 --- a/src/game-server/player.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include <cassert> - -#include "defines.h" -#include "game-server/player.hpp" - -Player::Player(std::string const &name, int id) - : Being(OBJECT_PLAYER, 65535), - PlayerData(name, id), - mClient(NULL) -{ - mStats.base.resize(NB_STATS_PLAYER, 1); //TODO: fill with the real values - mStats.absoluteModificator.resize(NB_STATS_PLAYER, 0); - mStats.percentModificators.resize(NB_STATS_PLAYER); - - // some bogus values for testing purpose - mStats.base.at(STRENGTH) = 10; - mStats.base.at(SKILL_WEAPON_UNARMED) = 5; - - calculateBaseStats(); - - mHitpoints = getRealStat(STAT_HP_MAXIMUM); - mSize = 16; -} - -/** - * Update the internal status. - */ -void Player::update() -{ - // attacking - if (mAction == ATTACK) - { - // plausibility check of attack command - if (mActionTime <= 0) - { - // request perform attack - mActionTime = 1000; - mAction = STAND; - raiseUpdateFlags(UPDATEFLAG_ATTACK); - } - } -} - -void Player::calculateBaseStats() -{ - mStats.base.at(STAT_HP_MAXIMUM) - = getRealStat(VITALITY); - - mStats.base.at(STAT_PHYSICAL_ATTACK_MINIMUM) - = getRealStat(STRENGTH) /* + weapon damage fluctuation*/; - - // TODO: get the skill that is skill required for weapon - mStats.base.at(STAT_PHYSICAL_ATTACK_FLUCTUATION) - = getRealStat(SKILL_WEAPON_UNARMED) /* + weapon damage fluctuation*/; - - mStats.base.at(STAT_PHYSICAL_DEFENCE) - = 42 /* + sum of equipment pieces */; -} diff --git a/src/game-server/player.hpp b/src/game-server/player.hpp deleted file mode 100644 index 76c3f591..00000000 --- a/src/game-server/player.hpp +++ /dev/null @@ -1,136 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _TMWSERV_PLAYER_H_ -#define _TMWSERV_PLAYER_H_ - -#include <string> -#include <vector> - -#include "playerdata.hpp" -#include "game-server/being.hpp" - -class GameClient; - -/** - * Actions for a player being. - */ -enum -{ - PLAYER_STAND = 0, - PLAYER_SIT, - PLAYER_ATTACK -}; - -/** - * Stores the data of a remote client. - */ -class Player : public Being, public PlayerData -{ - public: - - /** - * Base attributes of a player character - */ - enum Attributes - { - STRENGTH = NB_STATS_BEING, - AGILITY, - DEXTERITY, - VITALITY, - INTELLIGENCE, - WILLPOWER, - CHARISMA, - NB_ATTRIBUTES - }; - - enum WeaponSkills - { - SKILL_WEAPON_UNARMED = NB_ATTRIBUTES, - SKILL_WEAPON_SWORD, - SKILL_WEAPON_AXE, - SKILL_WEAPON_POLEARM, - SKILL_WEAPON_JAVELIN, - SKILL_WEAPON_WHIP, - SKILL_WEAPON_DAGGER, - SKILL_WEAPON_STAFF, - SKILL_WEAPON_BOW, - SKILL_WEAPON_CROSSBOW, - SKILL_WEAPON_THROWN, - NB_WEAPONSKILLS - }; - - enum MagicSkills - { - SKILL_MAGIC_IAMJUSTAPLACEHOLDER = NB_WEAPONSKILLS, - NB_MAGICSKILLS - }; - - enum CraftSkills - { - SKILL_CRAFT_IAMJUSTAPLACEHOLDER = NB_MAGICSKILLS, - NB_CRAFTSKILLS - }; - - enum OtherSkills - { - SKILL_IAMJUSTAPLACEHOLDER = NB_CRAFTSKILLS, - NB_OTHERSKILLS - } - - static const NB_STATS_PLAYER = NB_OTHERSKILLS; - - Player(std::string const &name, int id = -1); - - /** - * Updates the internal status. - */ - void update(); - - /** - * Gets client computer. - */ - GameClient *getClient() const - { return mClient; } - - /** - * Sets client computer. - */ - void setClient(GameClient *c) - { mClient = c; } - - /** - * Recalculates all player stats that are derived from others. - * Call whenever you change something that affects a derived stat. - * Called automatically when you manipulate a stat using setBaseStat() - */ - virtual void calculateBaseStats(); - - - private: - Player(Player const &); - Player &operator=(Player const &); - - GameClient *mClient; /**< Client computer. */ -}; - -#endif // _TMWSERV_PLAYER_H_ diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 0c392da8..9a58edc7 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -82,14 +82,14 @@ void State::updateMap(MapComposite *map) map->update(); } -void State::informPlayer(MapComposite *map, Player *p) +void State::informPlayer(MapComposite *map, Character *p) { MessageOut moveMsg(GPMSG_BEINGS_MOVE); MessageOut damageMsg(GPMSG_BEINGS_DAMAGE); Point pold = p->getOldPosition(), ppos = p->getPosition(); int pid = p->getPublicID(), pflags = p->getUpdateFlags(); - for (MovingObjectIterator i(map->getAroundPlayerIterator(p, AROUND_AREA)); i; ++i) + for (MovingObjectIterator i(map->getAroundCharacterIterator(p, AROUND_AREA)); i; ++i) { MovingObject *o = *i; @@ -140,7 +140,7 @@ void State::informPlayer(MapComposite *map, Player *p) } } - // Check if this player and this moving object were around. + // Check if this character and this moving object were around. bool wereInRange = pold.inRangeOf(oold, AROUND_AREA) && !((pflags | oflags) & UPDATEFLAG_NEW_ON_MAP); @@ -162,9 +162,9 @@ void State::informPlayer(MapComposite *map, Player *p) enterMsg.writeShort(opos.x); enterMsg.writeShort(opos.y); switch (otype) { - case OBJECT_PLAYER: + case OBJECT_CHARACTER: { - Player *q = static_cast< Player * >(o); + Character *q = static_cast< Character * >(o); enterMsg.writeString(q->getName()); enterMsg.writeByte(q->getHairStyle()); enterMsg.writeByte(q->getHairColor()); @@ -234,7 +234,7 @@ void State::informPlayer(MapComposite *map, Player *p) gameHandler->sendTo(p, damageMsg); MessageOut itemMsg(GPMSG_ITEMS); - for (FixedObjectIterator i(map->getAroundPlayerIterator(p, AROUND_AREA)); i; ++i) + for (FixedObjectIterator i(map->getAroundCharacterIterator(p, AROUND_AREA)); i; ++i) { assert((*i)->getType() == OBJECT_ITEM); Item *o = static_cast< Item * >(*i); @@ -276,7 +276,7 @@ void State::update() MapComposite *map = m->second; updateMap(map); - for (PlayerIterator p(map->getWholeMapIterator()); p; ++p) + for (CharacterIterator p(map->getWholeMapIterator()); p; ++p) { informPlayer(map, *p); } @@ -303,9 +303,9 @@ void State::update() case EVENT_REMOVE: { remove(o); - if (o->getType() == OBJECT_PLAYER) + if (o->getType() == OBJECT_CHARACTER) { - gameHandler->kill(static_cast< Player * >(o)); + gameHandler->kill(static_cast< Character * >(o)); } delete o; } break; @@ -322,14 +322,14 @@ void State::update() o->setMapId(e.map); o->setPosition(pos); - assert(o->getType() == OBJECT_PLAYER); - Player *p = static_cast< Player * >(o); + assert(o->getType() == OBJECT_CHARACTER); + Character *p = static_cast< Character * >(o); /* Force update of persistent data on map change, so that - players can respawn at the start of the map after a death or + characters can respawn at the start of the map after a death or a disconnection. */ - p->setMap(e.map); - p->setPos(pos); - accountHandler->sendPlayerData(p); + p->setMapId(e.map); + p->setPosition(pos); + accountHandler->sendCharacterData(p); if (mapManager->isActive(e.map)) { @@ -362,16 +362,16 @@ void State::insert(Thing *ptr) { Object *obj = static_cast< Object * >(ptr); obj->raiseUpdateFlags(UPDATEFLAG_NEW_ON_MAP); - if (obj->getType() != OBJECT_PLAYER) return; + if (obj->getType() != OBJECT_CHARACTER) return; - /* Since the player doesn't know yet where on the world he is after + /* Since the character doesn't know yet where on the world he is after connecting to the map server, we send him an initial change map message. */ MessageOut mapChangeMessage(GPMSG_PLAYER_MAP_CHANGE); mapChangeMessage.writeString(mapManager->getMapName(mapId)); Point pos = obj->getPosition(); mapChangeMessage.writeShort(pos.x); mapChangeMessage.writeShort(pos.y); - gameHandler->sendTo(static_cast< Player * >(obj), mapChangeMessage); + gameHandler->sendTo(static_cast< Character * >(obj), mapChangeMessage); } } @@ -389,7 +389,7 @@ void State::remove(Thing *ptr) msg.writeShort(obj->getPublicID()); Point objectPos = obj->getPosition(); - for (PlayerIterator p(map->getAroundObjectIterator(obj, AROUND_AREA)); p; ++p) + for (CharacterIterator p(map->getAroundObjectIterator(obj, AROUND_AREA)); p; ++p) { if (*p != obj && objectPos.inRangeOf((*p)->getPosition(), AROUND_AREA)) { @@ -406,7 +406,7 @@ void State::remove(Thing *ptr) msg.writeShort(pos.x); msg.writeShort(pos.y); - for (PlayerIterator p(map->getAroundObjectIterator(obj, AROUND_AREA)); p; ++p) + for (CharacterIterator p(map->getAroundObjectIterator(obj, AROUND_AREA)); p; ++p) { if (pos.inRangeOf((*p)->getPosition(), AROUND_AREA)) { @@ -462,7 +462,7 @@ void State::sayAround(Object *obj, std::string text) MapComposite *map = getMap(obj->getMapId()); Point speakerPosition = obj->getPosition(); - for (PlayerIterator i(map->getAroundObjectIterator(obj, AROUND_AREA)); i; ++i) + for (CharacterIterator i(map->getAroundObjectIterator(obj, AROUND_AREA)); i; ++i) { if (speakerPosition.inRangeOf((*i)->getPosition(), AROUND_AREA)) { diff --git a/src/game-server/state.hpp b/src/game-server/state.hpp index 44c71600..80db0461 100644 --- a/src/game-server/state.hpp +++ b/src/game-server/state.hpp @@ -30,7 +30,7 @@ class MapComposite; class Thing; class Object; -class Player; +class Character; enum { @@ -69,9 +69,9 @@ class State void updateMap(MapComposite *); /** - * Informs a player of what happened around. + * Informs a player of what happened around the character. */ - void informPlayer(MapComposite *, Player *); + void informPlayer(MapComposite *, Character *); /** * Loads map into game world. diff --git a/src/game-server/testing.cpp b/src/game-server/testing.cpp index 7c3f87af..e09f4feb 100644 --- a/src/game-server/testing.cpp +++ b/src/game-server/testing.cpp @@ -5,6 +5,8 @@ #include <cassert> #include "controller.h" + +#include "defines.h" #include "game-server/itemmanager.hpp" #include "game-server/state.hpp" #include "game-server/trigger.hpp" @@ -39,12 +41,12 @@ void testingMap(int id) being->setSize(8); // some bogus stats for testing - being->setBaseStat(Being::STAT_HP_MAXIMUM, 42); - being->setBaseStat(Being::STAT_PHYSICAL_ATTACK_MINIMUM, 1); - being->setBaseStat(Being::STAT_PHYSICAL_ATTACK_FLUCTUATION, 0); - being->setBaseStat(Being::STAT_PHYSICAL_DEFENCE, 5); + being->setCompoundAttribute(ATT_HP_MAXIMUM, 42); + being->setCompoundAttribute(ATT_PHYSICAL_ATTACK_MINIMUM, 1); + being->setCompoundAttribute(ATT_PHYSICAL_ATTACK_FLUCTUATION, 0); + being->setCompoundAttribute(ATT_PHYSICAL_DEFENCE, 5); - being->setHitpoints(being->getRealStat(Being::STAT_HP_MAXIMUM)); + being->setHitpoints(42); being->setMapId(1); Point pos(720, 900); diff --git a/src/game-server/trigger.cpp b/src/game-server/trigger.cpp index 469fb544..4e593f4f 100644 --- a/src/game-server/trigger.cpp +++ b/src/game-server/trigger.cpp @@ -28,7 +28,7 @@ void WarpAction::process(Object *obj) { - if (obj->getType() == OBJECT_PLAYER) + if (obj->getType() == OBJECT_CHARACTER) { DelayedEvent e = { EVENT_WARP, mMap, mX, mY }; gameState->enqueueEvent(obj, e); diff --git a/src/playerdata.cpp b/src/playerdata.cpp deleted file mode 100644 index 52f35e98..00000000 --- a/src/playerdata.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * The Mana World Server - * Copyright 2007 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include "playerdata.hpp" -#include "net/messagein.hpp" -#include "net/messageout.hpp" - -PlayerData::PlayerData(std::string const &name, int id): - mAccountID(-1), - mDatabaseID(id), - mName(name) -{ - for (int j = 0; j < EQUIPMENT_SLOTS; ++j) - { - mPossessions.equipment[j] = 0; - } -} - -void PlayerData::serialize(MessageOut &msg) const -{ - msg.writeByte(mGender); - msg.writeByte(mHairStyle); - msg.writeByte(mHairColor); - msg.writeByte(mLevel); - msg.writeShort(mMoney); - for (int j = 0; j < NB_RSTAT; ++j) - { - msg.writeByte(mRawStats.stats[j]); - } - msg.writeShort(mMapId); - msg.writeShort(mPos.x); - msg.writeShort(mPos.y); - for (int j = 0; j < EQUIPMENT_SLOTS; ++j) - { - msg.writeShort(mPossessions.equipment[j]); - } - for (std::vector< InventoryItem >::const_iterator j = mPossessions.inventory.begin(), - j_end = mPossessions.inventory.end(); j != j_end; ++j) - { - msg.writeShort(j->itemId); - msg.writeByte(j->amount); - } -} - -void PlayerData::deserialize(MessageIn &msg) -{ - mGender = msg.readByte(); - mHairStyle = msg.readByte(); - mHairColor = msg.readByte(); - mLevel = msg.readByte(); - mMoney = msg.readShort(); - for (int j = 0; j < NB_RSTAT; ++j) - { - mRawStats.stats[j] = msg.readByte(); - } - mMapId = msg.readShort(); - mPos.x = msg.readShort(); - mPos.y = msg.readShort(); - for (int j = 0; j < EQUIPMENT_SLOTS; ++j) - { - mPossessions.equipment[j] = msg.readShort(); - } - mPossessions.inventory.clear(); - while (msg.getUnreadLength()) - { - InventoryItem i; - i.itemId = msg.readShort(); - i.amount = msg.readByte(); - mPossessions.inventory.push_back(i); - } -} diff --git a/src/playerdata.hpp b/src/playerdata.hpp deleted file mode 100644 index 1c5b1ad9..00000000 --- a/src/playerdata.hpp +++ /dev/null @@ -1,301 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _TMWSERV_PLAYERDATA -#define _TMWSERV_PLAYERDATA - -#include <string> -#include <vector> - -#include "point.h" - -class MessageIn; -class MessageOut; - -/** - * Gender of a Player. - */ -enum -{ - GENDER_MALE = 0, - GENDER_FEMALE -}; - -/** - * Raw statistics of a Player. - */ -enum -{ - STAT_STRENGTH = 0, - STAT_AGILITY, - STAT_VITALITY, - STAT_INTELLIGENCE, - STAT_DEXTERITY, - STAT_LUCK, - NB_RSTAT -}; - -/** - * Structure storing the raw statistics of a Player. - */ -struct RawStatistics -{ - unsigned short stats[NB_RSTAT]; -}; - -/** - * Numbers of inventory slots - */ - -enum -{ - EQUIPMENT_SLOTS = 11, - INVENTORY_SLOTS = 50 -}; - -/** - * Structure storing an item in the inventory. - * When the itemId, it represents "amount" consecutive empty slots. - */ - -struct InventoryItem -{ - unsigned short itemId; - unsigned char amount; -}; - -/** - * Structure storing the equipment and inventory of a Player. - */ -struct Possessions -{ - unsigned short equipment[EQUIPMENT_SLOTS]; - std::vector< InventoryItem > inventory; -}; - -class PlayerData -{ - public: - - PlayerData(std::string const &name, int id = -1); - - /** - * Gets the name. - * - * @return the name. - */ - std::string const &getName() const - { return mName; } - - /** - * Sets the hair style. - * - * @param style the new hair style. - */ - void setHairStyle(int style) - { mHairStyle = style; } - - /** - * Gets the hair style. - * - * @return the hair style value. - */ - int getHairStyle() const - { return mHairStyle; } - - /** - * Sets the hair color. - * - * @param color the new hair color. - */ - void setHairColor(int color) - { mHairColor = color; } - - /** - * Gets the hair color. - * - * @return the hair color value. - */ - int getHairColor() const - { return mHairColor; } - - /** - * Sets the gender. - * - * @param gender the new gender. - */ - void setGender(int gender) - { mGender = gender; } - - /** - * Gets the gender. - * - * @return the gender. - */ - int getGender() const - { return mGender; } - - /** - * Sets the level. - * - * @param level the new level. - */ - void setLevel(int level) - { mLevel = level; } - - /** - * Gets the level. - * - * @return the level. - */ - int getLevel() const - { return mLevel; } - - /** - * Sets the money. - * - * @param amount the new amount. - */ - void setMoney(int amount) - { mMoney = amount; } - - /** - * Gets the amount of money. - * - * @return the amount of money. - */ - int getMoney() const - { return mMoney; } - - /** - * Sets a raw statistic. - * - * @param numStat the statistic number. - * @param value the new value. - */ - void setRawStat(int numStat, int value) - { mRawStats.stats[numStat] = value; } - - /** - * Gets a raw statistic. - * - * @param numStat the statistic number. - * @return the statistic value. - */ - int getRawStat(int numStat) - { return mRawStats.stats[numStat]; } - - /** - * Gets account ID. - * - * @return the account ID, a negative number if none yet. - */ - int getAccountID() const - { return mAccountID; } - - /** - * Sets account ID. - */ - void setAccountID(int id) - { mAccountID = id; } - - /** - * Gets database ID. - * - * @return the database ID, a negative number if none yet. - */ - int getDatabaseID() const - { return mDatabaseID; } - - /** - * Sets database ID. - * The object shall not have any ID yet. - */ - void setDatabaseID(int id) - { mDatabaseID = id; } - - /** - * Gets the map this thing is located on. - * - * @return ID of map. - */ - int getMap() const - { return mMapId; } - - /** - * Sets the map this thing is located on. - */ - void setMap(int mapId) - { mMapId = mapId; } - - /** - * Sets the coordinates. - * - * @param p the coordinates. - */ - void setPos(const Point &p) - { mPos = p; } - - /** - * Gets the coordinates. - * - * @return the coordinates. - */ - Point const &getPos() const - { return mPos; } - - /** - * Gets a reference on the possession. - */ - Possessions &getPossessions() - { return mPossessions; } - - /** - * Stores data into a packet. - */ - void serialize(MessageOut &) const; - - /** - * Restores data from a packet. - */ - void deserialize(MessageIn &); - - private: - PlayerData(PlayerData const &); - PlayerData &operator=(PlayerData const &); - - int mAccountID; /**< Account ID of the account the player - belongs to. */ - int mDatabaseID; /**< Player database ID. */ - std::string mName; /**< Name of the being. */ - unsigned char mGender; /**< Gender of the being. */ - unsigned char mHairStyle; /**< Hair Style of the being. */ - unsigned char mHairColor; /**< Hair Color of the being. */ - unsigned char mLevel; /**< Level of the being. */ - unsigned short mMapId; /**< Map the being is on. */ - Point mPos; /**< Position the being is at. */ - unsigned int mMoney; /**< Wealth of the being. */ - RawStatistics mRawStats; /**< Raw statistics of the being. */ - Possessions mPossessions; /**< Possesssions of the being. */ -}; - -#endif |