diff --git a/src/account-server/character.cpp b/src/account-server/character.cpp index 0f0a261..843bd6a 100644 --- a/src/account-server/character.cpp +++ b/src/account-server/character.cpp @@ -40,10 +40,6 @@ Character::Character(const std::string &name, int id): { mAttributes[i] = 0; } - for (int i = 0; i < CHAR_SKILL_NB; ++i) - { - mExperience[i] = 0; - } } void Character::setAccount(Account *acc) diff --git a/src/account-server/character.hpp b/src/account-server/character.hpp index be53b9d..d38d021 100644 --- a/src/account-server/character.hpp +++ b/src/account-server/character.hpp @@ -23,6 +23,7 @@ #include #include +#include #include "defines.h" #include "point.h" @@ -105,8 +106,17 @@ class Character void setAttribute(int n, int value) { mAttributes[n - CHAR_ATTR_BEGIN] = value; } + int getSkillSize() const + { return mExperience.size(); } + + const std::map::const_iterator getSkillBegin() const + { return mExperience.begin(); } + + const std::map::const_iterator getSkillEnd() const + { return mExperience.end(); } + int getExperience(int skill) const - { return mExperience[skill]; } + { return mExperience.find(skill)->second; } void setExperience(int skill, int value) { mExperience[skill] = value; } @@ -169,7 +179,7 @@ class Character Account *mAccount; //!< Account owning the character. Point mPos; //!< Position the being is at. unsigned short mAttributes[CHAR_ATTR_NB]; //!< Attributes. - int mExperience[CHAR_SKILL_NB]; //!< Skill Experience. + std::map mExperience; //!< Skill Experience. unsigned short mMapId; //!< Map the being is on. unsigned char mGender; //!< Gender of the being. unsigned char mHairStyle; //!< Hair style of the being. diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp index a78f26a..615e20f 100644 --- a/src/account-server/dalstorage.cpp +++ b/src/account-server/dalstorage.cpp @@ -536,10 +536,11 @@ bool DALStorage::updateCharacter(Character *character, */ try { - for (unsigned int skill_id = 0; skill_id < CHAR_SKILL_NB; skill_id++) + std::map::const_iterator skill_it; + for (skill_it = character->getSkillBegin(); + skill_it != character->getSkillEnd(); skill_it++) { - updateExperience(character->getDatabaseID(), skill_id, - character->getExperience(skill_id)); + updateExperience(character->getDatabaseID(), skill_it->first, skill_it->second); } } catch (const dal::DbSqlQueryExecFailure& e) @@ -760,11 +761,12 @@ void DALStorage::flush(Account *account) // Update the character ID. (*it)->setDatabaseID(mDb->getLastId()); - // update the characters skills - for (unsigned int skill_id = 0; skill_id < CHAR_SKILL_NB; skill_id++) + // update the characters skill + std::map::const_iterator skill_it; + for (skill_it = (*it)->getSkillBegin(); + skill_it != (*it)->getSkillEnd(); skill_it++) { - updateExperience((*it)->getDatabaseID(), skill_id, - (*it)->getExperience(skill_id)); + updateExperience((*it)->getDatabaseID(), skill_it->first, skill_it->second); } } } // diff --git a/src/defines.h b/src/defines.h index b256df2..821d2c3 100644 --- a/src/defines.h +++ b/src/defines.h @@ -126,7 +126,7 @@ enum { GPMSG_INVENTORY = 0x0120, // { B slot, W item id [, B amount] }* GPMSG_INVENTORY_FULL = 0x0121, // { B slot, W item id [, B amount] }* GPMSG_PLAYER_ATTRIBUTE_CHANGE = 0x0130, // { B attribute, W base value, W modified value }* - GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { B skill, D exp got, D exp needed }* + GPMSG_PLAYER_EXP_CHANGE = 0x0140, // { W skill, D exp got, D exp needed }* GPMSG_LEVELUP = 0x0150, // W new level, W character points, W correction points GPMSG_LEVEL_PROGRESS = 0x0151, // B percent completed to next levelup PGMSG_RAISE_ATTRIBUTE = 0x0160, // B attribute @@ -462,40 +462,6 @@ enum CHAR_ATTR_WILLPOWER, CHAR_ATTR_END, CHAR_ATTR_NB = CHAR_ATTR_END - CHAR_ATTR_BEGIN, - - CHAR_SKILL_BEGIN = CHAR_ATTR_END, - - CHAR_SKILL_WEAPON_BEGIN = CHAR_SKILL_BEGIN, - CHAR_SKILL_WEAPON_NONE = CHAR_SKILL_WEAPON_BEGIN, - CHAR_SKILL_WEAPON_KNIFE, - CHAR_SKILL_WEAPON_SWORD, - CHAR_SKILL_WEAPON_POLEARM, - CHAR_SKILL_WEAPON_STAFF, - CHAR_SKILL_WEAPON_WHIP, - CHAR_SKILL_WEAPON_BOW, - CHAR_SKILL_WEAPON_SHOOTING, - CHAR_SKILL_WEAPON_MACE, - CHAR_SKILL_WEAPON_AXE, - CHAR_SKILL_WEAPON_THROWN, - CHAR_SKILL_WEAPON_END, - CHAR_SKILL_WEAPON_NB = CHAR_SKILL_WEAPON_END - CHAR_SKILL_WEAPON_BEGIN, - - CHAR_SKILL_MAGIC_BEGIN = CHAR_SKILL_WEAPON_END, - CHAR_SKILL_MAGIC_IAMJUSTAPLACEHOLDER = CHAR_SKILL_MAGIC_BEGIN, - // add magic skills here - CHAR_SKILL_MAGIC_END, - CHAR_SKILL_MAGIC_NB = CHAR_SKILL_MAGIC_END - CHAR_SKILL_MAGIC_BEGIN, - - CHAR_SKILL_CRAFT_BEGIN = CHAR_SKILL_MAGIC_END, - CHAR_SKILL_CRAFT_IAMJUSTAPLACEHOLDER = CHAR_SKILL_CRAFT_BEGIN, - // add crafting skills here - CHAR_SKILL_CRAFT_END, - CHAR_SKILL_CRAFT_NB = CHAR_SKILL_CRAFT_END - CHAR_SKILL_CRAFT_BEGIN, - - CHAR_SKILL_END = CHAR_SKILL_CRAFT_END, - CHAR_SKILL_NB = CHAR_SKILL_END - CHAR_SKILL_BEGIN, - - NB_CHARACTER_ATTRIBUTES = CHAR_SKILL_END }; #endif // _TMWSERV_DEFINES_H_ diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 7e0dc12..d30939e 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -60,8 +60,7 @@ Character::Character(MessageIn &msg): mTransaction(TRANS_NONE) { Attribute attr = { 0, 0 }; - mAttributes.resize(NB_CHARACTER_ATTRIBUTES, attr); - mExperience.resize(CHAR_SKILL_NB, 0); + mAttributes.resize(CHAR_ATTR_NB, attr); // Get character data. mDatabaseID = msg.readLong(); setName(msg.readString()); @@ -128,16 +127,16 @@ void Character::perform() // TODO: Check slot 2 too. int itemId = mPossessions.equipment[EQUIP_FIGHT1_SLOT]; ItemClass *ic = ItemManager::getItem(itemId); - int type = ic ? ic->getModifiers().getValue(MOD_WEAPON_TYPE) : WPNTYPE_NONE; + int type = ic ? ic->getModifiers().getValue(MOD_WEAPON_TYPE) : 300; Damage damage; damage.base = getModifiedAttribute(BASE_ATTR_PHY_ATK_MIN); damage.delta = getModifiedAttribute(BASE_ATTR_PHY_ATK_DELTA) + - getModifiedAttribute(CHAR_SKILL_WEAPON_BEGIN + type); + getModifiedAttribute(type); damage.type = DAMAGE_PHYSICAL; damage.cth = getModifiedAttribute(BASE_ATTR_HIT) + - getModifiedAttribute(CHAR_SKILL_WEAPON_BEGIN + type); - damage.usedSkills.push_back(CHAR_SKILL_WEAPON_BEGIN + type); + getModifiedAttribute(type); + damage.usedSkills.push_back(type); if (ic) { @@ -298,7 +297,7 @@ void Character::sendStatus() i_end = mModifiedExperience.end(); i != i_end; ++i) { int skill = *i; - expMsg.writeByte(skill); + expMsg.writeShort(skill); expMsg.writeLong(getExpGot(skill)); expMsg.writeLong(getExpNeeded(skill)); } @@ -386,18 +385,18 @@ int Character::expForLevel(int level) void Character::receiveExperience(size_t skill, int experience) { - if (skill >= CHAR_SKILL_BEGIN && skill < CHAR_SKILL_END) + if (skill >= CHAR_ATTR_END) { // add exp - long int newExp = mExperience.at(skill - CHAR_SKILL_BEGIN) + experience; + long int newExp = mExperience[skill] + experience; if (newExp > INT_MAX) newExp = INT_MAX; // avoid integer overflow. if (newExp < 0) newExp = 0; // avoid integer underflow/negative exp - mExperience.at(skill - CHAR_SKILL_BEGIN) = newExp; - mModifiedExperience.insert(skill - CHAR_SKILL_BEGIN); + mExperience[skill] = newExp; + mModifiedExperience.insert(skill); // inform account server accountHandler->updateExperience(getDatabaseID(), - skill - CHAR_SKILL_BEGIN, newExp); + skill, newExp); // check for skill levelup while (newExp >= Character::expForLevel(getAttribute(skill) + 1)) @@ -413,11 +412,12 @@ void Character::receiveExperience(size_t skill, int experience) void Character::recalculateLevel() { std::list levels; - for (int a = CHAR_SKILL_BEGIN; a < CHAR_SKILL_END; a++) + std::map::const_iterator a; + for (a = getSkillBegin(); a != getSkillEnd(); a++) { - float expGot = getExpGot(a - CHAR_SKILL_BEGIN); - float expNeed = getExpNeeded(a - CHAR_SKILL_BEGIN); - levels.push_back(getAttribute(a) + expGot / expNeed); + float expGot = getExpGot(a->first); + float expNeed = getExpNeeded(a->first); + levels.push_back(getAttribute(a->first) + expGot / expNeed); } levels.sort(); @@ -450,13 +450,13 @@ void Character::recalculateLevel() int Character::getExpNeeded(size_t skill) { - int level = getAttribute(skill + CHAR_SKILL_BEGIN); + int level = getAttribute(skill); return Character::expForLevel(level + 1) - expForLevel(level); } int Character::getExpGot(size_t skill) { - int level = getAttribute(skill + CHAR_SKILL_BEGIN); + int level = getAttribute(skill); return mExperience.at(skill) - Character::expForLevel(level); } diff --git a/src/game-server/character.hpp b/src/game-server/character.hpp index f930c33..e87c15c 100644 --- a/src/game-server/character.hpp +++ b/src/game-server/character.hpp @@ -255,17 +255,26 @@ class Character : public Being */ void receiveExperience(size_t skill, int experience); + int getSkillSize() const + { return mExperience.size(); } + + const std::map::const_iterator getSkillBegin() const + { return mExperience.begin(); } + + const std::map::const_iterator getSkillEnd() const + { return mExperience.end(); } + /** * Gets total accumulated exp for skill */ int getExperience(int skill) const - { return mExperience[skill]; } + { return mExperience.find(skill)->second; } /** * Sets total accumulated exp for skill */ void setExperience(int skill, int value) - { mExperience[skill] = 0; receiveExperience(skill + CHAR_SKILL_BEGIN , value) ; } + { mExperience[skill] = 0; receiveExperience(skill, value) ; } /** * Shortcut to get being's health @@ -359,7 +368,7 @@ class Character : public Being std::set mModifiedAttributes; std::set mModifiedExperience; - std::vector mExperience; /**< experience collected for each skill.*/ + std::map mExperience; /**< experience collected for each skill.*/ std::map mSpecials; diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index 7c0f01e..69996bc 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -655,7 +655,7 @@ void GameHandler::tokenMatched(GameClient* computer, Character* character) // Force sending the whole character to the client. Inventory(character).sendFull(); - for (int i = 0; i < NB_CHARACTER_ATTRIBUTES; ++i) + for (int i = 0; i < CHAR_ATTR_NB; ++i) { character->modifiedAttribute(i); } diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp index 817c81e..e0ea58c 100644 --- a/src/game-server/item.cpp +++ b/src/game-server/item.cpp @@ -29,29 +29,6 @@ #include "game-server/being.hpp" #include "scripting/script.hpp" -WeaponType weaponTypeFromString (const std::string &name) -{ - static std::map table; - - if (table.empty()) - { - table["knife"] = WPNTYPE_KNIFE; - table["sword"] = WPNTYPE_SWORD; - table["polearm"] = WPNTYPE_POLEARM; - table["staff"] = WPNTYPE_STAFF; - table["whip"] = WPNTYPE_WHIP; - table["bow"] = WPNTYPE_BOW; - table["shooting"] = WPNTYPE_SHOOTING; - table["mace"] = WPNTYPE_MACE; - table["axe"] = WPNTYPE_AXE; - table["thrown"] = WPNTYPE_THROWN; - } - - std::map::iterator val = table.find(name); - - return val == table.end() ? WPNTYPE_NONE : (*val).second; -} - ItemType itemTypeFromString (const std::string &name) { static std::map table; diff --git a/src/game-server/item.hpp b/src/game-server/item.hpp index 828328b..e748366 100644 --- a/src/game-server/item.hpp +++ b/src/game-server/item.hpp @@ -55,27 +55,6 @@ enum ItemType ItemType itemTypeFromString (const std::string &name); - -/** - * Enumeration of available weapon's types. - */ -enum WeaponType -{ - WPNTYPE_NONE = 0, - WPNTYPE_KNIFE, - WPNTYPE_SWORD, - WPNTYPE_POLEARM, - WPNTYPE_STAFF, - WPNTYPE_WHIP, - WPNTYPE_BOW, - WPNTYPE_SHOOTING, - WPNTYPE_MACE, - WPNTYPE_AXE, - WPNTYPE_THROWN -}; - -WeaponType weaponTypeFromString (const std::string &name); - /** * State effects to beings, and actors. * States can be multiple for the same being. diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index ac0ea7d..297c5ad 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -145,13 +145,11 @@ void ItemManager::reload() if (itemType == ITEM_EQUIPMENT_ONE_HAND_WEAPON || itemType == ITEM_EQUIPMENT_TWO_HANDS_WEAPON) { - std::string sWeaponType = XML::getProperty(node, "weapon-type", ""); - WeaponType weaponType = weaponTypeFromString(sWeaponType); - if (weaponType == WPNTYPE_NONE) + int weaponType = XML::getProperty(node, "weapon-type", 0); + if (weaponType == 0) { LOG_WARN(itemReferenceFile<<": Unknown weapon type \"" - <= CHAR_SKILL_END) - { - raiseScriptError(s, "luaChr_GetExp called for nonexistent skill number %d.", skill); - return 0; - } - int exp = c->getExperience(skill - CHAR_SKILL_BEGIN); + int exp = c->getExperience(skill); lua_pushinteger(s, exp); return 1; @@ -969,11 +964,6 @@ static int chr_give_exp(lua_State *s) } int skill = lua_tointeger(s, 2); - if (skill < CHAR_SKILL_BEGIN || skill >= CHAR_SKILL_END) - { - raiseScriptError(s, "luaChr_GiveExp called for nonexistent skill number %d.", skill); - return 0; - } int exp = lua_tointeger(s, 3); diff --git a/src/serialize/characterdata.hpp b/src/serialize/characterdata.hpp index a93768b..09a8658 100644 --- a/src/serialize/characterdata.hpp +++ b/src/serialize/characterdata.hpp @@ -21,6 +21,8 @@ #ifndef _TMWSERV_SERIALIZE_CHARACTERDATA_HPP_ #define _TMWSERV_SERIALIZE_CHARACTERDATA_HPP_ +#include + #include "defines.h" #include "common/inventorydata.hpp" #include "net/messagein.hpp" @@ -43,9 +45,13 @@ void serializeCharacterData(const T &data, MessageOut &msg) msg.writeByte(data.getAttribute(i)); } - for (int i = 0; i < CHAR_SKILL_NB; ++i) + msg.writeShort(data.getSkillSize()); + + std::map::const_iterator skill_it; + for (skill_it = data.getSkillBegin(); skill_it != data.getSkillEnd() ; skill_it++) { - msg.writeLong(data.getExperience(i)); + msg.writeShort(skill_it->first); + msg.writeLong(skill_it->second); } @@ -84,9 +90,11 @@ void deserializeCharacterData(T &data, MessageIn &msg) data.setAttribute(i, msg.readByte()); } - for (int i = 0; i < CHAR_SKILL_NB; ++i) + int skillSize = msg.readShort(); + + for (int i = 0; i < skillSize; ++i) { - data.setExperience(i, msg.readLong()); + data.setExperience(msg.readShort(), msg.readLong()); } data.setMapId(msg.readShort());