diff --git a/sql/mangos.sql b/sql/mangos.sql index 45e2a6cd3..99a9422f4 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_9692_03_mangos_spell_proc_event` bit(1) default NULL + `required_9704_01_mangos_achievement_reward` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -67,13 +67,14 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `achievement_reward`; CREATE TABLE `achievement_reward` ( `entry` mediumint(8) unsigned NOT NULL default '0', + `gender` tinyint(3) default '2', `title_A` mediumint(8) unsigned NOT NULL default '0', `title_H` mediumint(8) unsigned NOT NULL default '0', `item` mediumint(8) unsigned NOT NULL default '0', `sender` mediumint(8) unsigned NOT NULL default '0', `subject` varchar(255) default NULL, `text` text, - PRIMARY KEY (`entry`) + PRIMARY KEY (`entry`,`gender`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Achievment system'; -- @@ -2370,6 +2371,7 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `locales_achievement_reward`; CREATE TABLE `locales_achievement_reward` ( `entry` mediumint(8) unsigned NOT NULL default '0', + `gender` tinyint(3) default '2', `subject_loc1` varchar(100) NOT NULL default '', `subject_loc2` varchar(100) NOT NULL default '', `subject_loc3` varchar(100) NOT NULL default '', @@ -2386,7 +2388,7 @@ CREATE TABLE `locales_achievement_reward` ( `text_loc6` text default NULL, `text_loc7` text default NULL, `text_loc8` text default NULL, - PRIMARY KEY (`entry`) + PRIMARY KEY (`entry`,`gender`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- diff --git a/sql/updates/9704_01_mangos_achievement_reward.sql b/sql/updates/9704_01_mangos_achievement_reward.sql new file mode 100644 index 000000000..2d98a7db2 --- /dev/null +++ b/sql/updates/9704_01_mangos_achievement_reward.sql @@ -0,0 +1,11 @@ +ALTER TABLE db_version CHANGE COLUMN required_9692_03_mangos_spell_proc_event required_9704_01_mangos_achievement_reward bit; + +ALTER TABLE achievement_reward + ADD COLUMN gender TINYINT(3) DEFAULT '2' after entry, + DROP PRIMARY KEY, + ADD PRIMARY KEY (entry,gender); + +ALTER TABLE locales_achievement_reward + ADD COLUMN gender TINYINT(3) DEFAULT '2' after entry, + DROP PRIMARY KEY, + ADD PRIMARY KEY (entry,gender); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 4270084c1..7dbf29ebf 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -110,6 +110,7 @@ pkgdata_DATA = \ 9692_02_characters_mail.sql \ 9692_03_mangos_spell_proc_event.sql \ 9702_01_characters_item.sql \ + 9704_01_mangos_achievement_reward.sql \ README ## Additional files to include when running 'make dist' @@ -200,4 +201,5 @@ EXTRA_DIST = \ 9692_02_characters_mail.sql \ 9692_03_mangos_spell_proc_event.sql \ 9702_01_characters_item.sql \ + 9704_01_mangos_achievement_reward.sql \ README diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index c80b43e3c..841ea1b1f 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -1796,7 +1796,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT); // reward items and titles if any - AchievementReward const* reward = sAchievementMgr.GetAchievementReward(achievement); + AchievementReward const* reward = sAchievementMgr.GetAchievementReward(achievement, GetPlayer()->getGender()); // no rewards if(!reward) @@ -1821,7 +1821,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) std::string text = reward->text; if ( loc_idx >= 0 ) { - if(AchievementRewardLocale const* loc = sAchievementMgr.GetAchievementRewardLocale(achievement)) + if(AchievementRewardLocale const* loc = sAchievementMgr.GetAchievementRewardLocale(achievement, GetPlayer()->getGender())) { if (loc->subject.size() > size_t(loc_idx) && !loc->subject[loc_idx].empty()) subject = loc->subject[loc_idx]; @@ -2128,8 +2128,8 @@ void AchievementGlobalMgr::LoadRewards() { m_achievementRewards.clear(); // need for reload case - // 0 1 2 3 4 5 6 - QueryResult *result = WorldDatabase.Query("SELECT entry, title_A, title_H, item, sender, subject, text FROM achievement_reward"); + // 0 1 2 3 4 5 6 7 + QueryResult *result = WorldDatabase.Query("SELECT entry, gender, title_A, title_H, item, sender, subject, text FROM achievement_reward"); if(!result) { @@ -2158,12 +2158,16 @@ void AchievementGlobalMgr::LoadRewards() } AchievementReward reward; - reward.titleId[0] = fields[1].GetUInt32(); - reward.titleId[1] = fields[2].GetUInt32(); - reward.itemId = fields[3].GetUInt32(); - reward.sender = fields[4].GetUInt32(); - reward.subject = fields[5].GetCppString(); - reward.text = fields[6].GetCppString(); + reward.gender = Gender(fields[1].GetUInt8()); + reward.titleId[0] = fields[2].GetUInt32(); + reward.titleId[1] = fields[3].GetUInt32(); + reward.itemId = fields[4].GetUInt32(); + reward.sender = fields[5].GetUInt32(); + reward.subject = fields[6].GetCppString(); + reward.text = fields[7].GetCppString(); + + if (reward.gender >= MAX_GENDER) + sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has wrong gender %u.", entry, reward.gender); if ((reward.titleId[0]==0)!=(reward.titleId[1]==0)) sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has title (A: %u H: %u) only for one from teams.", entry, reward.titleId[0], reward.titleId[1]); @@ -2225,7 +2229,7 @@ void AchievementGlobalMgr::LoadRewards() } } - m_achievementRewards[entry] = reward; + m_achievementRewards.insert(AchievementRewards::value_type(entry,reward)); ++count; } while (result->NextRow()); @@ -2240,7 +2244,7 @@ void AchievementGlobalMgr::LoadRewardLocales() { m_achievementRewardLocales.clear(); // need for reload case - QueryResult *result = WorldDatabase.Query("SELECT entry,subject_loc1,text_loc1,subject_loc2,text_loc2,subject_loc3,text_loc3,subject_loc4,text_loc4,subject_loc5,text_loc5,subject_loc6,text_loc6,subject_loc7,text_loc7,subject_loc8,text_loc8 FROM locales_achievement_reward"); + QueryResult *result = WorldDatabase.Query("SELECT entry,gender,subject_loc1,text_loc1,subject_loc2,text_loc2,subject_loc3,text_loc3,subject_loc4,text_loc4,subject_loc5,text_loc5,subject_loc6,text_loc6,subject_loc7,text_loc7,subject_loc8,text_loc8 FROM locales_achievement_reward"); if(!result) { @@ -2268,11 +2272,16 @@ void AchievementGlobalMgr::LoadRewardLocales() continue; } - AchievementRewardLocale& data = m_achievementRewardLocales[entry]; + AchievementRewardLocale data; + + data.gender = Gender(fields[1].GetUInt8()); + + if (data.gender >= MAX_GENDER) + sLog.outErrorDb( "Table `locales_achievement_reward` (Entry: %u) has wrong gender %u.", entry, data.gender); for(int i = 1; i < MAX_LOCALE; ++i) { - std::string str = fields[1+2*(i-1)].GetCppString(); + std::string str = fields[2+2*(i-1)].GetCppString(); if(!str.empty()) { int idx = sObjectMgr.GetOrNewIndexForLocale(LocaleConstant(i)); @@ -2284,7 +2293,7 @@ void AchievementGlobalMgr::LoadRewardLocales() data.subject[idx] = str; } } - str = fields[1+2*(i-1)+1].GetCppString(); + str = fields[2+2*(i-1)+1].GetCppString(); if(!str.empty()) { int idx = sObjectMgr.GetOrNewIndexForLocale(LocaleConstant(i)); @@ -2297,6 +2306,9 @@ void AchievementGlobalMgr::LoadRewardLocales() } } } + + m_achievementRewardLocales.insert(AchievementRewardLocales::value_type(entry,data)); + } while (result->NextRow()); delete result; diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h index 69966d4af..d66c11dbd 100644 --- a/src/game/AchievementMgr.h +++ b/src/game/AchievementMgr.h @@ -203,6 +203,7 @@ typedef std::map AchievementCriteriaRe struct AchievementReward { + Gender gender; uint32 titleId[2]; uint32 itemId; uint32 sender; @@ -210,15 +211,16 @@ struct AchievementReward std::string text; }; -typedef std::map AchievementRewards; +typedef std::multimap AchievementRewards; struct AchievementRewardLocale { + Gender gender; std::vector subject; std::vector text; }; -typedef std::map AchievementRewardLocales; +typedef std::multimap AchievementRewardLocales; struct CompletedAchievementData @@ -284,16 +286,26 @@ class AchievementGlobalMgr return itr != m_AchievementListByReferencedId.end() ? &itr->second : NULL; } - AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const + AchievementReward const* GetAchievementReward(AchievementEntry const* achievement, uint8 gender) const { - AchievementRewards::const_iterator iter = m_achievementRewards.find(achievement->ID); - return iter!=m_achievementRewards.end() ? &iter->second : NULL; + AchievementRewards::const_iterator iter_low = m_achievementRewards.lower_bound(achievement->ID); + AchievementRewards::const_iterator iter_up = m_achievementRewards.upper_bound(achievement->ID); + for (AchievementRewards::const_iterator iter = iter_low; iter != iter_low; ++iter) + if(iter->second.gender == GENDER_NONE || uint8(iter->second.gender) == gender) + return &iter->second; + + return NULL; } - AchievementRewardLocale const* GetAchievementRewardLocale(AchievementEntry const* achievement) const + AchievementRewardLocale const* GetAchievementRewardLocale(AchievementEntry const* achievement, uint8 gender) const { - AchievementRewardLocales::const_iterator iter = m_achievementRewardLocales.find(achievement->ID); - return iter!=m_achievementRewardLocales.end() ? &iter->second : NULL; + AchievementRewardLocales::const_iterator iter_low = m_achievementRewardLocales.lower_bound(achievement->ID); + AchievementRewardLocales::const_iterator iter_up = m_achievementRewardLocales.upper_bound(achievement->ID); + for (AchievementRewardLocales::const_iterator iter = iter_low; iter != iter_low; ++iter) + if(iter->second.gender == GENDER_NONE || uint8(iter->second.gender) == gender) + return &iter->second; + + return NULL; } AchievementCriteriaRequirementSet const* GetCriteriaRequirementSet(AchievementCriteriaEntry const *achievementCriteria) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index dfa8f33b7..0e144e936 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1011,7 +1011,7 @@ void ObjectMgr::LoadCreatureModelInfo() if (!sCreatureDisplayInfoStore.LookupEntry(minfo->modelid)) sLog.outErrorDb("Table `creature_model_info` has model for not existed display id (%u).", minfo->modelid); - if (minfo->gender > GENDER_NONE) + if (minfo->gender >= MAX_GENDER) { sLog.outErrorDb("Table `creature_model_info` has wrong gender (%u) for display id (%u).", uint32(minfo->gender), minfo->modelid); const_cast(minfo)->gender = GENDER_MALE; diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index f2e4d2600..d1d792f2b 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -29,6 +29,8 @@ enum Gender GENDER_NONE = 2 }; +#define MAX_GENDER 3 + // Race value is index in ChrRaces.dbc enum Races { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b5a1f4fe8..53024e4c3 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9703" + #define REVISION_NR "9704" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 8fec2ef11..f6e9c710d 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_9702_01_characters_item" - #define REVISION_DB_MANGOS "required_9692_03_mangos_spell_proc_event" + #define REVISION_DB_MANGOS "required_9704_01_mangos_achievement_reward" #define REVISION_DB_REALMD "required_9010_01_realmd_realmlist" #endif // __REVISION_SQL_H__