summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYohann Ferreira <bertram@cegetel.net>2006-01-08 22:52:59 +0000
committerYohann Ferreira <bertram@cegetel.net>2006-01-08 22:52:59 +0000
commitf7db7a051da79d8deef8b79419ce6772dce16725 (patch)
tree27ff5c5f33ea73d4e52e32ebbc583fa92ba50c87
parentac150f3543caf86fd071c73f53373b4ea243fa24 (diff)
downloadmanaserv-f7db7a051da79d8deef8b79419ce6772dce16725.tar.gz
manaserv-f7db7a051da79d8deef8b79419ce6772dce16725.tar.bz2
manaserv-f7db7a051da79d8deef8b79419ce6772dce16725.tar.xz
manaserv-f7db7a051da79d8deef8b79419ce6772dce16725.zip
Added customization of created character. (That makes previously created db invalid.) Made list of map indexed by map id, instead of map name. This will prevent unsyncing of player's current map when changing a map name. Remember you have now to add a map filename into db before being able to load it. (Default map id is 1, not ZERO, as zero is the not found return value.
-rw-r--r--ChangeLog14
-rw-r--r--src/accounthandler.cpp125
-rw-r--r--src/being.cpp24
-rw-r--r--src/being.h21
-rw-r--r--src/client.cpp78
-rw-r--r--src/dalstorage.cpp102
-rw-r--r--src/dalstorage.h6
-rw-r--r--src/dalstoragesql.h10
-rw-r--r--src/defines.h18
-rw-r--r--src/main.cpp6
-rw-r--r--src/mapmanager.cpp34
-rw-r--r--src/mapmanager.h22
-rw-r--r--src/netcomputer.cpp2
-rw-r--r--src/object.cpp10
-rw-r--r--src/object.h8
-rw-r--r--src/state.cpp54
-rw-r--r--src/state.h20
-rw-r--r--src/storage.h11
18 files changed, 421 insertions, 144 deletions
diff --git a/ChangeLog b/ChangeLog
index d3025903..bca3f50b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-01-08 Yohann Ferreira <bertram@cegetel.net>
+
+ * src/defines.h, src/client.cpp, src/accounthandler.cpp,
+ src/dalstorage.cpp, src/storage.h, src/dalstorage.h,
+ src/dalstoragesql.h, src/being.h, src/object.h, src/netcomputer.cpp,
+ src/object.cpp, src/being.cpp, src/state.h, src/state.cpp,
+ src/mapmanager.h, src/main.cpp, src/mapmanager.cpp: Added
+ customization of created character. (That makes previously created db
+ invalid.) Made list of map indexed by map id, instead of map name.
+ This will prevent unsyncing of player's current map when changing a
+ map name. Remember you have now to add a map filename into db before
+ being able to load it. (Default map id is 1, not ZERO, as zero is the
+ not found return value.
+
2005-01-04 Yohann Ferreira <bertram@cegetel.net>
* src/defines.h, src/accounthandler.cpp, src/main.cpp, src/client.cpp:
diff --git a/src/accounthandler.cpp b/src/accounthandler.cpp
index a8b02a92..1d1aef31 100644
--- a/src/accounthandler.cpp
+++ b/src/accounthandler.cpp
@@ -406,13 +406,110 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message)
LOG_INFO(name << ": Character's name too short or too long.", 1)
break;
}
- //char hairStyle = message.readByte();
- //char hairColor = message.readByte();
- Genders sex = (Genders)message.readByte();
+ char hairStyle = message.readByte();
+ if ((hairStyle < 0) || (hairStyle > (signed)MAX_HAIRSTYLE_VALUE))
+ {
+ result.writeByte(CREATE_INVALID_HAIRSTYLE);
+ LOG_INFO(name << ": Character's hair Style is invalid.", 1)
+ break;
+ }
+
+ char hairColor = message.readByte();
+ if ((hairColor < 0) || (hairColor > (signed)MAX_HAIRCOLOR_VALUE))
+ {
+ result.writeByte(CREATE_INVALID_HAIRCOLOR);
+ LOG_INFO(name << ": Character's hair Color is invalid.", 1)
+ break;
+ }
+ Genders gender = (Genders)message.readByte();
+ if ((gender < 0) || (gender > (signed)MAX_GENDER_VALUE))
+ {
+ result.writeByte(CREATE_INVALID_GENDER);
+ LOG_INFO(name << ": Character's gender is invalid.", 1)
+ break;
+ }
+ // LATER_ON: Add race attribute.
+
+ // Customization of player's stats...
+ std::vector<unsigned short> rawStats;
+ rawStats.reserve(6);
+ // strength
+ rawStats.push_back((unsigned short)message.readShort());
+ // agility
+ rawStats.push_back((unsigned short)message.readShort());
+ // vitality
+ rawStats.push_back((unsigned short)message.readShort());
+ // intelligence
+ rawStats.push_back((unsigned short)message.readShort());
+ // dexterity
+ rawStats.push_back((unsigned short)message.readShort());
+ // luck
+ rawStats.push_back((unsigned short)message.readShort());
+
+ // We see if the difference between the lowest stat and the highest isn't too
+ // big.
+ unsigned short lowestStat = 0;
+ unsigned short highestStat = 0;
+ unsigned int totalStats = 0;
+ bool validNonZeroRawStats = true;
+ for ( std::vector<unsigned short>::iterator i = rawStats.begin(); i != rawStats.end();)
+ {
+ // For good total stat check.
+ totalStats = totalStats + *i;
+
+ // For checking if all stats are at least > 0
+ if (*i <= 0) validNonZeroRawStats = false;
+ if (lowestStat != 0)
+ {
+ if (lowestStat > *i) lowestStat = *i;
+ }
+ else
+ {
+ // We take the first value
+ lowestStat = *i;
+ }
+ if (highestStat != 0)
+ {
+ if (highestStat < *i) highestStat = *i;
+ }
+ else
+ {
+ // We take the first value
+ highestStat = *i;
+ }
+ ++i;
+ }
+
+ if ( totalStats > POINTS_TO_DISTRIBUTES_AT_LVL1 )
+ {
+ result.writeByte(CREATE_RAW_STATS_TOO_HIGH);
+ LOG_INFO(name << ": Character's stats are too high to be of level 1.", 1)
+ break;
+ }
+ if ( totalStats < POINTS_TO_DISTRIBUTES_AT_LVL1 )
+ {
+ result.writeByte(CREATE_RAW_STATS_TOO_LOW);
+ LOG_INFO(name << ": Character's stats are too low to be of level 1.", 1)
+ break;
+ }
+ if ( (highestStat - lowestStat) > (signed)MAX_DIFF_BETWEEN_STATS )
+ {
+ result.writeByte(CREATE_RAW_STATS_INVALID_DIFF);
+ LOG_INFO(name << ": Character's stats difference is too high to be accepted.", 1)
+ break;
+ }
+ if ( !validNonZeroRawStats )
+ {
+ result.writeByte(CREATE_RAW_STATS_EQUAL_TO_ZERO);
+ LOG_INFO(name << ": One stat is equal to zero.", 1)
+ break;
+ }
- // TODO: Customization of player's stats...
- tmwserv::RawStatistics stats = {10, 10, 10, 10, 10, 10};
- tmwserv::BeingPtr newCharacter(new tmwserv::Being(name, sex, 1, 0, stats));
+ // The reserve(6) method allows us to be sure that rawStats[5] will work.
+ tmwserv::RawStatistics stats = {rawStats[0], rawStats[1], rawStats[2],
+ rawStats[3], rawStats[4], rawStats[5]};
+ tmwserv::BeingPtr newCharacter(new tmwserv::Being(name, gender, hairStyle, hairColor,
+ 1 /* level */, 0 /* Money */, stats));
computer.getAccount()->addCharacter(newCharacter);
LOG_INFO("Character " << name << " was created for "
@@ -535,14 +632,16 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message)
if (i >0) charStats += ", ";
charStats += chars[i]->getName();
result.writeByte(unsigned(short(chars[i]->getGender())));
+ result.writeByte(chars[i]->getHairStyle());
+ result.writeByte(chars[i]->getHairColor());
result.writeByte(chars[i]->getLevel());
- result.writeByte(chars[i]->getMoney());
- result.writeByte(chars[i]->getStrength());
- result.writeByte(chars[i]->getAgility());
- result.writeByte(chars[i]->getVitality());
- result.writeByte(chars[i]->getIntelligence());
- result.writeByte(chars[i]->getDexterity());
- result.writeByte(chars[i]->getLuck());
+ result.writeShort(chars[i]->getMoney());
+ result.writeShort(chars[i]->getStrength());
+ result.writeShort(chars[i]->getAgility());
+ result.writeShort(chars[i]->getVitality());
+ result.writeShort(chars[i]->getIntelligence());
+ result.writeShort(chars[i]->getDexterity());
+ result.writeShort(chars[i]->getLuck());
}
charStats += ".";
LOG_INFO(charStats.c_str(), 1)
diff --git a/src/being.cpp b/src/being.cpp
index ce8462f3..3138f4e1 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -38,11 +38,15 @@ PATH_NODE::PATH_NODE(unsigned short x, unsigned short y):
*/
Being::Being(const std::string& name,
const Genders gender,
+ const unsigned short hairStyle,
+ const unsigned short hairColor,
const unsigned short level,
const unsigned int money,
const RawStatistics& stats)
: mName(name),
mGender(gender),
+ mHairStyle(hairStyle),
+ mHairColor(hairColor),
mLevel(level),
mMoney(money),
mRawStats(stats)
@@ -82,6 +86,26 @@ Being::getGender(void) const
/**
+ * Get the Hair Style.
+ */
+unsigned short
+Being::getHairStyle(void) const
+{
+ return mHairStyle;
+}
+
+
+/**
+ * Get the Hair Color.
+ */
+unsigned short
+Being::getHairColor(void) const
+{
+ return mHairColor;
+}
+
+
+/**
* Set the level.
*/
void
diff --git a/src/being.h b/src/being.h
index b68f1c5f..80b73012 100644
--- a/src/being.h
+++ b/src/being.h
@@ -73,6 +73,8 @@ class Being: public Object
*/
Being(const std::string& name,
const Genders gender,
+ const unsigned short hairStyle,
+ const unsigned short hairColor,
const unsigned short level,
const unsigned int money,
const RawStatistics& stats);
@@ -92,6 +94,22 @@ class Being: public Object
getName(void) const;
/**
+ * Gets the hair Style.
+ *
+ * @return the Hair style value.
+ */
+ unsigned short
+ getHairStyle(void) const;
+
+ /**
+ * Gets the Hair Color.
+ *
+ * @return the Hair Color value.
+ */
+ unsigned short
+ getHairColor(void) const;
+
+ /**
* Gets the gender.
*
* @return the gender.
@@ -99,6 +117,7 @@ class Being: public Object
Genders
getGender(void) const;
+
/**
* Sets the level.
*
@@ -309,6 +328,8 @@ class Being: public Object
std::string mName; /**< name of the being */
Genders mGender; /**< gender of the being */
+ unsigned short mHairStyle;/**< Hair Style of the being */
+ unsigned short mHairColor;/**< Hair Color of the being */
unsigned short mLevel; /**< level of the being */
unsigned int mMoney; /**< wealth of the being */
RawStatistics mRawStats; /**< raw stats of the being */
diff --git a/src/client.cpp b/src/client.cpp
index f98d45d4..8c14e8b4 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -180,7 +180,42 @@ int main(int argc, char *argv[])
std::cout << "Name: ";
std::cin >> line;
msg.writeString(line);
- msg.writeByte(0);
+
+ std::cout << "Hair Style ID (0 - " << MAX_HAIRSTYLE_VALUE << "): ";
+ std::cin >> line;
+ msg.writeByte(atoi(line));
+
+ std::cout << "Hair Color ID (0 - " << MAX_HAIRCOLOR_VALUE << "): ";
+ std::cin >> line;
+ msg.writeByte(atoi(line));
+
+ std::cout << "Gender ID (0 - " << MAX_GENDER_VALUE << "): ";
+ std::cin >> line;
+ msg.writeByte(atoi(line));
+
+ std::cout << "Strength: ";
+ std::cin >> line;
+ msg.writeShort(atoi(line));
+
+ std::cout << "Agility: ";
+ std::cin >> line;
+ msg.writeShort(atoi(line));
+
+ std::cout << "Vitality: ";
+ std::cin >> line;
+ msg.writeShort(atoi(line));
+
+ std::cout << "Intelligence: ";
+ std::cin >> line;
+ msg.writeShort(atoi(line));
+
+ std::cout << "Dexterity: ";
+ std::cin >> line;
+ msg.writeShort(atoi(line));
+
+ std::cout << "Luck: ";
+ std::cin >> line;
+ msg.writeShort(atoi(line));
} break;
case 9:
@@ -488,17 +523,29 @@ int main(int argc, char *argv[])
case CREATE_TOO_MUCH_CHARACTERS:
std::cout << "Character Creation: Too much characters." << std::endl;
break;
- case CREATE_INVALID_HAIR:
- std::cout << "Character Creation: Invalid Hair Value." << std::endl;
+ case CREATE_INVALID_HAIRSTYLE:
+ std::cout << "Character Creation: Invalid Hair Style Value." << std::endl;
+ break;
+ case CREATE_INVALID_HAIRCOLOR:
+ std::cout << "Character Creation: Invalid Hair Color Value." << std::endl;
+ break;
+ case CREATE_INVALID_GENDER:
+ std::cout << "Character Creation: Invalid Gender Value." << std::endl;
break;
case CREATE_INVALID_NAME:
std::cout << "Character Creation: Invalid Name." << std::endl;
break;
- case CREATE_INVALID_SEX:
- std::cout << "Character Creation: Invalid Sex value." << std::endl;
+ case CREATE_RAW_STATS_EQUAL_TO_ZERO:
+ std::cout << "Character Creation: a Statistic is equal to zero." << std::endl;
break;
- case CREATE_INVALID_RAW_STATS:
- std::cout << "TODO: Character Creation: Invalid Raw Stats." << std::endl;
+ case CREATE_RAW_STATS_INVALID_DIFF:
+ std::cout << "Character Creation: Statistics disproportionned." << std::endl;
+ break;
+ case CREATE_RAW_STATS_TOO_HIGH:
+ std::cout << "Character Creation: Statistics too high for level 1." << std::endl;
+ break;
+ case CREATE_RAW_STATS_TOO_LOW:
+ std::cout << "Character Creation: Statistics too low for level 1." << std::endl;
break;
default:
case CREATE_UNKNOWN:
@@ -573,16 +620,19 @@ int main(int argc, char *argv[])
{
std::cout << msg.readString() << ":" << std::endl;
std::cout << "Gender: " << int(msg.readByte()) << ", ";
+ std::cout << "Hair Style: " << int(msg.readByte()) << ", ";
+ std::cout << "Hair Color: " << int(msg.readByte()) << ", "
+ << std::endl;
std::cout << "Level: " << int(msg.readByte()) << ", ";
- std::cout << "Money: " << int(msg.readByte()) << ", "
+ std::cout << "Money: " << int(msg.readShort()) << ", "
<< std::endl;
- std::cout << "Strength: " << int(msg.readByte()) << ", ";
- std::cout << "Agility: " << int(msg.readByte()) << ", ";
- std::cout << "Vitality: " << int(msg.readByte()) << ", "
+ std::cout << "Strength: " << int(msg.readShort()) << ", ";
+ std::cout << "Agility: " << int(msg.readShort()) << ", ";
+ std::cout << "Vitality: " << int(msg.readShort()) << ", "
<< std::endl;
- std::cout << "Intelligence: " << int(msg.readByte()) << ", ";
- std::cout << "Dexterity: " << int(msg.readByte()) << ", ";
- std::cout << "Luck: " << int(msg.readByte()) << ", "
+ std::cout << "Intelligence: " << int(msg.readShort()) << ", ";
+ std::cout << "Dexterity: " << int(msg.readShort()) << ", ";
+ std::cout << "Luck: " << int(msg.readShort()) << ". "
<< std::endl << std::endl;
}
break;
diff --git a/src/dalstorage.cpp b/src/dalstorage.cpp
index 4b6ce81f..eeb6249d 100644
--- a/src/dalstorage.cpp
+++ b/src/dalstorage.cpp
@@ -243,12 +243,12 @@ DALStorage::getAccount(const std::string& userName)
for (unsigned int k = 0; k < charRows; ++k) {
RawStatistics stats = {
- toUshort(strCharInfo[k][9]), // strength
- toUshort(strCharInfo[k][10]), // agility
- toUshort(strCharInfo[k][11]), // vitality
- toUshort(strCharInfo[k][12]), // intelligence
- toUshort(strCharInfo[k][13]), // dexterity
- toUshort(strCharInfo[k][14]) // luck
+ toUshort(strCharInfo[k][11]), // strength
+ toUshort(strCharInfo[k][12]), // agility
+ toUshort(strCharInfo[k][13]), // vitality
+ toUshort(strCharInfo[k][14]), // intelligence
+ toUshort(strCharInfo[k][15]), // dexterity
+ toUshort(strCharInfo[k][16]) // luck
};
BeingPtr being(
@@ -257,28 +257,25 @@ DALStorage::getAccount(const std::string& userName)
// a short to an enum is invalid, the explicit
// type cast works :D
(Genders) toUshort(strCharInfo[k][3]), // gender
- toUshort(strCharInfo[k][4]), // level
- toUint(strCharInfo[k][5]), // money
+ toUshort(strCharInfo[k][4]), // hair style
+ toUshort(strCharInfo[k][5]), // hair color
+ toUshort(strCharInfo[k][6]), // level
+ toUint(strCharInfo[k][7]), // money
stats
));
- std::stringstream ss;
- ss << "select map from " + MAPS_TBL_NAME + " where id = '"
- << toUint(strCharInfo[k][8]) << "';";
- sql = ss.str();
- // should be impossible for this to fail due to db referential integrity
-
- const RecordSet& mapInfo = mDb->execSql(sql);
-
- if (!mapInfo.isEmpty())
+ unsigned int mapId;
+ std::stringstream ssMapId(strCharInfo[k][10]);
+ ssMapId >> mapId;
+ if ( mapId > 0 )
{
- being.get()->setMap(std::string(mapInfo(0, 0)));
+ being.get()->setMap(mapId);
}
else
{
- // TODO: Set player to default map and one of the default location
- ss.str("None");
- being.get()->setMap(ss.str());
+ // Set player to default map and one of the default location
+ // Default map is to be 1, as not found return value will be 0.
+ being.get()->setMap(DEFAULT_MAP_ID);
}
mCharacters.push_back(being);
@@ -424,7 +421,7 @@ DALStorage::getSameEmailNumber(const std::string &email)
// If the account is empty then we have no choice but to return false.
if (accountInfo.isEmpty()) {
- return false;
+ return 0;
}
std::stringstream ssStream(accountInfo(0,0));
@@ -437,7 +434,7 @@ DALStorage::getSameEmailNumber(const std::string &email)
LOG_ERROR("SQL query failure: " << e.what(), 0);
}
- return false;
+ return 0;
}
/**
@@ -457,13 +454,13 @@ DALStorage::doesCharacterNameExists(std::string name)
sql += name;
sql += "';";
const dal::RecordSet& accountInfo = mDb->execSql(sql);
-
+
// if the account is empty then
// we have no choice but to return false.
if (accountInfo.isEmpty()) {
return false;
}
-
+
std::stringstream ssStream(accountInfo(0,0));
int iReturn = -1;
ssStream >> iReturn;
@@ -485,6 +482,40 @@ DALStorage::doesCharacterNameExists(std::string name)
}
/**
+ * Tells the map name from the map id
+ */
+const std::string
+DALStorage::getMapNameFromId(const unsigned int mapId)
+{
+ // If not opened already
+ open();
+
+ try {
+ std::string sql("select map from ");
+ sql += MAPS_TBL_NAME;
+ sql += " where id = '";
+ sql += mapId;
+ sql += "');";
+
+ const dal::RecordSet& mapInfo = mDb->execSql(sql);
+
+ // If the map return is empty then we have no choice but to return false.
+ if (mapInfo.isEmpty()) {
+ return "None";
+ }
+
+ std::string strMap(mapInfo(0,0));
+ return strMap;
+ }
+ catch (const dal::DbSqlQueryExecFailure& e) {
+ // TODO: throw an exception.
+ LOG_ERROR("SQL query failure: " << e.what(), 0);
+ }
+
+ return "None";
+}
+
+/**
* Save changes to the database permanently.
*/
void
@@ -609,16 +640,19 @@ DALStorage::_addAccount(const AccountPtr& account)
RawStatistics& stats = (*it)->getRawStatistics();
std::ostringstream sql3;
sql3 << "insert into " << CHARACTERS_TBL_NAME
- << " (name, gender, level, money, x, y, map_id, str, agi, vit, int, dex, luck)"
+ << " (name, gender, hair_style, hair_color, level, money, x, y, "
+ << "map_id, str, agi, vit, int, dex, luck)"
<< " values ("
<< (account_it->second).id << ", '"
- << (*it)->getName() << "', '"
- << (*it)->getGender() << "', "
+ << (*it)->getName() << "', "
+ << (*it)->getGender() << ", "
+ << (int)(*it)->getHairStyle() << ", "
+ << (int)(*it)->getHairColor() << ", "
<< (*it)->getLevel() << ", "
<< (*it)->getMoney() << ", "
<< (*it)->getX() << ", "
<< (*it)->getY() << ", "
- << "0, " // TODO: map id
+ << (int)(*it)->getMapId() << ", "
<< stats.strength << ", "
<< stats.agility << ", "
<< stats.vitality << ", "
@@ -700,7 +734,7 @@ DALStorage::_updAccount(const AccountPtr& account)
#ifdef SQLITE_SUPPORT
<< "user_id, "
#endif
- << "name, gender, level, money, x, y, map_id, str, agi, vit, int, dex, luck)"
+ << "name, gender, hair_style, hair_color, level, money, x, y, map_id, str, agi, vit, int, dex, luck)"
<< " values ("
#ifdef SQLITE_SUPPORT
<< (account_it->second).id << ", '"
@@ -709,11 +743,13 @@ DALStorage::_updAccount(const AccountPtr& account)
#endif
<< (*it)->getName() << "', "
<< (*it)->getGender() << ", "
+ << (*it)->getHairStyle() << ", "
+ << (*it)->getHairColor() << ", "
<< (*it)->getLevel() << ", "
<< (*it)->getMoney() << ", "
<< (*it)->getX() << ", "
<< (*it)->getY() << ", "
- << "0, " // TODO: map id
+ << (*it)->getMapId() << ", "
<< stats.strength << ", "
<< stats.agility << ", "
<< stats.vitality << ", "
@@ -725,11 +761,13 @@ DALStorage::_updAccount(const AccountPtr& account)
sql3 << "update " << CHARACTERS_TBL_NAME
<< " set name = '" << (*it)->getName() << "', "
<< " gender = " << (*it)->getGender() << ", "
+ << " hair_style = " << (*it)->getHairStyle() << ", "
+ << " hair_color = " << (*it)->getHairColor() << ", "
<< " level = " << (*it)->getLevel() << ", "
<< " money = " << (*it)->getMoney() << ", "
<< " x = " << (*it)->getX() << ", "
<< " y = " << (*it)->getY() << ", "
- << " map_id = 0, " // TODO: map id
+ << " map_id = " << (*it)->getMapId() << ", "
<< " str = " << stats.strength << ", "
<< " agi = " << stats.agility << ", "
<< " vit = " << stats.vitality << ", "
diff --git a/src/dalstorage.h b/src/dalstorage.h
index ae22b65f..c2257c6e 100644
--- a/src/dalstorage.h
+++ b/src/dalstorage.h
@@ -114,6 +114,12 @@ class DALStorage: public Storage
doesCharacterNameExists(std::string name);
/**
+ * Tells the map name from the map id
+ */
+ const std::string
+ getMapNameFromId(const unsigned int mapId);
+
+ /**
* Save changes to the database permanently.
*
* @exception tmwserv::dal::DbSqlQueryExecFailure.
diff --git a/src/dalstoragesql.h b/src/dalstoragesql.h
index 077b7b0a..cc287fbe 100644
--- a/src/dalstoragesql.h
+++ b/src/dalstoragesql.h
@@ -141,7 +141,9 @@ const std::string SQL_CHARACTERS_TABLE(
"user_id INTEGER UNSIGNED NOT NULL,"
"name VARCHAR(32) NOT NULL UNIQUE,"
// general information about the character
- "gender TINYINT UNSIGNED NOT NULL,"
+ "gender TINYINT UNSIGNED NOT NULL,"
+ "hair_style TINYINT UNSIGNED NOT NULL,"
+ "hair_color TINYINT UNSIGNED NOT NULL,"
"level TINYINT UNSIGNED NOT NULL,"
"money INTEGER UNSIGNED NOT NULL,"
// location on the map
@@ -164,7 +166,9 @@ const std::string SQL_CHARACTERS_TABLE(
"user_id INTEGER NOT NULL,"
"name TEXT NOT NULL UNIQUE,"
// general information about the character
- "gender INTEGER NOT NULL,"
+ "gender INTEGER NOT NULL,"
+ "hair_style INTEGER NOT NULL,"
+ "hair_color INTEGER NOT NULL,"
"level INTEGER NOT NULL,"
"money INTEGER NOT NULL,"
// location on the map
@@ -186,6 +190,8 @@ const std::string SQL_CHARACTERS_TABLE(
"name TEXT NOT NULL UNIQUE,"
// general information about the character
"gender INTEGER NOT NULL,"
+ "hair_style INTEGER NOT NULL,"
+ "hair_color INTEGER NOT NULL,"
"level INTEGER NOT NULL,"
"money INTEGER NOT NULL,"
// location on the map
diff --git a/src/defines.h b/src/defines.h
index c344011f..64629870 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -74,6 +74,9 @@ const unsigned int MAX_CLIENTS = 1024,
MIN_CHARACTER_LENGTH = 4,
MAX_CHARACTER_LENGTH = 25,
MAX_OF_CHARACTERS = 3,
+ MAX_HAIRSTYLE_VALUE = 5,
+ MAX_HAIRCOLOR_VALUE = 10,
+ MAX_GENDER_VALUE = 2,
/** Tells the max difference between the
* less big stat and the biggest one.
* So that players haven't disproportionned
@@ -90,7 +93,10 @@ const unsigned int MAX_CLIENTS = 1024,
* Determine the area in which a character
* can hear another one speak
*/
- AROUND_AREA_IN_TILES = 10;
+ AROUND_AREA_IN_TILES = 10,
+
+ // Maps related
+ DEFAULT_MAP_ID = 1;
/**
@@ -211,9 +217,13 @@ enum {
enum {
CREATE_OK = 0,
CREATE_INVALID_NAME,
- CREATE_INVALID_HAIR,
- CREATE_INVALID_SEX,
- CREATE_INVALID_RAW_STATS,
+ CREATE_INVALID_HAIRSTYLE,
+ CREATE_INVALID_HAIRCOLOR,
+ CREATE_INVALID_GENDER,
+ CREATE_RAW_STATS_TOO_HIGH,
+ CREATE_RAW_STATS_TOO_LOW,
+ CREATE_RAW_STATS_INVALID_DIFF,
+ CREATE_RAW_STATS_EQUAL_TO_ZERO,
CREATE_EXISTS_NAME,
CREATE_TOO_MUCH_CHARACTERS,
CREATE_NOLOGIN,
diff --git a/src/main.cpp b/src/main.cpp
index 83b30246..b915b4d9 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -239,9 +239,9 @@ void initialize()
PHYSFS_init("");
// TODO: only a test, maps should be loaded as they are needed
- tmwserv::MapManager::instance().loadMap("tulimshar.tmx.gz");
- tmwserv::MapManager::instance().reloadMap("tulimshar.tmx.gz");
- tmwserv::MapManager::instance().unloadMap("tulimshar.tmx.gz");
+ tmwserv::MapManager::instance().loadMap(1);
+ tmwserv::MapManager::instance().reloadMap(1);
+ tmwserv::MapManager::instance().unloadMap(1);
}
diff --git a/src/mapmanager.cpp b/src/mapmanager.cpp
index 4ce5e398..95ed73e4 100644
--- a/src/mapmanager.cpp
+++ b/src/mapmanager.cpp
@@ -22,9 +22,8 @@
*/
#include "mapmanager.h"
-
#include "mapreader.h"
-
+#include "storage.h"
#include "utils/logger.h"
namespace tmwserv
@@ -36,8 +35,11 @@ MapManager::~MapManager()
{
}
-void MapManager::loadMap(const std::string& mapFile)
+void MapManager::loadMap(const unsigned int mapId)
{
+ //TODO: Check if the id exists, then get the string associated.
+ Storage &store = Storage::instance("tmw");
+ std::string mapFile = store.getMapNameFromId(mapId);
Map *map = MapReader::readMap("maps/" + mapFile);
if (map == NULL)
{
@@ -46,39 +48,39 @@ void MapManager::loadMap(const std::string& mapFile)
else
{
LOG_INFO("Loaded map " << maps.size() << " (" << mapFile << ")", 0);
- maps[mapFile] = map;
+ maps[mapId] = map;
}
}
-void MapManager::unloadMap(const std::string& mapFile)
+void MapManager::unloadMap(const unsigned int mapId)
{
- std::map<std::string, Map *>::iterator i;
-
- i = maps.find(mapFile);
+ std::map<unsigned int, Map *>::iterator i;
+
+ i = maps.find(mapId);
if (i != maps.end())
{
delete i->second;
maps.erase(i);
- LOG_INFO("Unloaded map (" << mapFile << ")", 0);
+ LOG_INFO("Unloaded map (" << mapId << ")", 0);
}
else
{
- LOG_WARN("Unable to unload map (" << mapFile << ")", 0);
+ LOG_WARN("Unable to unload map (" << mapId << ")", 0);
}
}
-void MapManager::reloadMap(const std::string& mapFile)
+void MapManager::reloadMap(const unsigned int mapId)
{
- unloadMap(mapFile);
- loadMap(mapFile);
+ unloadMap(mapId);
+ loadMap(mapId);
}
-Map *MapManager::getMap(const std::string& mapFile)
+Map *MapManager::getMap(const unsigned int mapId)
{
Map *result = NULL;
- std::map<std::string, Map *>::iterator i;
+ std::map<unsigned int, Map *>::iterator i;
- i = maps.find(mapFile);
+ i = maps.find(mapId);
if (i != maps.end())
{
result = i->second;
diff --git a/src/mapmanager.h b/src/mapmanager.h
index e4edf196..be166881 100644
--- a/src/mapmanager.h
+++ b/src/mapmanager.h
@@ -41,38 +41,38 @@ class MapManager: public utils::Singleton<MapManager>
{
// friend so that Singleton can call the constructor.
friend class utils::Singleton<MapManager>;
-
+
public:
/**
* Load the specified map
*/
- void loadMap(const std::string& mapFile);
-
+ void loadMap(const unsigned int mapId);
+
/**
* Unload the specified map
*/
- void unloadMap(const std::string& mapFile);
-
+ void unloadMap(const unsigned int mapId);
+
/**
* Reload the specified map
*/
- void reloadMap(const std::string& mapFile);
-
+ void reloadMap(const unsigned int mapId);
+
/**
* Return the requested map
*/
- Map *getMap(const std::string& mapFile);
-
+ Map *getMap(const unsigned int mapId);
+
protected:
/**
* Destructor.
*/
~MapManager(void)
throw();
-
+
private:
// Hold all the loaded maps.
- std::map<std::string, Map *> maps;
+ std::map<unsigned int, Map *> maps;
};
} // namespace tmwserv
diff --git a/src/netcomputer.cpp b/src/netcomputer.cpp
index 2bf04db8..40685b51 100644
--- a/src/netcomputer.cpp
+++ b/src/netcomputer.cpp
@@ -64,7 +64,7 @@ void NetComputer::setCharacter(tmwserv::BeingPtr ch)
state.removeBeing(characterPtr);
}
characterPtr = ch;
- state.addBeing(characterPtr, characterPtr->getMap());
+ state.addBeing(characterPtr, characterPtr->getMapId());
}
void NetComputer::unsetAccount()
diff --git a/src/object.cpp b/src/object.cpp
index 75ce0bec..fc156e7e 100644
--- a/src/object.cpp
+++ b/src/object.cpp
@@ -139,14 +139,14 @@ Object::getStatistics(void)
return mStats;
}
-const std::string &
-Object::getMap() {
- return mMap;
+const unsigned int
+Object::getMapId() {
+ return mMapId;
}
void
-Object::setMap(const std::string &map) {
- mMap = map;
+Object::setMap(const unsigned int mapId) {
+ mMapId = mapId;
}
} // namespace tmwserv
diff --git a/src/object.h b/src/object.h
index a00b81ec..26edf884 100644
--- a/src/object.h
+++ b/src/object.h
@@ -158,14 +158,14 @@ class Object
*
* @return Name of map being is located.
*/
- const std::string &
- getMap();
+ const unsigned int
+ getMapId();
/**
* Set map being is located
*/
void
- setMap(const std::string &map);
+ setMap(const unsigned int mapId);
protected:
Statistics mStats; /**< stats modifiers or computed stats */
@@ -176,7 +176,7 @@ class Object
unsigned int mX; /**< x coordinate */
unsigned int mY; /**< y coordinate */
- std::string mMap; /**< name of the map being is on */
+ unsigned int mMapId; /**< id of the map being is on */
};
diff --git a/src/state.cpp b/src/state.cpp
index 3177131d..1fbbb189 100644
--- a/src/state.cpp
+++ b/src/state.cpp
@@ -34,7 +34,7 @@ State::State() throw() {
}
State::~State() throw() {
- for (std::map<std::string, MapComposite>::iterator i = maps.begin();
+ for (std::map<unsigned int, MapComposite>::iterator i = maps.begin();
i != maps.end();
i++) {
delete i->second.map;
@@ -44,7 +44,7 @@ State::~State() throw() {
void State::update(ConnectionHandler &connectionHandler)
{
// update game state (update AI, etc.)
- for (std::map<std::string, MapComposite>::iterator i = maps.begin();
+ for (std::map<unsigned int, MapComposite>::iterator i = maps.begin();
i != maps.end();
i++) {
for (Beings::iterator b = i->second.beings.begin();
@@ -56,7 +56,7 @@ void State::update(ConnectionHandler &connectionHandler)
// notify clients about changes in the game world (only on their maps)
// NOTE: Should only send differences in the game state.
- for (std::map<std::string, MapComposite>::iterator i = maps.begin();
+ for (std::map<unsigned int, MapComposite>::iterator i = maps.begin();
i != maps.end();
i++) {
//
@@ -82,20 +82,20 @@ void State::update(ConnectionHandler &connectionHandler)
}
}
-void State::addBeing(BeingPtr beingPtr, const std::string &map) {
+void State::addBeing(BeingPtr beingPtr, const unsigned int mapId) {
if (!beingExists(beingPtr)) {
- if (!mapExists(map))
- if (!loadMap(map))
+ if (!mapExists(mapId))
+ if (!loadMap(mapId))
return;
// WARNING: We should pass a copy there.
// Otherwise, remove being will erase one character
// from the account object.
- maps[map].beings.push_back(beingPtr);
+ maps[mapId].beings.push_back(beingPtr);
}
}
void State::removeBeing(BeingPtr beingPtr) {
- for (std::map<std::string, MapComposite>::iterator i = maps.begin();
+ for (std::map<unsigned int, MapComposite>::iterator i = maps.begin();
i != maps.end();
i++) {
for (Beings::iterator b = i->second.beings.begin();
@@ -109,15 +109,15 @@ void State::removeBeing(BeingPtr beingPtr) {
}
}
-bool State::mapExists(const std::string &map) {
- std::map<std::string, MapComposite>::iterator i = maps.find(map);
+bool State::mapExists(const unsigned int mapId) {
+ std::map<unsigned int, MapComposite>::iterator i = maps.find(mapId);
if (i == maps.end())
return false;
return true;
}
bool State::beingExists(BeingPtr beingPtr) {
- for (std::map<std::string, MapComposite>::iterator i = maps.begin();
+ for (std::map<unsigned int, MapComposite>::iterator i = maps.begin();
i != maps.end();
i++) {
for (Beings::iterator b = i->second.beings.begin();
@@ -130,31 +130,31 @@ bool State::beingExists(BeingPtr beingPtr) {
return false;
}
-bool State::loadMap(const std::string &map) {
+bool State::loadMap(const unsigned int mapId) {
// load map (FAILS)
Map *tmp = NULL; //MapReader::readMap("maps/" + map);
//if (!tmp)
// return false;
- maps[map] = MapComposite();
- maps[map].map = tmp;
+ maps[mapId] = MapComposite();
+ maps[mapId].map = tmp;
// will need to load extra map related resources here also
-
+
return true; // We let true for testing on beings
}
-void State::addObject(Object *object, const std::string &map) {
+void State::addObject(Object *object, const unsigned int mapId) {
if (!objectExists(object)) {
- if (!mapExists(map))
- if (!loadMap(map))
+ if (!mapExists(mapId))
+ if (!loadMap(mapId))
return;
- maps[map].objects.push_back(object);
+ maps[mapId].objects.push_back(object);
}
}
void State::removeObject(Object *object) {
- for (std::map<std::string, MapComposite>::iterator i = maps.begin();
+ for (std::map<unsigned int, MapComposite>::iterator i = maps.begin();
i != maps.end();
i++) {
for (std::vector<Object*>::iterator b = i->second.objects.begin();
@@ -169,7 +169,7 @@ void State::removeObject(Object *object) {
}
bool State::objectExists(const Object *object) {
- for (std::map<std::string, MapComposite>::iterator i = maps.begin();
+ for (std::map<unsigned int, MapComposite>::iterator i = maps.begin();
i != maps.end();
i++) {
for (std::vector<Object*>::iterator b = i->second.objects.begin();
@@ -182,8 +182,8 @@ bool State::objectExists(const Object *object) {
return false;
}
-const std::string State::findPlayer(BeingPtr beingPtr) {
- for (std::map<std::string, MapComposite>::iterator i = maps.begin();
+const unsigned int State::findPlayer(BeingPtr beingPtr) {
+ for (std::map<unsigned int, MapComposite>::iterator i = maps.begin();
i != maps.end();
i++) {
for (Beings::iterator b = i->second.beings.begin();
@@ -193,11 +193,11 @@ const std::string State::findPlayer(BeingPtr beingPtr) {
return i->first;
}
}
- return "";
+ return 0;
}
-const std::string State::findObject(Object *object) {
- for (std::map<std::string, MapComposite>::iterator i = maps.begin();
+const unsigned int State::findObject(Object *object) {
+ for (std::map<unsigned int, MapComposite>::iterator i = maps.begin();
i != maps.end();
i++) {
for (std::vector<Object*>::iterator b = i->second.objects.begin();
@@ -207,7 +207,7 @@ const std::string State::findObject(Object *object) {
return i->first;
}
}
- return "";
+ return 0;
}
} // namespace tmwserv
diff --git a/src/state.h b/src/state.h
index 2fda7f50..bc6d3331 100644
--- a/src/state.h
+++ b/src/state.h
@@ -42,17 +42,17 @@ struct MapComposite {
* Default constructor
*/
MapComposite() : map(NULL) { }
-
+
/**
* Actual map
*/
Map *map;
-
+
/**
* Beings located on the map
*/
Beings beings;
-
+
/**
* Items located on the map
*/
@@ -73,7 +73,7 @@ class State : public utils::Singleton<State>
/**
* List of maps
*/
- std::map<std::string, MapComposite> maps;
+ std::map<unsigned int, MapComposite> maps;
public:
@@ -85,7 +85,7 @@ class State : public utils::Singleton<State>
/**
* Add being to game world at specified map
*/
- void addBeing(BeingPtr beingPtr, const std::string &map);
+ void addBeing(BeingPtr beingPtr, const unsigned int mapId);
/**
* Remove being from game world
@@ -95,7 +95,7 @@ class State : public utils::Singleton<State>
/**
* Check to see if a map exists in game world
*/
- bool mapExists(const std::string &map);
+ bool mapExists(const unsigned int mapId);
/**
* Check if being exists in game world already
@@ -105,12 +105,12 @@ class State : public utils::Singleton<State>
/**
* Load map into game world
*/
- bool loadMap(const std::string &map);
+ bool loadMap(const unsigned int mapId);
/**
* Add object to the map
*/
- void addObject(Object *object, const std::string &map);
+ void addObject(Object *object, const unsigned int mapId);
/**
* Remove an object from the map
@@ -125,12 +125,12 @@ class State : public utils::Singleton<State>
/**
* Find map player in world is on
*/
- const std::string findPlayer(BeingPtr being);
+ const unsigned int findPlayer(BeingPtr being);
/**
* Find map object in world is on
*/
- const std::string findObject(Object *object);
+ const unsigned int findObject(Object *object);
};
} // namespace tmwserv
diff --git a/src/storage.h b/src/storage.h
index 6a844320..682782bf 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -302,8 +302,15 @@ class Storage
* Tells if the character's name already exists
* @return true if character's name exists.
*/
- virtual
- bool doesCharacterNameExists(std::string name) = 0;
+ virtual bool
+ doesCharacterNameExists(std::string name) = 0;
+
+ /**
+ * Tells the map name from the map id
+ * @return the name of the map
+ */
+ virtual const std::string
+ getMapNameFromId(const unsigned int mapId) = 0;
/**
* Saves the changes permanently.