aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/7040_01_mangos_achievement_reward.sql36
-rw-r--r--sql/updates/TBC-WLK_world.sql36
-rw-r--r--src/game/AchievementMgr.cpp373
-rw-r--r--src/game/AchievementMgr.h79
-rw-r--r--src/game/ObjectMgr.cpp33
-rw-r--r--src/game/ObjectMgr.h15
-rw-r--r--src/game/SpellEffects.cpp8
-rw-r--r--src/game/World.cpp19
-rw-r--r--src/shared/revision_nr.h2
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__