summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.