diff options
-rw-r--r-- | sql/updates/7040_01_mangos_achievement_reward.sql | 36 | ||||
-rw-r--r-- | sql/updates/TBC-WLK_world.sql | 36 | ||||
-rw-r--r-- | src/game/AchievementMgr.cpp | 373 | ||||
-rw-r--r-- | src/game/AchievementMgr.h | 79 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 33 | ||||
-rw-r--r-- | src/game/ObjectMgr.h | 15 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 8 | ||||
-rw-r--r-- | src/game/World.cpp | 19 | ||||
-rw-r--r-- | src/shared/revision_nr.h | 2 |
9 files changed, 433 insertions, 168 deletions
diff --git a/sql/updates/7040_01_mangos_achievement_reward.sql b/sql/updates/7040_01_mangos_achievement_reward.sql new file mode 100644 index 00000000000..0402a002526 --- /dev/null +++ b/sql/updates/7040_01_mangos_achievement_reward.sql @@ -0,0 +1,36 @@ +ALTER TABLE db_version CHANGE COLUMN required_7034_01_mangos_spell_proc_event required_7040_01_mangos_achievement_reward bit; + +DROP TABLE IF EXISTS `achievement_reward`; +CREATE TABLE `achievement_reward` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `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`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + + +DROP TABLE IF EXISTS `locales_achievement_reward`; +CREATE TABLE `locales_achievement_reward` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `subject_loc1` varchar(100) NOT NULL default '', + `subject_loc2` varchar(100) NOT NULL default '', + `subject_loc3` varchar(100) NOT NULL default '', + `subject_loc4` varchar(100) NOT NULL default '', + `subject_loc5` varchar(100) NOT NULL default '', + `subject_loc6` varchar(100) NOT NULL default '', + `subject_loc7` varchar(100) NOT NULL default '', + `subject_loc8` varchar(100) NOT NULL default '', + `text_loc1` text default NULL, + `text_loc2` text default NULL, + `text_loc3` text default NULL, + `text_loc4` text default NULL, + `text_loc5` text default NULL, + `text_loc6` text default NULL, + `text_loc7` text default NULL, + `text_loc8` text default NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/sql/updates/TBC-WLK_world.sql b/sql/updates/TBC-WLK_world.sql index 21ffaa1f17d..6a549ed4132 100644 --- a/sql/updates/TBC-WLK_world.sql +++ b/sql/updates/TBC-WLK_world.sql @@ -1,3 +1,39 @@ +DROP TABLE IF EXISTS `achievement_reward`; +CREATE TABLE `achievement_reward` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `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`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Loot System'; + + +DROP TABLE IF EXISTS `locales_achievement_reward`; +CREATE TABLE `locales_achievement_reward` ( + `entry` mediumint(8) unsigned NOT NULL default '0', + `subject_loc1` varchar(100) NOT NULL default '', + `subject_loc2` varchar(100) NOT NULL default '', + `subject_loc3` varchar(100) NOT NULL default '', + `subject_loc4` varchar(100) NOT NULL default '', + `subject_loc5` varchar(100) NOT NULL default '', + `subject_loc6` varchar(100) NOT NULL default '', + `subject_loc7` varchar(100) NOT NULL default '', + `subject_loc8` varchar(100) NOT NULL default '', + `text_loc1` text default NULL, + `text_loc2` text default NULL, + `text_loc3` text default NULL, + `text_loc4` text default NULL, + `text_loc5` text default NULL, + `text_loc6` text default NULL, + `text_loc7` text default NULL, + `text_loc8` text default NULL, + PRIMARY KEY (`entry`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + DELETE FROM battleground_template WHERE id IN (9,10,11); INSERT INTO battleground_template VALUES (9,0,0,0,0,1367,0,1368,0), diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index 44df14bf15b..c4a634c15c0 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -27,8 +27,13 @@ #include "GameEvent.h" #include "World.h" #include "SpellMgr.h" +#include "ProgressBar.h" -const CriteriaCastSpellRequirement AchievementMgr::criteriaCastSpellRequirements[CRITERIA_CAST_SPELL_REQ_COUNT] = +#include "Policies/SingletonImp.h" + +INSTANTIATE_SINGLETON_1(AchievementGlobalMgr); + +const CriteriaCastSpellRequirement AchievementGlobalMgr::m_criteriaCastSpellRequirements[CRITERIA_CAST_SPELL_REQ_COUNT] = { {5272, 3057, 0, 0}, {5273, 2784, 0, 0}, @@ -76,68 +81,6 @@ const CriteriaCastSpellRequirement AchievementMgr::criteriaCastSpellRequirements {6320, 0, CLASS_PALADIN, RACE_DRAENEI}, {6321, 0, CLASS_HUNTER, RACE_DWARF}, {6662, 31261, 0, 0} - }; - -const AchievementReward AchievementMgr::achievementRewards[ACHIEVEMENT_REWARD_COUNT] = - { - // achievementId, horde titleid, alliance titleid, itemid - {45, 0, 0, 43348}, - {46, 78, 78, 0}, - {230, 72, 72, 0}, - {456, 139, 139, 0}, - {614, 0, 0, 44223}, - {619, 0, 0, 44224}, - {714, 47, 47, 0}, - {762, 130, 130, 0}, - {870, 127, 126, 0}, - {871, 144, 144, 0}, - {876, 0, 0, 43349}, - {907, 48, 48, 0}, - {913, 74, 74, 0}, - {942, 79, 79, 0}, - {943, 79, 79, 0}, - {945, 131, 131, 0}, - {948, 130, 130, 0}, - {953, 132, 132, 0}, - {978, 81, 81, 0}, - {1015, 77, 77, 0}, - {1021, 0, 0, 40643}, - {1038, 75, 75, 0}, - {1039, 76, 76, 0}, - {1163, 128, 128, 0}, - {1174, 82, 82, 0}, - {1175, 72, 72, 0}, - {1250, 0, 0, 40653}, - {1400, 120, 120, 0}, - {1402, 122, 122, 0}, - {1516, 83, 83, 0}, - {1563, 84, 84, 0}, - {1656, 124, 124, 0}, - {1657, 124, 124, 0}, - {1658, 129, 129, 0}, - {1681, 125, 125, 43300}, - {1682, 125, 125, 43300}, - {1683, 133, 133, 0}, - {1684, 133, 133, 0}, - {1691, 134, 134, 0}, - {1692, 134, 134, 0}, - {1693, 135, 135, 0}, - {1707, 135, 135, 0}, - {1784, 84, 84, 0}, - {1793, 137, 137, 0}, - {1956, 0, 0, 43824}, - {2051, 140, 140, 0}, - {2054, 121, 121, 0}, - {2096, 0, 0, 44430}, - {2136, 0, 0, 0},// <- TODO: find item for spell 59961 - {2137, 0, 0, 0},// <- TODO: find item for spell 60021 - {2138, 0, 0, 0},// <- TODO: find item for spell 59976 - {2143, 0, 0, 44178}, - {2144, 0, 0, 0},// <- TODO: find item for spell 60024 - {2145, 0, 0, 0},// <- TODO: find item for spell 60024 - {2186, 141, 141, 0}, - {2187, 142, 142, 0}, - {2188, 143, 143, 0} }; AchievementMgr::AchievementMgr(Player *player) @@ -364,7 +307,7 @@ void AchievementMgr::CheckAllAchievementCriteria() void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, Unit *unit, uint32 time) { sLog.outDetail("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time); - AchievementCriteriaEntryList const& achievementCriteriaList = objmgr.GetAchievementCriteriaByType(type); + AchievementCriteriaEntryList const& achievementCriteriaList = achievementmgr.GetAchievementCriteriaByType(type); for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i) { AchievementCriteriaEntry const *achievementCriteria = (*i); @@ -523,19 +466,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui { if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID) continue; - // those requirements couldn't be found in the dbc - const CriteriaCastSpellRequirement *requirement = NULL; - for (uint32 i=0; i<CRITERIA_CAST_SPELL_REQ_COUNT; i++) - { - if (criteriaCastSpellRequirements[i].achievementCriteriaId == achievementCriteria->ID) - { - requirement = &criteriaCastSpellRequirements[i]; - break; - } - } - - if (requirement) + // those requirements couldn't be found in the dbc + if (CriteriaCastSpellRequirement const* requirement = AchievementGlobalMgr::GetCriteriaCastSpellRequirement(achievementCriteria)) { if (!unit) continue; @@ -549,6 +482,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (requirement->playerClass && (unit->GetTypeId() != TYPEID_PLAYER || unit->getClass()!=requirement->playerClass)) continue; } + SetCriteriaProgress(achievementCriteria, 1, true); break; } @@ -653,7 +587,7 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) { // someone on this realm has already completed that achievement - if(objmgr.allCompletedAchievements.find(achievement->ID)!=objmgr.allCompletedAchievements.end()) + if(achievementmgr.IsRealmCompleted(achievement)) return false; } @@ -838,55 +772,58 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) // don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement // TODO: where do set this instead? if(!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) - objmgr.allCompletedAchievements.insert(achievement->ID); + achievementmgr.SetRealmCompleted(achievement); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT); - // reward items and titles - // TODO: rewards should be send by mail - AchievementReward const* reward = NULL; - for (uint32 i=0; i<ACHIEVEMENT_REWARD_COUNT; i++) - { - if (achievementRewards[i].achievementId == achievement->ID) - { - reward = &achievementRewards[i]; - break; - } - } + // reward items and titles if any + AchievementReward const* reward = achievementmgr.GetAchievementReward(achievement); + + // no rewards + if(!reward) + return; - if (reward) + // titles + if(uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == HORDE?0:1]) { - uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == HORDE?0:1]; if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) GetPlayer()->SetTitle(titleEntry); + } - if (reward->itemId) + // mail + if(reward->sender) + { + Item* item = reward->itemId ? Item::CreateItem(reward->itemId,1,GetPlayer ()) : NULL; + + MailItemsInfo mi; + if(item) { - ItemPrototype const *pProto = objmgr.GetItemPrototype( reward->itemId ); + // save new item before send + item->SaveToDB(); // save for prevent lost at next mail load, if send fail then item will deleted - if(!pProto) - { - GetPlayer()->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); - return; - } + // item + mi.AddItem(item->GetGUIDLow(), item->GetEntry(), item); + } - ItemPosCountVec dest; - uint32 no_space = 0; - uint8 msg = GetPlayer()->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, reward->itemId, 1, &no_space ); + int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex(); - if( msg != EQUIP_ERR_OK ) - { - GetPlayer()->SendEquipError( msg, NULL, NULL ); - return; - } - Item* pItem = GetPlayer()->StoreNewItem( dest, reward->itemId, true); - - if(!pItem) + // subject and text + std::string subject = reward->subject; + std::string text = reward->text; + if ( loc_idx >= 0 ) + { + if(AchievementRewardLocale const* loc = achievementmgr.GetAchievementRewardLocale(achievement)) { - GetPlayer()->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); - return; + if (loc->subject.size() > size_t(loc_idx) && !loc->subject[loc_idx].empty()) + subject = loc->subject[loc_idx]; + if (loc->text.size() > size_t(loc_idx) && !loc->text[loc_idx].empty()) + text = loc->text[loc_idx]; } } + + uint32 itemTextId = objmgr.CreateItemText( text ); + + WorldSession::SendMailTo(GetPlayer(), MAIL_CREATURE, MAIL_STATIONERY_NORMAL, reward->sender, GetPlayer()->GetGUIDLow(), subject, itemTextId , &mi, 0, 0, MAIL_CHECK_MASK_NONE); } } @@ -932,3 +869,217 @@ void AchievementMgr::BuildAllDataPacket(WorldPacket *data) *data << int32(-1); } + +//========================================================== +AchievementCriteriaEntryList const& AchievementGlobalMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type) +{ + return m_AchievementCriteriasByType[type]; +} + +void AchievementGlobalMgr::LoadAchievementCriteriaList() +{ + for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++) + { + AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId); + if(!criteria) + continue; + + m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); + } +} + + +void AchievementGlobalMgr::LoadCompletedAchievements() +{ + QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement"); + + if(!result) + return; + + do + { + Field *fields = result->Fetch(); + m_allCompletedAchievements.insert(fields[0].GetUInt32()); + } while(result->NextRow()); + + delete result; +} + +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"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outString(">> Loaded 0 achievement rewards. DB table `achievement_reward` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + if (!sAchievementStore.LookupEntry(entry)) + { + sLog.outErrorDb( "Table `achievement_reward` has wrong achievement (Entry: %u), ignore", entry); + continue; + } + + 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(); + + 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]); + + // must be title or mail at least + if (!reward.titleId[0] && !reward.titleId[1] && !reward.sender) + { + sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have title or item reward data, ignore.", entry); + continue; + } + + if (reward.titleId[0]) + { + CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[0]); + if (!titleEntry) + { + sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_A`, set to 0", entry, reward.titleId[0]); + reward.titleId[0] = 0; + } + } + + if (reward.titleId[1]) + { + CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(reward.titleId[1]); + if (!titleEntry) + { + sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid title id (%u) in `title_A`, set to 0", entry, reward.titleId[1]); + reward.titleId[1] = 0; + } + } + + //check mail data before item for report including wrong item case + if (reward.sender) + { + if (!objmgr.GetCreatureTemplate(reward.sender)) + { + sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid creature entry %u as sender, mail reward skipped.", entry, reward.sender); + reward.sender = 0; + } + } + else + { + if (reward.itemId) + sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have item reward, item will not rewarded", entry); + + if (!reward.subject.empty()) + sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have mail subject.", entry); + + if (!reward.text.empty()) + sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) not have sender data but have mail text.", entry); + } + + if (reward.itemId) + { + if (!objmgr.GetItemPrototype(reward.itemId)) + { + sLog.outErrorDb( "Table `achievement_reward` (Entry: %u) has invalid item id %u, reward mail will be without item.", entry, reward.itemId); + reward.itemId = 0; + } + } + + m_achievementRewards[entry] = reward; + + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u achievement reward locale strings", m_achievementRewardLocales.size() ); +} + +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"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outString(">> Loaded 0 achievement reward locale strings. DB table `locales_achievement_reward` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + if(m_achievementRewards.find(entry)==m_achievementRewards.end()) + { + sLog.outErrorDb( "Table `locales_achievement_reward` (Entry: %u) has locale strings for not existed achievement reward .", entry); + continue; + } + + AchievementRewardLocale& data = m_achievementRewardLocales[entry]; + + for(int i = 1; i < MAX_LOCALE; ++i) + { + std::string str = fields[1+2*(i-1)].GetCppString(); + if(!str.empty()) + { + int idx = objmgr.GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.subject.size() <= idx) + data.subject.resize(idx+1); + + data.subject[idx] = str; + } + } + str = fields[1+2*(i-1)+1].GetCppString(); + if(!str.empty()) + { + int idx = objmgr.GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.text.size() <= idx) + data.text.resize(idx+1); + + data.text[idx] = str; + } + } + } + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u achievement reward locale strings", m_achievementRewardLocales.size() ); +} diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h index 6392a9fc647..19dc31c64e3 100644 --- a/src/game/AchievementMgr.h +++ b/src/game/AchievementMgr.h @@ -19,13 +19,19 @@ #define __MANGOS_ACHIEVEMENTMGR_H #include "Common.h" +#include "Policies/Singleton.h" #include "Database/DBCEnums.h" #include "Database/DBCStores.h" #include "Database/DatabaseEnv.h" +#include <map> +#include <string> + #define CRITERIA_CAST_SPELL_REQ_COUNT 46 #define ACHIEVEMENT_REWARD_COUNT 57 +typedef std::list<const AchievementCriteriaEntry*> AchievementCriteriaEntryList; + struct CriteriaProgress { uint32 counter; @@ -43,11 +49,24 @@ struct CriteriaCastSpellRequirement struct AchievementReward { - uint32 achievementId; uint32 titleId[2]; uint32 itemId; + uint32 sender; + std::string subject; + std::string text; }; +typedef std::map<uint32,AchievementReward> AchievementRewards; + +struct AchievementRewardLocale +{ + std::vector<std::string> subject; + std::vector<std::string> text; +}; + +typedef std::map<uint32,AchievementRewardLocale> AchievementRewardLocales; + + struct CompletedAchievementData { time_t date; @@ -95,7 +114,61 @@ class AchievementMgr Player* m_player; CriteriaProgressMap m_criteriaProgress; CompletedAchievementMap m_completedAchievements; - static const CriteriaCastSpellRequirement criteriaCastSpellRequirements[]; - static const AchievementReward achievementRewards[]; }; + +class AchievementGlobalMgr +{ + public: + AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type); + + AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const + { + AchievementRewards::const_iterator iter = m_achievementRewards.find(achievement->ID); + return iter!=m_achievementRewards.end() ? &iter->second : NULL; + } + + AchievementRewardLocale const* GetAchievementRewardLocale(AchievementEntry const* achievement) const + { + AchievementRewardLocales::const_iterator iter = m_achievementRewardLocales.find(achievement->ID); + return iter!=m_achievementRewardLocales.end() ? &iter->second : NULL; + } + + static CriteriaCastSpellRequirement const * GetCriteriaCastSpellRequirement(AchievementCriteriaEntry const *achievementCriteria) + { + for (uint32 i=0; i < CRITERIA_CAST_SPELL_REQ_COUNT; ++i) + if (m_criteriaCastSpellRequirements[i].achievementCriteriaId == achievementCriteria->ID) + return &m_criteriaCastSpellRequirements[i]; + + return NULL; + } + + bool IsRealmCompleted(AchievementEntry const* achievement) const + { + return m_allCompletedAchievements.find(achievement->ID) != m_allCompletedAchievements.end(); + } + + void SetRealmCompleted(AchievementEntry const* achievement) + { + m_allCompletedAchievements.insert(achievement->ID); + } + + void LoadAchievementCriteriaList(); + void LoadCompletedAchievements(); + void LoadRewards(); + void LoadRewardLocales(); + private: + static const CriteriaCastSpellRequirement m_criteriaCastSpellRequirements[]; + + // store achievement criterias by type to speed up lookup + AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL]; + + typedef std::set<uint32> AllCompletedAchievements; + AllCompletedAchievements m_allCompletedAchievements; + + AchievementRewards m_achievementRewards; + AchievementRewardLocales m_achievementRewardLocales; +}; + +#define achievementmgr MaNGOS::Singleton<AchievementGlobalMgr>::Instance() + #endif diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 0b2815c8beb..3e7a9d2925f 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -642,22 +642,6 @@ void ObjectMgr::LoadCreatureLocales() sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() ); } -void ObjectMgr::LoadCompletedAchievements() -{ - QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement"); - - if(!result) - return; - - do - { - Field *fields = result->Fetch(); - allCompletedAchievements.insert(fields[0].GetUInt32()); - } while(result->NextRow()); - - delete result; -} - void ObjectMgr::LoadNpcOptionLocales() { mNpcOptionLocaleMap.clear(); // need for reload case @@ -6493,23 +6477,6 @@ int ObjectMgr::GetOrNewIndexForLocale( LocaleConstant loc ) return m_LocalForIndex.size()-1; } -AchievementCriteriaEntryList const& ObjectMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type) -{ - return m_AchievementCriteriasByType[type]; -} - -void ObjectMgr::LoadAchievementCriteriaList() -{ - for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++) - { - AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId); - if(!criteria) - continue; - - m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); - } -} - void ObjectMgr::LoadBattleMastersEntry() { mBattleMastersMap.clear(); // need for reload case diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 4216792743c..e4383cae605 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -264,8 +264,6 @@ typedef std::list<GossipOption> CacheNpcOptionList; typedef UNORDERED_MAP<uint32, VendorItemData> CacheVendorItemMap; typedef UNORDERED_MAP<uint32, TrainerSpellData> CacheTrainerSpellMap; -typedef std::list<const AchievementCriteriaEntry*> AchievementCriteriaEntryList; - enum SkillRangeType { SKILL_RANGE_LANGUAGE, // 300..300 @@ -595,8 +593,7 @@ class ObjectMgr void LoadNpcTextId(); void LoadVendors(); void LoadTrainerSpell(); - void LoadCompletedAchievements(); - + std::string GeneratePetName(uint32 entry); uint32 GetBaseXP(uint32 level); @@ -809,14 +806,12 @@ class ObjectMgr bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true); // for event bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0 ) const; - void LoadAchievementCriteriaList(); - AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type); - std::set<uint32> allCompletedAchievements; - void LoadScriptNames(); ScriptNameMap &GetScriptNames() { return m_scriptNames; } const char * GetScriptName(uint32 id) { return id < m_scriptNames.size() ? m_scriptNames[id].c_str() : ""; } uint32 GetScriptId(const char *name); + + int GetOrNewIndexForLocale(LocaleConstant loc); protected: // first free id for selected id type @@ -888,7 +883,6 @@ class ObjectMgr typedef std::vector<LocaleConstant> LocalForIndex; LocalForIndex m_LocalForIndex; - int GetOrNewIndexForLocale(LocaleConstant loc); int DBCLocaleIndex; @@ -942,9 +936,6 @@ class ObjectMgr CacheNpcTextIdMap m_mCacheNpcTextIdMap; CacheVendorItemMap m_mCacheVendorItemMap; CacheTrainerSpellMap m_mCacheTrainerSpellMap; - - // store achievement criterias by type to speed up lookup - AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL]; }; #define objmgr Trinity::Singleton<ObjectMgr>::Instance() diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index d57c8875041..11d1fa7f501 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -4750,13 +4750,15 @@ void Spell::EffectScriptEffect(uint32 effIndex) } } - static uint32 const itypes[6][3] = { + static uint32 const itypes[8][3] = { { 5512,19004,19005}, // Minor Healthstone { 5511,19006,19007}, // Lesser Healthstone { 5509,19008,19009}, // Healthstone { 5510,19010,19011}, // Greater Healthstone { 9421,19012,19013}, // Major Healthstone - {22103,22104,22105} // Master Healthstone + {22103,22104,22105}, // Master Healthstone + {36889,36890,36891}, // Demonic Healthstone + {36892,36893,36894} // Fel Healthstone }; switch(m_spellInfo->Id) @@ -4767,6 +4769,8 @@ void Spell::EffectScriptEffect(uint32 effIndex) case 11729: itemtype=itypes[3][rank];break; // Greater Healthstone case 11730: itemtype=itypes[4][rank];break; // Major Healthstone case 27230: itemtype=itypes[5][rank];break; // Master Healthstone + case 47871: itemtype=itypes[6][rank];break; // Demonic Healthstone + case 47878: itemtype=itypes[7][rank];break; // Fel Healthstone default: return; } diff --git a/src/game/World.cpp b/src/game/World.cpp index 3f1fc1773f1..f8bdd9f24c2 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -37,6 +37,7 @@ #include "SkillDiscovery.h" #include "World.h" #include "AccountMgr.h" +#include "AchievementMgr.h" #include "ObjectMgr.h" #include "SpellMgr.h" #include "Chat.h" @@ -1106,12 +1107,6 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading InstanceTemplate" ); objmgr.LoadInstanceTemplate(); - sLog.outString( "Loading AchievementCriteriaList..." ); - objmgr.LoadAchievementCriteriaList(); - - sLog.outString( "Loading completed achievements..." ); - objmgr.LoadCompletedAchievements(); - sLog.outString( "Loading SkillLineAbilityMultiMap Data..." ); spellmgr.LoadSkillLineAbilityMap(); @@ -1285,6 +1280,18 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Skill Fishing base level requirements..." ); objmgr.LoadFishingBaseSkillLevel(); + sLog.outString( "Loading AchievementCriteriaList..." ); + achievementmgr.LoadAchievementCriteriaList(); + + sLog.outString( "Loading achievement rewards..." ); + achievementmgr.LoadRewards(); + + sLog.outString( "Loading achievement reward locale strings..." ); + achievementmgr.LoadRewardLocales(); + + sLog.outString( "Loading completed achievements..." ); + achievementmgr.LoadCompletedAchievements(); + ///- Load dynamic data tables from the database sLog.outString( "Loading Auctions..." ); objmgr.LoadAuctionItems(); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c956a070555..05ad9af7f9c 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 "7039" + #define REVISION_NR "7041" #endif // __REVISION_NR_H__ |