summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/account-server/character.cpp4
-rw-r--r--src/account-server/character.hpp14
-rw-r--r--src/account-server/dalstorage.cpp16
-rw-r--r--src/defines.h35
-rw-r--r--src/game-server/being.cpp2
-rw-r--r--src/game-server/character.cpp50
-rw-r--r--src/game-server/character.hpp21
-rw-r--r--src/game-server/gamehandler.cpp7
-rw-r--r--src/game-server/item.cpp23
-rw-r--r--src/game-server/item.hpp21
-rw-r--r--src/game-server/itemmanager.cpp8
-rw-r--r--src/scripting/lua.cpp12
-rw-r--r--src/serialize/characterdata.hpp16
13 files changed, 93 insertions, 136 deletions
diff --git a/src/account-server/character.cpp b/src/account-server/character.cpp
index 0f0a261e..843bd6a2 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 be53b9d1..d38d0211 100644
--- a/src/account-server/character.hpp
+++ b/src/account-server/character.hpp
@@ -23,6 +23,7 @@
#include <string>
#include <vector>
+#include <map>
#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<int, int>::const_iterator getSkillBegin() const
+ { return mExperience.begin(); }
+
+ const std::map<int, int>::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<int, int> 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 a78f26a1..615e20f2 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<int, int>::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<int, int>::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 3ca66bfe..69e0915b 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -449,7 +449,6 @@ enum
/**
* Attributes of characters. Used to derive being attributes.
- * Please keep weapon skills in sync with item weapon types.
*/
enum
{
@@ -462,40 +461,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/being.cpp b/src/game-server/being.cpp
index 79b2e2fd..bbe3ac91 100644
--- a/src/game-server/being.cpp
+++ b/src/game-server/being.cpp
@@ -39,7 +39,7 @@ Being::Being(ThingType type):
mHpRegenTimer(0)
{
Attribute attr = { 0, 0 };
- mAttributes.resize(NB_BEING_ATTRIBUTES, attr);
+ mAttributes.resize(NB_BEING_ATTRIBUTES + CHAR_ATTR_NB, attr);
// Initialize element resistance to 100 (normal damage).
for (int i = BASE_ELEM_BEGIN; i < BASE_ELEM_END; ++i)
{
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index 0488e4ec..9e30ca57 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());
@@ -137,16 +136,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) : 100;
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)
{
@@ -323,6 +322,18 @@ void Character::sendStatus()
}
}
+int Character::getAttribute(int attr) const
+{
+ if (attr <= CHAR_ATTR_NB)
+ {
+ return Being::getAttribute(attr);
+ }
+ else
+ {
+ return mExperience.find(attr)->second;
+ }
+}
+
void Character::modifiedAttribute(int attr)
{
if (attr >= CHAR_ATTR_BEGIN && attr < CHAR_ATTR_END)
@@ -395,18 +406,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))
@@ -422,11 +433,12 @@ void Character::receiveExperience(size_t skill, int experience)
void Character::recalculateLevel()
{
std::list<float> levels;
- for (int a = CHAR_SKILL_BEGIN; a < CHAR_SKILL_END; a++)
+ std::map<int, int>::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();
@@ -434,7 +446,7 @@ void Character::recalculateLevel()
float level = 0.0f;
float factor = 1.0f;
float factorSum = 0.0f;
- while (i != levels.begin()) //maybe it wouldn't be a bad idea to unroll this loop
+ while (i != levels.begin())
{
i--;
level += *i * factor;
@@ -459,14 +471,14 @@ 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);
- return mExperience.at(skill) - Character::expForLevel(level);
+ int level = getAttribute(skill);
+ return mExperience[skill] - Character::expForLevel(level);
}
void Character::levelup()
diff --git a/src/game-server/character.hpp b/src/game-server/character.hpp
index a7b8dd5a..d90adbf3 100644
--- a/src/game-server/character.hpp
+++ b/src/game-server/character.hpp
@@ -239,6 +239,12 @@ class Character : public Being
void setMapId(int);
/**
+ * Over loads being::getAttribute, character skills are
+ * treated as extend attributes
+ */
+ int getAttribute(int) const;
+
+ /**
* Updates base Being attributes.
*/
void modifiedAttribute(int);
@@ -260,17 +266,26 @@ class Character : public Being
*/
void receiveExperience(size_t skill, int experience);
+ int getSkillSize() const
+ { return mExperience.size(); }
+
+ const std::map<int, int>::const_iterator getSkillBegin() const
+ { return mExperience.begin(); }
+
+ const std::map<int, int>::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
@@ -364,7 +379,7 @@ class Character : public Being
std::set<size_t> mModifiedAttributes;
std::set<size_t> mModifiedExperience;
- std::vector<unsigned int> mExperience; /**< experience collected for each skill.*/
+ std::map<int, int> mExperience; /**< experience collected for each skill.*/
std::map<int, Special*> mSpecials;
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp
index 7c0f01ef..c20e8a2a 100644
--- a/src/game-server/gamehandler.cpp
+++ b/src/game-server/gamehandler.cpp
@@ -655,10 +655,15 @@ 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);
}
+ std::map<int, int>::const_iterator skill_it;
+ for (skill_it = character->getSkillBegin(); skill_it != character->getSkillEnd(); skill_it++)
+ {
+ character->modifiedAttribute(skill_it->first);
+ }
}
void GameHandler::deletePendingClient(GameClient* computer)
diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp
index 817c81ec..e0ea58ca 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<const std::string, WeaponType> 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<const std::string, WeaponType>::iterator val = table.find(name);
-
- return val == table.end() ? WPNTYPE_NONE : (*val).second;
-}
-
ItemType itemTypeFromString (const std::string &name)
{
static std::map<const std::string, ItemType> table;
diff --git a/src/game-server/item.hpp b/src/game-server/item.hpp
index 828328ba..e7483663 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 ac0ea7d2..297c5ad3 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 \""
- <<sWeaponType<<"\" for item #"<<id<<" - treating it as generic item");
- itemType = ITEM_UNUSABLE;
+ <<"\" for item #"<<id<<" - treating it as generic item");
}
modifiers.setValue(MOD_WEAPON_TYPE, weaponType);
modifiers.setValue(MOD_WEAPON_RANGE, XML::getProperty(node, "range", 0));
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index f5ec0671..f607d976 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -940,13 +940,8 @@ static int chr_get_exp(lua_State *s)
}
int skill = lua_tointeger(s, 2);
- if (skill < CHAR_SKILL_BEGIN || skill >= 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 a93768b8..09a8658a 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 <map>
+
#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<int, int>::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());