From f5fdb19e7aac292cca31ec23250587e0d97d0ff6 Mon Sep 17 00:00:00 2001 From: Chuck Miller Date: Thu, 1 Oct 2009 00:26:38 -0400 Subject: Adds code for saving and getting status effects from the database --- src/account-server/character.hpp | 16 ++++++++ src/account-server/dalstorage.cpp | 77 +++++++++++++++++++++++++++++++++++++++ src/account-server/dalstorage.hpp | 8 ++++ src/game-server/being.hpp | 2 +- src/game-server/character.cpp | 7 ++++ src/game-server/character.hpp | 15 ++++++++ src/serialize/characterdata.hpp | 17 +++++++++ 7 files changed, 141 insertions(+), 1 deletion(-) diff --git a/src/account-server/character.hpp b/src/account-server/character.hpp index d38d0211..32d8a8a6 100644 --- a/src/account-server/character.hpp +++ b/src/account-server/character.hpp @@ -124,6 +124,21 @@ class Character void receiveExperience(int skill, int value) { mExperience[skill] += value; } + /** + * Get / Set a status effects + */ + void applyStatusEffect(int id, int time) + { mStatusEffects[id] = time; } + + int getStatusEffectSize() const + { return mStatusEffects.size(); } + + const std::map::const_iterator getStatusEffectBegin() const + { return mStatusEffects.begin(); } + + const std::map::const_iterator getStatusEffectEnd() const + { return mStatusEffects.end(); } + /** * Gets the Id of the map that the character is on. */ @@ -180,6 +195,7 @@ class Character Point mPos; //!< Position the being is at. unsigned short mAttributes[CHAR_ATTR_NB]; //!< Attributes. std::map mExperience; //!< Skill Experience. + std::map mStatusEffects; //!< Status Effects 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 4628eca5..1f71d40c 100644 --- a/src/account-server/dalstorage.cpp +++ b/src/account-server/dalstorage.cpp @@ -314,6 +314,22 @@ Character *DALStorage::getCharacterBySQL(Account *owner) toUint(skillInfo(row, 1))); // experience } } + s.clear(); + s.str(""); + // Load the status effect + s << "select status_id, status_time FROM " << CHAR_STATUS_EFFECTS_TBL_NAME + << " WHERE char_id = " << character->getDatabaseID(); + const dal::RecordSet &statusInfo = mDb->execSql(s.str()); + if (!statusInfo.isEmpty()) + { + const unsigned int nRows = statusInfo.rows(); + for (unsigned int row = 0; row < nRows; row++) + { + character->applyStatusEffect( + toUint(statusInfo(row, 0)), // Statusid + toUint(statusInfo(row, 1))); // Time + } + } } catch (const dal::DbSqlQueryExecFailure &e) { @@ -670,6 +686,48 @@ bool DALStorage::updateCharacter(Character *character, return false; } + /** + * Update char status effects + */ + try + { + // Delete the old status effects first + std::ostringstream sql; + + sql << "delete from " << CHAR_STATUS_EFFECTS_TBL_NAME + << " where char_id = '" << character->getDatabaseID() << "';"; + + mDb->execSql(sql.str()); + } + catch (const dal::DbSqlQueryExecFailure& e) + { + // TODO: throw an exception. + if (startTransaction) + { + mDb->rollbackTransaction(); + } + LOG_ERROR("(DALStorage::updateCharacter #5) SQL query failure: " << e.what()); + return false; + } + try + { + std::map::const_iterator status_it; + for (status_it = character->getStatusEffectBegin(); + status_it != character->getStatusEffectEnd(); status_it++) + { + insertStatusEffect(character->getDatabaseID(), status_it->first, status_it->second); + } + } + catch (const dal::DbSqlQueryExecFailure& e) + { + // TODO: throw an exception + if (startTransaction) + { + mDb->rollbackTransaction(); + } + LOG_ERROR("(DALStorage::updateCharacter #6) SQL query failure: " << e.what()); + return false; + } if (startTransaction) { mDb->commitTransaction(); @@ -972,6 +1030,25 @@ void DALStorage::updateExperience(const int CharId, const int SkillId, } } +void DALStorage::insertStatusEffect(const int charId, const int statusId, const int time) +{ + try + { + std::ostringstream sql; + + sql << "insert into " << CHAR_STATUS_EFFECTS_TBL_NAME + << " (char_id, status_id, status_time) VALUES ( " + << charId << ", " + << statusId << ", " + << time << ")"; + mDb->execSql(sql.str()); + } + catch (const dal::DbSqlQueryExecFailure &e) + { + LOG_ERROR("DALStorage::insertStatusEffect: " << e.what()); + throw; + } +} /** diff --git a/src/account-server/dalstorage.hpp b/src/account-server/dalstorage.hpp index 77222377..36bb1e39 100644 --- a/src/account-server/dalstorage.hpp +++ b/src/account-server/dalstorage.hpp @@ -146,6 +146,14 @@ class DALStorage void updateExperience(const int CharId, const int SkillId, const int SkillValue); + /** + * Inserts a record about a status effect into the database + * @param charId ID of the character in the database + * @param statusId ID of the status effect + * @param time Time left on the status effect + */ + void insertStatusEffect(const int charId, const int statusId, const int time); + /** * Sets a ban on an account (hence on all its characters). * diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp index d78ca78a..cb811b12 100644 --- a/src/game-server/being.hpp +++ b/src/game-server/being.hpp @@ -334,6 +334,7 @@ class Being : public Actor static const int TICKS_PER_HP_REGENERATION = 100; Action mAction; std::vector< Attribute > mAttributes; + StatusEffects mStatus; Being *mTarget; Point mOld; /**< Old coordinates. */ Point mDst; /**< Target coordinates. */ @@ -349,7 +350,6 @@ class Being : public Actor std::string mName; Hits mHitsTaken; /**< List of punches taken since last update. */ AttributeModifiers mModifiers; /**< Currently modified attributes. */ - StatusEffects mStatus; int mHpRegenTimer; /**< Timer for hp regeneration. */ }; diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 2d022a1c..f7366dc3 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -124,6 +124,13 @@ void Character::update() mSpecialUpdateNeeded = false; } + mStatusEffects.clear(); + StatusEffects::iterator it = mStatus.begin(); + while(it != mStatus.end()) + { + mStatusEffects[it->first] = it->second.time; + it++; + } Being::update(); } diff --git a/src/game-server/character.hpp b/src/game-server/character.hpp index 603a4a16..2ffb9eeb 100644 --- a/src/game-server/character.hpp +++ b/src/game-server/character.hpp @@ -276,6 +276,18 @@ class Character : public Being const std::map::const_iterator getSkillEnd() const { return mExperience.end(); } + /** + * used to serialized status effects + */ + int getStatusEffectSize() const + { return mStatusEffects.size(); } + + const std::map::const_iterator getStatusEffectBegin() const + { return mStatusEffects.begin(); } + + const std::map::const_iterator getStatusEffectEnd() const + { return mStatusEffects.end(); } + /** * Gets total accumulated exp for skill */ @@ -391,6 +403,9 @@ class Character : public Being std::map mExperience; /**< experience collected for each skill.*/ std::map mSpecials; + std::map mStatusEffects; /**< only used by select functions + to make it easier to make the accountserver + do not modify or use anywhere else*/ int mRechargePerSpecial; bool mSpecialUpdateNeeded; diff --git a/src/serialize/characterdata.hpp b/src/serialize/characterdata.hpp index ac281e70..0f3f4c50 100644 --- a/src/serialize/characterdata.hpp +++ b/src/serialize/characterdata.hpp @@ -54,6 +54,14 @@ void serializeCharacterData(const T &data, MessageOut &msg) msg.writeLong(skill_it->second); } + msg.writeShort(data.getStatusEffectSize()); + std::map::const_iterator status_it; + for (status_it = data.getStatusEffectBegin(); status_it != data.getStatusEffectEnd(); status_it++) + { + msg.writeShort(status_it->first); + msg.writeShort(status_it->second); + } + msg.writeShort(data.getMapId()); const Point &pos = data.getPosition(); @@ -99,6 +107,15 @@ void deserializeCharacterData(T &data, MessageIn &msg) data.setExperience(skill,level); } + int statusSize = msg.readShort(); + + for (int i = 0; i < statusSize; i++) + { + int status = msg.readShort(); + int time = msg.readShort(); + data.applyStatusEffect(status, time); + } + data.setMapId(msg.readShort()); Point temporaryPoint; -- cgit v1.2.3-60-g2f50