aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Achievements/AchievementMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Achievements/AchievementMgr.cpp')
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp105
1 files changed, 95 insertions, 10 deletions
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index a377f83201f..39b09ecf29d 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -482,7 +482,7 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
if (m_player->IsGameMaster())
return;
- AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
+ AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type, 0/*get all*/);
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
{
AchievementCriteriaEntry const* achievementCriteria = (*i);
@@ -741,7 +741,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
TC_LOG_DEBUG("achievement", "UpdateAchievementCriteria: %s, %s (%u), %u, %u"
, m_player->GetGUID().ToString().c_str(), AchievementGlobalMgr::GetCriteriaTypeString(type), type, miscValue1, miscValue2);
- AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
+ AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type, miscValue1);
for (AchievementCriteriaEntry const* achievementCriteria : achievementCriteriaList)
{
AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementCriteria->ReferredAchievement);
@@ -768,7 +768,9 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
switch (type)
{
// std. case: increment at 1
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
case ACHIEVEMENT_CRITERIA_TYPE_DEATH:
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON:
@@ -808,9 +810,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
break;
// std case: increment at miscvalue1
- case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
- case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS:
@@ -864,7 +864,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
SetCriteriaProgress(achievementCriteria, maxSkillvalue);
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
- if (m_completedAchievements.find(achievementCriteria->Asset.AchievementID) != m_completedAchievements.end())
+ if ((miscValue1 && achievementCriteria->Asset.AchievementID == miscValue1) || (!miscValue1 && m_completedAchievements.find(achievementCriteria->Asset.AchievementID) != m_completedAchievements.end()))
SetCriteriaProgress(achievementCriteria, 1);
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
@@ -1492,7 +1492,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
sAchievementMgr->SetRealmCompleted(achievement, GetPlayer()->GetInstanceId());
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, achievement->ID);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->Points);
// reward items and titles if any
@@ -1879,11 +1879,11 @@ bool AchievementMgr::RequirementsSatisfied(AchievementCriteriaEntry const* achie
return false;
break;
case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
- // miscvalue1 = itemid
- // miscvalue2 = itemSlot
- if (!miscValue1)
+ // miscvalue1 = itemSlot
+ // miscvalue2 = itemid
+ if (!miscValue2)
return false;
- if (miscValue2 != achievementCriteria->Asset.ItemSlot)
+ if (miscValue1 != achievementCriteria->Asset.ItemSlot)
return false;
break;
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
@@ -2187,6 +2187,60 @@ AchievementGlobalMgr* AchievementGlobalMgr::instance()
return &instance;
}
+inline bool IsAchievementCriteriaTypeStoredByMiscValue(AchievementCriteriaTypes type)
+{
+ switch (type)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
+ case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
+ case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
+ case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+AchievementCriteriaEntryList const& AchievementGlobalMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type, uint32 miscValue) const
+{
+ if (miscValue && IsAchievementCriteriaTypeStoredByMiscValue(type))
+ {
+ auto itr = m_AchievementCriteriasByMiscValue[type].find(miscValue);
+ if (itr != m_AchievementCriteriasByMiscValue[type].end())
+ return itr->second;
+ }
+
+ return m_AchievementCriteriasByType[type];
+}
+
//==========================================================
void AchievementGlobalMgr::LoadAchievementCriteriaList()
{
@@ -2205,11 +2259,42 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
if (!criteria)
continue;
+ ASSERT(criteria->Type < ACHIEVEMENT_CRITERIA_TYPE_TOTAL, "ACHIEVEMENT_CRITERIA_TYPE_TOTAL must be greater than or equal to %u but is currently equal to %u",
+ criteria->Type + 1, ACHIEVEMENT_CRITERIA_TYPE_TOTAL);
+
m_AchievementCriteriasByType[criteria->Type].push_back(criteria);
m_AchievementCriteriaListByAchievement[criteria->ReferredAchievement].push_back(criteria);
+ if (IsAchievementCriteriaTypeStoredByMiscValue(AchievementCriteriaTypes(criteria->Type)))
+ {
+ if (criteria->Type != ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA)
+ m_AchievementCriteriasByMiscValue[criteria->Type][criteria->Asset.ID].push_back(criteria);
+ else
+ {
+ WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(criteria->Asset.WorldMapOverlayID);
+ if (!worldOverlayEntry)
+ break;
+
+ for (uint8 j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j)
+ {
+ if (worldOverlayEntry->areatableID[j])
+ {
+ bool valid = true;
+ for (uint8 i = 0; i < j; ++i)
+ if (worldOverlayEntry->areatableID[j] == worldOverlayEntry->areatableID[i])
+ valid = false;
+ if (valid)
+ m_AchievementCriteriasByMiscValue[criteria->Type][worldOverlayEntry->areatableID[j]].push_back(criteria);
+ }
+ }
+ }
+ }
if (criteria->StartTimer)
+ {
+ ASSERT(criteria->StartEvent < ACHIEVEMENT_TIMED_TYPE_MAX, "ACHIEVEMENT_TIMED_TYPE_MAX must be greater than or equal to %u but is currently equal to %u",
+ criteria->StartEvent + 1, ACHIEVEMENT_TIMED_TYPE_MAX);
m_AchievementCriteriasByTimedType[criteria->StartEvent].push_back(criteria);
+ }
++loaded;
}